main.c 61.5 KB
Newer Older
1
/*
2
 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/nl80211.h>
18
#include <linux/delay.h>
S
Sujith 已提交
19
#include "ath9k.h"
20
#include "btcoex.h"
21

22
u8 ath9k_parse_mpdudensity(u8 mpdudensity)
S
Sujith 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
{
	/*
	 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
	 *   0 for no restriction
	 *   1 for 1/4 us
	 *   2 for 1/2 us
	 *   3 for 1 us
	 *   4 for 2 us
	 *   5 for 4 us
	 *   6 for 8 us
	 *   7 for 16 us
	 */
	switch (mpdudensity) {
	case 0:
		return 0;
	case 1:
	case 2:
	case 3:
		/* Our lower layer calculations limit our precision to
		   1 microsecond */
		return 1;
	case 4:
		return 2;
	case 5:
		return 4;
	case 6:
		return 8;
	case 7:
		return 16;
	default:
		return 0;
	}
}

57 58
static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq,
				     bool sw_pending)
59 60 61 62 63
{
	bool pending = false;

	spin_lock_bh(&txq->axq_lock);

64
	if (txq->axq_depth) {
65
		pending = true;
66 67
		goto out;
	}
68

69 70 71
	if (!sw_pending)
		goto out;

72 73 74 75 76 77 78
	if (txq->mac80211_qnum >= 0) {
		struct list_head *list;

		list = &sc->cur_chan->acq[txq->mac80211_qnum];
		if (!list_empty(list))
			pending = true;
	}
79
out:
80 81 82 83
	spin_unlock_bh(&txq->axq_lock);
	return pending;
}

84
static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
85 86 87 88
{
	unsigned long flags;
	bool ret;

89 90 91
	spin_lock_irqsave(&sc->sc_pm_lock, flags);
	ret = ath9k_hw_setpower(sc->sc_ah, mode);
	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
92 93 94 95

	return ret;
}

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
void ath_ps_full_sleep(unsigned long data)
{
	struct ath_softc *sc = (struct ath_softc *) data;
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	bool reset;

	spin_lock(&common->cc_lock);
	ath_hw_cycle_counters_update(common);
	spin_unlock(&common->cc_lock);

	ath9k_hw_setrxabort(sc->sc_ah, 1);
	ath9k_hw_stopdmarecv(sc->sc_ah, &reset);

	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
}

112 113
void ath9k_ps_wakeup(struct ath_softc *sc)
{
114
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
115
	unsigned long flags;
116
	enum ath9k_power_mode power_mode;
117 118 119 120 121

	spin_lock_irqsave(&sc->sc_pm_lock, flags);
	if (++sc->ps_usecount != 1)
		goto unlock;

122
	del_timer_sync(&sc->sleep_timer);
123
	power_mode = sc->sc_ah->power_mode;
124
	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
125

126 127 128 129 130
	/*
	 * While the hardware is asleep, the cycle counters contain no
	 * useful data. Better clear them now so that they don't mess up
	 * survey data results.
	 */
131 132 133 134
	if (power_mode != ATH9K_PM_AWAKE) {
		spin_lock(&common->cc_lock);
		ath_hw_cycle_counters_update(common);
		memset(&common->cc_survey, 0, sizeof(common->cc_survey));
135
		memset(&common->cc_ani, 0, sizeof(common->cc_ani));
136 137
		spin_unlock(&common->cc_lock);
	}
138

139 140 141 142 143 144
 unlock:
	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}

void ath9k_ps_restore(struct ath_softc *sc)
{
145
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
F
Felix Fietkau 已提交
146
	enum ath9k_power_mode mode;
147 148 149 150 151 152
	unsigned long flags;

	spin_lock_irqsave(&sc->sc_pm_lock, flags);
	if (--sc->ps_usecount != 0)
		goto unlock;

S
Sujith Manoharan 已提交
153
	if (sc->ps_idle) {
154 155 156 157 158
		mod_timer(&sc->sleep_timer, jiffies + HZ / 10);
		goto unlock;
	}

	if (sc->ps_enabled &&
S
Sujith Manoharan 已提交
159 160 161
		   !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
				     PS_WAIT_FOR_CAB |
				     PS_WAIT_FOR_PSPOLL_DATA |
162 163
				     PS_WAIT_FOR_TX_ACK |
				     PS_WAIT_FOR_ANI))) {
F
Felix Fietkau 已提交
164
		mode = ATH9K_PM_NETWORK_SLEEP;
165 166
		if (ath9k_hw_btcoex_is_enabled(sc->sc_ah))
			ath9k_btcoex_stop_gen_timer(sc);
S
Sujith Manoharan 已提交
167
	} else {
F
Felix Fietkau 已提交
168
		goto unlock;
S
Sujith Manoharan 已提交
169
	}
F
Felix Fietkau 已提交
170 171 172 173 174

	spin_lock(&common->cc_lock);
	ath_hw_cycle_counters_update(common);
	spin_unlock(&common->cc_lock);

175
	ath9k_hw_setpower(sc->sc_ah, mode);
176 177 178 179 180

 unlock:
	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}

181
static void __ath_cancel_work(struct ath_softc *sc)
S
Sujith 已提交
182
{
183 184
	cancel_work_sync(&sc->paprd_work);
	cancel_delayed_work_sync(&sc->tx_complete_work);
185
	cancel_delayed_work_sync(&sc->hw_pll_work);
S
Sujith Manoharan 已提交
186

187
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
S
Sujith Manoharan 已提交
188 189
	if (ath9k_hw_mci_is_enabled(sc->sc_ah))
		cancel_work_sync(&sc->mci_work);
190
#endif
191
}
192

S
Sujith Manoharan 已提交
193
void ath_cancel_work(struct ath_softc *sc)
194 195 196 197
{
	__ath_cancel_work(sc);
	cancel_work_sync(&sc->hw_reset_work);
}
198

S
Sujith Manoharan 已提交
199
void ath_restart_work(struct ath_softc *sc)
S
Sujith Manoharan 已提交
200 201 202
{
	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);

203
	if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah))
S
Sujith Manoharan 已提交
204 205 206
		ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
				     msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));

S
Sujith Manoharan 已提交
207
	ath_start_ani(sc);
S
Sujith Manoharan 已提交
208 209
}

210
static bool ath_prepare_reset(struct ath_softc *sc)
211 212
{
	struct ath_hw *ah = sc->sc_ah;
213
	bool ret = true;
214

215
	ieee80211_stop_queues(sc->hw);
S
Sujith Manoharan 已提交
216
	ath_stop_ani(sc);
217
	ath9k_hw_disable_interrupts(ah);
218

219
	if (!ath_drain_all_txq(sc))
220
		ret = false;
221

F
Felix Fietkau 已提交
222
	if (!ath_stoprecv(sc))
223 224
		ret = false;

225 226
	return ret;
}
S
Sujith 已提交
227

228 229 230 231
static bool ath_complete_reset(struct ath_softc *sc, bool start)
{
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
232
	unsigned long flags;
233

234
	ath9k_calculate_summary_state(sc, sc->cur_chan);
S
Sujith Manoharan 已提交
235
	ath_startrecv(sc);
236
	ath9k_cmn_update_txpow(ah, sc->curtxpow,
237
			       sc->cur_chan->txpower, &sc->curtxpow);
238
	clear_bit(ATH_OP_HW_RESET, &common->op_flags);
239

240
	if (!sc->cur_chan->offchannel && start) {
241 242 243 244 245 246 247 248 249 250
		/* restore per chanctx TSF timer */
		if (sc->cur_chan->tsf_val) {
			u32 offset;

			offset = ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts,
							 NULL);
			ath9k_hw_settsf64(ah, sc->cur_chan->tsf_val + offset);
		}


251
		if (!test_bit(ATH_OP_BEACONS, &common->op_flags))
252 253 254
			goto work;

		if (ah->opmode == NL80211_IFTYPE_STATION &&
255
		    test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) {
256 257 258
			spin_lock_irqsave(&sc->sc_pm_lock, flags);
			sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
			spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
259 260
		} else {
			ath9k_set_beacon(sc);
261 262
		}
	work:
S
Sujith Manoharan 已提交
263
		ath_restart_work(sc);
264
		ath_txq_schedule_all(sc);
265 266
	}

S
Sujith Manoharan 已提交
267
	sc->gtt_cnt = 0;
268 269 270

	ath9k_hw_set_interrupts(ah);
	ath9k_hw_enable_interrupts(ah);
271
	ieee80211_wake_queues(sc->hw);
272 273
	ath9k_p2p_ps_timer(sc);

274 275 276
	return true;
}

S
Sujith Manoharan 已提交
277
static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
278 279 280 281 282 283 284 285 286
{
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_cal_data *caldata = NULL;
	bool fastcc = true;
	int r;

	__ath_cancel_work(sc);

287
	tasklet_disable(&sc->intr_tq);
288
	tasklet_disable(&sc->bcon_tasklet);
289
	spin_lock_bh(&sc->sc_pcu_lock);
290

291
	if (!sc->cur_chan->offchannel) {
292
		fastcc = false;
293
		caldata = &sc->cur_chan->caldata;
294 295 296 297 298 299 300
	}

	if (!hchan) {
		fastcc = false;
		hchan = ah->curchan;
	}

301
	if (!ath_prepare_reset(sc))
302 303
		fastcc = false;

304 305 306
	if (ath9k_is_chanctx_enabled())
		fastcc = false;

307 308 309
	spin_lock_bh(&sc->chan_lock);
	sc->cur_chandef = sc->cur_chan->chandef;
	spin_unlock_bh(&sc->chan_lock);
310

311
	ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
312
		hchan->channel, IS_CHAN_HT40(hchan), fastcc);
313 314 315 316 317

	r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
	if (r) {
		ath_err(common,
			"Unable to reset channel, reset status %d\n", r);
318 319 320 321

		ath9k_hw_enable_interrupts(ah);
		ath9k_queue_reset(sc, RESET_TYPE_BB_HANG);

322 323 324
		goto out;
	}

325
	if (ath9k_hw_mci_is_enabled(sc->sc_ah) &&
326
	    sc->cur_chan->offchannel)
327 328
		ath9k_mci_set_txpower(sc, true, false);

329 330 331 332
	if (!ath_complete_reset(sc, true))
		r = -EIO;

out:
333
	spin_unlock_bh(&sc->sc_pcu_lock);
334
	tasklet_enable(&sc->bcon_tasklet);
335 336
	tasklet_enable(&sc->intr_tq);

337 338 339
	return r;
}

340 341
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
			    struct ieee80211_vif *vif)
S
Sujith 已提交
342 343 344 345
{
	struct ath_node *an;
	an = (struct ath_node *)sta->drv_priv;

346
	an->sc = sc;
347
	an->sta = sta;
348
	an->vif = vif;
349
	memset(&an->key_idx, 0, sizeof(an->key_idx));
350

351
	ath_tx_node_init(sc, an);
352 353

	ath_dynack_node_init(sc->sc_ah, an);
S
Sujith 已提交
354 355 356 357 358
}

static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
{
	struct ath_node *an = (struct ath_node *)sta->drv_priv;
359
	ath_tx_node_cleanup(sc, an);
360 361

	ath_dynack_node_deinit(sc->sc_ah, an);
S
Sujith 已提交
362 363
}

