diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2014-09-22 10:39:22 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-09-26 17:22:28 -0400 |
commit | 3c67b8f9f3b5bb1207c9bb198e5ef04ff56921dd (patch) | |
tree | b89d24575741253e1bc07f8b25b1fbfe913f2e3f /drivers/net/wireless/rtlwifi/efuse.c | |
parent | 9afa2e44f4d8f9d031f815c32bb8f225f0f6746b (diff) |
rtlwifi: Modify cam.{c,h} and efuse.{c,h} for new drivers
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi/efuse.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/efuse.c | 224 |
1 files changed, 116 insertions, 108 deletions
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 2ffc7298f686..118293b631cd 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
@@ -11,10 +11,6 @@ | |||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * tmis program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * Tme full GNU General Public License is included in this distribution in the | 14 | * Tme full GNU General Public License is included in this distribution in the |
19 | * file called LICENSE. | 15 | * file called LICENSE. |
20 | * | 16 | * |
@@ -26,10 +22,9 @@ | |||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | 22 | * Larry Finger <Larry.Finger@lwfinger.net> |
27 | * | 23 | * |
28 | *****************************************************************************/ | 24 | *****************************************************************************/ |
29 | |||
30 | #include <linux/export.h> | ||
31 | #include "wifi.h" | 25 | #include "wifi.h" |
32 | #include "efuse.h" | 26 | #include "efuse.h" |
27 | #include <linux/export.h> | ||
33 | 28 | ||
34 | static const u8 MAX_PGPKT_SIZE = 9; | 29 | static const u8 MAX_PGPKT_SIZE = 9; |
35 | static const u8 PGPKT_DATA_SIZE = 8; | 30 | static const u8 PGPKT_DATA_SIZE = 8; |
@@ -63,21 +58,19 @@ static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset, | |||
63 | u16 value); | 58 | u16 value); |
64 | static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset, | 59 | static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset, |
65 | u32 value); | 60 | u32 value); |
66 | static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, | ||
67 | u8 *data); | ||
68 | static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, | 61 | static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, |
69 | u8 data); | 62 | u8 data); |
70 | static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse); | 63 | static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse); |
71 | static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, | 64 | static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, |
72 | u8 *data); | 65 | u8 *data); |
73 | static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset, | 66 | static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset, |
74 | u8 word_en, u8 *data); | 67 | u8 word_en, u8 *data); |
75 | static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, | 68 | static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, |
76 | u8 *targetdata); | 69 | u8 *targetdata); |
77 | static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, | 70 | static u8 enable_efuse_data_write(struct ieee80211_hw *hw, |
78 | u16 efuse_addr, u8 word_en, u8 *data); | 71 | u16 efuse_addr, u8 word_en, u8 *data); |
79 | static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, | 72 | static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, |
80 | u8 pwrstate); | 73 | u8 pwrstate); |
81 | static u16 efuse_get_current_size(struct ieee80211_hw *hw); | 74 | static u16 efuse_get_current_size(struct ieee80211_hw *hw); |
82 | static u8 efuse_calculate_word_cnts(u8 word_en); | 75 | static u8 efuse_calculate_word_cnts(u8 word_en); |
83 | 76 | ||
@@ -413,8 +406,7 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) | |||
413 | efuse_used = rtlefuse->efuse_usedbytes; | 406 | efuse_used = rtlefuse->efuse_usedbytes; |
414 | 407 | ||
415 | if ((totalbytes + efuse_used) >= | 408 | if ((totalbytes + efuse_used) >= |
416 | (EFUSE_MAX_SIZE - | 409 | (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) |
417 | rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) | ||
418 | result = false; | 410 | result = false; |
419 | 411 | ||
420 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, | 412 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, |
@@ -428,13 +420,14 @@ void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, | |||
428 | u16 offset, u32 *value) | 420 | u16 offset, u32 *value) |
429 | { | 421 | { |
430 | if (type == 1) | 422 | if (type == 1) |
431 | efuse_shadow_read_1byte(hw, offset, (u8 *) value); | 423 | efuse_shadow_read_1byte(hw, offset, (u8 *)value); |
432 | else if (type == 2) | 424 | else if (type == 2) |
433 | efuse_shadow_read_2byte(hw, offset, (u16 *) value); | 425 | efuse_shadow_read_2byte(hw, offset, (u16 *)value); |
434 | else if (type == 4) | 426 | else if (type == 4) |
435 | efuse_shadow_read_4byte(hw, offset, value); | 427 | efuse_shadow_read_4byte(hw, offset, value); |
436 | 428 | ||
437 | } | 429 | } |
430 | EXPORT_SYMBOL(efuse_shadow_read); | ||
438 | 431 | ||
439 | void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, | 432 | void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, |
440 | u32 value) | 433 | u32 value) |
@@ -456,7 +449,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) | |||
456 | u8 word_en = 0x0F; | 449 | u8 word_en = 0x0F; |
457 | u8 first_pg = false; | 450 | u8 first_pg = false; |
458 | 451 | ||
459 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "--->\n"); | 452 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); |
460 | 453 | ||
461 | if (!efuse_shadow_update_chk(hw)) { | 454 | if (!efuse_shadow_update_chk(hw)) { |
462 | efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); | 455 | efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); |
@@ -465,7 +458,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) | |||
465 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); | 458 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); |
466 | 459 | ||
467 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, | 460 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, |
468 | "<---efuse out of capacity!!\n"); | 461 | "efuse out of capacity!!\n"); |
469 | return false; | 462 | return false; |
470 | } | 463 | } |
471 | efuse_power_switch(hw, true, true); | 464 | efuse_power_switch(hw, true, true); |
@@ -477,7 +470,6 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) | |||
477 | 470 | ||
478 | for (i = 0; i < 8; i++) { | 471 | for (i = 0; i < 8; i++) { |
479 | if (first_pg) { | 472 | if (first_pg) { |
480 | |||
481 | word_en &= ~(BIT(i / 2)); | 473 | word_en &= ~(BIT(i / 2)); |
482 | 474 | ||
483 | rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] = | 475 | rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] = |
@@ -500,7 +492,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) | |||
500 | &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base], | 492 | &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base], |
501 | 8); | 493 | 8); |
502 | RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, | 494 | RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, |
503 | "U-efuse", tmpdata, 8); | 495 | "U-efuse\n", tmpdata, 8); |
504 | 496 | ||
505 | if (!efuse_pg_packet_write(hw, (u8) offset, word_en, | 497 | if (!efuse_pg_packet_write(hw, (u8) offset, word_en, |
506 | tmpdata)) { | 498 | tmpdata)) { |
@@ -519,7 +511,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) | |||
519 | &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], | 511 | &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], |
520 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); | 512 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); |
521 | 513 | ||
522 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "<---\n"); | 514 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); |
523 | return true; | 515 | return true; |
524 | } | 516 | } |
525 | 517 | ||
@@ -529,14 +521,14 @@ void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw) | |||
529 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 521 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
530 | 522 | ||
531 | if (rtlefuse->autoload_failflag) | 523 | if (rtlefuse->autoload_failflag) |
532 | memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, | 524 | memset((&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]), |
533 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); | 525 | 0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); |
534 | else | 526 | else |
535 | efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); | 527 | efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); |
536 | 528 | ||
537 | memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], | 529 | memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], |
538 | &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], | 530 | &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], |
539 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); | 531 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); |
540 | 532 | ||
541 | } | 533 | } |
542 | EXPORT_SYMBOL(rtl_efuse_shadow_map_update); | 534 | EXPORT_SYMBOL(rtl_efuse_shadow_map_update); |
@@ -619,7 +611,7 @@ static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, | |||
619 | 611 | ||
620 | } | 612 | } |
621 | 613 | ||
622 | static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data) | 614 | int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data) |
623 | { | 615 | { |
624 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 616 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
625 | u8 tmpidx = 0; | 617 | u8 tmpidx = 0; |
@@ -650,14 +642,15 @@ static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data) | |||
650 | } | 642 | } |
651 | return result; | 643 | return result; |
652 | } | 644 | } |
645 | EXPORT_SYMBOL(efuse_one_byte_read); | ||
653 | 646 | ||
654 | static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) | 647 | static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) |
655 | { | 648 | { |
656 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 649 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
657 | u8 tmpidx = 0; | 650 | u8 tmpidx = 0; |
658 | 651 | ||
659 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr = %x Data=%x\n", | 652 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, |
660 | addr, data); | 653 | "Addr = %x Data=%x\n", addr, data); |
661 | 654 | ||
662 | rtl_write_byte(rtlpriv, | 655 | rtl_write_byte(rtlpriv, |
663 | rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); | 656 | rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); |
@@ -677,11 +670,10 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) | |||
677 | 670 | ||
678 | if (tmpidx < 100) | 671 | if (tmpidx < 100) |
679 | return true; | 672 | return true; |
680 | |||
681 | return false; | 673 | return false; |
682 | } | 674 | } |
683 | 675 | ||
684 | static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse) | 676 | static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse) |
685 | { | 677 | { |
686 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 678 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
687 | efuse_power_switch(hw, false, true); | 679 | efuse_power_switch(hw, false, true); |
@@ -706,14 +698,14 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
706 | if (hoffset == offset) { | 698 | if (hoffset == offset) { |
707 | for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) { | 699 | for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) { |
708 | if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx, | 700 | if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx, |
709 | &efuse_data)) { | 701 | &efuse_data)) { |
710 | tmpdata[tmpidx] = efuse_data; | 702 | tmpdata[tmpidx] = efuse_data; |
711 | if (efuse_data != 0xff) | 703 | if (efuse_data != 0xff) |
712 | dataempty = true; | 704 | dataempty = false; |
713 | } | 705 | } |
714 | } | 706 | } |
715 | 707 | ||
716 | if (dataempty) { | 708 | if (!dataempty) { |
717 | *readstate = PG_STATE_DATA; | 709 | *readstate = PG_STATE_DATA; |
718 | } else { | 710 | } else { |
719 | *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; | 711 | *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; |
@@ -729,7 +721,9 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
729 | static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) | 721 | static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) |
730 | { | 722 | { |
731 | u8 readstate = PG_STATE_HEADER; | 723 | u8 readstate = PG_STATE_HEADER; |
724 | |||
732 | bool continual = true; | 725 | bool continual = true; |
726 | |||
733 | u8 efuse_data, word_cnts = 0; | 727 | u8 efuse_data, word_cnts = 0; |
734 | u16 efuse_addr = 0; | 728 | u16 efuse_addr = 0; |
735 | u8 tmpdata[8]; | 729 | u8 tmpdata[8]; |
@@ -747,9 +741,8 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) | |||
747 | if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) | 741 | if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) |
748 | && (efuse_data != 0xFF)) | 742 | && (efuse_data != 0xFF)) |
749 | efuse_read_data_case1(hw, &efuse_addr, | 743 | efuse_read_data_case1(hw, &efuse_addr, |
750 | efuse_data, | 744 | efuse_data, offset, |
751 | offset, tmpdata, | 745 | tmpdata, &readstate); |
752 | &readstate); | ||
753 | else | 746 | else |
754 | continual = false; | 747 | continual = false; |
755 | } else if (readstate & PG_STATE_DATA) { | 748 | } else if (readstate & PG_STATE_DATA) { |
@@ -771,13 +764,14 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) | |||
771 | } | 764 | } |
772 | 765 | ||
773 | static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | 766 | static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, |
774 | u8 efuse_data, u8 offset, int *continual, | 767 | u8 efuse_data, u8 offset, |
775 | u8 *write_state, struct pgpkt_struct *target_pkt, | 768 | int *continual, u8 *write_state, |
776 | int *repeat_times, int *result, u8 word_en) | 769 | struct pgpkt_struct *target_pkt, |
770 | int *repeat_times, int *result, u8 word_en) | ||
777 | { | 771 | { |
778 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 772 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
779 | struct pgpkt_struct tmp_pkt; | 773 | struct pgpkt_struct tmp_pkt; |
780 | bool dataempty = true; | 774 | int dataempty = true; |
781 | u8 originaldata[8 * sizeof(u8)]; | 775 | u8 originaldata[8 * sizeof(u8)]; |
782 | u8 badworden = 0x0F; | 776 | u8 badworden = 0x0F; |
783 | u8 match_word_en, tmp_word_en; | 777 | u8 match_word_en, tmp_word_en; |
@@ -794,9 +788,10 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
794 | *write_state = PG_STATE_HEADER; | 788 | *write_state = PG_STATE_HEADER; |
795 | } else { | 789 | } else { |
796 | for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { | 790 | for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { |
797 | u16 address = *efuse_addr + 1 + tmpindex; | 791 | if (efuse_one_byte_read(hw, |
798 | if (efuse_one_byte_read(hw, address, | 792 | (*efuse_addr + 1 + tmpindex), |
799 | &efuse_data) && (efuse_data != 0xFF)) | 793 | &efuse_data) && |
794 | (efuse_data != 0xFF)) | ||
800 | dataempty = false; | 795 | dataempty = false; |
801 | } | 796 | } |
802 | 797 | ||
@@ -806,33 +801,34 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
806 | } else { | 801 | } else { |
807 | match_word_en = 0x0F; | 802 | match_word_en = 0x0F; |
808 | if (!((target_pkt->word_en & BIT(0)) | | 803 | if (!((target_pkt->word_en & BIT(0)) | |
809 | (tmp_pkt.word_en & BIT(0)))) | 804 | (tmp_pkt.word_en & BIT(0)))) |
810 | match_word_en &= (~BIT(0)); | 805 | match_word_en &= (~BIT(0)); |
811 | 806 | ||
812 | if (!((target_pkt->word_en & BIT(1)) | | 807 | if (!((target_pkt->word_en & BIT(1)) | |
813 | (tmp_pkt.word_en & BIT(1)))) | 808 | (tmp_pkt.word_en & BIT(1)))) |
814 | match_word_en &= (~BIT(1)); | 809 | match_word_en &= (~BIT(1)); |
815 | 810 | ||
816 | if (!((target_pkt->word_en & BIT(2)) | | 811 | if (!((target_pkt->word_en & BIT(2)) | |
817 | (tmp_pkt.word_en & BIT(2)))) | 812 | (tmp_pkt.word_en & BIT(2)))) |
818 | match_word_en &= (~BIT(2)); | 813 | match_word_en &= (~BIT(2)); |
819 | 814 | ||
820 | if (!((target_pkt->word_en & BIT(3)) | | 815 | if (!((target_pkt->word_en & BIT(3)) | |
821 | (tmp_pkt.word_en & BIT(3)))) | 816 | (tmp_pkt.word_en & BIT(3)))) |
822 | match_word_en &= (~BIT(3)); | 817 | match_word_en &= (~BIT(3)); |
823 | 818 | ||
824 | if ((match_word_en & 0x0F) != 0x0F) { | 819 | if ((match_word_en & 0x0F) != 0x0F) { |
825 | badworden = efuse_word_enable_data_write( | 820 | badworden = |
826 | hw, *efuse_addr + 1, | 821 | enable_efuse_data_write(hw, |
827 | tmp_pkt.word_en, | 822 | *efuse_addr + 1, |
828 | target_pkt->data); | 823 | tmp_pkt.word_en, |
824 | target_pkt->data); | ||
829 | 825 | ||
830 | if (0x0F != (badworden & 0x0F)) { | 826 | if (0x0F != (badworden & 0x0F)) { |
831 | u8 reorg_offset = offset; | 827 | u8 reorg_offset = offset; |
832 | u8 reorg_worden = badworden; | 828 | u8 reorg_worden = badworden; |
833 | efuse_pg_packet_write(hw, reorg_offset, | 829 | efuse_pg_packet_write(hw, reorg_offset, |
834 | reorg_worden, | 830 | reorg_worden, |
835 | originaldata); | 831 | originaldata); |
836 | } | 832 | } |
837 | 833 | ||
838 | tmp_word_en = 0x0F; | 834 | tmp_word_en = 0x0F; |
@@ -845,11 +841,11 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
845 | tmp_word_en &= (~BIT(1)); | 841 | tmp_word_en &= (~BIT(1)); |
846 | 842 | ||
847 | if ((target_pkt->word_en & BIT(2)) ^ | 843 | if ((target_pkt->word_en & BIT(2)) ^ |
848 | (match_word_en & BIT(2))) | 844 | (match_word_en & BIT(2))) |
849 | tmp_word_en &= (~BIT(2)); | 845 | tmp_word_en &= (~BIT(2)); |
850 | 846 | ||
851 | if ((target_pkt->word_en & BIT(3)) ^ | 847 | if ((target_pkt->word_en & BIT(3)) ^ |
852 | (match_word_en & BIT(3))) | 848 | (match_word_en & BIT(3))) |
853 | tmp_word_en &= (~BIT(3)); | 849 | tmp_word_en &= (~BIT(3)); |
854 | 850 | ||
855 | if ((tmp_word_en & 0x0F) != 0x0F) { | 851 | if ((tmp_word_en & 0x0F) != 0x0F) { |
@@ -873,7 +869,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
873 | } | 869 | } |
874 | } | 870 | } |
875 | } | 871 | } |
876 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n"); | 872 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n"); |
877 | } | 873 | } |
878 | 874 | ||
879 | static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, | 875 | static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, |
@@ -908,12 +904,13 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
908 | 904 | ||
909 | tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); | 905 | tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); |
910 | 906 | ||
911 | memset(originaldata, 0xff, 8 * sizeof(u8)); | 907 | memset(originaldata, 0xff, 8 * sizeof(u8)); |
912 | 908 | ||
913 | if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) { | 909 | if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) { |
914 | badworden = efuse_word_enable_data_write(hw, | 910 | badworden = enable_efuse_data_write(hw, |
915 | *efuse_addr + 1, tmp_pkt.word_en, | 911 | *efuse_addr + 1, |
916 | originaldata); | 912 | tmp_pkt.word_en, |
913 | originaldata); | ||
917 | 914 | ||
918 | if (0x0F != (badworden & 0x0F)) { | 915 | if (0x0F != (badworden & 0x0F)) { |
919 | u8 reorg_offset = tmp_pkt.offset; | 916 | u8 reorg_offset = tmp_pkt.offset; |
@@ -923,8 +920,8 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
923 | originaldata); | 920 | originaldata); |
924 | *efuse_addr = efuse_get_current_size(hw); | 921 | *efuse_addr = efuse_get_current_size(hw); |
925 | } else { | 922 | } else { |
926 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) | 923 | *efuse_addr = *efuse_addr + |
927 | + 1; | 924 | (tmp_word_cnts * 2) + 1; |
928 | } | 925 | } |
929 | } else { | 926 | } else { |
930 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; | 927 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; |
@@ -948,7 +945,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
948 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 945 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
949 | struct pgpkt_struct target_pkt; | 946 | struct pgpkt_struct target_pkt; |
950 | u8 write_state = PG_STATE_HEADER; | 947 | u8 write_state = PG_STATE_HEADER; |
951 | int continual = true, result = true; | 948 | int continual = true, dataempty = true, result = true; |
952 | u16 efuse_addr = 0; | 949 | u16 efuse_addr = 0; |
953 | u8 efuse_data; | 950 | u8 efuse_data; |
954 | u8 target_word_cnts = 0; | 951 | u8 target_word_cnts = 0; |
@@ -956,7 +953,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
956 | static int repeat_times; | 953 | static int repeat_times; |
957 | 954 | ||
958 | if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE - | 955 | if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE - |
959 | rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { | 956 | rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { |
960 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, | 957 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, |
961 | "efuse_pg_packet_write error\n"); | 958 | "efuse_pg_packet_write error\n"); |
962 | return false; | 959 | return false; |
@@ -965,17 +962,18 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
965 | target_pkt.offset = offset; | 962 | target_pkt.offset = offset; |
966 | target_pkt.word_en = word_en; | 963 | target_pkt.word_en = word_en; |
967 | 964 | ||
968 | memset(target_pkt.data, 0xFF, 8 * sizeof(u8)); | 965 | memset(target_pkt.data, 0xFF, 8 * sizeof(u8)); |
969 | 966 | ||
970 | efuse_word_enable_data_read(word_en, data, target_pkt.data); | 967 | efuse_word_enable_data_read(word_en, data, target_pkt.data); |
971 | target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en); | 968 | target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en); |
972 | 969 | ||
973 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n"); | 970 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n"); |
974 | 971 | ||
975 | while (continual && (efuse_addr < (EFUSE_MAX_SIZE - | 972 | while (continual && (efuse_addr < (EFUSE_MAX_SIZE - |
976 | rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) { | 973 | rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) { |
977 | 974 | ||
978 | if (write_state == PG_STATE_HEADER) { | 975 | if (write_state == PG_STATE_HEADER) { |
976 | dataempty = true; | ||
979 | badworden = 0x0F; | 977 | badworden = 0x0F; |
980 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, | 978 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, |
981 | "efuse PG_STATE_HEADER\n"); | 979 | "efuse PG_STATE_HEADER\n"); |
@@ -985,7 +983,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
985 | efuse_write_data_case1(hw, &efuse_addr, | 983 | efuse_write_data_case1(hw, &efuse_addr, |
986 | efuse_data, offset, | 984 | efuse_data, offset, |
987 | &continual, | 985 | &continual, |
988 | &write_state, &target_pkt, | 986 | &write_state, |
987 | &target_pkt, | ||
989 | &repeat_times, &result, | 988 | &repeat_times, &result, |
990 | word_en); | 989 | word_en); |
991 | else | 990 | else |
@@ -999,15 +998,17 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
999 | } else if (write_state == PG_STATE_DATA) { | 998 | } else if (write_state == PG_STATE_DATA) { |
1000 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, | 999 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, |
1001 | "efuse PG_STATE_DATA\n"); | 1000 | "efuse PG_STATE_DATA\n"); |
1001 | badworden = 0x0f; | ||
1002 | badworden = | 1002 | badworden = |
1003 | efuse_word_enable_data_write(hw, efuse_addr + 1, | 1003 | enable_efuse_data_write(hw, efuse_addr + 1, |
1004 | target_pkt.word_en, | 1004 | target_pkt.word_en, |
1005 | target_pkt.data); | 1005 | target_pkt.data); |
1006 | 1006 | ||
1007 | if ((badworden & 0x0F) == 0x0F) { | 1007 | if ((badworden & 0x0F) == 0x0F) { |
1008 | continual = false; | 1008 | continual = false; |
1009 | } else { | 1009 | } else { |
1010 | efuse_addr += (2 * target_word_cnts) + 1; | 1010 | efuse_addr = |
1011 | efuse_addr + (2 * target_word_cnts) + 1; | ||
1011 | 1012 | ||
1012 | target_pkt.offset = offset; | 1013 | target_pkt.offset = offset; |
1013 | target_pkt.word_en = badworden; | 1014 | target_pkt.word_en = badworden; |
@@ -1027,7 +1028,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
1027 | } | 1028 | } |
1028 | 1029 | ||
1029 | if (efuse_addr >= (EFUSE_MAX_SIZE - | 1030 | if (efuse_addr >= (EFUSE_MAX_SIZE - |
1030 | rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { | 1031 | rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { |
1031 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, | 1032 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, |
1032 | "efuse_addr(%#x) Out of size!!\n", efuse_addr); | 1033 | "efuse_addr(%#x) Out of size!!\n", efuse_addr); |
1033 | } | 1034 | } |
@@ -1035,8 +1036,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
1035 | return true; | 1036 | return true; |
1036 | } | 1037 | } |
1037 | 1038 | ||
1038 | static void efuse_word_enable_data_read(u8 word_en, | 1039 | static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, |
1039 | u8 *sourdata, u8 *targetdata) | 1040 | u8 *targetdata) |
1040 | { | 1041 | { |
1041 | if (!(word_en & BIT(0))) { | 1042 | if (!(word_en & BIT(0))) { |
1042 | targetdata[0] = sourdata[0]; | 1043 | targetdata[0] = sourdata[0]; |
@@ -1059,8 +1060,8 @@ static void efuse_word_enable_data_read(u8 word_en, | |||
1059 | } | 1060 | } |
1060 | } | 1061 | } |
1061 | 1062 | ||
1062 | static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, | 1063 | static u8 enable_efuse_data_write(struct ieee80211_hw *hw, |
1063 | u16 efuse_addr, u8 word_en, u8 *data) | 1064 | u16 efuse_addr, u8 word_en, u8 *data) |
1064 | { | 1065 | { |
1065 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1066 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1066 | u16 tmpaddr; | 1067 | u16 tmpaddr; |
@@ -1069,8 +1070,8 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, | |||
1069 | u8 tmpdata[8]; | 1070 | u8 tmpdata[8]; |
1070 | 1071 | ||
1071 | memset(tmpdata, 0xff, PGPKT_DATA_SIZE); | 1072 | memset(tmpdata, 0xff, PGPKT_DATA_SIZE); |
1072 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "word_en = %x efuse_addr=%x\n", | 1073 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, |
1073 | word_en, efuse_addr); | 1074 | "word_en = %x efuse_addr=%x\n", word_en, efuse_addr); |
1074 | 1075 | ||
1075 | if (!(word_en & BIT(0))) { | 1076 | if (!(word_en & BIT(0))) { |
1076 | tmpaddr = start_addr; | 1077 | tmpaddr = start_addr; |
@@ -1127,19 +1128,22 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) | |||
1127 | u16 tmpV16; | 1128 | u16 tmpV16; |
1128 | 1129 | ||
1129 | if (pwrstate && (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)) { | 1130 | if (pwrstate && (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)) { |
1130 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE) | ||
1131 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], | ||
1132 | 0x69); | ||
1133 | 1131 | ||
1134 | tmpV16 = rtl_read_word(rtlpriv, | 1132 | if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE && |
1135 | rtlpriv->cfg->maps[SYS_ISO_CTRL]); | 1133 | rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) { |
1136 | if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { | 1134 | rtl_write_byte(rtlpriv, |
1137 | tmpV16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V]; | 1135 | rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69); |
1138 | rtl_write_word(rtlpriv, | 1136 | } else { |
1139 | rtlpriv->cfg->maps[SYS_ISO_CTRL], | 1137 | tmpV16 = |
1140 | tmpV16); | 1138 | rtl_read_word(rtlpriv, |
1139 | rtlpriv->cfg->maps[SYS_ISO_CTRL]); | ||
1140 | if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { | ||
1141 | tmpV16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V]; | ||
1142 | rtl_write_word(rtlpriv, | ||
1143 | rtlpriv->cfg->maps[SYS_ISO_CTRL], | ||
1144 | tmpV16); | ||
1145 | } | ||
1141 | } | 1146 | } |
1142 | |||
1143 | tmpV16 = rtl_read_word(rtlpriv, | 1147 | tmpV16 = rtl_read_word(rtlpriv, |
1144 | rtlpriv->cfg->maps[SYS_FUNC_EN]); | 1148 | rtlpriv->cfg->maps[SYS_FUNC_EN]); |
1145 | if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) { | 1149 | if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) { |
@@ -1164,7 +1168,10 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) | |||
1164 | rtlpriv->cfg->maps[EFUSE_TEST] + | 1168 | rtlpriv->cfg->maps[EFUSE_TEST] + |
1165 | 3); | 1169 | 3); |
1166 | 1170 | ||
1167 | if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) { | 1171 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { |
1172 | tempval &= ~(BIT(3) | BIT(4) | BIT(5) | BIT(6)); | ||
1173 | tempval |= (VOLTAGE_V25 << 3); | ||
1174 | } else if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) { | ||
1168 | tempval &= 0x0F; | 1175 | tempval &= 0x0F; |
1169 | tempval |= (VOLTAGE_V25 << 4); | 1176 | tempval |= (VOLTAGE_V25 << 4); |
1170 | } | 1177 | } |
@@ -1176,11 +1183,11 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) | |||
1176 | 1183 | ||
1177 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { | 1184 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { |
1178 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], | 1185 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], |
1179 | 0x03); | 1186 | 0x03); |
1180 | } | 1187 | } |
1181 | |||
1182 | } else { | 1188 | } else { |
1183 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE) | 1189 | if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE && |
1190 | rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) | ||
1184 | rtl_write_byte(rtlpriv, | 1191 | rtl_write_byte(rtlpriv, |
1185 | rtlpriv->cfg->maps[EFUSE_ACCESS], 0); | 1192 | rtlpriv->cfg->maps[EFUSE_ACCESS], 0); |
1186 | 1193 | ||
@@ -1195,27 +1202,28 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) | |||
1195 | 1202 | ||
1196 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { | 1203 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { |
1197 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], | 1204 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], |
1198 | 0x02); | 1205 | 0x02); |
1199 | } | 1206 | } |
1200 | |||
1201 | } | 1207 | } |
1202 | |||
1203 | } | 1208 | } |
1204 | 1209 | ||
1205 | static u16 efuse_get_current_size(struct ieee80211_hw *hw) | 1210 | static u16 efuse_get_current_size(struct ieee80211_hw *hw) |
1206 | { | 1211 | { |
1212 | int continual = true; | ||
1207 | u16 efuse_addr = 0; | 1213 | u16 efuse_addr = 0; |
1208 | u8 hworden; | 1214 | u8 hoffset, hworden; |
1209 | u8 efuse_data, word_cnts; | 1215 | u8 efuse_data, word_cnts; |
1210 | 1216 | ||
1211 | while (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && | 1217 | while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) && |
1212 | efuse_addr < EFUSE_MAX_SIZE) { | 1218 | (efuse_addr < EFUSE_MAX_SIZE)) { |
1213 | if (efuse_data == 0xFF) | 1219 | if (efuse_data != 0xFF) { |
1214 | break; | 1220 | hoffset = (efuse_data >> 4) & 0x0F; |
1215 | 1221 | hworden = efuse_data & 0x0F; | |
1216 | hworden = efuse_data & 0x0F; | 1222 | word_cnts = efuse_calculate_word_cnts(hworden); |
1217 | word_cnts = efuse_calculate_word_cnts(hworden); | 1223 | efuse_addr = efuse_addr + (word_cnts * 2) + 1; |
1218 | efuse_addr = efuse_addr + (word_cnts * 2) + 1; | 1224 | } else { |
1225 | continual = false; | ||
1226 | } | ||
1219 | } | 1227 | } |
1220 | 1228 | ||
1221 | return efuse_addr; | 1229 | return efuse_addr; |