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/main.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/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 1943 |
1 files changed, 546 insertions, 1397 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 43d2be9867fc..115e1aeedb59 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -16,88 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include "ath9k.h" | 18 | #include "ath9k.h" |
19 | 19 | #include "btcoex.h" | |
20 | static char *dev_info = "ath9k"; | ||
21 | |||
22 | MODULE_AUTHOR("Atheros Communications"); | ||
23 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | ||
24 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | ||
25 | MODULE_LICENSE("Dual BSD/GPL"); | ||
26 | |||
27 | static int modparam_nohwcrypt; | ||
28 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | ||
29 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | ||
30 | |||
31 | /* We use the hw_value as an index into our private channel structure */ | ||
32 | |||
33 | #define CHAN2G(_freq, _idx) { \ | ||
34 | .center_freq = (_freq), \ | ||
35 | .hw_value = (_idx), \ | ||
36 | .max_power = 20, \ | ||
37 | } | ||
38 | |||
39 | #define CHAN5G(_freq, _idx) { \ | ||
40 | .band = IEEE80211_BAND_5GHZ, \ | ||
41 | .center_freq = (_freq), \ | ||
42 | .hw_value = (_idx), \ | ||
43 | .max_power = 20, \ | ||
44 | } | ||
45 | |||
46 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
47 | * on 5 MHz steps, we support the channels which we know | ||
48 | * we have calibration data for all cards though to make | ||
49 | * this static */ | ||
50 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
51 | CHAN2G(2412, 0), /* Channel 1 */ | ||
52 | CHAN2G(2417, 1), /* Channel 2 */ | ||
53 | CHAN2G(2422, 2), /* Channel 3 */ | ||
54 | CHAN2G(2427, 3), /* Channel 4 */ | ||
55 | CHAN2G(2432, 4), /* Channel 5 */ | ||
56 | CHAN2G(2437, 5), /* Channel 6 */ | ||
57 | CHAN2G(2442, 6), /* Channel 7 */ | ||
58 | CHAN2G(2447, 7), /* Channel 8 */ | ||
59 | CHAN2G(2452, 8), /* Channel 9 */ | ||
60 | CHAN2G(2457, 9), /* Channel 10 */ | ||
61 | CHAN2G(2462, 10), /* Channel 11 */ | ||
62 | CHAN2G(2467, 11), /* Channel 12 */ | ||
63 | CHAN2G(2472, 12), /* Channel 13 */ | ||
64 | CHAN2G(2484, 13), /* Channel 14 */ | ||
65 | }; | ||
66 | |||
67 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
68 | * on 5 MHz steps, we support the channels which we know | ||
69 | * we have calibration data for all cards though to make | ||
70 | * this static */ | ||
71 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
72 | /* _We_ call this UNII 1 */ | ||
73 | CHAN5G(5180, 14), /* Channel 36 */ | ||
74 | CHAN5G(5200, 15), /* Channel 40 */ | ||
75 | CHAN5G(5220, 16), /* Channel 44 */ | ||
76 | CHAN5G(5240, 17), /* Channel 48 */ | ||
77 | /* _We_ call this UNII 2 */ | ||
78 | CHAN5G(5260, 18), /* Channel 52 */ | ||
79 | CHAN5G(5280, 19), /* Channel 56 */ | ||
80 | CHAN5G(5300, 20), /* Channel 60 */ | ||
81 | CHAN5G(5320, 21), /* Channel 64 */ | ||
82 | /* _We_ call this "Middle band" */ | ||
83 | CHAN5G(5500, 22), /* Channel 100 */ | ||
84 | CHAN5G(5520, 23), /* Channel 104 */ | ||
85 | CHAN5G(5540, 24), /* Channel 108 */ | ||
86 | CHAN5G(5560, 25), /* Channel 112 */ | ||
87 | CHAN5G(5580, 26), /* Channel 116 */ | ||
88 | CHAN5G(5600, 27), /* Channel 120 */ | ||
89 | CHAN5G(5620, 28), /* Channel 124 */ | ||
90 | CHAN5G(5640, 29), /* Channel 128 */ | ||
91 | CHAN5G(5660, 30), /* Channel 132 */ | ||
92 | CHAN5G(5680, 31), /* Channel 136 */ | ||
93 | CHAN5G(5700, 32), /* Channel 140 */ | ||
94 | /* _We_ call this UNII 3 */ | ||
95 | CHAN5G(5745, 33), /* Channel 149 */ | ||
96 | CHAN5G(5765, 34), /* Channel 153 */ | ||
97 | CHAN5G(5785, 35), /* Channel 157 */ | ||
98 | CHAN5G(5805, 36), /* Channel 161 */ | ||
99 | CHAN5G(5825, 37), /* Channel 165 */ | ||
100 | }; | ||
101 | 20 | ||
102 | static void ath_cache_conf_rate(struct ath_softc *sc, | 21 | static void ath_cache_conf_rate(struct ath_softc *sc, |
103 | struct ieee80211_conf *conf) | 22 | struct ieee80211_conf *conf) |
@@ -105,31 +24,23 @@ static void ath_cache_conf_rate(struct ath_softc *sc, | |||
105 | switch (conf->channel->band) { | 24 | switch (conf->channel->band) { |
106 | case IEEE80211_BAND_2GHZ: | 25 | case IEEE80211_BAND_2GHZ: |
107 | if (conf_is_ht20(conf)) | 26 | if (conf_is_ht20(conf)) |
108 | sc->cur_rate_table = | 27 | sc->cur_rate_mode = ATH9K_MODE_11NG_HT20; |
109 | sc->hw_rate_table[ATH9K_MODE_11NG_HT20]; | ||
110 | else if (conf_is_ht40_minus(conf)) | 28 | else if (conf_is_ht40_minus(conf)) |
111 | sc->cur_rate_table = | 29 | sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS; |
112 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS]; | ||
113 | else if (conf_is_ht40_plus(conf)) | 30 | else if (conf_is_ht40_plus(conf)) |
114 | sc->cur_rate_table = | 31 | sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS; |
115 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS]; | ||
116 | else | 32 | else |
117 | sc->cur_rate_table = | 33 | sc->cur_rate_mode = ATH9K_MODE_11G; |
118 | sc->hw_rate_table[ATH9K_MODE_11G]; | ||
119 | break; | 34 | break; |
120 | case IEEE80211_BAND_5GHZ: | 35 | case IEEE80211_BAND_5GHZ: |
121 | if (conf_is_ht20(conf)) | 36 | if (conf_is_ht20(conf)) |
122 | sc->cur_rate_table = | 37 | sc->cur_rate_mode = ATH9K_MODE_11NA_HT20; |
123 | sc->hw_rate_table[ATH9K_MODE_11NA_HT20]; | ||
124 | else if (conf_is_ht40_minus(conf)) | 38 | else if (conf_is_ht40_minus(conf)) |
125 | sc->cur_rate_table = | 39 | sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS; |
126 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS]; | ||
127 | else if (conf_is_ht40_plus(conf)) | 40 | else if (conf_is_ht40_plus(conf)) |
128 | sc->cur_rate_table = | 41 | sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS; |
129 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS]; | ||
130 | else | 42 | else |
131 | sc->cur_rate_table = | 43 | sc->cur_rate_mode = ATH9K_MODE_11A; |
132 | sc->hw_rate_table[ATH9K_MODE_11A]; | ||
133 | break; | 44 | break; |
134 | default: | 45 | default: |
135 | BUG_ON(1); | 46 | BUG_ON(1); |
@@ -185,50 +96,6 @@ static u8 parse_mpdudensity(u8 mpdudensity) | |||
185 | } | 96 | } |
186 | } | 97 | } |
187 | 98 | ||
188 | static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | ||
189 | { | ||
190 | const struct ath_rate_table *rate_table = NULL; | ||
191 | struct ieee80211_supported_band *sband; | ||
192 | struct ieee80211_rate *rate; | ||
193 | int i, maxrates; | ||
194 | |||
195 | switch (band) { | ||
196 | case IEEE80211_BAND_2GHZ: | ||
197 | rate_table = sc->hw_rate_table[ATH9K_MODE_11G]; | ||
198 | break; | ||
199 | case IEEE80211_BAND_5GHZ: | ||
200 | rate_table = sc->hw_rate_table[ATH9K_MODE_11A]; | ||
201 | break; | ||
202 | default: | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | if (rate_table == NULL) | ||
207 | return; | ||
208 | |||
209 | sband = &sc->sbands[band]; | ||
210 | rate = sc->rates[band]; | ||
211 | |||
212 | if (rate_table->rate_cnt > ATH_RATE_MAX) | ||
213 | maxrates = ATH_RATE_MAX; | ||
214 | else | ||
215 | maxrates = rate_table->rate_cnt; | ||
216 | |||
217 | for (i = 0; i < maxrates; i++) { | ||
218 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; | ||
219 | rate[i].hw_value = rate_table->info[i].ratecode; | ||
220 | if (rate_table->info[i].short_preamble) { | ||
221 | rate[i].hw_value_short = rate_table->info[i].ratecode | | ||
222 | rate_table->info[i].short_preamble; | ||
223 | rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE; | ||
224 | } | ||
225 | sband->n_bitrates++; | ||
226 | |||
227 | DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", | ||
228 | rate[i].bitrate / 10, rate[i].hw_value); | ||
229 | } | ||
230 | } | ||
231 | |||
232 | static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, | 99 | static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, |
233 | struct ieee80211_hw *hw) | 100 | struct ieee80211_hw *hw) |
234 | { | 101 | { |
@@ -242,6 +109,53 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, | |||
242 | return channel; | 109 | return channel; |
243 | } | 110 | } |
244 | 111 | ||
112 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) | ||
113 | { | ||
114 | unsigned long flags; | ||
115 | bool ret; | ||
116 | |||
117 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
118 | ret = ath9k_hw_setpower(sc->sc_ah, mode); | ||
119 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
120 | |||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | void ath9k_ps_wakeup(struct ath_softc *sc) | ||
125 | { | ||
126 | unsigned long flags; | ||
127 | |||
128 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
129 | if (++sc->ps_usecount != 1) | ||
130 | goto unlock; | ||
131 | |||
132 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
133 | |||
134 | unlock: | ||
135 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
136 | } | ||
137 | |||
138 | void ath9k_ps_restore(struct ath_softc *sc) | ||
139 | { | ||
140 | unsigned long flags; | ||
141 | |||
142 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
143 | if (--sc->ps_usecount != 0) | ||
144 | goto unlock; | ||
145 | |||
146 | if (sc->ps_idle) | ||
147 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); | ||
148 | else if (sc->ps_enabled && | ||
149 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | | ||
150 | PS_WAIT_FOR_CAB | | ||
151 | PS_WAIT_FOR_PSPOLL_DATA | | ||
152 | PS_WAIT_FOR_TX_ACK))) | ||
153 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | ||
154 | |||
155 | unlock: | ||
156 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
157 | } | ||
158 | |||
245 | /* | 159 | /* |
246 | * Set/change channels. If the channel is really being changed, it's done | 160 | * Set/change channels. If the channel is really being changed, it's done |
247 | * by reseting the chip. To accomplish this we must first cleanup any pending | 161 | * by reseting the chip. To accomplish this we must first cleanup any pending |
@@ -251,6 +165,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
251 | struct ath9k_channel *hchan) | 165 | struct ath9k_channel *hchan) |
252 | { | 166 | { |
253 | struct ath_hw *ah = sc->sc_ah; | 167 | struct ath_hw *ah = sc->sc_ah; |
168 | struct ath_common *common = ath9k_hw_common(ah); | ||
169 | struct ieee80211_conf *conf = &common->hw->conf; | ||
254 | bool fastcc = true, stopped; | 170 | bool fastcc = true, stopped; |
255 | struct ieee80211_channel *channel = hw->conf.channel; | 171 | struct ieee80211_channel *channel = hw->conf.channel; |
256 | int r; | 172 | int r; |
@@ -280,19 +196,19 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
280 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) | 196 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) |
281 | fastcc = false; | 197 | fastcc = false; |
282 | 198 | ||
283 | DPRINTF(sc, ATH_DBG_CONFIG, | 199 | ath_print(common, ATH_DBG_CONFIG, |
284 | "(%u MHz) -> (%u MHz), chanwidth: %d\n", | 200 | "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n", |
285 | sc->sc_ah->curchan->channel, | 201 | sc->sc_ah->curchan->channel, |
286 | channel->center_freq, sc->tx_chan_width); | 202 | channel->center_freq, conf_is_ht40(conf)); |
287 | 203 | ||
288 | spin_lock_bh(&sc->sc_resetlock); | 204 | spin_lock_bh(&sc->sc_resetlock); |
289 | 205 | ||
290 | r = ath9k_hw_reset(ah, hchan, fastcc); | 206 | r = ath9k_hw_reset(ah, hchan, fastcc); |
291 | if (r) { | 207 | if (r) { |
292 | DPRINTF(sc, ATH_DBG_FATAL, | 208 | ath_print(common, ATH_DBG_FATAL, |
293 | "Unable to reset channel (%u Mhz) " | 209 | "Unable to reset channel (%u MHz), " |
294 | "reset status %d\n", | 210 | "reset status %d\n", |
295 | channel->center_freq, r); | 211 | channel->center_freq, r); |
296 | spin_unlock_bh(&sc->sc_resetlock); | 212 | spin_unlock_bh(&sc->sc_resetlock); |
297 | goto ps_restore; | 213 | goto ps_restore; |
298 | } | 214 | } |
@@ -301,8 +217,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
301 | sc->sc_flags &= ~SC_OP_FULL_RESET; | 217 | sc->sc_flags &= ~SC_OP_FULL_RESET; |
302 | 218 | ||
303 | if (ath_startrecv(sc) != 0) { | 219 | if (ath_startrecv(sc) != 0) { |
304 | DPRINTF(sc, ATH_DBG_FATAL, | 220 | ath_print(common, ATH_DBG_FATAL, |
305 | "Unable to restart recv logic\n"); | 221 | "Unable to restart recv logic\n"); |
306 | r = -EIO; | 222 | r = -EIO; |
307 | goto ps_restore; | 223 | goto ps_restore; |
308 | } | 224 | } |
@@ -323,10 +239,11 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
323 | * When the task is complete, it reschedules itself depending on the | 239 | * When the task is complete, it reschedules itself depending on the |
324 | * appropriate interval that was calculated. | 240 | * appropriate interval that was calculated. |
325 | */ | 241 | */ |
326 | static void ath_ani_calibrate(unsigned long data) | 242 | void ath_ani_calibrate(unsigned long data) |
327 | { | 243 | { |
328 | struct ath_softc *sc = (struct ath_softc *)data; | 244 | struct ath_softc *sc = (struct ath_softc *)data; |
329 | struct ath_hw *ah = sc->sc_ah; | 245 | struct ath_hw *ah = sc->sc_ah; |
246 | struct ath_common *common = ath9k_hw_common(ah); | ||
330 | bool longcal = false; | 247 | bool longcal = false; |
331 | bool shortcal = false; | 248 | bool shortcal = false; |
332 | bool aniflag = false; | 249 | bool aniflag = false; |
@@ -336,14 +253,6 @@ static void ath_ani_calibrate(unsigned long data) | |||
336 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? | 253 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? |
337 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; | 254 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; |
338 | 255 | ||
339 | /* | ||
340 | * don't calibrate when we're scanning. | ||
341 | * we are most likely not on our home channel. | ||
342 | */ | ||
343 | spin_lock(&sc->ani_lock); | ||
344 | if (sc->sc_flags & SC_OP_SCANNING) | ||
345 | goto set_timer; | ||
346 | |||
347 | /* Only calibrate if awake */ | 256 | /* Only calibrate if awake */ |
348 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) | 257 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) |
349 | goto set_timer; | 258 | goto set_timer; |
@@ -351,33 +260,34 @@ static void ath_ani_calibrate(unsigned long data) | |||
351 | ath9k_ps_wakeup(sc); | 260 | ath9k_ps_wakeup(sc); |
352 | 261 | ||
353 | /* Long calibration runs independently of short calibration. */ | 262 | /* Long calibration runs independently of short calibration. */ |
354 | if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { | 263 | if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { |
355 | longcal = true; | 264 | longcal = true; |
356 | DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies); | 265 | ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); |
357 | sc->ani.longcal_timer = timestamp; | 266 | common->ani.longcal_timer = timestamp; |
358 | } | 267 | } |
359 | 268 | ||
360 | /* Short calibration applies only while caldone is false */ | 269 | /* Short calibration applies only while caldone is false */ |
361 | if (!sc->ani.caldone) { | 270 | if (!common->ani.caldone) { |
362 | if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) { | 271 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { |
363 | shortcal = true; | 272 | shortcal = true; |
364 | DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies); | 273 | ath_print(common, ATH_DBG_ANI, |
365 | sc->ani.shortcal_timer = timestamp; | 274 | "shortcal @%lu\n", jiffies); |
366 | sc->ani.resetcal_timer = timestamp; | 275 | common->ani.shortcal_timer = timestamp; |
276 | common->ani.resetcal_timer = timestamp; | ||
367 | } | 277 | } |
368 | } else { | 278 | } else { |
369 | if ((timestamp - sc->ani.resetcal_timer) >= | 279 | if ((timestamp - common->ani.resetcal_timer) >= |
370 | ATH_RESTART_CALINTERVAL) { | 280 | ATH_RESTART_CALINTERVAL) { |
371 | sc->ani.caldone = ath9k_hw_reset_calvalid(ah); | 281 | common->ani.caldone = ath9k_hw_reset_calvalid(ah); |
372 | if (sc->ani.caldone) | 282 | if (common->ani.caldone) |
373 | sc->ani.resetcal_timer = timestamp; | 283 | common->ani.resetcal_timer = timestamp; |
374 | } | 284 | } |
375 | } | 285 | } |
376 | 286 | ||
377 | /* Verify whether we must check ANI */ | 287 | /* Verify whether we must check ANI */ |
378 | if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { | 288 | if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { |
379 | aniflag = true; | 289 | aniflag = true; |
380 | sc->ani.checkani_timer = timestamp; | 290 | common->ani.checkani_timer = timestamp; |
381 | } | 291 | } |
382 | 292 | ||
383 | /* Skip all processing if there's nothing to do. */ | 293 | /* Skip all processing if there's nothing to do. */ |
@@ -388,23 +298,27 @@ static void ath_ani_calibrate(unsigned long data) | |||
388 | 298 | ||
389 | /* Perform calibration if necessary */ | 299 | /* Perform calibration if necessary */ |
390 | if (longcal || shortcal) { | 300 | if (longcal || shortcal) { |
391 | sc->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan, | 301 | common->ani.caldone = |
392 | sc->rx_chainmask, longcal); | 302 | ath9k_hw_calibrate(ah, |
303 | ah->curchan, | ||
304 | common->rx_chainmask, | ||
305 | longcal); | ||
393 | 306 | ||
394 | if (longcal) | 307 | if (longcal) |
395 | sc->ani.noise_floor = ath9k_hw_getchan_noise(ah, | 308 | common->ani.noise_floor = ath9k_hw_getchan_noise(ah, |
396 | ah->curchan); | 309 | ah->curchan); |
397 | 310 | ||
398 | DPRINTF(sc, ATH_DBG_ANI," calibrate chan %u/%x nf: %d\n", | 311 | ath_print(common, ATH_DBG_ANI, |
399 | ah->curchan->channel, ah->curchan->channelFlags, | 312 | " calibrate chan %u/%x nf: %d\n", |
400 | sc->ani.noise_floor); | 313 | ah->curchan->channel, |
314 | ah->curchan->channelFlags, | ||
315 | common->ani.noise_floor); | ||
401 | } | 316 | } |
402 | } | 317 | } |
403 | 318 | ||
404 | ath9k_ps_restore(sc); | 319 | ath9k_ps_restore(sc); |
405 | 320 | ||
406 | set_timer: | 321 | set_timer: |
407 | spin_unlock(&sc->ani_lock); | ||
408 | /* | 322 | /* |
409 | * Set timer interval based on previous results. | 323 | * Set timer interval based on previous results. |
410 | * The interval must be the shortest necessary to satisfy ANI, | 324 | * The interval must be the shortest necessary to satisfy ANI, |
@@ -413,21 +327,21 @@ set_timer: | |||
413 | cal_interval = ATH_LONG_CALINTERVAL; | 327 | cal_interval = ATH_LONG_CALINTERVAL; |
414 | if (sc->sc_ah->config.enable_ani) | 328 | if (sc->sc_ah->config.enable_ani) |
415 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); | 329 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); |
416 | if (!sc->ani.caldone) | 330 | if (!common->ani.caldone) |
417 | cal_interval = min(cal_interval, (u32)short_cal_interval); | 331 | cal_interval = min(cal_interval, (u32)short_cal_interval); |
418 | 332 | ||
419 | mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | 333 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); |
420 | } | 334 | } |
421 | 335 | ||
422 | static void ath_start_ani(struct ath_softc *sc) | 336 | static void ath_start_ani(struct ath_common *common) |
423 | { | 337 | { |
424 | unsigned long timestamp = jiffies_to_msecs(jiffies); | 338 | unsigned long timestamp = jiffies_to_msecs(jiffies); |
425 | 339 | ||
426 | sc->ani.longcal_timer = timestamp; | 340 | common->ani.longcal_timer = timestamp; |
427 | sc->ani.shortcal_timer = timestamp; | 341 | common->ani.shortcal_timer = timestamp; |
428 | sc->ani.checkani_timer = timestamp; | 342 | common->ani.checkani_timer = timestamp; |
429 | 343 | ||
430 | mod_timer(&sc->ani.timer, | 344 | mod_timer(&common->ani.timer, |
431 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | 345 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); |
432 | } | 346 | } |
433 | 347 | ||
@@ -439,17 +353,22 @@ static void ath_start_ani(struct ath_softc *sc) | |||
439 | */ | 353 | */ |
440 | void ath_update_chainmask(struct ath_softc *sc, int is_ht) | 354 | void ath_update_chainmask(struct ath_softc *sc, int is_ht) |
441 | { | 355 | { |
356 | struct ath_hw *ah = sc->sc_ah; | ||
357 | struct ath_common *common = ath9k_hw_common(ah); | ||
358 | |||
442 | if ((sc->sc_flags & SC_OP_SCANNING) || is_ht || | 359 | if ((sc->sc_flags & SC_OP_SCANNING) || is_ht || |
443 | (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE)) { | 360 | (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) { |
444 | sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask; | 361 | common->tx_chainmask = ah->caps.tx_chainmask; |
445 | sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask; | 362 | common->rx_chainmask = ah->caps.rx_chainmask; |
446 | } else { | 363 | } else { |
447 | sc->tx_chainmask = 1; | 364 | common->tx_chainmask = 1; |
448 | sc->rx_chainmask = 1; | 365 | common->rx_chainmask = 1; |
449 | } | 366 | } |
450 | 367 | ||
451 | DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n", | 368 | ath_print(common, ATH_DBG_CONFIG, |
452 | sc->tx_chainmask, sc->rx_chainmask); | 369 | "tx chmask: %d, rx chmask: %d\n", |
370 | common->tx_chainmask, | ||
371 | common->rx_chainmask); | ||
453 | } | 372 | } |
454 | 373 | ||
455 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | 374 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) |
@@ -475,9 +394,12 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
475 | ath_tx_node_cleanup(sc, an); | 394 | ath_tx_node_cleanup(sc, an); |
476 | } | 395 | } |
477 | 396 | ||
478 | static void ath9k_tasklet(unsigned long data) | 397 | void ath9k_tasklet(unsigned long data) |
479 | { | 398 | { |
480 | struct ath_softc *sc = (struct ath_softc *)data; | 399 | struct ath_softc *sc = (struct ath_softc *)data; |
400 | struct ath_hw *ah = sc->sc_ah; | ||
401 | struct ath_common *common = ath9k_hw_common(ah); | ||
402 | |||
481 | u32 status = sc->intrstatus; | 403 | u32 status = sc->intrstatus; |
482 | 404 | ||
483 | ath9k_ps_wakeup(sc); | 405 | ath9k_ps_wakeup(sc); |
@@ -502,16 +424,17 @@ static void ath9k_tasklet(unsigned long data) | |||
502 | * TSF sync does not look correct; remain awake to sync with | 424 | * TSF sync does not look correct; remain awake to sync with |
503 | * the next Beacon. | 425 | * the next Beacon. |
504 | */ | 426 | */ |
505 | DPRINTF(sc, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n"); | 427 | ath_print(common, ATH_DBG_PS, |
506 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC; | 428 | "TSFOOR - Sync with next Beacon\n"); |
429 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; | ||
507 | } | 430 | } |
508 | 431 | ||
509 | if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) | 432 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
510 | if (status & ATH9K_INT_GENTIMER) | 433 | if (status & ATH9K_INT_GENTIMER) |
511 | ath_gen_timer_isr(sc->sc_ah); | 434 | ath_gen_timer_isr(sc->sc_ah); |
512 | 435 | ||
513 | /* re-enable hardware interrupt */ | 436 | /* re-enable hardware interrupt */ |
514 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 437 | ath9k_hw_set_interrupts(ah, sc->imask); |
515 | ath9k_ps_restore(sc); | 438 | ath9k_ps_restore(sc); |
516 | } | 439 | } |
517 | 440 | ||
@@ -602,9 +525,9 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
602 | if (status & ATH9K_INT_TIM_TIMER) { | 525 | if (status & ATH9K_INT_TIM_TIMER) { |
603 | /* Clear RxAbort bit so that we can | 526 | /* Clear RxAbort bit so that we can |
604 | * receive frames */ | 527 | * receive frames */ |
605 | ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); | 528 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
606 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 529 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
607 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; | 530 | sc->ps_flags |= PS_WAIT_FOR_BEACON; |
608 | } | 531 | } |
609 | 532 | ||
610 | chip_reset: | 533 | chip_reset: |
@@ -664,10 +587,11 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, | |||
664 | return chanmode; | 587 | return chanmode; |
665 | } | 588 | } |
666 | 589 | ||
667 | static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, | 590 | static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, |
668 | struct ath9k_keyval *hk, const u8 *addr, | 591 | struct ath9k_keyval *hk, const u8 *addr, |
669 | bool authenticator) | 592 | bool authenticator) |
670 | { | 593 | { |
594 | struct ath_hw *ah = common->ah; | ||
671 | const u8 *key_rxmic; | 595 | const u8 *key_rxmic; |
672 | const u8 *key_txmic; | 596 | const u8 *key_txmic; |
673 | 597 | ||
@@ -687,42 +611,42 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, | |||
687 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 611 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
688 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); | 612 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); |
689 | } | 613 | } |
690 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr); | 614 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); |
691 | } | 615 | } |
692 | if (!sc->splitmic) { | 616 | if (!common->splitmic) { |
693 | /* TX and RX keys share the same key cache entry. */ | 617 | /* TX and RX keys share the same key cache entry. */ |
694 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 618 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
695 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); | 619 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); |
696 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr); | 620 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); |
697 | } | 621 | } |
698 | 622 | ||
699 | /* Separate key cache entries for TX and RX */ | 623 | /* Separate key cache entries for TX and RX */ |
700 | 624 | ||
701 | /* TX key goes at first index, RX key at +32. */ | 625 | /* TX key goes at first index, RX key at +32. */ |
702 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | 626 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); |
703 | if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) { | 627 | if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { |
704 | /* TX MIC entry failed. No need to proceed further */ | 628 | /* TX MIC entry failed. No need to proceed further */ |
705 | DPRINTF(sc, ATH_DBG_FATAL, | 629 | ath_print(common, ATH_DBG_FATAL, |
706 | "Setting TX MIC Key Failed\n"); | 630 | "Setting TX MIC Key Failed\n"); |
707 | return 0; | 631 | return 0; |
708 | } | 632 | } |
709 | 633 | ||
710 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 634 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
711 | /* XXX delete tx key on failure? */ | 635 | /* XXX delete tx key on failure? */ |
712 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr); | 636 | return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); |
713 | } | 637 | } |
714 | 638 | ||
715 | static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) | 639 | static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) |
716 | { | 640 | { |
717 | int i; | 641 | int i; |
718 | 642 | ||
719 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) { | 643 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { |
720 | if (test_bit(i, sc->keymap) || | 644 | if (test_bit(i, common->keymap) || |
721 | test_bit(i + 64, sc->keymap)) | 645 | test_bit(i + 64, common->keymap)) |
722 | continue; /* At least one part of TKIP key allocated */ | 646 | continue; /* At least one part of TKIP key allocated */ |
723 | if (sc->splitmic && | 647 | if (common->splitmic && |
724 | (test_bit(i + 32, sc->keymap) || | 648 | (test_bit(i + 32, common->keymap) || |
725 | test_bit(i + 64 + 32, sc->keymap))) | 649 | test_bit(i + 64 + 32, common->keymap))) |
726 | continue; /* At least one part of TKIP key allocated */ | 650 | continue; /* At least one part of TKIP key allocated */ |
727 | 651 | ||
728 | /* Found a free slot for a TKIP key */ | 652 | /* Found a free slot for a TKIP key */ |
@@ -731,60 +655,60 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) | |||
731 | return -1; | 655 | return -1; |
732 | } | 656 | } |
733 | 657 | ||
734 | static int ath_reserve_key_cache_slot(struct ath_softc *sc) | 658 | static int ath_reserve_key_cache_slot(struct ath_common *common) |
735 | { | 659 | { |
736 | int i; | 660 | int i; |
737 | 661 | ||
738 | /* First, try to find slots that would not be available for TKIP. */ | 662 | /* First, try to find slots that would not be available for TKIP. */ |
739 | if (sc->splitmic) { | 663 | if (common->splitmic) { |
740 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) { | 664 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { |
741 | if (!test_bit(i, sc->keymap) && | 665 | if (!test_bit(i, common->keymap) && |
742 | (test_bit(i + 32, sc->keymap) || | 666 | (test_bit(i + 32, common->keymap) || |
743 | test_bit(i + 64, sc->keymap) || | 667 | test_bit(i + 64, common->keymap) || |
744 | test_bit(i + 64 + 32, sc->keymap))) | 668 | test_bit(i + 64 + 32, common->keymap))) |
745 | return i; | 669 | return i; |
746 | if (!test_bit(i + 32, sc->keymap) && | 670 | if (!test_bit(i + 32, common->keymap) && |
747 | (test_bit(i, sc->keymap) || | 671 | (test_bit(i, common->keymap) || |
748 | test_bit(i + 64, sc->keymap) || | 672 | test_bit(i + 64, common->keymap) || |
749 | test_bit(i + 64 + 32, sc->keymap))) | 673 | test_bit(i + 64 + 32, common->keymap))) |
750 | return i + 32; | 674 | return i + 32; |
751 | if (!test_bit(i + 64, sc->keymap) && | 675 | if (!test_bit(i + 64, common->keymap) && |
752 | (test_bit(i , sc->keymap) || | 676 | (test_bit(i , common->keymap) || |
753 | test_bit(i + 32, sc->keymap) || | 677 | test_bit(i + 32, common->keymap) || |
754 | test_bit(i + 64 + 32, sc->keymap))) | 678 | test_bit(i + 64 + 32, common->keymap))) |
755 | return i + 64; | 679 | return i + 64; |
756 | if (!test_bit(i + 64 + 32, sc->keymap) && | 680 | if (!test_bit(i + 64 + 32, common->keymap) && |
757 | (test_bit(i, sc->keymap) || | 681 | (test_bit(i, common->keymap) || |
758 | test_bit(i + 32, sc->keymap) || | 682 | test_bit(i + 32, common->keymap) || |
759 | test_bit(i + 64, sc->keymap))) | 683 | test_bit(i + 64, common->keymap))) |
760 | return i + 64 + 32; | 684 | return i + 64 + 32; |
761 | } | 685 | } |
762 | } else { | 686 | } else { |
763 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) { | 687 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { |
764 | if (!test_bit(i, sc->keymap) && | 688 | if (!test_bit(i, common->keymap) && |
765 | test_bit(i + 64, sc->keymap)) | 689 | test_bit(i + 64, common->keymap)) |
766 | return i; | 690 | return i; |
767 | if (test_bit(i, sc->keymap) && | 691 | if (test_bit(i, common->keymap) && |
768 | !test_bit(i + 64, sc->keymap)) | 692 | !test_bit(i + 64, common->keymap)) |
769 | return i + 64; | 693 | return i + 64; |
770 | } | 694 | } |
771 | } | 695 | } |
772 | 696 | ||
773 | /* No partially used TKIP slots, pick any available slot */ | 697 | /* No partially used TKIP slots, pick any available slot */ |
774 | for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) { | 698 | for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { |
775 | /* Do not allow slots that could be needed for TKIP group keys | 699 | /* Do not allow slots that could be needed for TKIP group keys |
776 | * to be used. This limitation could be removed if we know that | 700 | * to be used. This limitation could be removed if we know that |
777 | * TKIP will not be used. */ | 701 | * TKIP will not be used. */ |
778 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) | 702 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) |
779 | continue; | 703 | continue; |
780 | if (sc->splitmic) { | 704 | if (common->splitmic) { |
781 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) | 705 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) |
782 | continue; | 706 | continue; |
783 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) | 707 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) |
784 | continue; | 708 | continue; |
785 | } | 709 | } |
786 | 710 | ||
787 | if (!test_bit(i, sc->keymap)) | 711 | if (!test_bit(i, common->keymap)) |
788 | return i; /* Found a free slot for a key */ | 712 | return i; /* Found a free slot for a key */ |
789 | } | 713 | } |
790 | 714 | ||
@@ -792,11 +716,12 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc) | |||
792 | return -1; | 716 | return -1; |
793 | } | 717 | } |
794 | 718 | ||
795 | static int ath_key_config(struct ath_softc *sc, | 719 | static int ath_key_config(struct ath_common *common, |
796 | struct ieee80211_vif *vif, | 720 | struct ieee80211_vif *vif, |
797 | struct ieee80211_sta *sta, | 721 | struct ieee80211_sta *sta, |
798 | struct ieee80211_key_conf *key) | 722 | struct ieee80211_key_conf *key) |
799 | { | 723 | { |
724 | struct ath_hw *ah = common->ah; | ||
800 | struct ath9k_keyval hk; | 725 | struct ath9k_keyval hk; |
801 | const u8 *mac = NULL; | 726 | const u8 *mac = NULL; |
802 | int ret = 0; | 727 | int ret = 0; |
@@ -842,104 +767,76 @@ static int ath_key_config(struct ath_softc *sc, | |||
842 | mac = sta->addr; | 767 | mac = sta->addr; |
843 | 768 | ||
844 | if (key->alg == ALG_TKIP) | 769 | if (key->alg == ALG_TKIP) |
845 | idx = ath_reserve_key_cache_slot_tkip(sc); | 770 | idx = ath_reserve_key_cache_slot_tkip(common); |
846 | else | 771 | else |
847 | idx = ath_reserve_key_cache_slot(sc); | 772 | idx = ath_reserve_key_cache_slot(common); |
848 | if (idx < 0) | 773 | if (idx < 0) |
849 | return -ENOSPC; /* no free key cache entries */ | 774 | return -ENOSPC; /* no free key cache entries */ |
850 | } | 775 | } |
851 | 776 | ||
852 | if (key->alg == ALG_TKIP) | 777 | if (key->alg == ALG_TKIP) |
853 | ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac, | 778 | ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, |
854 | vif->type == NL80211_IFTYPE_AP); | 779 | vif->type == NL80211_IFTYPE_AP); |
855 | else | 780 | else |
856 | ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac); | 781 | ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); |
857 | 782 | ||
858 | if (!ret) | 783 | if (!ret) |
859 | return -EIO; | 784 | return -EIO; |
860 | 785 | ||
861 | set_bit(idx, sc->keymap); | 786 | set_bit(idx, common->keymap); |
862 | if (key->alg == ALG_TKIP) { | 787 | if (key->alg == ALG_TKIP) { |
863 | set_bit(idx + 64, sc->keymap); | 788 | set_bit(idx + 64, common->keymap); |
864 | if (sc->splitmic) { | 789 | if (common->splitmic) { |
865 | set_bit(idx + 32, sc->keymap); | 790 | set_bit(idx + 32, common->keymap); |
866 | set_bit(idx + 64 + 32, sc->keymap); | 791 | set_bit(idx + 64 + 32, common->keymap); |
867 | } | 792 | } |
868 | } | 793 | } |
869 | 794 | ||
870 | return idx; | 795 | return idx; |
871 | } | 796 | } |
872 | 797 | ||
873 | static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) | 798 | static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) |
874 | { | 799 | { |
875 | ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx); | 800 | struct ath_hw *ah = common->ah; |
801 | |||
802 | ath9k_hw_keyreset(ah, key->hw_key_idx); | ||
876 | if (key->hw_key_idx < IEEE80211_WEP_NKID) | 803 | if (key->hw_key_idx < IEEE80211_WEP_NKID) |
877 | return; | 804 | return; |
878 | 805 | ||
879 | clear_bit(key->hw_key_idx, sc->keymap); | 806 | clear_bit(key->hw_key_idx, common->keymap); |
880 | if (key->alg != ALG_TKIP) | 807 | if (key->alg != ALG_TKIP) |
881 | return; | 808 | return; |
882 | 809 | ||
883 | clear_bit(key->hw_key_idx + 64, sc->keymap); | 810 | clear_bit(key->hw_key_idx + 64, common->keymap); |
884 | if (sc->splitmic) { | 811 | if (common->splitmic) { |
885 | clear_bit(key->hw_key_idx + 32, sc->keymap); | 812 | ath9k_hw_keyreset(ah, key->hw_key_idx + 32); |
886 | clear_bit(key->hw_key_idx + 64 + 32, sc->keymap); | 813 | clear_bit(key->hw_key_idx + 32, common->keymap); |
814 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); | ||
887 | } | 815 | } |
888 | } | 816 | } |
889 | 817 | ||
890 | static void setup_ht_cap(struct ath_softc *sc, | ||
891 | struct ieee80211_sta_ht_cap *ht_info) | ||
892 | { | ||
893 | u8 tx_streams, rx_streams; | ||
894 | |||
895 | ht_info->ht_supported = true; | ||
896 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
897 | IEEE80211_HT_CAP_SM_PS | | ||
898 | IEEE80211_HT_CAP_SGI_40 | | ||
899 | IEEE80211_HT_CAP_DSSSCCK40; | ||
900 | |||
901 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
902 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
903 | |||
904 | /* set up supported mcs set */ | ||
905 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
906 | tx_streams = !(sc->tx_chainmask & (sc->tx_chainmask - 1)) ? 1 : 2; | ||
907 | rx_streams = !(sc->rx_chainmask & (sc->rx_chainmask - 1)) ? 1 : 2; | ||
908 | |||
909 | if (tx_streams != rx_streams) { | ||
910 | DPRINTF(sc, ATH_DBG_CONFIG, "TX streams %d, RX streams: %d\n", | ||
911 | tx_streams, rx_streams); | ||
912 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
913 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | ||
914 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
915 | } | ||
916 | |||
917 | ht_info->mcs.rx_mask[0] = 0xff; | ||
918 | if (rx_streams >= 2) | ||
919 | ht_info->mcs.rx_mask[1] = 0xff; | ||
920 | |||
921 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
922 | } | ||
923 | |||
924 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | 818 | static void ath9k_bss_assoc_info(struct ath_softc *sc, |
925 | struct ieee80211_vif *vif, | 819 | struct ieee80211_vif *vif, |
926 | struct ieee80211_bss_conf *bss_conf) | 820 | struct ieee80211_bss_conf *bss_conf) |
927 | { | 821 | { |
822 | struct ath_hw *ah = sc->sc_ah; | ||
823 | struct ath_common *common = ath9k_hw_common(ah); | ||
928 | 824 | ||
929 | if (bss_conf->assoc) { | 825 | if (bss_conf->assoc) { |
930 | DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", | 826 | ath_print(common, ATH_DBG_CONFIG, |
931 | bss_conf->aid, sc->curbssid); | 827 | "Bss Info ASSOC %d, bssid: %pM\n", |
828 | bss_conf->aid, common->curbssid); | ||
932 | 829 | ||
933 | /* New association, store aid */ | 830 | /* New association, store aid */ |
934 | sc->curaid = bss_conf->aid; | 831 | common->curaid = bss_conf->aid; |
935 | ath9k_hw_write_associd(sc); | 832 | ath9k_hw_write_associd(ah); |
936 | 833 | ||
937 | /* | 834 | /* |
938 | * Request a re-configuration of Beacon related timers | 835 | * Request a re-configuration of Beacon related timers |
939 | * on the receipt of the first Beacon frame (i.e., | 836 | * on the receipt of the first Beacon frame (i.e., |
940 | * after time sync with the AP). | 837 | * after time sync with the AP). |
941 | */ | 838 | */ |
942 | sc->sc_flags |= SC_OP_BEACON_SYNC; | 839 | sc->ps_flags |= PS_BEACON_SYNC; |
943 | 840 | ||
944 | /* Configure the beacon */ | 841 | /* Configure the beacon */ |
945 | ath_beacon_config(sc, vif); | 842 | ath_beacon_config(sc, vif); |
@@ -947,187 +844,20 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
947 | /* Reset rssi stats */ | 844 | /* Reset rssi stats */ |
948 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 845 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
949 | 846 | ||
950 | ath_start_ani(sc); | 847 | ath_start_ani(common); |
951 | } else { | 848 | } else { |
952 | DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); | 849 | ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); |
953 | sc->curaid = 0; | 850 | common->curaid = 0; |
954 | /* Stop ANI */ | 851 | /* Stop ANI */ |
955 | del_timer_sync(&sc->ani.timer); | 852 | del_timer_sync(&common->ani.timer); |
956 | } | 853 | } |
957 | } | 854 | } |
958 | 855 | ||
959 | /********************************/ | 856 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) |
960 | /* LED functions */ | ||
961 | /********************************/ | ||
962 | |||
963 | static void ath_led_blink_work(struct work_struct *work) | ||
964 | { | ||
965 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
966 | ath_led_blink_work.work); | ||
967 | |||
968 | if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) | ||
969 | return; | ||
970 | |||
971 | if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
972 | (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
973 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
974 | else | ||
975 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
976 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); | ||
977 | |||
978 | ieee80211_queue_delayed_work(sc->hw, | ||
979 | &sc->ath_led_blink_work, | ||
980 | (sc->sc_flags & SC_OP_LED_ON) ? | ||
981 | msecs_to_jiffies(sc->led_off_duration) : | ||
982 | msecs_to_jiffies(sc->led_on_duration)); | ||
983 | |||
984 | sc->led_on_duration = sc->led_on_cnt ? | ||
985 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : | ||
986 | ATH_LED_ON_DURATION_IDLE; | ||
987 | sc->led_off_duration = sc->led_off_cnt ? | ||
988 | max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) : | ||
989 | ATH_LED_OFF_DURATION_IDLE; | ||
990 | sc->led_on_cnt = sc->led_off_cnt = 0; | ||
991 | if (sc->sc_flags & SC_OP_LED_ON) | ||
992 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
993 | else | ||
994 | sc->sc_flags |= SC_OP_LED_ON; | ||
995 | } | ||
996 | |||
997 | static void ath_led_brightness(struct led_classdev *led_cdev, | ||
998 | enum led_brightness brightness) | ||
999 | { | ||
1000 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | ||
1001 | struct ath_softc *sc = led->sc; | ||
1002 | |||
1003 | switch (brightness) { | ||
1004 | case LED_OFF: | ||
1005 | if (led->led_type == ATH_LED_ASSOC || | ||
1006 | led->led_type == ATH_LED_RADIO) { | ||
1007 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
1008 | (led->led_type == ATH_LED_RADIO)); | ||
1009 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
1010 | if (led->led_type == ATH_LED_RADIO) | ||
1011 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
1012 | } else { | ||
1013 | sc->led_off_cnt++; | ||
1014 | } | ||
1015 | break; | ||
1016 | case LED_FULL: | ||
1017 | if (led->led_type == ATH_LED_ASSOC) { | ||
1018 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; | ||
1019 | ieee80211_queue_delayed_work(sc->hw, | ||
1020 | &sc->ath_led_blink_work, 0); | ||
1021 | } else if (led->led_type == ATH_LED_RADIO) { | ||
1022 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
1023 | sc->sc_flags |= SC_OP_LED_ON; | ||
1024 | } else { | ||
1025 | sc->led_on_cnt++; | ||
1026 | } | ||
1027 | break; | ||
1028 | default: | ||
1029 | break; | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | static int ath_register_led(struct ath_softc *sc, struct ath_led *led, | ||
1034 | char *trigger) | ||
1035 | { | ||
1036 | int ret; | ||
1037 | |||
1038 | led->sc = sc; | ||
1039 | led->led_cdev.name = led->name; | ||
1040 | led->led_cdev.default_trigger = trigger; | ||
1041 | led->led_cdev.brightness_set = ath_led_brightness; | ||
1042 | |||
1043 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); | ||
1044 | if (ret) | ||
1045 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1046 | "Failed to register led:%s", led->name); | ||
1047 | else | ||
1048 | led->registered = 1; | ||
1049 | return ret; | ||
1050 | } | ||
1051 | |||
1052 | static void ath_unregister_led(struct ath_led *led) | ||
1053 | { | ||
1054 | if (led->registered) { | ||
1055 | led_classdev_unregister(&led->led_cdev); | ||
1056 | led->registered = 0; | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | static void ath_deinit_leds(struct ath_softc *sc) | ||
1061 | { | ||
1062 | ath_unregister_led(&sc->assoc_led); | ||
1063 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
1064 | ath_unregister_led(&sc->tx_led); | ||
1065 | ath_unregister_led(&sc->rx_led); | ||
1066 | ath_unregister_led(&sc->radio_led); | ||
1067 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
1068 | } | ||
1069 | |||
1070 | static void ath_init_leds(struct ath_softc *sc) | ||
1071 | { | ||
1072 | char *trigger; | ||
1073 | int ret; | ||
1074 | |||
1075 | if (AR_SREV_9287(sc->sc_ah)) | ||
1076 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; | ||
1077 | else | ||
1078 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | ||
1079 | |||
1080 | /* Configure gpio 1 for output */ | ||
1081 | ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, | ||
1082 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
1083 | /* LED off, active low */ | ||
1084 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
1085 | |||
1086 | INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); | ||
1087 | |||
1088 | trigger = ieee80211_get_radio_led_name(sc->hw); | ||
1089 | snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), | ||
1090 | "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); | ||
1091 | ret = ath_register_led(sc, &sc->radio_led, trigger); | ||
1092 | sc->radio_led.led_type = ATH_LED_RADIO; | ||
1093 | if (ret) | ||
1094 | goto fail; | ||
1095 | |||
1096 | trigger = ieee80211_get_assoc_led_name(sc->hw); | ||
1097 | snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), | ||
1098 | "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); | ||
1099 | ret = ath_register_led(sc, &sc->assoc_led, trigger); | ||
1100 | sc->assoc_led.led_type = ATH_LED_ASSOC; | ||
1101 | if (ret) | ||
1102 | goto fail; | ||
1103 | |||
1104 | trigger = ieee80211_get_tx_led_name(sc->hw); | ||
1105 | snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), | ||
1106 | "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); | ||
1107 | ret = ath_register_led(sc, &sc->tx_led, trigger); | ||
1108 | sc->tx_led.led_type = ATH_LED_TX; | ||
1109 | if (ret) | ||
1110 | goto fail; | ||
1111 | |||
1112 | trigger = ieee80211_get_rx_led_name(sc->hw); | ||
1113 | snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), | ||
1114 | "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); | ||
1115 | ret = ath_register_led(sc, &sc->rx_led, trigger); | ||
1116 | sc->rx_led.led_type = ATH_LED_RX; | ||
1117 | if (ret) | ||
1118 | goto fail; | ||
1119 | |||
1120 | return; | ||
1121 | |||
1122 | fail: | ||
1123 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | ||
1124 | ath_deinit_leds(sc); | ||
1125 | } | ||
1126 | |||
1127 | void ath_radio_enable(struct ath_softc *sc) | ||
1128 | { | 857 | { |
1129 | struct ath_hw *ah = sc->sc_ah; | 858 | struct ath_hw *ah = sc->sc_ah; |
1130 | struct ieee80211_channel *channel = sc->hw->conf.channel; | 859 | struct ath_common *common = ath9k_hw_common(ah); |
860 | struct ieee80211_channel *channel = hw->conf.channel; | ||
1131 | int r; | 861 | int r; |
1132 | 862 | ||
1133 | ath9k_ps_wakeup(sc); | 863 | ath9k_ps_wakeup(sc); |
@@ -1139,17 +869,17 @@ void ath_radio_enable(struct ath_softc *sc) | |||
1139 | spin_lock_bh(&sc->sc_resetlock); | 869 | spin_lock_bh(&sc->sc_resetlock); |
1140 | r = ath9k_hw_reset(ah, ah->curchan, false); | 870 | r = ath9k_hw_reset(ah, ah->curchan, false); |
1141 | if (r) { | 871 | if (r) { |
1142 | DPRINTF(sc, ATH_DBG_FATAL, | 872 | ath_print(common, ATH_DBG_FATAL, |
1143 | "Unable to reset channel %u (%uMhz) ", | 873 | "Unable to reset channel (%u MHz), " |
1144 | "reset status %d\n", | 874 | "reset status %d\n", |
1145 | channel->center_freq, r); | 875 | channel->center_freq, r); |
1146 | } | 876 | } |
1147 | spin_unlock_bh(&sc->sc_resetlock); | 877 | spin_unlock_bh(&sc->sc_resetlock); |
1148 | 878 | ||
1149 | ath_update_txpow(sc); | 879 | ath_update_txpow(sc); |
1150 | if (ath_startrecv(sc) != 0) { | 880 | if (ath_startrecv(sc) != 0) { |
1151 | DPRINTF(sc, ATH_DBG_FATAL, | 881 | ath_print(common, ATH_DBG_FATAL, |
1152 | "Unable to restart recv logic\n"); | 882 | "Unable to restart recv logic\n"); |
1153 | return; | 883 | return; |
1154 | } | 884 | } |
1155 | 885 | ||
@@ -1164,18 +894,18 @@ void ath_radio_enable(struct ath_softc *sc) | |||
1164 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | 894 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); |
1165 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); | 895 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); |
1166 | 896 | ||
1167 | ieee80211_wake_queues(sc->hw); | 897 | ieee80211_wake_queues(hw); |
1168 | ath9k_ps_restore(sc); | 898 | ath9k_ps_restore(sc); |
1169 | } | 899 | } |
1170 | 900 | ||
1171 | void ath_radio_disable(struct ath_softc *sc) | 901 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) |
1172 | { | 902 | { |
1173 | struct ath_hw *ah = sc->sc_ah; | 903 | struct ath_hw *ah = sc->sc_ah; |
1174 | struct ieee80211_channel *channel = sc->hw->conf.channel; | 904 | struct ieee80211_channel *channel = hw->conf.channel; |
1175 | int r; | 905 | int r; |
1176 | 906 | ||
1177 | ath9k_ps_wakeup(sc); | 907 | ath9k_ps_wakeup(sc); |
1178 | ieee80211_stop_queues(sc->hw); | 908 | ieee80211_stop_queues(hw); |
1179 | 909 | ||
1180 | /* Disable LED */ | 910 | /* Disable LED */ |
1181 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); | 911 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); |
@@ -1189,471 +919,36 @@ void ath_radio_disable(struct ath_softc *sc) | |||
1189 | ath_flushrecv(sc); /* flush recv queue */ | 919 | ath_flushrecv(sc); /* flush recv queue */ |
1190 | 920 | ||
1191 | if (!ah->curchan) | 921 | if (!ah->curchan) |
1192 | ah->curchan = ath_get_curchannel(sc, sc->hw); | 922 | ah->curchan = ath_get_curchannel(sc, hw); |
1193 | 923 | ||
1194 | spin_lock_bh(&sc->sc_resetlock); | 924 | spin_lock_bh(&sc->sc_resetlock); |
1195 | r = ath9k_hw_reset(ah, ah->curchan, false); | 925 | r = ath9k_hw_reset(ah, ah->curchan, false); |
1196 | if (r) { | 926 | if (r) { |
1197 | DPRINTF(sc, ATH_DBG_FATAL, | 927 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1198 | "Unable to reset channel %u (%uMhz) " | 928 | "Unable to reset channel (%u MHz), " |
1199 | "reset status %d\n", | 929 | "reset status %d\n", |
1200 | channel->center_freq, r); | 930 | channel->center_freq, r); |
1201 | } | 931 | } |
1202 | spin_unlock_bh(&sc->sc_resetlock); | 932 | spin_unlock_bh(&sc->sc_resetlock); |
1203 | 933 | ||
1204 | ath9k_hw_phy_disable(ah); | 934 | ath9k_hw_phy_disable(ah); |
1205 | ath9k_hw_configpcipowersave(ah, 1, 1); | 935 | ath9k_hw_configpcipowersave(ah, 1, 1); |
1206 | ath9k_ps_restore(sc); | 936 | ath9k_ps_restore(sc); |
1207 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 937 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
1208 | } | ||
1209 | |||
1210 | /*******************/ | ||
1211 | /* Rfkill */ | ||
1212 | /*******************/ | ||
1213 | |||
1214 | static bool ath_is_rfkill_set(struct ath_softc *sc) | ||
1215 | { | ||
1216 | struct ath_hw *ah = sc->sc_ah; | ||
1217 | |||
1218 | return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) == | ||
1219 | ah->rfkill_polarity; | ||
1220 | } | ||
1221 | |||
1222 | static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) | ||
1223 | { | ||
1224 | struct ath_wiphy *aphy = hw->priv; | ||
1225 | struct ath_softc *sc = aphy->sc; | ||
1226 | bool blocked = !!ath_is_rfkill_set(sc); | ||
1227 | |||
1228 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); | ||
1229 | } | ||
1230 | |||
1231 | static void ath_start_rfkill_poll(struct ath_softc *sc) | ||
1232 | { | ||
1233 | struct ath_hw *ah = sc->sc_ah; | ||
1234 | |||
1235 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1236 | wiphy_rfkill_start_polling(sc->hw->wiphy); | ||
1237 | } | ||
1238 | |||
1239 | void ath_cleanup(struct ath_softc *sc) | ||
1240 | { | ||
1241 | ath_detach(sc); | ||
1242 | free_irq(sc->irq, sc); | ||
1243 | ath_bus_cleanup(sc); | ||
1244 | kfree(sc->sec_wiphy); | ||
1245 | ieee80211_free_hw(sc->hw); | ||
1246 | } | ||
1247 | |||
1248 | void ath_detach(struct ath_softc *sc) | ||
1249 | { | ||
1250 | struct ieee80211_hw *hw = sc->hw; | ||
1251 | int i = 0; | ||
1252 | |||
1253 | ath9k_ps_wakeup(sc); | ||
1254 | |||
1255 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); | ||
1256 | |||
1257 | ath_deinit_leds(sc); | ||
1258 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | ||
1259 | |||
1260 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
1261 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
1262 | if (aphy == NULL) | ||
1263 | continue; | ||
1264 | sc->sec_wiphy[i] = NULL; | ||
1265 | ieee80211_unregister_hw(aphy->hw); | ||
1266 | ieee80211_free_hw(aphy->hw); | ||
1267 | } | ||
1268 | ieee80211_unregister_hw(hw); | ||
1269 | ath_rx_cleanup(sc); | ||
1270 | ath_tx_cleanup(sc); | ||
1271 | |||
1272 | tasklet_kill(&sc->intr_tq); | ||
1273 | tasklet_kill(&sc->bcon_tasklet); | ||
1274 | |||
1275 | if (!(sc->sc_flags & SC_OP_INVALID)) | ||
1276 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
1277 | |||
1278 | /* cleanup tx queues */ | ||
1279 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1280 | if (ATH_TXQ_SETUP(sc, i)) | ||
1281 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1282 | |||
1283 | if ((sc->btcoex_info.no_stomp_timer) && | ||
1284 | sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) | ||
1285 | ath_gen_timer_free(sc->sc_ah, sc->btcoex_info.no_stomp_timer); | ||
1286 | |||
1287 | ath9k_hw_detach(sc->sc_ah); | ||
1288 | sc->sc_ah = NULL; | ||
1289 | ath9k_exit_debug(sc); | ||
1290 | } | ||
1291 | |||
1292 | static int ath9k_reg_notifier(struct wiphy *wiphy, | ||
1293 | struct regulatory_request *request) | ||
1294 | { | ||
1295 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
1296 | struct ath_wiphy *aphy = hw->priv; | ||
1297 | struct ath_softc *sc = aphy->sc; | ||
1298 | struct ath_regulatory *reg = &sc->common.regulatory; | ||
1299 | |||
1300 | return ath_reg_notifier_apply(wiphy, request, reg); | ||
1301 | } | ||
1302 | |||
1303 | /* | ||
1304 | * Initialize and fill ath_softc, ath_sofct is the | ||
1305 | * "Software Carrier" struct. Historically it has existed | ||
1306 | * to allow the separation between hardware specific | ||
1307 | * variables (now in ath_hw) and driver specific variables. | ||
1308 | */ | ||
1309 | static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | ||
1310 | { | ||
1311 | struct ath_hw *ah = NULL; | ||
1312 | int r = 0, i; | ||
1313 | int csz = 0; | ||
1314 | |||
1315 | /* XXX: hardware will not be ready until ath_open() being called */ | ||
1316 | sc->sc_flags |= SC_OP_INVALID; | ||
1317 | |||
1318 | if (ath9k_init_debug(sc) < 0) | ||
1319 | printk(KERN_ERR "Unable to create debugfs files\n"); | ||
1320 | |||
1321 | spin_lock_init(&sc->wiphy_lock); | ||
1322 | spin_lock_init(&sc->sc_resetlock); | ||
1323 | spin_lock_init(&sc->sc_serial_rw); | ||
1324 | spin_lock_init(&sc->ani_lock); | ||
1325 | spin_lock_init(&sc->sc_pm_lock); | ||
1326 | mutex_init(&sc->mutex); | ||
1327 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | ||
1328 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | ||
1329 | (unsigned long)sc); | ||
1330 | |||
1331 | /* | ||
1332 | * Cache line size is used to size and align various | ||
1333 | * structures used to communicate with the hardware. | ||
1334 | */ | ||
1335 | ath_read_cachesize(sc, &csz); | ||
1336 | /* XXX assert csz is non-zero */ | ||
1337 | sc->common.cachelsz = csz << 2; /* convert to bytes */ | ||
1338 | |||
1339 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | ||
1340 | if (!ah) { | ||
1341 | r = -ENOMEM; | ||
1342 | goto bad_no_ah; | ||
1343 | } | ||
1344 | |||
1345 | ah->ah_sc = sc; | ||
1346 | ah->hw_version.devid = devid; | ||
1347 | ah->hw_version.subsysid = subsysid; | ||
1348 | sc->sc_ah = ah; | ||
1349 | |||
1350 | r = ath9k_hw_init(ah); | ||
1351 | if (r) { | ||
1352 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1353 | "Unable to initialize hardware; " | ||
1354 | "initialization status: %d\n", r); | ||
1355 | goto bad; | ||
1356 | } | ||
1357 | |||
1358 | /* Get the hardware key cache size. */ | ||
1359 | sc->keymax = ah->caps.keycache_size; | ||
1360 | if (sc->keymax > ATH_KEYMAX) { | ||
1361 | DPRINTF(sc, ATH_DBG_ANY, | ||
1362 | "Warning, using only %u entries in %u key cache\n", | ||
1363 | ATH_KEYMAX, sc->keymax); | ||
1364 | sc->keymax = ATH_KEYMAX; | ||
1365 | } | ||
1366 | |||
1367 | /* | ||
1368 | * Reset the key cache since some parts do not | ||
1369 | * reset the contents on initial power up. | ||
1370 | */ | ||
1371 | for (i = 0; i < sc->keymax; i++) | ||
1372 | ath9k_hw_keyreset(ah, (u16) i); | ||
1373 | |||
1374 | /* default to MONITOR mode */ | ||
1375 | sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; | ||
1376 | |||
1377 | /* Setup rate tables */ | ||
1378 | |||
1379 | ath_rate_attach(sc); | ||
1380 | ath_setup_rates(sc, IEEE80211_BAND_2GHZ); | ||
1381 | ath_setup_rates(sc, IEEE80211_BAND_5GHZ); | ||
1382 | |||
1383 | /* | ||
1384 | * Allocate hardware transmit queues: one queue for | ||
1385 | * beacon frames and one data queue for each QoS | ||
1386 | * priority. Note that the hal handles reseting | ||
1387 | * these queues at the needed time. | ||
1388 | */ | ||
1389 | sc->beacon.beaconq = ath_beaconq_setup(ah); | ||
1390 | if (sc->beacon.beaconq == -1) { | ||
1391 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1392 | "Unable to setup a beacon xmit queue\n"); | ||
1393 | r = -EIO; | ||
1394 | goto bad2; | ||
1395 | } | ||
1396 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | ||
1397 | if (sc->beacon.cabq == NULL) { | ||
1398 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1399 | "Unable to setup CAB xmit queue\n"); | ||
1400 | r = -EIO; | ||
1401 | goto bad2; | ||
1402 | } | ||
1403 | |||
1404 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | ||
1405 | ath_cabq_update(sc); | ||
1406 | |||
1407 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
1408 | sc->tx.hwq_map[i] = -1; | ||
1409 | |||
1410 | /* Setup data queues */ | ||
1411 | /* NB: ensure BK queue is the lowest priority h/w queue */ | ||
1412 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | ||
1413 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1414 | "Unable to setup xmit queue for BK traffic\n"); | ||
1415 | r = -EIO; | ||
1416 | goto bad2; | ||
1417 | } | ||
1418 | |||
1419 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | ||
1420 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1421 | "Unable to setup xmit queue for BE traffic\n"); | ||
1422 | r = -EIO; | ||
1423 | goto bad2; | ||
1424 | } | ||
1425 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | ||
1426 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1427 | "Unable to setup xmit queue for VI traffic\n"); | ||
1428 | r = -EIO; | ||
1429 | goto bad2; | ||
1430 | } | ||
1431 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | ||
1432 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1433 | "Unable to setup xmit queue for VO traffic\n"); | ||
1434 | r = -EIO; | ||
1435 | goto bad2; | ||
1436 | } | ||
1437 | |||
1438 | /* Initializes the noise floor to a reasonable default value. | ||
1439 | * Later on this will be updated during ANI processing. */ | ||
1440 | |||
1441 | sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
1442 | setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc); | ||
1443 | |||
1444 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1445 | ATH9K_CIPHER_TKIP, NULL)) { | ||
1446 | /* | ||
1447 | * Whether we should enable h/w TKIP MIC. | ||
1448 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | ||
1449 | * report WMM capable, so it's always safe to turn on | ||
1450 | * TKIP MIC in this case. | ||
1451 | */ | ||
1452 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, | ||
1453 | 0, 1, NULL); | ||
1454 | } | ||
1455 | |||
1456 | /* | ||
1457 | * Check whether the separate key cache entries | ||
1458 | * are required to handle both tx+rx MIC keys. | ||
1459 | * With split mic keys the number of stations is limited | ||
1460 | * to 27 otherwise 59. | ||
1461 | */ | ||
1462 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1463 | ATH9K_CIPHER_TKIP, NULL) | ||
1464 | && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1465 | ATH9K_CIPHER_MIC, NULL) | ||
1466 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, | ||
1467 | 0, NULL)) | ||
1468 | sc->splitmic = 1; | ||
1469 | |||
1470 | /* turn on mcast key search if possible */ | ||
1471 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | ||
1472 | (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1, | ||
1473 | 1, NULL); | ||
1474 | |||
1475 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | ||
1476 | |||
1477 | /* 11n Capabilities */ | ||
1478 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
1479 | sc->sc_flags |= SC_OP_TXAGGR; | ||
1480 | sc->sc_flags |= SC_OP_RXAGGR; | ||
1481 | } | ||
1482 | |||
1483 | sc->tx_chainmask = ah->caps.tx_chainmask; | ||
1484 | sc->rx_chainmask = ah->caps.rx_chainmask; | ||
1485 | |||
1486 | ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | ||
1487 | sc->rx.defant = ath9k_hw_getdefantenna(ah); | ||
1488 | |||
1489 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
1490 | memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
1491 | |||
1492 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ | ||
1493 | |||
1494 | /* initialize beacon slots */ | ||
1495 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | ||
1496 | sc->beacon.bslot[i] = NULL; | ||
1497 | sc->beacon.bslot_aphy[i] = NULL; | ||
1498 | } | ||
1499 | |||
1500 | /* setup channels and rates */ | ||
1501 | |||
1502 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; | ||
1503 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = | ||
1504 | sc->rates[IEEE80211_BAND_2GHZ]; | ||
1505 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
1506 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
1507 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
1508 | |||
1509 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { | ||
1510 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; | ||
1511 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
1512 | sc->rates[IEEE80211_BAND_5GHZ]; | ||
1513 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
1514 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
1515 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
1516 | } | ||
1517 | |||
1518 | if (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) { | ||
1519 | r = ath9k_hw_btcoex_init(ah); | ||
1520 | if (r) | ||
1521 | goto bad2; | ||
1522 | } | ||
1523 | |||
1524 | return 0; | ||
1525 | bad2: | ||
1526 | /* cleanup tx queues */ | ||
1527 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1528 | if (ATH_TXQ_SETUP(sc, i)) | ||
1529 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1530 | bad: | ||
1531 | ath9k_hw_detach(ah); | ||
1532 | sc->sc_ah = NULL; | ||
1533 | bad_no_ah: | ||
1534 | ath9k_exit_debug(sc); | ||
1535 | |||
1536 | return r; | ||
1537 | } | ||
1538 | |||
1539 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
1540 | { | ||
1541 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
1542 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
1543 | IEEE80211_HW_SIGNAL_DBM | | ||
1544 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
1545 | IEEE80211_HW_SUPPORTS_PS | | ||
1546 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
1547 | IEEE80211_HW_SPECTRUM_MGMT; | ||
1548 | |||
1549 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) | ||
1550 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
1551 | |||
1552 | hw->wiphy->interface_modes = | ||
1553 | BIT(NL80211_IFTYPE_AP) | | ||
1554 | BIT(NL80211_IFTYPE_STATION) | | ||
1555 | BIT(NL80211_IFTYPE_ADHOC) | | ||
1556 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
1557 | |||
1558 | hw->wiphy->ps_default = false; | ||
1559 | |||
1560 | hw->queues = 4; | ||
1561 | hw->max_rates = 4; | ||
1562 | hw->channel_change_time = 5000; | ||
1563 | hw->max_listen_interval = 10; | ||
1564 | /* Hardware supports 10 but we use 4 */ | ||
1565 | hw->max_rate_tries = 4; | ||
1566 | hw->sta_data_size = sizeof(struct ath_node); | ||
1567 | hw->vif_data_size = sizeof(struct ath_vif); | ||
1568 | |||
1569 | hw->rate_control_algorithm = "ath9k_rate_control"; | ||
1570 | |||
1571 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
1572 | &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
1573 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
1574 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
1575 | &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
1576 | } | ||
1577 | |||
1578 | /* Device driver core initialization */ | ||
1579 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid) | ||
1580 | { | ||
1581 | struct ieee80211_hw *hw = sc->hw; | ||
1582 | int error = 0, i; | ||
1583 | struct ath_regulatory *reg; | ||
1584 | |||
1585 | DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); | ||
1586 | |||
1587 | error = ath_init_softc(devid, sc, subsysid); | ||
1588 | if (error != 0) | ||
1589 | return error; | ||
1590 | |||
1591 | /* get mac address from hardware and set in mac80211 */ | ||
1592 | |||
1593 | SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr); | ||
1594 | |||
1595 | ath_set_hw_capab(sc, hw); | ||
1596 | |||
1597 | error = ath_regd_init(&sc->common.regulatory, sc->hw->wiphy, | ||
1598 | ath9k_reg_notifier); | ||
1599 | if (error) | ||
1600 | return error; | ||
1601 | |||
1602 | reg = &sc->common.regulatory; | ||
1603 | |||
1604 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
1605 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
1606 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
1607 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
1608 | } | ||
1609 | |||
1610 | /* initialize tx/rx engine */ | ||
1611 | error = ath_tx_init(sc, ATH_TXBUF); | ||
1612 | if (error != 0) | ||
1613 | goto error_attach; | ||
1614 | |||
1615 | error = ath_rx_init(sc, ATH_RXBUF); | ||
1616 | if (error != 0) | ||
1617 | goto error_attach; | ||
1618 | |||
1619 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | ||
1620 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | ||
1621 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
1622 | |||
1623 | error = ieee80211_register_hw(hw); | ||
1624 | |||
1625 | if (!ath_is_world_regd(reg)) { | ||
1626 | error = regulatory_hint(hw->wiphy, reg->alpha2); | ||
1627 | if (error) | ||
1628 | goto error_attach; | ||
1629 | } | ||
1630 | |||
1631 | /* Initialize LED control */ | ||
1632 | ath_init_leds(sc); | ||
1633 | |||
1634 | ath_start_rfkill_poll(sc); | ||
1635 | |||
1636 | return 0; | ||
1637 | |||
1638 | error_attach: | ||
1639 | /* cleanup tx queues */ | ||
1640 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1641 | if (ATH_TXQ_SETUP(sc, i)) | ||
1642 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1643 | |||
1644 | ath9k_hw_detach(sc->sc_ah); | ||
1645 | sc->sc_ah = NULL; | ||
1646 | ath9k_exit_debug(sc); | ||
1647 | |||
1648 | return error; | ||
1649 | } | 938 | } |
1650 | 939 | ||
1651 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 940 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
1652 | { | 941 | { |
1653 | struct ath_hw *ah = sc->sc_ah; | 942 | struct ath_hw *ah = sc->sc_ah; |
943 | struct ath_common *common = ath9k_hw_common(ah); | ||
1654 | struct ieee80211_hw *hw = sc->hw; | 944 | struct ieee80211_hw *hw = sc->hw; |
1655 | int r; | 945 | int r; |
1656 | 946 | ||
947 | /* Stop ANI */ | ||
948 | del_timer_sync(&common->ani.timer); | ||
949 | |||
950 | ieee80211_stop_queues(hw); | ||
951 | |||
1657 | ath9k_hw_set_interrupts(ah, 0); | 952 | ath9k_hw_set_interrupts(ah, 0); |
1658 | ath_drain_all_txq(sc, retry_tx); | 953 | ath_drain_all_txq(sc, retry_tx); |
1659 | ath_stoprecv(sc); | 954 | ath_stoprecv(sc); |
@@ -1662,12 +957,13 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1662 | spin_lock_bh(&sc->sc_resetlock); | 957 | spin_lock_bh(&sc->sc_resetlock); |
1663 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); | 958 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); |
1664 | if (r) | 959 | if (r) |
1665 | DPRINTF(sc, ATH_DBG_FATAL, | 960 | ath_print(common, ATH_DBG_FATAL, |
1666 | "Unable to reset hardware; reset status %d\n", r); | 961 | "Unable to reset hardware; reset status %d\n", r); |
1667 | spin_unlock_bh(&sc->sc_resetlock); | 962 | spin_unlock_bh(&sc->sc_resetlock); |
1668 | 963 | ||
1669 | if (ath_startrecv(sc) != 0) | 964 | if (ath_startrecv(sc) != 0) |
1670 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); | 965 | ath_print(common, ATH_DBG_FATAL, |
966 | "Unable to start recv logic\n"); | ||
1671 | 967 | ||
1672 | /* | 968 | /* |
1673 | * We may be doing a reset in response to a request | 969 | * We may be doing a reset in response to a request |
@@ -1694,125 +990,12 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1694 | } | 990 | } |
1695 | } | 991 | } |
1696 | 992 | ||
1697 | return r; | 993 | ieee80211_wake_queues(hw); |
1698 | } | ||
1699 | |||
1700 | /* | ||
1701 | * This function will allocate both the DMA descriptor structure, and the | ||
1702 | * buffers it contains. These are used to contain the descriptors used | ||
1703 | * by the system. | ||
1704 | */ | ||
1705 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | ||
1706 | struct list_head *head, const char *name, | ||
1707 | int nbuf, int ndesc) | ||
1708 | { | ||
1709 | #define DS2PHYS(_dd, _ds) \ | ||
1710 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) | ||
1711 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) | ||
1712 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) | ||
1713 | |||
1714 | struct ath_desc *ds; | ||
1715 | struct ath_buf *bf; | ||
1716 | int i, bsize, error; | ||
1717 | |||
1718 | DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | ||
1719 | name, nbuf, ndesc); | ||
1720 | |||
1721 | INIT_LIST_HEAD(head); | ||
1722 | /* ath_desc must be a multiple of DWORDs */ | ||
1723 | if ((sizeof(struct ath_desc) % 4) != 0) { | ||
1724 | DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n"); | ||
1725 | ASSERT((sizeof(struct ath_desc) % 4) == 0); | ||
1726 | error = -ENOMEM; | ||
1727 | goto fail; | ||
1728 | } | ||
1729 | |||
1730 | dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; | ||
1731 | |||
1732 | /* | ||
1733 | * Need additional DMA memory because we can't use | ||
1734 | * descriptors that cross the 4K page boundary. Assume | ||
1735 | * one skipped descriptor per 4K page. | ||
1736 | */ | ||
1737 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
1738 | u32 ndesc_skipped = | ||
1739 | ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); | ||
1740 | u32 dma_len; | ||
1741 | |||
1742 | while (ndesc_skipped) { | ||
1743 | dma_len = ndesc_skipped * sizeof(struct ath_desc); | ||
1744 | dd->dd_desc_len += dma_len; | ||
1745 | |||
1746 | ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); | ||
1747 | }; | ||
1748 | } | ||
1749 | |||
1750 | /* allocate descriptors */ | ||
1751 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | ||
1752 | &dd->dd_desc_paddr, GFP_KERNEL); | ||
1753 | if (dd->dd_desc == NULL) { | ||
1754 | error = -ENOMEM; | ||
1755 | goto fail; | ||
1756 | } | ||
1757 | ds = dd->dd_desc; | ||
1758 | DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | ||
1759 | name, ds, (u32) dd->dd_desc_len, | ||
1760 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | ||
1761 | |||
1762 | /* allocate buffers */ | ||
1763 | bsize = sizeof(struct ath_buf) * nbuf; | ||
1764 | bf = kzalloc(bsize, GFP_KERNEL); | ||
1765 | if (bf == NULL) { | ||
1766 | error = -ENOMEM; | ||
1767 | goto fail2; | ||
1768 | } | ||
1769 | dd->dd_bufptr = bf; | ||
1770 | |||
1771 | for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { | ||
1772 | bf->bf_desc = ds; | ||
1773 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
1774 | |||
1775 | if (!(sc->sc_ah->caps.hw_caps & | ||
1776 | ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
1777 | /* | ||
1778 | * Skip descriptor addresses which can cause 4KB | ||
1779 | * boundary crossing (addr + length) with a 32 dword | ||
1780 | * descriptor fetch. | ||
1781 | */ | ||
1782 | while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { | ||
1783 | ASSERT((caddr_t) bf->bf_desc < | ||
1784 | ((caddr_t) dd->dd_desc + | ||
1785 | dd->dd_desc_len)); | ||
1786 | |||
1787 | ds += ndesc; | ||
1788 | bf->bf_desc = ds; | ||
1789 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
1790 | } | ||
1791 | } | ||
1792 | list_add_tail(&bf->list, head); | ||
1793 | } | ||
1794 | return 0; | ||
1795 | fail2: | ||
1796 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
1797 | dd->dd_desc_paddr); | ||
1798 | fail: | ||
1799 | memset(dd, 0, sizeof(*dd)); | ||
1800 | return error; | ||
1801 | #undef ATH_DESC_4KB_BOUND_CHECK | ||
1802 | #undef ATH_DESC_4KB_BOUND_NUM_SKIPPED | ||
1803 | #undef DS2PHYS | ||
1804 | } | ||
1805 | 994 | ||
1806 | void ath_descdma_cleanup(struct ath_softc *sc, | 995 | /* Start ANI */ |
1807 | struct ath_descdma *dd, | 996 | ath_start_ani(common); |
1808 | struct list_head *head) | ||
1809 | { | ||
1810 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
1811 | dd->dd_desc_paddr); | ||
1812 | 997 | ||
1813 | INIT_LIST_HEAD(head); | 998 | return r; |
1814 | kfree(dd->dd_bufptr); | ||
1815 | memset(dd, 0, sizeof(*dd)); | ||
1816 | } | 999 | } |
1817 | 1000 | ||
1818 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) | 1001 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) |
@@ -1884,15 +1067,9 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
1884 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | 1067 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; |
1885 | } | 1068 | } |
1886 | 1069 | ||
1887 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | 1070 | if (conf_is_ht(conf)) |
1888 | |||
1889 | if (conf_is_ht(conf)) { | ||
1890 | if (conf_is_ht40(conf)) | ||
1891 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
1892 | |||
1893 | ichan->chanmode = ath_get_extchanmode(sc, chan, | 1071 | ichan->chanmode = ath_get_extchanmode(sc, chan, |
1894 | conf->channel_type); | 1072 | conf->channel_type); |
1895 | } | ||
1896 | } | 1073 | } |
1897 | 1074 | ||
1898 | /**********************/ | 1075 | /**********************/ |
@@ -1903,12 +1080,15 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1903 | { | 1080 | { |
1904 | struct ath_wiphy *aphy = hw->priv; | 1081 | struct ath_wiphy *aphy = hw->priv; |
1905 | struct ath_softc *sc = aphy->sc; | 1082 | struct ath_softc *sc = aphy->sc; |
1083 | struct ath_hw *ah = sc->sc_ah; | ||
1084 | struct ath_common *common = ath9k_hw_common(ah); | ||
1906 | struct ieee80211_channel *curchan = hw->conf.channel; | 1085 | struct ieee80211_channel *curchan = hw->conf.channel; |
1907 | struct ath9k_channel *init_channel; | 1086 | struct ath9k_channel *init_channel; |
1908 | int r; | 1087 | int r; |
1909 | 1088 | ||
1910 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " | 1089 | ath_print(common, ATH_DBG_CONFIG, |
1911 | "initial channel: %d MHz\n", curchan->center_freq); | 1090 | "Starting driver with initial channel: %d MHz\n", |
1091 | curchan->center_freq); | ||
1912 | 1092 | ||
1913 | mutex_lock(&sc->mutex); | 1093 | mutex_lock(&sc->mutex); |
1914 | 1094 | ||
@@ -1940,7 +1120,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1940 | init_channel = ath_get_curchannel(sc, hw); | 1120 | init_channel = ath_get_curchannel(sc, hw); |
1941 | 1121 | ||
1942 | /* Reset SERDES registers */ | 1122 | /* Reset SERDES registers */ |
1943 | ath9k_hw_configpcipowersave(sc->sc_ah, 0, 0); | 1123 | ath9k_hw_configpcipowersave(ah, 0, 0); |
1944 | 1124 | ||
1945 | /* | 1125 | /* |
1946 | * The basic interface to setting the hardware in a good | 1126 | * The basic interface to setting the hardware in a good |
@@ -1950,12 +1130,12 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1950 | * and then setup of the interrupt mask. | 1130 | * and then setup of the interrupt mask. |
1951 | */ | 1131 | */ |
1952 | spin_lock_bh(&sc->sc_resetlock); | 1132 | spin_lock_bh(&sc->sc_resetlock); |
1953 | r = ath9k_hw_reset(sc->sc_ah, init_channel, false); | 1133 | r = ath9k_hw_reset(ah, init_channel, false); |
1954 | if (r) { | 1134 | if (r) { |
1955 | DPRINTF(sc, ATH_DBG_FATAL, | 1135 | ath_print(common, ATH_DBG_FATAL, |
1956 | "Unable to reset hardware; reset status %d " | 1136 | "Unable to reset hardware; reset status %d " |
1957 | "(freq %u MHz)\n", r, | 1137 | "(freq %u MHz)\n", r, |
1958 | curchan->center_freq); | 1138 | curchan->center_freq); |
1959 | spin_unlock_bh(&sc->sc_resetlock); | 1139 | spin_unlock_bh(&sc->sc_resetlock); |
1960 | goto mutex_unlock; | 1140 | goto mutex_unlock; |
1961 | } | 1141 | } |
@@ -1975,7 +1155,8 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1975 | * here except setup the interrupt mask. | 1155 | * here except setup the interrupt mask. |
1976 | */ | 1156 | */ |
1977 | if (ath_startrecv(sc) != 0) { | 1157 | if (ath_startrecv(sc) != 0) { |
1978 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); | 1158 | ath_print(common, ATH_DBG_FATAL, |
1159 | "Unable to start recv logic\n"); | ||
1979 | r = -EIO; | 1160 | r = -EIO; |
1980 | goto mutex_unlock; | 1161 | goto mutex_unlock; |
1981 | } | 1162 | } |
@@ -1985,10 +1166,10 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1985 | | ATH9K_INT_RXEOL | ATH9K_INT_RXORN | 1166 | | ATH9K_INT_RXEOL | ATH9K_INT_RXORN |
1986 | | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; | 1167 | | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; |
1987 | 1168 | ||
1988 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT) | 1169 | if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) |
1989 | sc->imask |= ATH9K_INT_GTT; | 1170 | sc->imask |= ATH9K_INT_GTT; |
1990 | 1171 | ||
1991 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 1172 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
1992 | sc->imask |= ATH9K_INT_CST; | 1173 | sc->imask |= ATH9K_INT_CST; |
1993 | 1174 | ||
1994 | ath_cache_conf_rate(sc, &hw->conf); | 1175 | ath_cache_conf_rate(sc, &hw->conf); |
@@ -1997,21 +1178,22 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1997 | 1178 | ||
1998 | /* Disable BMISS interrupt when we're not associated */ | 1179 | /* Disable BMISS interrupt when we're not associated */ |
1999 | sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); | 1180 | sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); |
2000 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 1181 | ath9k_hw_set_interrupts(ah, sc->imask); |
2001 | 1182 | ||
2002 | ieee80211_wake_queues(hw); | 1183 | ieee80211_wake_queues(hw); |
2003 | 1184 | ||
2004 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 1185 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
2005 | 1186 | ||
2006 | if ((sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) && | 1187 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && |
2007 | !(sc->sc_flags & SC_OP_BTCOEX_ENABLED)) { | 1188 | !ah->btcoex_hw.enabled) { |
2008 | ath_btcoex_set_weight(&sc->btcoex_info, AR_BT_COEX_WGHT, | 1189 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
2009 | AR_STOMP_LOW_WLAN_WGHT); | 1190 | AR_STOMP_LOW_WLAN_WGHT); |
2010 | ath9k_hw_btcoex_enable(sc->sc_ah); | 1191 | ath9k_hw_btcoex_enable(ah); |
2011 | 1192 | ||
2012 | ath_pcie_aspm_disable(sc); | 1193 | if (common->bus_ops->bt_coex_prep) |
2013 | if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) | 1194 | common->bus_ops->bt_coex_prep(common); |
2014 | ath_btcoex_timer_resume(sc, &sc->btcoex_info); | 1195 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
1196 | ath9k_btcoex_timer_resume(sc); | ||
2015 | } | 1197 | } |
2016 | 1198 | ||
2017 | mutex_unlock: | 1199 | mutex_unlock: |
@@ -2026,17 +1208,19 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2026 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1208 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2027 | struct ath_wiphy *aphy = hw->priv; | 1209 | struct ath_wiphy *aphy = hw->priv; |
2028 | struct ath_softc *sc = aphy->sc; | 1210 | struct ath_softc *sc = aphy->sc; |
1211 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2029 | struct ath_tx_control txctl; | 1212 | struct ath_tx_control txctl; |
2030 | int hdrlen, padsize; | 1213 | int padpos, padsize; |
1214 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
2031 | 1215 | ||
2032 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { | 1216 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { |
2033 | printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state " | 1217 | ath_print(common, ATH_DBG_XMIT, |
2034 | "%d\n", wiphy_name(hw->wiphy), aphy->state); | 1218 | "ath9k: %s: TX in unexpected wiphy state " |
1219 | "%d\n", wiphy_name(hw->wiphy), aphy->state); | ||
2035 | goto exit; | 1220 | goto exit; |
2036 | } | 1221 | } |
2037 | 1222 | ||
2038 | if (sc->ps_enabled) { | 1223 | if (sc->ps_enabled) { |
2039 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
2040 | /* | 1224 | /* |
2041 | * mac80211 does not set PM field for normal data frames, so we | 1225 | * mac80211 does not set PM field for normal data frames, so we |
2042 | * need to update that based on the current PS mode. | 1226 | * need to update that based on the current PS mode. |
@@ -2044,8 +1228,8 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2044 | if (ieee80211_is_data(hdr->frame_control) && | 1228 | if (ieee80211_is_data(hdr->frame_control) && |
2045 | !ieee80211_is_nullfunc(hdr->frame_control) && | 1229 | !ieee80211_is_nullfunc(hdr->frame_control) && |
2046 | !ieee80211_has_pm(hdr->frame_control)) { | 1230 | !ieee80211_has_pm(hdr->frame_control)) { |
2047 | DPRINTF(sc, ATH_DBG_PS, "Add PM=1 for a TX frame " | 1231 | ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame " |
2048 | "while in PS mode\n"); | 1232 | "while in PS mode\n"); |
2049 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | 1233 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); |
2050 | } | 1234 | } |
2051 | } | 1235 | } |
@@ -2056,16 +1240,16 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2056 | * power save mode. Need to wake up hardware for the TX to be | 1240 | * power save mode. Need to wake up hardware for the TX to be |
2057 | * completed and if needed, also for RX of buffered frames. | 1241 | * completed and if needed, also for RX of buffered frames. |
2058 | */ | 1242 | */ |
2059 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
2060 | ath9k_ps_wakeup(sc); | 1243 | ath9k_ps_wakeup(sc); |
2061 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 1244 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
2062 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 1245 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
2063 | DPRINTF(sc, ATH_DBG_PS, "Sending PS-Poll to pick a " | 1246 | ath_print(common, ATH_DBG_PS, |
2064 | "buffered frame\n"); | 1247 | "Sending PS-Poll to pick a buffered frame\n"); |
2065 | sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA; | 1248 | sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA; |
2066 | } else { | 1249 | } else { |
2067 | DPRINTF(sc, ATH_DBG_PS, "Wake up to complete TX\n"); | 1250 | ath_print(common, ATH_DBG_PS, |
2068 | sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK; | 1251 | "Wake up to complete TX\n"); |
1252 | sc->ps_flags |= PS_WAIT_FOR_TX_ACK; | ||
2069 | } | 1253 | } |
2070 | /* | 1254 | /* |
2071 | * The actual restore operation will happen only after | 1255 | * The actual restore operation will happen only after |
@@ -2083,7 +1267,6 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2083 | * BSSes. | 1267 | * BSSes. |
2084 | */ | 1268 | */ |
2085 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 1269 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
2086 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
2087 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 1270 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
2088 | sc->tx.seq_no += 0x10; | 1271 | sc->tx.seq_no += 0x10; |
2089 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | 1272 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); |
@@ -2091,13 +1274,13 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2091 | } | 1274 | } |
2092 | 1275 | ||
2093 | /* Add the padding after the header if this is not already done */ | 1276 | /* Add the padding after the header if this is not already done */ |
2094 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1277 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
2095 | if (hdrlen & 3) { | 1278 | padsize = padpos & 3; |
2096 | padsize = hdrlen % 4; | 1279 | if (padsize && skb->len>padpos) { |
2097 | if (skb_headroom(skb) < padsize) | 1280 | if (skb_headroom(skb) < padsize) |
2098 | return -1; | 1281 | return -1; |
2099 | skb_push(skb, padsize); | 1282 | skb_push(skb, padsize); |
2100 | memmove(skb->data, skb->data + padsize, hdrlen); | 1283 | memmove(skb->data, skb->data + padsize, padpos); |
2101 | } | 1284 | } |
2102 | 1285 | ||
2103 | /* Check if a tx queue is available */ | 1286 | /* Check if a tx queue is available */ |
@@ -2106,10 +1289,10 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2106 | if (!txctl.txq) | 1289 | if (!txctl.txq) |
2107 | goto exit; | 1290 | goto exit; |
2108 | 1291 | ||
2109 | DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); | 1292 | ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); |
2110 | 1293 | ||
2111 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 1294 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
2112 | DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n"); | 1295 | ath_print(common, ATH_DBG_XMIT, "TX failed\n"); |
2113 | goto exit; | 1296 | goto exit; |
2114 | } | 1297 | } |
2115 | 1298 | ||
@@ -2123,6 +1306,8 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2123 | { | 1306 | { |
2124 | struct ath_wiphy *aphy = hw->priv; | 1307 | struct ath_wiphy *aphy = hw->priv; |
2125 | struct ath_softc *sc = aphy->sc; | 1308 | struct ath_softc *sc = aphy->sc; |
1309 | struct ath_hw *ah = sc->sc_ah; | ||
1310 | struct ath_common *common = ath9k_hw_common(ah); | ||
2126 | 1311 | ||
2127 | mutex_lock(&sc->mutex); | 1312 | mutex_lock(&sc->mutex); |
2128 | 1313 | ||
@@ -2137,7 +1322,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2137 | } | 1322 | } |
2138 | 1323 | ||
2139 | if (sc->sc_flags & SC_OP_INVALID) { | 1324 | if (sc->sc_flags & SC_OP_INVALID) { |
2140 | DPRINTF(sc, ATH_DBG_ANY, "Device not present\n"); | 1325 | ath_print(common, ATH_DBG_ANY, "Device not present\n"); |
2141 | mutex_unlock(&sc->mutex); | 1326 | mutex_unlock(&sc->mutex); |
2142 | return; | 1327 | return; |
2143 | } | 1328 | } |
@@ -2147,41 +1332,48 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2147 | return; /* another wiphy still in use */ | 1332 | return; /* another wiphy still in use */ |
2148 | } | 1333 | } |
2149 | 1334 | ||
2150 | if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) { | 1335 | /* Ensure HW is awake when we try to shut it down. */ |
2151 | ath9k_hw_btcoex_disable(sc->sc_ah); | 1336 | ath9k_ps_wakeup(sc); |
2152 | if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) | 1337 | |
2153 | ath_btcoex_timer_pause(sc, &sc->btcoex_info); | 1338 | if (ah->btcoex_hw.enabled) { |
1339 | ath9k_hw_btcoex_disable(ah); | ||
1340 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | ||
1341 | ath9k_btcoex_timer_pause(sc); | ||
2154 | } | 1342 | } |
2155 | 1343 | ||
2156 | /* make sure h/w will not generate any interrupt | 1344 | /* make sure h/w will not generate any interrupt |
2157 | * before setting the invalid flag. */ | 1345 | * before setting the invalid flag. */ |
2158 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | 1346 | ath9k_hw_set_interrupts(ah, 0); |
2159 | 1347 | ||
2160 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 1348 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
2161 | ath_drain_all_txq(sc, false); | 1349 | ath_drain_all_txq(sc, false); |
2162 | ath_stoprecv(sc); | 1350 | ath_stoprecv(sc); |
2163 | ath9k_hw_phy_disable(sc->sc_ah); | 1351 | ath9k_hw_phy_disable(ah); |
2164 | } else | 1352 | } else |
2165 | sc->rx.rxlink = NULL; | 1353 | sc->rx.rxlink = NULL; |
2166 | 1354 | ||
2167 | /* disable HAL and put h/w to sleep */ | 1355 | /* disable HAL and put h/w to sleep */ |
2168 | ath9k_hw_disable(sc->sc_ah); | 1356 | ath9k_hw_disable(ah); |
2169 | ath9k_hw_configpcipowersave(sc->sc_ah, 1, 1); | 1357 | ath9k_hw_configpcipowersave(ah, 1, 1); |
2170 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); | 1358 | ath9k_ps_restore(sc); |
1359 | |||
1360 | /* Finally, put the chip in FULL SLEEP mode */ | ||
1361 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | ||
2171 | 1362 | ||
2172 | sc->sc_flags |= SC_OP_INVALID; | 1363 | sc->sc_flags |= SC_OP_INVALID; |
2173 | 1364 | ||
2174 | mutex_unlock(&sc->mutex); | 1365 | mutex_unlock(&sc->mutex); |
2175 | 1366 | ||
2176 | DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n"); | 1367 | ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); |
2177 | } | 1368 | } |
2178 | 1369 | ||
2179 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 1370 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
2180 | struct ieee80211_if_init_conf *conf) | 1371 | struct ieee80211_vif *vif) |
2181 | { | 1372 | { |
2182 | struct ath_wiphy *aphy = hw->priv; | 1373 | struct ath_wiphy *aphy = hw->priv; |
2183 | struct ath_softc *sc = aphy->sc; | 1374 | struct ath_softc *sc = aphy->sc; |
2184 | struct ath_vif *avp = (void *)conf->vif->drv_priv; | 1375 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1376 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
2185 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; | 1377 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; |
2186 | int ret = 0; | 1378 | int ret = 0; |
2187 | 1379 | ||
@@ -2193,7 +1385,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2193 | goto out; | 1385 | goto out; |
2194 | } | 1386 | } |
2195 | 1387 | ||
2196 | switch (conf->type) { | 1388 | switch (vif->type) { |
2197 | case NL80211_IFTYPE_STATION: | 1389 | case NL80211_IFTYPE_STATION: |
2198 | ic_opmode = NL80211_IFTYPE_STATION; | 1390 | ic_opmode = NL80211_IFTYPE_STATION; |
2199 | break; | 1391 | break; |
@@ -2204,16 +1396,17 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2204 | ret = -ENOBUFS; | 1396 | ret = -ENOBUFS; |
2205 | goto out; | 1397 | goto out; |
2206 | } | 1398 | } |
2207 | ic_opmode = conf->type; | 1399 | ic_opmode = vif->type; |
2208 | break; | 1400 | break; |
2209 | default: | 1401 | default: |
2210 | DPRINTF(sc, ATH_DBG_FATAL, | 1402 | ath_print(common, ATH_DBG_FATAL, |
2211 | "Interface type %d not yet supported\n", conf->type); | 1403 | "Interface type %d not yet supported\n", vif->type); |
2212 | ret = -EOPNOTSUPP; | 1404 | ret = -EOPNOTSUPP; |
2213 | goto out; | 1405 | goto out; |
2214 | } | 1406 | } |
2215 | 1407 | ||
2216 | DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode); | 1408 | ath_print(common, ATH_DBG_CONFIG, |
1409 | "Attach a VIF of type: %d\n", ic_opmode); | ||
2217 | 1410 | ||
2218 | /* Set the VIF opmode */ | 1411 | /* Set the VIF opmode */ |
2219 | avp->av_opmode = ic_opmode; | 1412 | avp->av_opmode = ic_opmode; |
@@ -2239,19 +1432,19 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2239 | * Enable MIB interrupts when there are hardware phy counters. | 1432 | * Enable MIB interrupts when there are hardware phy counters. |
2240 | * Note we only do this (at the moment) for station mode. | 1433 | * Note we only do this (at the moment) for station mode. |
2241 | */ | 1434 | */ |
2242 | if ((conf->type == NL80211_IFTYPE_STATION) || | 1435 | if ((vif->type == NL80211_IFTYPE_STATION) || |
2243 | (conf->type == NL80211_IFTYPE_ADHOC) || | 1436 | (vif->type == NL80211_IFTYPE_ADHOC) || |
2244 | (conf->type == NL80211_IFTYPE_MESH_POINT)) { | 1437 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { |
2245 | sc->imask |= ATH9K_INT_MIB; | 1438 | sc->imask |= ATH9K_INT_MIB; |
2246 | sc->imask |= ATH9K_INT_TSFOOR; | 1439 | sc->imask |= ATH9K_INT_TSFOOR; |
2247 | } | 1440 | } |
2248 | 1441 | ||
2249 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 1442 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); |
2250 | 1443 | ||
2251 | if (conf->type == NL80211_IFTYPE_AP || | 1444 | if (vif->type == NL80211_IFTYPE_AP || |
2252 | conf->type == NL80211_IFTYPE_ADHOC || | 1445 | vif->type == NL80211_IFTYPE_ADHOC || |
2253 | conf->type == NL80211_IFTYPE_MONITOR) | 1446 | vif->type == NL80211_IFTYPE_MONITOR) |
2254 | ath_start_ani(sc); | 1447 | ath_start_ani(common); |
2255 | 1448 | ||
2256 | out: | 1449 | out: |
2257 | mutex_unlock(&sc->mutex); | 1450 | mutex_unlock(&sc->mutex); |
@@ -2259,32 +1452,35 @@ out: | |||
2259 | } | 1452 | } |
2260 | 1453 | ||
2261 | static void ath9k_remove_interface(struct ieee80211_hw *hw, | 1454 | static void ath9k_remove_interface(struct ieee80211_hw *hw, |
2262 | struct ieee80211_if_init_conf *conf) | 1455 | struct ieee80211_vif *vif) |
2263 | { | 1456 | { |
2264 | struct ath_wiphy *aphy = hw->priv; | 1457 | struct ath_wiphy *aphy = hw->priv; |
2265 | struct ath_softc *sc = aphy->sc; | 1458 | struct ath_softc *sc = aphy->sc; |
2266 | struct ath_vif *avp = (void *)conf->vif->drv_priv; | 1459 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1460 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
2267 | int i; | 1461 | int i; |
2268 | 1462 | ||
2269 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); | 1463 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
2270 | 1464 | ||
2271 | mutex_lock(&sc->mutex); | 1465 | mutex_lock(&sc->mutex); |
2272 | 1466 | ||
2273 | /* Stop ANI */ | 1467 | /* Stop ANI */ |
2274 | del_timer_sync(&sc->ani.timer); | 1468 | del_timer_sync(&common->ani.timer); |
2275 | 1469 | ||
2276 | /* Reclaim beacon resources */ | 1470 | /* Reclaim beacon resources */ |
2277 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 1471 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
2278 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 1472 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
2279 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | 1473 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { |
1474 | ath9k_ps_wakeup(sc); | ||
2280 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1475 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2281 | ath_beacon_return(sc, avp); | 1476 | ath9k_ps_restore(sc); |
2282 | } | 1477 | } |
2283 | 1478 | ||
1479 | ath_beacon_return(sc, avp); | ||
2284 | sc->sc_flags &= ~SC_OP_BEACONS; | 1480 | sc->sc_flags &= ~SC_OP_BEACONS; |
2285 | 1481 | ||
2286 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 1482 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { |
2287 | if (sc->beacon.bslot[i] == conf->vif) { | 1483 | if (sc->beacon.bslot[i] == vif) { |
2288 | printk(KERN_DEBUG "%s: vif had allocated beacon " | 1484 | printk(KERN_DEBUG "%s: vif had allocated beacon " |
2289 | "slot\n", __func__); | 1485 | "slot\n", __func__); |
2290 | sc->beacon.bslot[i] = NULL; | 1486 | sc->beacon.bslot[i] = NULL; |
@@ -2297,56 +1493,92 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2297 | mutex_unlock(&sc->mutex); | 1493 | mutex_unlock(&sc->mutex); |
2298 | } | 1494 | } |
2299 | 1495 | ||
1496 | void ath9k_enable_ps(struct ath_softc *sc) | ||
1497 | { | ||
1498 | sc->ps_enabled = true; | ||
1499 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
1500 | if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { | ||
1501 | sc->imask |= ATH9K_INT_TIM_TIMER; | ||
1502 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
1503 | sc->imask); | ||
1504 | } | ||
1505 | } | ||
1506 | ath9k_hw_setrxabort(sc->sc_ah, 1); | ||
1507 | } | ||
1508 | |||
2300 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 1509 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) |
2301 | { | 1510 | { |
2302 | struct ath_wiphy *aphy = hw->priv; | 1511 | struct ath_wiphy *aphy = hw->priv; |
2303 | struct ath_softc *sc = aphy->sc; | 1512 | struct ath_softc *sc = aphy->sc; |
1513 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2304 | struct ieee80211_conf *conf = &hw->conf; | 1514 | struct ieee80211_conf *conf = &hw->conf; |
2305 | struct ath_hw *ah = sc->sc_ah; | 1515 | struct ath_hw *ah = sc->sc_ah; |
2306 | bool all_wiphys_idle = false, disable_radio = false; | 1516 | bool disable_radio; |
2307 | 1517 | ||
2308 | mutex_lock(&sc->mutex); | 1518 | mutex_lock(&sc->mutex); |
2309 | 1519 | ||
2310 | /* Leave this as the first check */ | 1520 | /* |
1521 | * Leave this as the first check because we need to turn on the | ||
1522 | * radio if it was disabled before prior to processing the rest | ||
1523 | * of the changes. Likewise we must only disable the radio towards | ||
1524 | * the end. | ||
1525 | */ | ||
2311 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | 1526 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { |
1527 | bool enable_radio; | ||
1528 | bool all_wiphys_idle; | ||
1529 | bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); | ||
2312 | 1530 | ||
2313 | spin_lock_bh(&sc->wiphy_lock); | 1531 | spin_lock_bh(&sc->wiphy_lock); |
2314 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); | 1532 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); |
1533 | ath9k_set_wiphy_idle(aphy, idle); | ||
1534 | |||
1535 | enable_radio = (!idle && all_wiphys_idle); | ||
1536 | |||
1537 | /* | ||
1538 | * After we unlock here its possible another wiphy | ||
1539 | * can be re-renabled so to account for that we will | ||
1540 | * only disable the radio toward the end of this routine | ||
1541 | * if by then all wiphys are still idle. | ||
1542 | */ | ||
2315 | spin_unlock_bh(&sc->wiphy_lock); | 1543 | spin_unlock_bh(&sc->wiphy_lock); |
2316 | 1544 | ||
2317 | if (conf->flags & IEEE80211_CONF_IDLE){ | 1545 | if (enable_radio) { |
2318 | if (all_wiphys_idle) | 1546 | sc->ps_idle = false; |
2319 | disable_radio = true; | 1547 | ath_radio_enable(sc, hw); |
2320 | } | 1548 | ath_print(common, ATH_DBG_CONFIG, |
2321 | else if (all_wiphys_idle) { | 1549 | "not-idle: enabling radio\n"); |
2322 | ath_radio_enable(sc); | ||
2323 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
2324 | "not-idle: enabling radio\n"); | ||
2325 | } | 1550 | } |
2326 | } | 1551 | } |
2327 | 1552 | ||
1553 | /* | ||
1554 | * We just prepare to enable PS. We have to wait until our AP has | ||
1555 | * ACK'd our null data frame to disable RX otherwise we'll ignore | ||
1556 | * those ACKs and end up retransmitting the same null data frames. | ||
1557 | * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode. | ||
1558 | */ | ||
2328 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 1559 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
2329 | if (conf->flags & IEEE80211_CONF_PS) { | 1560 | if (conf->flags & IEEE80211_CONF_PS) { |
2330 | if (!(ah->caps.hw_caps & | 1561 | sc->ps_flags |= PS_ENABLED; |
2331 | ATH9K_HW_CAP_AUTOSLEEP)) { | 1562 | /* |
2332 | if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { | 1563 | * At this point we know hardware has received an ACK |
2333 | sc->imask |= ATH9K_INT_TIM_TIMER; | 1564 | * of a previously sent null data frame. |
2334 | ath9k_hw_set_interrupts(sc->sc_ah, | 1565 | */ |
2335 | sc->imask); | 1566 | if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) { |
2336 | } | 1567 | sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; |
2337 | ath9k_hw_setrxabort(sc->sc_ah, 1); | 1568 | ath9k_enable_ps(sc); |
2338 | } | 1569 | } |
2339 | sc->ps_enabled = true; | ||
2340 | } else { | 1570 | } else { |
2341 | sc->ps_enabled = false; | 1571 | sc->ps_enabled = false; |
2342 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | 1572 | sc->ps_flags &= ~(PS_ENABLED | |
1573 | PS_NULLFUNC_COMPLETED); | ||
1574 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | ||
2343 | if (!(ah->caps.hw_caps & | 1575 | if (!(ah->caps.hw_caps & |
2344 | ATH9K_HW_CAP_AUTOSLEEP)) { | 1576 | ATH9K_HW_CAP_AUTOSLEEP)) { |
2345 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 1577 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
2346 | sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | | 1578 | sc->ps_flags &= ~(PS_WAIT_FOR_BEACON | |
2347 | SC_OP_WAIT_FOR_CAB | | 1579 | PS_WAIT_FOR_CAB | |
2348 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 1580 | PS_WAIT_FOR_PSPOLL_DATA | |
2349 | SC_OP_WAIT_FOR_TX_ACK); | 1581 | PS_WAIT_FOR_TX_ACK); |
2350 | if (sc->imask & ATH9K_INT_TIM_TIMER) { | 1582 | if (sc->imask & ATH9K_INT_TIM_TIMER) { |
2351 | sc->imask &= ~ATH9K_INT_TIM_TIMER; | 1583 | sc->imask &= ~ATH9K_INT_TIM_TIMER; |
2352 | ath9k_hw_set_interrupts(sc->sc_ah, | 1584 | ath9k_hw_set_interrupts(sc->sc_ah, |
@@ -2356,6 +1588,14 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2356 | } | 1588 | } |
2357 | } | 1589 | } |
2358 | 1590 | ||
1591 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | ||
1592 | if (conf->flags & IEEE80211_CONF_MONITOR) { | ||
1593 | ath_print(common, ATH_DBG_CONFIG, | ||
1594 | "HW opmode set to Monitor mode\n"); | ||
1595 | sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; | ||
1596 | } | ||
1597 | } | ||
1598 | |||
2359 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1599 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
2360 | struct ieee80211_channel *curchan = hw->conf.channel; | 1600 | struct ieee80211_channel *curchan = hw->conf.channel; |
2361 | int pos = curchan->hw_value; | 1601 | int pos = curchan->hw_value; |
@@ -2374,8 +1614,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2374 | goto skip_chan_change; | 1614 | goto skip_chan_change; |
2375 | } | 1615 | } |
2376 | 1616 | ||
2377 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 1617 | ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
2378 | curchan->center_freq); | 1618 | curchan->center_freq); |
2379 | 1619 | ||
2380 | /* XXX: remove me eventualy */ | 1620 | /* XXX: remove me eventualy */ |
2381 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); | 1621 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); |
@@ -2383,19 +1623,27 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2383 | ath_update_chainmask(sc, conf_is_ht(conf)); | 1623 | ath_update_chainmask(sc, conf_is_ht(conf)); |
2384 | 1624 | ||
2385 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { | 1625 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { |
2386 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); | 1626 | ath_print(common, ATH_DBG_FATAL, |
1627 | "Unable to set channel\n"); | ||
2387 | mutex_unlock(&sc->mutex); | 1628 | mutex_unlock(&sc->mutex); |
2388 | return -EINVAL; | 1629 | return -EINVAL; |
2389 | } | 1630 | } |
2390 | } | 1631 | } |
2391 | 1632 | ||
2392 | skip_chan_change: | 1633 | skip_chan_change: |
2393 | if (changed & IEEE80211_CONF_CHANGE_POWER) | 1634 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
2394 | sc->config.txpowlimit = 2 * conf->power_level; | 1635 | sc->config.txpowlimit = 2 * conf->power_level; |
1636 | ath_update_txpow(sc); | ||
1637 | } | ||
1638 | |||
1639 | spin_lock_bh(&sc->wiphy_lock); | ||
1640 | disable_radio = ath9k_all_wiphys_idle(sc); | ||
1641 | spin_unlock_bh(&sc->wiphy_lock); | ||
2395 | 1642 | ||
2396 | if (disable_radio) { | 1643 | if (disable_radio) { |
2397 | DPRINTF(sc, ATH_DBG_CONFIG, "idle: disabling radio\n"); | 1644 | ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); |
2398 | ath_radio_disable(sc); | 1645 | sc->ps_idle = true; |
1646 | ath_radio_disable(sc, hw); | ||
2399 | } | 1647 | } |
2400 | 1648 | ||
2401 | mutex_unlock(&sc->mutex); | 1649 | mutex_unlock(&sc->mutex); |
@@ -2431,27 +1679,32 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
2431 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); | 1679 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); |
2432 | ath9k_ps_restore(sc); | 1680 | ath9k_ps_restore(sc); |
2433 | 1681 | ||
2434 | DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", rfilt); | 1682 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, |
1683 | "Set HW RX filter: 0x%x\n", rfilt); | ||
2435 | } | 1684 | } |
2436 | 1685 | ||
2437 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | 1686 | static int ath9k_sta_add(struct ieee80211_hw *hw, |
2438 | struct ieee80211_vif *vif, | 1687 | struct ieee80211_vif *vif, |
2439 | enum sta_notify_cmd cmd, | 1688 | struct ieee80211_sta *sta) |
2440 | struct ieee80211_sta *sta) | ||
2441 | { | 1689 | { |
2442 | struct ath_wiphy *aphy = hw->priv; | 1690 | struct ath_wiphy *aphy = hw->priv; |
2443 | struct ath_softc *sc = aphy->sc; | 1691 | struct ath_softc *sc = aphy->sc; |
2444 | 1692 | ||
2445 | switch (cmd) { | 1693 | ath_node_attach(sc, sta); |
2446 | case STA_NOTIFY_ADD: | 1694 | |
2447 | ath_node_attach(sc, sta); | 1695 | return 0; |
2448 | break; | 1696 | } |
2449 | case STA_NOTIFY_REMOVE: | 1697 | |
2450 | ath_node_detach(sc, sta); | 1698 | static int ath9k_sta_remove(struct ieee80211_hw *hw, |
2451 | break; | 1699 | struct ieee80211_vif *vif, |
2452 | default: | 1700 | struct ieee80211_sta *sta) |
2453 | break; | 1701 | { |
2454 | } | 1702 | struct ath_wiphy *aphy = hw->priv; |
1703 | struct ath_softc *sc = aphy->sc; | ||
1704 | |||
1705 | ath_node_detach(sc, sta); | ||
1706 | |||
1707 | return 0; | ||
2455 | } | 1708 | } |
2456 | 1709 | ||
2457 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | 1710 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, |
@@ -2459,6 +1712,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2459 | { | 1712 | { |
2460 | struct ath_wiphy *aphy = hw->priv; | 1713 | struct ath_wiphy *aphy = hw->priv; |
2461 | struct ath_softc *sc = aphy->sc; | 1714 | struct ath_softc *sc = aphy->sc; |
1715 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2462 | struct ath9k_tx_queue_info qi; | 1716 | struct ath9k_tx_queue_info qi; |
2463 | int ret = 0, qnum; | 1717 | int ret = 0, qnum; |
2464 | 1718 | ||
@@ -2475,15 +1729,19 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2475 | qi.tqi_burstTime = params->txop; | 1729 | qi.tqi_burstTime = params->txop; |
2476 | qnum = ath_get_hal_qnum(queue, sc); | 1730 | qnum = ath_get_hal_qnum(queue, sc); |
2477 | 1731 | ||
2478 | DPRINTF(sc, ATH_DBG_CONFIG, | 1732 | ath_print(common, ATH_DBG_CONFIG, |
2479 | "Configure tx [queue/halq] [%d/%d], " | 1733 | "Configure tx [queue/halq] [%d/%d], " |
2480 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | 1734 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", |
2481 | queue, qnum, params->aifs, params->cw_min, | 1735 | queue, qnum, params->aifs, params->cw_min, |
2482 | params->cw_max, params->txop); | 1736 | params->cw_max, params->txop); |
2483 | 1737 | ||
2484 | ret = ath_txq_update(sc, qnum, &qi); | 1738 | ret = ath_txq_update(sc, qnum, &qi); |
2485 | if (ret) | 1739 | if (ret) |
2486 | DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n"); | 1740 | ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); |
1741 | |||
1742 | if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) | ||
1743 | if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret) | ||
1744 | ath_beaconq_config(sc); | ||
2487 | 1745 | ||
2488 | mutex_unlock(&sc->mutex); | 1746 | mutex_unlock(&sc->mutex); |
2489 | 1747 | ||
@@ -2498,6 +1756,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2498 | { | 1756 | { |
2499 | struct ath_wiphy *aphy = hw->priv; | 1757 | struct ath_wiphy *aphy = hw->priv; |
2500 | struct ath_softc *sc = aphy->sc; | 1758 | struct ath_softc *sc = aphy->sc; |
1759 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2501 | int ret = 0; | 1760 | int ret = 0; |
2502 | 1761 | ||
2503 | if (modparam_nohwcrypt) | 1762 | if (modparam_nohwcrypt) |
@@ -2505,11 +1764,11 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2505 | 1764 | ||
2506 | mutex_lock(&sc->mutex); | 1765 | mutex_lock(&sc->mutex); |
2507 | ath9k_ps_wakeup(sc); | 1766 | ath9k_ps_wakeup(sc); |
2508 | DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n"); | 1767 | ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n"); |
2509 | 1768 | ||
2510 | switch (cmd) { | 1769 | switch (cmd) { |
2511 | case SET_KEY: | 1770 | case SET_KEY: |
2512 | ret = ath_key_config(sc, vif, sta, key); | 1771 | ret = ath_key_config(common, vif, sta, key); |
2513 | if (ret >= 0) { | 1772 | if (ret >= 0) { |
2514 | key->hw_key_idx = ret; | 1773 | key->hw_key_idx = ret; |
2515 | /* push IV and Michael MIC generation to stack */ | 1774 | /* push IV and Michael MIC generation to stack */ |
@@ -2522,7 +1781,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2522 | } | 1781 | } |
2523 | break; | 1782 | break; |
2524 | case DISABLE_KEY: | 1783 | case DISABLE_KEY: |
2525 | ath_key_delete(sc, key); | 1784 | ath_key_delete(common, key); |
2526 | break; | 1785 | break; |
2527 | default: | 1786 | default: |
2528 | ret = -EINVAL; | 1787 | ret = -EINVAL; |
@@ -2542,94 +1801,87 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2542 | struct ath_wiphy *aphy = hw->priv; | 1801 | struct ath_wiphy *aphy = hw->priv; |
2543 | struct ath_softc *sc = aphy->sc; | 1802 | struct ath_softc *sc = aphy->sc; |
2544 | struct ath_hw *ah = sc->sc_ah; | 1803 | struct ath_hw *ah = sc->sc_ah; |
1804 | struct ath_common *common = ath9k_hw_common(ah); | ||
2545 | struct ath_vif *avp = (void *)vif->drv_priv; | 1805 | struct ath_vif *avp = (void *)vif->drv_priv; |
2546 | u32 rfilt = 0; | 1806 | int slottime; |
2547 | int error, i; | 1807 | int error; |
2548 | 1808 | ||
2549 | mutex_lock(&sc->mutex); | 1809 | mutex_lock(&sc->mutex); |
2550 | 1810 | ||
2551 | /* | 1811 | if (changed & BSS_CHANGED_BSSID) { |
2552 | * TODO: Need to decide which hw opmode to use for | 1812 | /* Set BSSID */ |
2553 | * multi-interface cases | 1813 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
2554 | * XXX: This belongs into add_interface! | 1814 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); |
2555 | */ | 1815 | common->curaid = 0; |
2556 | if (vif->type == NL80211_IFTYPE_AP && | 1816 | ath9k_hw_write_associd(ah); |
2557 | ah->opmode != NL80211_IFTYPE_AP) { | ||
2558 | ah->opmode = NL80211_IFTYPE_STATION; | ||
2559 | ath9k_hw_setopmode(ah); | ||
2560 | memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN); | ||
2561 | sc->curaid = 0; | ||
2562 | ath9k_hw_write_associd(sc); | ||
2563 | /* Request full reset to get hw opmode changed properly */ | ||
2564 | sc->sc_flags |= SC_OP_FULL_RESET; | ||
2565 | } | ||
2566 | |||
2567 | if ((changed & BSS_CHANGED_BSSID) && | ||
2568 | !is_zero_ether_addr(bss_conf->bssid)) { | ||
2569 | switch (vif->type) { | ||
2570 | case NL80211_IFTYPE_STATION: | ||
2571 | case NL80211_IFTYPE_ADHOC: | ||
2572 | case NL80211_IFTYPE_MESH_POINT: | ||
2573 | /* Set BSSID */ | ||
2574 | memcpy(sc->curbssid, bss_conf->bssid, ETH_ALEN); | ||
2575 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); | ||
2576 | sc->curaid = 0; | ||
2577 | ath9k_hw_write_associd(sc); | ||
2578 | |||
2579 | /* Set aggregation protection mode parameters */ | ||
2580 | sc->config.ath_aggr_prot = 0; | ||
2581 | |||
2582 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
2583 | "RX filter 0x%x bssid %pM aid 0x%x\n", | ||
2584 | rfilt, sc->curbssid, sc->curaid); | ||
2585 | |||
2586 | /* need to reconfigure the beacon */ | ||
2587 | sc->sc_flags &= ~SC_OP_BEACONS ; | ||
2588 | 1817 | ||
2589 | break; | 1818 | /* Set aggregation protection mode parameters */ |
2590 | default: | 1819 | sc->config.ath_aggr_prot = 0; |
2591 | break; | 1820 | |
2592 | } | 1821 | /* Only legacy IBSS for now */ |
1822 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
1823 | ath_update_chainmask(sc, 0); | ||
1824 | |||
1825 | ath_print(common, ATH_DBG_CONFIG, | ||
1826 | "BSSID: %pM aid: 0x%x\n", | ||
1827 | common->curbssid, common->curaid); | ||
1828 | |||
1829 | /* need to reconfigure the beacon */ | ||
1830 | sc->sc_flags &= ~SC_OP_BEACONS ; | ||
2593 | } | 1831 | } |
2594 | 1832 | ||
2595 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | 1833 | /* Enable transmission of beacons (AP, IBSS, MESH) */ |
2596 | (vif->type == NL80211_IFTYPE_AP) || | 1834 | if ((changed & BSS_CHANGED_BEACON) || |
2597 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 1835 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { |
2598 | if ((changed & BSS_CHANGED_BEACON) || | 1836 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2599 | (changed & BSS_CHANGED_BEACON_ENABLED && | 1837 | error = ath_beacon_alloc(aphy, vif); |
2600 | bss_conf->enable_beacon)) { | 1838 | if (!error) |
1839 | ath_beacon_config(sc, vif); | ||
1840 | } | ||
1841 | |||
1842 | if (changed & BSS_CHANGED_ERP_SLOT) { | ||
1843 | if (bss_conf->use_short_slot) | ||
1844 | slottime = 9; | ||
1845 | else | ||
1846 | slottime = 20; | ||
1847 | if (vif->type == NL80211_IFTYPE_AP) { | ||
2601 | /* | 1848 | /* |
2602 | * Allocate and setup the beacon frame. | 1849 | * Defer update, so that connected stations can adjust |
2603 | * | 1850 | * their settings at the same time. |
2604 | * Stop any previous beacon DMA. This may be | 1851 | * See beacon.c for more details |
2605 | * necessary, for example, when an ibss merge | ||
2606 | * causes reconfiguration; we may be called | ||
2607 | * with beacon transmission active. | ||
2608 | */ | 1852 | */ |
2609 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1853 | sc->beacon.slottime = slottime; |
1854 | sc->beacon.updateslot = UPDATE; | ||
1855 | } else { | ||
1856 | ah->slottime = slottime; | ||
1857 | ath9k_hw_init_global_settings(ah); | ||
1858 | } | ||
1859 | } | ||
1860 | |||
1861 | /* Disable transmission of beacons */ | ||
1862 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) | ||
1863 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2610 | 1864 | ||
1865 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
1866 | sc->beacon_interval = bss_conf->beacon_int; | ||
1867 | /* | ||
1868 | * In case of AP mode, the HW TSF has to be reset | ||
1869 | * when the beacon interval changes. | ||
1870 | */ | ||
1871 | if (vif->type == NL80211_IFTYPE_AP) { | ||
1872 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
1873 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2611 | error = ath_beacon_alloc(aphy, vif); | 1874 | error = ath_beacon_alloc(aphy, vif); |
2612 | if (!error) | 1875 | if (!error) |
2613 | ath_beacon_config(sc, vif); | 1876 | ath_beacon_config(sc, vif); |
1877 | } else { | ||
1878 | ath_beacon_config(sc, vif); | ||
2614 | } | 1879 | } |
2615 | } | 1880 | } |
2616 | 1881 | ||
2617 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | ||
2618 | if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { | ||
2619 | for (i = 0; i < IEEE80211_WEP_NKID; i++) | ||
2620 | if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) | ||
2621 | ath9k_hw_keysetmac(sc->sc_ah, | ||
2622 | (u16)i, | ||
2623 | sc->curbssid); | ||
2624 | } | ||
2625 | |||
2626 | /* Only legacy IBSS for now */ | ||
2627 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
2628 | ath_update_chainmask(sc, 0); | ||
2629 | |||
2630 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 1882 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
2631 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | 1883 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", |
2632 | bss_conf->use_short_preamble); | 1884 | bss_conf->use_short_preamble); |
2633 | if (bss_conf->use_short_preamble) | 1885 | if (bss_conf->use_short_preamble) |
2634 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; | 1886 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; |
2635 | else | 1887 | else |
@@ -2637,8 +1889,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2637 | } | 1889 | } |
2638 | 1890 | ||
2639 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | 1891 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { |
2640 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", | 1892 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", |
2641 | bss_conf->use_cts_prot); | 1893 | bss_conf->use_cts_prot); |
2642 | if (bss_conf->use_cts_prot && | 1894 | if (bss_conf->use_cts_prot && |
2643 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) | 1895 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) |
2644 | sc->sc_flags |= SC_OP_PROTECT_ENABLE; | 1896 | sc->sc_flags |= SC_OP_PROTECT_ENABLE; |
@@ -2647,23 +1899,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2647 | } | 1899 | } |
2648 | 1900 | ||
2649 | if (changed & BSS_CHANGED_ASSOC) { | 1901 | if (changed & BSS_CHANGED_ASSOC) { |
2650 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | 1902 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", |
2651 | bss_conf->assoc); | 1903 | bss_conf->assoc); |
2652 | ath9k_bss_assoc_info(sc, vif, bss_conf); | 1904 | ath9k_bss_assoc_info(sc, vif, bss_conf); |
2653 | } | 1905 | } |
2654 | 1906 | ||
2655 | /* | ||
2656 | * The HW TSF has to be reset when the beacon interval changes. | ||
2657 | * We set the flag here, and ath_beacon_config_ap() would take this | ||
2658 | * into account when it gets called through the subsequent | ||
2659 | * config_interface() call - with IFCC_BEACON in the changed field. | ||
2660 | */ | ||
2661 | |||
2662 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
2663 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
2664 | sc->beacon_interval = bss_conf->beacon_int; | ||
2665 | } | ||
2666 | |||
2667 | mutex_unlock(&sc->mutex); | 1907 | mutex_unlock(&sc->mutex); |
2668 | } | 1908 | } |
2669 | 1909 | ||
@@ -2696,11 +1936,16 @@ static void ath9k_reset_tsf(struct ieee80211_hw *hw) | |||
2696 | struct ath_softc *sc = aphy->sc; | 1936 | struct ath_softc *sc = aphy->sc; |
2697 | 1937 | ||
2698 | mutex_lock(&sc->mutex); | 1938 | mutex_lock(&sc->mutex); |
1939 | |||
1940 | ath9k_ps_wakeup(sc); | ||
2699 | ath9k_hw_reset_tsf(sc->sc_ah); | 1941 | ath9k_hw_reset_tsf(sc->sc_ah); |
1942 | ath9k_ps_restore(sc); | ||
1943 | |||
2700 | mutex_unlock(&sc->mutex); | 1944 | mutex_unlock(&sc->mutex); |
2701 | } | 1945 | } |
2702 | 1946 | ||
2703 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, | 1947 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, |
1948 | struct ieee80211_vif *vif, | ||
2704 | enum ieee80211_ampdu_mlme_action action, | 1949 | enum ieee80211_ampdu_mlme_action action, |
2705 | struct ieee80211_sta *sta, | 1950 | struct ieee80211_sta *sta, |
2706 | u16 tid, u16 *ssn) | 1951 | u16 tid, u16 *ssn) |
@@ -2717,18 +1962,25 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2717 | case IEEE80211_AMPDU_RX_STOP: | 1962 | case IEEE80211_AMPDU_RX_STOP: |
2718 | break; | 1963 | break; |
2719 | case IEEE80211_AMPDU_TX_START: | 1964 | case IEEE80211_AMPDU_TX_START: |
1965 | ath9k_ps_wakeup(sc); | ||
2720 | ath_tx_aggr_start(sc, sta, tid, ssn); | 1966 | ath_tx_aggr_start(sc, sta, tid, ssn); |
2721 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 1967 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1968 | ath9k_ps_restore(sc); | ||
2722 | break; | 1969 | break; |
2723 | case IEEE80211_AMPDU_TX_STOP: | 1970 | case IEEE80211_AMPDU_TX_STOP: |
1971 | ath9k_ps_wakeup(sc); | ||
2724 | ath_tx_aggr_stop(sc, sta, tid); | 1972 | ath_tx_aggr_stop(sc, sta, tid); |
2725 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 1973 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1974 | ath9k_ps_restore(sc); | ||
2726 | break; | 1975 | break; |
2727 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 1976 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
1977 | ath9k_ps_wakeup(sc); | ||
2728 | ath_tx_aggr_resume(sc, sta, tid); | 1978 | ath_tx_aggr_resume(sc, sta, tid); |
1979 | ath9k_ps_restore(sc); | ||
2729 | break; | 1980 | break; |
2730 | default: | 1981 | default: |
2731 | DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n"); | 1982 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1983 | "Unknown AMPDU action\n"); | ||
2732 | } | 1984 | } |
2733 | 1985 | ||
2734 | return ret; | 1986 | return ret; |
@@ -2738,6 +1990,7 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
2738 | { | 1990 | { |
2739 | struct ath_wiphy *aphy = hw->priv; | 1991 | struct ath_wiphy *aphy = hw->priv; |
2740 | struct ath_softc *sc = aphy->sc; | 1992 | struct ath_softc *sc = aphy->sc; |
1993 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2741 | 1994 | ||
2742 | mutex_lock(&sc->mutex); | 1995 | mutex_lock(&sc->mutex); |
2743 | if (ath9k_wiphy_scanning(sc)) { | 1996 | if (ath9k_wiphy_scanning(sc)) { |
@@ -2753,10 +2006,9 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
2753 | 2006 | ||
2754 | aphy->state = ATH_WIPHY_SCAN; | 2007 | aphy->state = ATH_WIPHY_SCAN; |
2755 | ath9k_wiphy_pause_all_forced(sc, aphy); | 2008 | ath9k_wiphy_pause_all_forced(sc, aphy); |
2756 | |||
2757 | spin_lock_bh(&sc->ani_lock); | ||
2758 | sc->sc_flags |= SC_OP_SCANNING; | 2009 | sc->sc_flags |= SC_OP_SCANNING; |
2759 | spin_unlock_bh(&sc->ani_lock); | 2010 | del_timer_sync(&common->ani.timer); |
2011 | cancel_delayed_work_sync(&sc->tx_complete_work); | ||
2760 | mutex_unlock(&sc->mutex); | 2012 | mutex_unlock(&sc->mutex); |
2761 | } | 2013 | } |
2762 | 2014 | ||
@@ -2764,17 +2016,30 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
2764 | { | 2016 | { |
2765 | struct ath_wiphy *aphy = hw->priv; | 2017 | struct ath_wiphy *aphy = hw->priv; |
2766 | struct ath_softc *sc = aphy->sc; | 2018 | struct ath_softc *sc = aphy->sc; |
2019 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2767 | 2020 | ||
2768 | mutex_lock(&sc->mutex); | 2021 | mutex_lock(&sc->mutex); |
2769 | spin_lock_bh(&sc->ani_lock); | ||
2770 | aphy->state = ATH_WIPHY_ACTIVE; | 2022 | aphy->state = ATH_WIPHY_ACTIVE; |
2771 | sc->sc_flags &= ~SC_OP_SCANNING; | 2023 | sc->sc_flags &= ~SC_OP_SCANNING; |
2772 | sc->sc_flags |= SC_OP_FULL_RESET; | 2024 | sc->sc_flags |= SC_OP_FULL_RESET; |
2773 | spin_unlock_bh(&sc->ani_lock); | 2025 | ath_start_ani(common); |
2026 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | ||
2774 | ath_beacon_config(sc, NULL); | 2027 | ath_beacon_config(sc, NULL); |
2775 | mutex_unlock(&sc->mutex); | 2028 | mutex_unlock(&sc->mutex); |
2776 | } | 2029 | } |
2777 | 2030 | ||
2031 | static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | ||
2032 | { | ||
2033 | struct ath_wiphy *aphy = hw->priv; | ||
2034 | struct ath_softc *sc = aphy->sc; | ||
2035 | struct ath_hw *ah = sc->sc_ah; | ||
2036 | |||
2037 | mutex_lock(&sc->mutex); | ||
2038 | ah->coverage_class = coverage_class; | ||
2039 | ath9k_hw_init_global_settings(ah); | ||
2040 | mutex_unlock(&sc->mutex); | ||
2041 | } | ||
2042 | |||
2778 | struct ieee80211_ops ath9k_ops = { | 2043 | struct ieee80211_ops ath9k_ops = { |
2779 | .tx = ath9k_tx, | 2044 | .tx = ath9k_tx, |
2780 | .start = ath9k_start, | 2045 | .start = ath9k_start, |
@@ -2783,7 +2048,8 @@ struct ieee80211_ops ath9k_ops = { | |||
2783 | .remove_interface = ath9k_remove_interface, | 2048 | .remove_interface = ath9k_remove_interface, |
2784 | .config = ath9k_config, | 2049 | .config = ath9k_config, |
2785 | .configure_filter = ath9k_configure_filter, | 2050 | .configure_filter = ath9k_configure_filter, |
2786 | .sta_notify = ath9k_sta_notify, | 2051 | .sta_add = ath9k_sta_add, |
2052 | .sta_remove = ath9k_sta_remove, | ||
2787 | .conf_tx = ath9k_conf_tx, | 2053 | .conf_tx = ath9k_conf_tx, |
2788 | .bss_info_changed = ath9k_bss_info_changed, | 2054 | .bss_info_changed = ath9k_bss_info_changed, |
2789 | .set_key = ath9k_set_key, | 2055 | .set_key = ath9k_set_key, |
@@ -2794,122 +2060,5 @@ struct ieee80211_ops ath9k_ops = { | |||
2794 | .sw_scan_start = ath9k_sw_scan_start, | 2060 | .sw_scan_start = ath9k_sw_scan_start, |
2795 | .sw_scan_complete = ath9k_sw_scan_complete, | 2061 | .sw_scan_complete = ath9k_sw_scan_complete, |
2796 | .rfkill_poll = ath9k_rfkill_poll_state, | 2062 | .rfkill_poll = ath9k_rfkill_poll_state, |
2063 | .set_coverage_class = ath9k_set_coverage_class, | ||
2797 | }; | 2064 | }; |
2798 | |||
2799 | static struct { | ||
2800 | u32 version; | ||
2801 | const char * name; | ||
2802 | } ath_mac_bb_names[] = { | ||
2803 | { AR_SREV_VERSION_5416_PCI, "5416" }, | ||
2804 | { AR_SREV_VERSION_5416_PCIE, "5418" }, | ||
2805 | { AR_SREV_VERSION_9100, "9100" }, | ||
2806 | { AR_SREV_VERSION_9160, "9160" }, | ||
2807 | { AR_SREV_VERSION_9280, "9280" }, | ||
2808 | { AR_SREV_VERSION_9285, "9285" }, | ||
2809 | { AR_SREV_VERSION_9287, "9287" } | ||
2810 | }; | ||
2811 | |||
2812 | static struct { | ||
2813 | u16 version; | ||
2814 | const char * name; | ||
2815 | } ath_rf_names[] = { | ||
2816 | { 0, "5133" }, | ||
2817 | { AR_RAD5133_SREV_MAJOR, "5133" }, | ||
2818 | { AR_RAD5122_SREV_MAJOR, "5122" }, | ||
2819 | { AR_RAD2133_SREV_MAJOR, "2133" }, | ||
2820 | { AR_RAD2122_SREV_MAJOR, "2122" } | ||
2821 | }; | ||
2822 | |||
2823 | /* | ||
2824 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. | ||
2825 | */ | ||
2826 | const char * | ||
2827 | ath_mac_bb_name(u32 mac_bb_version) | ||
2828 | { | ||
2829 | int i; | ||
2830 | |||
2831 | for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) { | ||
2832 | if (ath_mac_bb_names[i].version == mac_bb_version) { | ||
2833 | return ath_mac_bb_names[i].name; | ||
2834 | } | ||
2835 | } | ||
2836 | |||
2837 | return "????"; | ||
2838 | } | ||
2839 | |||
2840 | /* | ||
2841 | * Return the RF name. "????" is returned if the RF is unknown. | ||
2842 | */ | ||
2843 | const char * | ||
2844 | ath_rf_name(u16 rf_version) | ||
2845 | { | ||
2846 | int i; | ||
2847 | |||
2848 | for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) { | ||
2849 | if (ath_rf_names[i].version == rf_version) { | ||
2850 | return ath_rf_names[i].name; | ||
2851 | } | ||
2852 | } | ||
2853 | |||
2854 | return "????"; | ||
2855 | } | ||
2856 | |||
2857 | static int __init ath9k_init(void) | ||
2858 | { | ||
2859 | int error; | ||
2860 | |||
2861 | /* Register rate control algorithm */ | ||
2862 | error = ath_rate_control_register(); | ||
2863 | if (error != 0) { | ||
2864 | printk(KERN_ERR | ||
2865 | "ath9k: Unable to register rate control " | ||
2866 | "algorithm: %d\n", | ||
2867 | error); | ||
2868 | goto err_out; | ||
2869 | } | ||
2870 | |||
2871 | error = ath9k_debug_create_root(); | ||
2872 | if (error) { | ||
2873 | printk(KERN_ERR | ||
2874 | "ath9k: Unable to create debugfs root: %d\n", | ||
2875 | error); | ||
2876 | goto err_rate_unregister; | ||
2877 | } | ||
2878 | |||
2879 | error = ath_pci_init(); | ||
2880 | if (error < 0) { | ||
2881 | printk(KERN_ERR | ||
2882 | "ath9k: No PCI devices found, driver not installed.\n"); | ||
2883 | error = -ENODEV; | ||
2884 | goto err_remove_root; | ||
2885 | } | ||
2886 | |||
2887 | error = ath_ahb_init(); | ||
2888 | if (error < 0) { | ||
2889 | error = -ENODEV; | ||
2890 | goto err_pci_exit; | ||
2891 | } | ||
2892 | |||
2893 | return 0; | ||
2894 | |||
2895 | err_pci_exit: | ||
2896 | ath_pci_exit(); | ||
2897 | |||
2898 | err_remove_root: | ||
2899 | ath9k_debug_remove_root(); | ||
2900 | err_rate_unregister: | ||
2901 | ath_rate_control_unregister(); | ||
2902 | err_out: | ||
2903 | return error; | ||
2904 | } | ||
2905 | module_init(ath9k_init); | ||
2906 | |||
2907 | static void __exit ath9k_exit(void) | ||
2908 | { | ||
2909 | ath_ahb_exit(); | ||
2910 | ath_pci_exit(); | ||
2911 | ath9k_debug_remove_root(); | ||
2912 | ath_rate_control_unregister(); | ||
2913 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | ||
2914 | } | ||
2915 | module_exit(ath9k_exit); | ||