S
Sujith 已提交
364
void ath9k_tasklet(unsigned long data)
S
Sujith 已提交
365 366
{
	struct ath_softc *sc = (struct ath_softc *)data;
367
	struct ath_hw *ah = sc->sc_ah;
368
	struct ath_common *common = ath9k_hw_common(ah);
369
	enum ath_reset_type type;
S
Sujith Manoharan 已提交
370
	unsigned long flags;
S
Sujith 已提交
371
	u32 status = sc->intrstatus;
F
Felix Fietkau 已提交
372
	u32 rxmask;
S
Sujith 已提交
373

374 375 376
	ath9k_ps_wakeup(sc);
	spin_lock(&sc->sc_pcu_lock);

377 378
	if (status & ATH9K_INT_FATAL) {
		type = RESET_TYPE_FATAL_INT;
379
		ath9k_queue_reset(sc, type);
380 381 382 383 384 385

		/*
		 * Increment the ref. counter here so that
		 * interrupts are enabled in the reset routine.
		 */
		atomic_inc(&ah->intr_ref_cnt);
386
		ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
387
		goto out;
S
Sujith 已提交
388
	}
S
Sujith 已提交
389

390 391
	if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) &&
	    (status & ATH9K_INT_BB_WATCHDOG)) {
392 393 394 395 396
		spin_lock(&common->cc_lock);
		ath_hw_cycle_counters_update(common);
		ar9003_hw_bb_watchdog_dbg_info(ah);
		spin_unlock(&common->cc_lock);

397 398 399 400 401 402 403 404 405
		if (ar9003_hw_bb_watchdog_check(ah)) {
			type = RESET_TYPE_BB_WATCHDOG;
			ath9k_queue_reset(sc, type);

			/*
			 * Increment the ref. counter here so that
			 * interrupts are enabled in the reset routine.
			 */
			atomic_inc(&ah->intr_ref_cnt);
406
			ath_dbg(common, RESET,
407 408 409 410 411
				"BB_WATCHDOG: Skipping interrupts\n");
			goto out;
		}
	}

S
Sujith Manoharan 已提交
412 413 414 415 416 417 418
	if (status & ATH9K_INT_GTT) {
		sc->gtt_cnt++;

		if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
			type = RESET_TYPE_TX_GTT;
			ath9k_queue_reset(sc, type);
			atomic_inc(&ah->intr_ref_cnt);
419
			ath_dbg(common, RESET,
S
Sujith Manoharan 已提交
420 421 422 423 424
				"GTT: Skipping interrupts\n");
			goto out;
		}
	}

S
Sujith Manoharan 已提交
425
	spin_lock_irqsave(&sc->sc_pm_lock, flags);
426 427 428 429 430
	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
		/*
		 * TSF sync does not look correct; remain awake to sync with
		 * the next Beacon.
		 */
431
		ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n");
432
		sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
433
	}
S
Sujith Manoharan 已提交
434
	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
435

F
Felix Fietkau 已提交
436 437 438 439 440 441 442 443 444 445 446 447 448
	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
		rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
			  ATH9K_INT_RXORN);
	else
		rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);

	if (status & rxmask) {
		/* Check for high priority Rx first */
		if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
		    (status & ATH9K_INT_RXHP))
			ath_rx_tasklet(sc, 0, true);

		ath_rx_tasklet(sc, 0, false);
S
Sujith 已提交
449 450
	}

451
	if (status & ATH9K_INT_TX) {
S
Sujith Manoharan 已提交
452 453 454 455 456 457 458
		if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
			/*
			 * For EDMA chips, TX completion is enabled for the
			 * beacon queue, so if a beacon has been transmitted
			 * successfully after a GTT interrupt, the GTT counter
			 * gets reset to zero here.
			 */
S
Sujith Manoharan 已提交
459
			sc->gtt_cnt = 0;
S
Sujith Manoharan 已提交
460

461
			ath_tx_edma_tasklet(sc);
S
Sujith Manoharan 已提交
462
		} else {
463
			ath_tx_tasklet(sc);
S
Sujith Manoharan 已提交
464
		}
F
Felix Fietkau 已提交
465 466

		wake_up(&sc->tx_wait);
467
	}
S
Sujith 已提交
468

469 470 471
	if (status & ATH9K_INT_GENTIMER)
		ath_gen_timer_isr(sc->sc_ah);

472
	ath9k_btcoex_handle_interrupt(sc, status);
473

S
Sujith 已提交
474
	/* re-enable hardware interrupt */
475
	ath9k_hw_enable_interrupts(ah);
476
out:
477
	spin_unlock(&sc->sc_pcu_lock);
478
	ath9k_ps_restore(sc);
S
Sujith 已提交
479 480
}

481
irqreturn_t ath_isr(int irq, void *dev)
S
Sujith 已提交
482
{
S
Sujith 已提交
483 484
#define SCHED_INTR (				\
		ATH9K_INT_FATAL |		\
485
		ATH9K_INT_BB_WATCHDOG |		\
S
Sujith 已提交
486 487 488
		ATH9K_INT_RXORN |		\
		ATH9K_INT_RXEOL |		\
		ATH9K_INT_RX |			\
F
Felix Fietkau 已提交
489 490
		ATH9K_INT_RXLP |		\
		ATH9K_INT_RXHP |		\
S
Sujith 已提交
491 492 493
		ATH9K_INT_TX |			\
		ATH9K_INT_BMISS |		\
		ATH9K_INT_CST |			\
S
Sujith Manoharan 已提交
494
		ATH9K_INT_GTT |			\
495
		ATH9K_INT_TSFOOR |		\
496 497
		ATH9K_INT_GENTIMER |		\
		ATH9K_INT_MCI)
S
Sujith 已提交
498

S
Sujith 已提交
499
	struct ath_softc *sc = dev;
500
	struct ath_hw *ah = sc->sc_ah;
501
	struct ath_common *common = ath9k_hw_common(ah);
S
Sujith 已提交
502
	enum ath9k_int status;
503
	u32 sync_cause = 0;
S
Sujith 已提交
504 505
	bool sched = false;

S
Sujith 已提交
506 507 508 509 510
	/*
	 * The hardware is not ready/present, don't
	 * touch anything. Note this can happen early
	 * on if the IRQ is shared.
	 */
511
	if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags))
S
Sujith 已提交
512
		return IRQ_NONE;
S
Sujith 已提交
513

S
Sujith 已提交
514 515
	/* shared irq, not for us */

516
	if (!ath9k_hw_intrpend(ah))
S
Sujith 已提交
517 518
		return IRQ_NONE;

519
	if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) {
520
		ath9k_hw_kill_interrupts(ah);
521
		return IRQ_HANDLED;
522
	}
523

S
Sujith 已提交
524 525 526 527 528 529
	/*
	 * Figure out the reason(s) for the interrupt.  Note
	 * that the hal returns a pseudo-ISR that may include
	 * bits we haven't explicitly enabled so we mask the
	 * value to insure we only process bits we requested.
	 */
530 531
	ath9k_hw_getisr(ah, &status, &sync_cause); /* NB: clears ISR too */
	ath9k_debug_sync_cause(sc, sync_cause);
P
Pavel Roskin 已提交
532
	status &= ah->imask;	/* discard unasked-for bits */
S
Sujith 已提交
533

S
Sujith 已提交
534 535 536 537
	/*
	 * If there are no status bits set, then this interrupt was not
	 * for me (should have been caught above).
	 */
538
	if (!status)
S
Sujith 已提交
539
		return IRQ_NONE;
S
Sujith 已提交
540

S
Sujith 已提交
541 542 543 544 545 546 547 548 549 550
	/* Cache the status */
	sc->intrstatus = status;

	if (status & SCHED_INTR)
		sched = true;

	/*
	 * If a FATAL or RXORN interrupt is received, we have to reset the
	 * chip immediately.
	 */
F
Felix Fietkau 已提交
551 552
	if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
	    !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
S
Sujith 已提交
553 554
		goto chip_reset;

555
	if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) &&
556
	    (status & ATH9K_INT_BB_WATCHDOG))
557
		goto chip_reset;
S
Sujith Manoharan 已提交
558 559

#ifdef CONFIG_ATH9K_WOW
560 561 562 563 564 565 566
	if (status & ATH9K_INT_BMISS) {
		if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
			atomic_inc(&sc->wow_got_bmiss_intr);
			atomic_dec(&sc->wow_sleep_proc_intr);
		}
	}
#endif
S
Sujith Manoharan 已提交
567

S
Sujith 已提交
568 569 570 571 572 573
	if (status & ATH9K_INT_SWBA)
		tasklet_schedule(&sc->bcon_tasklet);

	if (status & ATH9K_INT_TXURN)
		ath9k_hw_updatetxtriglevel(ah, true);

574 575
	if (status & ATH9K_INT_RXEOL) {
		ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
576
		ath9k_hw_set_interrupts(ah);
F
Felix Fietkau 已提交
577 578
	}

579 580
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
		if (status & ATH9K_INT_TIM_TIMER) {
581 582
			if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle))
				goto chip_reset;
S
Sujith 已提交
583 584
			/* Clear RxAbort bit so that we can
			 * receive frames */
585
			ath9k_setpower(sc, ATH9K_PM_AWAKE);
S
Sujith Manoharan 已提交
586
			spin_lock(&sc->sc_pm_lock);
587
			ath9k_hw_setrxabort(sc->sc_ah, 0);
S
Sujith 已提交
588
			sc->ps_flags |= PS_WAIT_FOR_BEACON;
S
Sujith Manoharan 已提交
589
			spin_unlock(&sc->sc_pm_lock);
S
Sujith 已提交
590
		}
S
Sujith 已提交
591 592

chip_reset:
S
Sujith 已提交
593

594 595
	ath_debug_stat_interrupt(sc, status);

S
Sujith 已提交
596
	if (sched) {
597 598
		/* turn off every interrupt */
		ath9k_hw_disable_interrupts(ah);
S
Sujith 已提交
599 600 601 602
		tasklet_schedule(&sc->intr_tq);
	}

	return IRQ_HANDLED;
S
Sujith 已提交
603 604

#undef SCHED_INTR
S
Sujith 已提交
605 606
}

607 608 609 610
/*
 * This function is called when a HW reset cannot be deferred
 * and has to be immediate.
 */
S
Sujith Manoharan 已提交
611
int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan)
S
Sujith 已提交
612
{
613
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
614
	int r;
S
Sujith 已提交
615

616 617
	set_bit(ATH_OP_HW_RESET, &common->op_flags);

618
	ath9k_ps_wakeup(sc);
S
Sujith Manoharan 已提交
619
	r = ath_reset_internal(sc, hchan);
620
	ath9k_ps_restore(sc);
S
Sujith 已提交
621

622
	return r;
S
Sujith 已提交
623 624
}

625 626 627 628 629
/*
 * When a HW reset can be deferred, it is added to the
 * hw_reset_work workqueue, but we set ATH_OP_HW_RESET before
 * queueing.
 */
630 631
void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type)
{
632
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
633 634 635
#ifdef CONFIG_ATH9K_DEBUGFS
	RESET_STAT_INC(sc, type);
#endif
636
	set_bit(ATH_OP_HW_RESET, &common->op_flags);
637 638 639
	ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
}

640 641 642 643
void ath_reset_work(struct work_struct *work)
{
	struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work);

S
Sujith Manoharan 已提交
644 645 646
	ath9k_ps_wakeup(sc);
	ath_reset_internal(sc, NULL);
	ath9k_ps_restore(sc);
647 648
}

S
Sujith 已提交
649 650 651 652
/**********************/
/* mac80211 callbacks */
/**********************/

