aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi/efuse.c
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2014-09-22 10:39:22 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-26 17:22:28 -0400
commit3c67b8f9f3b5bb1207c9bb198e5ef04ff56921dd (patch)
treeb89d24575741253e1bc07f8b25b1fbfe913f2e3f /drivers/net/wireless/rtlwifi/efuse.c
parent9afa2e44f4d8f9d031f815c32bb8f225f0f6746b (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.c224
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
34static const u8 MAX_PGPKT_SIZE = 9; 29static const u8 MAX_PGPKT_SIZE = 9;
35static const u8 PGPKT_DATA_SIZE = 8; 30static 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);
64static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset, 59static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
65 u32 value); 60 u32 value);
66static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr,
67 u8 *data);
68static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, 61static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
69 u8 data); 62 u8 data);
70static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse); 63static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse);
71static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, 64static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
72 u8 *data); 65 u8 *data);
73static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset, 66static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
74 u8 word_en, u8 *data); 67 u8 word_en, u8 *data);
75static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, 68static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
76 u8 *targetdata); 69 u8 *targetdata);
77static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, 70static 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);
79static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, 72static void efuse_power_switch(struct ieee80211_hw *hw, u8 write,
80 u8 pwrstate); 73 u8 pwrstate);
81static u16 efuse_get_current_size(struct ieee80211_hw *hw); 74static u16 efuse_get_current_size(struct ieee80211_hw *hw);
82static u8 efuse_calculate_word_cnts(u8 word_en); 75static 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}
430EXPORT_SYMBOL(efuse_shadow_read);
438 431
439void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, 432void 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}
542EXPORT_SYMBOL(rtl_efuse_shadow_map_update); 534EXPORT_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
622static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data) 614int 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}
645EXPORT_SYMBOL(efuse_one_byte_read);
653 646
654static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) 647static 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
684static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse) 676static 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,
729static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) 721static 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
773static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, 766static 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
879static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, 875static 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
1038static void efuse_word_enable_data_read(u8 word_en, 1039static 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
1062static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, 1063static 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
1205static u16 efuse_get_current_size(struct ieee80211_hw *hw) 1210static 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;