diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ath/ath9k/hw.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hw.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 1496 |
1 files changed, 549 insertions, 947 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index ca7694caf364..78b571129c92 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -15,10 +15,11 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/slab.h> | ||
18 | #include <asm/unaligned.h> | 19 | #include <asm/unaligned.h> |
19 | #include <linux/pci.h> | ||
20 | 20 | ||
21 | #include "ath9k.h" | 21 | #include "hw.h" |
22 | #include "rc.h" | ||
22 | #include "initvals.h" | 23 | #include "initvals.h" |
23 | 24 | ||
24 | #define ATH9K_CLOCK_RATE_CCK 22 | 25 | #define ATH9K_CLOCK_RATE_CCK 22 |
@@ -26,43 +27,35 @@ | |||
26 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 | 27 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 |
27 | 28 | ||
28 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); | 29 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); |
29 | static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan, | 30 | static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan); |
30 | enum ath9k_ht_macmode macmode); | ||
31 | static u32 ath9k_hw_ini_fixup(struct ath_hw *ah, | 31 | static u32 ath9k_hw_ini_fixup(struct ath_hw *ah, |
32 | struct ar5416_eeprom_def *pEepData, | 32 | struct ar5416_eeprom_def *pEepData, |
33 | u32 reg, u32 value); | 33 | u32 reg, u32 value); |
34 | static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan); | ||
35 | static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan); | ||
36 | 34 | ||
37 | /********************/ | 35 | MODULE_AUTHOR("Atheros Communications"); |
38 | /* Helper Functions */ | 36 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); |
39 | /********************/ | 37 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); |
38 | MODULE_LICENSE("Dual BSD/GPL"); | ||
40 | 39 | ||
41 | static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks) | 40 | static int __init ath9k_init(void) |
42 | { | 41 | { |
43 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | 42 | return 0; |
44 | |||
45 | if (!ah->curchan) /* should really check for CCK instead */ | ||
46 | return clks / ATH9K_CLOCK_RATE_CCK; | ||
47 | if (conf->channel->band == IEEE80211_BAND_2GHZ) | ||
48 | return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM; | ||
49 | |||
50 | return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
51 | } | 43 | } |
44 | module_init(ath9k_init); | ||
52 | 45 | ||
53 | static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks) | 46 | static void __exit ath9k_exit(void) |
54 | { | 47 | { |
55 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | 48 | return; |
56 | |||
57 | if (conf_is_ht40(conf)) | ||
58 | return ath9k_hw_mac_usec(ah, clks) / 2; | ||
59 | else | ||
60 | return ath9k_hw_mac_usec(ah, clks); | ||
61 | } | 49 | } |
50 | module_exit(ath9k_exit); | ||
51 | |||
52 | /********************/ | ||
53 | /* Helper Functions */ | ||
54 | /********************/ | ||
62 | 55 | ||
63 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) | 56 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) |
64 | { | 57 | { |
65 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | 58 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
66 | 59 | ||
67 | if (!ah->curchan) /* should really check for CCK instead */ | 60 | if (!ah->curchan) /* should really check for CCK instead */ |
68 | return usecs *ATH9K_CLOCK_RATE_CCK; | 61 | return usecs *ATH9K_CLOCK_RATE_CCK; |
@@ -73,7 +66,7 @@ static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) | |||
73 | 66 | ||
74 | static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) | 67 | static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) |
75 | { | 68 | { |
76 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | 69 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
77 | 70 | ||
78 | if (conf_is_ht40(conf)) | 71 | if (conf_is_ht40(conf)) |
79 | return ath9k_hw_mac_clks(ah, usecs) * 2; | 72 | return ath9k_hw_mac_clks(ah, usecs) * 2; |
@@ -81,38 +74,6 @@ static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) | |||
81 | return ath9k_hw_mac_clks(ah, usecs); | 74 | return ath9k_hw_mac_clks(ah, usecs); |
82 | } | 75 | } |
83 | 76 | ||
84 | /* | ||
85 | * Read and write, they both share the same lock. We do this to serialize | ||
86 | * reads and writes on Atheros 802.11n PCI devices only. This is required | ||
87 | * as the FIFO on these devices can only accept sanely 2 requests. After | ||
88 | * that the device goes bananas. Serializing the reads/writes prevents this | ||
89 | * from happening. | ||
90 | */ | ||
91 | |||
92 | void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val) | ||
93 | { | ||
94 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
95 | unsigned long flags; | ||
96 | spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); | ||
97 | iowrite32(val, ah->ah_sc->mem + reg_offset); | ||
98 | spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); | ||
99 | } else | ||
100 | iowrite32(val, ah->ah_sc->mem + reg_offset); | ||
101 | } | ||
102 | |||
103 | unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset) | ||
104 | { | ||
105 | u32 val; | ||
106 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
107 | unsigned long flags; | ||
108 | spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); | ||
109 | val = ioread32(ah->ah_sc->mem + reg_offset); | ||
110 | spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); | ||
111 | } else | ||
112 | val = ioread32(ah->ah_sc->mem + reg_offset); | ||
113 | return val; | ||
114 | } | ||
115 | |||
116 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) | 77 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) |
117 | { | 78 | { |
118 | int i; | 79 | int i; |
@@ -126,12 +87,13 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) | |||
126 | udelay(AH_TIME_QUANTUM); | 87 | udelay(AH_TIME_QUANTUM); |
127 | } | 88 | } |
128 | 89 | ||
129 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 90 | ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, |
130 | "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", | 91 | "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", |
131 | timeout, reg, REG_READ(ah, reg), mask, val); | 92 | timeout, reg, REG_READ(ah, reg), mask, val); |
132 | 93 | ||
133 | return false; | 94 | return false; |
134 | } | 95 | } |
96 | EXPORT_SYMBOL(ath9k_hw_wait); | ||
135 | 97 | ||
136 | u32 ath9k_hw_reverse_bits(u32 val, u32 n) | 98 | u32 ath9k_hw_reverse_bits(u32 val, u32 n) |
137 | { | 99 | { |
@@ -165,22 +127,19 @@ bool ath9k_get_channel_edges(struct ath_hw *ah, | |||
165 | } | 127 | } |
166 | 128 | ||
167 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, | 129 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, |
168 | const struct ath_rate_table *rates, | 130 | u8 phy, int kbps, |
169 | u32 frameLen, u16 rateix, | 131 | u32 frameLen, u16 rateix, |
170 | bool shortPreamble) | 132 | bool shortPreamble) |
171 | { | 133 | { |
172 | u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime; | 134 | u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime; |
173 | u32 kbps; | ||
174 | |||
175 | kbps = rates->info[rateix].ratekbps; | ||
176 | 135 | ||
177 | if (kbps == 0) | 136 | if (kbps == 0) |
178 | return 0; | 137 | return 0; |
179 | 138 | ||
180 | switch (rates->info[rateix].phy) { | 139 | switch (phy) { |
181 | case WLAN_RC_PHY_CCK: | 140 | case WLAN_RC_PHY_CCK: |
182 | phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; | 141 | phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; |
183 | if (shortPreamble && rates->info[rateix].short_preamble) | 142 | if (shortPreamble) |
184 | phyTime >>= 1; | 143 | phyTime >>= 1; |
185 | numBits = frameLen << 3; | 144 | numBits = frameLen << 3; |
186 | txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); | 145 | txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); |
@@ -210,15 +169,15 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah, | |||
210 | } | 169 | } |
211 | break; | 170 | break; |
212 | default: | 171 | default: |
213 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 172 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, |
214 | "Unknown phy %u (rate ix %u)\n", | 173 | "Unknown phy %u (rate ix %u)\n", phy, rateix); |
215 | rates->info[rateix].phy, rateix); | ||
216 | txTime = 0; | 174 | txTime = 0; |
217 | break; | 175 | break; |
218 | } | 176 | } |
219 | 177 | ||
220 | return txTime; | 178 | return txTime; |
221 | } | 179 | } |
180 | EXPORT_SYMBOL(ath9k_hw_computetxtime); | ||
222 | 181 | ||
223 | void ath9k_hw_get_channel_centers(struct ath_hw *ah, | 182 | void ath9k_hw_get_channel_centers(struct ath_hw *ah, |
224 | struct ath9k_channel *chan, | 183 | struct ath9k_channel *chan, |
@@ -245,10 +204,9 @@ void ath9k_hw_get_channel_centers(struct ath_hw *ah, | |||
245 | 204 | ||
246 | centers->ctl_center = | 205 | centers->ctl_center = |
247 | centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT); | 206 | centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT); |
207 | /* 25 MHz spacing is supported by hw but not on upper layers */ | ||
248 | centers->ext_center = | 208 | centers->ext_center = |
249 | centers->synth_center + (extoff * | 209 | centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); |
250 | ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ? | ||
251 | HT40_CHANNEL_CENTER_SHIFT : 15)); | ||
252 | } | 210 | } |
253 | 211 | ||
254 | /******************/ | 212 | /******************/ |
@@ -317,6 +275,7 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) | |||
317 | 275 | ||
318 | static bool ath9k_hw_chip_test(struct ath_hw *ah) | 276 | static bool ath9k_hw_chip_test(struct ath_hw *ah) |
319 | { | 277 | { |
278 | struct ath_common *common = ath9k_hw_common(ah); | ||
320 | u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) }; | 279 | u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) }; |
321 | u32 regHold[2]; | 280 | u32 regHold[2]; |
322 | u32 patternData[4] = { 0x55555555, | 281 | u32 patternData[4] = { 0x55555555, |
@@ -335,10 +294,11 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) | |||
335 | REG_WRITE(ah, addr, wrData); | 294 | REG_WRITE(ah, addr, wrData); |
336 | rdData = REG_READ(ah, addr); | 295 | rdData = REG_READ(ah, addr); |
337 | if (rdData != wrData) { | 296 | if (rdData != wrData) { |
338 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 297 | ath_print(common, ATH_DBG_FATAL, |
339 | "address test failed " | 298 | "address test failed " |
340 | "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", | 299 | "addr: 0x%08x - wr:0x%08x != " |
341 | addr, wrData, rdData); | 300 | "rd:0x%08x\n", |
301 | addr, wrData, rdData); | ||
342 | return false; | 302 | return false; |
343 | } | 303 | } |
344 | } | 304 | } |
@@ -347,10 +307,11 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) | |||
347 | REG_WRITE(ah, addr, wrData); | 307 | REG_WRITE(ah, addr, wrData); |
348 | rdData = REG_READ(ah, addr); | 308 | rdData = REG_READ(ah, addr); |
349 | if (wrData != rdData) { | 309 | if (wrData != rdData) { |
350 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 310 | ath_print(common, ATH_DBG_FATAL, |
351 | "address test failed " | 311 | "address test failed " |
352 | "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", | 312 | "addr: 0x%08x - wr:0x%08x != " |
353 | addr, wrData, rdData); | 313 | "rd:0x%08x\n", |
314 | addr, wrData, rdData); | ||
354 | return false; | 315 | return false; |
355 | } | 316 | } |
356 | } | 317 | } |
@@ -361,30 +322,6 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) | |||
361 | return true; | 322 | return true; |
362 | } | 323 | } |
363 | 324 | ||
364 | static const char *ath9k_hw_devname(u16 devid) | ||
365 | { | ||
366 | switch (devid) { | ||
367 | case AR5416_DEVID_PCI: | ||
368 | return "Atheros 5416"; | ||
369 | case AR5416_DEVID_PCIE: | ||
370 | return "Atheros 5418"; | ||
371 | case AR9160_DEVID_PCI: | ||
372 | return "Atheros 9160"; | ||
373 | case AR5416_AR9100_DEVID: | ||
374 | return "Atheros 9100"; | ||
375 | case AR9280_DEVID_PCI: | ||
376 | case AR9280_DEVID_PCIE: | ||
377 | return "Atheros 9280"; | ||
378 | case AR9285_DEVID_PCIE: | ||
379 | return "Atheros 9285"; | ||
380 | case AR5416_DEVID_AR9287_PCI: | ||
381 | case AR5416_DEVID_AR9287_PCIE: | ||
382 | return "Atheros 9287"; | ||
383 | } | ||
384 | |||
385 | return NULL; | ||
386 | } | ||
387 | |||
388 | static void ath9k_hw_init_config(struct ath_hw *ah) | 325 | static void ath9k_hw_init_config(struct ath_hw *ah) |
389 | { | 326 | { |
390 | int i; | 327 | int i; |
@@ -398,21 +335,23 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
398 | ah->config.pcie_clock_req = 0; | 335 | ah->config.pcie_clock_req = 0; |
399 | ah->config.pcie_waen = 0; | 336 | ah->config.pcie_waen = 0; |
400 | ah->config.analog_shiftreg = 1; | 337 | ah->config.analog_shiftreg = 1; |
401 | ah->config.ht_enable = 1; | ||
402 | ah->config.ofdm_trig_low = 200; | 338 | ah->config.ofdm_trig_low = 200; |
403 | ah->config.ofdm_trig_high = 500; | 339 | ah->config.ofdm_trig_high = 500; |
404 | ah->config.cck_trig_high = 200; | 340 | ah->config.cck_trig_high = 200; |
405 | ah->config.cck_trig_low = 100; | 341 | ah->config.cck_trig_low = 100; |
406 | ah->config.enable_ani = 1; | 342 | ah->config.enable_ani = 1; |
407 | ah->config.diversity_control = ATH9K_ANT_VARIABLE; | ||
408 | ah->config.antenna_switch_swap = 0; | ||
409 | 343 | ||
410 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | 344 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
411 | ah->config.spurchans[i][0] = AR_NO_SPUR; | 345 | ah->config.spurchans[i][0] = AR_NO_SPUR; |
412 | ah->config.spurchans[i][1] = AR_NO_SPUR; | 346 | ah->config.spurchans[i][1] = AR_NO_SPUR; |
413 | } | 347 | } |
414 | 348 | ||
415 | ah->config.intr_mitigation = true; | 349 | if (ah->hw_version.devid != AR2427_DEVID_PCIE) |
350 | ah->config.ht_enable = 1; | ||
351 | else | ||
352 | ah->config.ht_enable = 0; | ||
353 | |||
354 | ah->config.rx_intr_mitigation = true; | ||
416 | 355 | ||
417 | /* | 356 | /* |
418 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) | 357 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) |
@@ -433,6 +372,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
433 | if (num_possible_cpus() > 1) | 372 | if (num_possible_cpus() > 1) |
434 | ah->config.serialize_regmode = SER_REG_MODE_AUTO; | 373 | ah->config.serialize_regmode = SER_REG_MODE_AUTO; |
435 | } | 374 | } |
375 | EXPORT_SYMBOL(ath9k_hw_init); | ||
436 | 376 | ||
437 | static void ath9k_hw_init_defaults(struct ath_hw *ah) | 377 | static void ath9k_hw_init_defaults(struct ath_hw *ah) |
438 | { | 378 | { |
@@ -456,30 +396,10 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
456 | ah->beacon_interval = 100; | 396 | ah->beacon_interval = 100; |
457 | ah->enable_32kHz_clock = DONT_USE_32KHZ; | 397 | ah->enable_32kHz_clock = DONT_USE_32KHZ; |
458 | ah->slottime = (u32) -1; | 398 | ah->slottime = (u32) -1; |
459 | ah->acktimeout = (u32) -1; | ||
460 | ah->ctstimeout = (u32) -1; | ||
461 | ah->globaltxtimeout = (u32) -1; | 399 | ah->globaltxtimeout = (u32) -1; |
462 | |||
463 | ah->gbeacon_rate = 0; | ||
464 | |||
465 | ah->power_mode = ATH9K_PM_UNDEFINED; | 400 | ah->power_mode = ATH9K_PM_UNDEFINED; |
466 | } | 401 | } |
467 | 402 | ||
468 | static int ath9k_hw_rfattach(struct ath_hw *ah) | ||
469 | { | ||
470 | bool rfStatus = false; | ||
471 | int ecode = 0; | ||
472 | |||
473 | rfStatus = ath9k_hw_init_rf(ah, &ecode); | ||
474 | if (!rfStatus) { | ||
475 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
476 | "RF setup failed, status: %u\n", ecode); | ||
477 | return ecode; | ||
478 | } | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | static int ath9k_hw_rf_claim(struct ath_hw *ah) | 403 | static int ath9k_hw_rf_claim(struct ath_hw *ah) |
484 | { | 404 | { |
485 | u32 val; | 405 | u32 val; |
@@ -497,9 +417,9 @@ static int ath9k_hw_rf_claim(struct ath_hw *ah) | |||
497 | case AR_RAD2122_SREV_MAJOR: | 417 | case AR_RAD2122_SREV_MAJOR: |
498 | break; | 418 | break; |
499 | default: | 419 | default: |
500 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 420 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, |
501 | "Radio Chip Rev 0x%02X not supported\n", | 421 | "Radio Chip Rev 0x%02X not supported\n", |
502 | val & AR_RADIO_SREV_MAJOR); | 422 | val & AR_RADIO_SREV_MAJOR); |
503 | return -EOPNOTSUPP; | 423 | return -EOPNOTSUPP; |
504 | } | 424 | } |
505 | 425 | ||
@@ -510,6 +430,7 @@ static int ath9k_hw_rf_claim(struct ath_hw *ah) | |||
510 | 430 | ||
511 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) | 431 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) |
512 | { | 432 | { |
433 | struct ath_common *common = ath9k_hw_common(ah); | ||
513 | u32 sum; | 434 | u32 sum; |
514 | int i; | 435 | int i; |
515 | u16 eeval; | 436 | u16 eeval; |
@@ -518,8 +439,8 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah) | |||
518 | for (i = 0; i < 3; i++) { | 439 | for (i = 0; i < 3; i++) { |
519 | eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i)); | 440 | eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i)); |
520 | sum += eeval; | 441 | sum += eeval; |
521 | ah->macaddr[2 * i] = eeval >> 8; | 442 | common->macaddr[2 * i] = eeval >> 8; |
522 | ah->macaddr[2 * i + 1] = eeval & 0xff; | 443 | common->macaddr[2 * i + 1] = eeval & 0xff; |
523 | } | 444 | } |
524 | if (sum == 0 || sum == 0xffff * 3) | 445 | if (sum == 0 || sum == 0xffff * 3) |
525 | return -EADDRNOTAVAIL; | 446 | return -EADDRNOTAVAIL; |
@@ -590,12 +511,20 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
590 | if (ecode != 0) | 511 | if (ecode != 0) |
591 | return ecode; | 512 | return ecode; |
592 | 513 | ||
593 | DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n", | 514 | ath_print(ath9k_hw_common(ah), ATH_DBG_CONFIG, |
594 | ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah)); | 515 | "Eeprom VER: %d, REV: %d\n", |
595 | 516 | ah->eep_ops->get_eeprom_ver(ah), | |
596 | ecode = ath9k_hw_rfattach(ah); | 517 | ah->eep_ops->get_eeprom_rev(ah)); |
597 | if (ecode != 0) | 518 | |
598 | return ecode; | 519 | if (!AR_SREV_9280_10_OR_LATER(ah)) { |
520 | ecode = ath9k_hw_rf_alloc_ext_banks(ah); | ||
521 | if (ecode) { | ||
522 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | ||
523 | "Failed allocating banks for " | ||
524 | "external radio\n"); | ||
525 | return ecode; | ||
526 | } | ||
527 | } | ||
599 | 528 | ||
600 | if (!AR_SREV_9100(ah)) { | 529 | if (!AR_SREV_9100(ah)) { |
601 | ath9k_hw_ani_setup(ah); | 530 | ath9k_hw_ani_setup(ah); |
@@ -617,6 +546,8 @@ static bool ath9k_hw_devid_supported(u16 devid) | |||
617 | case AR9285_DEVID_PCIE: | 546 | case AR9285_DEVID_PCIE: |
618 | case AR5416_DEVID_AR9287_PCI: | 547 | case AR5416_DEVID_AR9287_PCI: |
619 | case AR5416_DEVID_AR9287_PCIE: | 548 | case AR5416_DEVID_AR9287_PCIE: |
549 | case AR9271_USB: | ||
550 | case AR2427_DEVID_PCIE: | ||
620 | return true; | 551 | return true; |
621 | default: | 552 | default: |
622 | break; | 553 | break; |
@@ -634,9 +565,8 @@ static bool ath9k_hw_macversion_supported(u32 macversion) | |||
634 | case AR_SREV_VERSION_9280: | 565 | case AR_SREV_VERSION_9280: |
635 | case AR_SREV_VERSION_9285: | 566 | case AR_SREV_VERSION_9285: |
636 | case AR_SREV_VERSION_9287: | 567 | case AR_SREV_VERSION_9287: |
637 | return true; | ||
638 | /* Not yet */ | ||
639 | case AR_SREV_VERSION_9271: | 568 | case AR_SREV_VERSION_9271: |
569 | return true; | ||
640 | default: | 570 | default: |
641 | break; | 571 | break; |
642 | } | 572 | } |
@@ -670,10 +600,13 @@ static void ath9k_hw_init_cal_settings(struct ath_hw *ah) | |||
670 | static void ath9k_hw_init_mode_regs(struct ath_hw *ah) | 600 | static void ath9k_hw_init_mode_regs(struct ath_hw *ah) |
671 | { | 601 | { |
672 | if (AR_SREV_9271(ah)) { | 602 | if (AR_SREV_9271(ah)) { |
673 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271_1_0, | 603 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271, |
674 | ARRAY_SIZE(ar9271Modes_9271_1_0), 6); | 604 | ARRAY_SIZE(ar9271Modes_9271), 6); |
675 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271_1_0, | 605 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, |
676 | ARRAY_SIZE(ar9271Common_9271_1_0), 2); | 606 | ARRAY_SIZE(ar9271Common_9271), 2); |
607 | INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, | ||
608 | ar9271Modes_9271_1_0_only, | ||
609 | ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6); | ||
677 | return; | 610 | return; |
678 | } | 611 | } |
679 | 612 | ||
@@ -880,12 +813,11 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) | |||
880 | } | 813 | } |
881 | } | 814 | } |
882 | 815 | ||
883 | static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah) | 816 | static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah) |
884 | { | 817 | { |
885 | u32 i, j; | 818 | u32 i, j; |
886 | 819 | ||
887 | if ((ah->hw_version.devid == AR9280_DEVID_PCI) && | 820 | if (ah->hw_version.devid == AR9280_DEVID_PCI) { |
888 | test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) { | ||
889 | 821 | ||
890 | /* EEPROM Fixup */ | 822 | /* EEPROM Fixup */ |
891 | for (i = 0; i < ah->iniModes.ia_rows; i++) { | 823 | for (i = 0; i < ah->iniModes.ia_rows; i++) { |
@@ -905,21 +837,27 @@ static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah) | |||
905 | 837 | ||
906 | int ath9k_hw_init(struct ath_hw *ah) | 838 | int ath9k_hw_init(struct ath_hw *ah) |
907 | { | 839 | { |
840 | struct ath_common *common = ath9k_hw_common(ah); | ||
908 | int r = 0; | 841 | int r = 0; |
909 | 842 | ||
910 | if (!ath9k_hw_devid_supported(ah->hw_version.devid)) | 843 | if (!ath9k_hw_devid_supported(ah->hw_version.devid)) { |
844 | ath_print(common, ATH_DBG_FATAL, | ||
845 | "Unsupported device ID: 0x%0x\n", | ||
846 | ah->hw_version.devid); | ||
911 | return -EOPNOTSUPP; | 847 | return -EOPNOTSUPP; |
848 | } | ||
912 | 849 | ||
913 | ath9k_hw_init_defaults(ah); | 850 | ath9k_hw_init_defaults(ah); |
914 | ath9k_hw_init_config(ah); | 851 | ath9k_hw_init_config(ah); |
915 | 852 | ||
916 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { | 853 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { |
917 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Couldn't reset chip\n"); | 854 | ath_print(common, ATH_DBG_FATAL, |
855 | "Couldn't reset chip\n"); | ||
918 | return -EIO; | 856 | return -EIO; |
919 | } | 857 | } |
920 | 858 | ||
921 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { | 859 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { |
922 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); | 860 | ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); |
923 | return -EIO; | 861 | return -EIO; |
924 | } | 862 | } |
925 | 863 | ||
@@ -934,14 +872,19 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
934 | } | 872 | } |
935 | } | 873 | } |
936 | 874 | ||
937 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "serialize_regmode is %d\n", | 875 | ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n", |
938 | ah->config.serialize_regmode); | 876 | ah->config.serialize_regmode); |
939 | 877 | ||
878 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||
879 | ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1; | ||
880 | else | ||
881 | ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; | ||
882 | |||
940 | if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) { | 883 | if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) { |
941 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 884 | ath_print(common, ATH_DBG_FATAL, |
942 | "Mac Chip Rev 0x%02x.%x is not supported by " | 885 | "Mac Chip Rev 0x%02x.%x is not supported by " |
943 | "this driver\n", ah->hw_version.macVersion, | 886 | "this driver\n", ah->hw_version.macVersion, |
944 | ah->hw_version.macRev); | 887 | ah->hw_version.macRev); |
945 | return -EOPNOTSUPP; | 888 | return -EOPNOTSUPP; |
946 | } | 889 | } |
947 | 890 | ||
@@ -959,8 +902,14 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
959 | ath9k_hw_init_cal_settings(ah); | 902 | ath9k_hw_init_cal_settings(ah); |
960 | 903 | ||
961 | ah->ani_function = ATH9K_ANI_ALL; | 904 | ah->ani_function = ATH9K_ANI_ALL; |
962 | if (AR_SREV_9280_10_OR_LATER(ah)) | 905 | if (AR_SREV_9280_10_OR_LATER(ah)) { |
963 | ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; | 906 | ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; |
907 | ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel; | ||
908 | ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_9280_spur_mitigate; | ||
909 | } else { | ||
910 | ah->ath9k_hw_rf_set_freq = &ath9k_hw_set_channel; | ||
911 | ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_spur_mitigate; | ||
912 | } | ||
964 | 913 | ||
965 | ath9k_hw_init_mode_regs(ah); | 914 | ath9k_hw_init_mode_regs(ah); |
966 | 915 | ||
@@ -969,18 +918,31 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
969 | else | 918 | else |
970 | ath9k_hw_disablepcie(ah); | 919 | ath9k_hw_disablepcie(ah); |
971 | 920 | ||
921 | /* Support for Japan ch.14 (2484) spread */ | ||
922 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
923 | INIT_INI_ARRAY(&ah->iniCckfirNormal, | ||
924 | ar9287Common_normal_cck_fir_coeff_92871_1, | ||
925 | ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), 2); | ||
926 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | ||
927 | ar9287Common_japan_2484_cck_fir_coeff_92871_1, | ||
928 | ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), 2); | ||
929 | } | ||
930 | |||
972 | r = ath9k_hw_post_init(ah); | 931 | r = ath9k_hw_post_init(ah); |
973 | if (r) | 932 | if (r) |
974 | return r; | 933 | return r; |
975 | 934 | ||
976 | ath9k_hw_init_mode_gain_regs(ah); | 935 | ath9k_hw_init_mode_gain_regs(ah); |
977 | ath9k_hw_fill_cap_info(ah); | 936 | r = ath9k_hw_fill_cap_info(ah); |
978 | ath9k_hw_init_11a_eeprom_fix(ah); | 937 | if (r) |
938 | return r; | ||
939 | |||
940 | ath9k_hw_init_eeprom_fix(ah); | ||
979 | 941 | ||
980 | r = ath9k_hw_init_macaddr(ah); | 942 | r = ath9k_hw_init_macaddr(ah); |
981 | if (r) { | 943 | if (r) { |
982 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 944 | ath_print(common, ATH_DBG_FATAL, |
983 | "Failed to initialize MAC address\n"); | 945 | "Failed to initialize MAC address\n"); |
984 | return r; | 946 | return r; |
985 | } | 947 | } |
986 | 948 | ||
@@ -991,6 +953,8 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
991 | 953 | ||
992 | ath9k_init_nfcal_hist_buffer(ah); | 954 | ath9k_init_nfcal_hist_buffer(ah); |
993 | 955 | ||
956 | common->state = ATH_HW_INITIALIZED; | ||
957 | |||
994 | return 0; | 958 | return 0; |
995 | } | 959 | } |
996 | 960 | ||
@@ -1027,6 +991,22 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
1027 | REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); | 991 | REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); |
1028 | } | 992 | } |
1029 | 993 | ||
994 | static void ath9k_hw_change_target_baud(struct ath_hw *ah, u32 freq, u32 baud) | ||
995 | { | ||
996 | u32 lcr; | ||
997 | u32 baud_divider = freq * 1000 * 1000 / 16 / baud; | ||
998 | |||
999 | lcr = REG_READ(ah , 0x5100c); | ||
1000 | lcr |= 0x80; | ||
1001 | |||
1002 | REG_WRITE(ah, 0x5100c, lcr); | ||
1003 | REG_WRITE(ah, 0x51004, (baud_divider >> 8)); | ||
1004 | REG_WRITE(ah, 0x51000, (baud_divider & 0xff)); | ||
1005 | |||
1006 | lcr &= ~0x80; | ||
1007 | REG_WRITE(ah, 0x5100c, lcr); | ||
1008 | } | ||
1009 | |||
1030 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 1010 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
1031 | struct ath9k_channel *chan) | 1011 | struct ath9k_channel *chan) |
1032 | { | 1012 | { |
@@ -1090,6 +1070,26 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
1090 | } | 1070 | } |
1091 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 1071 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
1092 | 1072 | ||
1073 | /* Switch the core clock for ar9271 to 117Mhz */ | ||
1074 | if (AR_SREV_9271(ah)) { | ||
1075 | if ((pll == 0x142c) || (pll == 0x2850) ) { | ||
1076 | udelay(500); | ||
1077 | /* set CLKOBS to output AHB clock */ | ||
1078 | REG_WRITE(ah, 0x7020, 0xe); | ||
1079 | /* | ||
1080 | * 0x304: 117Mhz, ahb_ratio: 1x1 | ||
1081 | * 0x306: 40Mhz, ahb_ratio: 1x1 | ||
1082 | */ | ||
1083 | REG_WRITE(ah, 0x50040, 0x304); | ||
1084 | /* | ||
1085 | * makes adjustments for the baud dividor to keep the | ||
1086 | * targetted baud rate based on the used core clock. | ||
1087 | */ | ||
1088 | ath9k_hw_change_target_baud(ah, AR9271_CORE_CLOCK, | ||
1089 | AR9271_TARGET_BAUD_RATE); | ||
1090 | } | ||
1091 | } | ||
1092 | |||
1093 | udelay(RTC_PLL_SETTLE_DELAY); | 1093 | udelay(RTC_PLL_SETTLE_DELAY); |
1094 | 1094 | ||
1095 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); | 1095 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); |
@@ -1107,7 +1107,7 @@ static void ath9k_hw_init_chain_masks(struct ath_hw *ah) | |||
1107 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | 1107 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, |
1108 | AR_PHY_SWAP_ALT_CHAIN); | 1108 | AR_PHY_SWAP_ALT_CHAIN); |
1109 | case 0x3: | 1109 | case 0x3: |
1110 | if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) { | 1110 | if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { |
1111 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); | 1111 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); |
1112 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); | 1112 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); |
1113 | break; | 1113 | break; |
@@ -1141,7 +1141,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
1141 | AR_IMR_RXORN | | 1141 | AR_IMR_RXORN | |
1142 | AR_IMR_BCNMISC; | 1142 | AR_IMR_BCNMISC; |
1143 | 1143 | ||
1144 | if (ah->config.intr_mitigation) | 1144 | if (ah->config.rx_intr_mitigation) |
1145 | ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; | 1145 | ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; |
1146 | else | 1146 | else |
1147 | ah->mask_reg |= AR_IMR_RXOK; | 1147 | ah->mask_reg |= AR_IMR_RXOK; |
@@ -1161,39 +1161,32 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
1161 | } | 1161 | } |
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) | 1164 | static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) |
1165 | { | 1165 | { |
1166 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { | 1166 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1167 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us); | 1167 | val = min(val, (u32) 0xFFFF); |
1168 | ah->acktimeout = (u32) -1; | 1168 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val); |
1169 | return false; | ||
1170 | } else { | ||
1171 | REG_RMW_FIELD(ah, AR_TIME_OUT, | ||
1172 | AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us)); | ||
1173 | ah->acktimeout = us; | ||
1174 | return true; | ||
1175 | } | ||
1176 | } | 1169 | } |
1177 | 1170 | ||
1178 | static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) | 1171 | static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) |
1179 | { | 1172 | { |
1180 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { | 1173 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1181 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us); | 1174 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK)); |
1182 | ah->ctstimeout = (u32) -1; | 1175 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val); |
1183 | return false; | 1176 | } |
1184 | } else { | 1177 | |
1185 | REG_RMW_FIELD(ah, AR_TIME_OUT, | 1178 | static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) |
1186 | AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); | 1179 | { |
1187 | ah->ctstimeout = us; | 1180 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1188 | return true; | 1181 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS)); |
1189 | } | 1182 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val); |
1190 | } | 1183 | } |
1191 | 1184 | ||
1192 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | 1185 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) |
1193 | { | 1186 | { |
1194 | if (tu > 0xFFFF) { | 1187 | if (tu > 0xFFFF) { |
1195 | DPRINTF(ah->ah_sc, ATH_DBG_XMIT, | 1188 | ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT, |
1196 | "bad global tx timeout %u\n", tu); | 1189 | "bad global tx timeout %u\n", tu); |
1197 | ah->globaltxtimeout = (u32) -1; | 1190 | ah->globaltxtimeout = (u32) -1; |
1198 | return false; | 1191 | return false; |
1199 | } else { | 1192 | } else { |
@@ -1203,40 +1196,66 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | |||
1203 | } | 1196 | } |
1204 | } | 1197 | } |
1205 | 1198 | ||
1206 | static void ath9k_hw_init_user_settings(struct ath_hw *ah) | 1199 | void ath9k_hw_init_global_settings(struct ath_hw *ah) |
1207 | { | 1200 | { |
1208 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n", | 1201 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
1209 | ah->misc_mode); | 1202 | int acktimeout; |
1203 | int slottime; | ||
1204 | int sifstime; | ||
1205 | |||
1206 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", | ||
1207 | ah->misc_mode); | ||
1210 | 1208 | ||
1211 | if (ah->misc_mode != 0) | 1209 | if (ah->misc_mode != 0) |
1212 | REG_WRITE(ah, AR_PCU_MISC, | 1210 | REG_WRITE(ah, AR_PCU_MISC, |
1213 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); | 1211 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); |
1214 | if (ah->slottime != (u32) -1) | 1212 | |
1215 | ath9k_hw_setslottime(ah, ah->slottime); | 1213 | if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) |
1216 | if (ah->acktimeout != (u32) -1) | 1214 | sifstime = 16; |
1217 | ath9k_hw_set_ack_timeout(ah, ah->acktimeout); | 1215 | else |
1218 | if (ah->ctstimeout != (u32) -1) | 1216 | sifstime = 10; |
1219 | ath9k_hw_set_cts_timeout(ah, ah->ctstimeout); | 1217 | |
1218 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ | ||
1219 | slottime = ah->slottime + 3 * ah->coverage_class; | ||
1220 | acktimeout = slottime + sifstime; | ||
1221 | |||
1222 | /* | ||
1223 | * Workaround for early ACK timeouts, add an offset to match the | ||
1224 | * initval's 64us ack timeout value. | ||
1225 | * This was initially only meant to work around an issue with delayed | ||
1226 | * BA frames in some implementations, but it has been found to fix ACK | ||
1227 | * timeout issues in other cases as well. | ||
1228 | */ | ||
1229 | if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) | ||
1230 | acktimeout += 64 - sifstime - ah->slottime; | ||
1231 | |||
1232 | ath9k_hw_setslottime(ah, slottime); | ||
1233 | ath9k_hw_set_ack_timeout(ah, acktimeout); | ||
1234 | ath9k_hw_set_cts_timeout(ah, acktimeout); | ||
1220 | if (ah->globaltxtimeout != (u32) -1) | 1235 | if (ah->globaltxtimeout != (u32) -1) |
1221 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); | 1236 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); |
1222 | } | 1237 | } |
1238 | EXPORT_SYMBOL(ath9k_hw_init_global_settings); | ||
1223 | 1239 | ||
1224 | const char *ath9k_hw_probe(u16 vendorid, u16 devid) | 1240 | void ath9k_hw_deinit(struct ath_hw *ah) |
1225 | { | 1241 | { |
1226 | return vendorid == ATHEROS_VENDOR_ID ? | 1242 | struct ath_common *common = ath9k_hw_common(ah); |
1227 | ath9k_hw_devname(devid) : NULL; | 1243 | |
1228 | } | 1244 | if (common->state <= ATH_HW_INITIALIZED) |
1245 | goto free_hw; | ||
1229 | 1246 | ||
1230 | void ath9k_hw_detach(struct ath_hw *ah) | ||
1231 | { | ||
1232 | if (!AR_SREV_9100(ah)) | 1247 | if (!AR_SREV_9100(ah)) |
1233 | ath9k_hw_ani_disable(ah); | 1248 | ath9k_hw_ani_disable(ah); |
1234 | 1249 | ||
1235 | ath9k_hw_rf_free(ah); | ||
1236 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 1250 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); |
1251 | |||
1252 | free_hw: | ||
1253 | if (!AR_SREV_9280_10_OR_LATER(ah)) | ||
1254 | ath9k_hw_rf_free_ext_banks(ah); | ||
1237 | kfree(ah); | 1255 | kfree(ah); |
1238 | ah = NULL; | 1256 | ah = NULL; |
1239 | } | 1257 | } |
1258 | EXPORT_SYMBOL(ath9k_hw_deinit); | ||
1240 | 1259 | ||
1241 | /*******/ | 1260 | /*******/ |
1242 | /* INI */ | 1261 | /* INI */ |
@@ -1254,7 +1273,8 @@ static void ath9k_hw_override_ini(struct ath_hw *ah, | |||
1254 | * AR9271 1.1 | 1273 | * AR9271 1.1 |
1255 | */ | 1274 | */ |
1256 | if (AR_SREV_9271_10(ah)) { | 1275 | if (AR_SREV_9271_10(ah)) { |
1257 | val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) | AR_PHY_SPECTRAL_SCAN_ENABLE; | 1276 | val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) | |
1277 | AR_PHY_SPECTRAL_SCAN_ENABLE; | ||
1258 | REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); | 1278 | REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); |
1259 | } | 1279 | } |
1260 | else if (AR_SREV_9271_11(ah)) | 1280 | else if (AR_SREV_9271_11(ah)) |
@@ -1291,6 +1311,16 @@ static void ath9k_hw_override_ini(struct ath_hw *ah, | |||
1291 | * Necessary to avoid issues on AR5416 2.0 | 1311 | * Necessary to avoid issues on AR5416 2.0 |
1292 | */ | 1312 | */ |
1293 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); | 1313 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); |
1314 | |||
1315 | /* | ||
1316 | * Disable RIFS search on some chips to avoid baseband | ||
1317 | * hang issues. | ||
1318 | */ | ||
1319 | if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) { | ||
1320 | val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); | ||
1321 | val &= ~AR_PHY_RIFS_INIT_DELAY; | ||
1322 | REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); | ||
1323 | } | ||
1294 | } | 1324 | } |
1295 | 1325 | ||
1296 | static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, | 1326 | static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, |
@@ -1298,28 +1328,29 @@ static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, | |||
1298 | u32 reg, u32 value) | 1328 | u32 reg, u32 value) |
1299 | { | 1329 | { |
1300 | struct base_eep_header *pBase = &(pEepData->baseEepHeader); | 1330 | struct base_eep_header *pBase = &(pEepData->baseEepHeader); |
1331 | struct ath_common *common = ath9k_hw_common(ah); | ||
1301 | 1332 | ||
1302 | switch (ah->hw_version.devid) { | 1333 | switch (ah->hw_version.devid) { |
1303 | case AR9280_DEVID_PCI: | 1334 | case AR9280_DEVID_PCI: |
1304 | if (reg == 0x7894) { | 1335 | if (reg == 0x7894) { |
1305 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 1336 | ath_print(common, ATH_DBG_EEPROM, |
1306 | "ini VAL: %x EEPROM: %x\n", value, | 1337 | "ini VAL: %x EEPROM: %x\n", value, |
1307 | (pBase->version & 0xff)); | 1338 | (pBase->version & 0xff)); |
1308 | 1339 | ||
1309 | if ((pBase->version & 0xff) > 0x0a) { | 1340 | if ((pBase->version & 0xff) > 0x0a) { |
1310 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 1341 | ath_print(common, ATH_DBG_EEPROM, |
1311 | "PWDCLKIND: %d\n", | 1342 | "PWDCLKIND: %d\n", |
1312 | pBase->pwdclkind); | 1343 | pBase->pwdclkind); |
1313 | value &= ~AR_AN_TOP2_PWDCLKIND; | 1344 | value &= ~AR_AN_TOP2_PWDCLKIND; |
1314 | value |= AR_AN_TOP2_PWDCLKIND & | 1345 | value |= AR_AN_TOP2_PWDCLKIND & |
1315 | (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S); | 1346 | (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S); |
1316 | } else { | 1347 | } else { |
1317 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 1348 | ath_print(common, ATH_DBG_EEPROM, |
1318 | "PWDCLKIND Earlier Rev\n"); | 1349 | "PWDCLKIND Earlier Rev\n"); |
1319 | } | 1350 | } |
1320 | 1351 | ||
1321 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 1352 | ath_print(common, ATH_DBG_EEPROM, |
1322 | "final ini VAL: %x\n", value); | 1353 | "final ini VAL: %x\n", value); |
1323 | } | 1354 | } |
1324 | break; | 1355 | break; |
1325 | } | 1356 | } |
@@ -1374,8 +1405,7 @@ static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, | |||
1374 | } | 1405 | } |
1375 | 1406 | ||
1376 | static int ath9k_hw_process_ini(struct ath_hw *ah, | 1407 | static int ath9k_hw_process_ini(struct ath_hw *ah, |
1377 | struct ath9k_channel *chan, | 1408 | struct ath9k_channel *chan) |
1378 | enum ath9k_ht_macmode macmode) | ||
1379 | { | 1409 | { |
1380 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 1410 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
1381 | int i, regWrites = 0; | 1411 | int i, regWrites = 0; |
@@ -1469,7 +1499,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, | |||
1469 | DO_DELAY(regWrites); | 1499 | DO_DELAY(regWrites); |
1470 | } | 1500 | } |
1471 | 1501 | ||
1472 | ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites); | 1502 | ath9k_hw_write_regs(ah, freqIndex, regWrites); |
1503 | |||
1504 | if (AR_SREV_9271_10(ah)) | ||
1505 | REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only, | ||
1506 | modesIndex, regWrites); | ||
1473 | 1507 | ||
1474 | if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { | 1508 | if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { |
1475 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, | 1509 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, |
@@ -1477,7 +1511,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, | |||
1477 | } | 1511 | } |
1478 | 1512 | ||
1479 | ath9k_hw_override_ini(ah, chan); | 1513 | ath9k_hw_override_ini(ah, chan); |
1480 | ath9k_hw_set_regs(ah, chan, macmode); | 1514 | ath9k_hw_set_regs(ah, chan); |
1481 | ath9k_hw_init_chain_masks(ah); | 1515 | ath9k_hw_init_chain_masks(ah); |
1482 | 1516 | ||
1483 | if (OLC_FOR_AR9280_20_LATER) | 1517 | if (OLC_FOR_AR9280_20_LATER) |
@@ -1491,8 +1525,8 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, | |||
1491 | (u32) regulatory->power_limit)); | 1525 | (u32) regulatory->power_limit)); |
1492 | 1526 | ||
1493 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { | 1527 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { |
1494 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 1528 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, |
1495 | "ar5416SetRfRegs failed\n"); | 1529 | "ar5416SetRfRegs failed\n"); |
1496 | return -EIO; | 1530 | return -EIO; |
1497 | } | 1531 | } |
1498 | 1532 | ||
@@ -1697,16 +1731,14 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1697 | 1731 | ||
1698 | REG_WRITE(ah, AR_RTC_RC, 0); | 1732 | REG_WRITE(ah, AR_RTC_RC, 0); |
1699 | if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) { | 1733 | if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) { |
1700 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 1734 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, |
1701 | "RTC stuck in MAC reset\n"); | 1735 | "RTC stuck in MAC reset\n"); |
1702 | return false; | 1736 | return false; |
1703 | } | 1737 | } |
1704 | 1738 | ||
1705 | if (!AR_SREV_9100(ah)) | 1739 | if (!AR_SREV_9100(ah)) |
1706 | REG_WRITE(ah, AR_RC, 0); | 1740 | REG_WRITE(ah, AR_RC, 0); |
1707 | 1741 | ||
1708 | ath9k_hw_init_pll(ah, NULL); | ||
1709 | |||
1710 | if (AR_SREV_9100(ah)) | 1742 | if (AR_SREV_9100(ah)) |
1711 | udelay(50); | 1743 | udelay(50); |
1712 | 1744 | ||
@@ -1734,7 +1766,8 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | |||
1734 | AR_RTC_STATUS_M, | 1766 | AR_RTC_STATUS_M, |
1735 | AR_RTC_STATUS_ON, | 1767 | AR_RTC_STATUS_ON, |
1736 | AH_WAIT_TIMEOUT)) { | 1768 | AH_WAIT_TIMEOUT)) { |
1737 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n"); | 1769 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, |
1770 | "RTC not waking up\n"); | ||
1738 | return false; | 1771 | return false; |
1739 | } | 1772 | } |
1740 | 1773 | ||
@@ -1759,8 +1792,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | |||
1759 | } | 1792 | } |
1760 | } | 1793 | } |
1761 | 1794 | ||
1762 | static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan, | 1795 | static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan) |
1763 | enum ath9k_ht_macmode macmode) | ||
1764 | { | 1796 | { |
1765 | u32 phymode; | 1797 | u32 phymode; |
1766 | u32 enableDacFifo = 0; | 1798 | u32 enableDacFifo = 0; |
@@ -1779,12 +1811,10 @@ static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1779 | (chan->chanmode == CHANNEL_G_HT40PLUS)) | 1811 | (chan->chanmode == CHANNEL_G_HT40PLUS)) |
1780 | phymode |= AR_PHY_FC_DYN2040_PRI_CH; | 1812 | phymode |= AR_PHY_FC_DYN2040_PRI_CH; |
1781 | 1813 | ||
1782 | if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25) | ||
1783 | phymode |= AR_PHY_FC_DYN2040_EXT_CH; | ||
1784 | } | 1814 | } |
1785 | REG_WRITE(ah, AR_PHY_TURBO, phymode); | 1815 | REG_WRITE(ah, AR_PHY_TURBO, phymode); |
1786 | 1816 | ||
1787 | ath9k_hw_set11nmac2040(ah, macmode); | 1817 | ath9k_hw_set11nmac2040(ah); |
1788 | 1818 | ||
1789 | REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); | 1819 | REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); |
1790 | REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); | 1820 | REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); |
@@ -1810,17 +1840,19 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah, | |||
1810 | } | 1840 | } |
1811 | 1841 | ||
1812 | static bool ath9k_hw_channel_change(struct ath_hw *ah, | 1842 | static bool ath9k_hw_channel_change(struct ath_hw *ah, |
1813 | struct ath9k_channel *chan, | 1843 | struct ath9k_channel *chan) |
1814 | enum ath9k_ht_macmode macmode) | ||
1815 | { | 1844 | { |
1816 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 1845 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
1846 | struct ath_common *common = ath9k_hw_common(ah); | ||
1817 | struct ieee80211_channel *channel = chan->chan; | 1847 | struct ieee80211_channel *channel = chan->chan; |
1818 | u32 synthDelay, qnum; | 1848 | u32 synthDelay, qnum; |
1849 | int r; | ||
1819 | 1850 | ||
1820 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { | 1851 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { |
1821 | if (ath9k_hw_numtxpending(ah, qnum)) { | 1852 | if (ath9k_hw_numtxpending(ah, qnum)) { |
1822 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | 1853 | ath_print(common, ATH_DBG_QUEUE, |
1823 | "Transmit frames pending on queue %d\n", qnum); | 1854 | "Transmit frames pending on " |
1855 | "queue %d\n", qnum); | ||
1824 | return false; | 1856 | return false; |
1825 | } | 1857 | } |
1826 | } | 1858 | } |
@@ -1828,21 +1860,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1828 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); | 1860 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); |
1829 | if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, | 1861 | if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, |
1830 | AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) { | 1862 | AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) { |
1831 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 1863 | ath_print(common, ATH_DBG_FATAL, |
1832 | "Could not kill baseband RX\n"); | 1864 | "Could not kill baseband RX\n"); |
1833 | return false; | 1865 | return false; |
1834 | } | 1866 | } |
1835 | 1867 | ||
1836 | ath9k_hw_set_regs(ah, chan, macmode); | 1868 | ath9k_hw_set_regs(ah, chan); |
1837 | 1869 | ||
1838 | if (AR_SREV_9280_10_OR_LATER(ah)) { | 1870 | r = ah->ath9k_hw_rf_set_freq(ah, chan); |
1839 | ath9k_hw_ar9280_set_channel(ah, chan); | 1871 | if (r) { |
1840 | } else { | 1872 | ath_print(common, ATH_DBG_FATAL, |
1841 | if (!(ath9k_hw_set_channel(ah, chan))) { | 1873 | "Failed to set channel\n"); |
1842 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 1874 | return false; |
1843 | "Failed to set channel\n"); | ||
1844 | return false; | ||
1845 | } | ||
1846 | } | 1875 | } |
1847 | 1876 | ||
1848 | ah->eep_ops->set_txpower(ah, chan, | 1877 | ah->eep_ops->set_txpower(ah, chan, |
@@ -1865,10 +1894,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1865 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) | 1894 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) |
1866 | ath9k_hw_set_delta_slope(ah, chan); | 1895 | ath9k_hw_set_delta_slope(ah, chan); |
1867 | 1896 | ||
1868 | if (AR_SREV_9280_10_OR_LATER(ah)) | 1897 | ah->ath9k_hw_spur_mitigate_freq(ah, chan); |
1869 | ath9k_hw_9280_spur_mitigate(ah, chan); | ||
1870 | else | ||
1871 | ath9k_hw_spur_mitigate(ah, chan); | ||
1872 | 1898 | ||
1873 | if (!chan->oneTimeCalsDone) | 1899 | if (!chan->oneTimeCalsDone) |
1874 | chan->oneTimeCalsDone = true; | 1900 | chan->oneTimeCalsDone = true; |
@@ -1876,457 +1902,6 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1876 | return true; | 1902 | return true; |
1877 | } | 1903 | } |
1878 | 1904 | ||
1879 | static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1880 | { | ||
1881 | int bb_spur = AR_NO_SPUR; | ||
1882 | int freq; | ||
1883 | int bin, cur_bin; | ||
1884 | int bb_spur_off, spur_subchannel_sd; | ||
1885 | int spur_freq_sd; | ||
1886 | int spur_delta_phase; | ||
1887 | int denominator; | ||
1888 | int upper, lower, cur_vit_mask; | ||
1889 | int tmp, newVal; | ||
1890 | int i; | ||
1891 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
1892 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
1893 | }; | ||
1894 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
1895 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
1896 | }; | ||
1897 | int inc[4] = { 0, 100, 0, 0 }; | ||
1898 | struct chan_centers centers; | ||
1899 | |||
1900 | int8_t mask_m[123]; | ||
1901 | int8_t mask_p[123]; | ||
1902 | int8_t mask_amt; | ||
1903 | int tmp_mask; | ||
1904 | int cur_bb_spur; | ||
1905 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
1906 | |||
1907 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
1908 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
1909 | |||
1910 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
1911 | freq = centers.synth_center; | ||
1912 | |||
1913 | ah->config.spurmode = SPUR_ENABLE_EEPROM; | ||
1914 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
1915 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
1916 | |||
1917 | if (is2GHz) | ||
1918 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; | ||
1919 | else | ||
1920 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; | ||
1921 | |||
1922 | if (AR_NO_SPUR == cur_bb_spur) | ||
1923 | break; | ||
1924 | cur_bb_spur = cur_bb_spur - freq; | ||
1925 | |||
1926 | if (IS_CHAN_HT40(chan)) { | ||
1927 | if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && | ||
1928 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { | ||
1929 | bb_spur = cur_bb_spur; | ||
1930 | break; | ||
1931 | } | ||
1932 | } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && | ||
1933 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { | ||
1934 | bb_spur = cur_bb_spur; | ||
1935 | break; | ||
1936 | } | ||
1937 | } | ||
1938 | |||
1939 | if (AR_NO_SPUR == bb_spur) { | ||
1940 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
1941 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
1942 | return; | ||
1943 | } else { | ||
1944 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
1945 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
1946 | } | ||
1947 | |||
1948 | bin = bb_spur * 320; | ||
1949 | |||
1950 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
1951 | |||
1952 | newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
1953 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
1954 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
1955 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
1956 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal); | ||
1957 | |||
1958 | newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
1959 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
1960 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
1961 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
1962 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
1963 | REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); | ||
1964 | |||
1965 | if (IS_CHAN_HT40(chan)) { | ||
1966 | if (bb_spur < 0) { | ||
1967 | spur_subchannel_sd = 1; | ||
1968 | bb_spur_off = bb_spur + 10; | ||
1969 | } else { | ||
1970 | spur_subchannel_sd = 0; | ||
1971 | bb_spur_off = bb_spur - 10; | ||
1972 | } | ||
1973 | } else { | ||
1974 | spur_subchannel_sd = 0; | ||
1975 | bb_spur_off = bb_spur; | ||
1976 | } | ||
1977 | |||
1978 | if (IS_CHAN_HT40(chan)) | ||
1979 | spur_delta_phase = | ||
1980 | ((bb_spur * 262144) / | ||
1981 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
1982 | else | ||
1983 | spur_delta_phase = | ||
1984 | ((bb_spur * 524288) / | ||
1985 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
1986 | |||
1987 | denominator = IS_CHAN_2GHZ(chan) ? 44 : 40; | ||
1988 | spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; | ||
1989 | |||
1990 | newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
1991 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
1992 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
1993 | REG_WRITE(ah, AR_PHY_TIMING11, newVal); | ||
1994 | |||
1995 | newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; | ||
1996 | REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); | ||
1997 | |||
1998 | cur_bin = -6000; | ||
1999 | upper = bin + 100; | ||
2000 | lower = bin - 100; | ||
2001 | |||
2002 | for (i = 0; i < 4; i++) { | ||
2003 | int pilot_mask = 0; | ||
2004 | int chan_mask = 0; | ||
2005 | int bp = 0; | ||
2006 | for (bp = 0; bp < 30; bp++) { | ||
2007 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
2008 | pilot_mask = pilot_mask | 0x1 << bp; | ||
2009 | chan_mask = chan_mask | 0x1 << bp; | ||
2010 | } | ||
2011 | cur_bin += 100; | ||
2012 | } | ||
2013 | cur_bin += inc[i]; | ||
2014 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
2015 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
2016 | } | ||
2017 | |||
2018 | cur_vit_mask = 6100; | ||
2019 | upper = bin + 120; | ||
2020 | lower = bin - 120; | ||
2021 | |||
2022 | for (i = 0; i < 123; i++) { | ||
2023 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
2024 | |||
2025 | /* workaround for gcc bug #37014 */ | ||
2026 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
2027 | |||
2028 | if (tmp_v < 75) | ||
2029 | mask_amt = 1; | ||
2030 | else | ||
2031 | mask_amt = 0; | ||
2032 | if (cur_vit_mask < 0) | ||
2033 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
2034 | else | ||
2035 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
2036 | } | ||
2037 | cur_vit_mask -= 100; | ||
2038 | } | ||
2039 | |||
2040 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
2041 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
2042 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
2043 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
2044 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
2045 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
2046 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
2047 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
2048 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
2049 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
2050 | |||
2051 | tmp_mask = (mask_m[31] << 28) | ||
2052 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
2053 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
2054 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
2055 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
2056 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
2057 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
2058 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
2059 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
2060 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
2061 | |||
2062 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
2063 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
2064 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
2065 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
2066 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
2067 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
2068 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
2069 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
2070 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
2071 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
2072 | |||
2073 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
2074 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
2075 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
2076 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
2077 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
2078 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
2079 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
2080 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
2081 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
2082 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
2083 | |||
2084 | tmp_mask = (mask_p[15] << 28) | ||
2085 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
2086 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
2087 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
2088 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
2089 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
2090 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
2091 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
2092 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
2093 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
2094 | |||
2095 | tmp_mask = (mask_p[30] << 28) | ||
2096 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
2097 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
2098 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
2099 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
2100 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
2101 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
2102 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
2103 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
2104 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
2105 | |||
2106 | tmp_mask = (mask_p[45] << 28) | ||
2107 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
2108 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
2109 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
2110 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
2111 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
2112 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
2113 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
2114 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
2115 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
2116 | |||
2117 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
2118 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
2119 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
2120 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
2121 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
2122 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
2123 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
2124 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
2125 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
2126 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
2127 | } | ||
2128 | |||
2129 | static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) | ||
2130 | { | ||
2131 | int bb_spur = AR_NO_SPUR; | ||
2132 | int bin, cur_bin; | ||
2133 | int spur_freq_sd; | ||
2134 | int spur_delta_phase; | ||
2135 | int denominator; | ||
2136 | int upper, lower, cur_vit_mask; | ||
2137 | int tmp, new; | ||
2138 | int i; | ||
2139 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
2140 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
2141 | }; | ||
2142 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
2143 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
2144 | }; | ||
2145 | int inc[4] = { 0, 100, 0, 0 }; | ||
2146 | |||
2147 | int8_t mask_m[123]; | ||
2148 | int8_t mask_p[123]; | ||
2149 | int8_t mask_amt; | ||
2150 | int tmp_mask; | ||
2151 | int cur_bb_spur; | ||
2152 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
2153 | |||
2154 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
2155 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
2156 | |||
2157 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
2158 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
2159 | if (AR_NO_SPUR == cur_bb_spur) | ||
2160 | break; | ||
2161 | cur_bb_spur = cur_bb_spur - (chan->channel * 10); | ||
2162 | if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) { | ||
2163 | bb_spur = cur_bb_spur; | ||
2164 | break; | ||
2165 | } | ||
2166 | } | ||
2167 | |||
2168 | if (AR_NO_SPUR == bb_spur) | ||
2169 | return; | ||
2170 | |||
2171 | bin = bb_spur * 32; | ||
2172 | |||
2173 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
2174 | new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
2175 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
2176 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
2177 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
2178 | |||
2179 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new); | ||
2180 | |||
2181 | new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
2182 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
2183 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
2184 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
2185 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
2186 | REG_WRITE(ah, AR_PHY_SPUR_REG, new); | ||
2187 | |||
2188 | spur_delta_phase = ((bb_spur * 524288) / 100) & | ||
2189 | AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
2190 | |||
2191 | denominator = IS_CHAN_2GHZ(chan) ? 440 : 400; | ||
2192 | spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff; | ||
2193 | |||
2194 | new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
2195 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
2196 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
2197 | REG_WRITE(ah, AR_PHY_TIMING11, new); | ||
2198 | |||
2199 | cur_bin = -6000; | ||
2200 | upper = bin + 100; | ||
2201 | lower = bin - 100; | ||
2202 | |||
2203 | for (i = 0; i < 4; i++) { | ||
2204 | int pilot_mask = 0; | ||
2205 | int chan_mask = 0; | ||
2206 | int bp = 0; | ||
2207 | for (bp = 0; bp < 30; bp++) { | ||
2208 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
2209 | pilot_mask = pilot_mask | 0x1 << bp; | ||
2210 | chan_mask = chan_mask | 0x1 << bp; | ||
2211 | } | ||
2212 | cur_bin += 100; | ||
2213 | } | ||
2214 | cur_bin += inc[i]; | ||
2215 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
2216 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
2217 | } | ||
2218 | |||
2219 | cur_vit_mask = 6100; | ||
2220 | upper = bin + 120; | ||
2221 | lower = bin - 120; | ||
2222 | |||
2223 | for (i = 0; i < 123; i++) { | ||
2224 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
2225 | |||
2226 | /* workaround for gcc bug #37014 */ | ||
2227 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
2228 | |||
2229 | if (tmp_v < 75) | ||
2230 | mask_amt = 1; | ||
2231 | else | ||
2232 | mask_amt = 0; | ||
2233 | if (cur_vit_mask < 0) | ||
2234 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
2235 | else | ||
2236 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
2237 | } | ||
2238 | cur_vit_mask -= 100; | ||
2239 | } | ||
2240 | |||
2241 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
2242 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
2243 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
2244 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
2245 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
2246 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
2247 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
2248 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
2249 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
2250 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
2251 | |||
2252 | tmp_mask = (mask_m[31] << 28) | ||
2253 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
2254 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
2255 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
2256 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
2257 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
2258 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
2259 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
2260 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
2261 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
2262 | |||
2263 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
2264 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
2265 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
2266 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
2267 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
2268 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
2269 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
2270 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
2271 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
2272 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
2273 | |||
2274 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
2275 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
2276 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
2277 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
2278 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
2279 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
2280 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
2281 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
2282 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
2283 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
2284 | |||
2285 | tmp_mask = (mask_p[15] << 28) | ||
2286 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
2287 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
2288 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
2289 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
2290 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
2291 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
2292 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
2293 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
2294 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
2295 | |||
2296 | tmp_mask = (mask_p[30] << 28) | ||
2297 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
2298 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
2299 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
2300 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
2301 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
2302 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
2303 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
2304 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
2305 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
2306 | |||
2307 | tmp_mask = (mask_p[45] << 28) | ||
2308 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
2309 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
2310 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
2311 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
2312 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
2313 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
2314 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
2315 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
2316 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
2317 | |||
2318 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
2319 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
2320 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
2321 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
2322 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
2323 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
2324 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
2325 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
2326 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
2327 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
2328 | } | ||
2329 | |||
2330 | static void ath9k_enable_rfkill(struct ath_hw *ah) | 1905 | static void ath9k_enable_rfkill(struct ath_hw *ah) |
2331 | { | 1906 | { |
2332 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | 1907 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, |
@@ -2342,17 +1917,16 @@ static void ath9k_enable_rfkill(struct ath_hw *ah) | |||
2342 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 1917 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
2343 | bool bChannelChange) | 1918 | bool bChannelChange) |
2344 | { | 1919 | { |
1920 | struct ath_common *common = ath9k_hw_common(ah); | ||
2345 | u32 saveLedState; | 1921 | u32 saveLedState; |
2346 | struct ath_softc *sc = ah->ah_sc; | ||
2347 | struct ath9k_channel *curchan = ah->curchan; | 1922 | struct ath9k_channel *curchan = ah->curchan; |
2348 | u32 saveDefAntenna; | 1923 | u32 saveDefAntenna; |
2349 | u32 macStaId1; | 1924 | u32 macStaId1; |
2350 | u64 tsf = 0; | 1925 | u64 tsf = 0; |
2351 | int i, rx_chainmask, r; | 1926 | int i, rx_chainmask, r; |
2352 | 1927 | ||
2353 | ah->extprotspacing = sc->ht_extprotspacing; | 1928 | ah->txchainmask = common->tx_chainmask; |
2354 | ah->txchainmask = sc->tx_chainmask; | 1929 | ah->rxchainmask = common->rx_chainmask; |
2355 | ah->rxchainmask = sc->rx_chainmask; | ||
2356 | 1930 | ||
2357 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 1931 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
2358 | return -EIO; | 1932 | return -EIO; |
@@ -2369,7 +1943,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2369 | !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) || | 1943 | !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) || |
2370 | IS_CHAN_A_5MHZ_SPACED(ah->curchan))) { | 1944 | IS_CHAN_A_5MHZ_SPACED(ah->curchan))) { |
2371 | 1945 | ||
2372 | if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) { | 1946 | if (ath9k_hw_channel_change(ah, chan)) { |
2373 | ath9k_hw_loadnf(ah, ah->curchan); | 1947 | ath9k_hw_loadnf(ah, ah->curchan); |
2374 | ath9k_hw_start_nfcal(ah); | 1948 | ath9k_hw_start_nfcal(ah); |
2375 | return 0; | 1949 | return 0; |
@@ -2400,7 +1974,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2400 | } | 1974 | } |
2401 | 1975 | ||
2402 | if (!ath9k_hw_chip_reset(ah, chan)) { | 1976 | if (!ath9k_hw_chip_reset(ah, chan)) { |
2403 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n"); | 1977 | ath_print(common, ATH_DBG_FATAL, "Chip reset failed\n"); |
2404 | return -EINVAL; | 1978 | return -EINVAL; |
2405 | } | 1979 | } |
2406 | 1980 | ||
@@ -2429,7 +2003,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2429 | REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, | 2003 | REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, |
2430 | AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); | 2004 | AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); |
2431 | } | 2005 | } |
2432 | r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width); | 2006 | r = ath9k_hw_process_ini(ah, chan); |
2433 | if (r) | 2007 | if (r) |
2434 | return r; | 2008 | return r; |
2435 | 2009 | ||
@@ -2453,17 +2027,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2453 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) | 2027 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) |
2454 | ath9k_hw_set_delta_slope(ah, chan); | 2028 | ath9k_hw_set_delta_slope(ah, chan); |
2455 | 2029 | ||
2456 | if (AR_SREV_9280_10_OR_LATER(ah)) | 2030 | ah->ath9k_hw_spur_mitigate_freq(ah, chan); |
2457 | ath9k_hw_9280_spur_mitigate(ah, chan); | ||
2458 | else | ||
2459 | ath9k_hw_spur_mitigate(ah, chan); | ||
2460 | |||
2461 | ah->eep_ops->set_board_values(ah, chan); | 2031 | ah->eep_ops->set_board_values(ah, chan); |
2462 | 2032 | ||
2463 | ath9k_hw_decrease_chain_power(ah, chan); | 2033 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); |
2464 | 2034 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) | |
2465 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr)); | ||
2466 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4) | ||
2467 | | macStaId1 | 2035 | | macStaId1 |
2468 | | AR_STA_ID1_RTS_USE_DEF | 2036 | | AR_STA_ID1_RTS_USE_DEF |
2469 | | (ah->config. | 2037 | | (ah->config. |
@@ -2471,24 +2039,19 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2471 | | ah->sta_id1_defaults); | 2039 | | ah->sta_id1_defaults); |
2472 | ath9k_hw_set_operating_mode(ah, ah->opmode); | 2040 | ath9k_hw_set_operating_mode(ah, ah->opmode); |
2473 | 2041 | ||
2474 | REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask)); | 2042 | ath_hw_setbssidmask(common); |
2475 | REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4)); | ||
2476 | 2043 | ||
2477 | REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); | 2044 | REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); |
2478 | 2045 | ||
2479 | REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid)); | 2046 | ath9k_hw_write_associd(ah); |
2480 | REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) | | ||
2481 | ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S)); | ||
2482 | 2047 | ||
2483 | REG_WRITE(ah, AR_ISR, ~0); | 2048 | REG_WRITE(ah, AR_ISR, ~0); |
2484 | 2049 | ||
2485 | REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); | 2050 | REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); |
2486 | 2051 | ||
2487 | if (AR_SREV_9280_10_OR_LATER(ah)) | 2052 | r = ah->ath9k_hw_rf_set_freq(ah, chan); |
2488 | ath9k_hw_ar9280_set_channel(ah, chan); | 2053 | if (r) |
2489 | else | 2054 | return r; |
2490 | if (!(ath9k_hw_set_channel(ah, chan))) | ||
2491 | return -EIO; | ||
2492 | 2055 | ||
2493 | for (i = 0; i < AR_NUM_DCU; i++) | 2056 | for (i = 0; i < AR_NUM_DCU; i++) |
2494 | REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); | 2057 | REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); |
@@ -2503,7 +2066,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2503 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | 2066 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) |
2504 | ath9k_enable_rfkill(ah); | 2067 | ath9k_enable_rfkill(ah); |
2505 | 2068 | ||
2506 | ath9k_hw_init_user_settings(ah); | 2069 | ath9k_hw_init_global_settings(ah); |
2507 | 2070 | ||
2508 | if (AR_SREV_9287_12_OR_LATER(ah)) { | 2071 | if (AR_SREV_9287_12_OR_LATER(ah)) { |
2509 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, | 2072 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, |
@@ -2533,7 +2096,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2533 | 2096 | ||
2534 | REG_WRITE(ah, AR_OBS, 8); | 2097 | REG_WRITE(ah, AR_OBS, 8); |
2535 | 2098 | ||
2536 | if (ah->config.intr_mitigation) { | 2099 | if (ah->config.rx_intr_mitigation) { |
2537 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); | 2100 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); |
2538 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); | 2101 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); |
2539 | } | 2102 | } |
@@ -2558,13 +2121,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2558 | u32 mask; | 2121 | u32 mask; |
2559 | mask = REG_READ(ah, AR_CFG); | 2122 | mask = REG_READ(ah, AR_CFG); |
2560 | if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { | 2123 | if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { |
2561 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 2124 | ath_print(common, ATH_DBG_RESET, |
2562 | "CFG Byte Swap Set 0x%x\n", mask); | 2125 | "CFG Byte Swap Set 0x%x\n", mask); |
2563 | } else { | 2126 | } else { |
2564 | mask = | 2127 | mask = |
2565 | INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; | 2128 | INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; |
2566 | REG_WRITE(ah, AR_CFG, mask); | 2129 | REG_WRITE(ah, AR_CFG, mask); |
2567 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 2130 | ath_print(common, ATH_DBG_RESET, |
2568 | "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); | 2131 | "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); |
2569 | } | 2132 | } |
2570 | } else { | 2133 | } else { |
@@ -2577,11 +2140,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2577 | #endif | 2140 | #endif |
2578 | } | 2141 | } |
2579 | 2142 | ||
2580 | if (ah->ah_sc->sc_flags & SC_OP_BTCOEX_ENABLED) | 2143 | if (ah->btcoex_hw.enabled) |
2581 | ath9k_hw_btcoex_enable(ah); | 2144 | ath9k_hw_btcoex_enable(ah); |
2582 | 2145 | ||
2583 | return 0; | 2146 | return 0; |
2584 | } | 2147 | } |
2148 | EXPORT_SYMBOL(ath9k_hw_reset); | ||
2585 | 2149 | ||
2586 | /************************/ | 2150 | /************************/ |
2587 | /* Key Cache Management */ | 2151 | /* Key Cache Management */ |
@@ -2592,8 +2156,8 @@ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry) | |||
2592 | u32 keyType; | 2156 | u32 keyType; |
2593 | 2157 | ||
2594 | if (entry >= ah->caps.keycache_size) { | 2158 | if (entry >= ah->caps.keycache_size) { |
2595 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 2159 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, |
2596 | "keychache entry %u out of range\n", entry); | 2160 | "keychache entry %u out of range\n", entry); |
2597 | return false; | 2161 | return false; |
2598 | } | 2162 | } |
2599 | 2163 | ||
@@ -2620,14 +2184,15 @@ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry) | |||
2620 | 2184 | ||
2621 | return true; | 2185 | return true; |
2622 | } | 2186 | } |
2187 | EXPORT_SYMBOL(ath9k_hw_keyreset); | ||
2623 | 2188 | ||
2624 | bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) | 2189 | bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) |
2625 | { | 2190 | { |
2626 | u32 macHi, macLo; | 2191 | u32 macHi, macLo; |
2627 | 2192 | ||
2628 | if (entry >= ah->caps.keycache_size) { | 2193 | if (entry >= ah->caps.keycache_size) { |
2629 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 2194 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, |
2630 | "keychache entry %u out of range\n", entry); | 2195 | "keychache entry %u out of range\n", entry); |
2631 | return false; | 2196 | return false; |
2632 | } | 2197 | } |
2633 | 2198 | ||
@@ -2648,18 +2213,20 @@ bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) | |||
2648 | 2213 | ||
2649 | return true; | 2214 | return true; |
2650 | } | 2215 | } |
2216 | EXPORT_SYMBOL(ath9k_hw_keysetmac); | ||
2651 | 2217 | ||
2652 | bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | 2218 | bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, |
2653 | const struct ath9k_keyval *k, | 2219 | const struct ath9k_keyval *k, |
2654 | const u8 *mac) | 2220 | const u8 *mac) |
2655 | { | 2221 | { |
2656 | const struct ath9k_hw_capabilities *pCap = &ah->caps; | 2222 | const struct ath9k_hw_capabilities *pCap = &ah->caps; |
2223 | struct ath_common *common = ath9k_hw_common(ah); | ||
2657 | u32 key0, key1, key2, key3, key4; | 2224 | u32 key0, key1, key2, key3, key4; |
2658 | u32 keyType; | 2225 | u32 keyType; |
2659 | 2226 | ||
2660 | if (entry >= pCap->keycache_size) { | 2227 | if (entry >= pCap->keycache_size) { |
2661 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 2228 | ath_print(common, ATH_DBG_FATAL, |
2662 | "keycache entry %u out of range\n", entry); | 2229 | "keycache entry %u out of range\n", entry); |
2663 | return false; | 2230 | return false; |
2664 | } | 2231 | } |
2665 | 2232 | ||
@@ -2669,9 +2236,9 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | |||
2669 | break; | 2236 | break; |
2670 | case ATH9K_CIPHER_AES_CCM: | 2237 | case ATH9K_CIPHER_AES_CCM: |
2671 | if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { | 2238 | if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { |
2672 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 2239 | ath_print(common, ATH_DBG_ANY, |
2673 | "AES-CCM not supported by mac rev 0x%x\n", | 2240 | "AES-CCM not supported by mac rev 0x%x\n", |
2674 | ah->hw_version.macRev); | 2241 | ah->hw_version.macRev); |
2675 | return false; | 2242 | return false; |
2676 | } | 2243 | } |
2677 | keyType = AR_KEYTABLE_TYPE_CCM; | 2244 | keyType = AR_KEYTABLE_TYPE_CCM; |
@@ -2680,15 +2247,15 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | |||
2680 | keyType = AR_KEYTABLE_TYPE_TKIP; | 2247 | keyType = AR_KEYTABLE_TYPE_TKIP; |
2681 | if (ATH9K_IS_MIC_ENABLED(ah) | 2248 | if (ATH9K_IS_MIC_ENABLED(ah) |
2682 | && entry + 64 >= pCap->keycache_size) { | 2249 | && entry + 64 >= pCap->keycache_size) { |
2683 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 2250 | ath_print(common, ATH_DBG_ANY, |
2684 | "entry %u inappropriate for TKIP\n", entry); | 2251 | "entry %u inappropriate for TKIP\n", entry); |
2685 | return false; | 2252 | return false; |
2686 | } | 2253 | } |
2687 | break; | 2254 | break; |
2688 | case ATH9K_CIPHER_WEP: | 2255 | case ATH9K_CIPHER_WEP: |
2689 | if (k->kv_len < WLAN_KEY_LEN_WEP40) { | 2256 | if (k->kv_len < WLAN_KEY_LEN_WEP40) { |
2690 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 2257 | ath_print(common, ATH_DBG_ANY, |
2691 | "WEP key length %u too small\n", k->kv_len); | 2258 | "WEP key length %u too small\n", k->kv_len); |
2692 | return false; | 2259 | return false; |
2693 | } | 2260 | } |
2694 | if (k->kv_len <= WLAN_KEY_LEN_WEP40) | 2261 | if (k->kv_len <= WLAN_KEY_LEN_WEP40) |
@@ -2702,8 +2269,8 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | |||
2702 | keyType = AR_KEYTABLE_TYPE_CLR; | 2269 | keyType = AR_KEYTABLE_TYPE_CLR; |
2703 | break; | 2270 | break; |
2704 | default: | 2271 | default: |
2705 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 2272 | ath_print(common, ATH_DBG_FATAL, |
2706 | "cipher %u not supported\n", k->kv_type); | 2273 | "cipher %u not supported\n", k->kv_type); |
2707 | return false; | 2274 | return false; |
2708 | } | 2275 | } |
2709 | 2276 | ||
@@ -2845,6 +2412,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | |||
2845 | 2412 | ||
2846 | return true; | 2413 | return true; |
2847 | } | 2414 | } |
2415 | EXPORT_SYMBOL(ath9k_hw_set_keycache_entry); | ||
2848 | 2416 | ||
2849 | bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry) | 2417 | bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry) |
2850 | { | 2418 | { |
@@ -2855,6 +2423,7 @@ bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry) | |||
2855 | } | 2423 | } |
2856 | return false; | 2424 | return false; |
2857 | } | 2425 | } |
2426 | EXPORT_SYMBOL(ath9k_hw_keyisvalid); | ||
2858 | 2427 | ||
2859 | /******************************/ | 2428 | /******************************/ |
2860 | /* Power Management (Chipset) */ | 2429 | /* Power Management (Chipset) */ |
@@ -2869,8 +2438,9 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | |||
2869 | if (!AR_SREV_9100(ah)) | 2438 | if (!AR_SREV_9100(ah)) |
2870 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); | 2439 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); |
2871 | 2440 | ||
2872 | REG_CLR_BIT(ah, (AR_RTC_RESET), | 2441 | if(!AR_SREV_5416(ah)) |
2873 | AR_RTC_RESET_EN); | 2442 | REG_CLR_BIT(ah, (AR_RTC_RESET), |
2443 | AR_RTC_RESET_EN); | ||
2874 | } | 2444 | } |
2875 | } | 2445 | } |
2876 | 2446 | ||
@@ -2902,6 +2472,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | |||
2902 | ATH9K_RESET_POWER_ON) != true) { | 2472 | ATH9K_RESET_POWER_ON) != true) { |
2903 | return false; | 2473 | return false; |
2904 | } | 2474 | } |
2475 | ath9k_hw_init_pll(ah, NULL); | ||
2905 | } | 2476 | } |
2906 | if (AR_SREV_9100(ah)) | 2477 | if (AR_SREV_9100(ah)) |
2907 | REG_SET_BIT(ah, AR_RTC_RESET, | 2478 | REG_SET_BIT(ah, AR_RTC_RESET, |
@@ -2920,8 +2491,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | |||
2920 | AR_RTC_FORCE_WAKE_EN); | 2491 | AR_RTC_FORCE_WAKE_EN); |
2921 | } | 2492 | } |
2922 | if (i == 0) { | 2493 | if (i == 0) { |
2923 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 2494 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, |
2924 | "Failed to wakeup in %uus\n", POWER_UP_TIME / 20); | 2495 | "Failed to wakeup in %uus\n", |
2496 | POWER_UP_TIME / 20); | ||
2925 | return false; | 2497 | return false; |
2926 | } | 2498 | } |
2927 | } | 2499 | } |
@@ -2931,9 +2503,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | |||
2931 | return true; | 2503 | return true; |
2932 | } | 2504 | } |
2933 | 2505 | ||
2934 | static bool ath9k_hw_setpower_nolock(struct ath_hw *ah, | 2506 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) |
2935 | enum ath9k_power_mode mode) | ||
2936 | { | 2507 | { |
2508 | struct ath_common *common = ath9k_hw_common(ah); | ||
2937 | int status = true, setChip = true; | 2509 | int status = true, setChip = true; |
2938 | static const char *modes[] = { | 2510 | static const char *modes[] = { |
2939 | "AWAKE", | 2511 | "AWAKE", |
@@ -2945,8 +2517,8 @@ static bool ath9k_hw_setpower_nolock(struct ath_hw *ah, | |||
2945 | if (ah->power_mode == mode) | 2517 | if (ah->power_mode == mode) |
2946 | return status; | 2518 | return status; |
2947 | 2519 | ||
2948 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n", | 2520 | ath_print(common, ATH_DBG_RESET, "%s -> %s\n", |
2949 | modes[ah->power_mode], modes[mode]); | 2521 | modes[ah->power_mode], modes[mode]); |
2950 | 2522 | ||
2951 | switch (mode) { | 2523 | switch (mode) { |
2952 | case ATH9K_PM_AWAKE: | 2524 | case ATH9K_PM_AWAKE: |
@@ -2960,59 +2532,15 @@ static bool ath9k_hw_setpower_nolock(struct ath_hw *ah, | |||
2960 | ath9k_set_power_network_sleep(ah, setChip); | 2532 | ath9k_set_power_network_sleep(ah, setChip); |
2961 | break; | 2533 | break; |
2962 | default: | 2534 | default: |
2963 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 2535 | ath_print(common, ATH_DBG_FATAL, |
2964 | "Unknown power mode %u\n", mode); | 2536 | "Unknown power mode %u\n", mode); |
2965 | return false; | 2537 | return false; |
2966 | } | 2538 | } |
2967 | ah->power_mode = mode; | 2539 | ah->power_mode = mode; |
2968 | 2540 | ||
2969 | return status; | 2541 | return status; |
2970 | } | 2542 | } |
2971 | 2543 | EXPORT_SYMBOL(ath9k_hw_setpower); | |
2972 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | ||
2973 | { | ||
2974 | unsigned long flags; | ||
2975 | bool ret; | ||
2976 | |||
2977 | spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags); | ||
2978 | ret = ath9k_hw_setpower_nolock(ah, mode); | ||
2979 | spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags); | ||
2980 | |||
2981 | return ret; | ||
2982 | } | ||
2983 | |||
2984 | void ath9k_ps_wakeup(struct ath_softc *sc) | ||
2985 | { | ||
2986 | unsigned long flags; | ||
2987 | |||
2988 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
2989 | if (++sc->ps_usecount != 1) | ||
2990 | goto unlock; | ||
2991 | |||
2992 | ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE); | ||
2993 | |||
2994 | unlock: | ||
2995 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
2996 | } | ||
2997 | |||
2998 | void ath9k_ps_restore(struct ath_softc *sc) | ||
2999 | { | ||
3000 | unsigned long flags; | ||
3001 | |||
3002 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
3003 | if (--sc->ps_usecount != 0) | ||
3004 | goto unlock; | ||
3005 | |||
3006 | if (sc->ps_enabled && | ||
3007 | !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | ||
3008 | SC_OP_WAIT_FOR_CAB | | ||
3009 | SC_OP_WAIT_FOR_PSPOLL_DATA | | ||
3010 | SC_OP_WAIT_FOR_TX_ACK))) | ||
3011 | ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | ||
3012 | |||
3013 | unlock: | ||
3014 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
3015 | } | ||
3016 | 2544 | ||
3017 | /* | 2545 | /* |
3018 | * Helper for ASPM support. | 2546 | * Helper for ASPM support. |
@@ -3145,6 +2673,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off) | |||
3145 | } | 2673 | } |
3146 | } | 2674 | } |
3147 | } | 2675 | } |
2676 | EXPORT_SYMBOL(ath9k_hw_configpcipowersave); | ||
3148 | 2677 | ||
3149 | /**********************/ | 2678 | /**********************/ |
3150 | /* Interrupt Handling */ | 2679 | /* Interrupt Handling */ |
@@ -3168,6 +2697,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah) | |||
3168 | 2697 | ||
3169 | return false; | 2698 | return false; |
3170 | } | 2699 | } |
2700 | EXPORT_SYMBOL(ath9k_hw_intrpend); | ||
3171 | 2701 | ||
3172 | bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | 2702 | bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) |
3173 | { | 2703 | { |
@@ -3176,6 +2706,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | |||
3176 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 2706 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
3177 | u32 sync_cause = 0; | 2707 | u32 sync_cause = 0; |
3178 | bool fatal_int = false; | 2708 | bool fatal_int = false; |
2709 | struct ath_common *common = ath9k_hw_common(ah); | ||
3179 | 2710 | ||
3180 | if (!AR_SREV_9100(ah)) { | 2711 | if (!AR_SREV_9100(ah)) { |
3181 | if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) { | 2712 | if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) { |
@@ -3225,7 +2756,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | |||
3225 | 2756 | ||
3226 | *masked = isr & ATH9K_INT_COMMON; | 2757 | *masked = isr & ATH9K_INT_COMMON; |
3227 | 2758 | ||
3228 | if (ah->config.intr_mitigation) { | 2759 | if (ah->config.rx_intr_mitigation) { |
3229 | if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) | 2760 | if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) |
3230 | *masked |= ATH9K_INT_RX; | 2761 | *masked |= ATH9K_INT_RX; |
3231 | } | 2762 | } |
@@ -3249,8 +2780,8 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | |||
3249 | } | 2780 | } |
3250 | 2781 | ||
3251 | if (isr & AR_ISR_RXORN) { | 2782 | if (isr & AR_ISR_RXORN) { |
3252 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | 2783 | ath_print(common, ATH_DBG_INTERRUPT, |
3253 | "receive FIFO overrun interrupt\n"); | 2784 | "receive FIFO overrun interrupt\n"); |
3254 | } | 2785 | } |
3255 | 2786 | ||
3256 | if (!AR_SREV_9100(ah)) { | 2787 | if (!AR_SREV_9100(ah)) { |
@@ -3292,25 +2823,25 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | |||
3292 | 2823 | ||
3293 | if (fatal_int) { | 2824 | if (fatal_int) { |
3294 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { | 2825 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { |
3295 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 2826 | ath_print(common, ATH_DBG_ANY, |
3296 | "received PCI FATAL interrupt\n"); | 2827 | "received PCI FATAL interrupt\n"); |
3297 | } | 2828 | } |
3298 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { | 2829 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { |
3299 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 2830 | ath_print(common, ATH_DBG_ANY, |
3300 | "received PCI PERR interrupt\n"); | 2831 | "received PCI PERR interrupt\n"); |
3301 | } | 2832 | } |
3302 | *masked |= ATH9K_INT_FATAL; | 2833 | *masked |= ATH9K_INT_FATAL; |
3303 | } | 2834 | } |
3304 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | 2835 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { |
3305 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | 2836 | ath_print(common, ATH_DBG_INTERRUPT, |
3306 | "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); | 2837 | "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); |
3307 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | 2838 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); |
3308 | REG_WRITE(ah, AR_RC, 0); | 2839 | REG_WRITE(ah, AR_RC, 0); |
3309 | *masked |= ATH9K_INT_FATAL; | 2840 | *masked |= ATH9K_INT_FATAL; |
3310 | } | 2841 | } |
3311 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { | 2842 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { |
3312 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | 2843 | ath_print(common, ATH_DBG_INTERRUPT, |
3313 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); | 2844 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); |
3314 | } | 2845 | } |
3315 | 2846 | ||
3316 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); | 2847 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); |
@@ -3319,17 +2850,19 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | |||
3319 | 2850 | ||
3320 | return true; | 2851 | return true; |
3321 | } | 2852 | } |
2853 | EXPORT_SYMBOL(ath9k_hw_getisr); | ||
3322 | 2854 | ||
3323 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | 2855 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) |
3324 | { | 2856 | { |
3325 | u32 omask = ah->mask_reg; | 2857 | u32 omask = ah->mask_reg; |
3326 | u32 mask, mask2; | 2858 | u32 mask, mask2; |
3327 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 2859 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
2860 | struct ath_common *common = ath9k_hw_common(ah); | ||
3328 | 2861 | ||
3329 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); | 2862 | ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); |
3330 | 2863 | ||
3331 | if (omask & ATH9K_INT_GLOBAL) { | 2864 | if (omask & ATH9K_INT_GLOBAL) { |
3332 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "disable IER\n"); | 2865 | ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n"); |
3333 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); | 2866 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); |
3334 | (void) REG_READ(ah, AR_IER); | 2867 | (void) REG_READ(ah, AR_IER); |
3335 | if (!AR_SREV_9100(ah)) { | 2868 | if (!AR_SREV_9100(ah)) { |
@@ -3356,7 +2889,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
3356 | } | 2889 | } |
3357 | if (ints & ATH9K_INT_RX) { | 2890 | if (ints & ATH9K_INT_RX) { |
3358 | mask |= AR_IMR_RXERR; | 2891 | mask |= AR_IMR_RXERR; |
3359 | if (ah->config.intr_mitigation) | 2892 | if (ah->config.rx_intr_mitigation) |
3360 | mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; | 2893 | mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; |
3361 | else | 2894 | else |
3362 | mask |= AR_IMR_RXOK | AR_IMR_RXDESC; | 2895 | mask |= AR_IMR_RXOK | AR_IMR_RXDESC; |
@@ -3386,7 +2919,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
3386 | mask2 |= AR_IMR_S2_CST; | 2919 | mask2 |= AR_IMR_S2_CST; |
3387 | } | 2920 | } |
3388 | 2921 | ||
3389 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); | 2922 | ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); |
3390 | REG_WRITE(ah, AR_IMR, mask); | 2923 | REG_WRITE(ah, AR_IMR, mask); |
3391 | mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | | 2924 | mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | |
3392 | AR_IMR_S2_DTIM | | 2925 | AR_IMR_S2_DTIM | |
@@ -3406,7 +2939,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
3406 | } | 2939 | } |
3407 | 2940 | ||
3408 | if (ints & ATH9K_INT_GLOBAL) { | 2941 | if (ints & ATH9K_INT_GLOBAL) { |
3409 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n"); | 2942 | ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n"); |
3410 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | 2943 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); |
3411 | if (!AR_SREV_9100(ah)) { | 2944 | if (!AR_SREV_9100(ah)) { |
3412 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, | 2945 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, |
@@ -3419,12 +2952,13 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
3419 | REG_WRITE(ah, AR_INTR_SYNC_MASK, | 2952 | REG_WRITE(ah, AR_INTR_SYNC_MASK, |
3420 | AR_INTR_SYNC_DEFAULT); | 2953 | AR_INTR_SYNC_DEFAULT); |
3421 | } | 2954 | } |
3422 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", | 2955 | ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", |
3423 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); | 2956 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); |
3424 | } | 2957 | } |
3425 | 2958 | ||
3426 | return omask; | 2959 | return omask; |
3427 | } | 2960 | } |
2961 | EXPORT_SYMBOL(ath9k_hw_set_interrupts); | ||
3428 | 2962 | ||
3429 | /*******************/ | 2963 | /*******************/ |
3430 | /* Beacon Handling */ | 2964 | /* Beacon Handling */ |
@@ -3467,9 +3001,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) | |||
3467 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; | 3001 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; |
3468 | break; | 3002 | break; |
3469 | default: | 3003 | default: |
3470 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, | 3004 | ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON, |
3471 | "%s: unsupported opmode: %d\n", | 3005 | "%s: unsupported opmode: %d\n", |
3472 | __func__, ah->opmode); | 3006 | __func__, ah->opmode); |
3473 | return; | 3007 | return; |
3474 | break; | 3008 | break; |
3475 | } | 3009 | } |
@@ -3481,18 +3015,19 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) | |||
3481 | 3015 | ||
3482 | beacon_period &= ~ATH9K_BEACON_ENA; | 3016 | beacon_period &= ~ATH9K_BEACON_ENA; |
3483 | if (beacon_period & ATH9K_BEACON_RESET_TSF) { | 3017 | if (beacon_period & ATH9K_BEACON_RESET_TSF) { |
3484 | beacon_period &= ~ATH9K_BEACON_RESET_TSF; | ||
3485 | ath9k_hw_reset_tsf(ah); | 3018 | ath9k_hw_reset_tsf(ah); |
3486 | } | 3019 | } |
3487 | 3020 | ||
3488 | REG_SET_BIT(ah, AR_TIMER_MODE, flags); | 3021 | REG_SET_BIT(ah, AR_TIMER_MODE, flags); |
3489 | } | 3022 | } |
3023 | EXPORT_SYMBOL(ath9k_hw_beaconinit); | ||
3490 | 3024 | ||
3491 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | 3025 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, |
3492 | const struct ath9k_beacon_state *bs) | 3026 | const struct ath9k_beacon_state *bs) |
3493 | { | 3027 | { |
3494 | u32 nextTbtt, beaconintval, dtimperiod, beacontimeout; | 3028 | u32 nextTbtt, beaconintval, dtimperiod, beacontimeout; |
3495 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 3029 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
3030 | struct ath_common *common = ath9k_hw_common(ah); | ||
3496 | 3031 | ||
3497 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); | 3032 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); |
3498 | 3033 | ||
@@ -3518,10 +3053,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
3518 | else | 3053 | else |
3519 | nextTbtt = bs->bs_nexttbtt; | 3054 | nextTbtt = bs->bs_nexttbtt; |
3520 | 3055 | ||
3521 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim); | 3056 | ath_print(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim); |
3522 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt); | 3057 | ath_print(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt); |
3523 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); | 3058 | ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); |
3524 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); | 3059 | ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); |
3525 | 3060 | ||
3526 | REG_WRITE(ah, AR_NEXT_DTIM, | 3061 | REG_WRITE(ah, AR_NEXT_DTIM, |
3527 | TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); | 3062 | TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); |
@@ -3549,16 +3084,18 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
3549 | /* TSF Out of Range Threshold */ | 3084 | /* TSF Out of Range Threshold */ |
3550 | REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold); | 3085 | REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold); |
3551 | } | 3086 | } |
3087 | EXPORT_SYMBOL(ath9k_hw_set_sta_beacon_timers); | ||
3552 | 3088 | ||
3553 | /*******************/ | 3089 | /*******************/ |
3554 | /* HW Capabilities */ | 3090 | /* HW Capabilities */ |
3555 | /*******************/ | 3091 | /*******************/ |
3556 | 3092 | ||
3557 | void ath9k_hw_fill_cap_info(struct ath_hw *ah) | 3093 | int ath9k_hw_fill_cap_info(struct ath_hw *ah) |
3558 | { | 3094 | { |
3559 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 3095 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
3560 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 3096 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
3561 | struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info; | 3097 | struct ath_common *common = ath9k_hw_common(ah); |
3098 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | ||
3562 | 3099 | ||
3563 | u16 capField = 0, eeval; | 3100 | u16 capField = 0, eeval; |
3564 | 3101 | ||
@@ -3579,11 +3116,17 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3579 | regulatory->current_rd += 5; | 3116 | regulatory->current_rd += 5; |
3580 | else if (regulatory->current_rd == 0x41) | 3117 | else if (regulatory->current_rd == 0x41) |
3581 | regulatory->current_rd = 0x43; | 3118 | regulatory->current_rd = 0x43; |
3582 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 3119 | ath_print(common, ATH_DBG_REGULATORY, |
3583 | "regdomain mapped to 0x%x\n", regulatory->current_rd); | 3120 | "regdomain mapped to 0x%x\n", regulatory->current_rd); |
3584 | } | 3121 | } |
3585 | 3122 | ||
3586 | eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); | 3123 | eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); |
3124 | if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) { | ||
3125 | ath_print(common, ATH_DBG_FATAL, | ||
3126 | "no band has been marked as supported in EEPROM.\n"); | ||
3127 | return -EINVAL; | ||
3128 | } | ||
3129 | |||
3587 | bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX); | 3130 | bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX); |
3588 | 3131 | ||
3589 | if (eeval & AR5416_OPFLAGS_11A) { | 3132 | if (eeval & AR5416_OPFLAGS_11A) { |
@@ -3670,7 +3213,11 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3670 | pCap->keycache_size = AR_KEYTABLE_SIZE; | 3213 | pCap->keycache_size = AR_KEYTABLE_SIZE; |
3671 | 3214 | ||
3672 | pCap->hw_caps |= ATH9K_HW_CAP_FASTCC; | 3215 | pCap->hw_caps |= ATH9K_HW_CAP_FASTCC; |
3673 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; | 3216 | |
3217 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||
3218 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1; | ||
3219 | else | ||
3220 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; | ||
3674 | 3221 | ||
3675 | if (AR_SREV_9285_10_OR_LATER(ah)) | 3222 | if (AR_SREV_9285_10_OR_LATER(ah)) |
3676 | pCap->num_gpio_pins = AR9285_NUM_GPIO; | 3223 | pCap->num_gpio_pins = AR9285_NUM_GPIO; |
@@ -3719,7 +3266,10 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3719 | AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN; | 3266 | AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN; |
3720 | } | 3267 | } |
3721 | 3268 | ||
3722 | pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; | 3269 | /* Advertise midband for AR5416 with FCC midband set in eeprom */ |
3270 | if (regulatory->current_rd_ext & (1 << REG_EXT_FCC_MIDBAND) && | ||
3271 | AR_SREV_5416(ah)) | ||
3272 | pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; | ||
3723 | 3273 | ||
3724 | pCap->num_antcfg_5ghz = | 3274 | pCap->num_antcfg_5ghz = |
3725 | ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ); | 3275 | ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ); |
@@ -3727,19 +3277,21 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3727 | ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); | 3277 | ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); |
3728 | 3278 | ||
3729 | if (AR_SREV_9280_10_OR_LATER(ah) && | 3279 | if (AR_SREV_9280_10_OR_LATER(ah) && |
3730 | ath_btcoex_supported(ah->hw_version.subsysid)) { | 3280 | ath9k_hw_btcoex_supported(ah)) { |
3731 | btcoex_info->btactive_gpio = ATH_BTACTIVE_GPIO; | 3281 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; |
3732 | btcoex_info->wlanactive_gpio = ATH_WLANACTIVE_GPIO; | 3282 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; |
3733 | 3283 | ||
3734 | if (AR_SREV_9285(ah)) { | 3284 | if (AR_SREV_9285(ah)) { |
3735 | btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_3WIRE; | 3285 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; |
3736 | btcoex_info->btpriority_gpio = ATH_BTPRIORITY_GPIO; | 3286 | btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO; |
3737 | } else { | 3287 | } else { |
3738 | btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_2WIRE; | 3288 | btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; |
3739 | } | 3289 | } |
3740 | } else { | 3290 | } else { |
3741 | btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_NONE; | 3291 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; |
3742 | } | 3292 | } |
3293 | |||
3294 | return 0; | ||
3743 | } | 3295 | } |
3744 | 3296 | ||
3745 | bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, | 3297 | bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, |
@@ -3812,6 +3364,7 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, | |||
3812 | return false; | 3364 | return false; |
3813 | } | 3365 | } |
3814 | } | 3366 | } |
3367 | EXPORT_SYMBOL(ath9k_hw_getcapability); | ||
3815 | 3368 | ||
3816 | bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, | 3369 | bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, |
3817 | u32 capability, u32 setting, int *status) | 3370 | u32 capability, u32 setting, int *status) |
@@ -3845,6 +3398,7 @@ bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, | |||
3845 | return false; | 3398 | return false; |
3846 | } | 3399 | } |
3847 | } | 3400 | } |
3401 | EXPORT_SYMBOL(ath9k_hw_setcapability); | ||
3848 | 3402 | ||
3849 | /****************************/ | 3403 | /****************************/ |
3850 | /* GPIO / RFKILL / Antennae */ | 3404 | /* GPIO / RFKILL / Antennae */ |
@@ -3882,7 +3436,7 @@ void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio) | |||
3882 | { | 3436 | { |
3883 | u32 gpio_shift; | 3437 | u32 gpio_shift; |
3884 | 3438 | ||
3885 | ASSERT(gpio < ah->caps.num_gpio_pins); | 3439 | BUG_ON(gpio >= ah->caps.num_gpio_pins); |
3886 | 3440 | ||
3887 | gpio_shift = gpio << 1; | 3441 | gpio_shift = gpio << 1; |
3888 | 3442 | ||
@@ -3891,6 +3445,7 @@ void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio) | |||
3891 | (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), | 3445 | (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), |
3892 | (AR_GPIO_OE_OUT_DRV << gpio_shift)); | 3446 | (AR_GPIO_OE_OUT_DRV << gpio_shift)); |
3893 | } | 3447 | } |
3448 | EXPORT_SYMBOL(ath9k_hw_cfg_gpio_input); | ||
3894 | 3449 | ||
3895 | u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) | 3450 | u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) |
3896 | { | 3451 | { |
@@ -3909,6 +3464,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) | |||
3909 | else | 3464 | else |
3910 | return MS_REG_READ(AR, gpio) != 0; | 3465 | return MS_REG_READ(AR, gpio) != 0; |
3911 | } | 3466 | } |
3467 | EXPORT_SYMBOL(ath9k_hw_gpio_get); | ||
3912 | 3468 | ||
3913 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | 3469 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, |
3914 | u32 ah_signal_type) | 3470 | u32 ah_signal_type) |
@@ -3924,67 +3480,26 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | |||
3924 | (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), | 3480 | (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), |
3925 | (AR_GPIO_OE_OUT_DRV << gpio_shift)); | 3481 | (AR_GPIO_OE_OUT_DRV << gpio_shift)); |
3926 | } | 3482 | } |
3483 | EXPORT_SYMBOL(ath9k_hw_cfg_output); | ||
3927 | 3484 | ||
3928 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) | 3485 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) |
3929 | { | 3486 | { |
3930 | REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), | 3487 | REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), |
3931 | AR_GPIO_BIT(gpio)); | 3488 | AR_GPIO_BIT(gpio)); |
3932 | } | 3489 | } |
3490 | EXPORT_SYMBOL(ath9k_hw_set_gpio); | ||
3933 | 3491 | ||
3934 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah) | 3492 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah) |
3935 | { | 3493 | { |
3936 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; | 3494 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; |
3937 | } | 3495 | } |
3496 | EXPORT_SYMBOL(ath9k_hw_getdefantenna); | ||
3938 | 3497 | ||
3939 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) | 3498 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) |
3940 | { | 3499 | { |
3941 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); | 3500 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); |
3942 | } | 3501 | } |
3943 | 3502 | EXPORT_SYMBOL(ath9k_hw_setantenna); | |
3944 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, | ||
3945 | enum ath9k_ant_setting settings, | ||
3946 | struct ath9k_channel *chan, | ||
3947 | u8 *tx_chainmask, | ||
3948 | u8 *rx_chainmask, | ||
3949 | u8 *antenna_cfgd) | ||
3950 | { | ||
3951 | static u8 tx_chainmask_cfg, rx_chainmask_cfg; | ||
3952 | |||
3953 | if (AR_SREV_9280(ah)) { | ||
3954 | if (!tx_chainmask_cfg) { | ||
3955 | |||
3956 | tx_chainmask_cfg = *tx_chainmask; | ||
3957 | rx_chainmask_cfg = *rx_chainmask; | ||
3958 | } | ||
3959 | |||
3960 | switch (settings) { | ||
3961 | case ATH9K_ANT_FIXED_A: | ||
3962 | *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK; | ||
3963 | *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK; | ||
3964 | *antenna_cfgd = true; | ||
3965 | break; | ||
3966 | case ATH9K_ANT_FIXED_B: | ||
3967 | if (ah->caps.tx_chainmask > | ||
3968 | ATH9K_ANTENNA1_CHAINMASK) { | ||
3969 | *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK; | ||
3970 | } | ||
3971 | *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK; | ||
3972 | *antenna_cfgd = true; | ||
3973 | break; | ||
3974 | case ATH9K_ANT_VARIABLE: | ||
3975 | *tx_chainmask = tx_chainmask_cfg; | ||
3976 | *rx_chainmask = rx_chainmask_cfg; | ||
3977 | *antenna_cfgd = true; | ||
3978 | break; | ||
3979 | default: | ||
3980 | break; | ||
3981 | } | ||
3982 | } else { | ||
3983 | ah->config.diversity_control = settings; | ||
3984 | } | ||
3985 | |||
3986 | return true; | ||
3987 | } | ||
3988 | 3503 | ||
3989 | /*********************/ | 3504 | /*********************/ |
3990 | /* General Operation */ | 3505 | /* General Operation */ |
@@ -4002,6 +3517,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah) | |||
4002 | 3517 | ||
4003 | return bits; | 3518 | return bits; |
4004 | } | 3519 | } |
3520 | EXPORT_SYMBOL(ath9k_hw_getrxfilter); | ||
4005 | 3521 | ||
4006 | void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) | 3522 | void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) |
4007 | { | 3523 | { |
@@ -4023,19 +3539,30 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) | |||
4023 | REG_WRITE(ah, AR_RXCFG, | 3539 | REG_WRITE(ah, AR_RXCFG, |
4024 | REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); | 3540 | REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); |
4025 | } | 3541 | } |
3542 | EXPORT_SYMBOL(ath9k_hw_setrxfilter); | ||
4026 | 3543 | ||
4027 | bool ath9k_hw_phy_disable(struct ath_hw *ah) | 3544 | bool ath9k_hw_phy_disable(struct ath_hw *ah) |
4028 | { | 3545 | { |
4029 | return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM); | 3546 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) |
3547 | return false; | ||
3548 | |||
3549 | ath9k_hw_init_pll(ah, NULL); | ||
3550 | return true; | ||
4030 | } | 3551 | } |
3552 | EXPORT_SYMBOL(ath9k_hw_phy_disable); | ||
4031 | 3553 | ||
4032 | bool ath9k_hw_disable(struct ath_hw *ah) | 3554 | bool ath9k_hw_disable(struct ath_hw *ah) |
4033 | { | 3555 | { |
4034 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 3556 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
4035 | return false; | 3557 | return false; |
4036 | 3558 | ||
4037 | return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD); | 3559 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD)) |
3560 | return false; | ||
3561 | |||
3562 | ath9k_hw_init_pll(ah, NULL); | ||
3563 | return true; | ||
4038 | } | 3564 | } |
3565 | EXPORT_SYMBOL(ath9k_hw_disable); | ||
4039 | 3566 | ||
4040 | void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) | 3567 | void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) |
4041 | { | 3568 | { |
@@ -4052,35 +3579,36 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) | |||
4052 | min((u32) MAX_RATE_POWER, | 3579 | min((u32) MAX_RATE_POWER, |
4053 | (u32) regulatory->power_limit)); | 3580 | (u32) regulatory->power_limit)); |
4054 | } | 3581 | } |
3582 | EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); | ||
4055 | 3583 | ||
4056 | void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac) | 3584 | void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac) |
4057 | { | 3585 | { |
4058 | memcpy(ah->macaddr, mac, ETH_ALEN); | 3586 | memcpy(ath9k_hw_common(ah)->macaddr, mac, ETH_ALEN); |
4059 | } | 3587 | } |
3588 | EXPORT_SYMBOL(ath9k_hw_setmac); | ||
4060 | 3589 | ||
4061 | void ath9k_hw_setopmode(struct ath_hw *ah) | 3590 | void ath9k_hw_setopmode(struct ath_hw *ah) |
4062 | { | 3591 | { |
4063 | ath9k_hw_set_operating_mode(ah, ah->opmode); | 3592 | ath9k_hw_set_operating_mode(ah, ah->opmode); |
4064 | } | 3593 | } |
3594 | EXPORT_SYMBOL(ath9k_hw_setopmode); | ||
4065 | 3595 | ||
4066 | void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1) | 3596 | void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1) |
4067 | { | 3597 | { |
4068 | REG_WRITE(ah, AR_MCAST_FIL0, filter0); | 3598 | REG_WRITE(ah, AR_MCAST_FIL0, filter0); |
4069 | REG_WRITE(ah, AR_MCAST_FIL1, filter1); | 3599 | REG_WRITE(ah, AR_MCAST_FIL1, filter1); |
4070 | } | 3600 | } |
3601 | EXPORT_SYMBOL(ath9k_hw_setmcastfilter); | ||
4071 | 3602 | ||
4072 | void ath9k_hw_setbssidmask(struct ath_softc *sc) | 3603 | void ath9k_hw_write_associd(struct ath_hw *ah) |
4073 | { | 3604 | { |
4074 | REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask)); | 3605 | struct ath_common *common = ath9k_hw_common(ah); |
4075 | REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4)); | ||
4076 | } | ||
4077 | 3606 | ||
4078 | void ath9k_hw_write_associd(struct ath_softc *sc) | 3607 | REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(common->curbssid)); |
4079 | { | 3608 | REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(common->curbssid + 4) | |
4080 | REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid)); | 3609 | ((common->curaid & 0x3fff) << AR_BSS_ID1_AID_S)); |
4081 | REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) | | ||
4082 | ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S)); | ||
4083 | } | 3610 | } |
3611 | EXPORT_SYMBOL(ath9k_hw_write_associd); | ||
4084 | 3612 | ||
4085 | u64 ath9k_hw_gettsf64(struct ath_hw *ah) | 3613 | u64 ath9k_hw_gettsf64(struct ath_hw *ah) |
4086 | { | 3614 | { |
@@ -4091,24 +3619,25 @@ u64 ath9k_hw_gettsf64(struct ath_hw *ah) | |||
4091 | 3619 | ||
4092 | return tsf; | 3620 | return tsf; |
4093 | } | 3621 | } |
3622 | EXPORT_SYMBOL(ath9k_hw_gettsf64); | ||
4094 | 3623 | ||
4095 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64) | 3624 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64) |
4096 | { | 3625 | { |
4097 | REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff); | 3626 | REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff); |
4098 | REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff); | 3627 | REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff); |
4099 | } | 3628 | } |
3629 | EXPORT_SYMBOL(ath9k_hw_settsf64); | ||
4100 | 3630 | ||
4101 | void ath9k_hw_reset_tsf(struct ath_hw *ah) | 3631 | void ath9k_hw_reset_tsf(struct ath_hw *ah) |
4102 | { | 3632 | { |
4103 | ath9k_ps_wakeup(ah->ah_sc); | ||
4104 | if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0, | 3633 | if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0, |
4105 | AH_TSF_WRITE_TIMEOUT)) | 3634 | AH_TSF_WRITE_TIMEOUT)) |
4106 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 3635 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, |
4107 | "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); | 3636 | "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); |
4108 | 3637 | ||
4109 | REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); | 3638 | REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); |
4110 | ath9k_ps_restore(ah->ah_sc); | ||
4111 | } | 3639 | } |
3640 | EXPORT_SYMBOL(ath9k_hw_reset_tsf); | ||
4112 | 3641 | ||
4113 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) | 3642 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) |
4114 | { | 3643 | { |
@@ -4117,26 +3646,29 @@ void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) | |||
4117 | else | 3646 | else |
4118 | ah->misc_mode &= ~AR_PCU_TX_ADD_TSF; | 3647 | ah->misc_mode &= ~AR_PCU_TX_ADD_TSF; |
4119 | } | 3648 | } |
3649 | EXPORT_SYMBOL(ath9k_hw_set_tsfadjust); | ||
4120 | 3650 | ||
4121 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) | 3651 | /* |
3652 | * Extend 15-bit time stamp from rx descriptor to | ||
3653 | * a full 64-bit TSF using the current h/w TSF. | ||
3654 | */ | ||
3655 | u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp) | ||
4122 | { | 3656 | { |
4123 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { | 3657 | u64 tsf; |
4124 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us); | 3658 | |
4125 | ah->slottime = (u32) -1; | 3659 | tsf = ath9k_hw_gettsf64(ah); |
4126 | return false; | 3660 | if ((tsf & 0x7fff) < rstamp) |
4127 | } else { | 3661 | tsf -= 0x8000; |
4128 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us)); | 3662 | return (tsf & ~0x7fff) | rstamp; |
4129 | ah->slottime = us; | ||
4130 | return true; | ||
4131 | } | ||
4132 | } | 3663 | } |
3664 | EXPORT_SYMBOL(ath9k_hw_extend_tsf); | ||
4133 | 3665 | ||
4134 | void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode) | 3666 | void ath9k_hw_set11nmac2040(struct ath_hw *ah) |
4135 | { | 3667 | { |
3668 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
4136 | u32 macmode; | 3669 | u32 macmode; |
4137 | 3670 | ||
4138 | if (mode == ATH9K_HT_MACMODE_2040 && | 3671 | if (conf_is_ht40(conf) && !ah->config.cwm_ignore_extcca) |
4139 | !ah->config.cwm_ignore_extcca) | ||
4140 | macmode = AR_2040_JOINED_RX_CLEAR; | 3672 | macmode = AR_2040_JOINED_RX_CLEAR; |
4141 | else | 3673 | else |
4142 | macmode = 0; | 3674 | macmode = 0; |
@@ -4193,6 +3725,7 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah) | |||
4193 | { | 3725 | { |
4194 | return REG_READ(ah, AR_TSF_L32); | 3726 | return REG_READ(ah, AR_TSF_L32); |
4195 | } | 3727 | } |
3728 | EXPORT_SYMBOL(ath9k_hw_gettsf32); | ||
4196 | 3729 | ||
4197 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, | 3730 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, |
4198 | void (*trigger)(void *), | 3731 | void (*trigger)(void *), |
@@ -4206,8 +3739,9 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, | |||
4206 | timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL); | 3739 | timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL); |
4207 | 3740 | ||
4208 | if (timer == NULL) { | 3741 | if (timer == NULL) { |
4209 | printk(KERN_DEBUG "Failed to allocate memory" | 3742 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, |
4210 | "for hw timer[%d]\n", timer_index); | 3743 | "Failed to allocate memory" |
3744 | "for hw timer[%d]\n", timer_index); | ||
4211 | return NULL; | 3745 | return NULL; |
4212 | } | 3746 | } |
4213 | 3747 | ||
@@ -4220,10 +3754,12 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, | |||
4220 | 3754 | ||
4221 | return timer; | 3755 | return timer; |
4222 | } | 3756 | } |
3757 | EXPORT_SYMBOL(ath_gen_timer_alloc); | ||
4223 | 3758 | ||
4224 | void ath_gen_timer_start(struct ath_hw *ah, | 3759 | void ath9k_hw_gen_timer_start(struct ath_hw *ah, |
4225 | struct ath_gen_timer *timer, | 3760 | struct ath_gen_timer *timer, |
4226 | u32 timer_next, u32 timer_period) | 3761 | u32 timer_next, |
3762 | u32 timer_period) | ||
4227 | { | 3763 | { |
4228 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | 3764 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; |
4229 | u32 tsf; | 3765 | u32 tsf; |
@@ -4234,8 +3770,9 @@ void ath_gen_timer_start(struct ath_hw *ah, | |||
4234 | 3770 | ||
4235 | tsf = ath9k_hw_gettsf32(ah); | 3771 | tsf = ath9k_hw_gettsf32(ah); |
4236 | 3772 | ||
4237 | DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER, "curent tsf %x period %x" | 3773 | ath_print(ath9k_hw_common(ah), ATH_DBG_HWTIMER, |
4238 | "timer_next %x\n", tsf, timer_period, timer_next); | 3774 | "curent tsf %x period %x" |
3775 | "timer_next %x\n", tsf, timer_period, timer_next); | ||
4239 | 3776 | ||
4240 | /* | 3777 | /* |
4241 | * Pull timer_next forward if the current TSF already passed it | 3778 | * Pull timer_next forward if the current TSF already passed it |
@@ -4258,15 +3795,10 @@ void ath_gen_timer_start(struct ath_hw *ah, | |||
4258 | REG_SET_BIT(ah, AR_IMR_S5, | 3795 | REG_SET_BIT(ah, AR_IMR_S5, |
4259 | (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) | | 3796 | (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) | |
4260 | SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG))); | 3797 | SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG))); |
4261 | |||
4262 | if ((ah->ah_sc->imask & ATH9K_INT_GENTIMER) == 0) { | ||
4263 | ath9k_hw_set_interrupts(ah, 0); | ||
4264 | ah->ah_sc->imask |= ATH9K_INT_GENTIMER; | ||
4265 | ath9k_hw_set_interrupts(ah, ah->ah_sc->imask); | ||
4266 | } | ||
4267 | } | 3798 | } |
3799 | EXPORT_SYMBOL(ath9k_hw_gen_timer_start); | ||
4268 | 3800 | ||
4269 | void ath_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | 3801 | void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) |
4270 | { | 3802 | { |
4271 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | 3803 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; |
4272 | 3804 | ||
@@ -4285,14 +3817,8 @@ void ath_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | |||
4285 | SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG))); | 3817 | SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG))); |
4286 | 3818 | ||
4287 | clear_bit(timer->index, &timer_table->timer_mask.timer_bits); | 3819 | clear_bit(timer->index, &timer_table->timer_mask.timer_bits); |
4288 | |||
4289 | /* if no timer is enabled, turn off interrupt mask */ | ||
4290 | if (timer_table->timer_mask.val == 0) { | ||
4291 | ath9k_hw_set_interrupts(ah, 0); | ||
4292 | ah->ah_sc->imask &= ~ATH9K_INT_GENTIMER; | ||
4293 | ath9k_hw_set_interrupts(ah, ah->ah_sc->imask); | ||
4294 | } | ||
4295 | } | 3820 | } |
3821 | EXPORT_SYMBOL(ath9k_hw_gen_timer_stop); | ||
4296 | 3822 | ||
4297 | void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer) | 3823 | void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer) |
4298 | { | 3824 | { |
@@ -4302,6 +3828,7 @@ void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer) | |||
4302 | timer_table->timers[timer->index] = NULL; | 3828 | timer_table->timers[timer->index] = NULL; |
4303 | kfree(timer); | 3829 | kfree(timer); |
4304 | } | 3830 | } |
3831 | EXPORT_SYMBOL(ath_gen_timer_free); | ||
4305 | 3832 | ||
4306 | /* | 3833 | /* |
4307 | * Generic Timer Interrupts handling | 3834 | * Generic Timer Interrupts handling |
@@ -4310,6 +3837,7 @@ void ath_gen_timer_isr(struct ath_hw *ah) | |||
4310 | { | 3837 | { |
4311 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | 3838 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; |
4312 | struct ath_gen_timer *timer; | 3839 | struct ath_gen_timer *timer; |
3840 | struct ath_common *common = ath9k_hw_common(ah); | ||
4313 | u32 trigger_mask, thresh_mask, index; | 3841 | u32 trigger_mask, thresh_mask, index; |
4314 | 3842 | ||
4315 | /* get hardware generic timer interrupt status */ | 3843 | /* get hardware generic timer interrupt status */ |
@@ -4324,8 +3852,8 @@ void ath_gen_timer_isr(struct ath_hw *ah) | |||
4324 | index = rightmost_index(timer_table, &thresh_mask); | 3852 | index = rightmost_index(timer_table, &thresh_mask); |
4325 | timer = timer_table->timers[index]; | 3853 | timer = timer_table->timers[index]; |
4326 | BUG_ON(!timer); | 3854 | BUG_ON(!timer); |
4327 | DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER, | 3855 | ath_print(common, ATH_DBG_HWTIMER, |
4328 | "TSF overflow for Gen timer %d\n", index); | 3856 | "TSF overflow for Gen timer %d\n", index); |
4329 | timer->overflow(timer->arg); | 3857 | timer->overflow(timer->arg); |
4330 | } | 3858 | } |
4331 | 3859 | ||
@@ -4333,21 +3861,95 @@ void ath_gen_timer_isr(struct ath_hw *ah) | |||
4333 | index = rightmost_index(timer_table, &trigger_mask); | 3861 | index = rightmost_index(timer_table, &trigger_mask); |
4334 | timer = timer_table->timers[index]; | 3862 | timer = timer_table->timers[index]; |
4335 | BUG_ON(!timer); | 3863 | BUG_ON(!timer); |
4336 | DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER, | 3864 | ath_print(common, ATH_DBG_HWTIMER, |
4337 | "Gen timer[%d] trigger\n", index); | 3865 | "Gen timer[%d] trigger\n", index); |
4338 | timer->trigger(timer->arg); | 3866 | timer->trigger(timer->arg); |
4339 | } | 3867 | } |
4340 | } | 3868 | } |
3869 | EXPORT_SYMBOL(ath_gen_timer_isr); | ||
3870 | |||
3871 | static struct { | ||
3872 | u32 version; | ||
3873 | const char * name; | ||
3874 | } ath_mac_bb_names[] = { | ||
3875 | /* Devices with external radios */ | ||
3876 | { AR_SREV_VERSION_5416_PCI, "5416" }, | ||
3877 | { AR_SREV_VERSION_5416_PCIE, "5418" }, | ||
3878 | { AR_SREV_VERSION_9100, "9100" }, | ||
3879 | { AR_SREV_VERSION_9160, "9160" }, | ||
3880 | /* Single-chip solutions */ | ||
3881 | { AR_SREV_VERSION_9280, "9280" }, | ||
3882 | { AR_SREV_VERSION_9285, "9285" }, | ||
3883 | { AR_SREV_VERSION_9287, "9287" }, | ||
3884 | { AR_SREV_VERSION_9271, "9271" }, | ||
3885 | }; | ||
3886 | |||
3887 | /* For devices with external radios */ | ||
3888 | static struct { | ||
3889 | u16 version; | ||
3890 | const char * name; | ||
3891 | } ath_rf_names[] = { | ||
3892 | { 0, "5133" }, | ||
3893 | { AR_RAD5133_SREV_MAJOR, "5133" }, | ||
3894 | { AR_RAD5122_SREV_MAJOR, "5122" }, | ||
3895 | { AR_RAD2133_SREV_MAJOR, "2133" }, | ||
3896 | { AR_RAD2122_SREV_MAJOR, "2122" } | ||
3897 | }; | ||
3898 | |||
3899 | /* | ||
3900 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. | ||
3901 | */ | ||
3902 | static const char *ath9k_hw_mac_bb_name(u32 mac_bb_version) | ||
3903 | { | ||
3904 | int i; | ||
3905 | |||
3906 | for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) { | ||
3907 | if (ath_mac_bb_names[i].version == mac_bb_version) { | ||
3908 | return ath_mac_bb_names[i].name; | ||
3909 | } | ||
3910 | } | ||
3911 | |||
3912 | return "????"; | ||
3913 | } | ||
4341 | 3914 | ||
4342 | /* | 3915 | /* |
4343 | * Primitive to disable ASPM | 3916 | * Return the RF name. "????" is returned if the RF is unknown. |
3917 | * Used for devices with external radios. | ||
4344 | */ | 3918 | */ |
4345 | void ath_pcie_aspm_disable(struct ath_softc *sc) | 3919 | static const char *ath9k_hw_rf_name(u16 rf_version) |
4346 | { | 3920 | { |
4347 | struct pci_dev *pdev = to_pci_dev(sc->dev); | 3921 | int i; |
4348 | u8 aspm; | 3922 | |
3923 | for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) { | ||
3924 | if (ath_rf_names[i].version == rf_version) { | ||
3925 | return ath_rf_names[i].name; | ||
3926 | } | ||
3927 | } | ||
3928 | |||
3929 | return "????"; | ||
3930 | } | ||
3931 | |||
3932 | void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len) | ||
3933 | { | ||
3934 | int used; | ||
3935 | |||
3936 | /* chipsets >= AR9280 are single-chip */ | ||
3937 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
3938 | used = snprintf(hw_name, len, | ||
3939 | "Atheros AR%s Rev:%x", | ||
3940 | ath9k_hw_mac_bb_name(ah->hw_version.macVersion), | ||
3941 | ah->hw_version.macRev); | ||
3942 | } | ||
3943 | else { | ||
3944 | used = snprintf(hw_name, len, | ||
3945 | "Atheros AR%s MAC/BB Rev:%x AR%s RF Rev:%x", | ||
3946 | ath9k_hw_mac_bb_name(ah->hw_version.macVersion), | ||
3947 | ah->hw_version.macRev, | ||
3948 | ath9k_hw_rf_name((ah->hw_version.analog5GhzRev & | ||
3949 | AR_RADIO_SREV_MAJOR)), | ||
3950 | ah->hw_version.phyRev); | ||
3951 | } | ||
4349 | 3952 | ||
4350 | pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm); | 3953 | hw_name[used] = '\0'; |
4351 | aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1); | ||
4352 | pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm); | ||
4353 | } | 3954 | } |
3955 | EXPORT_SYMBOL(ath9k_hw_name); | ||