653
static int ath9k_start(struct ieee80211_hw *hw)
654
{
655
	struct ath_softc *sc = hw->priv;
656
	struct ath_hw *ah = sc->sc_ah;
657
	struct ath_common *common = ath9k_hw_common(ah);
658
	struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
659
	struct ath_chanctx *ctx = sc->cur_chan;
S
Sujith 已提交
660
	struct ath9k_channel *init_channel;
661
	int r;
662

663
	ath_dbg(common, CONFIG,
J
Joe Perches 已提交
664 665
		"Starting driver with initial channel: %d MHz\n",
		curchan->center_freq);
666

667
	ath9k_ps_wakeup(sc);
668 669
	mutex_lock(&sc->mutex);

670
	init_channel = ath9k_cmn_get_channel(hw, ah, &ctx->chandef);
671
	sc->cur_chandef = hw->conf.chandef;
S
Sujith 已提交
672 673

	/* Reset SERDES registers */
674
	ath9k_hw_configpcipowersave(ah, false);
S
Sujith 已提交
675 676 677 678 679 680 681 682

	/*
	 * The basic interface to setting the hardware in a good
	 * state is ``reset''.  On return the hardware is known to
	 * be powered up and with interrupts disabled.  This must
	 * be followed by initialization of the appropriate bits
	 * and then setup of the interrupt mask.
	 */
683
	spin_lock_bh(&sc->sc_pcu_lock);
F
Felix Fietkau 已提交
684 685 686

	atomic_set(&ah->intr_ref_cnt, -1);

687
	r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
688
	if (r) {
689 690 691
		ath_err(common,
			"Unable to reset hardware; reset status %d (freq %u MHz)\n",
			r, curchan->center_freq);
692
		ah->reset_power_on = false;
S
Sujith 已提交
693 694 695
	}

	/* Setup our intr mask. */
F
Felix Fietkau 已提交
696 697 698 699 700
	ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
		    ATH9K_INT_RXORN | ATH9K_INT_FATAL |
		    ATH9K_INT_GLOBAL;

	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
701
		ah->imask |= ATH9K_INT_RXHP |
702
			     ATH9K_INT_RXLP;
F
Felix Fietkau 已提交
703 704
	else
		ah->imask |= ATH9K_INT_RX;
S
Sujith 已提交
705

706 707 708
	if (ah->config.hw_hang_checks & HW_BB_WATCHDOG)
		ah->imask |= ATH9K_INT_BB_WATCHDOG;

S
Sujith Manoharan 已提交
709 710 711 712 713 714
	/*
	 * Enable GTT interrupts only for AR9003/AR9004 chips
	 * for now.
	 */
	if (AR_SREV_9300_20_OR_LATER(ah))
		ah->imask |= ATH9K_INT_GTT;
S
Sujith 已提交
715

716
	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
P
Pavel Roskin 已提交
717
		ah->imask |= ATH9K_INT_CST;
S
Sujith 已提交
718

719
	ath_mci_enable(sc);
720

721
	clear_bit(ATH_OP_INVALID, &common->op_flags);
722
	sc->sc_ah->is_monitoring = false;
S
Sujith 已提交
723

724 725
	if (!ath_complete_reset(sc, false))
		ah->reset_power_on = false;
S
Sujith 已提交
726

F
Felix Fietkau 已提交
727 728 729 730 731 732 733 734 735 736 737 738
	if (ah->led_pin >= 0) {
		ath9k_hw_cfg_output(ah, ah->led_pin,
				    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
		ath9k_hw_set_gpio(ah, ah->led_pin, 0);
	}

	/*
	 * Reset key cache to sane defaults (all entries cleared) instead of
	 * semi-random values after suspend/resume.
	 */
	ath9k_cmn_init_crypto(sc->sc_ah);

739 740
	ath9k_hw_reset_tsf(ah);

741
	spin_unlock_bh(&sc->sc_pcu_lock);
742

743 744
	mutex_unlock(&sc->mutex);

745 746
	ath9k_ps_restore(sc);

747
	return 0;
748 749
}

750 751 752
static void ath9k_tx(struct ieee80211_hw *hw,
		     struct ieee80211_tx_control *control,
		     struct sk_buff *skb)
753
{
754
	struct ath_softc *sc = hw->priv;
755
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
S
Sujith 已提交
756
	struct ath_tx_control txctl;
757
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
S
Sujith Manoharan 已提交
758
	unsigned long flags;
S
Sujith 已提交
759

760
	if (sc->ps_enabled) {
761 762 763 764 765 766 767
		/*
		 * mac80211 does not set PM field for normal data frames, so we
		 * need to update that based on the current PS mode.
		 */
		if (ieee80211_is_data(hdr->frame_control) &&
		    !ieee80211_is_nullfunc(hdr->frame_control) &&
		    !ieee80211_has_pm(hdr->frame_control)) {
768
			ath_dbg(common, PS,
J
Joe Perches 已提交
769
				"Add PM=1 for a TX frame while in PS mode\n");
770 771 772 773
			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
		}
	}

S
Sujith Manoharan 已提交
774
	if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_NETWORK_SLEEP)) {
775 776 777 778 779 780
		/*
		 * We are using PS-Poll and mac80211 can request TX while in
		 * power save mode. Need to wake up hardware for the TX to be
		 * completed and if needed, also for RX of buffered frames.
		 */
		ath9k_ps_wakeup(sc);
S
Sujith Manoharan 已提交
781
		spin_lock_irqsave(&sc->sc_pm_lock, flags);
782 783
		if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
			ath9k_hw_setrxabort(sc->sc_ah, 0);
784
		if (ieee80211_is_pspoll(hdr->frame_control)) {
785
			ath_dbg(common, PS,
J
Joe Perches 已提交
786
				"Sending PS-Poll to pick a buffered frame\n");
S
Sujith 已提交
787
			sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
788
		} else {
789
			ath_dbg(common, PS, "Wake up to complete TX\n");
S
Sujith 已提交
790
			sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
791 792 793
		}
		/*
		 * The actual restore operation will happen only after
S
Sujith Manoharan 已提交
794
		 * the ps_flags bit is cleared. We are just dropping
795 796
		 * the ps_usecount here.
		 */
S
Sujith Manoharan 已提交
797
		spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
798 799 800
		ath9k_ps_restore(sc);
	}

S
Sujith Manoharan 已提交
801 802 803 804 805 806 807 808 809
	/*
	 * Cannot tx while the hardware is in full sleep, it first needs a full
	 * chip reset to recover from that
	 */
	if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP)) {
		ath_err(common, "TX while HW is in FULL_SLEEP mode\n");
		goto exit;
	}

S
Sujith 已提交
810
	memset(&txctl, 0, sizeof(struct ath_tx_control));
811
	txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
812
	txctl.sta = control->sta;
S
Sujith 已提交
813

814
	ath_dbg(common, XMIT, "transmitting packet, skb: %p\n", skb);
815

816
	if (ath_tx_start(hw, skb, &txctl) != 0) {
817
		ath_dbg(common, XMIT, "TX failed\n");
B
Ben Greear 已提交
818
		TX_STAT_INC(txctl.txq->axq_qnum, txfailed);
S
Sujith 已提交
819
		goto exit;
820 821
	}

822
	return;
S
Sujith 已提交
823
exit:
F
Felix Fietkau 已提交
824
	ieee80211_free_txskb(hw, skb);
825 826
}

827
static void ath9k_stop(struct ieee80211_hw *hw)
828
{
829
	struct ath_softc *sc = hw->priv;
830
	struct ath_hw *ah = sc->sc_ah;
831
	struct ath_common *common = ath9k_hw_common(ah);
F
Felix Fietkau 已提交
832
	bool prev_idle;
833

834 835
	ath9k_deinit_channel_context(sc);

S
Sujith 已提交
836 837
	mutex_lock(&sc->mutex);

838
	ath_cancel_work(sc);
839

840
	if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
841
		ath_dbg(common, ANY, "Device not present\n");
S
Sujith 已提交
842
		mutex_unlock(&sc->mutex);
S
Sujith 已提交
843 844
		return;
	}
845

846 847 848
	/* Ensure HW is awake when we try to shut it down. */
	ath9k_ps_wakeup(sc);

849 850
	spin_lock_bh(&sc->sc_pcu_lock);

851 852 853
	/* prevent tasklets to enable interrupts once we disable them */
	ah->imask &= ~ATH9K_INT_GLOBAL;

S
Sujith 已提交
854 855
	/* make sure h/w will not generate any interrupt
	 * before setting the invalid flag. */
856
	ath9k_hw_disable_interrupts(ah);
S
Sujith 已提交
857

F
Felix Fietkau 已提交
858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
	spin_unlock_bh(&sc->sc_pcu_lock);

	/* we can now sync irq and kill any running tasklets, since we already
	 * disabled interrupts and not holding a spin lock */
	synchronize_irq(sc->irq);
	tasklet_kill(&sc->intr_tq);
	tasklet_kill(&sc->bcon_tasklet);

	prev_idle = sc->ps_idle;
	sc->ps_idle = true;

	spin_lock_bh(&sc->sc_pcu_lock);

	if (ah->led_pin >= 0) {
		ath9k_hw_set_gpio(ah, ah->led_pin, 1);
		ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
	}

876
	ath_prepare_reset(sc);
S
Sujith 已提交
877

878 879 880 881 882
	if (sc->rx.frag) {
		dev_kfree_skb_any(sc->rx.frag);
		sc->rx.frag = NULL;
	}

F
Felix Fietkau 已提交
883
	if (!ah->curchan)
884 885
		ah->curchan = ath9k_cmn_get_channel(hw, ah,
						    &sc->cur_chan->chandef);
886

F
Felix Fietkau 已提交
887 888
	ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
	ath9k_hw_phy_disable(ah);
889

F
Felix Fietkau 已提交
890
	ath9k_hw_configpcipowersave(ah, true);
891

F
Felix Fietkau 已提交
892
	spin_unlock_bh(&sc->sc_pcu_lock);
893

F
Felix Fietkau 已提交
894
	ath9k_ps_restore(sc);
S
Sujith 已提交
895

896
	set_bit(ATH_OP_INVALID, &common->op_flags);
F
Felix Fietkau 已提交
897
	sc->ps_idle = prev_idle;
898

899 900
	mutex_unlock(&sc->mutex);

901
	ath_dbg(common, CONFIG, "Driver halt\n");
902 903
}

904
static bool ath9k_uses_beacons(int type)
905 906 907 908 909 910 911 912 913 914 915
{
	switch (type) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_MESH_POINT:
		return true;
	default:
		return false;
	}
}

916 917
static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
			   u8 *mac, struct ieee80211_vif *vif)
918
{
S
Sujith Manoharan 已提交
919
	struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
920 921
	int i;

922
	if (iter_data->has_hw_macaddr) {
923 924 925
		for (i = 0; i < ETH_ALEN; i++)
			iter_data->mask[i] &=
				~(iter_data->hw_macaddr[i] ^ mac[i]);
926 927 928 929
	} else {
		memcpy(iter_data->hw_macaddr, mac, ETH_ALEN);
		iter_data->has_hw_macaddr = true;
	}
930

931 932 933
	if (!vif->bss_conf.use_short_slot)
		iter_data->slottime = ATH9K_SLOT_TIME_20;

934
	switch (vif->type) {
935 936
	case NL80211_IFTYPE_AP:
		iter_data->naps++;
937
		break;
938 939
	case NL80211_IFTYPE_STATION:
		iter_data->nstations++;
S
Sujith Manoharan 已提交
940
		if (avp->assoc && !iter_data->primary_sta)
941
			iter_data->primary_sta = vif;
B
Bill Jordan 已提交
942
		break;
943
	case NL80211_IFTYPE_ADHOC:
944
		iter_data->nadhocs++;
945 946
		if (vif->bss_conf.enable_beacon)
			iter_data->beacons = true;
947
		break;
948
	case NL80211_IFTYPE_MESH_POINT:
949
		iter_data->nmeshes++;
950 951
		if (vif->bss_conf.enable_beacon)
			iter_data->beacons = true;
952 953 954
		break;
	case NL80211_IFTYPE_WDS:
		iter_data->nwds++;
955 956
		break;
	default:
957
		break;
958
	}
959
}
960

961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988
static void ath9k_update_bssid_mask(struct ath_softc *sc,
				    struct ath_chanctx *ctx,
				    struct ath9k_vif_iter_data *iter_data)
{
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	struct ath_vif *avp;
	int i;

	if (!ath9k_is_chanctx_enabled())
		return;

	list_for_each_entry(avp, &ctx->vifs, list) {
		if (ctx->nvifs_assigned != 1)
			continue;

		if (!avp->vif->p2p || !iter_data->has_hw_macaddr)
			continue;

		ether_addr_copy(common->curbssid, avp->bssid);

		/* perm_addr will be used as the p2p device address. */
		for (i = 0; i < ETH_ALEN; i++)
			iter_data->mask[i] &=
				~(iter_data->hw_macaddr[i] ^
				  sc->hw->wiphy->perm_addr[i]);
	}
}

989
/* Called with sc->mutex held. */
990 991
void ath9k_calculate_iter_data(struct ath_softc *sc,
			       struct ath_chanctx *ctx,
992 993
			       struct ath9k_vif_iter_data *iter_data)
{
994
	struct ath_vif *avp;
995

996
	/*
997 998 999
	 * Pick the MAC address of the first interface as the new hardware
	 * MAC address. The hardware will use it together with the BSSID mask
	 * when matching addresses.
1000 1001 1002
	 */
	memset(iter_data, 0, sizeof(*iter_data));
	memset(&iter_data->mask, 0xff, ETH_ALEN);
1003 1004 1005 1006
	iter_data->slottime = ATH9K_SLOT_TIME_9;

	list_for_each_entry(avp, &ctx->vifs, list)
		ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif);
1007 1008

	ath9k_update_bssid_mask(sc, ctx, iter_data);
1009 1010 1011 1012 1013 1014
}

static void ath9k_set_assoc_state(struct ath_softc *sc,
				  struct ieee80211_vif *vif, bool changed)
{
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
S
Sujith Manoharan 已提交
1015
	struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
1016 1017 1018 1019
	unsigned long flags;

	set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);

S
Sujith Manoharan 已提交
1020 1021
	ether_addr_copy(common->curbssid, avp->bssid);
	common->curaid = avp->aid;
1022 1023 1024 1025 1026
	ath9k_hw_write_associd(sc->sc_ah);

	if (changed) {
		common->last_rssi = ATH_RSSI_DUMMY_MARKER;
		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
S
Sujith 已提交
1027

1028 1029 1030 1031
		spin_lock_irqsave(&sc->sc_pm_lock, flags);
		sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
		spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
	}
1032

1033 1034
	if (ath9k_hw_mci_is_enabled(sc->sc_ah))
		ath9k_mci_update_wlan_channels(sc, false);
1035

1036 1037 1038
	ath_dbg(common, CONFIG,
		"Primary Station interface: %pM, BSSID: %pM\n",
		vif->addr, common->curbssid);
1039
}
1040

1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
static void ath9k_set_offchannel_state(struct ath_softc *sc)
{
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
	struct ieee80211_vif *vif = NULL;

	ath9k_ps_wakeup(sc);

	if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START)
		vif = sc->offchannel.scan_vif;
	else
		vif = sc->offchannel.roc_vif;

	if (WARN_ON(!vif))
		goto exit;

	eth_zero_addr(common->curbssid);
	eth_broadcast_addr(common->bssidmask);
S
Sujith Manoharan 已提交
1060
	memcpy(common->macaddr, vif->addr, ETH_ALEN);
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
	common->curaid = 0;
	ah->opmode = vif->type;
	ah->imask &= ~ATH9K_INT_SWBA;
	ah->imask &= ~ATH9K_INT_TSFOOR;
	ah->slottime = ATH9K_SLOT_TIME_9;

	ath_hw_setbssidmask(common);
	ath9k_hw_setopmode(ah);
	ath9k_hw_write_associd(sc->sc_ah);
	ath9k_hw_set_interrupts(ah);
	ath9k_hw_init_global_settings(ah);

exit:
	ath9k_ps_restore(sc);
}
#endif

1078
/* Called with sc->mutex held. */
1079 1080
void ath9k_calculate_summary_state(struct ath_softc *sc,
				   struct ath_chanctx *ctx)
1081 1082 1083 1084
{
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_vif_iter_data iter_data;
1085
	struct ath_beacon_config *cur_conf;
1086

1087 1088 1089 1090 1091
	ath_chanctx_check_active(sc, ctx);

	if (ctx != sc->cur_chan)
		return;

1092 1093 1094 1095 1096
#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
	if (ctx == &sc->offchannel.chan)
		return ath9k_set_offchannel_state(sc);
#endif

1097 1098 1099 1100
	ath9k_ps_wakeup(sc);
	ath9k_calculate_iter_data(sc, ctx, &iter_data);

	if (iter_data.has_hw_macaddr)
S
Sujith Manoharan 已提交
1101
		memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN);
1102

1103 1104 1105 1106
	memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
	ath_hw_setbssidmask(common);

	if (iter_data.naps > 0) {
1107
		cur_conf = &ctx->beacon;
1108
		ath9k_hw_set_tsfadjust(ah, true);
1109
		ah->opmode = NL80211_IFTYPE_AP;
1110 1111
		if (cur_conf->enable_beacon)
			iter_data.beacons = true;
1112
	} else {
1113
		ath9k_hw_set_tsfadjust(ah, false);
S
Sujith 已提交
1114

1115 1116 1117
		if (iter_data.nmeshes)
			ah->opmode = NL80211_IFTYPE_MESH_POINT;
		else if (iter_data.nwds)
1118 1119 1120 1121 1122 1123
			ah->opmode = NL80211_IFTYPE_AP;
		else if (iter_data.nadhocs)
			ah->opmode = NL80211_IFTYPE_ADHOC;
		else
			ah->opmode = NL80211_IFTYPE_STATION;
	}
S
Sujith 已提交
1124

1125 1126
	ath9k_hw_setopmode(ah);

1127
	ctx->switch_after_beacon = false;
1128
	if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0)
P
Pavel Roskin 已提交
1129
		ah->imask |= ATH9K_INT_TSFOOR;
1130
	else {
1131
		ah->imask &= ~ATH9K_INT_TSFOOR;
1132 1133 1134
		if (iter_data.naps == 1 && iter_data.beacons)
			ctx->switch_after_beacon = true;
	}
1135

1136 1137 1138 1139 1140
	ah->imask &= ~ATH9K_INT_SWBA;
	if (ah->opmode == NL80211_IFTYPE_STATION) {
		bool changed = (iter_data.primary_sta != ctx->primary_sta);

		if (iter_data.primary_sta) {
1141
			iter_data.beacons = true;
1142 1143
			ath9k_set_assoc_state(sc, iter_data.primary_sta,
					      changed);
1144
			ctx->primary_sta = iter_data.primary_sta;
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
		} else {
			ctx->primary_sta = NULL;
			memset(common->curbssid, 0, ETH_ALEN);
			common->curaid = 0;
			ath9k_hw_write_associd(sc->sc_ah);
			if (ath9k_hw_mci_is_enabled(sc->sc_ah))
				ath9k_mci_update_wlan_channels(sc, true);
		}
	} else if (iter_data.beacons) {
		ah->imask |= ATH9K_INT_SWBA;
	}
1156
	ath9k_hw_set_interrupts(ah);
1157

1158 1159 1160 1161 1162 1163 1164 1165
	if (iter_data.beacons)
		set_bit(ATH_OP_BEACONS, &common->op_flags);
	else
		clear_bit(ATH_OP_BEACONS, &common->op_flags);

	if (ah->slottime != iter_data.slottime) {
		ah->slottime = iter_data.slottime;
		ath9k_hw_init_global_settings(ah);
1166
	}
1167 1168 1169 1170 1171 1172

	if (iter_data.primary_sta)
		set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
	else
		clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);

1173 1174 1175 1176
	ath_dbg(common, CONFIG,
		"macaddr: %pM, bssid: %pM, bssidmask: %pM\n",
		common->macaddr, common->curbssid, common->bssidmask);

1177
	ath9k_ps_restore(sc);
1178
}
1179

1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
static void ath9k_assign_hw_queues(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif)
{
	int i;

	for (i = 0; i < IEEE80211_NUM_ACS; i++)
		vif->hw_queue[i] = i;

	if (vif->type == NL80211_IFTYPE_AP)
		vif->cab_queue = hw->queues - 2;
	else
		vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
}

1194 1195
static int ath9k_add_interface(struct ieee80211_hw *hw,
			       struct ieee80211_vif *vif)
1196
{
1197
	struct ath_softc *sc = hw->priv;
1198 1199
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
1200 1201
	struct ath_vif *avp = (void *)vif->drv_priv;
	struct ath_node *an = &avp->mcast_node;
1202

1203
	mutex_lock(&sc->mutex);
1204

L
Luis R. Rodriguez 已提交
1205
	if (config_enabled(CONFIG_ATH9K_TX99)) {
1206
		if (sc->cur_chan->nvifs >= 1) {
L
Luis R. Rodriguez 已提交
1207 1208 1209 1210 1211 1212
			mutex_unlock(&sc->mutex);
			return -EOPNOTSUPP;
		}
		sc->tx99_vif = vif;
	}

1213
	ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
1214
	sc->cur_chan->nvifs++;
1215

S
Sujith Manoharan 已提交
1216 1217 1218
	if (ath9k_uses_beacons(vif->type))
		ath9k_beacon_assign_slot(sc, vif);

1219
	avp->vif = vif;
1220
	if (!ath9k_is_chanctx_enabled()) {
1221
		avp->chanctx = sc->cur_chan;
1222 1223
		list_add_tail(&avp->list, &avp->chanctx->vifs);
	}
1224 1225

	ath9k_assign_hw_queues(hw, vif);
1226

1227 1228 1229 1230 1231 1232
	an->sc = sc;
	an->sta = NULL;
	an->vif = vif;
	an->no_ps_filter = true;
	ath_tx_node_init(sc, an);

1233
	mutex_unlock(&sc->mutex);
1234
	return 0;
1235 1236 1237 1238 1239 1240 1241
}

static int ath9k_change_interface(struct ieee80211_hw *hw,
				  struct ieee80211_vif *vif,
				  enum nl80211_iftype new_type,
				  bool p2p)
{
1242
	struct ath_softc *sc = hw->priv;
1243
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1244
	struct ath_vif *avp = (void *)vif->drv_priv;
1245 1246

	mutex_lock(&sc->mutex);
1247

L
Luis R. Rodriguez 已提交
1248 1249 1250 1251 1252 1253 1254
	if (config_enabled(CONFIG_ATH9K_TX99)) {
		mutex_unlock(&sc->mutex);
		return -EOPNOTSUPP;
	}

	ath_dbg(common, CONFIG, "Change Interface\n");

1255
	if (ath9k_uses_beacons(vif->type))
S
Sujith Manoharan 已提交
1256
		ath9k_beacon_remove_slot(sc, vif);
1257

1258 1259 1260
	vif->type = new_type;
	vif->p2p = p2p;

S
Sujith Manoharan 已提交
1261 1262
	if (ath9k_uses_beacons(vif->type))
		ath9k_beacon_assign_slot(sc, vif);
1263

1264
	ath9k_assign_hw_queues(hw, vif);
1265
	ath9k_calculate_summary_state(sc, avp->chanctx);
S
Sujith Manoharan 已提交
1266

1267
	mutex_unlock(&sc->mutex);
1268
	return 0;
1269 1270
}

1271
static void ath9k_remove_interface(struct ieee80211_hw *hw,
1272
				   struct ieee80211_vif *vif)
1273
{
1274
	struct ath_softc *sc = hw->priv;
1275
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1276
	struct ath_vif *avp = (void *)vif->drv_priv;
1277

1278
	ath_dbg(common, CONFIG, "Detach Interface\n");
1279

1280 1281
	mutex_lock(&sc->mutex);

1282
	ath9k_p2p_remove_vif(sc, vif);
1283

1284
	sc->cur_chan->nvifs--;
L
Luis R. Rodriguez 已提交
1285
	sc->tx99_vif = NULL;
1286
	if (!ath9k_is_chanctx_enabled())
1287
		list_del(&avp->list);
J
Jouni Malinen 已提交
1288

1289
	if (ath9k_uses_beacons(vif->type))
S
Sujith Manoharan 已提交
1290
		ath9k_beacon_remove_slot(sc, vif);
1291

1292 1293
	ath_tx_node_cleanup(sc, &avp->mcast_node);

1294
	mutex_unlock(&sc->mutex);
1295 1296
}

1297
static void ath9k_enable_ps(struct ath_softc *sc)
1298
{
P
Pavel Roskin 已提交
1299
	struct ath_hw *ah = sc->sc_ah;
S
Sujith Manoharan 已提交
1300
	struct ath_common *common = ath9k_hw_common(ah);
P
Pavel Roskin 已提交
1301

L
Luis R. Rodriguez 已提交
1302 1303 1304
	if (config_enabled(CONFIG_ATH9K_TX99))
		return;

1305
	sc->ps_enabled = true;
P
Pavel Roskin 已提交
1306 1307 1308
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
		if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) {
			ah->imask |= ATH9K_INT_TIM_TIMER;
1309
			ath9k_hw_set_interrupts(ah);
1310
		}
1311
		ath9k_hw_setrxabort(ah, 1);
1312
	}
S
Sujith Manoharan 已提交
1313
	ath_dbg(common, PS, "PowerSave enabled\n");
1314 1315
}

1316 1317 1318
static void ath9k_disable_ps(struct ath_softc *sc)
{
	struct ath_hw *ah = sc->sc_ah;
S
Sujith Manoharan 已提交
1319
	struct ath_common *common = ath9k_hw_common(ah);
1320

L
Luis R. Rodriguez 已提交
1321 1322 1323
	if (config_enabled(CONFIG_ATH9K_TX99))
		return;

1324 1325 1326 1327 1328 1329 1330 1331 1332 1333
	sc->ps_enabled = false;
	ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
		ath9k_hw_setrxabort(ah, 0);
		sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
				  PS_WAIT_FOR_CAB |
				  PS_WAIT_FOR_PSPOLL_DATA |
				  PS_WAIT_FOR_TX_ACK);
		if (ah->imask & ATH9K_INT_TIM_TIMER) {
			ah->imask &= ~ATH9K_INT_TIM_TIMER;
1334
			ath9k_hw_set_interrupts(ah);
1335 1336
		}
	}
S
Sujith Manoharan 已提交
1337
	ath_dbg(common, PS, "PowerSave disabled\n");
1338 1339
}

1340 1341 1342 1343 1344 1345 1346
void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw)
{
	struct ath_softc *sc = hw->priv;
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
	u32 rxfilter;

L
Luis R. Rodriguez 已提交
1347 1348 1349
	if (config_enabled(CONFIG_ATH9K_TX99))
		return;

1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384
	if (!ath9k_hw_ops(ah)->spectral_scan_trigger) {
		ath_err(common, "spectrum analyzer not implemented on this hardware\n");
		return;
	}

	ath9k_ps_wakeup(sc);
	rxfilter = ath9k_hw_getrxfilter(ah);
	ath9k_hw_setrxfilter(ah, rxfilter |
				 ATH9K_RX_FILTER_PHYRADAR |
				 ATH9K_RX_FILTER_PHYERR);

	/* TODO: usually this should not be neccesary, but for some reason
	 * (or in some mode?) the trigger must be called after the
	 * configuration, otherwise the register will have its values reset
	 * (on my ar9220 to value 0x01002310)
	 */
	ath9k_spectral_scan_config(hw, sc->spectral_mode);
	ath9k_hw_ops(ah)->spectral_scan_trigger(ah);
	ath9k_ps_restore(sc);
}

int ath9k_spectral_scan_config(struct ieee80211_hw *hw,
			       enum spectral_mode spectral_mode)
{
	struct ath_softc *sc = hw->priv;
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);

	if (!ath9k_hw_ops(ah)->spectral_scan_trigger) {
		ath_err(common, "spectrum analyzer not implemented on this hardware\n");
		return -1;
	}

	switch (spectral_mode) {
	case SPECTRAL_DISABLED:
1385
		sc->spec_config.enabled = 0;
1386 1387 1388 1389 1390
		break;
	case SPECTRAL_BACKGROUND:
		/* send endless samples.
		 * TODO: is this really useful for "background"?
		 */
1391 1392
		sc->spec_config.endless = 1;
		sc->spec_config.enabled = 1;
1393 1394 1395
		break;
	case SPECTRAL_CHANSCAN:
	case SPECTRAL_MANUAL:
1396 1397
		sc->spec_config.endless = 0;
		sc->spec_config.enabled = 1;
1398 1399 1400 1401 1402 1403
		break;
	default:
		return -1;
	}

	ath9k_ps_wakeup(sc);
1404
	ath9k_hw_ops(ah)->spectral_scan_config(ah, &sc->spec_config);
1405 1406 1407 1408 1409 1410 1411
	ath9k_ps_restore(sc);

	sc->spectral_mode = spectral_mode;

	return 0;
}

1412
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1413
{
1414
	struct ath_softc *sc = hw->priv;
1415 1416
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
1417
	struct ieee80211_conf *conf = &hw->conf;
1418
	struct ath_chanctx *ctx = sc->cur_chan;
1419

F
Felix Fietkau 已提交
1420
	ath9k_ps_wakeup(sc);
1421
	mutex_lock(&sc->mutex);
1422

1423
	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1424
		sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1425
		if (sc->ps_idle) {
1426
			ath_cancel_work(sc);
1427 1428 1429
			ath9k_stop_btcoex(sc);
		} else {
			ath9k_start_btcoex(sc);
1430 1431 1432 1433
			/*
			 * The chip needs a reset to properly wake up from
			 * full sleep
			 */
1434
			ath_chanctx_set_channel(sc, ctx, &ctx->chandef);
1435
		}
1436
	}
1437

1438 1439 1440 1441 1442 1443
	/*
	 * We just prepare to enable PS. We have to wait until our AP has
	 * ACK'd our null data frame to disable RX otherwise we'll ignore
	 * those ACKs and end up retransmitting the same null data frames.
	 * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode.
	 */
1444
	if (changed & IEEE80211_CONF_CHANGE_PS) {
1445 1446
		unsigned long flags;
		spin_lock_irqsave(&sc->sc_pm_lock, flags);
1447 1448
		if (conf->flags & IEEE80211_CONF_PS)
			ath9k_enable_ps(sc);
1449 1450
		else
			ath9k_disable_ps(sc);
1451
		spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1452 1453
	}

S
Sujith 已提交
1454 1455
	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
		if (conf->flags & IEEE80211_CONF_MONITOR) {
1456
			ath_dbg(common, CONFIG, "Monitor mode is enabled\n");
1457 1458
			sc->sc_ah->is_monitoring = true;
		} else {
1459
			ath_dbg(common, CONFIG, "Monitor mode is disabled\n");
1460
			sc->sc_ah->is_monitoring = false;
S
Sujith 已提交
1461 1462 1463
		}
	}

1464
	if (!ath9k_is_chanctx_enabled() && (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
1465
		ctx->offchannel = !!(conf->flags & IEEE80211_CONF_OFFCHANNEL);
1466
		ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef);
S
Sujith 已提交
1467
	}
1468

1469
	if (changed & IEEE80211_CONF_CHANGE_POWER) {
1470
		ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
1471
		sc->cur_chan->txpower = 2 * conf->power_level;
1472
		ath9k_cmn_update_txpow(ah, sc->curtxpow,
1473
				       sc->cur_chan->txpower, &sc->curtxpow);
1474 1475
	}

1476
	mutex_unlock(&sc->mutex);
F
Felix Fietkau 已提交
1477
	ath9k_ps_restore(sc);
1478

1479 1480 1481
	return 0;
}

1482 1483 1484 1485
#define SUPPORTED_FILTERS			\
	(FIF_PROMISC_IN_BSS |			\
	FIF_ALLMULTI |				\
	FIF_CONTROL |				\
1486
	FIF_PSPOLL |				\
1487 1488
	FIF_OTHER_BSS |				\
	FIF_BCN_PRBRESP_PROMISC |		\
1489
	FIF_PROBE_REQ |				\
1490
	FIF_FCSFAIL)
1491

1492 1493 1494 1495
/* FIXME: sc->sc_full_reset ? */
static void ath9k_configure_filter(struct ieee80211_hw *hw,
				   unsigned int changed_flags,
				   unsigned int *total_flags,
1496
				   u64 multicast)
1497
{
1498
	struct ath_softc *sc = hw->priv;
1499
	u32 rfilt;
1500

1501 1502
	changed_flags &= SUPPORTED_FILTERS;
	*total_flags &= SUPPORTED_FILTERS;
1503

1504 1505 1506 1507
	spin_lock_bh(&sc->chan_lock);
	sc->cur_chan->rxfilter = *total_flags;
	spin_unlock_bh(&sc->chan_lock);

1508
	ath9k_ps_wakeup(sc);
1509 1510
	rfilt = ath_calcrxfilter(sc);
	ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
1511
	ath9k_ps_restore(sc);
1512

1513 1514
	ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG, "Set HW RX filter: 0x%x\n",
		rfilt);
1515
}
1516

1517 1518 1519
static int ath9k_sta_add(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta)
1520
{
1521
	struct ath_softc *sc = hw->priv;
1522 1523 1524
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	struct ath_node *an = (struct ath_node *) sta->drv_priv;
	struct ieee80211_key_conf ps_key = { };
1525
	int key;
1526

1527
	ath_node_attach(sc, sta, vif);
1528 1529 1530 1531 1532

	if (vif->type != NL80211_IFTYPE_AP &&
	    vif->type != NL80211_IFTYPE_AP_VLAN)
		return 0;

1533
	key = ath_key_config(common, vif, sta, &ps_key);
1534
	if (key > 0) {
1535
		an->ps_key = key;
1536 1537
		an->key_idx[0] = key;
	}
1538 1539 1540 1541

	return 0;
}

1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553
static void ath9k_del_ps_key(struct ath_softc *sc,
			     struct ieee80211_vif *vif,
			     struct ieee80211_sta *sta)
{
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	struct ath_node *an = (struct ath_node *) sta->drv_priv;
	struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key };

	if (!an->ps_key)
	    return;

	ath_key_delete(common, &ps_key);
1554
	an->ps_key = 0;
1555
	an->key_idx[0] = 0;
1556 1557
}

1558 1559 1560 1561
static int ath9k_sta_remove(struct ieee80211_hw *hw,
			    struct ieee80211_vif *vif,
			    struct ieee80211_sta *sta)
{
1562
	struct ath_softc *sc = hw->priv;
1563

1564
	ath9k_del_ps_key(sc, vif, sta);
1565 1566 1567
	ath_node_detach(sc, sta);

	return 0;
1568 1569
}

S
Sujith Manoharan 已提交
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591
static int ath9k_sta_state(struct ieee80211_hw *hw,
			   struct ieee80211_vif *vif,
			   struct ieee80211_sta *sta,
			   enum ieee80211_sta_state old_state,
			   enum ieee80211_sta_state new_state)
{
	struct ath_softc *sc = hw->priv;
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	int ret = 0;

	if (old_state == IEEE80211_STA_AUTH &&
	    new_state == IEEE80211_STA_ASSOC) {
		ret = ath9k_sta_add(hw, vif, sta);
		ath_dbg(common, CONFIG,
			"Add station: %pM\n", sta->addr);
	} else if (old_state == IEEE80211_STA_ASSOC &&
		   new_state == IEEE80211_STA_AUTH) {
		ret = ath9k_sta_remove(hw, vif, sta);
		ath_dbg(common, CONFIG,
			"Remove station: %pM\n", sta->addr);
	}

1592
	if (ath9k_is_chanctx_enabled()) {
1593 1594 1595 1596 1597 1598
		if (vif->type == NL80211_IFTYPE_STATION) {
			if (old_state == IEEE80211_STA_ASSOC &&
			    new_state == IEEE80211_STA_AUTHORIZED)
				ath_chanctx_event(sc, vif,
						  ATH_CHANCTX_EVENT_AUTHORIZED);
		}
1599 1600
	}

S
Sujith Manoharan 已提交
1601 1602 1603
	return ret;
}

1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
static void ath9k_sta_set_tx_filter(struct ath_hw *ah,
				    struct ath_node *an,
				    bool set)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) {
		if (!an->key_idx[i])
			continue;
		ath9k_hw_set_tx_filter(ah, an->key_idx[i], set);
	}
}

1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627
static void ath9k_sta_notify(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif,
			 enum sta_notify_cmd cmd,
			 struct ieee80211_sta *sta)
{
	struct ath_softc *sc = hw->priv;
	struct ath_node *an = (struct ath_node *) sta->drv_priv;

	switch (cmd) {
	case STA_NOTIFY_SLEEP:
		an->sleeping = true;
1628
		ath_tx_aggr_sleep(sta, sc, an);
1629
		ath9k_sta_set_tx_filter(sc->sc_ah, an, true);
1630 1631
		break;
	case STA_NOTIFY_AWAKE:
1632
		ath9k_sta_set_tx_filter(sc->sc_ah, an, false);
1633 1634 1635 1636 1637 1638
		an->sleeping = false;
		ath_tx_aggr_wakeup(sc, an);
		break;
	}
}

1639 1640
static int ath9k_conf_tx(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif, u16 queue,
1641
			 const struct ieee80211_tx_queue_params *params)
1642
{
1643
	struct ath_softc *sc = hw->priv;
1644
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1645
	struct ath_txq *txq;
1646
	struct ath9k_tx_queue_info qi;
1647
	int ret = 0;
1648

1649
	if (queue >= IEEE80211_NUM_ACS)
1650
		return 0;
1651

1652 1653
	txq = sc->tx.txq_map[queue];

1654
	ath9k_ps_wakeup(sc);
1655 1656
	mutex_lock(&sc->mutex);

1657 1658
	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));

1659 1660 1661
	qi.tqi_aifs = params->aifs;
	qi.tqi_cwmin = params->cw_min;
	qi.tqi_cwmax = params->cw_max;
1662
	qi.tqi_burstTime = params->txop * 32;
1663

1664
	ath_dbg(common, CONFIG,
J
Joe Perches 已提交
1665 1666 1667
		"Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
		queue, txq->axq_qnum, params->aifs, params->cw_min,
		params->cw_max, params->txop);
1668

1669
	ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime);
1670
	ret = ath_txq_update(sc, txq->axq_qnum, &qi);
1671
	if (ret)
1672
		ath_err(common, "TXQ Update failed\n");
1673

1674
	mutex_unlock(&sc->mutex);
1675
	ath9k_ps_restore(sc);
1676

1677 1678
	return ret;
}
1679

1680 1681
static int ath9k_set_key(struct ieee80211_hw *hw,
			 enum set_key_cmd cmd,
1682 1683
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta,
1684 1685
			 struct ieee80211_key_conf *key)
{
1686
	struct ath_softc *sc = hw->priv;
1687
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1688 1689
	struct ath_node *an = NULL;
	int ret = 0, i;
1690

1691
	if (ath9k_modparam_nohwcrypt)
1692 1693
		return -ENOSPC;

C
Chun-Yeow Yeoh 已提交
1694 1695
	if ((vif->type == NL80211_IFTYPE_ADHOC ||
	     vif->type == NL80211_IFTYPE_MESH_POINT) &&
J
Jouni Malinen 已提交
1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708
	    (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
	     key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
		/*
		 * For now, disable hw crypto for the RSN IBSS group keys. This
		 * could be optimized in the future to use a modified key cache
		 * design to support per-STA RX GTK, but until that gets
		 * implemented, use of software crypto for group addressed
		 * frames is a acceptable to allow RSN IBSS to be used.
		 */
		return -EOPNOTSUPP;
	}

1709
	mutex_lock(&sc->mutex);
1710
	ath9k_ps_wakeup(sc);
1711 1712 1713
	ath_dbg(common, CONFIG, "Set HW Key %d\n", cmd);
	if (sta)
		an = (struct ath_node *)sta->drv_priv;
1714

1715 1716
	switch (cmd) {
	case SET_KEY:
1717 1718 1719
		if (sta)
			ath9k_del_ps_key(sc, vif, sta);

1720
		key->hw_key_idx = 0;
1721
		ret = ath_key_config(common, vif, sta, key);
1722 1723
		if (ret >= 0) {
			key->hw_key_idx = ret;
1724 1725
			/* push IV and Michael MIC generation to stack */
			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1726
			if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1727
				key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1728 1729
			if (sc->sc_ah->sw_mgmt_crypto &&
			    key->cipher == WLAN_CIPHER_SUITE_CCMP)
1730
				key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
1731
			ret = 0;
1732
		}
1733 1734 1735 1736 1737 1738 1739 1740 1741
		if (an && key->hw_key_idx) {
			for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) {
				if (an->key_idx[i])
					continue;
				an->key_idx[i] = key->hw_key_idx;
				break;
			}
			WARN_ON(i == ARRAY_SIZE(an->key_idx));
		}
1742 1743
		break;
	case DISABLE_KEY:
1744
		ath_key_delete(common, key);
1745 1746 1747 1748 1749 1750 1751 1752 1753
		if (an) {
			for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) {
				if (an->key_idx[i] != key->hw_key_idx)
					continue;
				an->key_idx[i] = 0;
				break;
			}
		}
		key->hw_key_idx = 0;
1754 1755 1756 1757
		break;
	default:
		ret = -EINVAL;
	}
1758

1759
	ath9k_ps_restore(sc);
1760 1761
	mutex_unlock(&sc->mutex);

1762 1763
	return ret;
}
1764

1765 1766 1767 1768 1769
static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_bss_conf *bss_conf,
				   u32 changed)
{
S
Sujith Manoharan 已提交
1770 1771 1772 1773 1774
#define CHECK_ANI				\
	(BSS_CHANGED_ASSOC |			\
	 BSS_CHANGED_IBSS |			\
	 BSS_CHANGED_BEACON_ENABLED)

1775
	struct ath_softc *sc = hw->priv;
1776
	struct ath_hw *ah = sc->sc_ah;
1777
	struct ath_common *common = ath9k_hw_common(ah);
1778
	struct ath_vif *avp = (void *)vif->drv_priv;
1779
	int slottime;
1780

1781
	ath9k_ps_wakeup(sc);
1782 1783
	mutex_lock(&sc->mutex);

1784
	if (changed & BSS_CHANGED_ASSOC) {
1785 1786 1787
		ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n",
			bss_conf->bssid, bss_conf->assoc);

S
Sujith Manoharan 已提交
1788
		memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
S
Sujith Manoharan 已提交
1789 1790 1791
		avp->aid = bss_conf->aid;
		avp->assoc = bss_conf->assoc;

1792
		ath9k_calculate_summary_state(sc, avp->chanctx);
S
Sujith 已提交
1793
	}
1794

1795 1796 1797 1798 1799 1800
	if (changed & BSS_CHANGED_IBSS) {
		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
		common->curaid = bss_conf->aid;
		ath9k_hw_write_associd(sc->sc_ah);
	}

S
Sujith Manoharan 已提交
1801
	if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
1802 1803
	    (changed & BSS_CHANGED_BEACON_INT) ||
	    (changed & BSS_CHANGED_BEACON_INFO)) {
1804
		ath9k_beacon_config(sc, vif, changed);
1805 1806 1807
		if (changed & BSS_CHANGED_BEACON_ENABLED)
			ath9k_calculate_summary_state(sc, avp->chanctx);
	}
1808

1809 1810
	if ((avp->chanctx == sc->cur_chan) &&
	    (changed & BSS_CHANGED_ERP_SLOT)) {
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826
		if (bss_conf->use_short_slot)
			slottime = 9;
		else
			slottime = 20;
		if (vif->type == NL80211_IFTYPE_AP) {
			/*
			 * Defer update, so that connected stations can adjust
			 * their settings at the same time.
			 * See beacon.c for more details
			 */
			sc->beacon.slottime = slottime;
			sc->beacon.updateslot = UPDATE;
		} else {
			ah->slottime = slottime;
			ath9k_hw_init_global_settings(ah);
		}
1827 1828
	}

1829 1830
	if (changed & BSS_CHANGED_P2P_PS)
		ath9k_p2p_bss_info_changed(sc, vif);
1831

S
Sujith Manoharan 已提交
1832 1833 1834
	if (changed & CHECK_ANI)
		ath_check_ani(sc);

1835
	mutex_unlock(&sc->mutex);
1836
	ath9k_ps_restore(sc);
S
Sujith Manoharan 已提交
1837 1838

#undef CHECK_ANI
1839
}
1840

1841
static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1842
{
1843
	struct ath_softc *sc = hw->priv;
1844
	u64 tsf;
1845

1846
	mutex_lock(&sc->mutex);
1847
	ath9k_ps_wakeup(sc);
1848
	tsf = ath9k_hw_gettsf64(sc->sc_ah);
1849
	ath9k_ps_restore(sc);
1850
	mutex_unlock(&sc->mutex);
1851

1852 1853
	return tsf;
}
1854

1855 1856 1857
static void ath9k_set_tsf(struct ieee80211_hw *hw,
			  struct ieee80211_vif *vif,
			  u64 tsf)
1858
{
1859
	struct ath_softc *sc = hw->priv;
1860

1861
	mutex_lock(&sc->mutex);
1862
	ath9k_ps_wakeup(sc);
1863
	ath9k_hw_settsf64(sc->sc_ah, tsf);
1864
	ath9k_ps_restore(sc);
1865
	mutex_unlock(&sc->mutex);
1866 1867
}

1868
static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1869
{
1870
	struct ath_softc *sc = hw->priv;
1871

1872
	mutex_lock(&sc->mutex);
1873 1874

	ath9k_ps_wakeup(sc);
1875
	ath9k_hw_reset_tsf(sc->sc_ah);
1876 1877
	ath9k_ps_restore(sc);

1878
	mutex_unlock(&sc->mutex);
1879
}
1880

1881
static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1882
			      struct ieee80211_vif *vif,
1883 1884
			      enum ieee80211_ampdu_mlme_action action,
			      struct ieee80211_sta *sta,
1885
			      u16 tid, u16 *ssn, u8 buf_size)
1886
{
1887
	struct ath_softc *sc = hw->priv;
1888
	bool flush = false;
1889
	int ret = 0;
1890

1891
	mutex_lock(&sc->mutex);
1892

1893 1894 1895 1896 1897 1898
	switch (action) {
	case IEEE80211_AMPDU_RX_START:
		break;
	case IEEE80211_AMPDU_RX_STOP:
		break;
	case IEEE80211_AMPDU_TX_START:
1899
		ath9k_ps_wakeup(sc);
1900 1901 1902
		ret = ath_tx_aggr_start(sc, sta, tid, ssn);
		if (!ret)
			ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1903
		ath9k_ps_restore(sc);
1904
		break;
1905 1906
	case IEEE80211_AMPDU_TX_STOP_FLUSH:
	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1907 1908
		flush = true;
	case IEEE80211_AMPDU_TX_STOP_CONT:
1909
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
1910
		ath_tx_aggr_stop(sc, sta, tid);
1911
		if (!flush)
1912
			ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1913
		ath9k_ps_restore(sc);
1914
		break;
1915
	case IEEE80211_AMPDU_TX_OPERATIONAL:
1916
		ath9k_ps_wakeup(sc);
1917
		ath_tx_aggr_resume(sc, sta, tid);
1918
		ath9k_ps_restore(sc);
1919
		break;
1920
	default:
1921
		ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
1922 1923
	}

1924
	mutex_unlock(&sc->mutex);
1925

1926
	return ret;
1927 1928
}

1929 1930 1931
static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
			     struct survey_info *survey)
{
1932
	struct ath_softc *sc = hw->priv;
1933
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1934
	struct ieee80211_supported_band *sband;
1935 1936 1937
	struct ieee80211_channel *chan;
	int pos;

L
Luis R. Rodriguez 已提交
1938 1939 1940
	if (config_enabled(CONFIG_ATH9K_TX99))
		return -EOPNOTSUPP;

S
Sujith Manoharan 已提交
1941
	spin_lock_bh(&common->cc_lock);
1942 1943
	if (idx == 0)
		ath_update_survey_stats(sc);
1944 1945 1946 1947 1948 1949

	sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
	if (sband && idx >= sband->n_channels) {
		idx -= sband->n_channels;
		sband = NULL;
	}
1950

1951 1952
	if (!sband)
		sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
1953

1954
	if (!sband || idx >= sband->n_channels) {
S
Sujith Manoharan 已提交
1955
		spin_unlock_bh(&common->cc_lock);
1956
		return -ENOENT;
1957
	}
1958

1959 1960 1961 1962
	chan = &sband->channels[idx];
	pos = chan->hw_value;
	memcpy(survey, &sc->survey[pos], sizeof(*survey));
	survey->channel = chan;
S
Sujith Manoharan 已提交
1963
	spin_unlock_bh(&common->cc_lock);
1964

1965 1966 1967
	return 0;
}

1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981
static void ath9k_enable_dynack(struct ath_softc *sc)
{
#ifdef CONFIG_ATH9K_DYNACK
	u32 rfilt;
	struct ath_hw *ah = sc->sc_ah;

	ath_dynack_reset(ah);

	ah->dynack.enabled = true;
	rfilt = ath_calcrxfilter(sc);
	ath9k_hw_setrxfilter(ah, rfilt);
#endif
}

1982 1983
static void ath9k_set_coverage_class(struct ieee80211_hw *hw,
				     s16 coverage_class)
1984
{
1985
	struct ath_softc *sc = hw->priv;
1986 1987
	struct ath_hw *ah = sc->sc_ah;

L
Luis R. Rodriguez 已提交
1988 1989 1990
	if (config_enabled(CONFIG_ATH9K_TX99))
		return;

1991
	mutex_lock(&sc->mutex);
1992

1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007
	if (coverage_class >= 0) {
		ah->coverage_class = coverage_class;
		if (ah->dynack.enabled) {
			u32 rfilt;

			ah->dynack.enabled = false;
			rfilt = ath_calcrxfilter(sc);
			ath9k_hw_setrxfilter(ah, rfilt);
		}
		ath9k_ps_wakeup(sc);
		ath9k_hw_init_global_settings(ah);
		ath9k_ps_restore(sc);
	} else if (!ah->dynack.enabled) {
		ath9k_enable_dynack(sc);
	}
2008

2009 2010 2011
	mutex_unlock(&sc->mutex);
}

2012 2013
static bool ath9k_has_tx_pending(struct ath_softc *sc,
				 bool sw_pending)
F
Felix Fietkau 已提交
2014
{
2015
	int i, npend = 0;
F
Felix Fietkau 已提交
2016 2017 2018 2019 2020

	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
		if (!ATH_TXQ_SETUP(sc, i))
			continue;

2021 2022
		npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i],
						 sw_pending);
F
Felix Fietkau 已提交
2023 2024 2025 2026 2027 2028 2029
		if (npend)
			break;
	}

	return !!npend;
}

2030 2031
static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
			u32 queues, bool drop)
2032 2033 2034 2035
{
	struct ath_softc *sc = hw->priv;

	mutex_lock(&sc->mutex);
2036
	__ath9k_flush(hw, queues, drop, true);
2037 2038 2039
	mutex_unlock(&sc->mutex);
}

2040 2041
void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
		   bool sw_pending)
2042 2043
{
	struct ath_softc *sc = hw->priv;
2044 2045
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
2046
	int timeout;
2047
	bool drain_txq;
2048 2049 2050

	cancel_delayed_work_sync(&sc->tx_complete_work);

2051
	if (ah->ah_flags & AH_UNPLUGGED) {
2052
		ath_dbg(common, ANY, "Device has been unplugged!\n");
2053 2054 2055
		return;
	}

2056
	if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
2057
		ath_dbg(common, ANY, "Device not present\n");
2058 2059 2060
		return;
	}

2061 2062 2063 2064 2065 2066 2067
	spin_lock_bh(&sc->chan_lock);
	timeout = sc->cur_chan->flush_timeout;
	spin_unlock_bh(&sc->chan_lock);

	ath_dbg(common, CHAN_CTX,
		"Flush timeout: %d\n", jiffies_to_msecs(timeout));

2068
	if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc, sw_pending),
F
Felix Fietkau 已提交
2069 2070
			       timeout) > 0)
		drop = false;
2071

2072 2073 2074
	if (drop) {
		ath9k_ps_wakeup(sc);
		spin_lock_bh(&sc->sc_pcu_lock);
2075
		drain_txq = ath_drain_all_txq(sc);
2076
		spin_unlock_bh(&sc->sc_pcu_lock);
2077

2078
		if (!drain_txq)
S
Sujith Manoharan 已提交
2079
			ath_reset(sc, NULL);
2080

2081 2082
		ath9k_ps_restore(sc);
	}
2083

2084 2085 2086
	ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
}

2087 2088 2089 2090
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
{
	struct ath_softc *sc = hw->priv;

2091
	return ath9k_has_tx_pending(sc, true);
2092 2093
}

2094
static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
2095 2096 2097 2098 2099 2100 2101
{
	struct ath_softc *sc = hw->priv;
	struct ath_hw *ah = sc->sc_ah;
	struct ieee80211_vif *vif;
	struct ath_vif *avp;
	struct ath_buf *bf;
	struct ath_tx_status ts;
2102
	bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
2103 2104 2105 2106 2107 2108
	int status;

	vif = sc->beacon.bslot[0];
	if (!vif)
		return 0;

S
Sujith Manoharan 已提交
2109
	if (!vif->bss_conf.enable_beacon)
2110 2111
		return 0;

S
Sujith Manoharan 已提交
2112 2113
	avp = (void *)vif->drv_priv;

2114
	if (!sc->beacon.tx_processed && !edma) {
2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134
		tasklet_disable(&sc->bcon_tasklet);

		bf = avp->av_bcbuf;
		if (!bf || !bf->bf_mpdu)
			goto skip;

		status = ath9k_hw_txprocdesc(ah, bf->bf_desc, &ts);
		if (status == -EINPROGRESS)
			goto skip;

		sc->beacon.tx_processed = true;
		sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);

skip:
		tasklet_enable(&sc->bcon_tasklet);
	}

	return sc->beacon.tx_last;
}

2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148
static int ath9k_get_stats(struct ieee80211_hw *hw,
			   struct ieee80211_low_level_stats *stats)
{
	struct ath_softc *sc = hw->priv;
	struct ath_hw *ah = sc->sc_ah;
	struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;

	stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;
	stats->dot11RTSFailureCount = mib_stats->rts_bad;
	stats->dot11FCSErrorCount = mib_stats->fcs_bad;
	stats->dot11RTSSuccessCount = mib_stats->rts_good;
	return 0;
}

2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166
static u32 fill_chainmask(u32 cap, u32 new)
{
	u32 filled = 0;
	int i;

	for (i = 0; cap && new; i++, cap >>= 1) {
		if (!(cap & BIT(0)))
			continue;

		if (new & BIT(0))
			filled |= BIT(i);

		new >>= 1;
	}

	return filled;
}

2167 2168
static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
{
2169 2170 2171
	if (AR_SREV_9300_20_OR_LATER(ah))
		return true;

2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183
	switch (val & 0x7) {
	case 0x1:
	case 0x3:
	case 0x7:
		return true;
	case 0x2:
		return (ah->caps.rx_chainmask == 1);
	default:
		return false;
	}
}

2184 2185 2186 2187 2188
static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
{
	struct ath_softc *sc = hw->priv;
	struct ath_hw *ah = sc->sc_ah;

2189 2190 2191 2192
	if (ah->caps.rx_chainmask != 1)
		rx_ant |= tx_ant;

	if (!validate_antenna_mask(ah, rx_ant) || !tx_ant)
2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207
		return -EINVAL;

	sc->ant_rx = rx_ant;
	sc->ant_tx = tx_ant;

	if (ah->caps.rx_chainmask == 1)
		return 0;

	/* AR9100 runs into calibration issues if not all rx chains are enabled */
	if (AR_SREV_9100(ah))
		ah->rxchainmask = 0x7;
	else
		ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant);

	ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant);
2208
	ath9k_cmn_reload_chainmask(ah);
2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221

	return 0;
}

static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
{
	struct ath_softc *sc = hw->priv;

	*tx_ant = sc->ant_tx;
	*rx_ant = sc->ant_rx;
	return 0;
}

2222 2223 2224
static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
{
	struct ath_softc *sc = hw->priv;
2225 2226
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	set_bit(ATH_OP_SCANNING, &common->op_flags);
2227 2228 2229 2230 2231
}

static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
{
	struct ath_softc *sc = hw->priv;
2232 2233
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	clear_bit(ATH_OP_SCANNING, &common->op_flags);
2234
}
2235

2236 2237
#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT

F
Felix Fietkau 已提交
2238
static int ath9k_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2239
			 struct ieee80211_scan_request *hw_req)
F
Felix Fietkau 已提交
2240
{
2241
	struct cfg80211_scan_request *req = &hw_req->req;
F
Felix Fietkau 已提交
2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258
	struct ath_softc *sc = hw->priv;
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	int ret = 0;

	mutex_lock(&sc->mutex);

	if (WARN_ON(sc->offchannel.scan_req)) {
		ret = -EBUSY;
		goto out;
	}

	ath9k_ps_wakeup(sc);
	set_bit(ATH_OP_SCANNING, &common->op_flags);
	sc->offchannel.scan_vif = vif;
	sc->offchannel.scan_req = req;
	sc->offchannel.scan_idx = 0;

S
Sujith Manoharan 已提交
2259 2260 2261 2262 2263
	ath_dbg(common, CHAN_CTX, "HW scan request received on vif: %pM\n",
		vif->addr);

	if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE) {
		ath_dbg(common, CHAN_CTX, "Starting HW scan\n");
2264
		ath_offchannel_next(sc);
S
Sujith Manoharan 已提交
2265
	}
F
Felix Fietkau 已提交
2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276

out:
	mutex_unlock(&sc->mutex);

	return ret;
}

static void ath9k_cancel_hw_scan(struct ieee80211_hw *hw,
				 struct ieee80211_vif *vif)
{
	struct ath_softc *sc = hw->priv;
S
Sujith Manoharan 已提交
2277 2278 2279
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);

	ath_dbg(common, CHAN_CTX, "Cancel HW scan on vif: %pM\n", vif->addr);
F
Felix Fietkau 已提交
2280 2281 2282 2283 2284 2285 2286

	mutex_lock(&sc->mutex);
	del_timer_sync(&sc->offchannel.timer);
	ath_scan_complete(sc, true);
	mutex_unlock(&sc->mutex);
}

2287 2288 2289 2290 2291 2292
static int ath9k_remain_on_channel(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_channel *chan, int duration,
				   enum ieee80211_roc_type type)
{
	struct ath_softc *sc = hw->priv;
S
Sujith Manoharan 已提交
2293
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307
	int ret = 0;

	mutex_lock(&sc->mutex);

	if (WARN_ON(sc->offchannel.roc_vif)) {
		ret = -EBUSY;
		goto out;
	}

	ath9k_ps_wakeup(sc);
	sc->offchannel.roc_vif = vif;
	sc->offchannel.roc_chan = chan;
	sc->offchannel.roc_duration = duration;

S
Sujith Manoharan 已提交
2308 2309 2310 2311 2312 2313
	ath_dbg(common, CHAN_CTX,
		"RoC request on vif: %pM, type: %d duration: %d\n",
		vif->addr, type, duration);

	if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE) {
		ath_dbg(common, CHAN_CTX, "Starting RoC period\n");
2314
		ath_offchannel_next(sc);
S
Sujith Manoharan 已提交
2315
	}
2316 2317 2318 2319 2320 2321 2322 2323 2324 2325

out:
	mutex_unlock(&sc->mutex);

	return ret;
}

static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw)
{
	struct ath_softc *sc = hw->priv;
S
Sujith Manoharan 已提交
2326
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2327 2328 2329

	mutex_lock(&sc->mutex);

S
Sujith Manoharan 已提交
2330
	ath_dbg(common, CHAN_CTX, "Cancel RoC\n");
2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342
	del_timer_sync(&sc->offchannel.timer);

	if (sc->offchannel.roc_vif) {
		if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START)
			ath_roc_complete(sc, true);
	}

	mutex_unlock(&sc->mutex);

	return 0;
}

2343 2344 2345 2346
static int ath9k_add_chanctx(struct ieee80211_hw *hw,
			     struct ieee80211_chanctx_conf *conf)
{
	struct ath_softc *sc = hw->priv;
S
Sujith Manoharan 已提交
2347
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2348
	struct ath_chanctx *ctx, **ptr;
2349
	int pos;
2350 2351

	mutex_lock(&sc->mutex);
2352 2353 2354 2355 2356 2357 2358 2359

	ath_for_each_chanctx(sc, ctx) {
		if (ctx->assigned)
			continue;

		ptr = (void *) conf->drv_priv;
		*ptr = ctx;
		ctx->assigned = true;
2360 2361
		pos = ctx - &sc->chanctx[0];
		ctx->hw_queue_base = pos * IEEE80211_NUM_ACS;
S
Sujith Manoharan 已提交
2362 2363 2364 2365 2366

		ath_dbg(common, CHAN_CTX,
			"Add channel context: %d MHz\n",
			conf->def.chan->center_freq);

2367
		ath_chanctx_set_channel(sc, ctx, &conf->def);
2368 2369
		ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_ASSIGN);

2370
		mutex_unlock(&sc->mutex);
2371
		return 0;
2372
	}
S
Sujith Manoharan 已提交
2373

2374
	mutex_unlock(&sc->mutex);
2375
	return -ENOSPC;
2376 2377 2378 2379 2380 2381 2382
}


static void ath9k_remove_chanctx(struct ieee80211_hw *hw,
				 struct ieee80211_chanctx_conf *conf)
{
	struct ath_softc *sc = hw->priv;
S
Sujith Manoharan 已提交
2383
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2384 2385 2386
	struct ath_chanctx *ctx = ath_chanctx_get(conf);

	mutex_lock(&sc->mutex);
S
Sujith Manoharan 已提交
2387 2388 2389 2390 2391

	ath_dbg(common, CHAN_CTX,
		"Remove channel context: %d MHz\n",
		conf->def.chan->center_freq);

2392
	ctx->assigned = false;
S
Sujith Manoharan 已提交
2393
	ctx->hw_queue_base = 0;
2394
	ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_UNASSIGN);
S
Sujith Manoharan 已提交
2395

2396 2397 2398 2399 2400 2401 2402 2403
	mutex_unlock(&sc->mutex);
}

static void ath9k_change_chanctx(struct ieee80211_hw *hw,
				 struct ieee80211_chanctx_conf *conf,
				 u32 changed)
{
	struct ath_softc *sc = hw->priv;
S
Sujith Manoharan 已提交
2404
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2405 2406 2407
	struct ath_chanctx *ctx = ath_chanctx_get(conf);

	mutex_lock(&sc->mutex);
S
Sujith Manoharan 已提交
2408 2409 2410
	ath_dbg(common, CHAN_CTX,
		"Change channel context: %d MHz\n",
		conf->def.chan->center_freq);
2411 2412 2413 2414 2415 2416 2417 2418 2419
	ath_chanctx_set_channel(sc, ctx, &conf->def);
	mutex_unlock(&sc->mutex);
}

static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw,
				    struct ieee80211_vif *vif,
				    struct ieee80211_chanctx_conf *conf)
{
	struct ath_softc *sc = hw->priv;
S
Sujith Manoharan 已提交
2420
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2421 2422
	struct ath_vif *avp = (void *)vif->drv_priv;
	struct ath_chanctx *ctx = ath_chanctx_get(conf);
2423
	int i;
2424 2425

	mutex_lock(&sc->mutex);
S
Sujith Manoharan 已提交
2426 2427 2428 2429 2430 2431

	ath_dbg(common, CHAN_CTX,
		"Assign VIF (addr: %pM, type: %d, p2p: %d) to channel context: %d MHz\n",
		vif->addr, vif->type, vif->p2p,
		conf->def.chan->center_freq);

2432
	avp->chanctx = ctx;
2433
	ctx->nvifs_assigned++;
2434
	list_add_tail(&avp->list, &ctx->vifs);
2435
	ath9k_calculate_summary_state(sc, ctx);
2436 2437
	for (i = 0; i < IEEE80211_NUM_ACS; i++)
		vif->hw_queue[i] = ctx->hw_queue_base + i;
S
Sujith Manoharan 已提交
2438

2439 2440 2441 2442 2443 2444 2445 2446 2447 2448
	mutex_unlock(&sc->mutex);

	return 0;
}

static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,
				       struct ieee80211_vif *vif,
				       struct ieee80211_chanctx_conf *conf)
{
	struct ath_softc *sc = hw->priv;
S
Sujith Manoharan 已提交
2449
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2450 2451
	struct ath_vif *avp = (void *)vif->drv_priv;
	struct ath_chanctx *ctx = ath_chanctx_get(conf);
2452
	int ac;
2453 2454

	mutex_lock(&sc->mutex);
S
Sujith Manoharan 已提交
2455 2456 2457 2458 2459 2460

	ath_dbg(common, CHAN_CTX,
		"Remove VIF (addr: %pM, type: %d, p2p: %d) from channel context: %d MHz\n",
		vif->addr, vif->type, vif->p2p,
		conf->def.chan->center_freq);

2461
	avp->chanctx = NULL;
2462
	ctx->nvifs_assigned--;
2463
	list_del(&avp->list);
2464
	ath9k_calculate_summary_state(sc, ctx);
2465 2466
	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
		vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE;
S
Sujith Manoharan 已提交
2467

2468 2469 2470
	mutex_unlock(&sc->mutex);
}

2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491
static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw,
				 struct ieee80211_vif *vif)
{
	struct ath_softc *sc = hw->priv;
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	struct ath_vif *avp = (struct ath_vif *) vif->drv_priv;
	bool changed = false;

	if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
		return;

	if (!avp->chanctx)
		return;

	mutex_lock(&sc->mutex);

	spin_lock_bh(&sc->chan_lock);
	if (sc->next_chan || (sc->cur_chan != avp->chanctx)) {
		sc->next_chan = avp->chanctx;
		changed = true;
	}
2492 2493 2494
	ath_dbg(common, CHAN_CTX,
		"%s: Set chanctx state to FORCE_ACTIVE, changed: %d\n",
		__func__, changed);
2495 2496 2497 2498 2499 2500 2501 2502 2503
	sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE;
	spin_unlock_bh(&sc->chan_lock);

	if (changed)
		ath_chanctx_set_next(sc, true);

	mutex_unlock(&sc->mutex);
}

F
Felix Fietkau 已提交
2504 2505
void ath9k_fill_chanctx_ops(void)
{
2506
	if (!ath9k_is_chanctx_enabled())
F
Felix Fietkau 已提交
2507 2508
		return;

S
Sujith Manoharan 已提交
2509 2510 2511
	ath9k_ops.hw_scan                  = ath9k_hw_scan;
	ath9k_ops.cancel_hw_scan           = ath9k_cancel_hw_scan;
	ath9k_ops.remain_on_channel        = ath9k_remain_on_channel;
2512
	ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel;
S
Sujith Manoharan 已提交
2513 2514 2515 2516 2517
	ath9k_ops.add_chanctx              = ath9k_add_chanctx;
	ath9k_ops.remove_chanctx           = ath9k_remove_chanctx;
	ath9k_ops.change_chanctx           = ath9k_change_chanctx;
	ath9k_ops.assign_vif_chanctx       = ath9k_assign_vif_chanctx;
	ath9k_ops.unassign_vif_chanctx     = ath9k_unassign_vif_chanctx;
2518
	ath9k_ops.mgd_prepare_tx           = ath9k_mgd_prepare_tx;
F
Felix Fietkau 已提交
2519 2520
}

2521 2522
#endif

2523
struct ieee80211_ops ath9k_ops = {
2524 2525 2526 2527
	.tx 		    = ath9k_tx,
	.start 		    = ath9k_start,
	.stop 		    = ath9k_stop,
	.add_interface 	    = ath9k_add_interface,
2528
	.change_interface   = ath9k_change_interface,
2529 2530 2531
	.remove_interface   = ath9k_remove_interface,
	.config 	    = ath9k_config,
	.configure_filter   = ath9k_configure_filter,
S
Sujith Manoharan 已提交
2532
	.sta_state          = ath9k_sta_state,
2533
	.sta_notify         = ath9k_sta_notify,
2534 2535 2536 2537
	.conf_tx 	    = ath9k_conf_tx,
	.bss_info_changed   = ath9k_bss_info_changed,
	.set_key            = ath9k_set_key,
	.get_tsf 	    = ath9k_get_tsf,
2538
	.set_tsf 	    = ath9k_set_tsf,
2539
	.reset_tsf 	    = ath9k_reset_tsf,
2540
	.ampdu_action       = ath9k_ampdu_action,
2541
	.get_survey	    = ath9k_get_survey,
J
Johannes Berg 已提交
2542
	.rfkill_poll        = ath9k_rfkill_poll_state,
2543
	.set_coverage_class = ath9k_set_coverage_class,
2544
	.flush		    = ath9k_flush,
2545
	.tx_frames_pending  = ath9k_tx_frames_pending,
2546
	.tx_last_beacon     = ath9k_tx_last_beacon,
2547
	.release_buffered_frames = ath9k_release_buffered_frames,
2548
	.get_stats	    = ath9k_get_stats,
2549 2550
	.set_antenna	    = ath9k_set_antenna,
	.get_antenna	    = ath9k_get_antenna,
2551

S
Sujith Manoharan 已提交
2552
#ifdef CONFIG_ATH9K_WOW
2553 2554 2555 2556 2557
	.suspend	    = ath9k_suspend,
	.resume		    = ath9k_resume,
	.set_wakeup	    = ath9k_set_wakeup,
#endif

2558 2559
#ifdef CONFIG_ATH9K_DEBUGFS
	.get_et_sset_count  = ath9k_get_et_sset_count,
2560 2561 2562 2563
	.get_et_stats       = ath9k_get_et_stats,
	.get_et_strings     = ath9k_get_et_strings,
#endif

2564
#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_STATION_STATISTICS)
2565
	.sta_add_debugfs    = ath9k_sta_add_debugfs,
2566
#endif
2567 2568
	.sw_scan_start	    = ath9k_sw_scan_start,
	.sw_scan_complete   = ath9k_sw_scan_complete,
2569
};