diff options
Diffstat (limited to 'drivers/net/wireless/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 1016 |
1 files changed, 430 insertions, 586 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 727f067aca4f..d8e826659c15 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -28,72 +28,113 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | |||
28 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | 28 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); |
29 | MODULE_LICENSE("Dual BSD/GPL"); | 29 | MODULE_LICENSE("Dual BSD/GPL"); |
30 | 30 | ||
31 | static struct pci_device_id ath_pci_id_table[] __devinitdata = { | 31 | /* We use the hw_value as an index into our private channel structure */ |
32 | { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ | 32 | |
33 | { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */ | 33 | #define CHAN2G(_freq, _idx) { \ |
34 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ | 34 | .center_freq = (_freq), \ |
35 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ | 35 | .hw_value = (_idx), \ |
36 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ | 36 | .max_power = 30, \ |
37 | { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ | 37 | } |
38 | { 0 } | 38 | |
39 | #define CHAN5G(_freq, _idx) { \ | ||
40 | .band = IEEE80211_BAND_5GHZ, \ | ||
41 | .center_freq = (_freq), \ | ||
42 | .hw_value = (_idx), \ | ||
43 | .max_power = 30, \ | ||
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 */ | ||
39 | }; | 65 | }; |
40 | 66 | ||
41 | static void ath_detach(struct ath_softc *sc); | 67 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY |
42 | 68 | * on 5 MHz steps, we support the channels which we know | |
43 | /* return bus cachesize in 4B word units */ | 69 | * we have calibration data for all cards though to make |
44 | 70 | * this static */ | |
45 | static void bus_read_cachesize(struct ath_softc *sc, int *csz) | 71 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { |
46 | { | 72 | /* _We_ call this UNII 1 */ |
47 | u8 u8tmp; | 73 | CHAN5G(5180, 14), /* Channel 36 */ |
48 | 74 | CHAN5G(5200, 15), /* Channel 40 */ | |
49 | pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp); | 75 | CHAN5G(5220, 16), /* Channel 44 */ |
50 | *csz = (int)u8tmp; | 76 | CHAN5G(5240, 17), /* Channel 48 */ |
51 | 77 | /* _We_ call this UNII 2 */ | |
52 | /* | 78 | CHAN5G(5260, 18), /* Channel 52 */ |
53 | * This check was put in to avoid "unplesant" consequences if | 79 | CHAN5G(5280, 19), /* Channel 56 */ |
54 | * the bootrom has not fully initialized all PCI devices. | 80 | CHAN5G(5300, 20), /* Channel 60 */ |
55 | * Sometimes the cache line size register is not set | 81 | CHAN5G(5320, 21), /* Channel 64 */ |
56 | */ | 82 | /* _We_ call this "Middle band" */ |
57 | 83 | CHAN5G(5500, 22), /* Channel 100 */ | |
58 | if (*csz == 0) | 84 | CHAN5G(5520, 23), /* Channel 104 */ |
59 | *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ | 85 | CHAN5G(5540, 24), /* Channel 108 */ |
60 | } | 86 | CHAN5G(5560, 25), /* Channel 112 */ |
61 | 87 | CHAN5G(5580, 26), /* Channel 116 */ | |
62 | static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) | 88 | CHAN5G(5600, 27), /* Channel 120 */ |
63 | { | 89 | CHAN5G(5620, 28), /* Channel 124 */ |
64 | sc->cur_rate_table = sc->hw_rate_table[mode]; | 90 | CHAN5G(5640, 29), /* Channel 128 */ |
65 | /* | 91 | CHAN5G(5660, 30), /* Channel 132 */ |
66 | * All protection frames are transmited at 2Mb/s for | 92 | CHAN5G(5680, 31), /* Channel 136 */ |
67 | * 11g, otherwise at 1Mb/s. | 93 | CHAN5G(5700, 32), /* Channel 140 */ |
68 | * XXX select protection rate index from rate table. | 94 | /* _We_ call this UNII 3 */ |
69 | */ | 95 | CHAN5G(5745, 33), /* Channel 149 */ |
70 | sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0); | 96 | CHAN5G(5765, 34), /* Channel 153 */ |
71 | } | 97 | CHAN5G(5785, 35), /* Channel 157 */ |
98 | CHAN5G(5805, 36), /* Channel 161 */ | ||
99 | CHAN5G(5825, 37), /* Channel 165 */ | ||
100 | }; | ||
72 | 101 | ||
73 | static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan) | 102 | static void ath_cache_conf_rate(struct ath_softc *sc, |
103 | struct ieee80211_conf *conf) | ||
74 | { | 104 | { |
75 | if (chan->chanmode == CHANNEL_A) | 105 | switch (conf->channel->band) { |
76 | return ATH9K_MODE_11A; | 106 | case IEEE80211_BAND_2GHZ: |
77 | else if (chan->chanmode == CHANNEL_G) | 107 | if (conf_is_ht20(conf)) |
78 | return ATH9K_MODE_11G; | 108 | sc->cur_rate_table = |
79 | else if (chan->chanmode == CHANNEL_B) | 109 | sc->hw_rate_table[ATH9K_MODE_11NG_HT20]; |
80 | return ATH9K_MODE_11B; | 110 | else if (conf_is_ht40_minus(conf)) |
81 | else if (chan->chanmode == CHANNEL_A_HT20) | 111 | sc->cur_rate_table = |
82 | return ATH9K_MODE_11NA_HT20; | 112 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS]; |
83 | else if (chan->chanmode == CHANNEL_G_HT20) | 113 | else if (conf_is_ht40_plus(conf)) |
84 | return ATH9K_MODE_11NG_HT20; | 114 | sc->cur_rate_table = |
85 | else if (chan->chanmode == CHANNEL_A_HT40PLUS) | 115 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS]; |
86 | return ATH9K_MODE_11NA_HT40PLUS; | 116 | else |
87 | else if (chan->chanmode == CHANNEL_A_HT40MINUS) | 117 | sc->cur_rate_table = |
88 | return ATH9K_MODE_11NA_HT40MINUS; | 118 | sc->hw_rate_table[ATH9K_MODE_11G]; |
89 | else if (chan->chanmode == CHANNEL_G_HT40PLUS) | 119 | break; |
90 | return ATH9K_MODE_11NG_HT40PLUS; | 120 | case IEEE80211_BAND_5GHZ: |
91 | else if (chan->chanmode == CHANNEL_G_HT40MINUS) | 121 | if (conf_is_ht20(conf)) |
92 | return ATH9K_MODE_11NG_HT40MINUS; | 122 | sc->cur_rate_table = |
93 | 123 | sc->hw_rate_table[ATH9K_MODE_11NA_HT20]; | |
94 | WARN_ON(1); /* should not get here */ | 124 | else if (conf_is_ht40_minus(conf)) |
95 | 125 | sc->cur_rate_table = | |
96 | return ATH9K_MODE_11B; | 126 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS]; |
127 | else if (conf_is_ht40_plus(conf)) | ||
128 | sc->cur_rate_table = | ||
129 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS]; | ||
130 | else | ||
131 | sc->cur_rate_table = | ||
132 | sc->hw_rate_table[ATH9K_MODE_11A]; | ||
133 | break; | ||
134 | default: | ||
135 | BUG_ON(1); | ||
136 | break; | ||
137 | } | ||
97 | } | 138 | } |
98 | 139 | ||
99 | static void ath_update_txpow(struct ath_softc *sc) | 140 | static void ath_update_txpow(struct ath_softc *sc) |
@@ -176,79 +217,18 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | |||
176 | for (i = 0; i < maxrates; i++) { | 217 | for (i = 0; i < maxrates; i++) { |
177 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; | 218 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; |
178 | rate[i].hw_value = rate_table->info[i].ratecode; | 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 | } | ||
179 | sband->n_bitrates++; | 225 | sband->n_bitrates++; |
226 | |||
180 | DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", | 227 | DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", |
181 | rate[i].bitrate / 10, rate[i].hw_value); | 228 | rate[i].bitrate / 10, rate[i].hw_value); |
182 | } | 229 | } |
183 | } | 230 | } |
184 | 231 | ||
185 | static int ath_setup_channels(struct ath_softc *sc) | ||
186 | { | ||
187 | struct ath_hal *ah = sc->sc_ah; | ||
188 | int nchan, i, a = 0, b = 0; | ||
189 | u8 regclassids[ATH_REGCLASSIDS_MAX]; | ||
190 | u32 nregclass = 0; | ||
191 | struct ieee80211_supported_band *band_2ghz; | ||
192 | struct ieee80211_supported_band *band_5ghz; | ||
193 | struct ieee80211_channel *chan_2ghz; | ||
194 | struct ieee80211_channel *chan_5ghz; | ||
195 | struct ath9k_channel *c; | ||
196 | |||
197 | /* Fill in ah->ah_channels */ | ||
198 | if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan, | ||
199 | regclassids, ATH_REGCLASSIDS_MAX, | ||
200 | &nregclass, CTRY_DEFAULT, false, 1)) { | ||
201 | u32 rd = ah->ah_currentRD; | ||
202 | DPRINTF(sc, ATH_DBG_FATAL, | ||
203 | "Unable to collect channel list; " | ||
204 | "regdomain likely %u country code %u\n", | ||
205 | rd, CTRY_DEFAULT); | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | |||
209 | band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
210 | band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
211 | chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ]; | ||
212 | chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ]; | ||
213 | |||
214 | for (i = 0; i < nchan; i++) { | ||
215 | c = &ah->ah_channels[i]; | ||
216 | if (IS_CHAN_2GHZ(c)) { | ||
217 | chan_2ghz[a].band = IEEE80211_BAND_2GHZ; | ||
218 | chan_2ghz[a].center_freq = c->channel; | ||
219 | chan_2ghz[a].max_power = c->maxTxPower; | ||
220 | |||
221 | if (c->privFlags & CHANNEL_DISALLOW_ADHOC) | ||
222 | chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS; | ||
223 | if (c->channelFlags & CHANNEL_PASSIVE) | ||
224 | chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
225 | |||
226 | band_2ghz->n_channels = ++a; | ||
227 | |||
228 | DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, " | ||
229 | "channelFlags: 0x%x\n", | ||
230 | c->channel, c->channelFlags); | ||
231 | } else if (IS_CHAN_5GHZ(c)) { | ||
232 | chan_5ghz[b].band = IEEE80211_BAND_5GHZ; | ||
233 | chan_5ghz[b].center_freq = c->channel; | ||
234 | chan_5ghz[b].max_power = c->maxTxPower; | ||
235 | |||
236 | if (c->privFlags & CHANNEL_DISALLOW_ADHOC) | ||
237 | chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS; | ||
238 | if (c->channelFlags & CHANNEL_PASSIVE) | ||
239 | chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
240 | |||
241 | band_5ghz->n_channels = ++b; | ||
242 | |||
243 | DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, " | ||
244 | "channelFlags: 0x%x\n", | ||
245 | c->channel, c->channelFlags); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* | 232 | /* |
253 | * Set/change channels. If the channel is really being changed, it's done | 233 | * Set/change channels. If the channel is really being changed, it's done |
254 | * by reseting the chip. To accomplish this we must first cleanup any pending | 234 | * by reseting the chip. To accomplish this we must first cleanup any pending |
@@ -258,68 +238,66 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
258 | { | 238 | { |
259 | struct ath_hal *ah = sc->sc_ah; | 239 | struct ath_hal *ah = sc->sc_ah; |
260 | bool fastcc = true, stopped; | 240 | bool fastcc = true, stopped; |
241 | struct ieee80211_hw *hw = sc->hw; | ||
242 | struct ieee80211_channel *channel = hw->conf.channel; | ||
243 | int r; | ||
261 | 244 | ||
262 | if (sc->sc_flags & SC_OP_INVALID) | 245 | if (sc->sc_flags & SC_OP_INVALID) |
263 | return -EIO; | 246 | return -EIO; |
264 | 247 | ||
265 | if (hchan->channel != sc->sc_ah->ah_curchan->channel || | 248 | ath9k_ps_wakeup(sc); |
266 | hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags || | ||
267 | (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) || | ||
268 | (sc->sc_flags & SC_OP_FULL_RESET)) { | ||
269 | int status; | ||
270 | /* | ||
271 | * This is only performed if the channel settings have | ||
272 | * actually changed. | ||
273 | * | ||
274 | * To switch channels clear any pending DMA operations; | ||
275 | * wait long enough for the RX fifo to drain, reset the | ||
276 | * hardware at the new frequency, and then re-enable | ||
277 | * the relevant bits of the h/w. | ||
278 | */ | ||
279 | ath9k_hw_set_interrupts(ah, 0); | ||
280 | ath_draintxq(sc, false); | ||
281 | stopped = ath_stoprecv(sc); | ||
282 | |||
283 | /* XXX: do not flush receive queue here. We don't want | ||
284 | * to flush data frames already in queue because of | ||
285 | * changing channel. */ | ||
286 | |||
287 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) | ||
288 | fastcc = false; | ||
289 | |||
290 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
291 | "(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n", | ||
292 | sc->sc_ah->ah_curchan->channel, | ||
293 | hchan->channel, hchan->channelFlags, sc->tx_chan_width); | ||
294 | |||
295 | spin_lock_bh(&sc->sc_resetlock); | ||
296 | if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width, | ||
297 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | ||
298 | sc->sc_ht_extprotspacing, fastcc, &status)) { | ||
299 | DPRINTF(sc, ATH_DBG_FATAL, | ||
300 | "Unable to reset channel %u (%uMhz) " | ||
301 | "flags 0x%x hal status %u\n", | ||
302 | ath9k_hw_mhz2ieee(ah, hchan->channel, | ||
303 | hchan->channelFlags), | ||
304 | hchan->channel, hchan->channelFlags, status); | ||
305 | spin_unlock_bh(&sc->sc_resetlock); | ||
306 | return -EIO; | ||
307 | } | ||
308 | spin_unlock_bh(&sc->sc_resetlock); | ||
309 | 249 | ||
310 | sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; | 250 | /* |
311 | sc->sc_flags &= ~SC_OP_FULL_RESET; | 251 | * This is only performed if the channel settings have |
252 | * actually changed. | ||
253 | * | ||
254 | * To switch channels clear any pending DMA operations; | ||
255 | * wait long enough for the RX fifo to drain, reset the | ||
256 | * hardware at the new frequency, and then re-enable | ||
257 | * the relevant bits of the h/w. | ||
258 | */ | ||
259 | ath9k_hw_set_interrupts(ah, 0); | ||
260 | ath_drain_all_txq(sc, false); | ||
261 | stopped = ath_stoprecv(sc); | ||
312 | 262 | ||
313 | if (ath_startrecv(sc) != 0) { | 263 | /* XXX: do not flush receive queue here. We don't want |
314 | DPRINTF(sc, ATH_DBG_FATAL, | 264 | * to flush data frames already in queue because of |
315 | "Unable to restart recv logic\n"); | 265 | * changing channel. */ |
316 | return -EIO; | ||
317 | } | ||
318 | 266 | ||
319 | ath_setcurmode(sc, ath_chan2mode(hchan)); | 267 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) |
320 | ath_update_txpow(sc); | 268 | fastcc = false; |
321 | ath9k_hw_set_interrupts(ah, sc->sc_imask); | 269 | |
270 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
271 | "(%u MHz) -> (%u MHz), chanwidth: %d\n", | ||
272 | sc->sc_ah->ah_curchan->channel, | ||
273 | channel->center_freq, sc->tx_chan_width); | ||
274 | |||
275 | spin_lock_bh(&sc->sc_resetlock); | ||
276 | |||
277 | r = ath9k_hw_reset(ah, hchan, fastcc); | ||
278 | if (r) { | ||
279 | DPRINTF(sc, ATH_DBG_FATAL, | ||
280 | "Unable to reset channel (%u Mhz) " | ||
281 | "reset status %u\n", | ||
282 | channel->center_freq, r); | ||
283 | spin_unlock_bh(&sc->sc_resetlock); | ||
284 | return r; | ||
285 | } | ||
286 | spin_unlock_bh(&sc->sc_resetlock); | ||
287 | |||
288 | sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; | ||
289 | sc->sc_flags &= ~SC_OP_FULL_RESET; | ||
290 | |||
291 | if (ath_startrecv(sc) != 0) { | ||
292 | DPRINTF(sc, ATH_DBG_FATAL, | ||
293 | "Unable to restart recv logic\n"); | ||
294 | return -EIO; | ||
322 | } | 295 | } |
296 | |||
297 | ath_cache_conf_rate(sc, &hw->conf); | ||
298 | ath_update_txpow(sc); | ||
299 | ath9k_hw_set_interrupts(ah, sc->sc_imask); | ||
300 | ath9k_ps_restore(sc); | ||
323 | return 0; | 301 | return 0; |
324 | } | 302 | } |
325 | 303 | ||
@@ -369,8 +347,7 @@ static void ath_ani_calibrate(unsigned long data) | |||
369 | } else { | 347 | } else { |
370 | if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= | 348 | if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= |
371 | ATH_RESTART_CALINTERVAL) { | 349 | ATH_RESTART_CALINTERVAL) { |
372 | ath9k_hw_reset_calvalid(ah, ah->ah_curchan, | 350 | sc->sc_ani.sc_caldone = ath9k_hw_reset_calvalid(ah); |
373 | &sc->sc_ani.sc_caldone); | ||
374 | if (sc->sc_ani.sc_caldone) | 351 | if (sc->sc_ani.sc_caldone) |
375 | sc->sc_ani.sc_resetcal_timer = timestamp; | 352 | sc->sc_ani.sc_resetcal_timer = timestamp; |
376 | } | 353 | } |
@@ -434,12 +411,14 @@ static void ath_ani_calibrate(unsigned long data) | |||
434 | /* | 411 | /* |
435 | * Update tx/rx chainmask. For legacy association, | 412 | * Update tx/rx chainmask. For legacy association, |
436 | * hard code chainmask to 1x1, for 11n association, use | 413 | * hard code chainmask to 1x1, for 11n association, use |
437 | * the chainmask configuration. | 414 | * the chainmask configuration, for bt coexistence, use |
415 | * the chainmask configuration even in legacy mode. | ||
438 | */ | 416 | */ |
439 | static void ath_update_chainmask(struct ath_softc *sc, int is_ht) | 417 | static void ath_update_chainmask(struct ath_softc *sc, int is_ht) |
440 | { | 418 | { |
441 | sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; | 419 | sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; |
442 | if (is_ht) { | 420 | if (is_ht || |
421 | (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) { | ||
443 | sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; | 422 | sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; |
444 | sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; | 423 | sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; |
445 | } else { | 424 | } else { |
@@ -499,7 +478,7 @@ static void ath9k_tasklet(unsigned long data) | |||
499 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); | 478 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); |
500 | } | 479 | } |
501 | 480 | ||
502 | static irqreturn_t ath_isr(int irq, void *dev) | 481 | irqreturn_t ath_isr(int irq, void *dev) |
503 | { | 482 | { |
504 | struct ath_softc *sc = dev; | 483 | struct ath_softc *sc = dev; |
505 | struct ath_hal *ah = sc->sc_ah; | 484 | struct ath_hal *ah = sc->sc_ah; |
@@ -591,8 +570,10 @@ static irqreturn_t ath_isr(int irq, void *dev) | |||
591 | ATH9K_HW_CAP_AUTOSLEEP)) { | 570 | ATH9K_HW_CAP_AUTOSLEEP)) { |
592 | /* Clear RxAbort bit so that we can | 571 | /* Clear RxAbort bit so that we can |
593 | * receive frames */ | 572 | * receive frames */ |
573 | ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); | ||
594 | ath9k_hw_setrxabort(ah, 0); | 574 | ath9k_hw_setrxabort(ah, 0); |
595 | sched = true; | 575 | sched = true; |
576 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; | ||
596 | } | 577 | } |
597 | } | 578 | } |
598 | } | 579 | } |
@@ -609,19 +590,6 @@ static irqreturn_t ath_isr(int irq, void *dev) | |||
609 | return IRQ_HANDLED; | 590 | return IRQ_HANDLED; |
610 | } | 591 | } |
611 | 592 | ||
612 | static int ath_get_channel(struct ath_softc *sc, | ||
613 | struct ieee80211_channel *chan) | ||
614 | { | ||
615 | int i; | ||
616 | |||
617 | for (i = 0; i < sc->sc_ah->ah_nchan; i++) { | ||
618 | if (sc->sc_ah->ah_channels[i].channel == chan->center_freq) | ||
619 | return i; | ||
620 | } | ||
621 | |||
622 | return -1; | ||
623 | } | ||
624 | |||
625 | static u32 ath_get_extchanmode(struct ath_softc *sc, | 593 | static u32 ath_get_extchanmode(struct ath_softc *sc, |
626 | struct ieee80211_channel *chan, | 594 | struct ieee80211_channel *chan, |
627 | enum nl80211_channel_type channel_type) | 595 | enum nl80211_channel_type channel_type) |
@@ -797,7 +765,7 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc) | |||
797 | } | 765 | } |
798 | 766 | ||
799 | static int ath_key_config(struct ath_softc *sc, | 767 | static int ath_key_config(struct ath_softc *sc, |
800 | const u8 *addr, | 768 | struct ieee80211_sta *sta, |
801 | struct ieee80211_key_conf *key) | 769 | struct ieee80211_key_conf *key) |
802 | { | 770 | { |
803 | struct ath9k_keyval hk; | 771 | struct ath9k_keyval hk; |
@@ -818,7 +786,7 @@ static int ath_key_config(struct ath_softc *sc, | |||
818 | hk.kv_type = ATH9K_CIPHER_AES_CCM; | 786 | hk.kv_type = ATH9K_CIPHER_AES_CCM; |
819 | break; | 787 | break; |
820 | default: | 788 | default: |
821 | return -EINVAL; | 789 | return -EOPNOTSUPP; |
822 | } | 790 | } |
823 | 791 | ||
824 | hk.kv_len = key->keylen; | 792 | hk.kv_len = key->keylen; |
@@ -831,7 +799,10 @@ static int ath_key_config(struct ath_softc *sc, | |||
831 | } else if (key->keyidx) { | 799 | } else if (key->keyidx) { |
832 | struct ieee80211_vif *vif; | 800 | struct ieee80211_vif *vif; |
833 | 801 | ||
834 | mac = addr; | 802 | if (WARN_ON(!sta)) |
803 | return -EOPNOTSUPP; | ||
804 | mac = sta->addr; | ||
805 | |||
835 | vif = sc->sc_vaps[0]; | 806 | vif = sc->sc_vaps[0]; |
836 | if (vif->type != NL80211_IFTYPE_AP) { | 807 | if (vif->type != NL80211_IFTYPE_AP) { |
837 | /* Only keyidx 0 should be used with unicast key, but | 808 | /* Only keyidx 0 should be used with unicast key, but |
@@ -840,13 +811,16 @@ static int ath_key_config(struct ath_softc *sc, | |||
840 | } else | 811 | } else |
841 | return -EIO; | 812 | return -EIO; |
842 | } else { | 813 | } else { |
843 | mac = addr; | 814 | if (WARN_ON(!sta)) |
815 | return -EOPNOTSUPP; | ||
816 | mac = sta->addr; | ||
817 | |||
844 | if (key->alg == ALG_TKIP) | 818 | if (key->alg == ALG_TKIP) |
845 | idx = ath_reserve_key_cache_slot_tkip(sc); | 819 | idx = ath_reserve_key_cache_slot_tkip(sc); |
846 | else | 820 | else |
847 | idx = ath_reserve_key_cache_slot(sc); | 821 | idx = ath_reserve_key_cache_slot(sc); |
848 | if (idx < 0) | 822 | if (idx < 0) |
849 | return -EIO; /* no free key cache entries */ | 823 | return -ENOSPC; /* no free key cache entries */ |
850 | } | 824 | } |
851 | 825 | ||
852 | if (key->alg == ALG_TKIP) | 826 | if (key->alg == ALG_TKIP) |
@@ -886,7 +860,8 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) | |||
886 | } | 860 | } |
887 | } | 861 | } |
888 | 862 | ||
889 | static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) | 863 | static void setup_ht_cap(struct ath_softc *sc, |
864 | struct ieee80211_sta_ht_cap *ht_info) | ||
890 | { | 865 | { |
891 | #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */ | 866 | #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */ |
892 | #define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */ | 867 | #define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */ |
@@ -899,10 +874,23 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) | |||
899 | 874 | ||
900 | ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536; | 875 | ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536; |
901 | ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8; | 876 | ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8; |
877 | |||
902 | /* set up supported mcs set */ | 878 | /* set up supported mcs set */ |
903 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | 879 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); |
904 | ht_info->mcs.rx_mask[0] = 0xff; | 880 | |
905 | ht_info->mcs.rx_mask[1] = 0xff; | 881 | switch(sc->sc_rx_chainmask) { |
882 | case 1: | ||
883 | ht_info->mcs.rx_mask[0] = 0xff; | ||
884 | break; | ||
885 | case 3: | ||
886 | case 5: | ||
887 | case 7: | ||
888 | default: | ||
889 | ht_info->mcs.rx_mask[0] = 0xff; | ||
890 | ht_info->mcs.rx_mask[1] = 0xff; | ||
891 | break; | ||
892 | } | ||
893 | |||
906 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | 894 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
907 | } | 895 | } |
908 | 896 | ||
@@ -1067,23 +1055,19 @@ fail: | |||
1067 | static void ath_radio_enable(struct ath_softc *sc) | 1055 | static void ath_radio_enable(struct ath_softc *sc) |
1068 | { | 1056 | { |
1069 | struct ath_hal *ah = sc->sc_ah; | 1057 | struct ath_hal *ah = sc->sc_ah; |
1070 | int status; | 1058 | struct ieee80211_channel *channel = sc->hw->conf.channel; |
1059 | int r; | ||
1071 | 1060 | ||
1061 | ath9k_ps_wakeup(sc); | ||
1072 | spin_lock_bh(&sc->sc_resetlock); | 1062 | spin_lock_bh(&sc->sc_resetlock); |
1073 | if (!ath9k_hw_reset(ah, ah->ah_curchan, | 1063 | |
1074 | sc->tx_chan_width, | 1064 | r = ath9k_hw_reset(ah, ah->ah_curchan, false); |
1075 | sc->sc_tx_chainmask, | 1065 | |
1076 | sc->sc_rx_chainmask, | 1066 | if (r) { |
1077 | sc->sc_ht_extprotspacing, | ||
1078 | false, &status)) { | ||
1079 | DPRINTF(sc, ATH_DBG_FATAL, | 1067 | DPRINTF(sc, ATH_DBG_FATAL, |
1080 | "Unable to reset channel %u (%uMhz) " | 1068 | "Unable to reset channel %u (%uMhz) ", |
1081 | "flags 0x%x hal status %u\n", | 1069 | "reset status %u\n", |
1082 | ath9k_hw_mhz2ieee(ah, | 1070 | channel->center_freq, r); |
1083 | ah->ah_curchan->channel, | ||
1084 | ah->ah_curchan->channelFlags), | ||
1085 | ah->ah_curchan->channel, | ||
1086 | ah->ah_curchan->channelFlags, status); | ||
1087 | } | 1071 | } |
1088 | spin_unlock_bh(&sc->sc_resetlock); | 1072 | spin_unlock_bh(&sc->sc_resetlock); |
1089 | 1073 | ||
@@ -1106,14 +1090,16 @@ static void ath_radio_enable(struct ath_softc *sc) | |||
1106 | ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0); | 1090 | ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0); |
1107 | 1091 | ||
1108 | ieee80211_wake_queues(sc->hw); | 1092 | ieee80211_wake_queues(sc->hw); |
1093 | ath9k_ps_restore(sc); | ||
1109 | } | 1094 | } |
1110 | 1095 | ||
1111 | static void ath_radio_disable(struct ath_softc *sc) | 1096 | static void ath_radio_disable(struct ath_softc *sc) |
1112 | { | 1097 | { |
1113 | struct ath_hal *ah = sc->sc_ah; | 1098 | struct ath_hal *ah = sc->sc_ah; |
1114 | int status; | 1099 | struct ieee80211_channel *channel = sc->hw->conf.channel; |
1115 | 1100 | int r; | |
1116 | 1101 | ||
1102 | ath9k_ps_wakeup(sc); | ||
1117 | ieee80211_stop_queues(sc->hw); | 1103 | ieee80211_stop_queues(sc->hw); |
1118 | 1104 | ||
1119 | /* Disable LED */ | 1105 | /* Disable LED */ |
@@ -1123,30 +1109,23 @@ static void ath_radio_disable(struct ath_softc *sc) | |||
1123 | /* Disable interrupts */ | 1109 | /* Disable interrupts */ |
1124 | ath9k_hw_set_interrupts(ah, 0); | 1110 | ath9k_hw_set_interrupts(ah, 0); |
1125 | 1111 | ||
1126 | ath_draintxq(sc, false); /* clear pending tx frames */ | 1112 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ |
1127 | ath_stoprecv(sc); /* turn off frame recv */ | 1113 | ath_stoprecv(sc); /* turn off frame recv */ |
1128 | ath_flushrecv(sc); /* flush recv queue */ | 1114 | ath_flushrecv(sc); /* flush recv queue */ |
1129 | 1115 | ||
1130 | spin_lock_bh(&sc->sc_resetlock); | 1116 | spin_lock_bh(&sc->sc_resetlock); |
1131 | if (!ath9k_hw_reset(ah, ah->ah_curchan, | 1117 | r = ath9k_hw_reset(ah, ah->ah_curchan, false); |
1132 | sc->tx_chan_width, | 1118 | if (r) { |
1133 | sc->sc_tx_chainmask, | ||
1134 | sc->sc_rx_chainmask, | ||
1135 | sc->sc_ht_extprotspacing, | ||
1136 | false, &status)) { | ||
1137 | DPRINTF(sc, ATH_DBG_FATAL, | 1119 | DPRINTF(sc, ATH_DBG_FATAL, |
1138 | "Unable to reset channel %u (%uMhz) " | 1120 | "Unable to reset channel %u (%uMhz) " |
1139 | "flags 0x%x hal status %u\n", | 1121 | "reset status %u\n", |
1140 | ath9k_hw_mhz2ieee(ah, | 1122 | channel->center_freq, r); |
1141 | ah->ah_curchan->channel, | ||
1142 | ah->ah_curchan->channelFlags), | ||
1143 | ah->ah_curchan->channel, | ||
1144 | ah->ah_curchan->channelFlags, status); | ||
1145 | } | 1123 | } |
1146 | spin_unlock_bh(&sc->sc_resetlock); | 1124 | spin_unlock_bh(&sc->sc_resetlock); |
1147 | 1125 | ||
1148 | ath9k_hw_phy_disable(ah); | 1126 | ath9k_hw_phy_disable(ah); |
1149 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 1127 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); |
1128 | ath9k_ps_restore(sc); | ||
1150 | } | 1129 | } |
1151 | 1130 | ||
1152 | static bool ath_is_rfkill_set(struct ath_softc *sc) | 1131 | static bool ath_is_rfkill_set(struct ath_softc *sc) |
@@ -1274,13 +1253,7 @@ static int ath_start_rfkill_poll(struct ath_softc *sc) | |||
1274 | rfkill_free(sc->rf_kill.rfkill); | 1253 | rfkill_free(sc->rf_kill.rfkill); |
1275 | 1254 | ||
1276 | /* Deinitialize the device */ | 1255 | /* Deinitialize the device */ |
1277 | ath_detach(sc); | 1256 | ath_cleanup(sc); |
1278 | if (sc->pdev->irq) | ||
1279 | free_irq(sc->pdev->irq, sc); | ||
1280 | pci_iounmap(sc->pdev, sc->mem); | ||
1281 | pci_release_region(sc->pdev, 0); | ||
1282 | pci_disable_device(sc->pdev); | ||
1283 | ieee80211_free_hw(sc->hw); | ||
1284 | return -EIO; | 1257 | return -EIO; |
1285 | } else { | 1258 | } else { |
1286 | sc->sc_flags |= SC_OP_RFKILL_REGISTERED; | 1259 | sc->sc_flags |= SC_OP_RFKILL_REGISTERED; |
@@ -1291,11 +1264,21 @@ static int ath_start_rfkill_poll(struct ath_softc *sc) | |||
1291 | } | 1264 | } |
1292 | #endif /* CONFIG_RFKILL */ | 1265 | #endif /* CONFIG_RFKILL */ |
1293 | 1266 | ||
1294 | static void ath_detach(struct ath_softc *sc) | 1267 | void ath_cleanup(struct ath_softc *sc) |
1268 | { | ||
1269 | ath_detach(sc); | ||
1270 | free_irq(sc->irq, sc); | ||
1271 | ath_bus_cleanup(sc); | ||
1272 | ieee80211_free_hw(sc->hw); | ||
1273 | } | ||
1274 | |||
1275 | void ath_detach(struct ath_softc *sc) | ||
1295 | { | 1276 | { |
1296 | struct ieee80211_hw *hw = sc->hw; | 1277 | struct ieee80211_hw *hw = sc->hw; |
1297 | int i = 0; | 1278 | int i = 0; |
1298 | 1279 | ||
1280 | ath9k_ps_wakeup(sc); | ||
1281 | |||
1299 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); | 1282 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); |
1300 | 1283 | ||
1301 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | 1284 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) |
@@ -1320,6 +1303,7 @@ static void ath_detach(struct ath_softc *sc) | |||
1320 | 1303 | ||
1321 | ath9k_hw_detach(sc->sc_ah); | 1304 | ath9k_hw_detach(sc->sc_ah); |
1322 | ath9k_exit_debug(sc); | 1305 | ath9k_exit_debug(sc); |
1306 | ath9k_ps_restore(sc); | ||
1323 | } | 1307 | } |
1324 | 1308 | ||
1325 | static int ath_init(u16 devid, struct ath_softc *sc) | 1309 | static int ath_init(u16 devid, struct ath_softc *sc) |
@@ -1345,14 +1329,14 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1345 | * Cache line size is used to size and align various | 1329 | * Cache line size is used to size and align various |
1346 | * structures used to communicate with the hardware. | 1330 | * structures used to communicate with the hardware. |
1347 | */ | 1331 | */ |
1348 | bus_read_cachesize(sc, &csz); | 1332 | ath_read_cachesize(sc, &csz); |
1349 | /* XXX assert csz is non-zero */ | 1333 | /* XXX assert csz is non-zero */ |
1350 | sc->sc_cachelsz = csz << 2; /* convert to bytes */ | 1334 | sc->sc_cachelsz = csz << 2; /* convert to bytes */ |
1351 | 1335 | ||
1352 | ah = ath9k_hw_attach(devid, sc, sc->mem, &status); | 1336 | ah = ath9k_hw_attach(devid, sc, sc->mem, &status); |
1353 | if (ah == NULL) { | 1337 | if (ah == NULL) { |
1354 | DPRINTF(sc, ATH_DBG_FATAL, | 1338 | DPRINTF(sc, ATH_DBG_FATAL, |
1355 | "Unable to attach hardware; HAL status %u\n", status); | 1339 | "Unable to attach hardware; HAL status %d\n", status); |
1356 | error = -ENXIO; | 1340 | error = -ENXIO; |
1357 | goto bad; | 1341 | goto bad; |
1358 | } | 1342 | } |
@@ -1374,16 +1358,12 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1374 | for (i = 0; i < sc->sc_keymax; i++) | 1358 | for (i = 0; i < sc->sc_keymax; i++) |
1375 | ath9k_hw_keyreset(ah, (u16) i); | 1359 | ath9k_hw_keyreset(ah, (u16) i); |
1376 | 1360 | ||
1377 | /* Collect the channel list using the default country code */ | 1361 | if (ath9k_regd_init(sc->sc_ah)) |
1378 | |||
1379 | error = ath_setup_channels(sc); | ||
1380 | if (error) | ||
1381 | goto bad; | 1362 | goto bad; |
1382 | 1363 | ||
1383 | /* default to MONITOR mode */ | 1364 | /* default to MONITOR mode */ |
1384 | sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; | 1365 | sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; |
1385 | 1366 | ||
1386 | |||
1387 | /* Setup rate tables */ | 1367 | /* Setup rate tables */ |
1388 | 1368 | ||
1389 | ath_rate_attach(sc); | 1369 | ath_rate_attach(sc); |
@@ -1515,20 +1495,25 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1515 | 1495 | ||
1516 | /* setup channels and rates */ | 1496 | /* setup channels and rates */ |
1517 | 1497 | ||
1518 | sc->sbands[IEEE80211_BAND_2GHZ].channels = | 1498 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; |
1519 | sc->channels[IEEE80211_BAND_2GHZ]; | ||
1520 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = | 1499 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = |
1521 | sc->rates[IEEE80211_BAND_2GHZ]; | 1500 | sc->rates[IEEE80211_BAND_2GHZ]; |
1522 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | 1501 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; |
1502 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
1503 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
1523 | 1504 | ||
1524 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { | 1505 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { |
1525 | sc->sbands[IEEE80211_BAND_5GHZ].channels = | 1506 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; |
1526 | sc->channels[IEEE80211_BAND_5GHZ]; | ||
1527 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | 1507 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = |
1528 | sc->rates[IEEE80211_BAND_5GHZ]; | 1508 | sc->rates[IEEE80211_BAND_5GHZ]; |
1529 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | 1509 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; |
1510 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
1511 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
1530 | } | 1512 | } |
1531 | 1513 | ||
1514 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX) | ||
1515 | ath9k_hw_btcoex_enable(sc->sc_ah); | ||
1516 | |||
1532 | return 0; | 1517 | return 0; |
1533 | bad2: | 1518 | bad2: |
1534 | /* cleanup tx queues */ | 1519 | /* cleanup tx queues */ |
@@ -1542,7 +1527,7 @@ bad: | |||
1542 | return error; | 1527 | return error; |
1543 | } | 1528 | } |
1544 | 1529 | ||
1545 | static int ath_attach(u16 devid, struct ath_softc *sc) | 1530 | int ath_attach(u16 devid, struct ath_softc *sc) |
1546 | { | 1531 | { |
1547 | struct ieee80211_hw *hw = sc->hw; | 1532 | struct ieee80211_hw *hw = sc->hw; |
1548 | int error = 0; | 1533 | int error = 0; |
@@ -1560,13 +1545,21 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
1560 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 1545 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
1561 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1546 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1562 | IEEE80211_HW_SIGNAL_DBM | | 1547 | IEEE80211_HW_SIGNAL_DBM | |
1563 | IEEE80211_HW_AMPDU_AGGREGATION; | 1548 | IEEE80211_HW_AMPDU_AGGREGATION | |
1549 | IEEE80211_HW_SUPPORTS_PS | | ||
1550 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
1551 | |||
1552 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah)) | ||
1553 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
1564 | 1554 | ||
1565 | hw->wiphy->interface_modes = | 1555 | hw->wiphy->interface_modes = |
1566 | BIT(NL80211_IFTYPE_AP) | | 1556 | BIT(NL80211_IFTYPE_AP) | |
1567 | BIT(NL80211_IFTYPE_STATION) | | 1557 | BIT(NL80211_IFTYPE_STATION) | |
1568 | BIT(NL80211_IFTYPE_ADHOC); | 1558 | BIT(NL80211_IFTYPE_ADHOC); |
1569 | 1559 | ||
1560 | hw->wiphy->reg_notifier = ath9k_reg_notifier; | ||
1561 | hw->wiphy->strict_regulatory = true; | ||
1562 | |||
1570 | hw->queues = 4; | 1563 | hw->queues = 4; |
1571 | hw->max_rates = 4; | 1564 | hw->max_rates = 4; |
1572 | hw->max_rate_tries = ATH_11N_TXMAXTRY; | 1565 | hw->max_rate_tries = ATH_11N_TXMAXTRY; |
@@ -1576,9 +1569,9 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
1576 | hw->rate_control_algorithm = "ath9k_rate_control"; | 1569 | hw->rate_control_algorithm = "ath9k_rate_control"; |
1577 | 1570 | ||
1578 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { | 1571 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { |
1579 | setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | 1572 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); |
1580 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) | 1573 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) |
1581 | setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | 1574 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); |
1582 | } | 1575 | } |
1583 | 1576 | ||
1584 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ]; | 1577 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ]; |
@@ -1605,11 +1598,36 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
1605 | goto detach; | 1598 | goto detach; |
1606 | #endif | 1599 | #endif |
1607 | 1600 | ||
1601 | if (ath9k_is_world_regd(sc->sc_ah)) { | ||
1602 | /* Anything applied here (prior to wiphy registratoin) gets | ||
1603 | * saved on the wiphy orig_* parameters */ | ||
1604 | const struct ieee80211_regdomain *regd = | ||
1605 | ath9k_world_regdomain(sc->sc_ah); | ||
1606 | hw->wiphy->custom_regulatory = true; | ||
1607 | hw->wiphy->strict_regulatory = false; | ||
1608 | wiphy_apply_custom_regulatory(sc->hw->wiphy, regd); | ||
1609 | ath9k_reg_apply_radar_flags(hw->wiphy); | ||
1610 | ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT); | ||
1611 | } else { | ||
1612 | /* This gets applied in the case of the absense of CRDA, | ||
1613 | * its our own custom world regulatory domain, similar to | ||
1614 | * cfg80211's but we enable passive scanning */ | ||
1615 | const struct ieee80211_regdomain *regd = | ||
1616 | ath9k_default_world_regdomain(); | ||
1617 | wiphy_apply_custom_regulatory(sc->hw->wiphy, regd); | ||
1618 | ath9k_reg_apply_radar_flags(hw->wiphy); | ||
1619 | ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT); | ||
1620 | } | ||
1621 | |||
1608 | error = ieee80211_register_hw(hw); | 1622 | error = ieee80211_register_hw(hw); |
1609 | 1623 | ||
1624 | if (!ath9k_is_world_regd(sc->sc_ah)) | ||
1625 | regulatory_hint(hw->wiphy, sc->sc_ah->alpha2); | ||
1626 | |||
1610 | /* Initialize LED control */ | 1627 | /* Initialize LED control */ |
1611 | ath_init_leds(sc); | 1628 | ath_init_leds(sc); |
1612 | 1629 | ||
1630 | |||
1613 | return 0; | 1631 | return 0; |
1614 | detach: | 1632 | detach: |
1615 | ath_detach(sc); | 1633 | ath_detach(sc); |
@@ -1619,23 +1637,19 @@ detach: | |||
1619 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 1637 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
1620 | { | 1638 | { |
1621 | struct ath_hal *ah = sc->sc_ah; | 1639 | struct ath_hal *ah = sc->sc_ah; |
1622 | int status; | 1640 | struct ieee80211_hw *hw = sc->hw; |
1623 | int error = 0; | 1641 | int r; |
1624 | 1642 | ||
1625 | ath9k_hw_set_interrupts(ah, 0); | 1643 | ath9k_hw_set_interrupts(ah, 0); |
1626 | ath_draintxq(sc, retry_tx); | 1644 | ath_drain_all_txq(sc, retry_tx); |
1627 | ath_stoprecv(sc); | 1645 | ath_stoprecv(sc); |
1628 | ath_flushrecv(sc); | 1646 | ath_flushrecv(sc); |
1629 | 1647 | ||
1630 | spin_lock_bh(&sc->sc_resetlock); | 1648 | spin_lock_bh(&sc->sc_resetlock); |
1631 | if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, | 1649 | r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, false); |
1632 | sc->tx_chan_width, | 1650 | if (r) |
1633 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | ||
1634 | sc->sc_ht_extprotspacing, false, &status)) { | ||
1635 | DPRINTF(sc, ATH_DBG_FATAL, | 1651 | DPRINTF(sc, ATH_DBG_FATAL, |
1636 | "Unable to reset hardware; hal status %u\n", status); | 1652 | "Unable to reset hardware; reset status %u\n", r); |
1637 | error = -EIO; | ||
1638 | } | ||
1639 | spin_unlock_bh(&sc->sc_resetlock); | 1653 | spin_unlock_bh(&sc->sc_resetlock); |
1640 | 1654 | ||
1641 | if (ath_startrecv(sc) != 0) | 1655 | if (ath_startrecv(sc) != 0) |
@@ -1646,7 +1660,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1646 | * that changes the channel so update any state that | 1660 | * that changes the channel so update any state that |
1647 | * might change as a result. | 1661 | * might change as a result. |
1648 | */ | 1662 | */ |
1649 | ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan)); | 1663 | ath_cache_conf_rate(sc, &hw->conf); |
1650 | 1664 | ||
1651 | ath_update_txpow(sc); | 1665 | ath_update_txpow(sc); |
1652 | 1666 | ||
@@ -1666,7 +1680,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1666 | } | 1680 | } |
1667 | } | 1681 | } |
1668 | 1682 | ||
1669 | return error; | 1683 | return r; |
1670 | } | 1684 | } |
1671 | 1685 | ||
1672 | /* | 1686 | /* |
@@ -1720,9 +1734,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1720 | } | 1734 | } |
1721 | 1735 | ||
1722 | /* allocate descriptors */ | 1736 | /* allocate descriptors */ |
1723 | dd->dd_desc = pci_alloc_consistent(sc->pdev, | 1737 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, |
1724 | dd->dd_desc_len, | 1738 | &dd->dd_desc_paddr, GFP_ATOMIC); |
1725 | &dd->dd_desc_paddr); | ||
1726 | if (dd->dd_desc == NULL) { | 1739 | if (dd->dd_desc == NULL) { |
1727 | error = -ENOMEM; | 1740 | error = -ENOMEM; |
1728 | goto fail; | 1741 | goto fail; |
@@ -1768,8 +1781,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1768 | } | 1781 | } |
1769 | return 0; | 1782 | return 0; |
1770 | fail2: | 1783 | fail2: |
1771 | pci_free_consistent(sc->pdev, | 1784 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, |
1772 | dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); | 1785 | dd->dd_desc_paddr); |
1773 | fail: | 1786 | fail: |
1774 | memset(dd, 0, sizeof(*dd)); | 1787 | memset(dd, 0, sizeof(*dd)); |
1775 | return error; | 1788 | return error; |
@@ -1782,8 +1795,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, | |||
1782 | struct ath_descdma *dd, | 1795 | struct ath_descdma *dd, |
1783 | struct list_head *head) | 1796 | struct list_head *head) |
1784 | { | 1797 | { |
1785 | pci_free_consistent(sc->pdev, | 1798 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, |
1786 | dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); | 1799 | dd->dd_desc_paddr); |
1787 | 1800 | ||
1788 | INIT_LIST_HEAD(head); | 1801 | INIT_LIST_HEAD(head); |
1789 | kfree(dd->dd_bufptr); | 1802 | kfree(dd->dd_bufptr); |
@@ -1840,6 +1853,37 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) | |||
1840 | return qnum; | 1853 | return qnum; |
1841 | } | 1854 | } |
1842 | 1855 | ||
1856 | /* XXX: Remove me once we don't depend on ath9k_channel for all | ||
1857 | * this redundant data */ | ||
1858 | static void ath9k_update_ichannel(struct ath_softc *sc, | ||
1859 | struct ath9k_channel *ichan) | ||
1860 | { | ||
1861 | struct ieee80211_hw *hw = sc->hw; | ||
1862 | struct ieee80211_channel *chan = hw->conf.channel; | ||
1863 | struct ieee80211_conf *conf = &hw->conf; | ||
1864 | |||
1865 | ichan->channel = chan->center_freq; | ||
1866 | ichan->chan = chan; | ||
1867 | |||
1868 | if (chan->band == IEEE80211_BAND_2GHZ) { | ||
1869 | ichan->chanmode = CHANNEL_G; | ||
1870 | ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM; | ||
1871 | } else { | ||
1872 | ichan->chanmode = CHANNEL_A; | ||
1873 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | ||
1874 | } | ||
1875 | |||
1876 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
1877 | |||
1878 | if (conf_is_ht(conf)) { | ||
1879 | if (conf_is_ht40(conf)) | ||
1880 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
1881 | |||
1882 | ichan->chanmode = ath_get_extchanmode(sc, chan, | ||
1883 | conf->channel_type); | ||
1884 | } | ||
1885 | } | ||
1886 | |||
1843 | /**********************/ | 1887 | /**********************/ |
1844 | /* mac80211 callbacks */ | 1888 | /* mac80211 callbacks */ |
1845 | /**********************/ | 1889 | /**********************/ |
@@ -1849,24 +1893,17 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1849 | struct ath_softc *sc = hw->priv; | 1893 | struct ath_softc *sc = hw->priv; |
1850 | struct ieee80211_channel *curchan = hw->conf.channel; | 1894 | struct ieee80211_channel *curchan = hw->conf.channel; |
1851 | struct ath9k_channel *init_channel; | 1895 | struct ath9k_channel *init_channel; |
1852 | int error = 0, pos, status; | 1896 | int r, pos; |
1853 | 1897 | ||
1854 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " | 1898 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " |
1855 | "initial channel: %d MHz\n", curchan->center_freq); | 1899 | "initial channel: %d MHz\n", curchan->center_freq); |
1856 | 1900 | ||
1857 | /* setup initial channel */ | 1901 | /* setup initial channel */ |
1858 | 1902 | ||
1859 | pos = ath_get_channel(sc, curchan); | 1903 | pos = curchan->hw_value; |
1860 | if (pos == -1) { | ||
1861 | DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); | ||
1862 | error = -EINVAL; | ||
1863 | goto error; | ||
1864 | } | ||
1865 | 1904 | ||
1866 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
1867 | sc->sc_ah->ah_channels[pos].chanmode = | ||
1868 | (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; | ||
1869 | init_channel = &sc->sc_ah->ah_channels[pos]; | 1905 | init_channel = &sc->sc_ah->ah_channels[pos]; |
1906 | ath9k_update_ichannel(sc, init_channel); | ||
1870 | 1907 | ||
1871 | /* Reset SERDES registers */ | 1908 | /* Reset SERDES registers */ |
1872 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); | 1909 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); |
@@ -1879,17 +1916,14 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1879 | * and then setup of the interrupt mask. | 1916 | * and then setup of the interrupt mask. |
1880 | */ | 1917 | */ |
1881 | spin_lock_bh(&sc->sc_resetlock); | 1918 | spin_lock_bh(&sc->sc_resetlock); |
1882 | if (!ath9k_hw_reset(sc->sc_ah, init_channel, | 1919 | r = ath9k_hw_reset(sc->sc_ah, init_channel, false); |
1883 | sc->tx_chan_width, | 1920 | if (r) { |
1884 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | ||
1885 | sc->sc_ht_extprotspacing, false, &status)) { | ||
1886 | DPRINTF(sc, ATH_DBG_FATAL, | 1921 | DPRINTF(sc, ATH_DBG_FATAL, |
1887 | "Unable to reset hardware; hal status %u " | 1922 | "Unable to reset hardware; reset status %u " |
1888 | "(freq %u flags 0x%x)\n", status, | 1923 | "(freq %u MHz)\n", r, |
1889 | init_channel->channel, init_channel->channelFlags); | 1924 | curchan->center_freq); |
1890 | error = -EIO; | ||
1891 | spin_unlock_bh(&sc->sc_resetlock); | 1925 | spin_unlock_bh(&sc->sc_resetlock); |
1892 | goto error; | 1926 | return r; |
1893 | } | 1927 | } |
1894 | spin_unlock_bh(&sc->sc_resetlock); | 1928 | spin_unlock_bh(&sc->sc_resetlock); |
1895 | 1929 | ||
@@ -1909,8 +1943,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1909 | if (ath_startrecv(sc) != 0) { | 1943 | if (ath_startrecv(sc) != 0) { |
1910 | DPRINTF(sc, ATH_DBG_FATAL, | 1944 | DPRINTF(sc, ATH_DBG_FATAL, |
1911 | "Unable to start recv logic\n"); | 1945 | "Unable to start recv logic\n"); |
1912 | error = -EIO; | 1946 | return -EIO; |
1913 | goto error; | ||
1914 | } | 1947 | } |
1915 | 1948 | ||
1916 | /* Setup our intr mask. */ | 1949 | /* Setup our intr mask. */ |
@@ -1943,7 +1976,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1943 | !sc->sc_config.swBeaconProcess) | 1976 | !sc->sc_config.swBeaconProcess) |
1944 | sc->sc_imask |= ATH9K_INT_TIM; | 1977 | sc->sc_imask |= ATH9K_INT_TIM; |
1945 | 1978 | ||
1946 | ath_setcurmode(sc, ath_chan2mode(init_channel)); | 1979 | ath_cache_conf_rate(sc, &hw->conf); |
1947 | 1980 | ||
1948 | sc->sc_flags &= ~SC_OP_INVALID; | 1981 | sc->sc_flags &= ~SC_OP_INVALID; |
1949 | 1982 | ||
@@ -1954,11 +1987,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1954 | ieee80211_wake_queues(sc->hw); | 1987 | ieee80211_wake_queues(sc->hw); |
1955 | 1988 | ||
1956 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | 1989 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) |
1957 | error = ath_start_rfkill_poll(sc); | 1990 | r = ath_start_rfkill_poll(sc); |
1958 | #endif | 1991 | #endif |
1959 | 1992 | return r; | |
1960 | error: | ||
1961 | return error; | ||
1962 | } | 1993 | } |
1963 | 1994 | ||
1964 | static int ath9k_tx(struct ieee80211_hw *hw, | 1995 | static int ath9k_tx(struct ieee80211_hw *hw, |
@@ -2031,7 +2062,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2031 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | 2062 | ath9k_hw_set_interrupts(sc->sc_ah, 0); |
2032 | 2063 | ||
2033 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 2064 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
2034 | ath_draintxq(sc, false); | 2065 | ath_drain_all_txq(sc, false); |
2035 | ath_stoprecv(sc); | 2066 | ath_stoprecv(sc); |
2036 | ath9k_hw_phy_disable(sc->sc_ah); | 2067 | ath9k_hw_phy_disable(sc->sc_ah); |
2037 | } else | 2068 | } else |
@@ -2133,38 +2164,38 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2133 | struct ieee80211_conf *conf = &hw->conf; | 2164 | struct ieee80211_conf *conf = &hw->conf; |
2134 | 2165 | ||
2135 | mutex_lock(&sc->mutex); | 2166 | mutex_lock(&sc->mutex); |
2136 | if (changed & (IEEE80211_CONF_CHANGE_CHANNEL | | 2167 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
2137 | IEEE80211_CONF_CHANGE_HT)) { | 2168 | if (conf->flags & IEEE80211_CONF_PS) { |
2169 | if ((sc->sc_imask & ATH9K_INT_TIM_TIMER) == 0) { | ||
2170 | sc->sc_imask |= ATH9K_INT_TIM_TIMER; | ||
2171 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
2172 | sc->sc_imask); | ||
2173 | } | ||
2174 | ath9k_hw_setrxabort(sc->sc_ah, 1); | ||
2175 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | ||
2176 | } else { | ||
2177 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
2178 | ath9k_hw_setrxabort(sc->sc_ah, 0); | ||
2179 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | ||
2180 | if (sc->sc_imask & ATH9K_INT_TIM_TIMER) { | ||
2181 | sc->sc_imask &= ~ATH9K_INT_TIM_TIMER; | ||
2182 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
2183 | sc->sc_imask); | ||
2184 | } | ||
2185 | } | ||
2186 | } | ||
2187 | |||
2188 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | ||
2138 | struct ieee80211_channel *curchan = hw->conf.channel; | 2189 | struct ieee80211_channel *curchan = hw->conf.channel; |
2139 | int pos; | 2190 | int pos = curchan->hw_value; |
2140 | 2191 | ||
2141 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 2192 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
2142 | curchan->center_freq); | 2193 | curchan->center_freq); |
2143 | 2194 | ||
2144 | pos = ath_get_channel(sc, curchan); | 2195 | /* XXX: remove me eventualy */ |
2145 | if (pos == -1) { | 2196 | ath9k_update_ichannel(sc, &sc->sc_ah->ah_channels[pos]); |
2146 | DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", | ||
2147 | curchan->center_freq); | ||
2148 | mutex_unlock(&sc->mutex); | ||
2149 | return -EINVAL; | ||
2150 | } | ||
2151 | |||
2152 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
2153 | sc->sc_ah->ah_channels[pos].chanmode = | ||
2154 | (curchan->band == IEEE80211_BAND_2GHZ) ? | ||
2155 | CHANNEL_G : CHANNEL_A; | ||
2156 | 2197 | ||
2157 | if (conf->ht.enabled) { | 2198 | ath_update_chainmask(sc, conf_is_ht(conf)); |
2158 | if (conf->ht.channel_type == NL80211_CHAN_HT40PLUS || | ||
2159 | conf->ht.channel_type == NL80211_CHAN_HT40MINUS) | ||
2160 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
2161 | |||
2162 | sc->sc_ah->ah_channels[pos].chanmode = | ||
2163 | ath_get_extchanmode(sc, curchan, | ||
2164 | conf->ht.channel_type); | ||
2165 | } | ||
2166 | |||
2167 | ath_update_chainmask(sc, conf->ht.enabled); | ||
2168 | 2199 | ||
2169 | if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { | 2200 | if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { |
2170 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); | 2201 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); |
@@ -2228,24 +2259,27 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, | |||
2228 | } | 2259 | } |
2229 | } | 2260 | } |
2230 | 2261 | ||
2231 | if ((conf->changed & IEEE80211_IFCC_BEACON) && | 2262 | if ((vif->type == NL80211_IFTYPE_ADHOC) || |
2232 | ((vif->type == NL80211_IFTYPE_ADHOC) || | 2263 | (vif->type == NL80211_IFTYPE_AP)) { |
2233 | (vif->type == NL80211_IFTYPE_AP))) { | 2264 | if ((conf->changed & IEEE80211_IFCC_BEACON) || |
2234 | /* | 2265 | (conf->changed & IEEE80211_IFCC_BEACON_ENABLED && |
2235 | * Allocate and setup the beacon frame. | 2266 | conf->enable_beacon)) { |
2236 | * | 2267 | /* |
2237 | * Stop any previous beacon DMA. This may be | 2268 | * Allocate and setup the beacon frame. |
2238 | * necessary, for example, when an ibss merge | 2269 | * |
2239 | * causes reconfiguration; we may be called | 2270 | * Stop any previous beacon DMA. This may be |
2240 | * with beacon transmission active. | 2271 | * necessary, for example, when an ibss merge |
2241 | */ | 2272 | * causes reconfiguration; we may be called |
2242 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 2273 | * with beacon transmission active. |
2274 | */ | ||
2275 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2243 | 2276 | ||
2244 | error = ath_beacon_alloc(sc, 0); | 2277 | error = ath_beacon_alloc(sc, 0); |
2245 | if (error != 0) | 2278 | if (error != 0) |
2246 | return error; | 2279 | return error; |
2247 | 2280 | ||
2248 | ath_beacon_sync(sc, 0); | 2281 | ath_beacon_sync(sc, 0); |
2282 | } | ||
2249 | } | 2283 | } |
2250 | 2284 | ||
2251 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | 2285 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ |
@@ -2348,24 +2382,27 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
2348 | 2382 | ||
2349 | static int ath9k_set_key(struct ieee80211_hw *hw, | 2383 | static int ath9k_set_key(struct ieee80211_hw *hw, |
2350 | enum set_key_cmd cmd, | 2384 | enum set_key_cmd cmd, |
2351 | const u8 *local_addr, | 2385 | struct ieee80211_vif *vif, |
2352 | const u8 *addr, | 2386 | struct ieee80211_sta *sta, |
2353 | struct ieee80211_key_conf *key) | 2387 | struct ieee80211_key_conf *key) |
2354 | { | 2388 | { |
2355 | struct ath_softc *sc = hw->priv; | 2389 | struct ath_softc *sc = hw->priv; |
2356 | int ret = 0; | 2390 | int ret = 0; |
2357 | 2391 | ||
2392 | ath9k_ps_wakeup(sc); | ||
2358 | DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); | 2393 | DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); |
2359 | 2394 | ||
2360 | switch (cmd) { | 2395 | switch (cmd) { |
2361 | case SET_KEY: | 2396 | case SET_KEY: |
2362 | ret = ath_key_config(sc, addr, key); | 2397 | ret = ath_key_config(sc, sta, key); |
2363 | if (ret >= 0) { | 2398 | if (ret >= 0) { |
2364 | key->hw_key_idx = ret; | 2399 | key->hw_key_idx = ret; |
2365 | /* push IV and Michael MIC generation to stack */ | 2400 | /* push IV and Michael MIC generation to stack */ |
2366 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | 2401 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
2367 | if (key->alg == ALG_TKIP) | 2402 | if (key->alg == ALG_TKIP) |
2368 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | 2403 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; |
2404 | if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP) | ||
2405 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; | ||
2369 | ret = 0; | 2406 | ret = 0; |
2370 | } | 2407 | } |
2371 | break; | 2408 | break; |
@@ -2376,6 +2413,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2376 | ret = -EINVAL; | 2413 | ret = -EINVAL; |
2377 | } | 2414 | } |
2378 | 2415 | ||
2416 | ath9k_ps_restore(sc); | ||
2379 | return ret; | 2417 | return ret; |
2380 | } | 2418 | } |
2381 | 2419 | ||
@@ -2423,6 +2461,14 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw) | |||
2423 | return tsf; | 2461 | return tsf; |
2424 | } | 2462 | } |
2425 | 2463 | ||
2464 | static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | ||
2465 | { | ||
2466 | struct ath_softc *sc = hw->priv; | ||
2467 | struct ath_hal *ah = sc->sc_ah; | ||
2468 | |||
2469 | ath9k_hw_settsf64(ah, tsf); | ||
2470 | } | ||
2471 | |||
2426 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) | 2472 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) |
2427 | { | 2473 | { |
2428 | struct ath_softc *sc = hw->priv; | 2474 | struct ath_softc *sc = hw->priv; |
@@ -2472,7 +2518,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2472 | return ret; | 2518 | return ret; |
2473 | } | 2519 | } |
2474 | 2520 | ||
2475 | static struct ieee80211_ops ath9k_ops = { | 2521 | struct ieee80211_ops ath9k_ops = { |
2476 | .tx = ath9k_tx, | 2522 | .tx = ath9k_tx, |
2477 | .start = ath9k_start, | 2523 | .start = ath9k_start, |
2478 | .stop = ath9k_stop, | 2524 | .stop = ath9k_stop, |
@@ -2486,6 +2532,7 @@ static struct ieee80211_ops ath9k_ops = { | |||
2486 | .bss_info_changed = ath9k_bss_info_changed, | 2532 | .bss_info_changed = ath9k_bss_info_changed, |
2487 | .set_key = ath9k_set_key, | 2533 | .set_key = ath9k_set_key, |
2488 | .get_tsf = ath9k_get_tsf, | 2534 | .get_tsf = ath9k_get_tsf, |
2535 | .set_tsf = ath9k_set_tsf, | ||
2489 | .reset_tsf = ath9k_reset_tsf, | 2536 | .reset_tsf = ath9k_reset_tsf, |
2490 | .ampdu_action = ath9k_ampdu_action, | 2537 | .ampdu_action = ath9k_ampdu_action, |
2491 | }; | 2538 | }; |
@@ -2516,7 +2563,7 @@ static struct { | |||
2516 | /* | 2563 | /* |
2517 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. | 2564 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. |
2518 | */ | 2565 | */ |
2519 | static const char * | 2566 | const char * |
2520 | ath_mac_bb_name(u32 mac_bb_version) | 2567 | ath_mac_bb_name(u32 mac_bb_version) |
2521 | { | 2568 | { |
2522 | int i; | 2569 | int i; |
@@ -2533,7 +2580,7 @@ ath_mac_bb_name(u32 mac_bb_version) | |||
2533 | /* | 2580 | /* |
2534 | * Return the RF name. "????" is returned if the RF is unknown. | 2581 | * Return the RF name. "????" is returned if the RF is unknown. |
2535 | */ | 2582 | */ |
2536 | static const char * | 2583 | const char * |
2537 | ath_rf_name(u16 rf_version) | 2584 | ath_rf_name(u16 rf_version) |
2538 | { | 2585 | { |
2539 | int i; | 2586 | int i; |
@@ -2547,254 +2594,51 @@ ath_rf_name(u16 rf_version) | |||
2547 | return "????"; | 2594 | return "????"; |
2548 | } | 2595 | } |
2549 | 2596 | ||
2550 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 2597 | static int __init ath9k_init(void) |
2551 | { | ||
2552 | void __iomem *mem; | ||
2553 | struct ath_softc *sc; | ||
2554 | struct ieee80211_hw *hw; | ||
2555 | u8 csz; | ||
2556 | u32 val; | ||
2557 | int ret = 0; | ||
2558 | struct ath_hal *ah; | ||
2559 | |||
2560 | if (pci_enable_device(pdev)) | ||
2561 | return -EIO; | ||
2562 | |||
2563 | ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
2564 | |||
2565 | if (ret) { | ||
2566 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); | ||
2567 | goto bad; | ||
2568 | } | ||
2569 | |||
2570 | ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
2571 | |||
2572 | if (ret) { | ||
2573 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | ||
2574 | "DMA enable failed\n"); | ||
2575 | goto bad; | ||
2576 | } | ||
2577 | |||
2578 | /* | ||
2579 | * Cache line size is used to size and align various | ||
2580 | * structures used to communicate with the hardware. | ||
2581 | */ | ||
2582 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); | ||
2583 | if (csz == 0) { | ||
2584 | /* | ||
2585 | * Linux 2.4.18 (at least) writes the cache line size | ||
2586 | * register as a 16-bit wide register which is wrong. | ||
2587 | * We must have this setup properly for rx buffer | ||
2588 | * DMA to work so force a reasonable value here if it | ||
2589 | * comes up zero. | ||
2590 | */ | ||
2591 | csz = L1_CACHE_BYTES / sizeof(u32); | ||
2592 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); | ||
2593 | } | ||
2594 | /* | ||
2595 | * The default setting of latency timer yields poor results, | ||
2596 | * set it to the value used by other systems. It may be worth | ||
2597 | * tweaking this setting more. | ||
2598 | */ | ||
2599 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); | ||
2600 | |||
2601 | pci_set_master(pdev); | ||
2602 | |||
2603 | /* | ||
2604 | * Disable the RETRY_TIMEOUT register (0x41) to keep | ||
2605 | * PCI Tx retries from interfering with C3 CPU state. | ||
2606 | */ | ||
2607 | pci_read_config_dword(pdev, 0x40, &val); | ||
2608 | if ((val & 0x0000ff00) != 0) | ||
2609 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); | ||
2610 | |||
2611 | ret = pci_request_region(pdev, 0, "ath9k"); | ||
2612 | if (ret) { | ||
2613 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); | ||
2614 | ret = -ENODEV; | ||
2615 | goto bad; | ||
2616 | } | ||
2617 | |||
2618 | mem = pci_iomap(pdev, 0, 0); | ||
2619 | if (!mem) { | ||
2620 | printk(KERN_ERR "PCI memory map error\n") ; | ||
2621 | ret = -EIO; | ||
2622 | goto bad1; | ||
2623 | } | ||
2624 | |||
2625 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); | ||
2626 | if (hw == NULL) { | ||
2627 | printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n"); | ||
2628 | goto bad2; | ||
2629 | } | ||
2630 | |||
2631 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
2632 | pci_set_drvdata(pdev, hw); | ||
2633 | |||
2634 | sc = hw->priv; | ||
2635 | sc->hw = hw; | ||
2636 | sc->pdev = pdev; | ||
2637 | sc->mem = mem; | ||
2638 | |||
2639 | if (ath_attach(id->device, sc) != 0) { | ||
2640 | ret = -ENODEV; | ||
2641 | goto bad3; | ||
2642 | } | ||
2643 | |||
2644 | /* setup interrupt service routine */ | ||
2645 | |||
2646 | if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) { | ||
2647 | printk(KERN_ERR "%s: request_irq failed\n", | ||
2648 | wiphy_name(hw->wiphy)); | ||
2649 | ret = -EIO; | ||
2650 | goto bad4; | ||
2651 | } | ||
2652 | |||
2653 | ah = sc->sc_ah; | ||
2654 | printk(KERN_INFO | ||
2655 | "%s: Atheros AR%s MAC/BB Rev:%x " | ||
2656 | "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n", | ||
2657 | wiphy_name(hw->wiphy), | ||
2658 | ath_mac_bb_name(ah->ah_macVersion), | ||
2659 | ah->ah_macRev, | ||
2660 | ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)), | ||
2661 | ah->ah_phyRev, | ||
2662 | (unsigned long)mem, pdev->irq); | ||
2663 | |||
2664 | return 0; | ||
2665 | bad4: | ||
2666 | ath_detach(sc); | ||
2667 | bad3: | ||
2668 | ieee80211_free_hw(hw); | ||
2669 | bad2: | ||
2670 | pci_iounmap(pdev, mem); | ||
2671 | bad1: | ||
2672 | pci_release_region(pdev, 0); | ||
2673 | bad: | ||
2674 | pci_disable_device(pdev); | ||
2675 | return ret; | ||
2676 | } | ||
2677 | |||
2678 | static void ath_pci_remove(struct pci_dev *pdev) | ||
2679 | { | ||
2680 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
2681 | struct ath_softc *sc = hw->priv; | ||
2682 | |||
2683 | ath_detach(sc); | ||
2684 | if (pdev->irq) | ||
2685 | free_irq(pdev->irq, sc); | ||
2686 | pci_iounmap(pdev, sc->mem); | ||
2687 | pci_release_region(pdev, 0); | ||
2688 | pci_disable_device(pdev); | ||
2689 | ieee80211_free_hw(hw); | ||
2690 | } | ||
2691 | |||
2692 | #ifdef CONFIG_PM | ||
2693 | |||
2694 | static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
2695 | { | ||
2696 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
2697 | struct ath_softc *sc = hw->priv; | ||
2698 | |||
2699 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
2700 | |||
2701 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2702 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
2703 | cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); | ||
2704 | #endif | ||
2705 | |||
2706 | pci_save_state(pdev); | ||
2707 | pci_disable_device(pdev); | ||
2708 | pci_set_power_state(pdev, 3); | ||
2709 | |||
2710 | return 0; | ||
2711 | } | ||
2712 | |||
2713 | static int ath_pci_resume(struct pci_dev *pdev) | ||
2714 | { | ||
2715 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
2716 | struct ath_softc *sc = hw->priv; | ||
2717 | u32 val; | ||
2718 | int err; | ||
2719 | |||
2720 | err = pci_enable_device(pdev); | ||
2721 | if (err) | ||
2722 | return err; | ||
2723 | pci_restore_state(pdev); | ||
2724 | /* | ||
2725 | * Suspend/Resume resets the PCI configuration space, so we have to | ||
2726 | * re-disable the RETRY_TIMEOUT register (0x41) to keep | ||
2727 | * PCI Tx retries from interfering with C3 CPU state | ||
2728 | */ | ||
2729 | pci_read_config_dword(pdev, 0x40, &val); | ||
2730 | if ((val & 0x0000ff00) != 0) | ||
2731 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); | ||
2732 | |||
2733 | /* Enable LED */ | ||
2734 | ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN, | ||
2735 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
2736 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
2737 | |||
2738 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2739 | /* | ||
2740 | * check the h/w rfkill state on resume | ||
2741 | * and start the rfkill poll timer | ||
2742 | */ | ||
2743 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
2744 | queue_delayed_work(sc->hw->workqueue, | ||
2745 | &sc->rf_kill.rfkill_poll, 0); | ||
2746 | #endif | ||
2747 | |||
2748 | return 0; | ||
2749 | } | ||
2750 | |||
2751 | #endif /* CONFIG_PM */ | ||
2752 | |||
2753 | MODULE_DEVICE_TABLE(pci, ath_pci_id_table); | ||
2754 | |||
2755 | static struct pci_driver ath_pci_driver = { | ||
2756 | .name = "ath9k", | ||
2757 | .id_table = ath_pci_id_table, | ||
2758 | .probe = ath_pci_probe, | ||
2759 | .remove = ath_pci_remove, | ||
2760 | #ifdef CONFIG_PM | ||
2761 | .suspend = ath_pci_suspend, | ||
2762 | .resume = ath_pci_resume, | ||
2763 | #endif /* CONFIG_PM */ | ||
2764 | }; | ||
2765 | |||
2766 | static int __init init_ath_pci(void) | ||
2767 | { | 2598 | { |
2768 | int error; | 2599 | int error; |
2769 | 2600 | ||
2770 | printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION); | ||
2771 | |||
2772 | /* Register rate control algorithm */ | 2601 | /* Register rate control algorithm */ |
2773 | error = ath_rate_control_register(); | 2602 | error = ath_rate_control_register(); |
2774 | if (error != 0) { | 2603 | if (error != 0) { |
2775 | printk(KERN_ERR | 2604 | printk(KERN_ERR |
2776 | "Unable to register rate control algorithm: %d\n", | 2605 | "ath9k: Unable to register rate control " |
2606 | "algorithm: %d\n", | ||
2777 | error); | 2607 | error); |
2778 | ath_rate_control_unregister(); | 2608 | goto err_out; |
2779 | return error; | ||
2780 | } | 2609 | } |
2781 | 2610 | ||
2782 | if (pci_register_driver(&ath_pci_driver) < 0) { | 2611 | error = ath_pci_init(); |
2612 | if (error < 0) { | ||
2783 | printk(KERN_ERR | 2613 | printk(KERN_ERR |
2784 | "ath_pci: No devices found, driver not installed.\n"); | 2614 | "ath9k: No PCI devices found, driver not installed.\n"); |
2785 | ath_rate_control_unregister(); | 2615 | error = -ENODEV; |
2786 | pci_unregister_driver(&ath_pci_driver); | 2616 | goto err_rate_unregister; |
2787 | return -ENODEV; | 2617 | } |
2618 | |||
2619 | error = ath_ahb_init(); | ||
2620 | if (error < 0) { | ||
2621 | error = -ENODEV; | ||
2622 | goto err_pci_exit; | ||
2788 | } | 2623 | } |
2789 | 2624 | ||
2790 | return 0; | 2625 | return 0; |
2626 | |||
2627 | err_pci_exit: | ||
2628 | ath_pci_exit(); | ||
2629 | |||
2630 | err_rate_unregister: | ||
2631 | ath_rate_control_unregister(); | ||
2632 | err_out: | ||
2633 | return error; | ||
2791 | } | 2634 | } |
2792 | module_init(init_ath_pci); | 2635 | module_init(ath9k_init); |
2793 | 2636 | ||
2794 | static void __exit exit_ath_pci(void) | 2637 | static void __exit ath9k_exit(void) |
2795 | { | 2638 | { |
2639 | ath_ahb_exit(); | ||
2640 | ath_pci_exit(); | ||
2796 | ath_rate_control_unregister(); | 2641 | ath_rate_control_unregister(); |
2797 | pci_unregister_driver(&ath_pci_driver); | ||
2798 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | 2642 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); |
2799 | } | 2643 | } |
2800 | module_exit(exit_ath_pci); | 2644 | module_exit(ath9k_exit); |