diff options
author | Senthil Balasubramanian <senthilkumar@atheros.com> | 2008-12-08 09:13:48 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-12-12 13:48:26 -0500 |
commit | e7594072a5b918510c937c1ab0acad4e8a931bc7 (patch) | |
tree | 50cc34039e87fc3152c54073b9349971249b050f /drivers/net | |
parent | e8fbc99edfe0efa0b42f04587a79a6b3371f961a (diff) |
ath9k: Adding support for Atheros AR9285 chipset.
Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath9k/ath9k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/calib.c | 98 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/eeprom.c | 1824 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/hw.c | 90 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/hw.h | 135 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/mac.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/phy.h | 5 |
8 files changed, 1826 insertions, 332 deletions
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 9520aa0898e..d2781350295 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #define AR9160_DEVID_PCI 0x0027 | 26 | #define AR9160_DEVID_PCI 0x0027 |
27 | #define AR9280_DEVID_PCI 0x0029 | 27 | #define AR9280_DEVID_PCI 0x0029 |
28 | #define AR9280_DEVID_PCIE 0x002a | 28 | #define AR9280_DEVID_PCIE 0x002a |
29 | #define AR9285_DEVID_PCIE 0x002b | ||
29 | 30 | ||
30 | #define AR5416_AR9100_DEVID 0x000b | 31 | #define AR5416_AR9100_DEVID 0x000b |
31 | 32 | ||
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c index 51c8a3ce4e6..3c7454fc51b 100644 --- a/drivers/net/wireless/ath9k/calib.c +++ b/drivers/net/wireless/ath9k/calib.c | |||
@@ -818,6 +818,101 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, | |||
818 | return true; | 818 | return true; |
819 | } | 819 | } |
820 | 820 | ||
821 | static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah) | ||
822 | { | ||
823 | |||
824 | u32 regVal; | ||
825 | int i, offset, offs_6_1, offs_0; | ||
826 | u32 ccomp_org, reg_field; | ||
827 | u32 regList[][2] = { | ||
828 | { 0x786c, 0 }, | ||
829 | { 0x7854, 0 }, | ||
830 | { 0x7820, 0 }, | ||
831 | { 0x7824, 0 }, | ||
832 | { 0x7868, 0 }, | ||
833 | { 0x783c, 0 }, | ||
834 | { 0x7838, 0 }, | ||
835 | }; | ||
836 | |||
837 | if (AR_SREV_9285_11(ah)) { | ||
838 | REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); | ||
839 | udelay(10); | ||
840 | } | ||
841 | |||
842 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
843 | regList[i][1] = REG_READ(ah, regList[i][0]); | ||
844 | |||
845 | regVal = REG_READ(ah, 0x7834); | ||
846 | regVal &= (~(0x1)); | ||
847 | REG_WRITE(ah, 0x7834, regVal); | ||
848 | regVal = REG_READ(ah, 0x9808); | ||
849 | regVal |= (0x1 << 27); | ||
850 | REG_WRITE(ah, 0x9808, regVal); | ||
851 | |||
852 | REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); | ||
853 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); | ||
854 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); | ||
855 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); | ||
856 | REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); | ||
857 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); | ||
858 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); | ||
859 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1); | ||
860 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0); | ||
861 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); | ||
862 | REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); | ||
863 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); | ||
864 | ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP); | ||
865 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7); | ||
866 | |||
867 | REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0); | ||
868 | udelay(30); | ||
869 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0); | ||
870 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0); | ||
871 | |||
872 | for (i = 6; i > 0; i--) { | ||
873 | regVal = REG_READ(ah, 0x7834); | ||
874 | regVal |= (1 << (19 + i)); | ||
875 | REG_WRITE(ah, 0x7834, regVal); | ||
876 | udelay(1); | ||
877 | regVal = REG_READ(ah, 0x7834); | ||
878 | regVal &= (~(0x1 << (19 + i))); | ||
879 | reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9); | ||
880 | regVal |= (reg_field << (19 + i)); | ||
881 | REG_WRITE(ah, 0x7834, regVal); | ||
882 | } | ||
883 | |||
884 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1); | ||
885 | udelay(1); | ||
886 | reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9); | ||
887 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field); | ||
888 | offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS); | ||
889 | offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP); | ||
890 | |||
891 | offset = (offs_6_1<<1) | offs_0; | ||
892 | offset = offset - 0; | ||
893 | offs_6_1 = offset>>1; | ||
894 | offs_0 = offset & 1; | ||
895 | |||
896 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1); | ||
897 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0); | ||
898 | |||
899 | regVal = REG_READ(ah, 0x7834); | ||
900 | regVal |= 0x1; | ||
901 | REG_WRITE(ah, 0x7834, regVal); | ||
902 | regVal = REG_READ(ah, 0x9808); | ||
903 | regVal &= (~(0x1 << 27)); | ||
904 | REG_WRITE(ah, 0x9808, regVal); | ||
905 | |||
906 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
907 | REG_WRITE(ah, regList[i][0], regList[i][1]); | ||
908 | |||
909 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org); | ||
910 | |||
911 | if (AR_SREV_9285_11(ah)) | ||
912 | REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); | ||
913 | |||
914 | } | ||
915 | |||
821 | bool ath9k_hw_init_cal(struct ath_hal *ah, | 916 | bool ath9k_hw_init_cal(struct ath_hal *ah, |
822 | struct ath9k_channel *chan) | 917 | struct ath9k_channel *chan) |
823 | { | 918 | { |
@@ -835,6 +930,9 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, | |||
835 | return false; | 930 | return false; |
836 | } | 931 | } |
837 | 932 | ||
933 | if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah)) | ||
934 | ath9k_hw_9285_pa_cal(ah); | ||
935 | |||
838 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | 936 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, |
839 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | 937 | REG_READ(ah, AR_PHY_AGC_CONTROL) | |
840 | AR_PHY_AGC_CONTROL_NF); | 938 | AR_PHY_AGC_CONTROL_NF); |
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c index e180c9043df..d4e51dda413 100644 --- a/drivers/net/wireless/ath9k/eeprom.c +++ b/drivers/net/wireless/ath9k/eeprom.c | |||
@@ -140,61 +140,97 @@ static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data) | |||
140 | return ath9k_hw_eeprom_read(ah, off, data); | 140 | return ath9k_hw_eeprom_read(ah, off, data); |
141 | } | 141 | } |
142 | 142 | ||
143 | static bool ath9k_hw_fill_eeprom(struct ath_hal *ah) | 143 | static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah) |
144 | { | 144 | { |
145 | #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) | ||
145 | struct ath_hal_5416 *ahp = AH5416(ah); | 146 | struct ath_hal_5416 *ahp = AH5416(ah); |
146 | struct ar5416_eeprom *eep = &ahp->ah_eeprom; | 147 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; |
147 | u16 *eep_data; | 148 | u16 *eep_data; |
148 | int addr, ar5416_eep_start_loc = 0; | 149 | int addr, eep_start_loc = 0; |
150 | |||
151 | eep_start_loc = 64; | ||
149 | 152 | ||
150 | if (!ath9k_hw_use_flash(ah)) { | 153 | if (!ath9k_hw_use_flash(ah)) { |
151 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 154 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
152 | "Reading from EEPROM, not flash\n"); | 155 | "Reading from EEPROM, not flash\n"); |
153 | ar5416_eep_start_loc = 256; | ||
154 | } | 156 | } |
155 | 157 | ||
156 | if (AR_SREV_9100(ah)) | 158 | eep_data = (u16 *)eep; |
157 | ar5416_eep_start_loc = 256; | 159 | |
160 | for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { | ||
161 | if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) { | ||
162 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
163 | "Unable to read eeprom region \n"); | ||
164 | return false; | ||
165 | } | ||
166 | eep_data++; | ||
167 | } | ||
168 | return true; | ||
169 | #undef SIZE_EEPROM_4K | ||
170 | } | ||
171 | |||
172 | static bool ath9k_hw_fill_def_eeprom(struct ath_hal *ah) | ||
173 | { | ||
174 | #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) | ||
175 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
176 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; | ||
177 | u16 *eep_data; | ||
178 | int addr, ar5416_eep_start_loc = 0x100; | ||
158 | 179 | ||
159 | eep_data = (u16 *)eep; | 180 | eep_data = (u16 *)eep; |
160 | 181 | ||
161 | for (addr = 0; addr < sizeof(struct ar5416_eeprom) / sizeof(u16); addr++) { | 182 | for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { |
162 | if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, | 183 | if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, |
163 | eep_data)) { | 184 | eep_data)) { |
164 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 185 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
165 | "Unable to read eeprom region \n"); | 186 | "Unable to read eeprom region\n"); |
166 | return false; | 187 | return false; |
167 | } | 188 | } |
168 | eep_data++; | 189 | eep_data++; |
169 | } | 190 | } |
170 | return true; | 191 | return true; |
192 | #undef SIZE_EEPROM_DEF | ||
193 | } | ||
194 | |||
195 | bool (*ath9k_fill_eeprom[]) (struct ath_hal *) = { | ||
196 | ath9k_hw_fill_def_eeprom, | ||
197 | ath9k_hw_fill_4k_eeprom | ||
198 | }; | ||
199 | |||
200 | static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah) | ||
201 | { | ||
202 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
203 | |||
204 | return ath9k_fill_eeprom[ahp->ah_eep_map](ah); | ||
171 | } | 205 | } |
172 | 206 | ||
173 | static int ath9k_hw_check_eeprom(struct ath_hal *ah) | 207 | static int ath9k_hw_check_def_eeprom(struct ath_hal *ah) |
174 | { | 208 | { |
175 | struct ath_hal_5416 *ahp = AH5416(ah); | 209 | struct ath_hal_5416 *ahp = AH5416(ah); |
176 | struct ar5416_eeprom *eep = | 210 | struct ar5416_eeprom_def *eep = |
177 | (struct ar5416_eeprom *) &ahp->ah_eeprom; | 211 | (struct ar5416_eeprom_def *) &ahp->ah_eeprom.def; |
178 | u16 *eepdata, temp, magic, magic2; | 212 | u16 *eepdata, temp, magic, magic2; |
179 | u32 sum = 0, el; | 213 | u32 sum = 0, el; |
180 | bool need_swap = false; | 214 | bool need_swap = false; |
181 | int i, addr, size; | 215 | int i, addr, size; |
182 | 216 | ||
217 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, | ||
218 | &magic)) { | ||
219 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
220 | "Reading Magic # failed\n"); | ||
221 | return false; | ||
222 | } | ||
223 | |||
183 | if (!ath9k_hw_use_flash(ah)) { | 224 | if (!ath9k_hw_use_flash(ah)) { |
184 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, | ||
185 | &magic)) { | ||
186 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
187 | "Reading Magic # failed\n"); | ||
188 | return false; | ||
189 | } | ||
190 | 225 | ||
191 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "Read Magic = 0x%04X\n", magic); | 226 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
227 | "Read Magic = 0x%04X\n", magic); | ||
192 | 228 | ||
193 | if (magic != AR5416_EEPROM_MAGIC) { | 229 | if (magic != AR5416_EEPROM_MAGIC) { |
194 | magic2 = swab16(magic); | 230 | magic2 = swab16(magic); |
195 | 231 | ||
196 | if (magic2 == AR5416_EEPROM_MAGIC) { | 232 | if (magic2 == AR5416_EEPROM_MAGIC) { |
197 | size = sizeof(struct ar5416_eeprom); | 233 | size = sizeof(struct ar5416_eeprom_def); |
198 | need_swap = true; | 234 | need_swap = true; |
199 | eepdata = (u16 *) (&ahp->ah_eeprom); | 235 | eepdata = (u16 *) (&ahp->ah_eeprom); |
200 | 236 | ||
@@ -223,12 +259,12 @@ static int ath9k_hw_check_eeprom(struct ath_hal *ah) | |||
223 | need_swap ? "True" : "False"); | 259 | need_swap ? "True" : "False"); |
224 | 260 | ||
225 | if (need_swap) | 261 | if (need_swap) |
226 | el = swab16(ahp->ah_eeprom.baseEepHeader.length); | 262 | el = swab16(ahp->ah_eeprom.def.baseEepHeader.length); |
227 | else | 263 | else |
228 | el = ahp->ah_eeprom.baseEepHeader.length; | 264 | el = ahp->ah_eeprom.def.baseEepHeader.length; |
229 | 265 | ||
230 | if (el > sizeof(struct ar5416_eeprom)) | 266 | if (el > sizeof(struct ar5416_eeprom_def)) |
231 | el = sizeof(struct ar5416_eeprom) / sizeof(u16); | 267 | el = sizeof(struct ar5416_eeprom_def) / sizeof(u16); |
232 | else | 268 | else |
233 | el = el / sizeof(u16); | 269 | el = el / sizeof(u16); |
234 | 270 | ||
@@ -297,6 +333,145 @@ static int ath9k_hw_check_eeprom(struct ath_hal *ah) | |||
297 | return 0; | 333 | return 0; |
298 | } | 334 | } |
299 | 335 | ||
336 | static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah) | ||
337 | { | ||
338 | #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) | ||
339 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
340 | struct ar5416_eeprom_4k *eep = | ||
341 | (struct ar5416_eeprom_4k *) &ahp->ah_eeprom.map4k; | ||
342 | u16 *eepdata, temp, magic, magic2; | ||
343 | u32 sum = 0, el; | ||
344 | bool need_swap = false; | ||
345 | int i, addr; | ||
346 | |||
347 | |||
348 | if (!ath9k_hw_use_flash(ah)) { | ||
349 | |||
350 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, | ||
351 | &magic)) { | ||
352 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
353 | "Reading Magic # failed\n"); | ||
354 | return false; | ||
355 | } | ||
356 | |||
357 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
358 | "Read Magic = 0x%04X\n", magic); | ||
359 | |||
360 | if (magic != AR5416_EEPROM_MAGIC) { | ||
361 | magic2 = swab16(magic); | ||
362 | |||
363 | if (magic2 == AR5416_EEPROM_MAGIC) { | ||
364 | need_swap = true; | ||
365 | eepdata = (u16 *) (&ahp->ah_eeprom); | ||
366 | |||
367 | for (addr = 0; addr < EEPROM_4K_SIZE; addr++) { | ||
368 | temp = swab16(*eepdata); | ||
369 | *eepdata = temp; | ||
370 | eepdata++; | ||
371 | |||
372 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
373 | "0x%04X ", *eepdata); | ||
374 | |||
375 | if (((addr + 1) % 6) == 0) | ||
376 | DPRINTF(ah->ah_sc, | ||
377 | ATH_DBG_EEPROM, "\n"); | ||
378 | } | ||
379 | } else { | ||
380 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
381 | "Invalid EEPROM Magic. " | ||
382 | "endianness mismatch.\n"); | ||
383 | return -EINVAL; | ||
384 | } | ||
385 | } | ||
386 | } | ||
387 | |||
388 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", | ||
389 | need_swap ? "True" : "False"); | ||
390 | |||
391 | if (need_swap) | ||
392 | el = swab16(ahp->ah_eeprom.map4k.baseEepHeader.length); | ||
393 | else | ||
394 | el = ahp->ah_eeprom.map4k.baseEepHeader.length; | ||
395 | |||
396 | if (el > sizeof(struct ar5416_eeprom_def)) | ||
397 | el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16); | ||
398 | else | ||
399 | el = el / sizeof(u16); | ||
400 | |||
401 | eepdata = (u16 *)(&ahp->ah_eeprom); | ||
402 | |||
403 | for (i = 0; i < el; i++) | ||
404 | sum ^= *eepdata++; | ||
405 | |||
406 | if (need_swap) { | ||
407 | u32 integer; | ||
408 | u16 word; | ||
409 | |||
410 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
411 | "EEPROM Endianness is not native.. Changing \n"); | ||
412 | |||
413 | word = swab16(eep->baseEepHeader.length); | ||
414 | eep->baseEepHeader.length = word; | ||
415 | |||
416 | word = swab16(eep->baseEepHeader.checksum); | ||
417 | eep->baseEepHeader.checksum = word; | ||
418 | |||
419 | word = swab16(eep->baseEepHeader.version); | ||
420 | eep->baseEepHeader.version = word; | ||
421 | |||
422 | word = swab16(eep->baseEepHeader.regDmn[0]); | ||
423 | eep->baseEepHeader.regDmn[0] = word; | ||
424 | |||
425 | word = swab16(eep->baseEepHeader.regDmn[1]); | ||
426 | eep->baseEepHeader.regDmn[1] = word; | ||
427 | |||
428 | word = swab16(eep->baseEepHeader.rfSilent); | ||
429 | eep->baseEepHeader.rfSilent = word; | ||
430 | |||
431 | word = swab16(eep->baseEepHeader.blueToothOptions); | ||
432 | eep->baseEepHeader.blueToothOptions = word; | ||
433 | |||
434 | word = swab16(eep->baseEepHeader.deviceCap); | ||
435 | eep->baseEepHeader.deviceCap = word; | ||
436 | |||
437 | integer = swab32(eep->modalHeader.antCtrlCommon); | ||
438 | eep->modalHeader.antCtrlCommon = integer; | ||
439 | |||
440 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
441 | integer = swab32(eep->modalHeader.antCtrlChain[i]); | ||
442 | eep->modalHeader.antCtrlChain[i] = integer; | ||
443 | } | ||
444 | |||
445 | for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { | ||
446 | word = swab16(eep->modalHeader.spurChans[i].spurChan); | ||
447 | eep->modalHeader.spurChans[i].spurChan = word; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | if (sum != 0xffff || ar5416_get_eep4k_ver(ahp) != AR5416_EEP_VER || | ||
452 | ar5416_get_eep4k_rev(ahp) < AR5416_EEP_NO_BACK_VER) { | ||
453 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
454 | "Bad EEPROM checksum 0x%x or revision 0x%04x\n", | ||
455 | sum, ar5416_get_eep4k_ver(ahp)); | ||
456 | return -EINVAL; | ||
457 | } | ||
458 | |||
459 | return 0; | ||
460 | #undef EEPROM_4K_SIZE | ||
461 | } | ||
462 | |||
463 | int (*ath9k_check_eeprom[]) (struct ath_hal *) = { | ||
464 | ath9k_hw_check_def_eeprom, | ||
465 | ath9k_hw_check_4k_eeprom | ||
466 | }; | ||
467 | |||
468 | static inline int ath9k_hw_check_eeprom(struct ath_hal *ah) | ||
469 | { | ||
470 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
471 | |||
472 | return ath9k_check_eeprom[ahp->ah_eep_map](ah); | ||
473 | } | ||
474 | |||
300 | static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, | 475 | static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, |
301 | u8 *pVpdList, u16 numIntercepts, | 476 | u8 *pVpdList, u16 numIntercepts, |
302 | u8 *pRetVpdList) | 477 | u8 *pRetVpdList) |
@@ -326,7 +501,175 @@ static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, | |||
326 | return true; | 501 | return true; |
327 | } | 502 | } |
328 | 503 | ||
329 | static void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah, | 504 | static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah, |
505 | struct ath9k_channel *chan, | ||
506 | struct cal_data_per_freq_4k *pRawDataSet, | ||
507 | u8 *bChans, u16 availPiers, | ||
508 | u16 tPdGainOverlap, int16_t *pMinCalPower, | ||
509 | u16 *pPdGainBoundaries, u8 *pPDADCValues, | ||
510 | u16 numXpdGains) | ||
511 | { | ||
512 | #define TMP_VAL_VPD_TABLE \ | ||
513 | ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); | ||
514 | int i, j, k; | ||
515 | int16_t ss; | ||
516 | u16 idxL = 0, idxR = 0, numPiers; | ||
517 | static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] | ||
518 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
519 | static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS] | ||
520 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
521 | static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] | ||
522 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
523 | |||
524 | u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; | ||
525 | u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS]; | ||
526 | u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS]; | ||
527 | int16_t vpdStep; | ||
528 | int16_t tmpVal; | ||
529 | u16 sizeCurrVpdTable, maxIndex, tgtIndex; | ||
530 | bool match; | ||
531 | int16_t minDelta = 0; | ||
532 | struct chan_centers centers; | ||
533 | #define PD_GAIN_BOUNDARY_DEFAULT 58; | ||
534 | |||
535 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
536 | |||
537 | for (numPiers = 0; numPiers < availPiers; numPiers++) { | ||
538 | if (bChans[numPiers] == AR5416_BCHAN_UNUSED) | ||
539 | break; | ||
540 | } | ||
541 | |||
542 | match = ath9k_hw_get_lower_upper_index( | ||
543 | (u8)FREQ2FBIN(centers.synth_center, | ||
544 | IS_CHAN_2GHZ(chan)), bChans, numPiers, | ||
545 | &idxL, &idxR); | ||
546 | |||
547 | if (match) { | ||
548 | for (i = 0; i < numXpdGains; i++) { | ||
549 | minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; | ||
550 | maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; | ||
551 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
552 | pRawDataSet[idxL].pwrPdg[i], | ||
553 | pRawDataSet[idxL].vpdPdg[i], | ||
554 | AR5416_EEP4K_PD_GAIN_ICEPTS, | ||
555 | vpdTableI[i]); | ||
556 | } | ||
557 | } else { | ||
558 | for (i = 0; i < numXpdGains; i++) { | ||
559 | pVpdL = pRawDataSet[idxL].vpdPdg[i]; | ||
560 | pPwrL = pRawDataSet[idxL].pwrPdg[i]; | ||
561 | pVpdR = pRawDataSet[idxR].vpdPdg[i]; | ||
562 | pPwrR = pRawDataSet[idxR].pwrPdg[i]; | ||
563 | |||
564 | minPwrT4[i] = max(pPwrL[0], pPwrR[0]); | ||
565 | |||
566 | maxPwrT4[i] = | ||
567 | min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1], | ||
568 | pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]); | ||
569 | |||
570 | |||
571 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
572 | pPwrL, pVpdL, | ||
573 | AR5416_EEP4K_PD_GAIN_ICEPTS, | ||
574 | vpdTableL[i]); | ||
575 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
576 | pPwrR, pVpdR, | ||
577 | AR5416_EEP4K_PD_GAIN_ICEPTS, | ||
578 | vpdTableR[i]); | ||
579 | |||
580 | for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { | ||
581 | vpdTableI[i][j] = | ||
582 | (u8)(ath9k_hw_interpolate((u16) | ||
583 | FREQ2FBIN(centers. | ||
584 | synth_center, | ||
585 | IS_CHAN_2GHZ | ||
586 | (chan)), | ||
587 | bChans[idxL], bChans[idxR], | ||
588 | vpdTableL[i][j], vpdTableR[i][j])); | ||
589 | } | ||
590 | } | ||
591 | } | ||
592 | |||
593 | *pMinCalPower = (int16_t)(minPwrT4[0] / 2); | ||
594 | |||
595 | k = 0; | ||
596 | |||
597 | for (i = 0; i < numXpdGains; i++) { | ||
598 | if (i == (numXpdGains - 1)) | ||
599 | pPdGainBoundaries[i] = | ||
600 | (u16)(maxPwrT4[i] / 2); | ||
601 | else | ||
602 | pPdGainBoundaries[i] = | ||
603 | (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); | ||
604 | |||
605 | pPdGainBoundaries[i] = | ||
606 | min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); | ||
607 | |||
608 | if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) { | ||
609 | minDelta = pPdGainBoundaries[0] - 23; | ||
610 | pPdGainBoundaries[0] = 23; | ||
611 | } else { | ||
612 | minDelta = 0; | ||
613 | } | ||
614 | |||
615 | if (i == 0) { | ||
616 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
617 | ss = (int16_t)(0 - (minPwrT4[i] / 2)); | ||
618 | else | ||
619 | ss = 0; | ||
620 | } else { | ||
621 | ss = (int16_t)((pPdGainBoundaries[i - 1] - | ||
622 | (minPwrT4[i] / 2)) - | ||
623 | tPdGainOverlap + 1 + minDelta); | ||
624 | } | ||
625 | vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); | ||
626 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); | ||
627 | |||
628 | while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { | ||
629 | tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); | ||
630 | pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); | ||
631 | ss++; | ||
632 | } | ||
633 | |||
634 | sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); | ||
635 | tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - | ||
636 | (minPwrT4[i] / 2)); | ||
637 | maxIndex = (tgtIndex < sizeCurrVpdTable) ? | ||
638 | tgtIndex : sizeCurrVpdTable; | ||
639 | |||
640 | while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) | ||
641 | pPDADCValues[k++] = vpdTableI[i][ss++]; | ||
642 | |||
643 | vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - | ||
644 | vpdTableI[i][sizeCurrVpdTable - 2]); | ||
645 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); | ||
646 | |||
647 | if (tgtIndex > maxIndex) { | ||
648 | while ((ss <= tgtIndex) && | ||
649 | (k < (AR5416_NUM_PDADC_VALUES - 1))) { | ||
650 | tmpVal = (int16_t) TMP_VAL_VPD_TABLE; | ||
651 | pPDADCValues[k++] = (u8)((tmpVal > 255) ? | ||
652 | 255 : tmpVal); | ||
653 | ss++; | ||
654 | } | ||
655 | } | ||
656 | } | ||
657 | |||
658 | while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) { | ||
659 | pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT; | ||
660 | i++; | ||
661 | } | ||
662 | |||
663 | while (k < AR5416_NUM_PDADC_VALUES) { | ||
664 | pPDADCValues[k] = pPDADCValues[k - 1]; | ||
665 | k++; | ||
666 | } | ||
667 | |||
668 | return; | ||
669 | #undef TMP_VAL_VPD_TABLE | ||
670 | } | ||
671 | |||
672 | static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal *ah, | ||
330 | struct ath9k_channel *chan, | 673 | struct ath9k_channel *chan, |
331 | struct cal_data_per_freq *pRawDataSet, | 674 | struct cal_data_per_freq *pRawDataSet, |
332 | u8 *bChans, u16 availPiers, | 675 | u8 *bChans, u16 availPiers, |
@@ -603,12 +946,12 @@ static void ath9k_hw_get_target_powers(struct ath_hal *ah, | |||
603 | 946 | ||
604 | static u16 ath9k_hw_get_max_edge_power(u16 freq, | 947 | static u16 ath9k_hw_get_max_edge_power(u16 freq, |
605 | struct cal_ctl_edges *pRdEdgesPower, | 948 | struct cal_ctl_edges *pRdEdgesPower, |
606 | bool is2GHz) | 949 | bool is2GHz, int num_band_edges) |
607 | { | 950 | { |
608 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | 951 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; |
609 | int i; | 952 | int i; |
610 | 953 | ||
611 | for (i = 0; (i < AR5416_NUM_BAND_EDGES) && | 954 | for (i = 0; (i < num_band_edges) && |
612 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { | 955 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { |
613 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { | 956 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { |
614 | twiceMaxEdgePower = pRdEdgesPower[i].tPower; | 957 | twiceMaxEdgePower = pRdEdgesPower[i].tPower; |
@@ -629,207 +972,269 @@ static u16 ath9k_hw_get_max_edge_power(u16 freq, | |||
629 | return twiceMaxEdgePower; | 972 | return twiceMaxEdgePower; |
630 | } | 973 | } |
631 | 974 | ||
632 | int ath9k_hw_set_txpower(struct ath_hal *ah, | 975 | static bool ath9k_hw_set_def_power_cal_table(struct ath_hal *ah, |
633 | struct ath9k_channel *chan, | 976 | struct ath9k_channel *chan, |
634 | u16 cfgCtl, | 977 | int16_t *pTxPowerIndexOffset) |
635 | u8 twiceAntennaReduction, | ||
636 | u8 twiceMaxRegulatoryPower, | ||
637 | u8 powerLimit) | ||
638 | { | 978 | { |
639 | struct ath_hal_5416 *ahp = AH5416(ah); | 979 | struct ath_hal_5416 *ahp = AH5416(ah); |
640 | struct ar5416_eeprom *pEepData = &ahp->ah_eeprom; | 980 | struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def; |
641 | struct modal_eep_header *pModal = | 981 | struct cal_data_per_freq *pRawDataset; |
642 | &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); | 982 | u8 *pCalBChans = NULL; |
643 | int16_t ratesArray[Ar5416RateSize]; | 983 | u16 pdGainOverlap_t2; |
644 | int16_t txPowerIndexOffset = 0; | 984 | static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; |
645 | u8 ht40PowerIncForPdadc = 2; | 985 | u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; |
646 | int i; | 986 | u16 numPiers, i, j; |
987 | int16_t tMinCalPower; | ||
988 | u16 numXpdGain, xpdMask; | ||
989 | u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; | ||
990 | u32 reg32, regOffset, regChainOffset; | ||
991 | int16_t modalIdx; | ||
647 | 992 | ||
648 | memset(ratesArray, 0, sizeof(ratesArray)); | 993 | modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; |
994 | xpdMask = pEepData->modalHeader[modalIdx].xpdGain; | ||
649 | 995 | ||
650 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | 996 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= |
651 | AR5416_EEP_MINOR_VER_2) { | 997 | AR5416_EEP_MINOR_VER_2) { |
652 | ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; | 998 | pdGainOverlap_t2 = |
653 | } | 999 | pEepData->modalHeader[modalIdx].pdGainOverlap; |
654 | 1000 | } else { | |
655 | if (!ath9k_hw_set_power_per_rate_table(ah, chan, | 1001 | pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), |
656 | &ratesArray[0], cfgCtl, | 1002 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); |
657 | twiceAntennaReduction, | ||
658 | twiceMaxRegulatoryPower, | ||
659 | powerLimit)) { | ||
660 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
661 | "ath9k_hw_set_txpower: unable to set " | ||
662 | "tx power per rate table\n"); | ||
663 | return -EIO; | ||
664 | } | 1003 | } |
665 | 1004 | ||
666 | if (!ath9k_hw_set_power_cal_table(ah, chan, &txPowerIndexOffset)) { | 1005 | if (IS_CHAN_2GHZ(chan)) { |
667 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 1006 | pCalBChans = pEepData->calFreqPier2G; |
668 | "ath9k_hw_set_txpower: unable to set power table\n"); | 1007 | numPiers = AR5416_NUM_2G_CAL_PIERS; |
669 | return -EIO; | 1008 | } else { |
1009 | pCalBChans = pEepData->calFreqPier5G; | ||
1010 | numPiers = AR5416_NUM_5G_CAL_PIERS; | ||
670 | } | 1011 | } |
671 | 1012 | ||
672 | for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { | 1013 | numXpdGain = 0; |
673 | ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); | ||
674 | if (ratesArray[i] > AR5416_MAX_RATE_POWER) | ||
675 | ratesArray[i] = AR5416_MAX_RATE_POWER; | ||
676 | } | ||
677 | 1014 | ||
678 | if (AR_SREV_9280_10_OR_LATER(ah)) { | 1015 | for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { |
679 | for (i = 0; i < Ar5416RateSize; i++) | 1016 | if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { |
680 | ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; | 1017 | if (numXpdGain >= AR5416_NUM_PD_GAINS) |
1018 | break; | ||
1019 | xpdGainValues[numXpdGain] = | ||
1020 | (u16)(AR5416_PD_GAINS_IN_MASK - i); | ||
1021 | numXpdGain++; | ||
1022 | } | ||
681 | } | 1023 | } |
682 | 1024 | ||
683 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | 1025 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, |
684 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | 1026 | (numXpdGain - 1) & 0x3); |
685 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) | 1027 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, |
686 | | ATH9K_POW_SM(ratesArray[rate9mb], 8) | 1028 | xpdGainValues[0]); |
687 | | ATH9K_POW_SM(ratesArray[rate6mb], 0)); | 1029 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, |
688 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, | 1030 | xpdGainValues[1]); |
689 | ATH9K_POW_SM(ratesArray[rate54mb], 24) | 1031 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, |
690 | | ATH9K_POW_SM(ratesArray[rate48mb], 16) | 1032 | xpdGainValues[2]); |
691 | | ATH9K_POW_SM(ratesArray[rate36mb], 8) | ||
692 | | ATH9K_POW_SM(ratesArray[rate24mb], 0)); | ||
693 | 1033 | ||
694 | if (IS_CHAN_2GHZ(chan)) { | 1034 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { |
695 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, | 1035 | if (AR_SREV_5416_V20_OR_LATER(ah) && |
696 | ATH9K_POW_SM(ratesArray[rate2s], 24) | 1036 | (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) && |
697 | | ATH9K_POW_SM(ratesArray[rate2l], 16) | 1037 | (i != 0)) { |
698 | | ATH9K_POW_SM(ratesArray[rateXr], 8) | 1038 | regChainOffset = (i == 1) ? 0x2000 : 0x1000; |
699 | | ATH9K_POW_SM(ratesArray[rate1l], 0)); | 1039 | } else |
700 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, | 1040 | regChainOffset = i * 0x1000; |
701 | ATH9K_POW_SM(ratesArray[rate11s], 24) | ||
702 | | ATH9K_POW_SM(ratesArray[rate11l], 16) | ||
703 | | ATH9K_POW_SM(ratesArray[rate5_5s], 8) | ||
704 | | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); | ||
705 | } | ||
706 | 1041 | ||
707 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, | 1042 | if (pEepData->baseEepHeader.txMask & (1 << i)) { |
708 | ATH9K_POW_SM(ratesArray[rateHt20_3], 24) | 1043 | if (IS_CHAN_2GHZ(chan)) |
709 | | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) | 1044 | pRawDataset = pEepData->calPierData2G[i]; |
710 | | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) | 1045 | else |
711 | | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); | 1046 | pRawDataset = pEepData->calPierData5G[i]; |
712 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, | ||
713 | ATH9K_POW_SM(ratesArray[rateHt20_7], 24) | ||
714 | | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) | ||
715 | | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) | ||
716 | | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); | ||
717 | 1047 | ||
718 | if (IS_CHAN_HT40(chan)) { | 1048 | ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan, |
719 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, | 1049 | pRawDataset, pCalBChans, |
720 | ATH9K_POW_SM(ratesArray[rateHt40_3] + | 1050 | numPiers, pdGainOverlap_t2, |
721 | ht40PowerIncForPdadc, 24) | 1051 | &tMinCalPower, gainBoundaries, |
722 | | ATH9K_POW_SM(ratesArray[rateHt40_2] + | 1052 | pdadcValues, numXpdGain); |
723 | ht40PowerIncForPdadc, 16) | ||
724 | | ATH9K_POW_SM(ratesArray[rateHt40_1] + | ||
725 | ht40PowerIncForPdadc, 8) | ||
726 | | ATH9K_POW_SM(ratesArray[rateHt40_0] + | ||
727 | ht40PowerIncForPdadc, 0)); | ||
728 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, | ||
729 | ATH9K_POW_SM(ratesArray[rateHt40_7] + | ||
730 | ht40PowerIncForPdadc, 24) | ||
731 | | ATH9K_POW_SM(ratesArray[rateHt40_6] + | ||
732 | ht40PowerIncForPdadc, 16) | ||
733 | | ATH9K_POW_SM(ratesArray[rateHt40_5] + | ||
734 | ht40PowerIncForPdadc, 8) | ||
735 | | ATH9K_POW_SM(ratesArray[rateHt40_4] + | ||
736 | ht40PowerIncForPdadc, 0)); | ||
737 | 1053 | ||
738 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, | 1054 | if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { |
739 | ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | 1055 | REG_WRITE(ah, |
740 | | ATH9K_POW_SM(ratesArray[rateExtCck], 16) | 1056 | AR_PHY_TPCRG5 + regChainOffset, |
741 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | 1057 | SM(pdGainOverlap_t2, |
742 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); | 1058 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
743 | } | 1059 | | SM(gainBoundaries[0], |
1060 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | ||
1061 | | SM(gainBoundaries[1], | ||
1062 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | ||
1063 | | SM(gainBoundaries[2], | ||
1064 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | ||
1065 | | SM(gainBoundaries[3], | ||
1066 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); | ||
1067 | } | ||
744 | 1068 | ||
745 | REG_WRITE(ah, AR_PHY_POWER_TX_SUB, | 1069 | regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; |
746 | ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) | 1070 | for (j = 0; j < 32; j++) { |
747 | | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); | 1071 | reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | |
1072 | ((pdadcValues[4 * j + 1] & 0xFF) << 8) | | ||
1073 | ((pdadcValues[4 * j + 2] & 0xFF) << 16)| | ||
1074 | ((pdadcValues[4 * j + 3] & 0xFF) << 24); | ||
1075 | REG_WRITE(ah, regOffset, reg32); | ||
748 | 1076 | ||
749 | i = rate6mb; | 1077 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
1078 | "PDADC (%d,%4x): %4.4x %8.8x\n", | ||
1079 | i, regChainOffset, regOffset, | ||
1080 | reg32); | ||
1081 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
1082 | "PDADC: Chain %d | PDADC %3d " | ||
1083 | "Value %3d | PDADC %3d Value %3d | " | ||
1084 | "PDADC %3d Value %3d | PDADC %3d " | ||
1085 | "Value %3d |\n", | ||
1086 | i, 4 * j, pdadcValues[4 * j], | ||
1087 | 4 * j + 1, pdadcValues[4 * j + 1], | ||
1088 | 4 * j + 2, pdadcValues[4 * j + 2], | ||
1089 | 4 * j + 3, | ||
1090 | pdadcValues[4 * j + 3]); | ||
750 | 1091 | ||
751 | if (IS_CHAN_HT40(chan)) | 1092 | regOffset += 4; |
752 | i = rateHt40_0; | 1093 | } |
753 | else if (IS_CHAN_HT20(chan)) | 1094 | } |
754 | i = rateHt20_0; | 1095 | } |
755 | 1096 | ||
756 | if (AR_SREV_9280_10_OR_LATER(ah)) | 1097 | *pTxPowerIndexOffset = 0; |
757 | ah->ah_maxPowerLevel = | ||
758 | ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; | ||
759 | else | ||
760 | ah->ah_maxPowerLevel = ratesArray[i]; | ||
761 | 1098 | ||
762 | return 0; | 1099 | return true; |
763 | } | 1100 | } |
764 | 1101 | ||
765 | void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan) | 1102 | static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah, |
1103 | struct ath9k_channel *chan, | ||
1104 | int16_t *pTxPowerIndexOffset) | ||
766 | { | 1105 | { |
767 | struct modal_eep_header *pModal; | ||
768 | struct ath_hal_5416 *ahp = AH5416(ah); | 1106 | struct ath_hal_5416 *ahp = AH5416(ah); |
769 | struct ar5416_eeprom *eep = &ahp->ah_eeprom; | 1107 | struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k; |
770 | u8 biaslevel; | 1108 | struct cal_data_per_freq_4k *pRawDataset; |
1109 | u8 *pCalBChans = NULL; | ||
1110 | u16 pdGainOverlap_t2; | ||
1111 | static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; | ||
1112 | u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; | ||
1113 | u16 numPiers, i, j; | ||
1114 | int16_t tMinCalPower; | ||
1115 | u16 numXpdGain, xpdMask; | ||
1116 | u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; | ||
1117 | u32 reg32, regOffset, regChainOffset; | ||
771 | 1118 | ||
772 | if (ah->ah_macVersion != AR_SREV_VERSION_9160) | 1119 | xpdMask = pEepData->modalHeader.xpdGain; |
773 | return; | ||
774 | 1120 | ||
775 | if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7) | 1121 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= |
776 | return; | 1122 | AR5416_EEP_MINOR_VER_2) { |
1123 | pdGainOverlap_t2 = | ||
1124 | pEepData->modalHeader.pdGainOverlap; | ||
1125 | } else { | ||
1126 | pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), | ||
1127 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); | ||
1128 | } | ||
777 | 1129 | ||
778 | pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); | 1130 | pCalBChans = pEepData->calFreqPier2G; |
1131 | numPiers = AR5416_NUM_2G_CAL_PIERS; | ||
779 | 1132 | ||
780 | if (pModal->xpaBiasLvl != 0xff) { | 1133 | numXpdGain = 0; |
781 | biaslevel = pModal->xpaBiasLvl; | ||
782 | } else { | ||
783 | u16 resetFreqBin, freqBin, freqCount = 0; | ||
784 | struct chan_centers centers; | ||
785 | 1134 | ||
786 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | 1135 | for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { |
1136 | if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { | ||
1137 | if (numXpdGain >= AR5416_NUM_PD_GAINS) | ||
1138 | break; | ||
1139 | xpdGainValues[numXpdGain] = | ||
1140 | (u16)(AR5416_PD_GAINS_IN_MASK - i); | ||
1141 | numXpdGain++; | ||
1142 | } | ||
1143 | } | ||
787 | 1144 | ||
788 | resetFreqBin = FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)); | 1145 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, |
789 | freqBin = pModal->xpaBiasLvlFreq[0] & 0xff; | 1146 | (numXpdGain - 1) & 0x3); |
790 | biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14); | 1147 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, |
1148 | xpdGainValues[0]); | ||
1149 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, | ||
1150 | xpdGainValues[1]); | ||
1151 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, | ||
1152 | xpdGainValues[2]); | ||
791 | 1153 | ||
792 | freqCount++; | 1154 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { |
1155 | if (AR_SREV_5416_V20_OR_LATER(ah) && | ||
1156 | (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) && | ||
1157 | (i != 0)) { | ||
1158 | regChainOffset = (i == 1) ? 0x2000 : 0x1000; | ||
1159 | } else | ||
1160 | regChainOffset = i * 0x1000; | ||
793 | 1161 | ||
794 | while (freqCount < 3) { | 1162 | if (pEepData->baseEepHeader.txMask & (1 << i)) { |
795 | if (pModal->xpaBiasLvlFreq[freqCount] == 0x0) | 1163 | pRawDataset = pEepData->calPierData2G[i]; |
796 | break; | ||
797 | 1164 | ||
798 | freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff; | 1165 | ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan, |
799 | if (resetFreqBin >= freqBin) { | 1166 | pRawDataset, pCalBChans, |
800 | biaslevel = (u8)(pModal->xpaBiasLvlFreq[freqCount] >> 14); | 1167 | numPiers, pdGainOverlap_t2, |
801 | } else { | 1168 | &tMinCalPower, gainBoundaries, |
802 | break; | 1169 | pdadcValues, numXpdGain); |
1170 | |||
1171 | if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { | ||
1172 | REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, | ||
1173 | SM(pdGainOverlap_t2, | ||
1174 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | ||
1175 | | SM(gainBoundaries[0], | ||
1176 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | ||
1177 | | SM(gainBoundaries[1], | ||
1178 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | ||
1179 | | SM(gainBoundaries[2], | ||
1180 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | ||
1181 | | SM(gainBoundaries[3], | ||
1182 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); | ||
1183 | } | ||
1184 | |||
1185 | regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; | ||
1186 | for (j = 0; j < 32; j++) { | ||
1187 | reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | | ||
1188 | ((pdadcValues[4 * j + 1] & 0xFF) << 8) | | ||
1189 | ((pdadcValues[4 * j + 2] & 0xFF) << 16)| | ||
1190 | ((pdadcValues[4 * j + 3] & 0xFF) << 24); | ||
1191 | REG_WRITE(ah, regOffset, reg32); | ||
1192 | |||
1193 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
1194 | "PDADC (%d,%4x): %4.4x %8.8x\n", | ||
1195 | i, regChainOffset, regOffset, | ||
1196 | reg32); | ||
1197 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
1198 | "PDADC: Chain %d | " | ||
1199 | "PDADC %3d Value %3d | " | ||
1200 | "PDADC %3d Value %3d | " | ||
1201 | "PDADC %3d Value %3d | " | ||
1202 | "PDADC %3d Value %3d |\n", | ||
1203 | i, 4 * j, pdadcValues[4 * j], | ||
1204 | 4 * j + 1, pdadcValues[4 * j + 1], | ||
1205 | 4 * j + 2, pdadcValues[4 * j + 2], | ||
1206 | 4 * j + 3, | ||
1207 | pdadcValues[4 * j + 3]); | ||
1208 | |||
1209 | regOffset += 4; | ||
803 | } | 1210 | } |
804 | freqCount++; | ||
805 | } | 1211 | } |
806 | } | 1212 | } |
807 | 1213 | ||
808 | if (IS_CHAN_2GHZ(chan)) { | 1214 | *pTxPowerIndexOffset = 0; |
809 | INI_RA(&ahp->ah_iniAddac, 7, 1) = | 1215 | |
810 | (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; | 1216 | return true; |
811 | } else { | ||
812 | INI_RA(&ahp->ah_iniAddac, 6, 1) = | ||
813 | (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel << 6; | ||
814 | } | ||
815 | } | 1217 | } |
816 | 1218 | ||
817 | bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | 1219 | bool ath9k_hw_set_def_power_per_rate_table(struct ath_hal *ah, |
818 | struct ath9k_channel *chan, | 1220 | struct ath9k_channel *chan, |
819 | int16_t *ratesArray, | 1221 | int16_t *ratesArray, |
820 | u16 cfgCtl, | 1222 | u16 cfgCtl, |
821 | u8 AntennaReduction, | 1223 | u16 AntennaReduction, |
822 | u8 twiceMaxRegulatoryPower, | 1224 | u16 twiceMaxRegulatoryPower, |
823 | u8 powerLimit) | 1225 | u16 powerLimit) |
824 | { | 1226 | { |
1227 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ | ||
1228 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ | ||
1229 | |||
825 | struct ath_hal_5416 *ahp = AH5416(ah); | 1230 | struct ath_hal_5416 *ahp = AH5416(ah); |
826 | struct ar5416_eeprom *pEepData = &ahp->ah_eeprom; | 1231 | struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def; |
827 | u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | 1232 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; |
828 | static const u16 tpScaleReductionTable[5] = | 1233 | static const u16 tpScaleReductionTable[5] = |
829 | { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; | 1234 | { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; |
830 | 1235 | ||
831 | int i; | 1236 | int i; |
832 | int8_t twiceLargestAntenna; | 1237 | int16_t twiceLargestAntenna; |
833 | struct cal_ctl_data *rep; | 1238 | struct cal_ctl_data *rep; |
834 | struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { | 1239 | struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { |
835 | 0, { 0, 0, 0, 0} | 1240 | 0, { 0, 0, 0, 0} |
@@ -841,7 +1246,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
841 | struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { | 1246 | struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { |
842 | 0, {0, 0, 0, 0} | 1247 | 0, {0, 0, 0, 0} |
843 | }; | 1248 | }; |
844 | u8 scaledPower = 0, minCtlPower, maxRegAllowedPower; | 1249 | u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; |
845 | u16 ctlModesFor11a[] = | 1250 | u16 ctlModesFor11a[] = |
846 | { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 }; | 1251 | { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 }; |
847 | u16 ctlModesFor11g[] = | 1252 | u16 ctlModesFor11g[] = |
@@ -851,7 +1256,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
851 | u16 numCtlModes, *pCtlMode, ctlMode, freq; | 1256 | u16 numCtlModes, *pCtlMode, ctlMode, freq; |
852 | struct chan_centers centers; | 1257 | struct chan_centers centers; |
853 | int tx_chainmask; | 1258 | int tx_chainmask; |
854 | u8 twiceMinEdgePower; | 1259 | u16 twiceMinEdgePower; |
855 | 1260 | ||
856 | tx_chainmask = ahp->ah_txchainmask; | 1261 | tx_chainmask = ahp->ah_txchainmask; |
857 | 1262 | ||
@@ -867,7 +1272,8 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
867 | pEepData->modalHeader | 1272 | pEepData->modalHeader |
868 | [IS_CHAN_2GHZ(chan)].antennaGainCh[2]); | 1273 | [IS_CHAN_2GHZ(chan)].antennaGainCh[2]); |
869 | 1274 | ||
870 | twiceLargestAntenna = (int8_t)min(AntennaReduction - twiceLargestAntenna, 0); | 1275 | twiceLargestAntenna = (int16_t)min(AntennaReduction - |
1276 | twiceLargestAntenna, 0); | ||
871 | 1277 | ||
872 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; | 1278 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; |
873 | 1279 | ||
@@ -882,16 +1288,14 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
882 | case 1: | 1288 | case 1: |
883 | break; | 1289 | break; |
884 | case 2: | 1290 | case 2: |
885 | scaledPower -= | 1291 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; |
886 | pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain; | ||
887 | break; | 1292 | break; |
888 | case 3: | 1293 | case 3: |
889 | scaledPower -= | 1294 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; |
890 | pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain; | ||
891 | break; | 1295 | break; |
892 | } | 1296 | } |
893 | 1297 | ||
894 | scaledPower = max(0, (int32_t) scaledPower); | 1298 | scaledPower = max((u16)0, scaledPower); |
895 | 1299 | ||
896 | if (IS_CHAN_2GHZ(chan)) { | 1300 | if (IS_CHAN_2GHZ(chan)) { |
897 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - | 1301 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - |
@@ -990,7 +1394,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
990 | 1394 | ||
991 | twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq, | 1395 | twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq, |
992 | rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1], | 1396 | rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1], |
993 | IS_CHAN_2GHZ(chan)); | 1397 | IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); |
994 | 1398 | ||
995 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, | 1399 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, |
996 | " MATCH-EE_IDX %d: ch %d is2 %d " | 1400 | " MATCH-EE_IDX %d: ch %d is2 %d " |
@@ -1021,7 +1425,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
1021 | case CTL_11B: | 1425 | case CTL_11B: |
1022 | for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { | 1426 | for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { |
1023 | targetPowerCck.tPow2x[i] = | 1427 | targetPowerCck.tPow2x[i] = |
1024 | min(targetPowerCck.tPow2x[i], | 1428 | min((u16)targetPowerCck.tPow2x[i], |
1025 | minCtlPower); | 1429 | minCtlPower); |
1026 | } | 1430 | } |
1027 | break; | 1431 | break; |
@@ -1029,7 +1433,7 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
1029 | case CTL_11G: | 1433 | case CTL_11G: |
1030 | for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { | 1434 | for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { |
1031 | targetPowerOfdm.tPow2x[i] = | 1435 | targetPowerOfdm.tPow2x[i] = |
1032 | min(targetPowerOfdm.tPow2x[i], | 1436 | min((u16)targetPowerOfdm.tPow2x[i], |
1033 | minCtlPower); | 1437 | minCtlPower); |
1034 | } | 1438 | } |
1035 | break; | 1439 | break; |
@@ -1037,24 +1441,26 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
1037 | case CTL_2GHT20: | 1441 | case CTL_2GHT20: |
1038 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { | 1442 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { |
1039 | targetPowerHt20.tPow2x[i] = | 1443 | targetPowerHt20.tPow2x[i] = |
1040 | min(targetPowerHt20.tPow2x[i], | 1444 | min((u16)targetPowerHt20.tPow2x[i], |
1041 | minCtlPower); | 1445 | minCtlPower); |
1042 | } | 1446 | } |
1043 | break; | 1447 | break; |
1044 | case CTL_11B_EXT: | 1448 | case CTL_11B_EXT: |
1045 | targetPowerCckExt.tPow2x[0] = | 1449 | targetPowerCckExt.tPow2x[0] = min((u16) |
1046 | min(targetPowerCckExt.tPow2x[0], minCtlPower); | 1450 | targetPowerCckExt.tPow2x[0], |
1451 | minCtlPower); | ||
1047 | break; | 1452 | break; |
1048 | case CTL_11A_EXT: | 1453 | case CTL_11A_EXT: |
1049 | case CTL_11G_EXT: | 1454 | case CTL_11G_EXT: |
1050 | targetPowerOfdmExt.tPow2x[0] = | 1455 | targetPowerOfdmExt.tPow2x[0] = min((u16) |
1051 | min(targetPowerOfdmExt.tPow2x[0], minCtlPower); | 1456 | targetPowerOfdmExt.tPow2x[0], |
1457 | minCtlPower); | ||
1052 | break; | 1458 | break; |
1053 | case CTL_5GHT40: | 1459 | case CTL_5GHT40: |
1054 | case CTL_2GHT40: | 1460 | case CTL_2GHT40: |
1055 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { | 1461 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { |
1056 | targetPowerHt40.tPow2x[i] = | 1462 | targetPowerHt40.tPow2x[i] = |
1057 | min(targetPowerHt40.tPow2x[i], | 1463 | min((u16)targetPowerHt40.tPow2x[i], |
1058 | minCtlPower); | 1464 | minCtlPower); |
1059 | } | 1465 | } |
1060 | break; | 1466 | break; |
@@ -1101,139 +1507,623 @@ bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, | |||
1101 | return true; | 1507 | return true; |
1102 | } | 1508 | } |
1103 | 1509 | ||
1104 | bool ath9k_hw_set_power_cal_table(struct ath_hal *ah, | 1510 | bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah, |
1105 | struct ath9k_channel *chan, | 1511 | struct ath9k_channel *chan, |
1106 | int16_t *pTxPowerIndexOffset) | 1512 | int16_t *ratesArray, |
1513 | u16 cfgCtl, | ||
1514 | u16 AntennaReduction, | ||
1515 | u16 twiceMaxRegulatoryPower, | ||
1516 | u16 powerLimit) | ||
1107 | { | 1517 | { |
1108 | struct ath_hal_5416 *ahp = AH5416(ah); | 1518 | struct ath_hal_5416 *ahp = AH5416(ah); |
1109 | struct ar5416_eeprom *pEepData = &ahp->ah_eeprom; | 1519 | struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k; |
1110 | struct cal_data_per_freq *pRawDataset; | 1520 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; |
1111 | u8 *pCalBChans = NULL; | 1521 | static const u16 tpScaleReductionTable[5] = |
1112 | u16 pdGainOverlap_t2; | 1522 | { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; |
1113 | static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; | ||
1114 | u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; | ||
1115 | u16 numPiers, i, j; | ||
1116 | int16_t tMinCalPower; | ||
1117 | u16 numXpdGain, xpdMask; | ||
1118 | u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; | ||
1119 | u32 reg32, regOffset, regChainOffset; | ||
1120 | int16_t modalIdx; | ||
1121 | 1523 | ||
1122 | modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; | 1524 | int i; |
1123 | xpdMask = pEepData->modalHeader[modalIdx].xpdGain; | 1525 | int16_t twiceLargestAntenna; |
1526 | struct cal_ctl_data_4k *rep; | ||
1527 | struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { | ||
1528 | 0, { 0, 0, 0, 0} | ||
1529 | }; | ||
1530 | struct cal_target_power_leg targetPowerOfdmExt = { | ||
1531 | 0, { 0, 0, 0, 0} }, targetPowerCckExt = { | ||
1532 | 0, { 0, 0, 0, 0 } | ||
1533 | }; | ||
1534 | struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { | ||
1535 | 0, {0, 0, 0, 0} | ||
1536 | }; | ||
1537 | u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; | ||
1538 | u16 ctlModesFor11g[] = | ||
1539 | { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, | ||
1540 | CTL_2GHT40 | ||
1541 | }; | ||
1542 | u16 numCtlModes, *pCtlMode, ctlMode, freq; | ||
1543 | struct chan_centers centers; | ||
1544 | int tx_chainmask; | ||
1545 | u16 twiceMinEdgePower; | ||
1546 | |||
1547 | tx_chainmask = ahp->ah_txchainmask; | ||
1548 | |||
1549 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
1550 | |||
1551 | twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0]; | ||
1552 | |||
1553 | twiceLargestAntenna = (int16_t)min(AntennaReduction - | ||
1554 | twiceLargestAntenna, 0); | ||
1555 | |||
1556 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; | ||
1557 | |||
1558 | if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) { | ||
1559 | maxRegAllowedPower -= | ||
1560 | (tpScaleReductionTable[(ah->ah_tpScale)] * 2); | ||
1561 | } | ||
1562 | |||
1563 | scaledPower = min(powerLimit, maxRegAllowedPower); | ||
1564 | scaledPower = max((u16)0, scaledPower); | ||
1565 | |||
1566 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; | ||
1567 | pCtlMode = ctlModesFor11g; | ||
1568 | |||
1569 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
1570 | pEepData->calTargetPowerCck, | ||
1571 | AR5416_NUM_2G_CCK_TARGET_POWERS, | ||
1572 | &targetPowerCck, 4, false); | ||
1573 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
1574 | pEepData->calTargetPower2G, | ||
1575 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
1576 | &targetPowerOfdm, 4, false); | ||
1577 | ath9k_hw_get_target_powers(ah, chan, | ||
1578 | pEepData->calTargetPower2GHT20, | ||
1579 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
1580 | &targetPowerHt20, 8, false); | ||
1581 | |||
1582 | if (IS_CHAN_HT40(chan)) { | ||
1583 | numCtlModes = ARRAY_SIZE(ctlModesFor11g); | ||
1584 | ath9k_hw_get_target_powers(ah, chan, | ||
1585 | pEepData->calTargetPower2GHT40, | ||
1586 | AR5416_NUM_2G_40_TARGET_POWERS, | ||
1587 | &targetPowerHt40, 8, true); | ||
1588 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
1589 | pEepData->calTargetPowerCck, | ||
1590 | AR5416_NUM_2G_CCK_TARGET_POWERS, | ||
1591 | &targetPowerCckExt, 4, true); | ||
1592 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
1593 | pEepData->calTargetPower2G, | ||
1594 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
1595 | &targetPowerOfdmExt, 4, true); | ||
1596 | } | ||
1597 | |||
1598 | for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { | ||
1599 | bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || | ||
1600 | (pCtlMode[ctlMode] == CTL_2GHT40); | ||
1601 | if (isHt40CtlMode) | ||
1602 | freq = centers.synth_center; | ||
1603 | else if (pCtlMode[ctlMode] & EXT_ADDITIVE) | ||
1604 | freq = centers.ext_center; | ||
1605 | else | ||
1606 | freq = centers.ctl_center; | ||
1607 | |||
1608 | if (ar5416_get_eep_ver(ahp) == 14 && | ||
1609 | ar5416_get_eep_rev(ahp) <= 2) | ||
1610 | twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | ||
1611 | |||
1612 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, | ||
1613 | "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " | ||
1614 | "EXT_ADDITIVE %d\n", | ||
1615 | ctlMode, numCtlModes, isHt40CtlMode, | ||
1616 | (pCtlMode[ctlMode] & EXT_ADDITIVE)); | ||
1617 | |||
1618 | for (i = 0; (i < AR5416_NUM_CTLS) && | ||
1619 | pEepData->ctlIndex[i]; i++) { | ||
1620 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, | ||
1621 | " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " | ||
1622 | "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " | ||
1623 | "chan %d\n", | ||
1624 | i, cfgCtl, pCtlMode[ctlMode], | ||
1625 | pEepData->ctlIndex[i], chan->channel); | ||
1626 | |||
1627 | if ((((cfgCtl & ~CTL_MODE_M) | | ||
1628 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
1629 | pEepData->ctlIndex[i]) || | ||
1630 | (((cfgCtl & ~CTL_MODE_M) | | ||
1631 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
1632 | ((pEepData->ctlIndex[i] & CTL_MODE_M) | | ||
1633 | SD_NO_CTL))) { | ||
1634 | rep = &(pEepData->ctlData[i]); | ||
1635 | |||
1636 | twiceMinEdgePower = | ||
1637 | ath9k_hw_get_max_edge_power(freq, | ||
1638 | rep->ctlEdges[ar5416_get_ntxchains | ||
1639 | (tx_chainmask) - 1], | ||
1640 | IS_CHAN_2GHZ(chan), | ||
1641 | AR5416_EEP4K_NUM_BAND_EDGES); | ||
1642 | |||
1643 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, | ||
1644 | " MATCH-EE_IDX %d: ch %d is2 %d " | ||
1645 | "2xMinEdge %d chainmask %d chains %d\n", | ||
1646 | i, freq, IS_CHAN_2GHZ(chan), | ||
1647 | twiceMinEdgePower, tx_chainmask, | ||
1648 | ar5416_get_ntxchains | ||
1649 | (tx_chainmask)); | ||
1650 | if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { | ||
1651 | twiceMaxEdgePower = | ||
1652 | min(twiceMaxEdgePower, | ||
1653 | twiceMinEdgePower); | ||
1654 | } else { | ||
1655 | twiceMaxEdgePower = twiceMinEdgePower; | ||
1656 | break; | ||
1657 | } | ||
1658 | } | ||
1659 | } | ||
1660 | |||
1661 | minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); | ||
1662 | |||
1663 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, | ||
1664 | " SEL-Min ctlMode %d pCtlMode %d " | ||
1665 | "2xMaxEdge %d sP %d minCtlPwr %d\n", | ||
1666 | ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, | ||
1667 | scaledPower, minCtlPower); | ||
1668 | |||
1669 | switch (pCtlMode[ctlMode]) { | ||
1670 | case CTL_11B: | ||
1671 | for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); | ||
1672 | i++) { | ||
1673 | targetPowerCck.tPow2x[i] = | ||
1674 | min((u16)targetPowerCck.tPow2x[i], | ||
1675 | minCtlPower); | ||
1676 | } | ||
1677 | break; | ||
1678 | case CTL_11G: | ||
1679 | for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); | ||
1680 | i++) { | ||
1681 | targetPowerOfdm.tPow2x[i] = | ||
1682 | min((u16)targetPowerOfdm.tPow2x[i], | ||
1683 | minCtlPower); | ||
1684 | } | ||
1685 | break; | ||
1686 | case CTL_2GHT20: | ||
1687 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); | ||
1688 | i++) { | ||
1689 | targetPowerHt20.tPow2x[i] = | ||
1690 | min((u16)targetPowerHt20.tPow2x[i], | ||
1691 | minCtlPower); | ||
1692 | } | ||
1693 | break; | ||
1694 | case CTL_11B_EXT: | ||
1695 | targetPowerCckExt.tPow2x[0] = min((u16) | ||
1696 | targetPowerCckExt.tPow2x[0], | ||
1697 | minCtlPower); | ||
1698 | break; | ||
1699 | case CTL_11G_EXT: | ||
1700 | targetPowerOfdmExt.tPow2x[0] = min((u16) | ||
1701 | targetPowerOfdmExt.tPow2x[0], | ||
1702 | minCtlPower); | ||
1703 | break; | ||
1704 | case CTL_2GHT40: | ||
1705 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); | ||
1706 | i++) { | ||
1707 | targetPowerHt40.tPow2x[i] = | ||
1708 | min((u16)targetPowerHt40.tPow2x[i], | ||
1709 | minCtlPower); | ||
1710 | } | ||
1711 | break; | ||
1712 | default: | ||
1713 | break; | ||
1714 | } | ||
1715 | } | ||
1716 | |||
1717 | ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = | ||
1718 | ratesArray[rate18mb] = ratesArray[rate24mb] = | ||
1719 | targetPowerOfdm.tPow2x[0]; | ||
1720 | ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; | ||
1721 | ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; | ||
1722 | ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; | ||
1723 | ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; | ||
1724 | |||
1725 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) | ||
1726 | ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; | ||
1727 | |||
1728 | ratesArray[rate1l] = targetPowerCck.tPow2x[0]; | ||
1729 | ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; | ||
1730 | ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; | ||
1731 | ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; | ||
1732 | |||
1733 | if (IS_CHAN_HT40(chan)) { | ||
1734 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { | ||
1735 | ratesArray[rateHt40_0 + i] = | ||
1736 | targetPowerHt40.tPow2x[i]; | ||
1737 | } | ||
1738 | ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; | ||
1739 | ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; | ||
1740 | ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; | ||
1741 | ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; | ||
1742 | } | ||
1743 | return true; | ||
1744 | } | ||
1745 | |||
1746 | static int ath9k_hw_def_set_txpower(struct ath_hal *ah, | ||
1747 | struct ath9k_channel *chan, | ||
1748 | u16 cfgCtl, | ||
1749 | u8 twiceAntennaReduction, | ||
1750 | u8 twiceMaxRegulatoryPower, | ||
1751 | u8 powerLimit) | ||
1752 | { | ||
1753 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
1754 | struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def; | ||
1755 | struct modal_eep_header *pModal = | ||
1756 | &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); | ||
1757 | int16_t ratesArray[Ar5416RateSize]; | ||
1758 | int16_t txPowerIndexOffset = 0; | ||
1759 | u8 ht40PowerIncForPdadc = 2; | ||
1760 | int i; | ||
1761 | |||
1762 | memset(ratesArray, 0, sizeof(ratesArray)); | ||
1124 | 1763 | ||
1125 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | 1764 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= |
1126 | AR5416_EEP_MINOR_VER_2) { | 1765 | AR5416_EEP_MINOR_VER_2) { |
1127 | pdGainOverlap_t2 = | 1766 | ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; |
1128 | pEepData->modalHeader[modalIdx].pdGainOverlap; | 1767 | } |
1129 | } else { | 1768 | |
1130 | pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), | 1769 | if (!ath9k_hw_set_def_power_per_rate_table(ah, chan, |
1131 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); | 1770 | &ratesArray[0], cfgCtl, |
1771 | twiceAntennaReduction, | ||
1772 | twiceMaxRegulatoryPower, | ||
1773 | powerLimit)) { | ||
1774 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1775 | "ath9k_hw_set_txpower: unable to set " | ||
1776 | "tx power per rate table\n"); | ||
1777 | return -EIO; | ||
1778 | } | ||
1779 | |||
1780 | if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) { | ||
1781 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1782 | "ath9k_hw_set_txpower: unable to set power table\n"); | ||
1783 | return -EIO; | ||
1784 | } | ||
1785 | |||
1786 | for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { | ||
1787 | ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); | ||
1788 | if (ratesArray[i] > AR5416_MAX_RATE_POWER) | ||
1789 | ratesArray[i] = AR5416_MAX_RATE_POWER; | ||
1132 | } | 1790 | } |
1133 | 1791 | ||
1792 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1793 | for (i = 0; i < Ar5416RateSize; i++) | ||
1794 | ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; | ||
1795 | } | ||
1796 | |||
1797 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | ||
1798 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | ||
1799 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) | ||
1800 | | ATH9K_POW_SM(ratesArray[rate9mb], 8) | ||
1801 | | ATH9K_POW_SM(ratesArray[rate6mb], 0)); | ||
1802 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, | ||
1803 | ATH9K_POW_SM(ratesArray[rate54mb], 24) | ||
1804 | | ATH9K_POW_SM(ratesArray[rate48mb], 16) | ||
1805 | | ATH9K_POW_SM(ratesArray[rate36mb], 8) | ||
1806 | | ATH9K_POW_SM(ratesArray[rate24mb], 0)); | ||
1807 | |||
1134 | if (IS_CHAN_2GHZ(chan)) { | 1808 | if (IS_CHAN_2GHZ(chan)) { |
1135 | pCalBChans = pEepData->calFreqPier2G; | 1809 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, |
1136 | numPiers = AR5416_NUM_2G_CAL_PIERS; | 1810 | ATH9K_POW_SM(ratesArray[rate2s], 24) |
1137 | } else { | 1811 | | ATH9K_POW_SM(ratesArray[rate2l], 16) |
1138 | pCalBChans = pEepData->calFreqPier5G; | 1812 | | ATH9K_POW_SM(ratesArray[rateXr], 8) |
1139 | numPiers = AR5416_NUM_5G_CAL_PIERS; | 1813 | | ATH9K_POW_SM(ratesArray[rate1l], 0)); |
1814 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, | ||
1815 | ATH9K_POW_SM(ratesArray[rate11s], 24) | ||
1816 | | ATH9K_POW_SM(ratesArray[rate11l], 16) | ||
1817 | | ATH9K_POW_SM(ratesArray[rate5_5s], 8) | ||
1818 | | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); | ||
1140 | } | 1819 | } |
1141 | 1820 | ||
1142 | numXpdGain = 0; | 1821 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, |
1822 | ATH9K_POW_SM(ratesArray[rateHt20_3], 24) | ||
1823 | | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) | ||
1824 | | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) | ||
1825 | | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); | ||
1826 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, | ||
1827 | ATH9K_POW_SM(ratesArray[rateHt20_7], 24) | ||
1828 | | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) | ||
1829 | | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) | ||
1830 | | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); | ||
1143 | 1831 | ||
1144 | for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { | 1832 | if (IS_CHAN_HT40(chan)) { |
1145 | if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { | 1833 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, |
1146 | if (numXpdGain >= AR5416_NUM_PD_GAINS) | 1834 | ATH9K_POW_SM(ratesArray[rateHt40_3] + |
1147 | break; | 1835 | ht40PowerIncForPdadc, 24) |
1148 | xpdGainValues[numXpdGain] = | 1836 | | ATH9K_POW_SM(ratesArray[rateHt40_2] + |
1149 | (u16)(AR5416_PD_GAINS_IN_MASK - i); | 1837 | ht40PowerIncForPdadc, 16) |
1150 | numXpdGain++; | 1838 | | ATH9K_POW_SM(ratesArray[rateHt40_1] + |
1151 | } | 1839 | ht40PowerIncForPdadc, 8) |
1840 | | ATH9K_POW_SM(ratesArray[rateHt40_0] + | ||
1841 | ht40PowerIncForPdadc, 0)); | ||
1842 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, | ||
1843 | ATH9K_POW_SM(ratesArray[rateHt40_7] + | ||
1844 | ht40PowerIncForPdadc, 24) | ||
1845 | | ATH9K_POW_SM(ratesArray[rateHt40_6] + | ||
1846 | ht40PowerIncForPdadc, 16) | ||
1847 | | ATH9K_POW_SM(ratesArray[rateHt40_5] + | ||
1848 | ht40PowerIncForPdadc, 8) | ||
1849 | | ATH9K_POW_SM(ratesArray[rateHt40_4] + | ||
1850 | ht40PowerIncForPdadc, 0)); | ||
1851 | |||
1852 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, | ||
1853 | ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ||
1854 | | ATH9K_POW_SM(ratesArray[rateExtCck], 16) | ||
1855 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ||
1856 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); | ||
1152 | } | 1857 | } |
1153 | 1858 | ||
1154 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, | 1859 | REG_WRITE(ah, AR_PHY_POWER_TX_SUB, |
1155 | (numXpdGain - 1) & 0x3); | 1860 | ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) |
1156 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, | 1861 | | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); |
1157 | xpdGainValues[0]); | ||
1158 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, | ||
1159 | xpdGainValues[1]); | ||
1160 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, | ||
1161 | xpdGainValues[2]); | ||
1162 | 1862 | ||
1163 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | 1863 | i = rate6mb; |
1164 | if (AR_SREV_5416_V20_OR_LATER(ah) && | ||
1165 | (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) && | ||
1166 | (i != 0)) { | ||
1167 | regChainOffset = (i == 1) ? 0x2000 : 0x1000; | ||
1168 | } else | ||
1169 | regChainOffset = i * 0x1000; | ||
1170 | 1864 | ||
1171 | if (pEepData->baseEepHeader.txMask & (1 << i)) { | 1865 | if (IS_CHAN_HT40(chan)) |
1172 | if (IS_CHAN_2GHZ(chan)) | 1866 | i = rateHt40_0; |
1173 | pRawDataset = pEepData->calPierData2G[i]; | 1867 | else if (IS_CHAN_HT20(chan)) |
1174 | else | 1868 | i = rateHt20_0; |
1175 | pRawDataset = pEepData->calPierData5G[i]; | ||
1176 | 1869 | ||
1177 | ath9k_hw_get_gain_boundaries_pdadcs(ah, chan, | 1870 | if (AR_SREV_9280_10_OR_LATER(ah)) |
1178 | pRawDataset, pCalBChans, | 1871 | ah->ah_maxPowerLevel = |
1179 | numPiers, pdGainOverlap_t2, | 1872 | ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; |
1180 | &tMinCalPower, gainBoundaries, | 1873 | else |
1181 | pdadcValues, numXpdGain); | 1874 | ah->ah_maxPowerLevel = ratesArray[i]; |
1182 | 1875 | ||
1183 | if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { | 1876 | return 0; |
1184 | REG_WRITE(ah, | 1877 | } |
1185 | AR_PHY_TPCRG5 + regChainOffset, | ||
1186 | SM(pdGainOverlap_t2, | ||
1187 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | ||
1188 | | SM(gainBoundaries[0], | ||
1189 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | ||
1190 | | SM(gainBoundaries[1], | ||
1191 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | ||
1192 | | SM(gainBoundaries[2], | ||
1193 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | ||
1194 | | SM(gainBoundaries[3], | ||
1195 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); | ||
1196 | } | ||
1197 | 1878 | ||
1198 | regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; | 1879 | static int ath9k_hw_4k_set_txpower(struct ath_hal *ah, |
1199 | for (j = 0; j < 32; j++) { | 1880 | struct ath9k_channel *chan, |
1200 | reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | | 1881 | u16 cfgCtl, |
1201 | ((pdadcValues[4 * j + 1] & 0xFF) << 8) | | 1882 | u8 twiceAntennaReduction, |
1202 | ((pdadcValues[4 * j + 2] & 0xFF) << 16) | | 1883 | u8 twiceMaxRegulatoryPower, |
1203 | ((pdadcValues[4 * j + 3] & 0xFF) << 24); | 1884 | u8 powerLimit) |
1204 | REG_WRITE(ah, regOffset, reg32); | 1885 | { |
1886 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
1887 | struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k; | ||
1888 | struct modal_eep_4k_header *pModal = &pEepData->modalHeader; | ||
1889 | int16_t ratesArray[Ar5416RateSize]; | ||
1890 | int16_t txPowerIndexOffset = 0; | ||
1891 | u8 ht40PowerIncForPdadc = 2; | ||
1892 | int i; | ||
1205 | 1893 | ||
1206 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | 1894 | memset(ratesArray, 0, sizeof(ratesArray)); |
1207 | "PDADC (%d,%4x): %4.4x %8.8x\n", | ||
1208 | i, regChainOffset, regOffset, | ||
1209 | reg32); | ||
1210 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
1211 | "PDADC: Chain %d | PDADC %3d Value %3d | " | ||
1212 | "PDADC %3d Value %3d | PDADC %3d Value %3d | " | ||
1213 | "PDADC %3d Value %3d |\n", | ||
1214 | i, 4 * j, pdadcValues[4 * j], | ||
1215 | 4 * j + 1, pdadcValues[4 * j + 1], | ||
1216 | 4 * j + 2, pdadcValues[4 * j + 2], | ||
1217 | 4 * j + 3, | ||
1218 | pdadcValues[4 * j + 3]); | ||
1219 | 1895 | ||
1220 | regOffset += 4; | 1896 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= |
1221 | } | 1897 | AR5416_EEP_MINOR_VER_2) { |
1898 | ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; | ||
1899 | } | ||
1900 | |||
1901 | if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan, | ||
1902 | &ratesArray[0], cfgCtl, | ||
1903 | twiceAntennaReduction, | ||
1904 | twiceMaxRegulatoryPower, | ||
1905 | powerLimit)) { | ||
1906 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1907 | "ath9k_hw_set_txpower: unable to set " | ||
1908 | "tx power per rate table\n"); | ||
1909 | return -EIO; | ||
1910 | } | ||
1911 | |||
1912 | if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) { | ||
1913 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1914 | "ath9k_hw_set_txpower: unable to set power table\n"); | ||
1915 | return -EIO; | ||
1916 | } | ||
1917 | |||
1918 | for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { | ||
1919 | ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); | ||
1920 | if (ratesArray[i] > AR5416_MAX_RATE_POWER) | ||
1921 | ratesArray[i] = AR5416_MAX_RATE_POWER; | ||
1922 | } | ||
1923 | |||
1924 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1925 | for (i = 0; i < Ar5416RateSize; i++) | ||
1926 | ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; | ||
1927 | } | ||
1928 | |||
1929 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | ||
1930 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | ||
1931 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) | ||
1932 | | ATH9K_POW_SM(ratesArray[rate9mb], 8) | ||
1933 | | ATH9K_POW_SM(ratesArray[rate6mb], 0)); | ||
1934 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, | ||
1935 | ATH9K_POW_SM(ratesArray[rate54mb], 24) | ||
1936 | | ATH9K_POW_SM(ratesArray[rate48mb], 16) | ||
1937 | | ATH9K_POW_SM(ratesArray[rate36mb], 8) | ||
1938 | | ATH9K_POW_SM(ratesArray[rate24mb], 0)); | ||
1939 | |||
1940 | if (IS_CHAN_2GHZ(chan)) { | ||
1941 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, | ||
1942 | ATH9K_POW_SM(ratesArray[rate2s], 24) | ||
1943 | | ATH9K_POW_SM(ratesArray[rate2l], 16) | ||
1944 | | ATH9K_POW_SM(ratesArray[rateXr], 8) | ||
1945 | | ATH9K_POW_SM(ratesArray[rate1l], 0)); | ||
1946 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, | ||
1947 | ATH9K_POW_SM(ratesArray[rate11s], 24) | ||
1948 | | ATH9K_POW_SM(ratesArray[rate11l], 16) | ||
1949 | | ATH9K_POW_SM(ratesArray[rate5_5s], 8) | ||
1950 | | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); | ||
1951 | } | ||
1952 | |||
1953 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, | ||
1954 | ATH9K_POW_SM(ratesArray[rateHt20_3], 24) | ||
1955 | | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) | ||
1956 | | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) | ||
1957 | | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); | ||
1958 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, | ||
1959 | ATH9K_POW_SM(ratesArray[rateHt20_7], 24) | ||
1960 | | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) | ||
1961 | | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) | ||
1962 | | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); | ||
1963 | |||
1964 | if (IS_CHAN_HT40(chan)) { | ||
1965 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, | ||
1966 | ATH9K_POW_SM(ratesArray[rateHt40_3] + | ||
1967 | ht40PowerIncForPdadc, 24) | ||
1968 | | ATH9K_POW_SM(ratesArray[rateHt40_2] + | ||
1969 | ht40PowerIncForPdadc, 16) | ||
1970 | | ATH9K_POW_SM(ratesArray[rateHt40_1] + | ||
1971 | ht40PowerIncForPdadc, 8) | ||
1972 | | ATH9K_POW_SM(ratesArray[rateHt40_0] + | ||
1973 | ht40PowerIncForPdadc, 0)); | ||
1974 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, | ||
1975 | ATH9K_POW_SM(ratesArray[rateHt40_7] + | ||
1976 | ht40PowerIncForPdadc, 24) | ||
1977 | | ATH9K_POW_SM(ratesArray[rateHt40_6] + | ||
1978 | ht40PowerIncForPdadc, 16) | ||
1979 | | ATH9K_POW_SM(ratesArray[rateHt40_5] + | ||
1980 | ht40PowerIncForPdadc, 8) | ||
1981 | | ATH9K_POW_SM(ratesArray[rateHt40_4] + | ||
1982 | ht40PowerIncForPdadc, 0)); | ||
1983 | |||
1984 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, | ||
1985 | ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ||
1986 | | ATH9K_POW_SM(ratesArray[rateExtCck], 16) | ||
1987 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ||
1988 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); | ||
1989 | } | ||
1990 | |||
1991 | i = rate6mb; | ||
1992 | |||
1993 | if (IS_CHAN_HT40(chan)) | ||
1994 | i = rateHt40_0; | ||
1995 | else if (IS_CHAN_HT20(chan)) | ||
1996 | i = rateHt20_0; | ||
1997 | |||
1998 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
1999 | ah->ah_maxPowerLevel = | ||
2000 | ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; | ||
2001 | else | ||
2002 | ah->ah_maxPowerLevel = ratesArray[i]; | ||
2003 | |||
2004 | return 0; | ||
2005 | } | ||
2006 | |||
2007 | int (*ath9k_set_txpower[]) (struct ath_hal *, | ||
2008 | struct ath9k_channel *, | ||
2009 | u16, u8, u8, u8) = { | ||
2010 | ath9k_hw_def_set_txpower, | ||
2011 | ath9k_hw_4k_set_txpower | ||
2012 | }; | ||
2013 | |||
2014 | int ath9k_hw_set_txpower(struct ath_hal *ah, | ||
2015 | struct ath9k_channel *chan, | ||
2016 | u16 cfgCtl, | ||
2017 | u8 twiceAntennaReduction, | ||
2018 | u8 twiceMaxRegulatoryPower, | ||
2019 | u8 powerLimit) | ||
2020 | { | ||
2021 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2022 | |||
2023 | return ath9k_set_txpower[ahp->ah_eep_map](ah, chan, cfgCtl, | ||
2024 | twiceAntennaReduction, twiceMaxRegulatoryPower, | ||
2025 | powerLimit); | ||
2026 | } | ||
2027 | |||
2028 | static void ath9k_hw_set_def_addac(struct ath_hal *ah, | ||
2029 | struct ath9k_channel *chan) | ||
2030 | { | ||
2031 | #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) | ||
2032 | struct modal_eep_header *pModal; | ||
2033 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2034 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; | ||
2035 | u8 biaslevel; | ||
2036 | |||
2037 | if (ah->ah_macVersion != AR_SREV_VERSION_9160) | ||
2038 | return; | ||
2039 | |||
2040 | if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7) | ||
2041 | return; | ||
2042 | |||
2043 | pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); | ||
2044 | |||
2045 | if (pModal->xpaBiasLvl != 0xff) { | ||
2046 | biaslevel = pModal->xpaBiasLvl; | ||
2047 | } else { | ||
2048 | u16 resetFreqBin, freqBin, freqCount = 0; | ||
2049 | struct chan_centers centers; | ||
2050 | |||
2051 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
2052 | |||
2053 | resetFreqBin = FREQ2FBIN(centers.synth_center, | ||
2054 | IS_CHAN_2GHZ(chan)); | ||
2055 | freqBin = XPA_LVL_FREQ(0) & 0xff; | ||
2056 | biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14); | ||
2057 | |||
2058 | freqCount++; | ||
2059 | |||
2060 | while (freqCount < 3) { | ||
2061 | if (XPA_LVL_FREQ(freqCount) == 0x0) | ||
2062 | break; | ||
2063 | |||
2064 | freqBin = XPA_LVL_FREQ(freqCount) & 0xff; | ||
2065 | if (resetFreqBin >= freqBin) | ||
2066 | biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14); | ||
2067 | else | ||
2068 | break; | ||
2069 | freqCount++; | ||
1222 | } | 2070 | } |
1223 | } | 2071 | } |
1224 | 2072 | ||
1225 | *pTxPowerIndexOffset = 0; | 2073 | if (IS_CHAN_2GHZ(chan)) { |
2074 | INI_RA(&ahp->ah_iniAddac, 7, 1) = (INI_RA(&ahp->ah_iniAddac, | ||
2075 | 7, 1) & (~0x18)) | biaslevel << 3; | ||
2076 | } else { | ||
2077 | INI_RA(&ahp->ah_iniAddac, 6, 1) = (INI_RA(&ahp->ah_iniAddac, | ||
2078 | 6, 1) & (~0xc0)) | biaslevel << 6; | ||
2079 | } | ||
2080 | #undef XPA_LVL_FREQ | ||
2081 | } | ||
1226 | 2082 | ||
1227 | return true; | 2083 | static void ath9k_hw_set_4k_addac(struct ath_hal *ah, |
2084 | struct ath9k_channel *chan) | ||
2085 | { | ||
2086 | struct modal_eep_4k_header *pModal; | ||
2087 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2088 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; | ||
2089 | u8 biaslevel; | ||
2090 | |||
2091 | if (ah->ah_macVersion != AR_SREV_VERSION_9160) | ||
2092 | return; | ||
2093 | |||
2094 | if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7) | ||
2095 | return; | ||
2096 | |||
2097 | pModal = &eep->modalHeader; | ||
2098 | |||
2099 | if (pModal->xpaBiasLvl != 0xff) { | ||
2100 | biaslevel = pModal->xpaBiasLvl; | ||
2101 | INI_RA(&ahp->ah_iniAddac, 7, 1) = | ||
2102 | (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; | ||
2103 | } | ||
2104 | } | ||
2105 | |||
2106 | void (*ath9k_set_addac[]) (struct ath_hal *, struct ath9k_channel *) = { | ||
2107 | ath9k_hw_set_def_addac, | ||
2108 | ath9k_hw_set_4k_addac | ||
2109 | }; | ||
2110 | |||
2111 | void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan) | ||
2112 | { | ||
2113 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2114 | |||
2115 | ath9k_set_addac[ahp->ah_eep_map](ah, chan); | ||
1228 | } | 2116 | } |
1229 | 2117 | ||
2118 | |||
2119 | |||
1230 | /* XXX: Clean me up, make me more legible */ | 2120 | /* XXX: Clean me up, make me more legible */ |
1231 | bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, | 2121 | static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah, |
1232 | struct ath9k_channel *chan) | 2122 | struct ath9k_channel *chan) |
1233 | { | 2123 | { |
1234 | struct modal_eep_header *pModal; | 2124 | struct modal_eep_header *pModal; |
1235 | struct ath_hal_5416 *ahp = AH5416(ah); | 2125 | struct ath_hal_5416 *ahp = AH5416(ah); |
1236 | struct ar5416_eeprom *eep = &ahp->ah_eeprom; | 2126 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; |
1237 | int i, regChainOffset; | 2127 | int i, regChainOffset; |
1238 | u8 txRxAttenLocal; | 2128 | u8 txRxAttenLocal; |
1239 | u16 ant_config; | 2129 | u16 ant_config; |
@@ -1462,12 +2352,214 @@ bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, | |||
1462 | return true; | 2352 | return true; |
1463 | } | 2353 | } |
1464 | 2354 | ||
1465 | int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah, | 2355 | static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah, |
2356 | struct ath9k_channel *chan) | ||
2357 | { | ||
2358 | struct modal_eep_4k_header *pModal; | ||
2359 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2360 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; | ||
2361 | int regChainOffset; | ||
2362 | u8 txRxAttenLocal; | ||
2363 | u16 ant_config = 0; | ||
2364 | u8 ob[5], db1[5], db2[5]; | ||
2365 | u8 ant_div_control1, ant_div_control2; | ||
2366 | u32 regVal; | ||
2367 | |||
2368 | |||
2369 | pModal = &eep->modalHeader; | ||
2370 | |||
2371 | txRxAttenLocal = 23; | ||
2372 | |||
2373 | ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config); | ||
2374 | REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config); | ||
2375 | |||
2376 | regChainOffset = 0; | ||
2377 | REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, | ||
2378 | pModal->antCtrlChain[0]); | ||
2379 | |||
2380 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, | ||
2381 | (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & | ||
2382 | ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | | ||
2383 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | | ||
2384 | SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | | ||
2385 | SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); | ||
2386 | |||
2387 | if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
2388 | AR5416_EEP_MINOR_VER_3) { | ||
2389 | txRxAttenLocal = pModal->txRxAttenCh[0]; | ||
2390 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
2391 | AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]); | ||
2392 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
2393 | AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); | ||
2394 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
2395 | AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, | ||
2396 | pModal->xatten2Margin[0]); | ||
2397 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
2398 | AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); | ||
2399 | } | ||
2400 | |||
2401 | REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, | ||
2402 | AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); | ||
2403 | REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, | ||
2404 | AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); | ||
2405 | |||
2406 | if (AR_SREV_9285_11(ah)) | ||
2407 | REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); | ||
2408 | |||
2409 | /* Initialize Ant Diversity settings from EEPROM */ | ||
2410 | if (pModal->version == 3) { | ||
2411 | ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf); | ||
2412 | ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf); | ||
2413 | regVal = REG_READ(ah, 0x99ac); | ||
2414 | regVal &= (~(0x7f000000)); | ||
2415 | regVal |= ((ant_div_control1 & 0x1) << 24); | ||
2416 | regVal |= (((ant_div_control1 >> 1) & 0x1) << 29); | ||
2417 | regVal |= (((ant_div_control1 >> 2) & 0x1) << 30); | ||
2418 | regVal |= ((ant_div_control2 & 0x3) << 25); | ||
2419 | regVal |= (((ant_div_control2 >> 2) & 0x3) << 27); | ||
2420 | REG_WRITE(ah, 0x99ac, regVal); | ||
2421 | regVal = REG_READ(ah, 0x99ac); | ||
2422 | regVal = REG_READ(ah, 0xa208); | ||
2423 | regVal &= (~(0x1 << 13)); | ||
2424 | regVal |= (((ant_div_control1 >> 3) & 0x1) << 13); | ||
2425 | REG_WRITE(ah, 0xa208, regVal); | ||
2426 | regVal = REG_READ(ah, 0xa208); | ||
2427 | } | ||
2428 | |||
2429 | if (pModal->version >= 2) { | ||
2430 | ob[0] = (pModal->ob_01 & 0xf); | ||
2431 | ob[1] = (pModal->ob_01 >> 4) & 0xf; | ||
2432 | ob[2] = (pModal->ob_234 & 0xf); | ||
2433 | ob[3] = ((pModal->ob_234 >> 4) & 0xf); | ||
2434 | ob[4] = ((pModal->ob_234 >> 8) & 0xf); | ||
2435 | |||
2436 | db1[0] = (pModal->db1_01 & 0xf); | ||
2437 | db1[1] = ((pModal->db1_01 >> 4) & 0xf); | ||
2438 | db1[2] = (pModal->db1_234 & 0xf); | ||
2439 | db1[3] = ((pModal->db1_234 >> 4) & 0xf); | ||
2440 | db1[4] = ((pModal->db1_234 >> 8) & 0xf); | ||
2441 | |||
2442 | db2[0] = (pModal->db2_01 & 0xf); | ||
2443 | db2[1] = ((pModal->db2_01 >> 4) & 0xf); | ||
2444 | db2[2] = (pModal->db2_234 & 0xf); | ||
2445 | db2[3] = ((pModal->db2_234 >> 4) & 0xf); | ||
2446 | db2[4] = ((pModal->db2_234 >> 8) & 0xf); | ||
2447 | |||
2448 | } else if (pModal->version == 1) { | ||
2449 | |||
2450 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2451 | "EEPROM Model version is set to 1 \n"); | ||
2452 | ob[0] = (pModal->ob_01 & 0xf); | ||
2453 | ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf; | ||
2454 | db1[0] = (pModal->db1_01 & 0xf); | ||
2455 | db1[1] = db1[2] = db1[3] = | ||
2456 | db1[4] = ((pModal->db1_01 >> 4) & 0xf); | ||
2457 | db2[0] = (pModal->db2_01 & 0xf); | ||
2458 | db2[1] = db2[2] = db2[3] = | ||
2459 | db2[4] = ((pModal->db2_01 >> 4) & 0xf); | ||
2460 | } else { | ||
2461 | int i; | ||
2462 | for (i = 0; i < 5; i++) { | ||
2463 | ob[i] = pModal->ob_01; | ||
2464 | db1[i] = pModal->db1_01; | ||
2465 | db2[i] = pModal->db1_01; | ||
2466 | } | ||
2467 | } | ||
2468 | |||
2469 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
2470 | AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]); | ||
2471 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
2472 | AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]); | ||
2473 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
2474 | AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]); | ||
2475 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
2476 | AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]); | ||
2477 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
2478 | AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]); | ||
2479 | |||
2480 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
2481 | AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]); | ||
2482 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
2483 | AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]); | ||
2484 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
2485 | AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]); | ||
2486 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
2487 | AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]); | ||
2488 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
2489 | AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]); | ||
2490 | |||
2491 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
2492 | AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]); | ||
2493 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
2494 | AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]); | ||
2495 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
2496 | AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]); | ||
2497 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
2498 | AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]); | ||
2499 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
2500 | AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]); | ||
2501 | |||
2502 | |||
2503 | if (AR_SREV_9285_11(ah)) | ||
2504 | REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); | ||
2505 | |||
2506 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, | ||
2507 | pModal->switchSettling); | ||
2508 | REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, | ||
2509 | pModal->adcDesiredSize); | ||
2510 | |||
2511 | REG_WRITE(ah, AR_PHY_RF_CTL4, | ||
2512 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | | ||
2513 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | | ||
2514 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | | ||
2515 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); | ||
2516 | |||
2517 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, | ||
2518 | pModal->txEndToRxOn); | ||
2519 | REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, | ||
2520 | pModal->thresh62); | ||
2521 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, | ||
2522 | pModal->thresh62); | ||
2523 | |||
2524 | if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
2525 | AR5416_EEP_MINOR_VER_2) { | ||
2526 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, | ||
2527 | pModal->txFrameToDataStart); | ||
2528 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, | ||
2529 | pModal->txFrameToPaOn); | ||
2530 | } | ||
2531 | |||
2532 | if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
2533 | AR5416_EEP_MINOR_VER_3) { | ||
2534 | if (IS_CHAN_HT40(chan)) | ||
2535 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, | ||
2536 | AR_PHY_SETTLING_SWITCH, | ||
2537 | pModal->swSettleHt40); | ||
2538 | } | ||
2539 | |||
2540 | return true; | ||
2541 | } | ||
2542 | |||
2543 | bool (*ath9k_eeprom_set_board_values[])(struct ath_hal *, | ||
2544 | struct ath9k_channel *) = { | ||
2545 | ath9k_hw_eeprom_set_def_board_values, | ||
2546 | ath9k_hw_eeprom_set_4k_board_values | ||
2547 | }; | ||
2548 | |||
2549 | bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, | ||
2550 | struct ath9k_channel *chan) | ||
2551 | { | ||
2552 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2553 | |||
2554 | return ath9k_eeprom_set_board_values[ahp->ah_eep_map](ah, chan); | ||
2555 | } | ||
2556 | |||
2557 | static int ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah, | ||
1466 | struct ath9k_channel *chan, | 2558 | struct ath9k_channel *chan, |
1467 | u8 index, u16 *config) | 2559 | u8 index, u16 *config) |
1468 | { | 2560 | { |
1469 | struct ath_hal_5416 *ahp = AH5416(ah); | 2561 | struct ath_hal_5416 *ahp = AH5416(ah); |
1470 | struct ar5416_eeprom *eep = &ahp->ah_eeprom; | 2562 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; |
1471 | struct modal_eep_header *pModal = | 2563 | struct modal_eep_header *pModal = |
1472 | &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); | 2564 | &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); |
1473 | struct base_eep_header *pBase = &eep->baseEepHeader; | 2565 | struct base_eep_header *pBase = &eep->baseEepHeader; |
@@ -1492,11 +2584,52 @@ int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah, | |||
1492 | return -EINVAL; | 2584 | return -EINVAL; |
1493 | } | 2585 | } |
1494 | 2586 | ||
1495 | u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah, | 2587 | static int ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah, |
2588 | struct ath9k_channel *chan, | ||
2589 | u8 index, u16 *config) | ||
2590 | { | ||
2591 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2592 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; | ||
2593 | struct modal_eep_4k_header *pModal = &eep->modalHeader; | ||
2594 | |||
2595 | switch (index) { | ||
2596 | case 0: | ||
2597 | *config = pModal->antCtrlCommon & 0xFFFF; | ||
2598 | return 0; | ||
2599 | default: | ||
2600 | break; | ||
2601 | } | ||
2602 | |||
2603 | return -EINVAL; | ||
2604 | } | ||
2605 | |||
2606 | int (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hal *, struct ath9k_channel *, | ||
2607 | u8, u16 *) = { | ||
2608 | ath9k_hw_get_def_eeprom_antenna_cfg, | ||
2609 | ath9k_hw_get_4k_eeprom_antenna_cfg | ||
2610 | }; | ||
2611 | |||
2612 | int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah, | ||
2613 | struct ath9k_channel *chan, | ||
2614 | u8 index, u16 *config) | ||
2615 | { | ||
2616 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2617 | |||
2618 | return ath9k_get_eeprom_antenna_cfg[ahp->ah_eep_map](ah, chan, | ||
2619 | index, config); | ||
2620 | } | ||
2621 | |||
2622 | u8 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah, | ||
2623 | enum ieee80211_band freq_band) | ||
2624 | { | ||
2625 | return 1; | ||
2626 | } | ||
2627 | |||
2628 | u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah, | ||
1496 | enum ieee80211_band freq_band) | 2629 | enum ieee80211_band freq_band) |
1497 | { | 2630 | { |
1498 | struct ath_hal_5416 *ahp = AH5416(ah); | 2631 | struct ath_hal_5416 *ahp = AH5416(ah); |
1499 | struct ar5416_eeprom *eep = &ahp->ah_eeprom; | 2632 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; |
1500 | struct modal_eep_header *pModal = | 2633 | struct modal_eep_header *pModal = |
1501 | &(eep->modalHeader[IEEE80211_BAND_5GHZ == freq_band]); | 2634 | &(eep->modalHeader[IEEE80211_BAND_5GHZ == freq_band]); |
1502 | struct base_eep_header *pBase = &eep->baseEepHeader; | 2635 | struct base_eep_header *pBase = &eep->baseEepHeader; |
@@ -1511,11 +2644,26 @@ u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah, | |||
1511 | return num_ant_config; | 2644 | return num_ant_config; |
1512 | } | 2645 | } |
1513 | 2646 | ||
2647 | u8 (*ath9k_get_num_ant_config[])(struct ath_hal *, enum ieee80211_band) = { | ||
2648 | ath9k_hw_get_def_num_ant_config, | ||
2649 | ath9k_hw_get_4k_num_ant_config | ||
2650 | }; | ||
2651 | |||
2652 | u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah, | ||
2653 | enum ieee80211_band freq_band) | ||
2654 | { | ||
2655 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2656 | |||
2657 | return ath9k_get_num_ant_config[ahp->ah_eep_map](ah, freq_band); | ||
2658 | } | ||
2659 | |||
1514 | u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz) | 2660 | u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz) |
1515 | { | 2661 | { |
2662 | #define EEP_MAP4K_SPURCHAN \ | ||
2663 | (ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan) | ||
2664 | #define EEP_DEF_SPURCHAN \ | ||
2665 | (ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan) | ||
1516 | struct ath_hal_5416 *ahp = AH5416(ah); | 2666 | struct ath_hal_5416 *ahp = AH5416(ah); |
1517 | struct ar5416_eeprom *eep = | ||
1518 | (struct ar5416_eeprom *) &ahp->ah_eeprom; | ||
1519 | u16 spur_val = AR_NO_SPUR; | 2667 | u16 spur_val = AR_NO_SPUR; |
1520 | 2668 | ||
1521 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 2669 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
@@ -1531,19 +2679,66 @@ u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz) | |||
1531 | "Getting spur val from new loc. %d\n", spur_val); | 2679 | "Getting spur val from new loc. %d\n", spur_val); |
1532 | break; | 2680 | break; |
1533 | case SPUR_ENABLE_EEPROM: | 2681 | case SPUR_ENABLE_EEPROM: |
1534 | spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan; | 2682 | if (ahp->ah_eep_map == EEP_MAP_4KBITS) |
2683 | spur_val = EEP_MAP4K_SPURCHAN; | ||
2684 | else | ||
2685 | spur_val = EEP_DEF_SPURCHAN; | ||
1535 | break; | 2686 | break; |
1536 | 2687 | ||
1537 | } | 2688 | } |
1538 | 2689 | ||
1539 | return spur_val; | 2690 | return spur_val; |
2691 | #undef EEP_DEF_SPURCHAN | ||
2692 | #undef EEP_MAP4K_SPURCHAN | ||
1540 | } | 2693 | } |
1541 | 2694 | ||
1542 | u32 ath9k_hw_get_eeprom(struct ath_hal *ah, | 2695 | static u32 ath9k_hw_get_eeprom_4k(struct ath_hal *ah, |
1543 | enum eeprom_param param) | 2696 | enum eeprom_param param) |
2697 | { | ||
2698 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2699 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; | ||
2700 | struct modal_eep_4k_header *pModal = &eep->modalHeader; | ||
2701 | struct base_eep_header_4k *pBase = &eep->baseEepHeader; | ||
2702 | |||
2703 | switch (param) { | ||
2704 | case EEP_NFTHRESH_2: | ||
2705 | return pModal[1].noiseFloorThreshCh[0]; | ||
2706 | case AR_EEPROM_MAC(0): | ||
2707 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; | ||
2708 | case AR_EEPROM_MAC(1): | ||
2709 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; | ||
2710 | case AR_EEPROM_MAC(2): | ||
2711 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; | ||
2712 | case EEP_REG_0: | ||
2713 | return pBase->regDmn[0]; | ||
2714 | case EEP_REG_1: | ||
2715 | return pBase->regDmn[1]; | ||
2716 | case EEP_OP_CAP: | ||
2717 | return pBase->deviceCap; | ||
2718 | case EEP_OP_MODE: | ||
2719 | return pBase->opCapFlags; | ||
2720 | case EEP_RF_SILENT: | ||
2721 | return pBase->rfSilent; | ||
2722 | case EEP_OB_2: | ||
2723 | return pModal->ob_01; | ||
2724 | case EEP_DB_2: | ||
2725 | return pModal->db1_01; | ||
2726 | case EEP_MINOR_REV: | ||
2727 | return pBase->version & AR5416_EEP_VER_MINOR_MASK; | ||
2728 | case EEP_TX_MASK: | ||
2729 | return pBase->txMask; | ||
2730 | case EEP_RX_MASK: | ||
2731 | return pBase->rxMask; | ||
2732 | default: | ||
2733 | return 0; | ||
2734 | } | ||
2735 | } | ||
2736 | |||
2737 | static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah, | ||
2738 | enum eeprom_param param) | ||
1544 | { | 2739 | { |
1545 | struct ath_hal_5416 *ahp = AH5416(ah); | 2740 | struct ath_hal_5416 *ahp = AH5416(ah); |
1546 | struct ar5416_eeprom *eep = &ahp->ah_eeprom; | 2741 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; |
1547 | struct modal_eep_header *pModal = eep->modalHeader; | 2742 | struct modal_eep_header *pModal = eep->modalHeader; |
1548 | struct base_eep_header *pBase = &eep->baseEepHeader; | 2743 | struct base_eep_header *pBase = &eep->baseEepHeader; |
1549 | 2744 | ||
@@ -1592,13 +2787,32 @@ u32 ath9k_hw_get_eeprom(struct ath_hal *ah, | |||
1592 | } | 2787 | } |
1593 | } | 2788 | } |
1594 | 2789 | ||
2790 | u32 (*ath9k_get_eeprom[])(struct ath_hal *, enum eeprom_param) = { | ||
2791 | ath9k_hw_get_eeprom_def, | ||
2792 | ath9k_hw_get_eeprom_4k | ||
2793 | }; | ||
2794 | |||
2795 | u32 ath9k_hw_get_eeprom(struct ath_hal *ah, | ||
2796 | enum eeprom_param param) | ||
2797 | { | ||
2798 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
2799 | |||
2800 | return ath9k_get_eeprom[ahp->ah_eep_map](ah, param); | ||
2801 | } | ||
2802 | |||
1595 | int ath9k_hw_eeprom_attach(struct ath_hal *ah) | 2803 | int ath9k_hw_eeprom_attach(struct ath_hal *ah) |
1596 | { | 2804 | { |
1597 | int status; | 2805 | int status; |
2806 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
1598 | 2807 | ||
1599 | if (ath9k_hw_use_flash(ah)) | 2808 | if (ath9k_hw_use_flash(ah)) |
1600 | ath9k_hw_flash_map(ah); | 2809 | ath9k_hw_flash_map(ah); |
1601 | 2810 | ||
2811 | if (AR_SREV_9285(ah)) | ||
2812 | ahp->ah_eep_map = EEP_MAP_4KBITS; | ||
2813 | else | ||
2814 | ahp->ah_eep_map = EEP_MAP_DEFAULT; | ||
2815 | |||
1602 | if (!ath9k_hw_fill_eeprom(ah)) | 2816 | if (!ath9k_hw_fill_eeprom(ah)) |
1603 | return -EIO; | 2817 | return -EIO; |
1604 | 2818 | ||
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 2176fa8e91e..e95dfa0a030 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c | |||
@@ -37,7 +37,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type); | |||
37 | static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, | 37 | static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, |
38 | enum ath9k_ht_macmode macmode); | 38 | enum ath9k_ht_macmode macmode); |
39 | static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, | 39 | static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, |
40 | struct ar5416_eeprom *pEepData, | 40 | struct ar5416_eeprom_def *pEepData, |
41 | u32 reg, u32 value); | 41 | u32 reg, u32 value); |
42 | static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); | 42 | static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); |
43 | static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); | 43 | static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); |
@@ -392,6 +392,8 @@ static const char *ath9k_hw_devname(u16 devid) | |||
392 | case AR9280_DEVID_PCI: | 392 | case AR9280_DEVID_PCI: |
393 | case AR9280_DEVID_PCIE: | 393 | case AR9280_DEVID_PCIE: |
394 | return "Atheros 9280"; | 394 | return "Atheros 9280"; |
395 | case AR9285_DEVID_PCIE: | ||
396 | return "Atheros 9285"; | ||
395 | } | 397 | } |
396 | 398 | ||
397 | return NULL; | 399 | return NULL; |
@@ -682,7 +684,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
682 | if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) && | 684 | if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) && |
683 | (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) && | 685 | (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) && |
684 | (ah->ah_macVersion != AR_SREV_VERSION_9160) && | 686 | (ah->ah_macVersion != AR_SREV_VERSION_9160) && |
685 | (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) { | 687 | (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) { |
686 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 688 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
687 | "Mac Chip Rev 0x%02x.%x is not supported by " | 689 | "Mac Chip Rev 0x%02x.%x is not supported by " |
688 | "this driver\n", ah->ah_macVersion, ah->ah_macRev); | 690 | "this driver\n", ah->ah_macVersion, ah->ah_macRev); |
@@ -733,7 +735,38 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
733 | "This Mac Chip Rev 0x%02x.%x is \n", | 735 | "This Mac Chip Rev 0x%02x.%x is \n", |
734 | ah->ah_macVersion, ah->ah_macRev); | 736 | ah->ah_macVersion, ah->ah_macRev); |
735 | 737 | ||
736 | if (AR_SREV_9280_20_OR_LATER(ah)) { | 738 | if (AR_SREV_9285_12_OR_LATER(ah)) { |
739 | INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2, | ||
740 | ARRAY_SIZE(ar9285Modes_9285_1_2), 6); | ||
741 | INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2, | ||
742 | ARRAY_SIZE(ar9285Common_9285_1_2), 2); | ||
743 | |||
744 | if (ah->ah_config.pcie_clock_req) { | ||
745 | INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, | ||
746 | ar9285PciePhy_clkreq_off_L1_9285_1_2, | ||
747 | ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2); | ||
748 | } else { | ||
749 | INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, | ||
750 | ar9285PciePhy_clkreq_always_on_L1_9285_1_2, | ||
751 | ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), | ||
752 | 2); | ||
753 | } | ||
754 | } else if (AR_SREV_9285_10_OR_LATER(ah)) { | ||
755 | INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285, | ||
756 | ARRAY_SIZE(ar9285Modes_9285), 6); | ||
757 | INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285, | ||
758 | ARRAY_SIZE(ar9285Common_9285), 2); | ||
759 | |||
760 | if (ah->ah_config.pcie_clock_req) { | ||
761 | INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, | ||
762 | ar9285PciePhy_clkreq_off_L1_9285, | ||
763 | ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2); | ||
764 | } else { | ||
765 | INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, | ||
766 | ar9285PciePhy_clkreq_always_on_L1_9285, | ||
767 | ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2); | ||
768 | } | ||
769 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
737 | INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2, | 770 | INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2, |
738 | ARRAY_SIZE(ar9280Modes_9280_2), 6); | 771 | ARRAY_SIZE(ar9280Modes_9280_2), 6); |
739 | INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2, | 772 | INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2, |
@@ -843,11 +876,11 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
843 | goto bad; | 876 | goto bad; |
844 | 877 | ||
845 | /* rxgain table */ | 878 | /* rxgain table */ |
846 | if (AR_SREV_9280_20_OR_LATER(ah)) | 879 | if (AR_SREV_9280_20(ah)) |
847 | ath9k_hw_init_rxgain_ini(ah); | 880 | ath9k_hw_init_rxgain_ini(ah); |
848 | 881 | ||
849 | /* txgain table */ | 882 | /* txgain table */ |
850 | if (AR_SREV_9280_20_OR_LATER(ah)) | 883 | if (AR_SREV_9280_20(ah)) |
851 | ath9k_hw_init_txgain_ini(ah); | 884 | ath9k_hw_init_txgain_ini(ah); |
852 | 885 | ||
853 | if (ah->ah_devid == AR9280_DEVID_PCI) { | 886 | if (ah->ah_devid == AR9280_DEVID_PCI) { |
@@ -858,7 +891,8 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
858 | u32 val = INI_RA(&ahp->ah_iniModes, i, j); | 891 | u32 val = INI_RA(&ahp->ah_iniModes, i, j); |
859 | 892 | ||
860 | INI_RA(&ahp->ah_iniModes, i, j) = | 893 | INI_RA(&ahp->ah_iniModes, i, j) = |
861 | ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, | 894 | ath9k_hw_ini_fixup(ah, |
895 | &ahp->ah_eeprom.def, | ||
862 | reg, val); | 896 | reg, val); |
863 | } | 897 | } |
864 | } | 898 | } |
@@ -1016,8 +1050,6 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah) | |||
1016 | } | 1050 | } |
1017 | case 0x1: | 1051 | case 0x1: |
1018 | case 0x2: | 1052 | case 0x2: |
1019 | if (!AR_SREV_9280(ah)) | ||
1020 | break; | ||
1021 | case 0x7: | 1053 | case 0x7: |
1022 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); | 1054 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); |
1023 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); | 1055 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); |
@@ -1162,12 +1194,10 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc, | |||
1162 | case AR9160_DEVID_PCI: | 1194 | case AR9160_DEVID_PCI: |
1163 | case AR9280_DEVID_PCI: | 1195 | case AR9280_DEVID_PCI: |
1164 | case AR9280_DEVID_PCIE: | 1196 | case AR9280_DEVID_PCIE: |
1197 | case AR9285_DEVID_PCIE: | ||
1165 | ah = ath9k_hw_do_attach(devid, sc, mem, error); | 1198 | ah = ath9k_hw_do_attach(devid, sc, mem, error); |
1166 | break; | 1199 | break; |
1167 | default: | 1200 | default: |
1168 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | ||
1169 | "devid=0x%x not supported.\n", devid); | ||
1170 | ah = NULL; | ||
1171 | *error = -ENXIO; | 1201 | *error = -ENXIO; |
1172 | break; | 1202 | break; |
1173 | } | 1203 | } |
@@ -1189,8 +1219,8 @@ static void ath9k_hw_override_ini(struct ath_hal *ah, | |||
1189 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); | 1219 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); |
1190 | } | 1220 | } |
1191 | 1221 | ||
1192 | static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, | 1222 | static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah, |
1193 | struct ar5416_eeprom *pEepData, | 1223 | struct ar5416_eeprom_def *pEepData, |
1194 | u32 reg, u32 value) | 1224 | u32 reg, u32 value) |
1195 | { | 1225 | { |
1196 | struct base_eep_header *pBase = &(pEepData->baseEepHeader); | 1226 | struct base_eep_header *pBase = &(pEepData->baseEepHeader); |
@@ -1223,6 +1253,18 @@ static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, | |||
1223 | return value; | 1253 | return value; |
1224 | } | 1254 | } |
1225 | 1255 | ||
1256 | static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, | ||
1257 | struct ar5416_eeprom_def *pEepData, | ||
1258 | u32 reg, u32 value) | ||
1259 | { | ||
1260 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
1261 | |||
1262 | if (ahp->ah_eep_map == EEP_MAP_4KBITS) | ||
1263 | return value; | ||
1264 | else | ||
1265 | return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value); | ||
1266 | } | ||
1267 | |||
1226 | static int ath9k_hw_process_ini(struct ath_hal *ah, | 1268 | static int ath9k_hw_process_ini(struct ath_hal *ah, |
1227 | struct ath9k_channel *chan, | 1269 | struct ath9k_channel *chan, |
1228 | enum ath9k_ht_macmode macmode) | 1270 | enum ath9k_ht_macmode macmode) |
@@ -1300,10 +1342,10 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, | |||
1300 | DO_DELAY(regWrites); | 1342 | DO_DELAY(regWrites); |
1301 | } | 1343 | } |
1302 | 1344 | ||
1303 | if (AR_SREV_9280_20_OR_LATER(ah)) | 1345 | if (AR_SREV_9280(ah)) |
1304 | REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites); | 1346 | REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites); |
1305 | 1347 | ||
1306 | if (AR_SREV_9280_20_OR_LATER(ah)) | 1348 | if (AR_SREV_9280(ah)) |
1307 | REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites); | 1349 | REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites); |
1308 | 1350 | ||
1309 | for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) { | 1351 | for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) { |
@@ -1576,10 +1618,15 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, | |||
1576 | enum ath9k_ht_macmode macmode) | 1618 | enum ath9k_ht_macmode macmode) |
1577 | { | 1619 | { |
1578 | u32 phymode; | 1620 | u32 phymode; |
1621 | u32 enableDacFifo = 0; | ||
1579 | struct ath_hal_5416 *ahp = AH5416(ah); | 1622 | struct ath_hal_5416 *ahp = AH5416(ah); |
1580 | 1623 | ||
1624 | if (AR_SREV_9285_10_OR_LATER(ah)) | ||
1625 | enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & | ||
1626 | AR_PHY_FC_ENABLE_DAC_FIFO); | ||
1627 | |||
1581 | phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 | 1628 | phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 |
1582 | | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH; | 1629 | | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; |
1583 | 1630 | ||
1584 | if (IS_CHAN_HT40(chan)) { | 1631 | if (IS_CHAN_HT40(chan)) { |
1585 | phymode |= AR_PHY_FC_DYN2040_EN; | 1632 | phymode |= AR_PHY_FC_DYN2040_EN; |
@@ -2762,11 +2809,14 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore) | |||
2762 | if (ah->ah_config.pcie_waen) { | 2809 | if (ah->ah_config.pcie_waen) { |
2763 | REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen); | 2810 | REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen); |
2764 | } else { | 2811 | } else { |
2765 | if (AR_SREV_9280(ah)) | 2812 | if (AR_SREV_9285(ah)) |
2766 | REG_WRITE(ah, AR_WA, 0x0040073f); | 2813 | REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); |
2814 | else if (AR_SREV_9280(ah)) | ||
2815 | REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT); | ||
2767 | else | 2816 | else |
2768 | REG_WRITE(ah, AR_WA, 0x0000073f); | 2817 | REG_WRITE(ah, AR_WA, AR_WA_DEFAULT); |
2769 | } | 2818 | } |
2819 | |||
2770 | } | 2820 | } |
2771 | 2821 | ||
2772 | /**********************/ | 2822 | /**********************/ |
@@ -3317,7 +3367,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) | |||
3317 | else | 3367 | else |
3318 | pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; | 3368 | pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; |
3319 | 3369 | ||
3320 | if (AR_SREV_9280(ah)) | 3370 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) |
3321 | pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; | 3371 | pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; |
3322 | else | 3372 | else |
3323 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; | 3373 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; |
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h index 02256c3ec07..a4d52850bdd 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath9k/hw.h | |||
@@ -448,6 +448,17 @@ struct ar5416Stats { | |||
448 | #define AR5416_EEP_TXGAIN_ORIGINAL 0 | 448 | #define AR5416_EEP_TXGAIN_ORIGINAL 0 |
449 | #define AR5416_EEP_TXGAIN_HIGH_POWER 1 | 449 | #define AR5416_EEP_TXGAIN_HIGH_POWER 1 |
450 | 450 | ||
451 | #define AR5416_EEP4K_START_LOC 64 | ||
452 | #define AR5416_EEP4K_NUM_2G_CAL_PIERS 3 | ||
453 | #define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3 | ||
454 | #define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3 | ||
455 | #define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3 | ||
456 | #define AR5416_EEP4K_NUM_CTLS 12 | ||
457 | #define AR5416_EEP4K_NUM_BAND_EDGES 4 | ||
458 | #define AR5416_EEP4K_NUM_PD_GAINS 2 | ||
459 | #define AR5416_EEP4K_PD_GAINS_IN_MASK 4 | ||
460 | #define AR5416_EEP4K_PD_GAIN_ICEPTS 5 | ||
461 | #define AR5416_EEP4K_MAX_CHAINS 1 | ||
451 | 462 | ||
452 | enum eeprom_param { | 463 | enum eeprom_param { |
453 | EEP_NFTHRESH_5, | 464 | EEP_NFTHRESH_5, |
@@ -507,6 +518,25 @@ struct base_eep_header { | |||
507 | u8 futureBase_3[25]; | 518 | u8 futureBase_3[25]; |
508 | } __packed; | 519 | } __packed; |
509 | 520 | ||
521 | struct base_eep_header_4k { | ||
522 | u16 length; | ||
523 | u16 checksum; | ||
524 | u16 version; | ||
525 | u8 opCapFlags; | ||
526 | u8 eepMisc; | ||
527 | u16 regDmn[2]; | ||
528 | u8 macAddr[6]; | ||
529 | u8 rxMask; | ||
530 | u8 txMask; | ||
531 | u16 rfSilent; | ||
532 | u16 blueToothOptions; | ||
533 | u16 deviceCap; | ||
534 | u32 binBuildNumber; | ||
535 | u8 deviceType; | ||
536 | u8 futureBase[1]; | ||
537 | } __packed; | ||
538 | |||
539 | |||
510 | struct spur_chan { | 540 | struct spur_chan { |
511 | u16 spurChan; | 541 | u16 spurChan; |
512 | u8 spurRangeLow; | 542 | u8 spurRangeLow; |
@@ -559,11 +589,58 @@ struct modal_eep_header { | |||
559 | struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; | 589 | struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; |
560 | } __packed; | 590 | } __packed; |
561 | 591 | ||
592 | struct modal_eep_4k_header { | ||
593 | u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; | ||
594 | u32 antCtrlCommon; | ||
595 | u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS]; | ||
596 | u8 switchSettling; | ||
597 | u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS]; | ||
598 | u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS]; | ||
599 | u8 adcDesiredSize; | ||
600 | u8 pgaDesiredSize; | ||
601 | u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS]; | ||
602 | u8 txEndToXpaOff; | ||
603 | u8 txEndToRxOn; | ||
604 | u8 txFrameToXpaOn; | ||
605 | u8 thresh62; | ||
606 | u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS]; | ||
607 | u8 xpdGain; | ||
608 | u8 xpd; | ||
609 | u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS]; | ||
610 | u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS]; | ||
611 | u8 pdGainOverlap; | ||
612 | u8 ob_01; | ||
613 | u8 db1_01; | ||
614 | u8 xpaBiasLvl; | ||
615 | u8 txFrameToDataStart; | ||
616 | u8 txFrameToPaOn; | ||
617 | u8 ht40PowerIncForPdadc; | ||
618 | u8 bswAtten[AR5416_EEP4K_MAX_CHAINS]; | ||
619 | u8 bswMargin[AR5416_EEP4K_MAX_CHAINS]; | ||
620 | u8 swSettleHt40; | ||
621 | u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS]; | ||
622 | u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS]; | ||
623 | u8 db2_01; | ||
624 | u8 version; | ||
625 | u16 ob_234; | ||
626 | u16 db1_234; | ||
627 | u16 db2_234; | ||
628 | u8 futureModal[4]; | ||
629 | |||
630 | struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; | ||
631 | } __packed; | ||
632 | |||
633 | |||
562 | struct cal_data_per_freq { | 634 | struct cal_data_per_freq { |
563 | u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; | 635 | u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; |
564 | u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; | 636 | u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; |
565 | } __packed; | 637 | } __packed; |
566 | 638 | ||
639 | struct cal_data_per_freq_4k { | ||
640 | u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS]; | ||
641 | u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS]; | ||
642 | } __packed; | ||
643 | |||
567 | struct cal_target_power_leg { | 644 | struct cal_target_power_leg { |
568 | u8 bChannel; | 645 | u8 bChannel; |
569 | u8 tPow2x[4]; | 646 | u8 tPow2x[4]; |
@@ -574,6 +651,7 @@ struct cal_target_power_ht { | |||
574 | u8 tPow2x[8]; | 651 | u8 tPow2x[8]; |
575 | } __packed; | 652 | } __packed; |
576 | 653 | ||
654 | |||
577 | #ifdef __BIG_ENDIAN_BITFIELD | 655 | #ifdef __BIG_ENDIAN_BITFIELD |
578 | struct cal_ctl_edges { | 656 | struct cal_ctl_edges { |
579 | u8 bChannel; | 657 | u8 bChannel; |
@@ -588,10 +666,15 @@ struct cal_ctl_edges { | |||
588 | 666 | ||
589 | struct cal_ctl_data { | 667 | struct cal_ctl_data { |
590 | struct cal_ctl_edges | 668 | struct cal_ctl_edges |
591 | ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; | 669 | ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; |
670 | } __packed; | ||
671 | |||
672 | struct cal_ctl_data_4k { | ||
673 | struct cal_ctl_edges | ||
674 | ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES]; | ||
592 | } __packed; | 675 | } __packed; |
593 | 676 | ||
594 | struct ar5416_eeprom { | 677 | struct ar5416_eeprom_def { |
595 | struct base_eep_header baseEepHeader; | 678 | struct base_eep_header baseEepHeader; |
596 | u8 custData[64]; | 679 | u8 custData[64]; |
597 | struct modal_eep_header modalHeader[2]; | 680 | struct modal_eep_header modalHeader[2]; |
@@ -620,6 +703,26 @@ struct ar5416_eeprom { | |||
620 | u8 padding; | 703 | u8 padding; |
621 | } __packed; | 704 | } __packed; |
622 | 705 | ||
706 | struct ar5416_eeprom_4k { | ||
707 | struct base_eep_header_4k baseEepHeader; | ||
708 | u8 custData[20]; | ||
709 | struct modal_eep_4k_header modalHeader; | ||
710 | u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS]; | ||
711 | struct cal_data_per_freq_4k | ||
712 | calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS]; | ||
713 | struct cal_target_power_leg | ||
714 | calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS]; | ||
715 | struct cal_target_power_leg | ||
716 | calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS]; | ||
717 | struct cal_target_power_ht | ||
718 | calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS]; | ||
719 | struct cal_target_power_ht | ||
720 | calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS]; | ||
721 | u8 ctlIndex[AR5416_EEP4K_NUM_CTLS]; | ||
722 | struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS]; | ||
723 | u8 padding; | ||
724 | } __packed; | ||
725 | |||
623 | struct ar5416IniArray { | 726 | struct ar5416IniArray { |
624 | u32 *ia_array; | 727 | u32 *ia_array; |
625 | u32 ia_rows; | 728 | u32 ia_rows; |
@@ -687,9 +790,22 @@ struct hal_cal_list { | |||
687 | struct hal_cal_list *calNext; | 790 | struct hal_cal_list *calNext; |
688 | }; | 791 | }; |
689 | 792 | ||
793 | /* | ||
794 | * Enum to indentify the eeprom mappings | ||
795 | */ | ||
796 | enum hal_eep_map { | ||
797 | EEP_MAP_DEFAULT = 0x0, | ||
798 | EEP_MAP_4KBITS, | ||
799 | EEP_MAP_MAX | ||
800 | }; | ||
801 | |||
802 | |||
690 | struct ath_hal_5416 { | 803 | struct ath_hal_5416 { |
691 | struct ath_hal ah; | 804 | struct ath_hal ah; |
692 | struct ar5416_eeprom ah_eeprom; | 805 | union { |
806 | struct ar5416_eeprom_def def; | ||
807 | struct ar5416_eeprom_4k map4k; | ||
808 | } ah_eeprom; | ||
693 | struct ar5416Stats ah_stats; | 809 | struct ar5416Stats ah_stats; |
694 | struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES]; | 810 | struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES]; |
695 | void __iomem *ah_cal_mem; | 811 | void __iomem *ah_cal_mem; |
@@ -813,6 +929,8 @@ struct ath_hal_5416 { | |||
813 | struct ar5416IniArray ah_iniModesAdditional; | 929 | struct ar5416IniArray ah_iniModesAdditional; |
814 | struct ar5416IniArray ah_iniModesRxGain; | 930 | struct ar5416IniArray ah_iniModesRxGain; |
815 | struct ar5416IniArray ah_iniModesTxGain; | 931 | struct ar5416IniArray ah_iniModesTxGain; |
932 | /* To indicate EEPROM mapping used */ | ||
933 | enum hal_eep_map ah_eep_map; | ||
816 | }; | 934 | }; |
817 | #define AH5416(_ah) ((struct ath_hal_5416 *)(_ah)) | 935 | #define AH5416(_ah) ((struct ath_hal_5416 *)(_ah)) |
818 | 936 | ||
@@ -854,13 +972,20 @@ struct ath_hal_5416 { | |||
854 | (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200 | 972 | (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200 |
855 | #define AR5416_EEPROM_MAX 0xae0 | 973 | #define AR5416_EEPROM_MAX 0xae0 |
856 | #define ar5416_get_eep_ver(_ahp) \ | 974 | #define ar5416_get_eep_ver(_ahp) \ |
857 | (((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF) | 975 | (((_ahp)->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF) |
858 | #define ar5416_get_eep_rev(_ahp) \ | 976 | #define ar5416_get_eep_rev(_ahp) \ |
859 | (((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF) | 977 | (((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF) |
860 | #define ar5416_get_ntxchains(_txchainmask) \ | 978 | #define ar5416_get_ntxchains(_txchainmask) \ |
861 | (((_txchainmask >> 2) & 1) + \ | 979 | (((_txchainmask >> 2) & 1) + \ |
862 | ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) | 980 | ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) |
863 | 981 | ||
982 | /* EEPROM 4K bit map definations */ | ||
983 | #define ar5416_get_eep4k_ver(_ahp) \ | ||
984 | (((_ahp)->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF) | ||
985 | #define ar5416_get_eep4k_rev(_ahp) \ | ||
986 | (((_ahp)->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF) | ||
987 | |||
988 | |||
864 | #ifdef __BIG_ENDIAN | 989 | #ifdef __BIG_ENDIAN |
865 | #define AR5416_EEPROM_MAGIC 0x5aa5 | 990 | #define AR5416_EEPROM_MAGIC 0x5aa5 |
866 | #else | 991 | #else |
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c index a4e98986dbc..5254ea49f8a 100644 --- a/drivers/net/wireless/ath9k/mac.c +++ b/drivers/net/wireless/ath9k/mac.c | |||
@@ -916,12 +916,12 @@ void ath9k_hw_rxena(struct ath_hal *ah) | |||
916 | 916 | ||
917 | void ath9k_hw_startpcureceive(struct ath_hal *ah) | 917 | void ath9k_hw_startpcureceive(struct ath_hal *ah) |
918 | { | 918 | { |
919 | REG_CLR_BIT(ah, AR_DIAG_SW, | 919 | REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); |
920 | (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
921 | 920 | ||
922 | ath9k_enable_mib_counters(ah); | 921 | ath9k_enable_mib_counters(ah); |
923 | 922 | ||
924 | ath9k_ani_reset(ah); | 923 | ath9k_ani_reset(ah); |
924 | |||
925 | } | 925 | } |
926 | 926 | ||
927 | void ath9k_hw_stoppcurecv(struct ath_hal *ah) | 927 | void ath9k_hw_stoppcurecv(struct ath_hal *ah) |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 44459d7c546..ebd531e574f 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -34,6 +34,7 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = { | |||
34 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ | 34 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ |
35 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ | 35 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ |
36 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ | 36 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ |
37 | { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ | ||
37 | { 0 } | 38 | { 0 } |
38 | }; | 39 | }; |
39 | 40 | ||
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h index 14702344448..3a406a5c059 100644 --- a/drivers/net/wireless/ath9k/phy.h +++ b/drivers/net/wireless/ath9k/phy.h | |||
@@ -50,6 +50,9 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, | |||
50 | #define AR_PHY_FC_SHORT_GI_40 0x00000080 | 50 | #define AR_PHY_FC_SHORT_GI_40 0x00000080 |
51 | #define AR_PHY_FC_WALSH 0x00000100 | 51 | #define AR_PHY_FC_WALSH 0x00000100 |
52 | #define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200 | 52 | #define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200 |
53 | #define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800 | ||
54 | |||
55 | #define AR_PHY_TEST2 0x9808 | ||
53 | 56 | ||
54 | #define AR_PHY_TIMING2 0x9810 | 57 | #define AR_PHY_TIMING2 0x9810 |
55 | #define AR_PHY_TIMING3 0x9814 | 58 | #define AR_PHY_TIMING3 0x9814 |
@@ -100,6 +103,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, | |||
100 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF | 103 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF |
101 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 | 104 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 |
102 | 105 | ||
106 | #define AR_PHY_TSTDAC_CONST 0x983c | ||
107 | |||
103 | #define AR_PHY_SETTLING 0x9844 | 108 | #define AR_PHY_SETTLING 0x9844 |
104 | #define AR_PHY_SETTLING_SWITCH 0x00003F80 | 109 | #define AR_PHY_SETTLING_SWITCH 0x00003F80 |
105 | #define AR_PHY_SETTLING_SWITCH_S 7 | 110 | #define AR_PHY_SETTLING_SWITCH_S 7 |