aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-05-11 11:23:03 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-05-12 16:39:07 -0400
commitffdc4cbe5b17c83af779f45de8536c6ece297e42 (patch)
tree07de5a7693a1b76fbd1f213e2a472ac346b82182 /drivers/net
parent9bff0bc4012c7f079b297eb45b47780e3713f367 (diff)
ath9k_hw: clean up EEPROM endian handling on AR9003
Remove the double swapping of the descriptor data structure, instead keep it little-endian (native format of the eeprom data), and byteswap on access. This allows sparse to verify endian access to the eeprom struct. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c174
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h10
2 files changed, 81 insertions, 103 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 8a79550dff71..23eb60ea5455 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -38,6 +38,9 @@
38#define AR_SWITCH_TABLE_ALL (0xfff) 38#define AR_SWITCH_TABLE_ALL (0xfff)
39#define AR_SWITCH_TABLE_ALL_S (0) 39#define AR_SWITCH_TABLE_ALL_S (0)
40 40
41#define LE16(x) __constant_cpu_to_le16(x)
42#define LE32(x) __constant_cpu_to_le32(x)
43
41static const struct ar9300_eeprom ar9300_default = { 44static const struct ar9300_eeprom ar9300_default = {
42 .eepromVersion = 2, 45 .eepromVersion = 2,
43 .templateVersion = 2, 46 .templateVersion = 2,
@@ -45,7 +48,7 @@ static const struct ar9300_eeprom ar9300_default = {
45 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
47 .baseEepHeader = { 50 .baseEepHeader = {
48 .regDmn = {0, 0x1f}, 51 .regDmn = { LE16(0), LE16(0x1f) },
49 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ 52 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
50 .opCapFlags = { 53 .opCapFlags = {
51 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 54 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
@@ -76,15 +79,15 @@ static const struct ar9300_eeprom ar9300_default = {
76 .modalHeader2G = { 79 .modalHeader2G = {
77 /* ar9300_modal_eep_header 2g */ 80 /* ar9300_modal_eep_header 2g */
78 /* 4 idle,t1,t2,b(4 bits per setting) */ 81 /* 4 idle,t1,t2,b(4 bits per setting) */
79 .antCtrlCommon = 0x110, 82 .antCtrlCommon = LE32(0x110),
80 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ 83 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
81 .antCtrlCommon2 = 0x22222, 84 .antCtrlCommon2 = LE32(0x22222),
82 85
83 /* 86 /*
84 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, 87 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
85 * rx1, rx12, b (2 bits each) 88 * rx1, rx12, b (2 bits each)
86 */ 89 */
87 .antCtrlChain = {0x150, 0x150, 0x150}, 90 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
88 91
89 /* 92 /*
90 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db 93 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
@@ -287,12 +290,12 @@ static const struct ar9300_eeprom ar9300_default = {
287 }, 290 },
288 .modalHeader5G = { 291 .modalHeader5G = {
289 /* 4 idle,t1,t2,b (4 bits per setting) */ 292 /* 4 idle,t1,t2,b (4 bits per setting) */
290 .antCtrlCommon = 0x110, 293 .antCtrlCommon = LE32(0x110),
291 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ 294 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
292 .antCtrlCommon2 = 0x22222, 295 .antCtrlCommon2 = LE32(0x22222),
293 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ 296 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
294 .antCtrlChain = { 297 .antCtrlChain = {
295 0x000, 0x000, 0x000, 298 LE16(0x000), LE16(0x000), LE16(0x000),
296 }, 299 },
297 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ 300 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
298 .xatten1DB = {0, 0, 0}, 301 .xatten1DB = {0, 0, 0},
@@ -620,9 +623,9 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
620 case EEP_MAC_MSW: 623 case EEP_MAC_MSW:
621 return eep->macAddr[4] << 8 | eep->macAddr[5]; 624 return eep->macAddr[4] << 8 | eep->macAddr[5];
622 case EEP_REG_0: 625 case EEP_REG_0:
623 return pBase->regDmn[0]; 626 return le16_to_cpu(pBase->regDmn[0]);
624 case EEP_REG_1: 627 case EEP_REG_1:
625 return pBase->regDmn[1]; 628 return le16_to_cpu(pBase->regDmn[1]);
626 case EEP_OP_CAP: 629 case EEP_OP_CAP:
627 return pBase->deviceCap; 630 return pBase->deviceCap;
628 case EEP_OP_MODE: 631 case EEP_OP_MODE:
@@ -640,93 +643,80 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
640 /* Bit 4 is internal regulator flag */ 643 /* Bit 4 is internal regulator flag */
641 return (pBase->featureEnable & 0x10) >> 4; 644 return (pBase->featureEnable & 0x10) >> 4;
642 case EEP_SWREG: 645 case EEP_SWREG:
643 return pBase->swreg; 646 return le32_to_cpu(pBase->swreg);
644 default: 647 default:
645 return 0; 648 return 0;
646 } 649 }
647} 650}
648 651
649#ifdef __BIG_ENDIAN 652static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
650static void ar9300_swap_eeprom(struct ar9300_eeprom *eep) 653 u8 *buffer)
651{ 654{
652 u32 dword; 655 u16 val;
653 u16 word;
654 int i;
655
656 word = swab16(eep->baseEepHeader.regDmn[0]);
657 eep->baseEepHeader.regDmn[0] = word;
658
659 word = swab16(eep->baseEepHeader.regDmn[1]);
660 eep->baseEepHeader.regDmn[1] = word;
661
662 dword = swab32(eep->baseEepHeader.swreg);
663 eep->baseEepHeader.swreg = dword;
664 656
665 dword = swab32(eep->modalHeader2G.antCtrlCommon); 657 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
666 eep->modalHeader2G.antCtrlCommon = dword; 658 return false;
667 659
668 dword = swab32(eep->modalHeader2G.antCtrlCommon2); 660 *buffer = (val >> (8 * (address % 2))) & 0xff;
669 eep->modalHeader2G.antCtrlCommon2 = dword; 661 return true;
662}
670 663
671 dword = swab32(eep->modalHeader5G.antCtrlCommon); 664static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
672 eep->modalHeader5G.antCtrlCommon = dword; 665 u8 *buffer)
666{
667 u16 val;
673 668
674 dword = swab32(eep->modalHeader5G.antCtrlCommon2); 669 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
675 eep->modalHeader5G.antCtrlCommon2 = dword; 670 return false;
676 671
677 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 672 buffer[0] = val >> 8;
678 word = swab16(eep->modalHeader2G.antCtrlChain[i]); 673 buffer[1] = val & 0xff;
679 eep->modalHeader2G.antCtrlChain[i] = word;
680 674
681 word = swab16(eep->modalHeader5G.antCtrlChain[i]); 675 return true;
682 eep->modalHeader5G.antCtrlChain[i] = word;
683 }
684} 676}
685#endif
686 677
687static bool ar9300_hw_read_eeprom(struct ath_hw *ah, 678static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
688 long address, u8 *buffer, int many) 679 int count)
689{ 680{
690 int i;
691 u8 value[2];
692 unsigned long eepAddr;
693 unsigned long byteAddr;
694 u16 *svalue;
695 struct ath_common *common = ath9k_hw_common(ah); 681 struct ath_common *common = ath9k_hw_common(ah);
682 int i;
696 683
697 if ((address < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) { 684 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
698 ath_print(common, ATH_DBG_EEPROM, 685 ath_print(common, ATH_DBG_EEPROM,
699 "eeprom address not in range\n"); 686 "eeprom address not in range\n");
700 return false; 687 return false;
701 } 688 }
702 689
703 for (i = 0; i < many; i++) { 690 /*
704 eepAddr = (u16) (address + i) / 2; 691 * Since we're reading the bytes in reverse order from a little-endian
705 byteAddr = (u16) (address + i) % 2; 692 * word stream, an even address means we only use the lower half of
706 svalue = (u16 *) value; 693 * the 16-bit word at that address
707 if (!ath9k_hw_nvram_read(common, eepAddr, svalue)) { 694 */
708 ath_print(common, ATH_DBG_EEPROM, 695 if (address % 2 == 0) {
709 "unable to read eeprom region\n"); 696 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
710 return false; 697 goto error;
711 } 698
712 *svalue = le16_to_cpu(*svalue); 699 count--;
713 buffer[i] = value[byteAddr];
714 } 700 }
715 701
716 return true; 702 for (i = 0; i < count / 2; i++) {
717} 703 if (!ar9300_eeprom_read_word(common, address, buffer))
704 goto error;
718 705
719static bool ar9300_read_eeprom(struct ath_hw *ah, 706 address -= 2;
720 int address, u8 *buffer, int many) 707 buffer += 2;
721{ 708 }
722 int it; 709
710 if (count % 2)
711 if (!ar9300_eeprom_read_byte(common, address, buffer))
712 goto error;
723 713
724 for (it = 0; it < many; it++)
725 if (!ar9300_hw_read_eeprom(ah,
726 (address - it),
727 (buffer + it), 1))
728 return false;
729 return true; 714 return true;
715
716error:
717 ath_print(common, ATH_DBG_EEPROM,
718 "unable to read eeprom region at offset %d\n", address);
719 return false;
730} 720}
731 721
732static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference, 722static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
@@ -927,30 +917,13 @@ fail:
927 */ 917 */
928static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah) 918static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
929{ 919{
930 u8 *mptr = NULL; 920 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
931 int mdata_size;
932 921
933 mptr = (u8 *) &ah->eeprom.ar9300_eep; 922 if (ar9300_eeprom_restore_internal(ah, mptr,
934 mdata_size = sizeof(struct ar9300_eeprom); 923 sizeof(struct ar9300_eeprom)) < 0)
924 return false;
935 925
936 if (mptr && mdata_size > 0) { 926 return true;
937 /* At this point, mptr points to the eeprom data structure
938 * in it's "default" state. If this is big endian, swap the
939 * data structures back to "little endian"
940 */
941 /* First swap, default to Little Endian */
942#ifdef __BIG_ENDIAN
943 ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
944#endif
945 if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0)
946 return true;
947
948 /* Second Swap, back to Big Endian */
949#ifdef __BIG_ENDIAN
950 ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
951#endif
952 }
953 return false;
954} 927}
955 928
956/* XXX: review hardware docs */ 929/* XXX: review hardware docs */
@@ -998,21 +971,25 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
998static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) 971static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
999{ 972{
1000 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 973 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
974 __le32 val;
1001 975
1002 if (is2ghz) 976 if (is2ghz)
1003 return eep->modalHeader2G.antCtrlCommon; 977 val = eep->modalHeader2G.antCtrlCommon;
1004 else 978 else
1005 return eep->modalHeader5G.antCtrlCommon; 979 val = eep->modalHeader5G.antCtrlCommon;
980 return le32_to_cpu(val);
1006} 981}
1007 982
1008static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz) 983static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
1009{ 984{
1010 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 985 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
986 __le32 val;
1011 987
1012 if (is2ghz) 988 if (is2ghz)
1013 return eep->modalHeader2G.antCtrlCommon2; 989 val = eep->modalHeader2G.antCtrlCommon2;
1014 else 990 else
1015 return eep->modalHeader5G.antCtrlCommon2; 991 val = eep->modalHeader5G.antCtrlCommon2;
992 return le32_to_cpu(val);
1016} 993}
1017 994
1018static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, 995static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
@@ -1020,15 +997,16 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
1020 bool is2ghz) 997 bool is2ghz)
1021{ 998{
1022 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 999 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1000 __le16 val = 0;
1023 1001
1024 if (chain >= 0 && chain < AR9300_MAX_CHAINS) { 1002 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
1025 if (is2ghz) 1003 if (is2ghz)
1026 return eep->modalHeader2G.antCtrlChain[chain]; 1004 val = eep->modalHeader2G.antCtrlChain[chain];
1027 else 1005 else
1028 return eep->modalHeader5G.antCtrlChain[chain]; 1006 val = eep->modalHeader5G.antCtrlChain[chain];
1029 } 1007 }
1030 1008
1031 return 0; 1009 return le16_to_cpu(val);
1032} 1010}
1033 1011
1034static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) 1012static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index d8c0318f416f..23fb353c3bba 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -169,7 +169,7 @@ enum CompressAlgorithm {
169}; 169};
170 170
171struct ar9300_base_eep_hdr { 171struct ar9300_base_eep_hdr {
172 u16 regDmn[2]; 172 __le16 regDmn[2];
173 /* 4 bits tx and 4 bits rx */ 173 /* 4 bits tx and 4 bits rx */
174 u8 txrxMask; 174 u8 txrxMask;
175 struct eepFlags opCapFlags; 175 struct eepFlags opCapFlags;
@@ -199,16 +199,16 @@ struct ar9300_base_eep_hdr {
199 u8 rxBandSelectGpio; 199 u8 rxBandSelectGpio;
200 u8 txrxgain; 200 u8 txrxgain;
201 /* SW controlled internal regulator fields */ 201 /* SW controlled internal regulator fields */
202 u32 swreg; 202 __le32 swreg;
203} __packed; 203} __packed;
204 204
205struct ar9300_modal_eep_header { 205struct ar9300_modal_eep_header {
206 /* 4 idle, t1, t2, b (4 bits per setting) */ 206 /* 4 idle, t1, t2, b (4 bits per setting) */
207 u32 antCtrlCommon; 207 __le32 antCtrlCommon;
208 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ 208 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
209 u32 antCtrlCommon2; 209 __le32 antCtrlCommon2;
210 /* 6 idle, t, r, rx1, rx12, b (2 bits each) */ 210 /* 6 idle, t, r, rx1, rx12, b (2 bits each) */
211 u16 antCtrlChain[AR9300_MAX_CHAINS]; 211 __le16 antCtrlChain[AR9300_MAX_CHAINS];
212 /* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ 212 /* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
213 u8 xatten1DB[AR9300_MAX_CHAINS]; 213 u8 xatten1DB[AR9300_MAX_CHAINS];
214 /* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */ 214 /* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */