Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2008-2011 Atheros Communications Inc.
3 : : *
4 : : * Permission to use, copy, modify, and/or distribute this software for any
5 : : * purpose with or without fee is hereby granted, provided that the above
6 : : * copyright notice and this permission notice appear in all copies.
7 : : *
8 : : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 : : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 : : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 : : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 : : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 : : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 : : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 : : */
16 : :
17 : : #include <linux/nl80211.h>
18 : : #include <linux/delay.h>
19 : : #include "ath9k.h"
20 : : #include "btcoex.h"
21 : :
22 : 0 : u8 ath9k_parse_mpdudensity(u8 mpdudensity)
23 : : {
24 : : /*
25 : : * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
26 : : * 0 for no restriction
27 : : * 1 for 1/4 us
28 : : * 2 for 1/2 us
29 : : * 3 for 1 us
30 : : * 4 for 2 us
31 : : * 5 for 4 us
32 : : * 6 for 8 us
33 : : * 7 for 16 us
34 : : */
35 [ # # ]: 0 : switch (mpdudensity) {
36 : : case 0:
37 : : return 0;
38 : : case 1:
39 : : case 2:
40 : : case 3:
41 : : /* Our lower layer calculations limit our precision to
42 : : 1 microsecond */
43 : : return 1;
44 : : case 4:
45 : : return 2;
46 : : case 5:
47 : : return 4;
48 : : case 6:
49 : : return 8;
50 : : case 7:
51 : : return 16;
52 : : default:
53 : : return 0;
54 : : }
55 : : }
56 : :
57 : 0 : static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq,
58 : : bool sw_pending)
59 : : {
60 : 0 : bool pending = false;
61 : :
62 : 0 : spin_lock_bh(&txq->axq_lock);
63 : :
64 [ # # ]: 0 : if (txq->axq_depth) {
65 : 0 : pending = true;
66 : 0 : goto out;
67 : : }
68 : :
69 [ # # ]: 0 : if (!sw_pending)
70 : 0 : goto out;
71 : :
72 [ # # ]: 0 : if (txq->mac80211_qnum >= 0) {
73 : 0 : struct ath_acq *acq;
74 : :
75 : 0 : acq = &sc->cur_chan->acq[txq->mac80211_qnum];
76 [ # # # # ]: 0 : if (!list_empty(&acq->acq_new) || !list_empty(&acq->acq_old))
77 : : pending = true;
78 : : }
79 : 0 : out:
80 : 0 : spin_unlock_bh(&txq->axq_lock);
81 : 0 : return pending;
82 : : }
83 : :
84 : 0 : static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
85 : : {
86 : 0 : unsigned long flags;
87 : 0 : bool ret;
88 : :
89 : 0 : spin_lock_irqsave(&sc->sc_pm_lock, flags);
90 : 0 : ret = ath9k_hw_setpower(sc->sc_ah, mode);
91 : 0 : spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
92 : :
93 : 0 : return ret;
94 : : }
95 : :
96 : 31 : void ath_ps_full_sleep(struct timer_list *t)
97 : : {
98 : 31 : struct ath_softc *sc = from_timer(sc, t, sleep_timer);
99 : 31 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
100 : 31 : unsigned long flags;
101 : 31 : bool reset;
102 : :
103 : 31 : spin_lock_irqsave(&common->cc_lock, flags);
104 : 31 : ath_hw_cycle_counters_update(common);
105 : 31 : spin_unlock_irqrestore(&common->cc_lock, flags);
106 : :
107 : 31 : ath9k_hw_setrxabort(sc->sc_ah, 1);
108 : 31 : ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
109 : :
110 : 31 : ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
111 : 31 : }
112 : :
113 : 238 : void ath9k_ps_wakeup(struct ath_softc *sc)
114 : : {
115 : 238 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
116 : 238 : unsigned long flags;
117 : 238 : enum ath9k_power_mode power_mode;
118 : :
119 : 238 : spin_lock_irqsave(&sc->sc_pm_lock, flags);
120 [ + + ]: 238 : if (++sc->ps_usecount != 1)
121 : 65 : goto unlock;
122 : :
123 : 173 : del_timer_sync(&sc->sleep_timer);
124 : 173 : power_mode = sc->sc_ah->power_mode;
125 : 173 : ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
126 : :
127 : : /*
128 : : * While the hardware is asleep, the cycle counters contain no
129 : : * useful data. Better clear them now so that they don't mess up
130 : : * survey data results.
131 : : */
132 [ + + ]: 173 : if (power_mode != ATH9K_PM_AWAKE) {
133 : 26 : spin_lock(&common->cc_lock);
134 : 26 : ath_hw_cycle_counters_update(common);
135 : 26 : memset(&common->cc_survey, 0, sizeof(common->cc_survey));
136 : 26 : memset(&common->cc_ani, 0, sizeof(common->cc_ani));
137 : 26 : spin_unlock(&common->cc_lock);
138 : : }
139 : :
140 : 147 : unlock:
141 : 238 : spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
142 : 238 : }
143 : :
144 : 238 : void ath9k_ps_restore(struct ath_softc *sc)
145 : : {
146 : 238 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
147 : 238 : enum ath9k_power_mode mode;
148 : 238 : unsigned long flags;
149 : :
150 : 238 : spin_lock_irqsave(&sc->sc_pm_lock, flags);
151 [ + + ]: 238 : if (--sc->ps_usecount != 0)
152 : 65 : goto unlock;
153 : :
154 [ + + ]: 173 : if (sc->ps_idle) {
155 : 109 : mod_timer(&sc->sleep_timer, jiffies + HZ / 10);
156 : 109 : goto unlock;
157 : : }
158 : :
159 [ - + ]: 64 : if (sc->ps_enabled &&
160 [ # # ]: 0 : !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
161 : : PS_WAIT_FOR_CAB |
162 : : PS_WAIT_FOR_PSPOLL_DATA |
163 : : PS_WAIT_FOR_TX_ACK |
164 : : PS_WAIT_FOR_ANI))) {
165 : 0 : mode = ATH9K_PM_NETWORK_SLEEP;
166 [ # # ]: 0 : if (ath9k_hw_btcoex_is_enabled(sc->sc_ah))
167 : 0 : ath9k_btcoex_stop_gen_timer(sc);
168 : : } else {
169 : 64 : goto unlock;
170 : : }
171 : :
172 : 0 : spin_lock(&common->cc_lock);
173 : 0 : ath_hw_cycle_counters_update(common);
174 : 0 : spin_unlock(&common->cc_lock);
175 : :
176 : 0 : ath9k_hw_setpower(sc->sc_ah, mode);
177 : :
178 : 238 : unlock:
179 : 238 : spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
180 : 238 : }
181 : :
182 : 59 : static void __ath_cancel_work(struct ath_softc *sc)
183 : : {
184 : 59 : cancel_work_sync(&sc->paprd_work);
185 : 59 : cancel_delayed_work_sync(&sc->hw_check_work);
186 : 59 : cancel_delayed_work_sync(&sc->hw_pll_work);
187 : :
188 : : #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
189 [ - + - + ]: 118 : if (ath9k_hw_mci_is_enabled(sc->sc_ah))
190 : 0 : cancel_work_sync(&sc->mci_work);
191 : : #endif
192 : 59 : }
193 : :
194 : 6 : void ath_cancel_work(struct ath_softc *sc)
195 : : {
196 : 0 : __ath_cancel_work(sc);
197 : 6 : cancel_work_sync(&sc->hw_reset_work);
198 : 0 : }
199 : :
200 : 53 : void ath_restart_work(struct ath_softc *sc)
201 : : {
202 : 53 : ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
203 : : ATH_HW_CHECK_POLL_INT);
204 : :
205 [ + - - + ]: 53 : if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah))
206 : 0 : ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
207 : : msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
208 : :
209 : 53 : ath_start_ani(sc);
210 : 53 : }
211 : :
212 : 53 : static bool ath_prepare_reset(struct ath_softc *sc)
213 : : {
214 : 53 : struct ath_hw *ah = sc->sc_ah;
215 : 53 : bool ret = true;
216 : :
217 : 53 : ieee80211_stop_queues(sc->hw);
218 : 53 : ath_stop_ani(sc);
219 : 53 : ath9k_hw_disable_interrupts(ah);
220 : :
221 [ + + ]: 53 : if (AR_SREV_9300_20_OR_LATER(ah)) {
222 : 35 : ret &= ath_stoprecv(sc);
223 : 35 : ret &= ath_drain_all_txq(sc);
224 : : } else {
225 : 18 : ret &= ath_drain_all_txq(sc);
226 : 18 : ret &= ath_stoprecv(sc);
227 : : }
228 : :
229 : 53 : return ret;
230 : : }
231 : :
232 : 59 : static bool ath_complete_reset(struct ath_softc *sc, bool start)
233 : : {
234 : 59 : struct ath_hw *ah = sc->sc_ah;
235 : 59 : struct ath_common *common = ath9k_hw_common(ah);
236 : 59 : unsigned long flags;
237 : :
238 : 59 : ath9k_calculate_summary_state(sc, sc->cur_chan);
239 : 59 : ath_startrecv(sc);
240 : 59 : ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
241 : 59 : sc->cur_chan->txpower,
242 : 59 : &sc->cur_chan->cur_txpower);
243 : 59 : clear_bit(ATH_OP_HW_RESET, &common->op_flags);
244 : :
245 [ + - + + ]: 59 : if (!sc->cur_chan->offchannel && start) {
246 : : /* restore per chanctx TSF timer */
247 [ - + ]: 53 : if (sc->cur_chan->tsf_val) {
248 : 0 : u32 offset;
249 : :
250 : 0 : offset = ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts,
251 : : NULL);
252 : 0 : ath9k_hw_settsf64(ah, sc->cur_chan->tsf_val + offset);
253 : : }
254 : :
255 : :
256 [ + - ]: 53 : if (!test_bit(ATH_OP_BEACONS, &common->op_flags))
257 : 53 : goto work;
258 : :
259 [ # # # # ]: 0 : if (ah->opmode == NL80211_IFTYPE_STATION &&
260 : : test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) {
261 : 0 : spin_lock_irqsave(&sc->sc_pm_lock, flags);
262 : 0 : sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
263 : 0 : spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
264 : : } else {
265 : 0 : ath9k_set_beacon(sc);
266 : : }
267 : 53 : work:
268 : 53 : ath_restart_work(sc);
269 : 53 : ath_txq_schedule_all(sc);
270 : : }
271 : :
272 : 59 : sc->gtt_cnt = 0;
273 : :
274 : 59 : ath9k_hw_set_interrupts(ah);
275 : 59 : ath9k_hw_enable_interrupts(ah);
276 : 59 : ieee80211_wake_queues(sc->hw);
277 : 59 : ath9k_p2p_ps_timer(sc);
278 : :
279 : 59 : return true;
280 : : }
281 : :
282 : 53 : static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
283 : : {
284 : 53 : struct ath_hw *ah = sc->sc_ah;
285 : 53 : struct ath_common *common = ath9k_hw_common(ah);
286 : 53 : struct ath9k_hw_cal_data *caldata = NULL;
287 : 53 : bool fastcc = true;
288 : 53 : int r;
289 : :
290 : 53 : __ath_cancel_work(sc);
291 : :
292 : 53 : disable_irq(sc->irq);
293 : 53 : tasklet_disable(&sc->intr_tq);
294 : 53 : tasklet_disable(&sc->bcon_tasklet);
295 : 53 : spin_lock_bh(&sc->sc_pcu_lock);
296 : :
297 [ + - ]: 53 : if (!sc->cur_chan->offchannel) {
298 : 53 : fastcc = false;
299 : 53 : caldata = &sc->cur_chan->caldata;
300 : : }
301 : :
302 [ + + ]: 53 : if (!hchan) {
303 : 47 : fastcc = false;
304 : 47 : hchan = ah->curchan;
305 : : }
306 : :
307 [ - + ]: 53 : if (!ath_prepare_reset(sc))
308 : 0 : fastcc = false;
309 : :
310 : 53 : if (ath9k_is_chanctx_enabled())
311 : : fastcc = false;
312 : :
313 : 53 : spin_lock_bh(&sc->chan_lock);
314 : 53 : sc->cur_chandef = sc->cur_chan->chandef;
315 : 53 : spin_unlock_bh(&sc->chan_lock);
316 : :
317 [ - + ]: 53 : ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
318 : : hchan->channel, IS_CHAN_HT40(hchan), fastcc);
319 : :
320 : 53 : r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
321 [ - + ]: 53 : if (r) {
322 : 0 : ath_err(common,
323 : : "Unable to reset channel, reset status %d\n", r);
324 : :
325 : 0 : ath9k_hw_enable_interrupts(ah);
326 : 0 : ath9k_queue_reset(sc, RESET_TYPE_BB_HANG);
327 : :
328 : 0 : goto out;
329 : : }
330 : :
331 [ - + - + ]: 106 : if (ath9k_hw_mci_is_enabled(sc->sc_ah) &&
332 [ # # ]: 0 : sc->cur_chan->offchannel)
333 : 0 : ath9k_mci_set_txpower(sc, true, false);
334 : :
335 [ + - ]: 53 : if (!ath_complete_reset(sc, true))
336 : 0 : r = -EIO;
337 : :
338 : 53 : out:
339 : 53 : enable_irq(sc->irq);
340 : 53 : spin_unlock_bh(&sc->sc_pcu_lock);
341 : 53 : tasklet_enable(&sc->bcon_tasklet);
342 : 53 : tasklet_enable(&sc->intr_tq);
343 : :
344 : 53 : return r;
345 : : }
346 : :
347 : 0 : static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
348 : : struct ieee80211_vif *vif)
349 : : {
350 : 0 : struct ath_node *an;
351 : 0 : an = (struct ath_node *)sta->drv_priv;
352 : :
353 : 0 : an->sc = sc;
354 : 0 : an->sta = sta;
355 : 0 : an->vif = vif;
356 : 0 : memset(&an->key_idx, 0, sizeof(an->key_idx));
357 : :
358 : 0 : ath_tx_node_init(sc, an);
359 : :
360 : 0 : ath_dynack_node_init(sc->sc_ah, an);
361 : 0 : }
362 : :
363 : 0 : static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
364 : : {
365 : 0 : struct ath_node *an = (struct ath_node *)sta->drv_priv;
366 : 0 : ath_tx_node_cleanup(sc, an);
367 : :
368 [ # # ]: 0 : ath_dynack_node_deinit(sc->sc_ah, an);
369 : : }
370 : :
371 : 48 : void ath9k_tasklet(unsigned long data)
372 : : {
373 : 48 : struct ath_softc *sc = (struct ath_softc *)data;
374 : 48 : struct ath_hw *ah = sc->sc_ah;
375 : 48 : struct ath_common *common = ath9k_hw_common(ah);
376 : 48 : enum ath_reset_type type;
377 : 48 : unsigned long flags;
378 : 48 : u32 status;
379 : 48 : u32 rxmask;
380 : :
381 : 48 : spin_lock_irqsave(&sc->intr_lock, flags);
382 : 48 : status = sc->intrstatus;
383 : 48 : sc->intrstatus = 0;
384 : 48 : spin_unlock_irqrestore(&sc->intr_lock, flags);
385 : :
386 : 48 : ath9k_ps_wakeup(sc);
387 : 48 : spin_lock(&sc->sc_pcu_lock);
388 : :
389 [ + + ]: 48 : if (status & ATH9K_INT_FATAL) {
390 : 46 : type = RESET_TYPE_FATAL_INT;
391 : 46 : ath9k_queue_reset(sc, type);
392 [ - + ]: 46 : ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
393 : 46 : goto out;
394 : : }
395 : :
396 [ + - ]: 2 : if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) &&
397 [ + + ]: 2 : (status & ATH9K_INT_BB_WATCHDOG)) {
398 : 1 : spin_lock_irqsave(&common->cc_lock, flags);
399 : 1 : ath_hw_cycle_counters_update(common);
400 : 1 : ar9003_hw_bb_watchdog_dbg_info(ah);
401 : 1 : spin_unlock_irqrestore(&common->cc_lock, flags);
402 : :
403 [ + - ]: 1 : if (ar9003_hw_bb_watchdog_check(ah)) {
404 : 1 : type = RESET_TYPE_BB_WATCHDOG;
405 : 1 : ath9k_queue_reset(sc, type);
406 : :
407 [ - + ]: 1 : ath_dbg(common, RESET,
408 : : "BB_WATCHDOG: Skipping interrupts\n");
409 : 1 : goto out;
410 : : }
411 : : }
412 : :
413 [ - + ]: 1 : if (status & ATH9K_INT_GTT) {
414 : 0 : sc->gtt_cnt++;
415 : :
416 [ # # # # ]: 0 : if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
417 : 0 : type = RESET_TYPE_TX_GTT;
418 : 0 : ath9k_queue_reset(sc, type);
419 [ # # ]: 0 : ath_dbg(common, RESET,
420 : : "GTT: Skipping interrupts\n");
421 : 0 : goto out;
422 : : }
423 : : }
424 : :
425 : 1 : spin_lock_irqsave(&sc->sc_pm_lock, flags);
426 [ - + - - ]: 1 : if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
427 : : /*
428 : : * TSF sync does not look correct; remain awake to sync with
429 : : * the next Beacon.
430 : : */
431 [ # # ]: 0 : ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n");
432 : 0 : sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
433 : : }
434 : 1 : spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
435 : :
436 [ - + ]: 1 : if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
437 : : rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
438 : : ATH9K_INT_RXORN);
439 : : else
440 : 0 : rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
441 : :
442 [ + - ]: 1 : if (status & rxmask) {
443 : : /* Check for high priority Rx first */
444 [ + - ]: 1 : if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
445 [ + - ]: 1 : (status & ATH9K_INT_RXHP))
446 : 1 : ath_rx_tasklet(sc, 0, true);
447 : :
448 : 1 : ath_rx_tasklet(sc, 0, false);
449 : : }
450 : :
451 [ + - ]: 1 : if (status & ATH9K_INT_TX) {
452 [ + - ]: 1 : if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
453 : : /*
454 : : * For EDMA chips, TX completion is enabled for the
455 : : * beacon queue, so if a beacon has been transmitted
456 : : * successfully after a GTT interrupt, the GTT counter
457 : : * gets reset to zero here.
458 : : */
459 : 1 : sc->gtt_cnt = 0;
460 : :
461 : 1 : ath_tx_edma_tasklet(sc);
462 : : } else {
463 : 0 : ath_tx_tasklet(sc);
464 : : }
465 : :
466 : 1 : wake_up(&sc->tx_wait);
467 : : }
468 : :
469 [ - + ]: 1 : if (status & ATH9K_INT_GENTIMER)
470 : 0 : ath_gen_timer_isr(sc->sc_ah);
471 : :
472 : 1 : ath9k_btcoex_handle_interrupt(sc, status);
473 : :
474 : : /* re-enable hardware interrupt */
475 : 1 : ath9k_hw_resume_interrupts(ah);
476 : 48 : out:
477 : 48 : spin_unlock(&sc->sc_pcu_lock);
478 : 48 : ath9k_ps_restore(sc);
479 : 48 : }
480 : :
481 : 2700239 : irqreturn_t ath_isr(int irq, void *dev)
482 : : {
483 : : #define SCHED_INTR ( \
484 : : ATH9K_INT_FATAL | \
485 : : ATH9K_INT_BB_WATCHDOG | \
486 : : ATH9K_INT_RXORN | \
487 : : ATH9K_INT_RXEOL | \
488 : : ATH9K_INT_RX | \
489 : : ATH9K_INT_RXLP | \
490 : : ATH9K_INT_RXHP | \
491 : : ATH9K_INT_TX | \
492 : : ATH9K_INT_BMISS | \
493 : : ATH9K_INT_CST | \
494 : : ATH9K_INT_GTT | \
495 : : ATH9K_INT_TSFOOR | \
496 : : ATH9K_INT_GENTIMER | \
497 : : ATH9K_INT_MCI)
498 : :
499 : 2700239 : struct ath_softc *sc = dev;
500 : 2700239 : struct ath_hw *ah = sc->sc_ah;
501 [ + - ]: 2700239 : struct ath_common *common = ath9k_hw_common(ah);
502 : 2700239 : enum ath9k_int status;
503 : 2700239 : u32 sync_cause = 0;
504 : 2700239 : bool sched = false;
505 : :
506 : : /*
507 : : * The hardware is not ready/present, don't
508 : : * touch anything. Note this can happen early
509 : : * on if the IRQ is shared.
510 : : */
511 [ + - + + ]: 2700239 : if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags))
512 : 2700063 : return IRQ_NONE;
513 : :
514 : : /* shared irq, not for us */
515 [ + + ]: 176 : if (!ath9k_hw_intrpend(ah))
516 : : return IRQ_NONE;
517 : :
518 : : /*
519 : : * Figure out the reason(s) for the interrupt. Note
520 : : * that the hal returns a pseudo-ISR that may include
521 : : * bits we haven't explicitly enabled so we mask the
522 : : * value to insure we only process bits we requested.
523 : : */
524 : 131 : ath9k_hw_getisr(ah, &status, &sync_cause); /* NB: clears ISR too */
525 : 131 : ath9k_debug_sync_cause(sc, sync_cause);
526 : 131 : status &= ah->imask; /* discard unasked-for bits */
527 : :
528 [ + - ]: 131 : if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
529 : : return IRQ_HANDLED;
530 : :
531 : : /*
532 : : * If there are no status bits set, then this interrupt was not
533 : : * for me (should have been caught above).
534 : : */
535 [ + + ]: 131 : if (!status)
536 : : return IRQ_NONE;
537 : :
538 : : /* Cache the status */
539 : 48 : spin_lock(&sc->intr_lock);
540 : 48 : sc->intrstatus |= status;
541 : 48 : spin_unlock(&sc->intr_lock);
542 : :
543 [ + - ]: 48 : if (status & SCHED_INTR)
544 : 48 : sched = true;
545 : :
546 : : /*
547 : : * If a FATAL interrupt is received, we have to reset the chip
548 : : * immediately.
549 : : */
550 [ + + ]: 48 : if (status & ATH9K_INT_FATAL)
551 : 46 : goto chip_reset;
552 : :
553 [ + - ]: 2 : if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) &&
554 [ + + ]: 2 : (status & ATH9K_INT_BB_WATCHDOG))
555 : 1 : goto chip_reset;
556 : :
557 [ - + ]: 1 : if (status & ATH9K_INT_SWBA)
558 : 0 : tasklet_schedule(&sc->bcon_tasklet);
559 : :
560 [ - + ]: 1 : if (status & ATH9K_INT_TXURN)
561 : 0 : ath9k_hw_updatetxtriglevel(ah, true);
562 : :
563 [ + - ]: 1 : if (status & ATH9K_INT_RXEOL) {
564 : 1 : ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
565 : 1 : ath9k_hw_set_interrupts(ah);
566 : : }
567 : :
568 [ + - ]: 1 : if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
569 [ # # ]: 0 : if (status & ATH9K_INT_TIM_TIMER) {
570 [ # # # # ]: 0 : if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle))
571 : 0 : goto chip_reset;
572 : : /* Clear RxAbort bit so that we can
573 : : * receive frames */
574 : 0 : ath9k_setpower(sc, ATH9K_PM_AWAKE);
575 : 0 : spin_lock(&sc->sc_pm_lock);
576 : 0 : ath9k_hw_setrxabort(sc->sc_ah, 0);
577 : 0 : sc->ps_flags |= PS_WAIT_FOR_BEACON;
578 : 0 : spin_unlock(&sc->sc_pm_lock);
579 : : }
580 : :
581 : 1 : chip_reset:
582 : :
583 : 48 : ath_debug_stat_interrupt(sc, status);
584 : :
585 [ + - ]: 48 : if (sched) {
586 : : /* turn off every interrupt */
587 : 48 : ath9k_hw_kill_interrupts(ah);
588 : 48 : tasklet_schedule(&sc->intr_tq);
589 : : }
590 : :
591 : : return IRQ_HANDLED;
592 : :
593 : : #undef SCHED_INTR
594 : : }
595 : :
596 : : /*
597 : : * This function is called when a HW reset cannot be deferred
598 : : * and has to be immediate.
599 : : */
600 : 6 : int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan)
601 : : {
602 : 6 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
603 : 6 : int r;
604 : :
605 : 6 : ath9k_hw_kill_interrupts(sc->sc_ah);
606 : 6 : set_bit(ATH_OP_HW_RESET, &common->op_flags);
607 : :
608 : 6 : ath9k_ps_wakeup(sc);
609 : 6 : r = ath_reset_internal(sc, hchan);
610 : 6 : ath9k_ps_restore(sc);
611 : :
612 : 6 : return r;
613 : : }
614 : :
615 : : /*
616 : : * When a HW reset can be deferred, it is added to the
617 : : * hw_reset_work workqueue, but we set ATH_OP_HW_RESET before
618 : : * queueing.
619 : : */
620 : 47 : void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type)
621 : : {
622 : 47 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
623 : : #ifdef CONFIG_ATH9K_DEBUGFS
624 : 47 : RESET_STAT_INC(sc, type);
625 : : #endif
626 : 47 : ath9k_hw_kill_interrupts(sc->sc_ah);
627 : 47 : set_bit(ATH_OP_HW_RESET, &common->op_flags);
628 : 47 : ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
629 : 47 : }
630 : :
631 : 47 : void ath_reset_work(struct work_struct *work)
632 : : {
633 : 47 : struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work);
634 : :
635 : 47 : ath9k_ps_wakeup(sc);
636 : 47 : ath_reset_internal(sc, NULL);
637 : 47 : ath9k_ps_restore(sc);
638 : 47 : }
639 : :
640 : : /**********************/
641 : : /* mac80211 callbacks */
642 : : /**********************/
643 : :
644 : 6 : static int ath9k_start(struct ieee80211_hw *hw)
645 : : {
646 : 6 : struct ath_softc *sc = hw->priv;
647 : 6 : struct ath_hw *ah = sc->sc_ah;
648 [ - + ]: 6 : struct ath_common *common = ath9k_hw_common(ah);
649 : 6 : struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
650 : 6 : struct ath_chanctx *ctx = sc->cur_chan;
651 : 6 : struct ath9k_channel *init_channel;
652 : 6 : int r;
653 : :
654 [ - + ]: 6 : ath_dbg(common, CONFIG,
655 : : "Starting driver with initial channel: %d MHz\n",
656 : : curchan->center_freq);
657 : :
658 : 6 : ath9k_ps_wakeup(sc);
659 : 6 : mutex_lock(&sc->mutex);
660 : :
661 : 6 : init_channel = ath9k_cmn_get_channel(hw, ah, &ctx->chandef);
662 : 6 : sc->cur_chandef = hw->conf.chandef;
663 : :
664 : : /* Reset SERDES registers */
665 [ - + ]: 6 : ath9k_hw_configpcipowersave(ah, false);
666 : :
667 : : /*
668 : : * The basic interface to setting the hardware in a good
669 : : * state is ``reset''. On return the hardware is known to
670 : : * be powered up and with interrupts disabled. This must
671 : : * be followed by initialization of the appropriate bits
672 : : * and then setup of the interrupt mask.
673 : : */
674 : 6 : spin_lock_bh(&sc->sc_pcu_lock);
675 : :
676 : 6 : atomic_set(&ah->intr_ref_cnt, -1);
677 : :
678 : 6 : r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
679 [ - + ]: 6 : if (r) {
680 : 0 : ath_err(common,
681 : : "Unable to reset hardware; reset status %d (freq %u MHz)\n",
682 : : r, curchan->center_freq);
683 : 0 : ah->reset_power_on = false;
684 : : }
685 : :
686 : : /* Setup our intr mask. */
687 : 6 : ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
688 : : ATH9K_INT_RXORN | ATH9K_INT_FATAL |
689 : : ATH9K_INT_GLOBAL;
690 : :
691 [ + + ]: 6 : if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
692 : 4 : ah->imask |= ATH9K_INT_RXHP |
693 : : ATH9K_INT_RXLP;
694 : : else
695 : 2 : ah->imask |= ATH9K_INT_RX;
696 : :
697 [ + + ]: 6 : if (ah->config.hw_hang_checks & HW_BB_WATCHDOG)
698 : 4 : ah->imask |= ATH9K_INT_BB_WATCHDOG;
699 : :
700 : : /*
701 : : * Enable GTT interrupts only for AR9003/AR9004 chips
702 : : * for now.
703 : : */
704 [ + + ]: 6 : if (AR_SREV_9300_20_OR_LATER(ah))
705 : 4 : ah->imask |= ATH9K_INT_GTT;
706 : :
707 [ + - ]: 6 : if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
708 : 6 : ah->imask |= ATH9K_INT_CST;
709 : :
710 : 6 : ath_mci_enable(sc);
711 : :
712 : 6 : clear_bit(ATH_OP_INVALID, &common->op_flags);
713 : 6 : sc->sc_ah->is_monitoring = false;
714 : :
715 [ - + ]: 6 : if (!ath_complete_reset(sc, false))
716 : 0 : ah->reset_power_on = false;
717 : :
718 [ + - ]: 6 : if (ah->led_pin >= 0) {
719 : 6 : ath9k_hw_set_gpio(ah, ah->led_pin,
720 : 6 : (ah->config.led_active_high) ? 1 : 0);
721 : 6 : ath9k_hw_gpio_request_out(ah, ah->led_pin, NULL,
722 : : AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
723 : : }
724 : :
725 : : /*
726 : : * Reset key cache to sane defaults (all entries cleared) instead of
727 : : * semi-random values after suspend/resume.
728 : : */
729 : 6 : ath9k_cmn_init_crypto(sc->sc_ah);
730 : :
731 : 6 : ath9k_hw_reset_tsf(ah);
732 : :
733 : 6 : spin_unlock_bh(&sc->sc_pcu_lock);
734 : :
735 : 6 : ath9k_rng_start(sc);
736 : :
737 : 6 : mutex_unlock(&sc->mutex);
738 : :
739 : 6 : ath9k_ps_restore(sc);
740 : :
741 : 6 : return 0;
742 : : }
743 : :
744 : 0 : static void ath9k_tx(struct ieee80211_hw *hw,
745 : : struct ieee80211_tx_control *control,
746 : : struct sk_buff *skb)
747 : : {
748 : 0 : struct ath_softc *sc = hw->priv;
749 [ # # ]: 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
750 : 0 : struct ath_tx_control txctl;
751 : 0 : struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
752 : 0 : unsigned long flags;
753 : :
754 [ # # ]: 0 : if (sc->ps_enabled) {
755 : : /*
756 : : * mac80211 does not set PM field for normal data frames, so we
757 : : * need to update that based on the current PS mode.
758 : : */
759 [ # # # # ]: 0 : if (ieee80211_is_data(hdr->frame_control) &&
760 [ # # ]: 0 : !ieee80211_is_nullfunc(hdr->frame_control) &&
761 : : !ieee80211_has_pm(hdr->frame_control)) {
762 [ # # ]: 0 : ath_dbg(common, PS,
763 : : "Add PM=1 for a TX frame while in PS mode\n");
764 : 0 : hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
765 : : }
766 : : }
767 : :
768 [ # # ]: 0 : if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_NETWORK_SLEEP)) {
769 : : /*
770 : : * We are using PS-Poll and mac80211 can request TX while in
771 : : * power save mode. Need to wake up hardware for the TX to be
772 : : * completed and if needed, also for RX of buffered frames.
773 : : */
774 : 0 : ath9k_ps_wakeup(sc);
775 : 0 : spin_lock_irqsave(&sc->sc_pm_lock, flags);
776 [ # # ]: 0 : if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
777 : 0 : ath9k_hw_setrxabort(sc->sc_ah, 0);
778 [ # # ]: 0 : if (ieee80211_is_pspoll(hdr->frame_control)) {
779 [ # # ]: 0 : ath_dbg(common, PS,
780 : : "Sending PS-Poll to pick a buffered frame\n");
781 : 0 : sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
782 : : } else {
783 [ # # ]: 0 : ath_dbg(common, PS, "Wake up to complete TX\n");
784 : 0 : sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
785 : : }
786 : : /*
787 : : * The actual restore operation will happen only after
788 : : * the ps_flags bit is cleared. We are just dropping
789 : : * the ps_usecount here.
790 : : */
791 : 0 : spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
792 : 0 : ath9k_ps_restore(sc);
793 : : }
794 : :
795 : : /*
796 : : * Cannot tx while the hardware is in full sleep, it first needs a full
797 : : * chip reset to recover from that
798 : : */
799 [ # # ]: 0 : if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP)) {
800 : 0 : ath_err(common, "TX while HW is in FULL_SLEEP mode\n");
801 : 0 : goto exit;
802 : : }
803 : :
804 : 0 : memset(&txctl, 0, sizeof(struct ath_tx_control));
805 [ # # ]: 0 : txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
806 : 0 : txctl.sta = control->sta;
807 : :
808 [ # # ]: 0 : ath_dbg(common, XMIT, "transmitting packet, skb: %p\n", skb);
809 : :
810 [ # # ]: 0 : if (ath_tx_start(hw, skb, &txctl) != 0) {
811 [ # # ]: 0 : ath_dbg(common, XMIT, "TX failed\n");
812 : 0 : TX_STAT_INC(sc, txctl.txq->axq_qnum, txfailed);
813 : 0 : goto exit;
814 : : }
815 : :
816 : 0 : return;
817 : 0 : exit:
818 : 0 : ieee80211_free_txskb(hw, skb);
819 : : }
820 : :
821 : 0 : static void ath9k_stop(struct ieee80211_hw *hw)
822 : : {
823 : 0 : struct ath_softc *sc = hw->priv;
824 : 0 : struct ath_hw *ah = sc->sc_ah;
825 : 0 : struct ath_common *common = ath9k_hw_common(ah);
826 : 0 : bool prev_idle;
827 : :
828 : 0 : ath9k_deinit_channel_context(sc);
829 : :
830 : 0 : mutex_lock(&sc->mutex);
831 : :
832 : 0 : ath9k_rng_stop(sc);
833 : :
834 : 0 : ath_cancel_work(sc);
835 : :
836 [ # # ]: 0 : if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
837 [ # # ]: 0 : ath_dbg(common, ANY, "Device not present\n");
838 : 0 : mutex_unlock(&sc->mutex);
839 : 0 : return;
840 : : }
841 : :
842 : : /* Ensure HW is awake when we try to shut it down. */
843 : 0 : ath9k_ps_wakeup(sc);
844 : :
845 : 0 : spin_lock_bh(&sc->sc_pcu_lock);
846 : :
847 : : /* prevent tasklets to enable interrupts once we disable them */
848 : 0 : ah->imask &= ~ATH9K_INT_GLOBAL;
849 : :
850 : : /* make sure h/w will not generate any interrupt
851 : : * before setting the invalid flag. */
852 : 0 : ath9k_hw_disable_interrupts(ah);
853 : :
854 : 0 : spin_unlock_bh(&sc->sc_pcu_lock);
855 : :
856 : : /* we can now sync irq and kill any running tasklets, since we already
857 : : * disabled interrupts and not holding a spin lock */
858 : 0 : synchronize_irq(sc->irq);
859 : 0 : tasklet_kill(&sc->intr_tq);
860 : 0 : tasklet_kill(&sc->bcon_tasklet);
861 : :
862 : 0 : prev_idle = sc->ps_idle;
863 : 0 : sc->ps_idle = true;
864 : :
865 : 0 : spin_lock_bh(&sc->sc_pcu_lock);
866 : :
867 [ # # ]: 0 : if (ah->led_pin >= 0) {
868 : 0 : ath9k_hw_set_gpio(ah, ah->led_pin,
869 : 0 : (ah->config.led_active_high) ? 0 : 1);
870 : 0 : ath9k_hw_gpio_request_in(ah, ah->led_pin, NULL);
871 : : }
872 : :
873 : 0 : ath_prepare_reset(sc);
874 : :
875 [ # # ]: 0 : if (sc->rx.frag) {
876 : 0 : dev_kfree_skb_any(sc->rx.frag);
877 : 0 : sc->rx.frag = NULL;
878 : : }
879 : :
880 [ # # ]: 0 : if (!ah->curchan)
881 : 0 : ah->curchan = ath9k_cmn_get_channel(hw, ah,
882 : 0 : &sc->cur_chan->chandef);
883 : :
884 : 0 : ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
885 : :
886 : 0 : set_bit(ATH_OP_INVALID, &common->op_flags);
887 : :
888 : 0 : ath9k_hw_phy_disable(ah);
889 : :
890 [ # # ]: 0 : ath9k_hw_configpcipowersave(ah, true);
891 : :
892 : 0 : spin_unlock_bh(&sc->sc_pcu_lock);
893 : :
894 : 0 : ath9k_ps_restore(sc);
895 : :
896 : 0 : sc->ps_idle = prev_idle;
897 : :
898 : 0 : mutex_unlock(&sc->mutex);
899 : :
900 [ # # ]: 0 : ath_dbg(common, CONFIG, "Driver halt\n");
901 : : }
902 : :
903 : 6 : static bool ath9k_uses_beacons(int type)
904 : : {
905 : 6 : switch (type) {
906 : : case NL80211_IFTYPE_AP:
907 : : case NL80211_IFTYPE_ADHOC:
908 : : case NL80211_IFTYPE_MESH_POINT:
909 : : return true;
910 : : default:
911 : : return false;
912 : : }
913 : : }
914 : :
915 : 0 : static void ath9k_vif_iter_set_beacon(struct ath9k_vif_iter_data *iter_data,
916 : : struct ieee80211_vif *vif)
917 : : {
918 : : /* Use the first (configured) interface, but prefering AP interfaces. */
919 : 0 : if (!iter_data->primary_beacon_vif) {
920 : 0 : iter_data->primary_beacon_vif = vif;
921 : : } else {
922 [ # # # # : 0 : if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP &&
# # ]
923 [ # # # # : 0 : vif->type == NL80211_IFTYPE_AP)
# # ]
924 : 0 : iter_data->primary_beacon_vif = vif;
925 : : }
926 : :
927 : 0 : iter_data->beacons = true;
928 : 0 : iter_data->nbcnvifs += 1;
929 : 0 : }
930 : :
931 : 54 : static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
932 : : u8 *mac, struct ieee80211_vif *vif)
933 : : {
934 : 54 : struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
935 : 54 : int i;
936 : :
937 [ - + ]: 54 : if (iter_data->has_hw_macaddr) {
938 [ # # ]: 0 : for (i = 0; i < ETH_ALEN; i++)
939 : 0 : iter_data->mask[i] &=
940 : 0 : ~(iter_data->hw_macaddr[i] ^ mac[i]);
941 : : } else {
942 : 54 : memcpy(iter_data->hw_macaddr, mac, ETH_ALEN);
943 : 54 : iter_data->has_hw_macaddr = true;
944 : : }
945 : :
946 [ + - ]: 54 : if (!vif->bss_conf.use_short_slot)
947 : 54 : iter_data->slottime = 20;
948 : :
949 [ - + - - : 54 : switch (vif->type) {
- - - ]
950 : 0 : case NL80211_IFTYPE_AP:
951 : 0 : iter_data->naps++;
952 [ # # ]: 0 : if (vif->bss_conf.enable_beacon)
953 [ # # ]: 0 : ath9k_vif_iter_set_beacon(iter_data, vif);
954 : : break;
955 : 54 : case NL80211_IFTYPE_STATION:
956 : 54 : iter_data->nstations++;
957 [ - + - - ]: 54 : if (avp->assoc && !iter_data->primary_sta)
958 : 0 : iter_data->primary_sta = vif;
959 : : break;
960 : 0 : case NL80211_IFTYPE_OCB:
961 : 0 : iter_data->nocbs++;
962 : 0 : break;
963 : 0 : case NL80211_IFTYPE_ADHOC:
964 : 0 : iter_data->nadhocs++;
965 [ # # ]: 0 : if (vif->bss_conf.enable_beacon)
966 [ # # ]: 0 : ath9k_vif_iter_set_beacon(iter_data, vif);
967 : : break;
968 : 0 : case NL80211_IFTYPE_MESH_POINT:
969 : 0 : iter_data->nmeshes++;
970 [ # # ]: 0 : if (vif->bss_conf.enable_beacon)
971 [ # # ]: 0 : ath9k_vif_iter_set_beacon(iter_data, vif);
972 : : break;
973 : 0 : case NL80211_IFTYPE_WDS:
974 : 0 : iter_data->nwds++;
975 : 0 : break;
976 : : default:
977 : : break;
978 : : }
979 : 54 : }
980 : :
981 : 65 : static void ath9k_update_bssid_mask(struct ath_softc *sc,
982 : : struct ath_chanctx *ctx,
983 : : struct ath9k_vif_iter_data *iter_data)
984 : : {
985 : 65 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
986 : 65 : struct ath_vif *avp;
987 : 65 : int i;
988 : :
989 : 65 : if (!ath9k_is_chanctx_enabled())
990 : 65 : return;
991 : :
992 : : list_for_each_entry(avp, &ctx->vifs, list) {
993 : : if (ctx->nvifs_assigned != 1)
994 : : continue;
995 : :
996 : : if (!iter_data->has_hw_macaddr)
997 : : continue;
998 : :
999 : : ether_addr_copy(common->curbssid, avp->bssid);
1000 : :
1001 : : /* perm_addr will be used as the p2p device address. */
1002 : : for (i = 0; i < ETH_ALEN; i++)
1003 : : iter_data->mask[i] &=
1004 : : ~(iter_data->hw_macaddr[i] ^
1005 : : sc->hw->wiphy->perm_addr[i]);
1006 : : }
1007 : : }
1008 : :
1009 : : /* Called with sc->mutex held. */
1010 : 65 : void ath9k_calculate_iter_data(struct ath_softc *sc,
1011 : : struct ath_chanctx *ctx,
1012 : : struct ath9k_vif_iter_data *iter_data)
1013 : : {
1014 : 65 : struct ath_vif *avp;
1015 : :
1016 : : /*
1017 : : * The hardware will use primary station addr together with the
1018 : : * BSSID mask when matching addresses.
1019 : : */
1020 : 65 : memset(iter_data, 0, sizeof(*iter_data));
1021 : 65 : eth_broadcast_addr(iter_data->mask);
1022 : 65 : iter_data->slottime = 9;
1023 : :
1024 [ + + ]: 119 : list_for_each_entry(avp, &ctx->vifs, list)
1025 : 54 : ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif);
1026 : :
1027 : 65 : ath9k_update_bssid_mask(sc, ctx, iter_data);
1028 : 65 : }
1029 : :
1030 : 0 : static void ath9k_set_assoc_state(struct ath_softc *sc,
1031 : : struct ieee80211_vif *vif, bool changed)
1032 : : {
1033 : 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1034 : 0 : struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
1035 : 0 : unsigned long flags;
1036 : :
1037 : 0 : set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
1038 : :
1039 : 0 : ether_addr_copy(common->curbssid, avp->bssid);
1040 : 0 : common->curaid = avp->aid;
1041 : 0 : ath9k_hw_write_associd(sc->sc_ah);
1042 : :
1043 [ # # ]: 0 : if (changed) {
1044 : 0 : common->last_rssi = ATH_RSSI_DUMMY_MARKER;
1045 : 0 : sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1046 : :
1047 : 0 : spin_lock_irqsave(&sc->sc_pm_lock, flags);
1048 : 0 : sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
1049 : 0 : spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1050 : : }
1051 : :
1052 [ # # # # ]: 0 : if (ath9k_hw_mci_is_enabled(sc->sc_ah))
1053 : 0 : ath9k_mci_update_wlan_channels(sc, false);
1054 : :
1055 [ # # ]: 0 : ath_dbg(common, CONFIG,
1056 : : "Primary Station interface: %pM, BSSID: %pM\n",
1057 : : vif->addr, common->curbssid);
1058 : 0 : }
1059 : :
1060 : : #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
1061 : : static void ath9k_set_offchannel_state(struct ath_softc *sc)
1062 : : {
1063 : : struct ath_hw *ah = sc->sc_ah;
1064 : : struct ath_common *common = ath9k_hw_common(ah);
1065 : : struct ieee80211_vif *vif = NULL;
1066 : :
1067 : : ath9k_ps_wakeup(sc);
1068 : :
1069 : : if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START)
1070 : : vif = sc->offchannel.scan_vif;
1071 : : else
1072 : : vif = sc->offchannel.roc_vif;
1073 : :
1074 : : if (WARN_ON(!vif))
1075 : : goto exit;
1076 : :
1077 : : eth_zero_addr(common->curbssid);
1078 : : eth_broadcast_addr(common->bssidmask);
1079 : : memcpy(common->macaddr, vif->addr, ETH_ALEN);
1080 : : common->curaid = 0;
1081 : : ah->opmode = vif->type;
1082 : : ah->imask &= ~ATH9K_INT_SWBA;
1083 : : ah->imask &= ~ATH9K_INT_TSFOOR;
1084 : : ah->slottime = 9;
1085 : :
1086 : : ath_hw_setbssidmask(common);
1087 : : ath9k_hw_setopmode(ah);
1088 : : ath9k_hw_write_associd(sc->sc_ah);
1089 : : ath9k_hw_set_interrupts(ah);
1090 : : ath9k_hw_init_global_settings(ah);
1091 : :
1092 : : exit:
1093 : : ath9k_ps_restore(sc);
1094 : : }
1095 : : #endif
1096 : :
1097 : : /* Called with sc->mutex held. */
1098 : 65 : void ath9k_calculate_summary_state(struct ath_softc *sc,
1099 : : struct ath_chanctx *ctx)
1100 : : {
1101 : 65 : struct ath_hw *ah = sc->sc_ah;
1102 [ - + ]: 65 : struct ath_common *common = ath9k_hw_common(ah);
1103 : 65 : struct ath9k_vif_iter_data iter_data;
1104 : :
1105 [ - + ]: 65 : ath_chanctx_check_active(sc, ctx);
1106 : :
1107 [ - + ]: 65 : if (ctx != sc->cur_chan)
1108 : 0 : return;
1109 : :
1110 : : #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
1111 : : if (ctx == &sc->offchannel.chan)
1112 : : return ath9k_set_offchannel_state(sc);
1113 : : #endif
1114 : :
1115 : 65 : ath9k_ps_wakeup(sc);
1116 : 65 : ath9k_calculate_iter_data(sc, ctx, &iter_data);
1117 : :
1118 [ + + ]: 65 : if (iter_data.has_hw_macaddr)
1119 : 54 : memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN);
1120 : :
1121 : 65 : memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
1122 : 65 : ath_hw_setbssidmask(common);
1123 : :
1124 [ - + ]: 65 : if (iter_data.naps > 0) {
1125 : 0 : ath9k_hw_set_tsfadjust(ah, true);
1126 : 0 : ah->opmode = NL80211_IFTYPE_AP;
1127 : : } else {
1128 : 65 : ath9k_hw_set_tsfadjust(ah, false);
1129 [ - + ]: 65 : if (iter_data.beacons)
1130 : 0 : ath9k_beacon_ensure_primary_slot(sc);
1131 : :
1132 [ - + ]: 65 : if (iter_data.nmeshes)
1133 : 0 : ah->opmode = NL80211_IFTYPE_MESH_POINT;
1134 [ - + ]: 65 : else if (iter_data.nocbs)
1135 : 0 : ah->opmode = NL80211_IFTYPE_OCB;
1136 [ - + ]: 65 : else if (iter_data.nwds)
1137 : 0 : ah->opmode = NL80211_IFTYPE_AP;
1138 [ - + ]: 65 : else if (iter_data.nadhocs)
1139 : 0 : ah->opmode = NL80211_IFTYPE_ADHOC;
1140 : : else
1141 : 65 : ah->opmode = NL80211_IFTYPE_STATION;
1142 : : }
1143 : :
1144 : 65 : ath9k_hw_setopmode(ah);
1145 : :
1146 : 65 : ctx->switch_after_beacon = false;
1147 [ + + ]: 65 : if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0)
1148 : 54 : ah->imask |= ATH9K_INT_TSFOOR;
1149 : : else {
1150 : 11 : ah->imask &= ~ATH9K_INT_TSFOOR;
1151 [ - + - - ]: 11 : if (iter_data.naps == 1 && iter_data.beacons)
1152 : 0 : ctx->switch_after_beacon = true;
1153 : : }
1154 : :
1155 [ + - ]: 65 : if (ah->opmode == NL80211_IFTYPE_STATION) {
1156 : 65 : bool changed = (iter_data.primary_sta != ctx->primary_sta);
1157 : :
1158 [ - + ]: 65 : if (iter_data.primary_sta) {
1159 : 0 : iter_data.primary_beacon_vif = iter_data.primary_sta;
1160 : 0 : iter_data.beacons = true;
1161 : 0 : ath9k_set_assoc_state(sc, iter_data.primary_sta,
1162 : : changed);
1163 : 0 : ctx->primary_sta = iter_data.primary_sta;
1164 : : } else {
1165 : 65 : ctx->primary_sta = NULL;
1166 : 65 : eth_zero_addr(common->curbssid);
1167 : 65 : common->curaid = 0;
1168 : 65 : ath9k_hw_write_associd(sc->sc_ah);
1169 [ - + - + ]: 130 : if (ath9k_hw_mci_is_enabled(sc->sc_ah))
1170 : 0 : ath9k_mci_update_wlan_channels(sc, true);
1171 : : }
1172 : : }
1173 : 65 : sc->nbcnvifs = iter_data.nbcnvifs;
1174 : 65 : ath9k_beacon_config(sc, iter_data.primary_beacon_vif,
1175 : 65 : iter_data.beacons);
1176 : 65 : ath9k_hw_set_interrupts(ah);
1177 : :
1178 [ + + ]: 65 : if (ah->slottime != iter_data.slottime) {
1179 : 6 : ah->slottime = iter_data.slottime;
1180 : 6 : ath9k_hw_init_global_settings(ah);
1181 : : }
1182 : :
1183 [ - + ]: 65 : if (iter_data.primary_sta)
1184 : 0 : set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
1185 : : else
1186 : 65 : clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
1187 : :
1188 [ - + ]: 65 : ath_dbg(common, CONFIG,
1189 : : "macaddr: %pM, bssid: %pM, bssidmask: %pM\n",
1190 : : common->macaddr, common->curbssid, common->bssidmask);
1191 : :
1192 : 65 : ath9k_ps_restore(sc);
1193 : : }
1194 : :
1195 : 0 : static void ath9k_tpc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1196 : : {
1197 : 0 : int *power = data;
1198 : :
1199 [ # # ]: 0 : if (*power < vif->bss_conf.txpower)
1200 : 0 : *power = vif->bss_conf.txpower;
1201 : 0 : }
1202 : :
1203 : : /* Called with sc->mutex held. */
1204 : 6 : void ath9k_set_txpower(struct ath_softc *sc, struct ieee80211_vif *vif)
1205 : : {
1206 : 6 : int power;
1207 : 6 : struct ath_hw *ah = sc->sc_ah;
1208 : 6 : struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
1209 : :
1210 : 6 : ath9k_ps_wakeup(sc);
1211 [ - + ]: 6 : if (ah->tpc_enabled) {
1212 [ # # ]: 0 : power = (vif) ? vif->bss_conf.txpower : -1;
1213 : 0 : ieee80211_iterate_active_interfaces_atomic(
1214 : : sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1215 : : ath9k_tpc_vif_iter, &power);
1216 [ # # ]: 0 : if (power == -1)
1217 : 0 : power = sc->hw->conf.power_level;
1218 : : } else {
1219 : 6 : power = sc->hw->conf.power_level;
1220 : : }
1221 : 6 : sc->cur_chan->txpower = 2 * power;
1222 : 6 : ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
1223 : 6 : sc->cur_chan->cur_txpower = reg->max_power_level;
1224 : 6 : ath9k_ps_restore(sc);
1225 : 6 : }
1226 : :
1227 : 6 : static void ath9k_assign_hw_queues(struct ieee80211_hw *hw,
1228 : : struct ieee80211_vif *vif)
1229 : : {
1230 : 6 : int i;
1231 : :
1232 : 6 : if (!ath9k_is_chanctx_enabled())
1233 : 6 : return;
1234 : :
1235 : : for (i = 0; i < IEEE80211_NUM_ACS; i++)
1236 : : vif->hw_queue[i] = i;
1237 : :
1238 : : if (vif->type == NL80211_IFTYPE_AP ||
1239 : : vif->type == NL80211_IFTYPE_MESH_POINT)
1240 : : vif->cab_queue = hw->queues - 2;
1241 : : else
1242 : : vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
1243 : : }
1244 : :
1245 : 6 : static int ath9k_add_interface(struct ieee80211_hw *hw,
1246 : : struct ieee80211_vif *vif)
1247 : : {
1248 : 6 : struct ath_softc *sc = hw->priv;
1249 : 6 : struct ath_hw *ah = sc->sc_ah;
1250 : 6 : struct ath_common *common = ath9k_hw_common(ah);
1251 : 6 : struct ath_vif *avp = (void *)vif->drv_priv;
1252 : 6 : struct ath_node *an = &avp->mcast_node;
1253 : :
1254 : 6 : mutex_lock(&sc->mutex);
1255 : 6 : if (IS_ENABLED(CONFIG_ATH9K_TX99)) {
1256 : : if (sc->cur_chan->nvifs >= 1) {
1257 : : mutex_unlock(&sc->mutex);
1258 : : return -EOPNOTSUPP;
1259 : : }
1260 : : sc->tx99_vif = vif;
1261 : : }
1262 : :
1263 [ - + ]: 6 : ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
1264 : 6 : sc->cur_chan->nvifs++;
1265 : :
1266 : 6 : if (vif->type == NL80211_IFTYPE_STATION && ath9k_is_chanctx_enabled())
1267 : : vif->driver_flags |= IEEE80211_VIF_GET_NOA_UPDATE;
1268 : :
1269 [ - + ]: 6 : if (ath9k_uses_beacons(vif->type))
1270 : 0 : ath9k_beacon_assign_slot(sc, vif);
1271 : :
1272 : 6 : avp->vif = vif;
1273 : 6 : if (!ath9k_is_chanctx_enabled()) {
1274 : 6 : avp->chanctx = sc->cur_chan;
1275 : 6 : list_add_tail(&avp->list, &avp->chanctx->vifs);
1276 : : }
1277 : :
1278 : 6 : ath9k_calculate_summary_state(sc, avp->chanctx);
1279 : :
1280 : 6 : ath9k_assign_hw_queues(hw, vif);
1281 : :
1282 : 6 : ath9k_set_txpower(sc, vif);
1283 : :
1284 : 6 : an->sc = sc;
1285 : 6 : an->sta = NULL;
1286 : 6 : an->vif = vif;
1287 : 6 : an->no_ps_filter = true;
1288 : 6 : ath_tx_node_init(sc, an);
1289 : :
1290 : 6 : mutex_unlock(&sc->mutex);
1291 : 6 : return 0;
1292 : : }
1293 : :
1294 : 0 : static int ath9k_change_interface(struct ieee80211_hw *hw,
1295 : : struct ieee80211_vif *vif,
1296 : : enum nl80211_iftype new_type,
1297 : : bool p2p)
1298 : : {
1299 : 0 : struct ath_softc *sc = hw->priv;
1300 : 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1301 : 0 : struct ath_vif *avp = (void *)vif->drv_priv;
1302 : :
1303 : 0 : mutex_lock(&sc->mutex);
1304 : :
1305 : 0 : if (IS_ENABLED(CONFIG_ATH9K_TX99)) {
1306 : : mutex_unlock(&sc->mutex);
1307 : : return -EOPNOTSUPP;
1308 : : }
1309 : :
1310 [ # # ]: 0 : ath_dbg(common, CONFIG, "Change Interface\n");
1311 : :
1312 [ # # ]: 0 : if (ath9k_uses_beacons(vif->type))
1313 : 0 : ath9k_beacon_remove_slot(sc, vif);
1314 : :
1315 : 0 : vif->type = new_type;
1316 : 0 : vif->p2p = p2p;
1317 : :
1318 [ # # ]: 0 : if (ath9k_uses_beacons(vif->type))
1319 : 0 : ath9k_beacon_assign_slot(sc, vif);
1320 : :
1321 : 0 : ath9k_assign_hw_queues(hw, vif);
1322 : 0 : ath9k_calculate_summary_state(sc, avp->chanctx);
1323 : :
1324 : 0 : ath9k_set_txpower(sc, vif);
1325 : :
1326 : 0 : mutex_unlock(&sc->mutex);
1327 : 0 : return 0;
1328 : : }
1329 : :
1330 : 0 : static void ath9k_remove_interface(struct ieee80211_hw *hw,
1331 : : struct ieee80211_vif *vif)
1332 : : {
1333 : 0 : struct ath_softc *sc = hw->priv;
1334 [ # # ]: 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1335 : 0 : struct ath_vif *avp = (void *)vif->drv_priv;
1336 : :
1337 [ # # ]: 0 : ath_dbg(common, CONFIG, "Detach Interface\n");
1338 : :
1339 : 0 : mutex_lock(&sc->mutex);
1340 : :
1341 [ # # ]: 0 : ath9k_p2p_remove_vif(sc, vif);
1342 : :
1343 : 0 : sc->cur_chan->nvifs--;
1344 : 0 : sc->tx99_vif = NULL;
1345 [ # # ]: 0 : if (!ath9k_is_chanctx_enabled())
1346 [ # # ]: 0 : list_del(&avp->list);
1347 : :
1348 [ # # ]: 0 : if (ath9k_uses_beacons(vif->type))
1349 : 0 : ath9k_beacon_remove_slot(sc, vif);
1350 : :
1351 : 0 : ath_tx_node_cleanup(sc, &avp->mcast_node);
1352 : :
1353 : 0 : ath9k_calculate_summary_state(sc, avp->chanctx);
1354 : :
1355 : 0 : ath9k_set_txpower(sc, NULL);
1356 : :
1357 : 0 : mutex_unlock(&sc->mutex);
1358 : 0 : }
1359 : :
1360 : : static void ath9k_enable_ps(struct ath_softc *sc)
1361 : : {
1362 : : struct ath_hw *ah = sc->sc_ah;
1363 : : struct ath_common *common = ath9k_hw_common(ah);
1364 : :
1365 : : if (IS_ENABLED(CONFIG_ATH9K_TX99))
1366 : : return;
1367 : :
1368 : : sc->ps_enabled = true;
1369 : : if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1370 : : if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) {
1371 : : ah->imask |= ATH9K_INT_TIM_TIMER;
1372 : : ath9k_hw_set_interrupts(ah);
1373 : : }
1374 : : ath9k_hw_setrxabort(ah, 1);
1375 : : }
1376 : : ath_dbg(common, PS, "PowerSave enabled\n");
1377 : : }
1378 : :
1379 : 6 : static void ath9k_disable_ps(struct ath_softc *sc)
1380 : : {
1381 : 6 : struct ath_hw *ah = sc->sc_ah;
1382 : 6 : struct ath_common *common = ath9k_hw_common(ah);
1383 : :
1384 : 6 : if (IS_ENABLED(CONFIG_ATH9K_TX99))
1385 : : return;
1386 : :
1387 : 6 : sc->ps_enabled = false;
1388 : 6 : ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
1389 [ + + ]: 6 : if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1390 : 2 : ath9k_hw_setrxabort(ah, 0);
1391 : 2 : sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
1392 : : PS_WAIT_FOR_CAB |
1393 : : PS_WAIT_FOR_PSPOLL_DATA |
1394 : : PS_WAIT_FOR_TX_ACK);
1395 [ - + ]: 2 : if (ah->imask & ATH9K_INT_TIM_TIMER) {
1396 : 0 : ah->imask &= ~ATH9K_INT_TIM_TIMER;
1397 : 0 : ath9k_hw_set_interrupts(ah);
1398 : : }
1399 : : }
1400 [ - + ]: 6 : ath_dbg(common, PS, "PowerSave disabled\n");
1401 : : }
1402 : :
1403 : 6 : static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1404 : : {
1405 : 6 : struct ath_softc *sc = hw->priv;
1406 : 6 : struct ath_hw *ah = sc->sc_ah;
1407 : 6 : struct ath_common *common = ath9k_hw_common(ah);
1408 : 6 : struct ieee80211_conf *conf = &hw->conf;
1409 : 6 : struct ath_chanctx *ctx = sc->cur_chan;
1410 : :
1411 : 6 : ath9k_ps_wakeup(sc);
1412 : 6 : mutex_lock(&sc->mutex);
1413 : :
1414 [ + - ]: 6 : if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1415 : 6 : sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1416 [ + - ]: 6 : if (sc->ps_idle) {
1417 : 6 : ath_cancel_work(sc);
1418 : 6 : ath9k_stop_btcoex(sc);
1419 : : } else {
1420 : 0 : ath9k_start_btcoex(sc);
1421 : : /*
1422 : : * The chip needs a reset to properly wake up from
1423 : : * full sleep
1424 : : */
1425 : 0 : ath_chanctx_set_channel(sc, ctx, &ctx->chandef);
1426 : : }
1427 : : }
1428 : :
1429 : : /*
1430 : : * We just prepare to enable PS. We have to wait until our AP has
1431 : : * ACK'd our null data frame to disable RX otherwise we'll ignore
1432 : : * those ACKs and end up retransmitting the same null data frames.
1433 : : * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode.
1434 : : */
1435 [ + - ]: 6 : if (changed & IEEE80211_CONF_CHANGE_PS) {
1436 : 6 : unsigned long flags;
1437 : 6 : spin_lock_irqsave(&sc->sc_pm_lock, flags);
1438 [ - + ]: 6 : if (conf->flags & IEEE80211_CONF_PS)
1439 : 0 : ath9k_enable_ps(sc);
1440 : : else
1441 : 6 : ath9k_disable_ps(sc);
1442 : 6 : spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1443 : : }
1444 : :
1445 [ + - ]: 6 : if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1446 [ - + ]: 6 : if (conf->flags & IEEE80211_CONF_MONITOR) {
1447 [ # # ]: 0 : ath_dbg(common, CONFIG, "Monitor mode is enabled\n");
1448 : 0 : sc->sc_ah->is_monitoring = true;
1449 : : } else {
1450 [ - + ]: 6 : ath_dbg(common, CONFIG, "Monitor mode is disabled\n");
1451 : 6 : sc->sc_ah->is_monitoring = false;
1452 : : }
1453 : : }
1454 : :
1455 [ + - ]: 6 : if (!ath9k_is_chanctx_enabled() && (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
1456 : 6 : ctx->offchannel = !!(conf->flags & IEEE80211_CONF_OFFCHANNEL);
1457 : 6 : ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef);
1458 : : }
1459 : :
1460 : 6 : mutex_unlock(&sc->mutex);
1461 : 6 : ath9k_ps_restore(sc);
1462 : :
1463 : 6 : return 0;
1464 : : }
1465 : :
1466 : : #define SUPPORTED_FILTERS \
1467 : : (FIF_ALLMULTI | \
1468 : : FIF_CONTROL | \
1469 : : FIF_PSPOLL | \
1470 : : FIF_OTHER_BSS | \
1471 : : FIF_BCN_PRBRESP_PROMISC | \
1472 : : FIF_PROBE_REQ | \
1473 : : FIF_FCSFAIL)
1474 : :
1475 : : /* FIXME: sc->sc_full_reset ? */
1476 : 12 : static void ath9k_configure_filter(struct ieee80211_hw *hw,
1477 : : unsigned int changed_flags,
1478 : : unsigned int *total_flags,
1479 : : u64 multicast)
1480 : : {
1481 : 12 : struct ath_softc *sc = hw->priv;
1482 : 12 : struct ath_chanctx *ctx;
1483 : 12 : u32 rfilt;
1484 : :
1485 : 12 : changed_flags &= SUPPORTED_FILTERS;
1486 : 12 : *total_flags &= SUPPORTED_FILTERS;
1487 : :
1488 : 12 : spin_lock_bh(&sc->chan_lock);
1489 [ + + ]: 36 : ath_for_each_chanctx(sc, ctx)
1490 : 24 : ctx->rxfilter = *total_flags;
1491 : : #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
1492 : : sc->offchannel.chan.rxfilter = *total_flags;
1493 : : #endif
1494 : 12 : spin_unlock_bh(&sc->chan_lock);
1495 : :
1496 : 12 : ath9k_ps_wakeup(sc);
1497 : 12 : rfilt = ath_calcrxfilter(sc);
1498 : 12 : ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
1499 : 12 : ath9k_ps_restore(sc);
1500 : :
1501 [ - + ]: 12 : ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG, "Set HW RX filter: 0x%x\n",
1502 : : rfilt);
1503 : 12 : }
1504 : :
1505 : : static int ath9k_sta_add(struct ieee80211_hw *hw,
1506 : : struct ieee80211_vif *vif,
1507 : : struct ieee80211_sta *sta)
1508 : : {
1509 : : struct ath_softc *sc = hw->priv;
1510 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1511 : : struct ath_node *an = (struct ath_node *) sta->drv_priv;
1512 : : struct ieee80211_key_conf ps_key = { };
1513 : : int key;
1514 : :
1515 : : ath_node_attach(sc, sta, vif);
1516 : :
1517 : : if (vif->type != NL80211_IFTYPE_AP &&
1518 : : vif->type != NL80211_IFTYPE_AP_VLAN)
1519 : : return 0;
1520 : :
1521 : : key = ath_key_config(common, vif, sta, &ps_key);
1522 : : if (key > 0) {
1523 : : an->ps_key = key;
1524 : : an->key_idx[0] = key;
1525 : : }
1526 : :
1527 : : return 0;
1528 : : }
1529 : :
1530 : : static void ath9k_del_ps_key(struct ath_softc *sc,
1531 : : struct ieee80211_vif *vif,
1532 : : struct ieee80211_sta *sta)
1533 : : {
1534 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1535 : : struct ath_node *an = (struct ath_node *) sta->drv_priv;
1536 : : struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key };
1537 : :
1538 : : if (!an->ps_key)
1539 : : return;
1540 : :
1541 : : ath_key_delete(common, &ps_key);
1542 : : an->ps_key = 0;
1543 : : an->key_idx[0] = 0;
1544 : : }
1545 : :
1546 : 0 : static int ath9k_sta_remove(struct ieee80211_hw *hw,
1547 : : struct ieee80211_vif *vif,
1548 : : struct ieee80211_sta *sta)
1549 : : {
1550 : 0 : struct ath_softc *sc = hw->priv;
1551 : :
1552 : 0 : ath9k_del_ps_key(sc, vif, sta);
1553 : 0 : ath_node_detach(sc, sta);
1554 : :
1555 : 0 : return 0;
1556 : : }
1557 : :
1558 : 0 : static int ath9k_sta_state(struct ieee80211_hw *hw,
1559 : : struct ieee80211_vif *vif,
1560 : : struct ieee80211_sta *sta,
1561 : : enum ieee80211_sta_state old_state,
1562 : : enum ieee80211_sta_state new_state)
1563 : : {
1564 : 0 : struct ath_softc *sc = hw->priv;
1565 [ # # ]: 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1566 : 0 : int ret = 0;
1567 : :
1568 [ # # # # ]: 0 : if (old_state == IEEE80211_STA_NOTEXIST &&
1569 : : new_state == IEEE80211_STA_NONE) {
1570 : 0 : ret = ath9k_sta_add(hw, vif, sta);
1571 [ # # ]: 0 : ath_dbg(common, CONFIG,
1572 : : "Add station: %pM\n", sta->addr);
1573 [ # # # # ]: 0 : } else if (old_state == IEEE80211_STA_NONE &&
1574 : : new_state == IEEE80211_STA_NOTEXIST) {
1575 : 0 : ret = ath9k_sta_remove(hw, vif, sta);
1576 [ # # ]: 0 : ath_dbg(common, CONFIG,
1577 : : "Remove station: %pM\n", sta->addr);
1578 : : }
1579 : :
1580 : 0 : if (ath9k_is_chanctx_enabled()) {
1581 : : if (vif->type == NL80211_IFTYPE_STATION) {
1582 : : if (old_state == IEEE80211_STA_ASSOC &&
1583 : : new_state == IEEE80211_STA_AUTHORIZED)
1584 : : ath_chanctx_event(sc, vif,
1585 : : ATH_CHANCTX_EVENT_AUTHORIZED);
1586 : : }
1587 : : }
1588 : :
1589 : 0 : return ret;
1590 : : }
1591 : :
1592 : 0 : static void ath9k_sta_set_tx_filter(struct ath_hw *ah,
1593 : : struct ath_node *an,
1594 : : bool set)
1595 : : {
1596 : 0 : int i;
1597 : :
1598 [ # # # # ]: 0 : for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) {
1599 [ # # # # ]: 0 : if (!an->key_idx[i])
1600 : 0 : continue;
1601 : 0 : ath9k_hw_set_tx_filter(ah, an->key_idx[i], set);
1602 : : }
1603 : : }
1604 : :
1605 : 0 : static void ath9k_sta_notify(struct ieee80211_hw *hw,
1606 : : struct ieee80211_vif *vif,
1607 : : enum sta_notify_cmd cmd,
1608 : : struct ieee80211_sta *sta)
1609 : : {
1610 : 0 : struct ath_softc *sc = hw->priv;
1611 : 0 : struct ath_node *an = (struct ath_node *) sta->drv_priv;
1612 : :
1613 [ # # # ]: 0 : switch (cmd) {
1614 : 0 : case STA_NOTIFY_SLEEP:
1615 : 0 : an->sleeping = true;
1616 : 0 : ath_tx_aggr_sleep(sta, sc, an);
1617 : 0 : ath9k_sta_set_tx_filter(sc->sc_ah, an, true);
1618 : : break;
1619 : 0 : case STA_NOTIFY_AWAKE:
1620 : 0 : ath9k_sta_set_tx_filter(sc->sc_ah, an, false);
1621 : 0 : an->sleeping = false;
1622 : 0 : ath_tx_aggr_wakeup(sc, an);
1623 : 0 : break;
1624 : : }
1625 : 0 : }
1626 : :
1627 : 24 : static int ath9k_conf_tx(struct ieee80211_hw *hw,
1628 : : struct ieee80211_vif *vif, u16 queue,
1629 : : const struct ieee80211_tx_queue_params *params)
1630 : : {
1631 : 24 : struct ath_softc *sc = hw->priv;
1632 [ + - ]: 24 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1633 : 24 : struct ath_txq *txq;
1634 : 24 : struct ath9k_tx_queue_info qi;
1635 : 24 : int ret = 0;
1636 : :
1637 [ + - ]: 24 : if (queue >= IEEE80211_NUM_ACS)
1638 : : return 0;
1639 : :
1640 : 24 : txq = sc->tx.txq_map[queue];
1641 : :
1642 : 24 : ath9k_ps_wakeup(sc);
1643 : 24 : mutex_lock(&sc->mutex);
1644 : :
1645 : 24 : memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1646 : :
1647 : 24 : qi.tqi_aifs = params->aifs;
1648 : 24 : qi.tqi_cwmin = params->cw_min;
1649 : 24 : qi.tqi_cwmax = params->cw_max;
1650 : 24 : qi.tqi_burstTime = params->txop * 32;
1651 : :
1652 [ - + ]: 24 : ath_dbg(common, CONFIG,
1653 : : "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1654 : : queue, txq->axq_qnum, params->aifs, params->cw_min,
1655 : : params->cw_max, params->txop);
1656 : :
1657 : 24 : ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime);
1658 : 24 : ret = ath_txq_update(sc, txq->axq_qnum, &qi);
1659 [ - + ]: 24 : if (ret)
1660 : 0 : ath_err(common, "TXQ Update failed\n");
1661 : :
1662 : 24 : mutex_unlock(&sc->mutex);
1663 : 24 : ath9k_ps_restore(sc);
1664 : :
1665 : 24 : return ret;
1666 : : }
1667 : :
1668 : 0 : static int ath9k_set_key(struct ieee80211_hw *hw,
1669 : : enum set_key_cmd cmd,
1670 : : struct ieee80211_vif *vif,
1671 : : struct ieee80211_sta *sta,
1672 : : struct ieee80211_key_conf *key)
1673 : : {
1674 : 0 : struct ath_softc *sc = hw->priv;
1675 [ # # ]: 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1676 : 0 : struct ath_node *an = NULL;
1677 : 0 : int ret = 0, i;
1678 : :
1679 [ # # ]: 0 : if (ath9k_modparam_nohwcrypt)
1680 : : return -ENOSPC;
1681 : :
1682 [ # # # # ]: 0 : if ((vif->type == NL80211_IFTYPE_ADHOC ||
1683 : 0 : vif->type == NL80211_IFTYPE_MESH_POINT) &&
1684 [ # # # # ]: 0 : (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
1685 : 0 : key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
1686 [ # # ]: 0 : !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
1687 : : /*
1688 : : * For now, disable hw crypto for the RSN IBSS group keys. This
1689 : : * could be optimized in the future to use a modified key cache
1690 : : * design to support per-STA RX GTK, but until that gets
1691 : : * implemented, use of software crypto for group addressed
1692 : : * frames is a acceptable to allow RSN IBSS to be used.
1693 : : */
1694 : : return -EOPNOTSUPP;
1695 : : }
1696 : :
1697 : 0 : mutex_lock(&sc->mutex);
1698 : 0 : ath9k_ps_wakeup(sc);
1699 [ # # ]: 0 : ath_dbg(common, CONFIG, "Set HW Key %d\n", cmd);
1700 [ # # ]: 0 : if (sta)
1701 : 0 : an = (struct ath_node *)sta->drv_priv;
1702 : :
1703 [ # # # ]: 0 : switch (cmd) {
1704 : 0 : case SET_KEY:
1705 [ # # ]: 0 : if (sta)
1706 : 0 : ath9k_del_ps_key(sc, vif, sta);
1707 : :
1708 : 0 : key->hw_key_idx = 0;
1709 : 0 : ret = ath_key_config(common, vif, sta, key);
1710 [ # # ]: 0 : if (ret >= 0) {
1711 : 0 : key->hw_key_idx = ret;
1712 : : /* push IV and Michael MIC generation to stack */
1713 : 0 : key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1714 [ # # ]: 0 : if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1715 : 0 : key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1716 [ # # # # ]: 0 : if (sc->sc_ah->sw_mgmt_crypto_tx &&
1717 : : key->cipher == WLAN_CIPHER_SUITE_CCMP)
1718 : 0 : key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
1719 : : ret = 0;
1720 : : }
1721 [ # # # # ]: 0 : if (an && key->hw_key_idx) {
1722 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) {
1723 [ # # ]: 0 : if (an->key_idx[i])
1724 : 0 : continue;
1725 : 0 : an->key_idx[i] = key->hw_key_idx;
1726 : 0 : break;
1727 : : }
1728 [ # # ]: 0 : WARN_ON(i == ARRAY_SIZE(an->key_idx));
1729 : : }
1730 : : break;
1731 : 0 : case DISABLE_KEY:
1732 : 0 : ath_key_delete(common, key);
1733 [ # # ]: 0 : if (an) {
1734 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) {
1735 [ # # ]: 0 : if (an->key_idx[i] != key->hw_key_idx)
1736 : 0 : continue;
1737 : 0 : an->key_idx[i] = 0;
1738 : 0 : break;
1739 : : }
1740 : : }
1741 : 0 : key->hw_key_idx = 0;
1742 : 0 : break;
1743 : : default:
1744 : : ret = -EINVAL;
1745 : : }
1746 : :
1747 : 0 : ath9k_ps_restore(sc);
1748 : 0 : mutex_unlock(&sc->mutex);
1749 : :
1750 : 0 : return ret;
1751 : : }
1752 : :
1753 : 12 : static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1754 : : struct ieee80211_vif *vif,
1755 : : struct ieee80211_bss_conf *bss_conf,
1756 : : u32 changed)
1757 : : {
1758 : : #define CHECK_ANI \
1759 : : (BSS_CHANGED_ASSOC | \
1760 : : BSS_CHANGED_IBSS | \
1761 : : BSS_CHANGED_BEACON_ENABLED)
1762 : :
1763 : 12 : struct ath_softc *sc = hw->priv;
1764 : 12 : struct ath_hw *ah = sc->sc_ah;
1765 : 12 : struct ath_common *common = ath9k_hw_common(ah);
1766 : 12 : struct ath_vif *avp = (void *)vif->drv_priv;
1767 : 12 : int slottime;
1768 : :
1769 : 12 : ath9k_ps_wakeup(sc);
1770 : 12 : mutex_lock(&sc->mutex);
1771 : :
1772 [ - + ]: 12 : if (changed & BSS_CHANGED_ASSOC) {
1773 [ # # ]: 0 : ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n",
1774 : : bss_conf->bssid, bss_conf->assoc);
1775 : :
1776 : 0 : memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
1777 : 0 : avp->aid = bss_conf->aid;
1778 : 0 : avp->assoc = bss_conf->assoc;
1779 : :
1780 : 0 : ath9k_calculate_summary_state(sc, avp->chanctx);
1781 : : }
1782 : :
1783 [ - + ]: 12 : if ((changed & BSS_CHANGED_IBSS) ||
1784 : : (changed & BSS_CHANGED_OCB)) {
1785 : 0 : memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1786 : 0 : common->curaid = bss_conf->aid;
1787 : 0 : ath9k_hw_write_associd(sc->sc_ah);
1788 : : }
1789 : :
1790 : 12 : if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
1791 [ - + ]: 12 : (changed & BSS_CHANGED_BEACON_INT) ||
1792 : : (changed & BSS_CHANGED_BEACON_INFO)) {
1793 : 0 : ath9k_calculate_summary_state(sc, avp->chanctx);
1794 : : }
1795 : :
1796 [ + - ]: 12 : if ((avp->chanctx == sc->cur_chan) &&
1797 [ + + ]: 12 : (changed & BSS_CHANGED_ERP_SLOT)) {
1798 [ + - ]: 6 : if (bss_conf->use_short_slot)
1799 : : slottime = 9;
1800 : : else
1801 : 6 : slottime = 20;
1802 : :
1803 [ - + ]: 6 : if (vif->type == NL80211_IFTYPE_AP) {
1804 : : /*
1805 : : * Defer update, so that connected stations can adjust
1806 : : * their settings at the same time.
1807 : : * See beacon.c for more details
1808 : : */
1809 : 0 : sc->beacon.slottime = slottime;
1810 : 0 : sc->beacon.updateslot = UPDATE;
1811 : : } else {
1812 : 6 : ah->slottime = slottime;
1813 : 6 : ath9k_hw_init_global_settings(ah);
1814 : : }
1815 : : }
1816 : :
1817 : 12 : if (changed & BSS_CHANGED_P2P_PS)
1818 : : ath9k_p2p_bss_info_changed(sc, vif);
1819 : :
1820 [ - + ]: 12 : if (changed & CHECK_ANI)
1821 : 0 : ath_check_ani(sc);
1822 : :
1823 [ - + ]: 12 : if (changed & BSS_CHANGED_TXPOWER) {
1824 [ # # ]: 0 : ath_dbg(common, CONFIG, "vif %pM power %d dbm power_type %d\n",
1825 : : vif->addr, bss_conf->txpower, bss_conf->txpower_type);
1826 : 0 : ath9k_set_txpower(sc, vif);
1827 : : }
1828 : :
1829 : 12 : mutex_unlock(&sc->mutex);
1830 : 12 : ath9k_ps_restore(sc);
1831 : :
1832 : : #undef CHECK_ANI
1833 : 12 : }
1834 : :
1835 : 0 : static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1836 : : {
1837 : 0 : struct ath_softc *sc = hw->priv;
1838 : 0 : struct ath_vif *avp = (void *)vif->drv_priv;
1839 : 0 : u64 tsf;
1840 : :
1841 : 0 : mutex_lock(&sc->mutex);
1842 : 0 : ath9k_ps_wakeup(sc);
1843 : : /* Get current TSF either from HW or kernel time. */
1844 [ # # ]: 0 : if (sc->cur_chan == avp->chanctx) {
1845 : 0 : tsf = ath9k_hw_gettsf64(sc->sc_ah);
1846 : : } else {
1847 : 0 : tsf = sc->cur_chan->tsf_val +
1848 : 0 : ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
1849 : : }
1850 : 0 : tsf += le64_to_cpu(avp->tsf_adjust);
1851 : 0 : ath9k_ps_restore(sc);
1852 : 0 : mutex_unlock(&sc->mutex);
1853 : :
1854 : 0 : return tsf;
1855 : : }
1856 : :
1857 : 0 : static void ath9k_set_tsf(struct ieee80211_hw *hw,
1858 : : struct ieee80211_vif *vif,
1859 : : u64 tsf)
1860 : : {
1861 : 0 : struct ath_softc *sc = hw->priv;
1862 : 0 : struct ath_vif *avp = (void *)vif->drv_priv;
1863 : :
1864 : 0 : mutex_lock(&sc->mutex);
1865 : 0 : ath9k_ps_wakeup(sc);
1866 : 0 : tsf -= le64_to_cpu(avp->tsf_adjust);
1867 : 0 : ktime_get_raw_ts64(&avp->chanctx->tsf_ts);
1868 [ # # ]: 0 : if (sc->cur_chan == avp->chanctx)
1869 : 0 : ath9k_hw_settsf64(sc->sc_ah, tsf);
1870 : 0 : avp->chanctx->tsf_val = tsf;
1871 : 0 : ath9k_ps_restore(sc);
1872 : 0 : mutex_unlock(&sc->mutex);
1873 : 0 : }
1874 : :
1875 : 0 : static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1876 : : {
1877 : 0 : struct ath_softc *sc = hw->priv;
1878 : 0 : struct ath_vif *avp = (void *)vif->drv_priv;
1879 : :
1880 : 0 : mutex_lock(&sc->mutex);
1881 : :
1882 : 0 : ath9k_ps_wakeup(sc);
1883 : 0 : ktime_get_raw_ts64(&avp->chanctx->tsf_ts);
1884 [ # # ]: 0 : if (sc->cur_chan == avp->chanctx)
1885 : 0 : ath9k_hw_reset_tsf(sc->sc_ah);
1886 : 0 : avp->chanctx->tsf_val = 0;
1887 : 0 : ath9k_ps_restore(sc);
1888 : :
1889 : 0 : mutex_unlock(&sc->mutex);
1890 : 0 : }
1891 : :
1892 : 0 : static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1893 : : struct ieee80211_vif *vif,
1894 : : struct ieee80211_ampdu_params *params)
1895 : : {
1896 : 0 : struct ath_softc *sc = hw->priv;
1897 : 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1898 : 0 : bool flush = false;
1899 : 0 : int ret = 0;
1900 : 0 : struct ieee80211_sta *sta = params->sta;
1901 : 0 : struct ath_node *an = (struct ath_node *)sta->drv_priv;
1902 : 0 : enum ieee80211_ampdu_mlme_action action = params->action;
1903 : 0 : u16 tid = params->tid;
1904 : 0 : u16 *ssn = ¶ms->ssn;
1905 : 0 : struct ath_atx_tid *atid;
1906 : :
1907 : 0 : mutex_lock(&sc->mutex);
1908 : :
1909 [ # # # # : 0 : switch (action) {
# # ]
1910 : : case IEEE80211_AMPDU_RX_START:
1911 : : break;
1912 : : case IEEE80211_AMPDU_RX_STOP:
1913 : : break;
1914 : : case IEEE80211_AMPDU_TX_START:
1915 : 0 : if (ath9k_is_chanctx_enabled()) {
1916 : : if (test_bit(ATH_OP_SCANNING, &common->op_flags)) {
1917 : : ret = -EBUSY;
1918 : : break;
1919 : : }
1920 : : }
1921 : 0 : ath9k_ps_wakeup(sc);
1922 : 0 : ret = ath_tx_aggr_start(sc, sta, tid, ssn);
1923 [ # # ]: 0 : if (!ret)
1924 : 0 : ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
1925 : 0 : ath9k_ps_restore(sc);
1926 : 0 : break;
1927 : 0 : case IEEE80211_AMPDU_TX_STOP_FLUSH:
1928 : : case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1929 : 0 : flush = true;
1930 : : /* fall through */
1931 : 0 : case IEEE80211_AMPDU_TX_STOP_CONT:
1932 : 0 : ath9k_ps_wakeup(sc);
1933 : 0 : ath_tx_aggr_stop(sc, sta, tid);
1934 [ # # ]: 0 : if (!flush)
1935 : 0 : ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1936 : 0 : ath9k_ps_restore(sc);
1937 : 0 : break;
1938 : 0 : case IEEE80211_AMPDU_TX_OPERATIONAL:
1939 [ # # ]: 0 : atid = ath_node_to_tid(an, tid);
1940 : 0 : atid->baw_size = IEEE80211_MIN_AMPDU_BUF <<
1941 : 0 : sta->ht_cap.ampdu_factor;
1942 : 0 : break;
1943 : 0 : default:
1944 : 0 : ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
1945 : : }
1946 : :
1947 : 0 : mutex_unlock(&sc->mutex);
1948 : :
1949 : 0 : return ret;
1950 : : }
1951 : :
1952 : 0 : static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
1953 : : struct survey_info *survey)
1954 : : {
1955 : 0 : struct ath_softc *sc = hw->priv;
1956 : 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1957 : 0 : struct ieee80211_supported_band *sband;
1958 : 0 : struct ieee80211_channel *chan;
1959 : 0 : unsigned long flags;
1960 : 0 : int pos;
1961 : :
1962 : 0 : if (IS_ENABLED(CONFIG_ATH9K_TX99))
1963 : : return -EOPNOTSUPP;
1964 : :
1965 : 0 : spin_lock_irqsave(&common->cc_lock, flags);
1966 [ # # ]: 0 : if (idx == 0)
1967 : 0 : ath_update_survey_stats(sc);
1968 : :
1969 : 0 : sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
1970 [ # # # # ]: 0 : if (sband && idx >= sband->n_channels) {
1971 : 0 : idx -= sband->n_channels;
1972 : 0 : sband = NULL;
1973 : : }
1974 : :
1975 [ # # ]: 0 : if (!sband)
1976 : 0 : sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
1977 : :
1978 [ # # # # ]: 0 : if (!sband || idx >= sband->n_channels) {
1979 : 0 : spin_unlock_irqrestore(&common->cc_lock, flags);
1980 : 0 : return -ENOENT;
1981 : : }
1982 : :
1983 : 0 : chan = &sband->channels[idx];
1984 : 0 : pos = chan->hw_value;
1985 : 0 : memcpy(survey, &sc->survey[pos], sizeof(*survey));
1986 : 0 : survey->channel = chan;
1987 : 0 : spin_unlock_irqrestore(&common->cc_lock, flags);
1988 : :
1989 : 0 : return 0;
1990 : : }
1991 : :
1992 : : static void ath9k_enable_dynack(struct ath_softc *sc)
1993 : : {
1994 : : #ifdef CONFIG_ATH9K_DYNACK
1995 : : u32 rfilt;
1996 : : struct ath_hw *ah = sc->sc_ah;
1997 : :
1998 : : ath_dynack_reset(ah);
1999 : :
2000 : : ah->dynack.enabled = true;
2001 : : rfilt = ath_calcrxfilter(sc);
2002 : : ath9k_hw_setrxfilter(ah, rfilt);
2003 : : #endif
2004 : : }
2005 : :
2006 : 0 : static void ath9k_set_coverage_class(struct ieee80211_hw *hw,
2007 : : s16 coverage_class)
2008 : : {
2009 : 0 : struct ath_softc *sc = hw->priv;
2010 : 0 : struct ath_hw *ah = sc->sc_ah;
2011 : :
2012 : 0 : if (IS_ENABLED(CONFIG_ATH9K_TX99))
2013 : : return;
2014 : :
2015 : 0 : mutex_lock(&sc->mutex);
2016 : :
2017 [ # # ]: 0 : if (coverage_class >= 0) {
2018 : 0 : ah->coverage_class = coverage_class;
2019 [ # # ]: 0 : if (ah->dynack.enabled) {
2020 : 0 : u32 rfilt;
2021 : :
2022 : 0 : ah->dynack.enabled = false;
2023 : 0 : rfilt = ath_calcrxfilter(sc);
2024 : 0 : ath9k_hw_setrxfilter(ah, rfilt);
2025 : : }
2026 : 0 : ath9k_ps_wakeup(sc);
2027 : 0 : ath9k_hw_init_global_settings(ah);
2028 : 0 : ath9k_ps_restore(sc);
2029 : : } else if (!ah->dynack.enabled) {
2030 : : ath9k_enable_dynack(sc);
2031 : : }
2032 : :
2033 : 0 : mutex_unlock(&sc->mutex);
2034 : : }
2035 : :
2036 : 0 : static bool ath9k_has_tx_pending(struct ath_softc *sc,
2037 : : bool sw_pending)
2038 : : {
2039 : 0 : int i, npend = 0;
2040 : :
2041 [ # # ]: 0 : for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
2042 [ # # ]: 0 : if (!ATH_TXQ_SETUP(sc, i))
2043 : 0 : continue;
2044 : :
2045 : 0 : npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i],
2046 : : sw_pending);
2047 [ # # ]: 0 : if (npend)
2048 : : break;
2049 : : }
2050 : :
2051 : 0 : return !!npend;
2052 : : }
2053 : :
2054 : 0 : static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2055 : : u32 queues, bool drop)
2056 : : {
2057 : 0 : struct ath_softc *sc = hw->priv;
2058 : 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2059 : :
2060 : 0 : if (ath9k_is_chanctx_enabled()) {
2061 : : if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
2062 : : goto flush;
2063 : :
2064 : : /*
2065 : : * If MCC is active, extend the flush timeout
2066 : : * and wait for the HW/SW queues to become
2067 : : * empty. This needs to be done outside the
2068 : : * sc->mutex lock to allow the channel scheduler
2069 : : * to switch channel contexts.
2070 : : *
2071 : : * The vif queues have been stopped in mac80211,
2072 : : * so there won't be any incoming frames.
2073 : : */
2074 : : __ath9k_flush(hw, queues, drop, true, true);
2075 : : return;
2076 : : }
2077 : : flush:
2078 : 0 : mutex_lock(&sc->mutex);
2079 : 0 : __ath9k_flush(hw, queues, drop, true, false);
2080 : 0 : mutex_unlock(&sc->mutex);
2081 : : }
2082 : :
2083 : 0 : void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
2084 : : bool sw_pending, bool timeout_override)
2085 : : {
2086 : 0 : struct ath_softc *sc = hw->priv;
2087 : 0 : struct ath_hw *ah = sc->sc_ah;
2088 : 0 : struct ath_common *common = ath9k_hw_common(ah);
2089 : 0 : int timeout;
2090 : 0 : bool drain_txq;
2091 : :
2092 : 0 : cancel_delayed_work_sync(&sc->hw_check_work);
2093 : :
2094 [ # # ]: 0 : if (ah->ah_flags & AH_UNPLUGGED) {
2095 [ # # ]: 0 : ath_dbg(common, ANY, "Device has been unplugged!\n");
2096 : 0 : return;
2097 : : }
2098 : :
2099 [ # # ]: 0 : if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
2100 [ # # ]: 0 : ath_dbg(common, ANY, "Device not present\n");
2101 : 0 : return;
2102 : : }
2103 : :
2104 : 0 : spin_lock_bh(&sc->chan_lock);
2105 [ # # ]: 0 : if (timeout_override)
2106 : : timeout = HZ / 5;
2107 : : else
2108 : 0 : timeout = sc->cur_chan->flush_timeout;
2109 : 0 : spin_unlock_bh(&sc->chan_lock);
2110 : :
2111 [ # # ]: 0 : ath_dbg(common, CHAN_CTX,
2112 : : "Flush timeout: %d\n", jiffies_to_msecs(timeout));
2113 : :
2114 [ # # # # : 0 : if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc, sw_pending),
# # # # #
# # # # #
# # # # ]
2115 : : timeout) > 0)
2116 : : drop = false;
2117 : :
2118 [ # # ]: 0 : if (drop) {
2119 : 0 : ath9k_ps_wakeup(sc);
2120 : 0 : spin_lock_bh(&sc->sc_pcu_lock);
2121 : 0 : drain_txq = ath_drain_all_txq(sc);
2122 : 0 : spin_unlock_bh(&sc->sc_pcu_lock);
2123 : :
2124 [ # # ]: 0 : if (!drain_txq)
2125 : 0 : ath_reset(sc, NULL);
2126 : :
2127 : 0 : ath9k_ps_restore(sc);
2128 : : }
2129 : :
2130 : 0 : ieee80211_queue_delayed_work(hw, &sc->hw_check_work,
2131 : : ATH_HW_CHECK_POLL_INT);
2132 : : }
2133 : :
2134 : 0 : static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
2135 : : {
2136 : 0 : struct ath_softc *sc = hw->priv;
2137 : :
2138 : 0 : return ath9k_has_tx_pending(sc, true);
2139 : : }
2140 : :
2141 : 0 : static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
2142 : : {
2143 : 0 : struct ath_softc *sc = hw->priv;
2144 : 0 : struct ath_hw *ah = sc->sc_ah;
2145 : 0 : struct ieee80211_vif *vif;
2146 : 0 : struct ath_vif *avp;
2147 : 0 : struct ath_buf *bf;
2148 : 0 : struct ath_tx_status ts;
2149 : 0 : bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
2150 : 0 : int status;
2151 : :
2152 : 0 : vif = sc->beacon.bslot[0];
2153 [ # # ]: 0 : if (!vif)
2154 : : return 0;
2155 : :
2156 [ # # ]: 0 : if (!vif->bss_conf.enable_beacon)
2157 : : return 0;
2158 : :
2159 : 0 : avp = (void *)vif->drv_priv;
2160 : :
2161 [ # # # # ]: 0 : if (!sc->beacon.tx_processed && !edma) {
2162 : 0 : tasklet_disable(&sc->bcon_tasklet);
2163 : :
2164 : 0 : bf = avp->av_bcbuf;
2165 [ # # # # ]: 0 : if (!bf || !bf->bf_mpdu)
2166 : 0 : goto skip;
2167 : :
2168 : 0 : status = ath9k_hw_txprocdesc(ah, bf->bf_desc, &ts);
2169 [ # # ]: 0 : if (status == -EINPROGRESS)
2170 : 0 : goto skip;
2171 : :
2172 : 0 : sc->beacon.tx_processed = true;
2173 : 0 : sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);
2174 : :
2175 : 0 : skip:
2176 : 0 : tasklet_enable(&sc->bcon_tasklet);
2177 : : }
2178 : :
2179 : 0 : return sc->beacon.tx_last;
2180 : : }
2181 : :
2182 : 0 : static int ath9k_get_stats(struct ieee80211_hw *hw,
2183 : : struct ieee80211_low_level_stats *stats)
2184 : : {
2185 : 0 : struct ath_softc *sc = hw->priv;
2186 : 0 : struct ath_hw *ah = sc->sc_ah;
2187 : 0 : struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;
2188 : :
2189 : 0 : stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;
2190 : 0 : stats->dot11RTSFailureCount = mib_stats->rts_bad;
2191 : 0 : stats->dot11FCSErrorCount = mib_stats->fcs_bad;
2192 : 0 : stats->dot11RTSSuccessCount = mib_stats->rts_good;
2193 : 0 : return 0;
2194 : : }
2195 : :
2196 : 0 : static u32 fill_chainmask(u32 cap, u32 new)
2197 : : {
2198 : 0 : u32 filled = 0;
2199 : 0 : int i;
2200 : :
2201 [ # # # # : 0 : for (i = 0; cap && new; i++, cap >>= 1) {
# # # # ]
2202 [ # # # # ]: 0 : if (!(cap & BIT(0)))
2203 : 0 : continue;
2204 : :
2205 [ # # # # ]: 0 : if (new & BIT(0))
2206 : 0 : filled |= BIT(i);
2207 : :
2208 : 0 : new >>= 1;
2209 : : }
2210 : :
2211 : 0 : return filled;
2212 : : }
2213 : :
2214 : 0 : static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
2215 : : {
2216 : 0 : if (AR_SREV_9300_20_OR_LATER(ah))
2217 : : return true;
2218 : :
2219 [ # # # ]: 0 : switch (val & 0x7) {
2220 : : case 0x1:
2221 : : case 0x3:
2222 : : case 0x7:
2223 : : return true;
2224 : 0 : case 0x2:
2225 : 0 : return (ah->caps.rx_chainmask == 1);
2226 : : default:
2227 : : return false;
2228 : : }
2229 : : }
2230 : :
2231 : 0 : static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
2232 : : {
2233 : 0 : struct ath_softc *sc = hw->priv;
2234 : 0 : struct ath_hw *ah = sc->sc_ah;
2235 : :
2236 [ # # ]: 0 : if (ah->caps.rx_chainmask != 1)
2237 : 0 : rx_ant |= tx_ant;
2238 : :
2239 [ # # # # : 0 : if (!validate_antenna_mask(ah, rx_ant) || !tx_ant)
# # ]
2240 : : return -EINVAL;
2241 : :
2242 : 0 : sc->ant_rx = rx_ant;
2243 : 0 : sc->ant_tx = tx_ant;
2244 : :
2245 [ # # ]: 0 : if (ah->caps.rx_chainmask == 1)
2246 : : return 0;
2247 : :
2248 : : /* AR9100 runs into calibration issues if not all rx chains are enabled */
2249 [ # # ]: 0 : if (AR_SREV_9100(ah))
2250 : 0 : ah->rxchainmask = 0x7;
2251 : : else
2252 : 0 : ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant);
2253 : :
2254 : 0 : ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant);
2255 : 0 : ath9k_cmn_reload_chainmask(ah);
2256 : :
2257 : 0 : return 0;
2258 : : }
2259 : :
2260 : 6 : static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
2261 : : {
2262 : 6 : struct ath_softc *sc = hw->priv;
2263 : :
2264 : 6 : *tx_ant = sc->ant_tx;
2265 : 6 : *rx_ant = sc->ant_rx;
2266 : 6 : return 0;
2267 : : }
2268 : :
2269 : 0 : static void ath9k_sw_scan_start(struct ieee80211_hw *hw,
2270 : : struct ieee80211_vif *vif,
2271 : : const u8 *mac_addr)
2272 : : {
2273 : 0 : struct ath_softc *sc = hw->priv;
2274 : 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2275 : 0 : set_bit(ATH_OP_SCANNING, &common->op_flags);
2276 : 0 : }
2277 : :
2278 : 0 : static void ath9k_sw_scan_complete(struct ieee80211_hw *hw,
2279 : : struct ieee80211_vif *vif)
2280 : : {
2281 : 0 : struct ath_softc *sc = hw->priv;
2282 : 0 : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2283 : 0 : clear_bit(ATH_OP_SCANNING, &common->op_flags);
2284 : 0 : }
2285 : :
2286 : : #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
2287 : :
2288 : : static void ath9k_cancel_pending_offchannel(struct ath_softc *sc)
2289 : : {
2290 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2291 : :
2292 : : if (sc->offchannel.roc_vif) {
2293 : : ath_dbg(common, CHAN_CTX,
2294 : : "%s: Aborting RoC\n", __func__);
2295 : :
2296 : : del_timer_sync(&sc->offchannel.timer);
2297 : : if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START)
2298 : : ath_roc_complete(sc, ATH_ROC_COMPLETE_ABORT);
2299 : : }
2300 : :
2301 : : if (test_bit(ATH_OP_SCANNING, &common->op_flags)) {
2302 : : ath_dbg(common, CHAN_CTX,
2303 : : "%s: Aborting HW scan\n", __func__);
2304 : :
2305 : : del_timer_sync(&sc->offchannel.timer);
2306 : : ath_scan_complete(sc, true);
2307 : : }
2308 : : }
2309 : :
2310 : : static int ath9k_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2311 : : struct ieee80211_scan_request *hw_req)
2312 : : {
2313 : : struct cfg80211_scan_request *req = &hw_req->req;
2314 : : struct ath_softc *sc = hw->priv;
2315 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2316 : : int ret = 0;
2317 : :
2318 : : mutex_lock(&sc->mutex);
2319 : :
2320 : : if (WARN_ON(sc->offchannel.scan_req)) {
2321 : : ret = -EBUSY;
2322 : : goto out;
2323 : : }
2324 : :
2325 : : ath9k_ps_wakeup(sc);
2326 : : set_bit(ATH_OP_SCANNING, &common->op_flags);
2327 : : sc->offchannel.scan_vif = vif;
2328 : : sc->offchannel.scan_req = req;
2329 : : sc->offchannel.scan_idx = 0;
2330 : :
2331 : : ath_dbg(common, CHAN_CTX, "HW scan request received on vif: %pM\n",
2332 : : vif->addr);
2333 : :
2334 : : if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE) {
2335 : : ath_dbg(common, CHAN_CTX, "Starting HW scan\n");
2336 : : ath_offchannel_next(sc);
2337 : : }
2338 : :
2339 : : out:
2340 : : mutex_unlock(&sc->mutex);
2341 : :
2342 : : return ret;
2343 : : }
2344 : :
2345 : : static void ath9k_cancel_hw_scan(struct ieee80211_hw *hw,
2346 : : struct ieee80211_vif *vif)
2347 : : {
2348 : : struct ath_softc *sc = hw->priv;
2349 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2350 : :
2351 : : ath_dbg(common, CHAN_CTX, "Cancel HW scan on vif: %pM\n", vif->addr);
2352 : :
2353 : : mutex_lock(&sc->mutex);
2354 : : del_timer_sync(&sc->offchannel.timer);
2355 : : ath_scan_complete(sc, true);
2356 : : mutex_unlock(&sc->mutex);
2357 : : }
2358 : :
2359 : : static int ath9k_remain_on_channel(struct ieee80211_hw *hw,
2360 : : struct ieee80211_vif *vif,
2361 : : struct ieee80211_channel *chan, int duration,
2362 : : enum ieee80211_roc_type type)
2363 : : {
2364 : : struct ath_softc *sc = hw->priv;
2365 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2366 : : int ret = 0;
2367 : :
2368 : : mutex_lock(&sc->mutex);
2369 : :
2370 : : if (WARN_ON(sc->offchannel.roc_vif)) {
2371 : : ret = -EBUSY;
2372 : : goto out;
2373 : : }
2374 : :
2375 : : ath9k_ps_wakeup(sc);
2376 : : sc->offchannel.roc_vif = vif;
2377 : : sc->offchannel.roc_chan = chan;
2378 : : sc->offchannel.roc_duration = duration;
2379 : :
2380 : : ath_dbg(common, CHAN_CTX,
2381 : : "RoC request on vif: %pM, type: %d duration: %d\n",
2382 : : vif->addr, type, duration);
2383 : :
2384 : : if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE) {
2385 : : ath_dbg(common, CHAN_CTX, "Starting RoC period\n");
2386 : : ath_offchannel_next(sc);
2387 : : }
2388 : :
2389 : : out:
2390 : : mutex_unlock(&sc->mutex);
2391 : :
2392 : : return ret;
2393 : : }
2394 : :
2395 : : static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw,
2396 : : struct ieee80211_vif *vif)
2397 : : {
2398 : : struct ath_softc *sc = hw->priv;
2399 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2400 : :
2401 : : mutex_lock(&sc->mutex);
2402 : :
2403 : : ath_dbg(common, CHAN_CTX, "Cancel RoC\n");
2404 : : del_timer_sync(&sc->offchannel.timer);
2405 : :
2406 : : if (sc->offchannel.roc_vif) {
2407 : : if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START)
2408 : : ath_roc_complete(sc, ATH_ROC_COMPLETE_CANCEL);
2409 : : }
2410 : :
2411 : : mutex_unlock(&sc->mutex);
2412 : :
2413 : : return 0;
2414 : : }
2415 : :
2416 : : static int ath9k_add_chanctx(struct ieee80211_hw *hw,
2417 : : struct ieee80211_chanctx_conf *conf)
2418 : : {
2419 : : struct ath_softc *sc = hw->priv;
2420 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2421 : : struct ath_chanctx *ctx, **ptr;
2422 : : int pos;
2423 : :
2424 : : mutex_lock(&sc->mutex);
2425 : :
2426 : : ath_for_each_chanctx(sc, ctx) {
2427 : : if (ctx->assigned)
2428 : : continue;
2429 : :
2430 : : ptr = (void *) conf->drv_priv;
2431 : : *ptr = ctx;
2432 : : ctx->assigned = true;
2433 : : pos = ctx - &sc->chanctx[0];
2434 : : ctx->hw_queue_base = pos * IEEE80211_NUM_ACS;
2435 : :
2436 : : ath_dbg(common, CHAN_CTX,
2437 : : "Add channel context: %d MHz\n",
2438 : : conf->def.chan->center_freq);
2439 : :
2440 : : ath_chanctx_set_channel(sc, ctx, &conf->def);
2441 : :
2442 : : mutex_unlock(&sc->mutex);
2443 : : return 0;
2444 : : }
2445 : :
2446 : : mutex_unlock(&sc->mutex);
2447 : : return -ENOSPC;
2448 : : }
2449 : :
2450 : :
2451 : : static void ath9k_remove_chanctx(struct ieee80211_hw *hw,
2452 : : struct ieee80211_chanctx_conf *conf)
2453 : : {
2454 : : struct ath_softc *sc = hw->priv;
2455 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2456 : : struct ath_chanctx *ctx = ath_chanctx_get(conf);
2457 : :
2458 : : mutex_lock(&sc->mutex);
2459 : :
2460 : : ath_dbg(common, CHAN_CTX,
2461 : : "Remove channel context: %d MHz\n",
2462 : : conf->def.chan->center_freq);
2463 : :
2464 : : ctx->assigned = false;
2465 : : ctx->hw_queue_base = 0;
2466 : : ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_UNASSIGN);
2467 : :
2468 : : mutex_unlock(&sc->mutex);
2469 : : }
2470 : :
2471 : : static void ath9k_change_chanctx(struct ieee80211_hw *hw,
2472 : : struct ieee80211_chanctx_conf *conf,
2473 : : u32 changed)
2474 : : {
2475 : : struct ath_softc *sc = hw->priv;
2476 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2477 : : struct ath_chanctx *ctx = ath_chanctx_get(conf);
2478 : :
2479 : : mutex_lock(&sc->mutex);
2480 : : ath_dbg(common, CHAN_CTX,
2481 : : "Change channel context: %d MHz\n",
2482 : : conf->def.chan->center_freq);
2483 : : ath_chanctx_set_channel(sc, ctx, &conf->def);
2484 : : mutex_unlock(&sc->mutex);
2485 : : }
2486 : :
2487 : : static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw,
2488 : : struct ieee80211_vif *vif,
2489 : : struct ieee80211_chanctx_conf *conf)
2490 : : {
2491 : : struct ath_softc *sc = hw->priv;
2492 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2493 : : struct ath_vif *avp = (void *)vif->drv_priv;
2494 : : struct ath_chanctx *ctx = ath_chanctx_get(conf);
2495 : : int i;
2496 : :
2497 : : ath9k_cancel_pending_offchannel(sc);
2498 : :
2499 : : mutex_lock(&sc->mutex);
2500 : :
2501 : : ath_dbg(common, CHAN_CTX,
2502 : : "Assign VIF (addr: %pM, type: %d, p2p: %d) to channel context: %d MHz\n",
2503 : : vif->addr, vif->type, vif->p2p,
2504 : : conf->def.chan->center_freq);
2505 : :
2506 : : avp->chanctx = ctx;
2507 : : ctx->nvifs_assigned++;
2508 : : list_add_tail(&avp->list, &ctx->vifs);
2509 : : ath9k_calculate_summary_state(sc, ctx);
2510 : : for (i = 0; i < IEEE80211_NUM_ACS; i++)
2511 : : vif->hw_queue[i] = ctx->hw_queue_base + i;
2512 : :
2513 : : mutex_unlock(&sc->mutex);
2514 : :
2515 : : return 0;
2516 : : }
2517 : :
2518 : : static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,
2519 : : struct ieee80211_vif *vif,
2520 : : struct ieee80211_chanctx_conf *conf)
2521 : : {
2522 : : struct ath_softc *sc = hw->priv;
2523 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2524 : : struct ath_vif *avp = (void *)vif->drv_priv;
2525 : : struct ath_chanctx *ctx = ath_chanctx_get(conf);
2526 : : int ac;
2527 : :
2528 : : ath9k_cancel_pending_offchannel(sc);
2529 : :
2530 : : mutex_lock(&sc->mutex);
2531 : :
2532 : : ath_dbg(common, CHAN_CTX,
2533 : : "Remove VIF (addr: %pM, type: %d, p2p: %d) from channel context: %d MHz\n",
2534 : : vif->addr, vif->type, vif->p2p,
2535 : : conf->def.chan->center_freq);
2536 : :
2537 : : avp->chanctx = NULL;
2538 : : ctx->nvifs_assigned--;
2539 : : list_del(&avp->list);
2540 : : ath9k_calculate_summary_state(sc, ctx);
2541 : : for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
2542 : : vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE;
2543 : :
2544 : : mutex_unlock(&sc->mutex);
2545 : : }
2546 : :
2547 : : static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw,
2548 : : struct ieee80211_vif *vif,
2549 : : u16 duration)
2550 : : {
2551 : : struct ath_softc *sc = hw->priv;
2552 : : struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2553 : : struct ath_vif *avp = (struct ath_vif *) vif->drv_priv;
2554 : : struct ath_beacon_config *cur_conf;
2555 : : struct ath_chanctx *go_ctx;
2556 : : unsigned long timeout;
2557 : : bool changed = false;
2558 : : u32 beacon_int;
2559 : :
2560 : : if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
2561 : : return;
2562 : :
2563 : : if (!avp->chanctx)
2564 : : return;
2565 : :
2566 : : mutex_lock(&sc->mutex);
2567 : :
2568 : : spin_lock_bh(&sc->chan_lock);
2569 : : if (sc->next_chan || (sc->cur_chan != avp->chanctx))
2570 : : changed = true;
2571 : : spin_unlock_bh(&sc->chan_lock);
2572 : :
2573 : : if (!changed)
2574 : : goto out;
2575 : :
2576 : : ath9k_cancel_pending_offchannel(sc);
2577 : :
2578 : : go_ctx = ath_is_go_chanctx_present(sc);
2579 : :
2580 : : if (go_ctx) {
2581 : : /*
2582 : : * Wait till the GO interface gets a chance
2583 : : * to send out an NoA.
2584 : : */
2585 : : spin_lock_bh(&sc->chan_lock);
2586 : : sc->sched.mgd_prepare_tx = true;
2587 : : cur_conf = &go_ctx->beacon;
2588 : : beacon_int = TU_TO_USEC(cur_conf->beacon_interval);
2589 : : spin_unlock_bh(&sc->chan_lock);
2590 : :
2591 : : timeout = usecs_to_jiffies(beacon_int * 2);
2592 : : init_completion(&sc->go_beacon);
2593 : :
2594 : : mutex_unlock(&sc->mutex);
2595 : :
2596 : : if (wait_for_completion_timeout(&sc->go_beacon,
2597 : : timeout) == 0) {
2598 : : ath_dbg(common, CHAN_CTX,
2599 : : "Failed to send new NoA\n");
2600 : :
2601 : : spin_lock_bh(&sc->chan_lock);
2602 : : sc->sched.mgd_prepare_tx = false;
2603 : : spin_unlock_bh(&sc->chan_lock);
2604 : : }
2605 : :
2606 : : mutex_lock(&sc->mutex);
2607 : : }
2608 : :
2609 : : ath_dbg(common, CHAN_CTX,
2610 : : "%s: Set chanctx state to FORCE_ACTIVE for vif: %pM\n",
2611 : : __func__, vif->addr);
2612 : :
2613 : : spin_lock_bh(&sc->chan_lock);
2614 : : sc->next_chan = avp->chanctx;
2615 : : sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE;
2616 : : spin_unlock_bh(&sc->chan_lock);
2617 : :
2618 : : ath_chanctx_set_next(sc, true);
2619 : : out:
2620 : : mutex_unlock(&sc->mutex);
2621 : : }
2622 : :
2623 : : void ath9k_fill_chanctx_ops(void)
2624 : : {
2625 : : if (!ath9k_is_chanctx_enabled())
2626 : : return;
2627 : :
2628 : : ath9k_ops.hw_scan = ath9k_hw_scan;
2629 : : ath9k_ops.cancel_hw_scan = ath9k_cancel_hw_scan;
2630 : : ath9k_ops.remain_on_channel = ath9k_remain_on_channel;
2631 : : ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel;
2632 : : ath9k_ops.add_chanctx = ath9k_add_chanctx;
2633 : : ath9k_ops.remove_chanctx = ath9k_remove_chanctx;
2634 : : ath9k_ops.change_chanctx = ath9k_change_chanctx;
2635 : : ath9k_ops.assign_vif_chanctx = ath9k_assign_vif_chanctx;
2636 : : ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx;
2637 : : ath9k_ops.mgd_prepare_tx = ath9k_mgd_prepare_tx;
2638 : : }
2639 : :
2640 : : #endif
2641 : :
2642 : 6 : static int ath9k_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2643 : : int *dbm)
2644 : : {
2645 : 6 : struct ath_softc *sc = hw->priv;
2646 : 6 : struct ath_vif *avp = (void *)vif->drv_priv;
2647 : :
2648 : 6 : mutex_lock(&sc->mutex);
2649 [ - + ]: 6 : if (avp->chanctx)
2650 : 0 : *dbm = avp->chanctx->cur_txpower;
2651 : : else
2652 : 6 : *dbm = sc->cur_chan->cur_txpower;
2653 : 6 : mutex_unlock(&sc->mutex);
2654 : :
2655 : 6 : *dbm /= 2;
2656 : :
2657 : 6 : return 0;
2658 : : }
2659 : :
2660 : : struct ieee80211_ops ath9k_ops = {
2661 : : .tx = ath9k_tx,
2662 : : .start = ath9k_start,
2663 : : .stop = ath9k_stop,
2664 : : .add_interface = ath9k_add_interface,
2665 : : .change_interface = ath9k_change_interface,
2666 : : .remove_interface = ath9k_remove_interface,
2667 : : .config = ath9k_config,
2668 : : .configure_filter = ath9k_configure_filter,
2669 : : .sta_state = ath9k_sta_state,
2670 : : .sta_notify = ath9k_sta_notify,
2671 : : .conf_tx = ath9k_conf_tx,
2672 : : .bss_info_changed = ath9k_bss_info_changed,
2673 : : .set_key = ath9k_set_key,
2674 : : .get_tsf = ath9k_get_tsf,
2675 : : .set_tsf = ath9k_set_tsf,
2676 : : .reset_tsf = ath9k_reset_tsf,
2677 : : .ampdu_action = ath9k_ampdu_action,
2678 : : .get_survey = ath9k_get_survey,
2679 : : .rfkill_poll = ath9k_rfkill_poll_state,
2680 : : .set_coverage_class = ath9k_set_coverage_class,
2681 : : .flush = ath9k_flush,
2682 : : .tx_frames_pending = ath9k_tx_frames_pending,
2683 : : .tx_last_beacon = ath9k_tx_last_beacon,
2684 : : .release_buffered_frames = ath9k_release_buffered_frames,
2685 : : .get_stats = ath9k_get_stats,
2686 : : .set_antenna = ath9k_set_antenna,
2687 : : .get_antenna = ath9k_get_antenna,
2688 : :
2689 : : #ifdef CONFIG_ATH9K_WOW
2690 : : .suspend = ath9k_suspend,
2691 : : .resume = ath9k_resume,
2692 : : .set_wakeup = ath9k_set_wakeup,
2693 : : #endif
2694 : :
2695 : : #ifdef CONFIG_ATH9K_DEBUGFS
2696 : : .get_et_sset_count = ath9k_get_et_sset_count,
2697 : : .get_et_stats = ath9k_get_et_stats,
2698 : : .get_et_strings = ath9k_get_et_strings,
2699 : : #endif
2700 : :
2701 : : #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_STATION_STATISTICS)
2702 : : .sta_add_debugfs = ath9k_sta_add_debugfs,
2703 : : #endif
2704 : : .sw_scan_start = ath9k_sw_scan_start,
2705 : : .sw_scan_complete = ath9k_sw_scan_complete,
2706 : : .get_txpower = ath9k_get_txpower,
2707 : : .wake_tx_queue = ath9k_wake_tx_queue,
2708 : : };
|