main.c 53.3 KB
Newer Older
1
/*
2
 * Copyright (c) 2008-2009 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>
S
Sujith 已提交
18
#include "ath9k.h"
19
#include "btcoex.h"
20

21 22
static void ath_cache_conf_rate(struct ath_softc *sc,
				struct ieee80211_conf *conf)
S
Sujith 已提交
23
{
24 25 26
	switch (conf->channel->band) {
	case IEEE80211_BAND_2GHZ:
		if (conf_is_ht20(conf))
27
			sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
28
		else if (conf_is_ht40_minus(conf))
29
			sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
30
		else if (conf_is_ht40_plus(conf))
31
			sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS;
32
		else
33
			sc->cur_rate_mode = ATH9K_MODE_11G;
34 35 36
		break;
	case IEEE80211_BAND_5GHZ:
		if (conf_is_ht20(conf))
37
			sc->cur_rate_mode = ATH9K_MODE_11NA_HT20;
38
		else if (conf_is_ht40_minus(conf))
39
			sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS;
40
		else if (conf_is_ht40_plus(conf))
41
			sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS;
42
		else
43
			sc->cur_rate_mode = ATH9K_MODE_11A;
44 45
		break;
	default:
46
		BUG_ON(1);
47 48
		break;
	}
S
Sujith 已提交
49 50 51 52
}

static void ath_update_txpow(struct ath_softc *sc)
{
53
	struct ath_hw *ah = sc->sc_ah;
S
Sujith 已提交
54 55
	u32 txpow;

S
Sujith 已提交
56 57
	if (sc->curtxpow != sc->config.txpowlimit) {
		ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
S
Sujith 已提交
58 59
		/* read back in case value is clamped */
		ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
S
Sujith 已提交
60
		sc->curtxpow = txpow;
S
Sujith 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
	}
}

static u8 parse_mpdudensity(u8 mpdudensity)
{
	/*
	 * 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;
	}
}

99 100 101 102 103 104 105 106 107 108 109 110 111
static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
						struct ieee80211_hw *hw)
{
	struct ieee80211_channel *curchan = hw->conf.channel;
	struct ath9k_channel *channel;
	u8 chan_idx;

	chan_idx = curchan->hw_value;
	channel = &sc->sc_ah->channels[chan_idx];
	ath9k_update_ichannel(sc, hw, channel);
	return channel;
}

S
Sujith 已提交
112
bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
113 114 115 116
{
	unsigned long flags;
	bool ret;

117 118 119
	spin_lock_irqsave(&sc->sc_pm_lock, flags);
	ret = ath9k_hw_setpower(sc->sc_ah, mode);
	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
120 121 122 123

	return ret;
}

124 125 126 127 128 129 130 131
void ath9k_ps_wakeup(struct ath_softc *sc)
{
	unsigned long flags;

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

132
	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
133 134 135 136 137 138 139 140 141 142 143 144 145

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

void ath9k_ps_restore(struct ath_softc *sc)
{
	unsigned long flags;

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

146 147 148 149
	if (sc->ps_idle)
		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
	else if (sc->ps_enabled &&
		 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
S
Sujith 已提交
150 151 152
			      PS_WAIT_FOR_CAB |
			      PS_WAIT_FOR_PSPOLL_DATA |
			      PS_WAIT_FOR_TX_ACK)))
153
		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
154 155 156 157 158

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

S
Sujith 已提交
159 160 161 162 163
/*
 * Set/change channels.  If the channel is really being changed, it's done
 * by reseting the chip.  To accomplish this we must first cleanup any pending
 * DMA, then restart stuff.
*/
164 165
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
		    struct ath9k_channel *hchan)
S
Sujith 已提交
166
{
167
	struct ath_hw *ah = sc->sc_ah;
168
	struct ath_common *common = ath9k_hw_common(ah);
L
Luis R. Rodriguez 已提交
169
	struct ieee80211_conf *conf = &common->hw->conf;
S
Sujith 已提交
170
	bool fastcc = true, stopped;
171 172
	struct ieee80211_channel *channel = hw->conf.channel;
	int r;
S
Sujith 已提交
173 174 175 176

	if (sc->sc_flags & SC_OP_INVALID)
		return -EIO;

177 178
	ath9k_ps_wakeup(sc);

179 180 181 182 183 184 185 186 187 188
	/*
	 * This is only performed if the channel settings have
	 * actually changed.
	 *
	 * To switch channels clear any pending DMA operations;
	 * wait long enough for the RX fifo to drain, reset the
	 * hardware at the new frequency, and then re-enable
	 * the relevant bits of the h/w.
	 */
	ath9k_hw_set_interrupts(ah, 0);
S
Sujith 已提交
189
	ath_drain_all_txq(sc, false);
190
	stopped = ath_stoprecv(sc);
S
Sujith 已提交
191

192 193 194
	/* XXX: do not flush receive queue here. We don't want
	 * to flush data frames already in queue because of
	 * changing channel. */
S
Sujith 已提交
195

196 197 198
	if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
		fastcc = false;

199
	ath_print(common, ATH_DBG_CONFIG,
L
Luis R. Rodriguez 已提交
200
		  "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n",
201
		  sc->sc_ah->curchan->channel,
L
Luis R. Rodriguez 已提交
202
		  channel->center_freq, conf_is_ht40(conf));
S
Sujith 已提交
203

204 205 206 207
	spin_lock_bh(&sc->sc_resetlock);

	r = ath9k_hw_reset(ah, hchan, fastcc);
	if (r) {
208
		ath_print(common, ATH_DBG_FATAL,
209
			  "Unable to reset channel (%u MHz), "
210 211
			  "reset status %d\n",
			  channel->center_freq, r);
212
		spin_unlock_bh(&sc->sc_resetlock);
213
		goto ps_restore;
S
Sujith 已提交
214
	}
215 216 217 218 219
	spin_unlock_bh(&sc->sc_resetlock);

	sc->sc_flags &= ~SC_OP_FULL_RESET;

	if (ath_startrecv(sc) != 0) {
220 221
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to restart recv logic\n");
222 223
		r = -EIO;
		goto ps_restore;
224 225 226 227
	}

	ath_cache_conf_rate(sc, &hw->conf);
	ath_update_txpow(sc);
P
Pavel Roskin 已提交
228
	ath9k_hw_set_interrupts(ah, ah->imask);
229 230

 ps_restore:
231
	ath9k_ps_restore(sc);
232
	return r;
S
Sujith 已提交
233 234 235 236 237 238 239 240 241
}

/*
 *  This routine performs the periodic noise floor calibration function
 *  that is used to adjust and optimize the chip performance.  This
 *  takes environmental changes (location, temperature) into account.
 *  When the task is complete, it reschedules itself depending on the
 *  appropriate interval that was calculated.
 */
S
Sujith 已提交
242
void ath_ani_calibrate(unsigned long data)
S
Sujith 已提交
243
{
244 245
	struct ath_softc *sc = (struct ath_softc *)data;
	struct ath_hw *ah = sc->sc_ah;
246
	struct ath_common *common = ath9k_hw_common(ah);
S
Sujith 已提交
247 248 249 250
	bool longcal = false;
	bool shortcal = false;
	bool aniflag = false;
	unsigned int timestamp = jiffies_to_msecs(jiffies);
251
	u32 cal_interval, short_cal_interval;
S
Sujith 已提交
252

253 254
	short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
		ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
S
Sujith 已提交
255

256 257 258 259 260 261
	/* Only calibrate if awake */
	if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
		goto set_timer;

	ath9k_ps_wakeup(sc);

S
Sujith 已提交
262
	/* Long calibration runs independently of short calibration. */
263
	if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
S
Sujith 已提交
264
		longcal = true;
265
		ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
266
		common->ani.longcal_timer = timestamp;
S
Sujith 已提交
267 268
	}

S
Sujith 已提交
269
	/* Short calibration applies only while caldone is false */
270 271
	if (!common->ani.caldone) {
		if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
S
Sujith 已提交
272
			shortcal = true;
273 274
			ath_print(common, ATH_DBG_ANI,
				  "shortcal @%lu\n", jiffies);
275 276
			common->ani.shortcal_timer = timestamp;
			common->ani.resetcal_timer = timestamp;
S
Sujith 已提交
277 278
		}
	} else {
279
		if ((timestamp - common->ani.resetcal_timer) >=
S
Sujith 已提交
280
		    ATH_RESTART_CALINTERVAL) {
281 282 283
			common->ani.caldone = ath9k_hw_reset_calvalid(ah);
			if (common->ani.caldone)
				common->ani.resetcal_timer = timestamp;
S
Sujith 已提交
284 285 286 287
		}
	}

	/* Verify whether we must check ANI */
288
	if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
S
Sujith 已提交
289
		aniflag = true;
290
		common->ani.checkani_timer = timestamp;
S
Sujith 已提交
291 292 293 294 295 296
	}

	/* Skip all processing if there's nothing to do. */
	if (longcal || shortcal || aniflag) {
		/* Call ANI routine if necessary */
		if (aniflag)
297
			ath9k_hw_ani_monitor(ah, ah->curchan);
S
Sujith 已提交
298 299 300

		/* Perform calibration if necessary */
		if (longcal || shortcal) {
301
			common->ani.caldone =
302 303 304 305
				ath9k_hw_calibrate(ah,
						   ah->curchan,
						   common->rx_chainmask,
						   longcal);
S
Sujith 已提交
306 307

			if (longcal)
308
				common->ani.noise_floor = ath9k_hw_getchan_noise(ah,
S
Sujith 已提交
309 310
								     ah->curchan);

311 312 313 314
			ath_print(common, ATH_DBG_ANI,
				  " calibrate chan %u/%x nf: %d\n",
				  ah->curchan->channel,
				  ah->curchan->channelFlags,
315
				  common->ani.noise_floor);
S
Sujith 已提交
316 317 318
		}
	}

319 320
	ath9k_ps_restore(sc);

321
set_timer:
S
Sujith 已提交
322 323 324 325 326
	/*
	* Set timer interval based on previous results.
	* The interval must be the shortest necessary to satisfy ANI,
	* short calibration and long calibration.
	*/
327
	cal_interval = ATH_LONG_CALINTERVAL;
328
	if (sc->sc_ah->config.enable_ani)
329
		cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
330
	if (!common->ani.caldone)
331
		cal_interval = min(cal_interval, (u32)short_cal_interval);
S
Sujith 已提交
332

333
	mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
S
Sujith 已提交
334 335
}

336
static void ath_start_ani(struct ath_common *common)
S
Sujith 已提交
337 338 339
{
	unsigned long timestamp = jiffies_to_msecs(jiffies);

340 341 342
	common->ani.longcal_timer = timestamp;
	common->ani.shortcal_timer = timestamp;
	common->ani.checkani_timer = timestamp;
S
Sujith 已提交
343

344
	mod_timer(&common->ani.timer,
S
Sujith 已提交
345 346 347
		  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
}

S
Sujith 已提交
348 349 350
/*
 * Update tx/rx chainmask. For legacy association,
 * hard code chainmask to 1x1, for 11n association, use
351 352
 * the chainmask configuration, for bt coexistence, use
 * the chainmask configuration even in legacy mode.
S
Sujith 已提交
353
 */
354
void ath_update_chainmask(struct ath_softc *sc, int is_ht)
S
Sujith 已提交
355
{
356
	struct ath_hw *ah = sc->sc_ah;
357
	struct ath_common *common = ath9k_hw_common(ah);
358

359
	if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
360
	    (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
361 362
		common->tx_chainmask = ah->caps.tx_chainmask;
		common->rx_chainmask = ah->caps.rx_chainmask;
S
Sujith 已提交
363
	} else {
364 365
		common->tx_chainmask = 1;
		common->rx_chainmask = 1;
S
Sujith 已提交
366 367
	}

368
	ath_print(common, ATH_DBG_CONFIG,
369
		  "tx chmask: %d, rx chmask: %d\n",
370 371
		  common->tx_chainmask,
		  common->rx_chainmask);
S
Sujith 已提交
372 373 374 375 376 377 378 379
}

static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
{
	struct ath_node *an;

	an = (struct ath_node *)sta->drv_priv;

380
	if (sc->sc_flags & SC_OP_TXAGGR) {
S
Sujith 已提交
381
		ath_tx_node_init(sc, an);
S
Sujith 已提交
382
		an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
383 384
				     sta->ht_cap.ampdu_factor);
		an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
385
		an->last_rssi = ATH_RSSI_DUMMY_MARKER;
386
	}
S
Sujith 已提交
387 388 389 390 391 392 393 394 395 396
}

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

	if (sc->sc_flags & SC_OP_TXAGGR)
		ath_tx_node_cleanup(sc, an);
}

S
Sujith 已提交
397
void ath9k_tasklet(unsigned long data)
S
Sujith 已提交
398 399
{
	struct ath_softc *sc = (struct ath_softc *)data;
400
	struct ath_hw *ah = sc->sc_ah;
401
	struct ath_common *common = ath9k_hw_common(ah);
402

S
Sujith 已提交
403
	u32 status = sc->intrstatus;
F
Felix Fietkau 已提交
404
	u32 rxmask;
S
Sujith 已提交
405

406 407
	ath9k_ps_wakeup(sc);

S
Sujith 已提交
408 409
	if (status & ATH9K_INT_FATAL) {
		ath_reset(sc, false);
410
		ath9k_ps_restore(sc);
S
Sujith 已提交
411
		return;
S
Sujith 已提交
412
	}
S
Sujith 已提交
413

F
Felix Fietkau 已提交
414 415 416 417 418 419 420
	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) {
S
Sujith 已提交
421
		spin_lock_bh(&sc->rx.rxflushlock);
F
Felix Fietkau 已提交
422 423 424 425 426 427 428

		/* 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 已提交
429
		spin_unlock_bh(&sc->rx.rxflushlock);
S
Sujith 已提交
430 431
	}

432 433 434 435 436 437
	if (status & ATH9K_INT_TX) {
		if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
			ath_tx_edma_tasklet(sc);
		else
			ath_tx_tasklet(sc);
	}
S
Sujith 已提交
438

439
	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
440 441 442 443
		/*
		 * TSF sync does not look correct; remain awake to sync with
		 * the next Beacon.
		 */
444 445
		ath_print(common, ATH_DBG_PS,
			  "TSFOOR - Sync with next Beacon\n");
S
Sujith 已提交
446
		sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
447 448
	}

449
	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
450 451 452
		if (status & ATH9K_INT_GENTIMER)
			ath_gen_timer_isr(sc->sc_ah);

S
Sujith 已提交
453
	/* re-enable hardware interrupt */
P
Pavel Roskin 已提交
454
	ath9k_hw_set_interrupts(ah, ah->imask);
455
	ath9k_ps_restore(sc);
S
Sujith 已提交
456 457
}

458
irqreturn_t ath_isr(int irq, void *dev)
S
Sujith 已提交
459
{
S
Sujith 已提交
460 461 462 463 464
#define SCHED_INTR (				\
		ATH9K_INT_FATAL |		\
		ATH9K_INT_RXORN |		\
		ATH9K_INT_RXEOL |		\
		ATH9K_INT_RX |			\
F
Felix Fietkau 已提交
465 466
		ATH9K_INT_RXLP |		\
		ATH9K_INT_RXHP |		\
S
Sujith 已提交
467 468 469
		ATH9K_INT_TX |			\
		ATH9K_INT_BMISS |		\
		ATH9K_INT_CST |			\
470 471
		ATH9K_INT_TSFOOR |		\
		ATH9K_INT_GENTIMER)
S
Sujith 已提交
472

S
Sujith 已提交
473
	struct ath_softc *sc = dev;
474
	struct ath_hw *ah = sc->sc_ah;
S
Sujith 已提交
475 476 477
	enum ath9k_int status;
	bool sched = false;

S
Sujith 已提交
478 479 480 481 482 483 484
	/*
	 * The hardware is not ready/present, don't
	 * touch anything. Note this can happen early
	 * on if the IRQ is shared.
	 */
	if (sc->sc_flags & SC_OP_INVALID)
		return IRQ_NONE;
S
Sujith 已提交
485

S
Sujith 已提交
486 487 488

	/* shared irq, not for us */

489
	if (!ath9k_hw_intrpend(ah))
S
Sujith 已提交
490 491 492 493 494 495 496 497 498
		return IRQ_NONE;

	/*
	 * 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.
	 */
	ath9k_hw_getisr(ah, &status);	/* NB: clears ISR too */
P
Pavel Roskin 已提交
499
	status &= ah->imask;	/* discard unasked-for bits */
S
Sujith 已提交
500

S
Sujith 已提交
501 502 503 504
	/*
	 * If there are no status bits set, then this interrupt was not
	 * for me (should have been caught above).
	 */
505
	if (!status)
S
Sujith 已提交
506
		return IRQ_NONE;
S
Sujith 已提交
507

S
Sujith 已提交
508 509 510 511 512 513 514 515 516 517
	/* 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 已提交
518 519
	if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
	    !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
S
Sujith 已提交
520 521 522 523 524 525 526 527
		goto chip_reset;

	if (status & ATH9K_INT_SWBA)
		tasklet_schedule(&sc->bcon_tasklet);

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

F
Felix Fietkau 已提交
528 529 530 531 532 533 534
	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
		if (status & ATH9K_INT_RXEOL) {
			ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
			ath9k_hw_set_interrupts(ah, ah->imask);
		}
	}

S
Sujith 已提交
535
	if (status & ATH9K_INT_MIB) {
S
Sujith 已提交
536
		/*
S
Sujith 已提交
537 538 539
		 * Disable interrupts until we service the MIB
		 * interrupt; otherwise it will continue to
		 * fire.
S
Sujith 已提交
540
		 */
S
Sujith 已提交
541 542 543 544 545 546
		ath9k_hw_set_interrupts(ah, 0);
		/*
		 * Let the hal handle the event. We assume
		 * it will clear whatever condition caused
		 * the interrupt.
		 */
547
		ath9k_hw_procmibevent(ah);
P
Pavel Roskin 已提交
548
		ath9k_hw_set_interrupts(ah, ah->imask);
S
Sujith 已提交
549
	}
S
Sujith 已提交
550

551 552
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
		if (status & ATH9K_INT_TIM_TIMER) {
S
Sujith 已提交
553 554
			/* Clear RxAbort bit so that we can
			 * receive frames */
555
			ath9k_setpower(sc, ATH9K_PM_AWAKE);
556
			ath9k_hw_setrxabort(sc->sc_ah, 0);
S
Sujith 已提交
557
			sc->ps_flags |= PS_WAIT_FOR_BEACON;
S
Sujith 已提交
558
		}
S
Sujith 已提交
559 560

chip_reset:
S
Sujith 已提交
561

562 563
	ath_debug_stat_interrupt(sc, status);

S
Sujith 已提交
564 565
	if (sched) {
		/* turn off every interrupt except SWBA */
P
Pavel Roskin 已提交
566
		ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
S
Sujith 已提交
567 568 569 570
		tasklet_schedule(&sc->intr_tq);
	}

	return IRQ_HANDLED;
S
Sujith 已提交
571 572

#undef SCHED_INTR
S
Sujith 已提交
573 574
}

575
static u32 ath_get_extchanmode(struct ath_softc *sc,
576
			       struct ieee80211_channel *chan,
S
Sujith 已提交
577
			       enum nl80211_channel_type channel_type)
578 579 580 581 582
{
	u32 chanmode = 0;

	switch (chan->band) {
	case IEEE80211_BAND_2GHZ:
S
Sujith 已提交
583 584 585
		switch(channel_type) {
		case NL80211_CHAN_NO_HT:
		case NL80211_CHAN_HT20:
586
			chanmode = CHANNEL_G_HT20;
S
Sujith 已提交
587 588
			break;
		case NL80211_CHAN_HT40PLUS:
589
			chanmode = CHANNEL_G_HT40PLUS;
S
Sujith 已提交
590 591
			break;
		case NL80211_CHAN_HT40MINUS:
592
			chanmode = CHANNEL_G_HT40MINUS;
S
Sujith 已提交
593 594
			break;
		}
595 596
		break;
	case IEEE80211_BAND_5GHZ:
S
Sujith 已提交
597 598 599
		switch(channel_type) {
		case NL80211_CHAN_NO_HT:
		case NL80211_CHAN_HT20:
600
			chanmode = CHANNEL_A_HT20;
S
Sujith 已提交
601 602
			break;
		case NL80211_CHAN_HT40PLUS:
603
			chanmode = CHANNEL_A_HT40PLUS;
S
Sujith 已提交
604 605
			break;
		case NL80211_CHAN_HT40MINUS:
606
			chanmode = CHANNEL_A_HT40MINUS;
S
Sujith 已提交
607 608
			break;
		}
609 610 611 612 613 614 615 616
		break;
	default:
		break;
	}

	return chanmode;
}

617
static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
618 619
			   struct ath9k_keyval *hk, const u8 *addr,
			   bool authenticator)
620
{
621
	struct ath_hw *ah = common->ah;
622 623
	const u8 *key_rxmic;
	const u8 *key_txmic;
624

625 626
	key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
	key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
627 628

	if (addr == NULL) {
629 630 631 632 633
		/*
		 * Group key installation - only two key cache entries are used
		 * regardless of splitmic capability since group key is only
		 * used either for TX or RX.
		 */
634 635 636 637 638 639 640
		if (authenticator) {
			memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
			memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
		} else {
			memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
			memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
		}
641
		return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
642
	}
643
	if (!common->splitmic) {
644
		/* TX and RX keys share the same key cache entry. */
645 646
		memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
		memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
647
		return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
648
	}
649 650 651 652

	/* Separate key cache entries for TX and RX */

	/* TX key goes at first index, RX key at +32. */
653
	memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
654
	if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
655
		/* TX MIC entry failed. No need to proceed further */
656
		ath_print(common, ATH_DBG_FATAL,
657
			  "Setting TX MIC Key Failed\n");
658 659 660 661 662
		return 0;
	}

	memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
	/* XXX delete tx key on failure? */
663
	return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
664 665
}

666
static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
667 668 669
{
	int i;

670 671 672
	for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
		if (test_bit(i, common->keymap) ||
		    test_bit(i + 64, common->keymap))
673
			continue; /* At least one part of TKIP key allocated */
674 675 676
		if (common->splitmic &&
		    (test_bit(i + 32, common->keymap) ||
		     test_bit(i + 64 + 32, common->keymap)))
677 678 679 680 681 682 683 684
			continue; /* At least one part of TKIP key allocated */

		/* Found a free slot for a TKIP key */
		return i;
	}
	return -1;
}

685
static int ath_reserve_key_cache_slot(struct ath_common *common)
686 687 688 689
{
	int i;

	/* First, try to find slots that would not be available for TKIP. */
690 691 692 693 694 695
	if (common->splitmic) {
		for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
			if (!test_bit(i, common->keymap) &&
			    (test_bit(i + 32, common->keymap) ||
			     test_bit(i + 64, common->keymap) ||
			     test_bit(i + 64 + 32, common->keymap)))
696
				return i;
697 698 699 700
			if (!test_bit(i + 32, common->keymap) &&
			    (test_bit(i, common->keymap) ||
			     test_bit(i + 64, common->keymap) ||
			     test_bit(i + 64 + 32, common->keymap)))
701
				return i + 32;
702 703 704 705
			if (!test_bit(i + 64, common->keymap) &&
			    (test_bit(i , common->keymap) ||
			     test_bit(i + 32, common->keymap) ||
			     test_bit(i + 64 + 32, common->keymap)))
706
				return i + 64;
707 708 709 710
			if (!test_bit(i + 64 + 32, common->keymap) &&
			    (test_bit(i, common->keymap) ||
			     test_bit(i + 32, common->keymap) ||
			     test_bit(i + 64, common->keymap)))
711
				return i + 64 + 32;
712 713
		}
	} else {
714 715 716
		for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
			if (!test_bit(i, common->keymap) &&
			    test_bit(i + 64, common->keymap))
717
				return i;
718 719
			if (test_bit(i, common->keymap) &&
			    !test_bit(i + 64, common->keymap))
720 721 722 723 724
				return i + 64;
		}
	}

	/* No partially used TKIP slots, pick any available slot */
725
	for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
726 727 728 729 730
		/* Do not allow slots that could be needed for TKIP group keys
		 * to be used. This limitation could be removed if we know that
		 * TKIP will not be used. */
		if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
			continue;
731
		if (common->splitmic) {
732 733 734 735 736 737
			if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
				continue;
			if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
				continue;
		}

738
		if (!test_bit(i, common->keymap))
739 740 741 742 743
			return i; /* Found a free slot for a key */
	}

	/* No free slot found */
	return -1;
744 745
}

746
static int ath_key_config(struct ath_common *common,
747
			  struct ieee80211_vif *vif,
748
			  struct ieee80211_sta *sta,
749 750
			  struct ieee80211_key_conf *key)
{
751
	struct ath_hw *ah = common->ah;
752 753
	struct ath9k_keyval hk;
	const u8 *mac = NULL;
754
	u8 gmac[ETH_ALEN];
755
	int ret = 0;
756
	int idx;
757 758 759 760 761 762 763 764 765 766 767 768 769 770

	memset(&hk, 0, sizeof(hk));

	switch (key->alg) {
	case ALG_WEP:
		hk.kv_type = ATH9K_CIPHER_WEP;
		break;
	case ALG_TKIP:
		hk.kv_type = ATH9K_CIPHER_TKIP;
		break;
	case ALG_CCMP:
		hk.kv_type = ATH9K_CIPHER_AES_CCM;
		break;
	default:
J
Jouni Malinen 已提交
771
		return -EOPNOTSUPP;
772 773
	}

774
	hk.kv_len = key->keylen;
775 776
	memcpy(hk.kv_val, key->key, key->keylen);

777
	if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801

		if (key->ap_addr) {
			/*
			 * Group keys on hardware that supports multicast frame
			 * key search use a mac that is the sender's address with
			 * the high bit set instead of the app-specified address.
			 */
			memcpy(gmac, key->ap_addr, ETH_ALEN);
			gmac[0] |= 0x80;
			mac = gmac;

			if (key->alg == ALG_TKIP)
				idx = ath_reserve_key_cache_slot_tkip(common);
			else
				idx = ath_reserve_key_cache_slot(common);
			if (idx < 0)
				mac = NULL; /* no free key cache entries */
		}

		if (!mac) {
			/* For now, use the default keys for broadcast keys. This may
			 * need to change with virtual interfaces. */
			idx = key->keyidx;
		}
802
	} else if (key->keyidx) {
803 804 805 806
		if (WARN_ON(!sta))
			return -EOPNOTSUPP;
		mac = sta->addr;

807 808 809 810 811 812
		if (vif->type != NL80211_IFTYPE_AP) {
			/* Only keyidx 0 should be used with unicast key, but
			 * allow this for client mode for now. */
			idx = key->keyidx;
		} else
			return -EIO;
813
	} else {
814 815 816 817
		if (WARN_ON(!sta))
			return -EOPNOTSUPP;
		mac = sta->addr;

818
		if (key->alg == ALG_TKIP)
819
			idx = ath_reserve_key_cache_slot_tkip(common);
820
		else
821
			idx = ath_reserve_key_cache_slot(common);
822
		if (idx < 0)
J
Jouni Malinen 已提交
823
			return -ENOSPC; /* no free key cache entries */
824 825 826
	}

	if (key->alg == ALG_TKIP)
827
		ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
828
				      vif->type == NL80211_IFTYPE_AP);
829
	else
830
		ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
831 832 833 834

	if (!ret)
		return -EIO;

835
	set_bit(idx, common->keymap);
836
	if (key->alg == ALG_TKIP) {
837 838 839 840
		set_bit(idx + 64, common->keymap);
		if (common->splitmic) {
			set_bit(idx + 32, common->keymap);
			set_bit(idx + 64 + 32, common->keymap);
841 842 843 844
		}
	}

	return idx;
845 846
}

847
static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key)
848
{
849 850 851
	struct ath_hw *ah = common->ah;

	ath9k_hw_keyreset(ah, key->hw_key_idx);
852 853 854
	if (key->hw_key_idx < IEEE80211_WEP_NKID)
		return;

855
	clear_bit(key->hw_key_idx, common->keymap);
856 857
	if (key->alg != ALG_TKIP)
		return;
858

859 860
	clear_bit(key->hw_key_idx + 64, common->keymap);
	if (common->splitmic) {
861
		ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
862 863
		clear_bit(key->hw_key_idx + 32, common->keymap);
		clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
864
	}
865 866
}

867
static void ath9k_bss_assoc_info(struct ath_softc *sc,
S
Sujith 已提交
868
				 struct ieee80211_vif *vif,
869
				 struct ieee80211_bss_conf *bss_conf)
870
{
871
	struct ath_hw *ah = sc->sc_ah;
872
	struct ath_common *common = ath9k_hw_common(ah);
873

874
	if (bss_conf->assoc) {
875 876 877
		ath_print(common, ATH_DBG_CONFIG,
			  "Bss Info ASSOC %d, bssid: %pM\n",
			   bss_conf->aid, common->curbssid);
878

879
		/* New association, store aid */
880
		common->curaid = bss_conf->aid;
881
		ath9k_hw_write_associd(ah);
882 883 884 885 886 887

		/*
		 * Request a re-configuration of Beacon related timers
		 * on the receipt of the first Beacon frame (i.e.,
		 * after time sync with the AP).
		 */
S
Sujith 已提交
888
		sc->ps_flags |= PS_BEACON_SYNC;
889

890
		/* Configure the beacon */
891
		ath_beacon_config(sc, vif);
892

893
		/* Reset rssi stats */
894
		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
895

896
		ath_start_ani(common);
897
	} else {
898
		ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
899
		common->curaid = 0;
900
		/* Stop ANI */
901
		del_timer_sync(&common->ani.timer);
902
	}
903
}
904

905
void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
906
{
907
	struct ath_hw *ah = sc->sc_ah;
908
	struct ath_common *common = ath9k_hw_common(ah);
909
	struct ieee80211_channel *channel = hw->conf.channel;
910
	int r;
911

912
	ath9k_ps_wakeup(sc);
V
Vivek Natarajan 已提交
913
	ath9k_hw_configpcipowersave(ah, 0, 0);
914

915 916 917
	if (!ah->curchan)
		ah->curchan = ath_get_curchannel(sc, sc->hw);

S
Sujith 已提交
918
	spin_lock_bh(&sc->sc_resetlock);
919
	r = ath9k_hw_reset(ah, ah->curchan, false);
920
	if (r) {
921
		ath_print(common, ATH_DBG_FATAL,
922
			  "Unable to reset channel (%u MHz), "
923 924
			  "reset status %d\n",
			  channel->center_freq, r);
925 926 927 928 929
	}
	spin_unlock_bh(&sc->sc_resetlock);

	ath_update_txpow(sc);
	if (ath_startrecv(sc) != 0) {
930 931
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to restart recv logic\n");
932 933 934 935
		return;
	}

	if (sc->sc_flags & SC_OP_BEACONS)
936
		ath_beacon_config(sc, NULL);	/* restart beacons */
937 938

	/* Re-Enable  interrupts */
P
Pavel Roskin 已提交
939
	ath9k_hw_set_interrupts(ah, ah->imask);
940 941

	/* Enable LED */
942
	ath9k_hw_cfg_output(ah, ah->led_pin,
943
			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
944
	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
945

946
	ieee80211_wake_queues(hw);
947
	ath9k_ps_restore(sc);
948 949
}

950
void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
951
{
952
	struct ath_hw *ah = sc->sc_ah;
953
	struct ieee80211_channel *channel = hw->conf.channel;
954
	int r;
955

956
	ath9k_ps_wakeup(sc);
957
	ieee80211_stop_queues(hw);
958 959

	/* Disable LED */
960 961
	ath9k_hw_set_gpio(ah, ah->led_pin, 1);
	ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
962 963 964 965

	/* Disable interrupts */
	ath9k_hw_set_interrupts(ah, 0);

S
Sujith 已提交
966
	ath_drain_all_txq(sc, false);	/* clear pending tx frames */
967 968 969
	ath_stoprecv(sc);		/* turn off frame recv */
	ath_flushrecv(sc);		/* flush recv queue */

970
	if (!ah->curchan)
971
		ah->curchan = ath_get_curchannel(sc, hw);
972

973
	spin_lock_bh(&sc->sc_resetlock);
974
	r = ath9k_hw_reset(ah, ah->curchan, false);
975
	if (r) {
976
		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
977
			  "Unable to reset channel (%u MHz), "
978 979
			  "reset status %d\n",
			  channel->center_freq, r);
980 981 982 983
	}
	spin_unlock_bh(&sc->sc_resetlock);

	ath9k_hw_phy_disable(ah);
V
Vivek Natarajan 已提交
984
	ath9k_hw_configpcipowersave(ah, 1, 1);
985
	ath9k_ps_restore(sc);
986
	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
987 988
}

S
Sujith 已提交
989 990
int ath_reset(struct ath_softc *sc, bool retry_tx)
{
991
	struct ath_hw *ah = sc->sc_ah;
992
	struct ath_common *common = ath9k_hw_common(ah);
993
	struct ieee80211_hw *hw = sc->hw;
994
	int r;
S
Sujith 已提交
995

S
Sujith 已提交
996 997 998
	/* Stop ANI */
	del_timer_sync(&common->ani.timer);

S
Sujith 已提交
999 1000
	ieee80211_stop_queues(hw);

S
Sujith 已提交
1001
	ath9k_hw_set_interrupts(ah, 0);
S
Sujith 已提交
1002
	ath_drain_all_txq(sc, retry_tx);
S
Sujith 已提交
1003 1004 1005 1006
	ath_stoprecv(sc);
	ath_flushrecv(sc);

	spin_lock_bh(&sc->sc_resetlock);
1007
	r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
1008
	if (r)
1009 1010
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to reset hardware; reset status %d\n", r);
S
Sujith 已提交
1011 1012 1013
	spin_unlock_bh(&sc->sc_resetlock);

	if (ath_startrecv(sc) != 0)
1014 1015
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to start recv logic\n");
S
Sujith 已提交
1016 1017 1018 1019 1020 1021

	/*
	 * We may be doing a reset in response to a request
	 * that changes the channel so update any state that
	 * might change as a result.
	 */
1022
	ath_cache_conf_rate(sc, &hw->conf);
S
Sujith 已提交
1023 1024 1025 1026

	ath_update_txpow(sc);

	if (sc->sc_flags & SC_OP_BEACONS)
1027
		ath_beacon_config(sc, NULL);	/* restart beacons */
S
Sujith 已提交
1028

P
Pavel Roskin 已提交
1029
	ath9k_hw_set_interrupts(ah, ah->imask);
S
Sujith 已提交
1030 1031 1032 1033 1034

	if (retry_tx) {
		int i;
		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
			if (ATH_TXQ_SETUP(sc, i)) {
S
Sujith 已提交
1035 1036 1037
				spin_lock_bh(&sc->tx.txq[i].axq_lock);
				ath_txq_schedule(sc, &sc->tx.txq[i]);
				spin_unlock_bh(&sc->tx.txq[i].axq_lock);
S
Sujith 已提交
1038 1039 1040 1041
			}
		}
	}

S
Sujith 已提交
1042 1043
	ieee80211_wake_queues(hw);

S
Sujith 已提交
1044 1045 1046
	/* Start ANI */
	ath_start_ani(common);

1047
	return r;
S
Sujith 已提交
1048 1049 1050 1051 1052 1053 1054 1055
}

int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
{
	int qnum;

	switch (queue) {
	case 0:
S
Sujith 已提交
1056
		qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
S
Sujith 已提交
1057 1058
		break;
	case 1:
S
Sujith 已提交
1059
		qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
S
Sujith 已提交
1060 1061
		break;
	case 2:
S
Sujith 已提交
1062
		qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
S
Sujith 已提交
1063 1064
		break;
	case 3:
S
Sujith 已提交
1065
		qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
S
Sujith 已提交
1066 1067
		break;
	default:
S
Sujith 已提交
1068
		qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
S
Sujith 已提交
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
		break;
	}

	return qnum;
}

int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
{
	int qnum;

	switch (queue) {
	case ATH9K_WME_AC_VO:
		qnum = 0;
		break;
	case ATH9K_WME_AC_VI:
		qnum = 1;
		break;
	case ATH9K_WME_AC_BE:
		qnum = 2;
		break;
	case ATH9K_WME_AC_BK:
		qnum = 3;
		break;
	default:
		qnum = -1;
		break;
	}

	return qnum;
}

1100 1101
/* XXX: Remove me once we don't depend on ath9k_channel for all
 * this redundant data */
1102 1103
void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
			   struct ath9k_channel *ichan)
1104 1105 1106 1107 1108 1109 1110 1111 1112
{
	struct ieee80211_channel *chan = hw->conf.channel;
	struct ieee80211_conf *conf = &hw->conf;

	ichan->channel = chan->center_freq;
	ichan->chan = chan;

	if (chan->band == IEEE80211_BAND_2GHZ) {
		ichan->chanmode = CHANNEL_G;
S
Sujith 已提交
1113
		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
1114 1115 1116 1117 1118
	} else {
		ichan->chanmode = CHANNEL_A;
		ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
	}

L
Luis R. Rodriguez 已提交
1119
	if (conf_is_ht(conf))
1120 1121 1122 1123
		ichan->chanmode = ath_get_extchanmode(sc, chan,
					    conf->channel_type);
}

S
Sujith 已提交
1124 1125 1126 1127
/**********************/
/* mac80211 callbacks */
/**********************/

1128
static int ath9k_start(struct ieee80211_hw *hw)
1129
{
1130 1131
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1132
	struct ath_hw *ah = sc->sc_ah;
1133
	struct ath_common *common = ath9k_hw_common(ah);
1134
	struct ieee80211_channel *curchan = hw->conf.channel;
S
Sujith 已提交
1135
	struct ath9k_channel *init_channel;
1136
	int r;
1137

1138 1139 1140
	ath_print(common, ATH_DBG_CONFIG,
		  "Starting driver with initial channel: %d MHz\n",
		  curchan->center_freq);
1141

1142 1143
	mutex_lock(&sc->mutex);

1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
	if (ath9k_wiphy_started(sc)) {
		if (sc->chan_idx == curchan->hw_value) {
			/*
			 * Already on the operational channel, the new wiphy
			 * can be marked active.
			 */
			aphy->state = ATH_WIPHY_ACTIVE;
			ieee80211_wake_queues(hw);
		} else {
			/*
			 * Another wiphy is on another channel, start the new
			 * wiphy in paused state.
			 */
			aphy->state = ATH_WIPHY_PAUSED;
			ieee80211_stop_queues(hw);
		}
		mutex_unlock(&sc->mutex);
		return 0;
	}
	aphy->state = ATH_WIPHY_ACTIVE;

1165
	/* setup initial channel */
1166

1167
	sc->chan_idx = curchan->hw_value;
1168

1169
	init_channel = ath_get_curchannel(sc, hw);
S
Sujith 已提交
1170 1171

	/* Reset SERDES registers */
1172
	ath9k_hw_configpcipowersave(ah, 0, 0);
S
Sujith 已提交
1173 1174 1175 1176 1177 1178 1179 1180 1181

	/*
	 * 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.
	 */
	spin_lock_bh(&sc->sc_resetlock);
1182
	r = ath9k_hw_reset(ah, init_channel, false);
1183
	if (r) {
1184 1185 1186 1187
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to reset hardware; reset status %d "
			  "(freq %u MHz)\n", r,
			  curchan->center_freq);
S
Sujith 已提交
1188
		spin_unlock_bh(&sc->sc_resetlock);
1189
		goto mutex_unlock;
S
Sujith 已提交
1190 1191 1192 1193 1194 1195 1196 1197
	}
	spin_unlock_bh(&sc->sc_resetlock);

	/*
	 * This is needed only to setup initial state
	 * but it's best done after a reset.
	 */
	ath_update_txpow(sc);
1198

S
Sujith 已提交
1199 1200 1201 1202 1203 1204 1205 1206
	/*
	 * Setup the hardware after reset:
	 * The receive engine is set going.
	 * Frame transmit is handled entirely
	 * in the frame output path; there's nothing to do
	 * here except setup the interrupt mask.
	 */
	if (ath_startrecv(sc) != 0) {
1207 1208
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to start recv logic\n");
1209 1210
		r = -EIO;
		goto mutex_unlock;
1211
	}
1212

S
Sujith 已提交
1213
	/* Setup our intr mask. */
F
Felix Fietkau 已提交
1214 1215 1216 1217 1218 1219 1220 1221
	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)
		ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP;
	else
		ah->imask |= ATH9K_INT_RX;
S
Sujith 已提交
1222

1223
	if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
P
Pavel Roskin 已提交
1224
		ah->imask |= ATH9K_INT_GTT;
S
Sujith 已提交
1225

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

1229
	ath_cache_conf_rate(sc, &hw->conf);
S
Sujith 已提交
1230 1231 1232 1233

	sc->sc_flags &= ~SC_OP_INVALID;

	/* Disable BMISS interrupt when we're not associated */
P
Pavel Roskin 已提交
1234 1235
	ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
	ath9k_hw_set_interrupts(ah, ah->imask);
S
Sujith 已提交
1236

1237
	ieee80211_wake_queues(hw);
S
Sujith 已提交
1238

1239
	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
1240

1241 1242
	if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
	    !ah->btcoex_hw.enabled) {
1243 1244
		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
					   AR_STOMP_LOW_WLAN_WGHT);
1245
		ath9k_hw_btcoex_enable(ah);
1246

1247 1248
		if (common->bus_ops->bt_coex_prep)
			common->bus_ops->bt_coex_prep(common);
1249
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1250
			ath9k_btcoex_timer_resume(sc);
1251 1252
	}

1253 1254 1255
mutex_unlock:
	mutex_unlock(&sc->mutex);

1256
	return r;
1257 1258
}

1259 1260
static int ath9k_tx(struct ieee80211_hw *hw,
		    struct sk_buff *skb)
1261
{
S
Sujith 已提交
1262
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1263 1264
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1265
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
S
Sujith 已提交
1266
	struct ath_tx_control txctl;
1267 1268
	int padpos, padsize;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
S
Sujith 已提交
1269

1270
	if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
1271 1272 1273
		ath_print(common, ATH_DBG_XMIT,
			  "ath9k: %s: TX in unexpected wiphy state "
			  "%d\n", wiphy_name(hw->wiphy), aphy->state);
1274 1275 1276
		goto exit;
	}

1277
	if (sc->ps_enabled) {
1278 1279 1280 1281 1282 1283 1284
		/*
		 * 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)) {
1285 1286
			ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame "
				  "while in PS mode\n");
1287 1288 1289 1290
			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
		}
	}

1291 1292 1293 1294 1295 1296 1297 1298 1299
	if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
		/*
		 * 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);
		ath9k_hw_setrxabort(sc->sc_ah, 0);
		if (ieee80211_is_pspoll(hdr->frame_control)) {
1300 1301
			ath_print(common, ATH_DBG_PS,
				  "Sending PS-Poll to pick a buffered frame\n");
S
Sujith 已提交
1302
			sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
1303
		} else {
1304 1305
			ath_print(common, ATH_DBG_PS,
				  "Wake up to complete TX\n");
S
Sujith 已提交
1306
			sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
1307 1308 1309 1310 1311 1312 1313 1314 1315
		}
		/*
		 * The actual restore operation will happen only after
		 * the sc_flags bit is cleared. We are just dropping
		 * the ps_usecount here.
		 */
		ath9k_ps_restore(sc);
	}

S
Sujith 已提交
1316
	memset(&txctl, 0, sizeof(struct ath_tx_control));
1317

1318 1319 1320 1321 1322 1323 1324
	/*
	 * As a temporary workaround, assign seq# here; this will likely need
	 * to be cleaned up to work better with Beacon transmission and virtual
	 * BSSes.
	 */
	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
		if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
S
Sujith 已提交
1325
			sc->tx.seq_no += 0x10;
1326
		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
S
Sujith 已提交
1327
		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
1328
	}
1329

1330
	/* Add the padding after the header if this is not already done */
1331 1332 1333
	padpos = ath9k_cmn_padpos(hdr->frame_control);
	padsize = padpos & 3;
	if (padsize && skb->len>padpos) {
1334 1335 1336
		if (skb_headroom(skb) < padsize)
			return -1;
		skb_push(skb, padsize);
1337
		memmove(skb->data, skb->data + padsize, padpos);
1338 1339
	}

S
Sujith 已提交
1340 1341 1342 1343 1344 1345
	/* Check if a tx queue is available */

	txctl.txq = ath_test_get_txq(sc, skb);
	if (!txctl.txq)
		goto exit;

1346
	ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
1347

1348
	if (ath_tx_start(hw, skb, &txctl) != 0) {
1349
		ath_print(common, ATH_DBG_XMIT, "TX failed\n");
S
Sujith 已提交
1350
		goto exit;
1351 1352
	}

S
Sujith 已提交
1353 1354 1355
	return 0;
exit:
	dev_kfree_skb_any(skb);
1356
	return 0;
1357 1358
}

1359
static void ath9k_stop(struct ieee80211_hw *hw)
1360
{
1361 1362
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1363
	struct ath_hw *ah = sc->sc_ah;
1364
	struct ath_common *common = ath9k_hw_common(ah);
1365

S
Sujith 已提交
1366 1367
	mutex_lock(&sc->mutex);

1368 1369
	aphy->state = ATH_WIPHY_INACTIVE;

1370 1371 1372 1373 1374 1375 1376 1377
	cancel_delayed_work_sync(&sc->ath_led_blink_work);
	cancel_delayed_work_sync(&sc->tx_complete_work);

	if (!sc->num_sec_wiphy) {
		cancel_delayed_work_sync(&sc->wiphy_work);
		cancel_work_sync(&sc->chan_work);
	}

S
Sujith 已提交
1378
	if (sc->sc_flags & SC_OP_INVALID) {
1379
		ath_print(common, ATH_DBG_ANY, "Device not present\n");
S
Sujith 已提交
1380
		mutex_unlock(&sc->mutex);
S
Sujith 已提交
1381 1382
		return;
	}
1383

1384 1385 1386 1387 1388
	if (ath9k_wiphy_started(sc)) {
		mutex_unlock(&sc->mutex);
		return; /* another wiphy still in use */
	}

1389 1390 1391
	/* Ensure HW is awake when we try to shut it down. */
	ath9k_ps_wakeup(sc);

1392
	if (ah->btcoex_hw.enabled) {
1393
		ath9k_hw_btcoex_disable(ah);
1394
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1395
			ath9k_btcoex_timer_pause(sc);
1396 1397
	}

S
Sujith 已提交
1398 1399
	/* make sure h/w will not generate any interrupt
	 * before setting the invalid flag. */
1400
	ath9k_hw_set_interrupts(ah, 0);
S
Sujith 已提交
1401 1402

	if (!(sc->sc_flags & SC_OP_INVALID)) {
S
Sujith 已提交
1403
		ath_drain_all_txq(sc, false);
S
Sujith 已提交
1404
		ath_stoprecv(sc);
1405
		ath9k_hw_phy_disable(ah);
S
Sujith 已提交
1406
	} else
S
Sujith 已提交
1407
		sc->rx.rxlink = NULL;
S
Sujith 已提交
1408 1409

	/* disable HAL and put h/w to sleep */
1410 1411
	ath9k_hw_disable(ah);
	ath9k_hw_configpcipowersave(ah, 1, 1);
1412 1413 1414
	ath9k_ps_restore(sc);

	/* Finally, put the chip in FULL SLEEP mode */
1415
	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
S
Sujith 已提交
1416 1417

	sc->sc_flags |= SC_OP_INVALID;
1418

1419 1420
	mutex_unlock(&sc->mutex);

1421
	ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1422 1423
}

1424
static int ath9k_add_interface(struct ieee80211_hw *hw,
1425
			       struct ieee80211_vif *vif)
1426
{
1427 1428
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
P
Pavel Roskin 已提交
1429 1430
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
1431
	struct ath_vif *avp = (void *)vif->drv_priv;
1432
	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
1433
	int ret = 0;
1434

1435 1436
	mutex_lock(&sc->mutex);

P
Pavel Roskin 已提交
1437
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
1438 1439 1440 1441 1442
	    sc->nvifs > 0) {
		ret = -ENOBUFS;
		goto out;
	}

1443
	switch (vif->type) {
1444
	case NL80211_IFTYPE_STATION:
1445
		ic_opmode = NL80211_IFTYPE_STATION;
1446
		break;
1447 1448
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_AP:
1449
	case NL80211_IFTYPE_MESH_POINT:
1450 1451 1452 1453
		if (sc->nbcnvifs >= ATH_BCBUF) {
			ret = -ENOBUFS;
			goto out;
		}
1454
		ic_opmode = vif->type;
1455 1456
		break;
	default:
1457
		ath_print(common, ATH_DBG_FATAL,
1458
			"Interface type %d not yet supported\n", vif->type);
1459 1460
		ret = -EOPNOTSUPP;
		goto out;
1461 1462
	}

1463 1464
	ath_print(common, ATH_DBG_CONFIG,
		  "Attach a VIF of type: %d\n", ic_opmode);
1465

S
Sujith 已提交
1466
	/* Set the VIF opmode */
S
Sujith 已提交
1467 1468 1469
	avp->av_opmode = ic_opmode;
	avp->av_bslot = -1;

1470
	sc->nvifs++;
1471

P
Pavel Roskin 已提交
1472
	if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
1473 1474
		ath9k_set_bssid_mask(hw);

1475 1476 1477
	if (sc->nvifs > 1)
		goto out; /* skip global settings for secondary vif */

S
Sujith 已提交
1478
	if (ic_opmode == NL80211_IFTYPE_AP) {
P
Pavel Roskin 已提交
1479
		ath9k_hw_set_tsfadjust(ah, 1);
S
Sujith 已提交
1480 1481
		sc->sc_flags |= SC_OP_TSF_RESET;
	}
S
Sujith 已提交
1482 1483

	/* Set the device opmode */
P
Pavel Roskin 已提交
1484
	ah->opmode = ic_opmode;
S
Sujith 已提交
1485

1486 1487 1488 1489
	/*
	 * Enable MIB interrupts when there are hardware phy counters.
	 * Note we only do this (at the moment) for station mode.
	 */
1490 1491 1492
	if ((vif->type == NL80211_IFTYPE_STATION) ||
	    (vif->type == NL80211_IFTYPE_ADHOC) ||
	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
1493 1494
		if (ah->config.enable_ani)
			ah->imask |= ATH9K_INT_MIB;
P
Pavel Roskin 已提交
1495
		ah->imask |= ATH9K_INT_TSFOOR;
1496 1497
	}

P
Pavel Roskin 已提交
1498
	ath9k_hw_set_interrupts(ah, ah->imask);
1499

1500 1501 1502
	if (vif->type == NL80211_IFTYPE_AP    ||
	    vif->type == NL80211_IFTYPE_ADHOC ||
	    vif->type == NL80211_IFTYPE_MONITOR)
1503
		ath_start_ani(common);
1504

1505
out:
1506
	mutex_unlock(&sc->mutex);
1507
	return ret;
1508 1509
}

1510
static void ath9k_remove_interface(struct ieee80211_hw *hw,
1511
				   struct ieee80211_vif *vif)
1512
{
1513 1514
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1515
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1516
	struct ath_vif *avp = (void *)vif->drv_priv;
1517
	int i;
1518

1519
	ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1520

1521 1522
	mutex_lock(&sc->mutex);

1523
	/* Stop ANI */
1524
	del_timer_sync(&common->ani.timer);
J
Jouni Malinen 已提交
1525

1526
	/* Reclaim beacon resources */
1527 1528 1529
	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
1530
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
1531
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1532
		ath9k_ps_restore(sc);
J
Jouni Malinen 已提交
1533
	}
1534

1535
	ath_beacon_return(sc, avp);
1536
	sc->sc_flags &= ~SC_OP_BEACONS;
1537

1538
	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
1539
		if (sc->beacon.bslot[i] == vif) {
1540 1541 1542
			printk(KERN_DEBUG "%s: vif had allocated beacon "
			       "slot\n", __func__);
			sc->beacon.bslot[i] = NULL;
1543
			sc->beacon.bslot_aphy[i] = NULL;
1544 1545 1546
		}
	}

S
Sujith 已提交
1547
	sc->nvifs--;
1548 1549

	mutex_unlock(&sc->mutex);
1550 1551
}

1552 1553
void ath9k_enable_ps(struct ath_softc *sc)
{
P
Pavel Roskin 已提交
1554 1555
	struct ath_hw *ah = sc->sc_ah;

1556
	sc->ps_enabled = true;
P
Pavel Roskin 已提交
1557 1558 1559 1560
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
		if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) {
			ah->imask |= ATH9K_INT_TIM_TIMER;
			ath9k_hw_set_interrupts(ah, ah->imask);
1561 1562
		}
	}
P
Pavel Roskin 已提交
1563
	ath9k_hw_setrxabort(ah, 1);
1564 1565
}

1566
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1567
{
1568 1569
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1570
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1571
	struct ieee80211_conf *conf = &hw->conf;
1572
	struct ath_hw *ah = sc->sc_ah;
1573
	bool disable_radio;
1574

1575
	mutex_lock(&sc->mutex);
1576

1577 1578 1579 1580 1581 1582
	/*
	 * Leave this as the first check because we need to turn on the
	 * radio if it was disabled before prior to processing the rest
	 * of the changes. Likewise we must only disable the radio towards
	 * the end.
	 */
1583
	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1584 1585 1586
		bool enable_radio;
		bool all_wiphys_idle;
		bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1587 1588 1589

		spin_lock_bh(&sc->wiphy_lock);
		all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
1590 1591
		ath9k_set_wiphy_idle(aphy, idle);

1592
		enable_radio = (!idle && all_wiphys_idle);
1593 1594 1595 1596 1597 1598 1599

		/*
		 * After we unlock here its possible another wiphy
		 * can be re-renabled so to account for that we will
		 * only disable the radio toward the end of this routine
		 * if by then all wiphys are still idle.
		 */
1600 1601
		spin_unlock_bh(&sc->wiphy_lock);

1602
		if (enable_radio) {
1603
			sc->ps_idle = false;
1604
			ath_radio_enable(sc, hw);
1605 1606
			ath_print(common, ATH_DBG_CONFIG,
				  "not-idle: enabling radio\n");
1607 1608 1609
		}
	}

1610 1611 1612 1613 1614 1615
	/*
	 * 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.
	 */
1616 1617
	if (changed & IEEE80211_CONF_CHANGE_PS) {
		if (conf->flags & IEEE80211_CONF_PS) {
S
Sujith 已提交
1618
			sc->ps_flags |= PS_ENABLED;
1619 1620 1621 1622
			/*
			 * At this point we know hardware has received an ACK
			 * of a previously sent null data frame.
			 */
S
Sujith 已提交
1623 1624
			if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
				sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
1625
				ath9k_enable_ps(sc);
1626
                        }
1627
		} else {
1628
			sc->ps_enabled = false;
S
Sujith 已提交
1629 1630
			sc->ps_flags &= ~(PS_ENABLED |
					  PS_NULLFUNC_COMPLETED);
1631
			ath9k_setpower(sc, ATH9K_PM_AWAKE);
1632 1633 1634
			if (!(ah->caps.hw_caps &
			      ATH9K_HW_CAP_AUTOSLEEP)) {
				ath9k_hw_setrxabort(sc->sc_ah, 0);
S
Sujith 已提交
1635 1636 1637 1638
				sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
						  PS_WAIT_FOR_CAB |
						  PS_WAIT_FOR_PSPOLL_DATA |
						  PS_WAIT_FOR_TX_ACK);
P
Pavel Roskin 已提交
1639 1640
				if (ah->imask & ATH9K_INT_TIM_TIMER) {
					ah->imask &= ~ATH9K_INT_TIM_TIMER;
1641
					ath9k_hw_set_interrupts(sc->sc_ah,
P
Pavel Roskin 已提交
1642
							ah->imask);
1643
				}
1644 1645 1646 1647
			}
		}
	}

S
Sujith 已提交
1648 1649 1650 1651 1652 1653 1654 1655
	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
		if (conf->flags & IEEE80211_CONF_MONITOR) {
			ath_print(common, ATH_DBG_CONFIG,
				  "HW opmode set to Monitor mode\n");
			sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
		}
	}

1656
	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1657
		struct ieee80211_channel *curchan = hw->conf.channel;
1658
		int pos = curchan->hw_value;
J
Johannes Berg 已提交
1659

1660 1661 1662
		aphy->chan_idx = pos;
		aphy->chan_is_ht = conf_is_ht(conf);

1663 1664 1665 1666 1667 1668 1669 1670 1671 1672
		if (aphy->state == ATH_WIPHY_SCAN ||
		    aphy->state == ATH_WIPHY_ACTIVE)
			ath9k_wiphy_pause_all_forced(sc, aphy);
		else {
			/*
			 * Do not change operational channel based on a paused
			 * wiphy changes.
			 */
			goto skip_chan_change;
		}
1673

1674 1675
		ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
			  curchan->center_freq);
1676

1677
		/* XXX: remove me eventualy */
1678
		ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
1679

1680
		ath_update_chainmask(sc, conf_is_ht(conf));
S
Sujith 已提交
1681

1682
		if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
1683 1684
			ath_print(common, ATH_DBG_FATAL,
				  "Unable to set channel\n");
1685
			mutex_unlock(&sc->mutex);
1686 1687
			return -EINVAL;
		}
S
Sujith 已提交
1688
	}
1689

1690
skip_chan_change:
1691
	if (changed & IEEE80211_CONF_CHANGE_POWER) {
S
Sujith 已提交
1692
		sc->config.txpowlimit = 2 * conf->power_level;
1693 1694
		ath_update_txpow(sc);
	}
1695

1696 1697 1698 1699
	spin_lock_bh(&sc->wiphy_lock);
	disable_radio = ath9k_all_wiphys_idle(sc);
	spin_unlock_bh(&sc->wiphy_lock);

1700
	if (disable_radio) {
1701
		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
1702
		sc->ps_idle = true;
1703
		ath_radio_disable(sc, hw);
1704 1705
	}

1706
	mutex_unlock(&sc->mutex);
1707

1708 1709 1710
	return 0;
}

1711 1712 1713 1714
#define SUPPORTED_FILTERS			\
	(FIF_PROMISC_IN_BSS |			\
	FIF_ALLMULTI |				\
	FIF_CONTROL |				\
1715
	FIF_PSPOLL |				\
1716 1717 1718
	FIF_OTHER_BSS |				\
	FIF_BCN_PRBRESP_PROMISC |		\
	FIF_FCSFAIL)
1719

1720 1721 1722 1723
/* FIXME: sc->sc_full_reset ? */
static void ath9k_configure_filter(struct ieee80211_hw *hw,
				   unsigned int changed_flags,
				   unsigned int *total_flags,
1724
				   u64 multicast)
1725
{
1726 1727
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1728
	u32 rfilt;
1729

1730 1731
	changed_flags &= SUPPORTED_FILTERS;
	*total_flags &= SUPPORTED_FILTERS;
1732

S
Sujith 已提交
1733
	sc->rx.rxfilter = *total_flags;
1734
	ath9k_ps_wakeup(sc);
1735 1736
	rfilt = ath_calcrxfilter(sc);
	ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
1737
	ath9k_ps_restore(sc);
1738

1739 1740
	ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
		  "Set HW RX filter: 0x%x\n", rfilt);
1741
}
1742

1743 1744 1745
static int ath9k_sta_add(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta)
1746
{
1747 1748
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1749

1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764
	ath_node_attach(sc, sta);

	return 0;
}

static int ath9k_sta_remove(struct ieee80211_hw *hw,
			    struct ieee80211_vif *vif,
			    struct ieee80211_sta *sta)
{
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;

	ath_node_detach(sc, sta);

	return 0;
1765 1766
}

1767
static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
1768
			 const struct ieee80211_tx_queue_params *params)
1769
{
1770 1771
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1772
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1773 1774
	struct ath9k_tx_queue_info qi;
	int ret = 0, qnum;
1775

1776 1777
	if (queue >= WME_NUM_AC)
		return 0;
1778

1779 1780
	mutex_lock(&sc->mutex);

1781 1782
	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));

1783 1784 1785 1786 1787
	qi.tqi_aifs = params->aifs;
	qi.tqi_cwmin = params->cw_min;
	qi.tqi_cwmax = params->cw_max;
	qi.tqi_burstTime = params->txop;
	qnum = ath_get_hal_qnum(queue, sc);
1788

1789 1790 1791 1792 1793
	ath_print(common, ATH_DBG_CONFIG,
		  "Configure tx [queue/halq] [%d/%d],  "
		  "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
		  queue, qnum, params->aifs, params->cw_min,
		  params->cw_max, params->txop);
1794

1795 1796
	ret = ath_txq_update(sc, qnum, &qi);
	if (ret)
1797
		ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1798

1799 1800 1801 1802
	if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
		if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret)
			ath_beaconq_config(sc);

1803 1804
	mutex_unlock(&sc->mutex);

1805 1806
	return ret;
}
1807

1808 1809
static int ath9k_set_key(struct ieee80211_hw *hw,
			 enum set_key_cmd cmd,
1810 1811
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta,
1812 1813
			 struct ieee80211_key_conf *key)
{
1814 1815
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1816
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1817
	int ret = 0;
1818

1819 1820 1821
	if (modparam_nohwcrypt)
		return -ENOSPC;

1822
	mutex_lock(&sc->mutex);
1823
	ath9k_ps_wakeup(sc);
1824
	ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1825

1826 1827
	switch (cmd) {
	case SET_KEY:
1828
		ret = ath_key_config(common, vif, sta, key);
1829 1830
		if (ret >= 0) {
			key->hw_key_idx = ret;
1831 1832 1833 1834
			/* push IV and Michael MIC generation to stack */
			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
			if (key->alg == ALG_TKIP)
				key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1835 1836
			if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
				key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1837
			ret = 0;
1838 1839 1840
		}
		break;
	case DISABLE_KEY:
1841
		ath_key_delete(common, key);
1842 1843 1844 1845
		break;
	default:
		ret = -EINVAL;
	}
1846

1847
	ath9k_ps_restore(sc);
1848 1849
	mutex_unlock(&sc->mutex);

1850 1851
	return ret;
}
1852

1853 1854 1855 1856 1857
static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_bss_conf *bss_conf,
				   u32 changed)
{
1858 1859
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1860
	struct ath_hw *ah = sc->sc_ah;
1861
	struct ath_common *common = ath9k_hw_common(ah);
1862
	struct ath_vif *avp = (void *)vif->drv_priv;
1863
	int slottime;
S
Sujith 已提交
1864
	int error;
1865

1866 1867
	mutex_lock(&sc->mutex);

S
Sujith 已提交
1868 1869 1870 1871
	if (changed & BSS_CHANGED_BSSID) {
		/* Set BSSID */
		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
		memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
1872
		common->curaid = 0;
1873
		ath9k_hw_write_associd(ah);
1874

S
Sujith 已提交
1875 1876
		/* Set aggregation protection mode parameters */
		sc->config.ath_aggr_prot = 0;
1877

S
Sujith 已提交
1878 1879 1880
		/* Only legacy IBSS for now */
		if (vif->type == NL80211_IFTYPE_ADHOC)
			ath_update_chainmask(sc, 0);
1881

S
Sujith 已提交
1882 1883 1884
		ath_print(common, ATH_DBG_CONFIG,
			  "BSSID: %pM aid: 0x%x\n",
			  common->curbssid, common->curaid);
1885

S
Sujith 已提交
1886 1887 1888
		/* need to reconfigure the beacon */
		sc->sc_flags &= ~SC_OP_BEACONS ;
	}
1889

S
Sujith 已提交
1890 1891 1892 1893 1894 1895 1896
	/* Enable transmission of beacons (AP, IBSS, MESH) */
	if ((changed & BSS_CHANGED_BEACON) ||
	    ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) {
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
		error = ath_beacon_alloc(aphy, vif);
		if (!error)
			ath_beacon_config(sc, vif);
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915
	}

	if (changed & BSS_CHANGED_ERP_SLOT) {
		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);
		}
1916 1917
	}

S
Sujith 已提交
1918 1919 1920
	/* Disable transmission of beacons */
	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1921

S
Sujith 已提交
1922 1923 1924 1925 1926 1927 1928 1929 1930
	if (changed & BSS_CHANGED_BEACON_INT) {
		sc->beacon_interval = bss_conf->beacon_int;
		/*
		 * In case of AP mode, the HW TSF has to be reset
		 * when the beacon interval changes.
		 */
		if (vif->type == NL80211_IFTYPE_AP) {
			sc->sc_flags |= SC_OP_TSF_RESET;
			ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1931 1932 1933
			error = ath_beacon_alloc(aphy, vif);
			if (!error)
				ath_beacon_config(sc, vif);
S
Sujith 已提交
1934 1935
		} else {
			ath_beacon_config(sc, vif);
1936 1937 1938
		}
	}

1939
	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1940 1941
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
			  bss_conf->use_short_preamble);
1942 1943 1944 1945 1946
		if (bss_conf->use_short_preamble)
			sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
		else
			sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
	}
1947

1948
	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1949 1950
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
			  bss_conf->use_cts_prot);
1951 1952 1953 1954 1955 1956
		if (bss_conf->use_cts_prot &&
		    hw->conf.channel->band != IEEE80211_BAND_5GHZ)
			sc->sc_flags |= SC_OP_PROTECT_ENABLE;
		else
			sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
	}
1957

1958
	if (changed & BSS_CHANGED_ASSOC) {
1959
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1960
			bss_conf->assoc);
S
Sujith 已提交
1961
		ath9k_bss_assoc_info(sc, vif, bss_conf);
1962
	}
1963 1964

	mutex_unlock(&sc->mutex);
1965
}
1966

1967 1968 1969
static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
{
	u64 tsf;
1970 1971
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1972

1973 1974 1975
	mutex_lock(&sc->mutex);
	tsf = ath9k_hw_gettsf64(sc->sc_ah);
	mutex_unlock(&sc->mutex);
1976

1977 1978
	return tsf;
}
1979

1980 1981
static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
1982 1983
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1984

1985 1986 1987
	mutex_lock(&sc->mutex);
	ath9k_hw_settsf64(sc->sc_ah, tsf);
	mutex_unlock(&sc->mutex);
1988 1989
}

1990 1991
static void ath9k_reset_tsf(struct ieee80211_hw *hw)
{
1992 1993
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1994

1995
	mutex_lock(&sc->mutex);
1996 1997

	ath9k_ps_wakeup(sc);
1998
	ath9k_hw_reset_tsf(sc->sc_ah);
1999 2000
	ath9k_ps_restore(sc);

2001
	mutex_unlock(&sc->mutex);
2002
}
2003

2004
static int ath9k_ampdu_action(struct ieee80211_hw *hw,
2005
			      struct ieee80211_vif *vif,
2006 2007 2008
			      enum ieee80211_ampdu_mlme_action action,
			      struct ieee80211_sta *sta,
			      u16 tid, u16 *ssn)
2009
{
2010 2011
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
2012
	int ret = 0;
2013

2014 2015
	switch (action) {
	case IEEE80211_AMPDU_RX_START:
2016 2017
		if (!(sc->sc_flags & SC_OP_RXAGGR))
			ret = -ENOTSUPP;
2018 2019 2020 2021
		break;
	case IEEE80211_AMPDU_RX_STOP:
		break;
	case IEEE80211_AMPDU_TX_START:
2022
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
2023
		ath_tx_aggr_start(sc, sta, tid, ssn);
2024
		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2025
		ath9k_ps_restore(sc);
2026 2027
		break;
	case IEEE80211_AMPDU_TX_STOP:
2028
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
2029
		ath_tx_aggr_stop(sc, sta, tid);
2030
		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2031
		ath9k_ps_restore(sc);
2032
		break;
2033
	case IEEE80211_AMPDU_TX_OPERATIONAL:
2034
		ath9k_ps_wakeup(sc);
2035
		ath_tx_aggr_resume(sc, sta, tid);
2036
		ath9k_ps_restore(sc);
2037
		break;
2038
	default:
2039 2040
		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
			  "Unknown AMPDU action\n");
2041 2042 2043
	}

	return ret;
2044 2045
}

2046 2047
static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
{
2048 2049
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
S
Sujith 已提交
2050
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2051

2052
	mutex_lock(&sc->mutex);
2053 2054 2055 2056 2057 2058 2059
	if (ath9k_wiphy_scanning(sc)) {
		printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
		       "same time\n");
		/*
		 * Do not allow the concurrent scanning state for now. This
		 * could be improved with scanning control moved into ath9k.
		 */
2060
		mutex_unlock(&sc->mutex);
2061 2062 2063 2064 2065
		return;
	}

	aphy->state = ATH_WIPHY_SCAN;
	ath9k_wiphy_pause_all_forced(sc, aphy);
2066
	sc->sc_flags |= SC_OP_SCANNING;
S
Sujith 已提交
2067
	del_timer_sync(&common->ani.timer);
S
Sujith 已提交
2068
	cancel_delayed_work_sync(&sc->tx_complete_work);
2069
	mutex_unlock(&sc->mutex);
2070 2071 2072 2073
}

static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
{
2074 2075
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
S
Sujith 已提交
2076
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2077

2078
	mutex_lock(&sc->mutex);
2079
	aphy->state = ATH_WIPHY_ACTIVE;
2080
	sc->sc_flags &= ~SC_OP_SCANNING;
S
Sujith 已提交
2081
	sc->sc_flags |= SC_OP_FULL_RESET;
S
Sujith 已提交
2082
	ath_start_ani(common);
S
Sujith 已提交
2083
	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
2084
	ath_beacon_config(sc, NULL);
2085
	mutex_unlock(&sc->mutex);
2086 2087
}

2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099
static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
{
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
	struct ath_hw *ah = sc->sc_ah;

	mutex_lock(&sc->mutex);
	ah->coverage_class = coverage_class;
	ath9k_hw_init_global_settings(ah);
	mutex_unlock(&sc->mutex);
}

2100
struct ieee80211_ops ath9k_ops = {
2101 2102 2103 2104 2105 2106 2107
	.tx 		    = ath9k_tx,
	.start 		    = ath9k_start,
	.stop 		    = ath9k_stop,
	.add_interface 	    = ath9k_add_interface,
	.remove_interface   = ath9k_remove_interface,
	.config 	    = ath9k_config,
	.configure_filter   = ath9k_configure_filter,
2108 2109
	.sta_add	    = ath9k_sta_add,
	.sta_remove	    = ath9k_sta_remove,
2110 2111 2112 2113
	.conf_tx 	    = ath9k_conf_tx,
	.bss_info_changed   = ath9k_bss_info_changed,
	.set_key            = ath9k_set_key,
	.get_tsf 	    = ath9k_get_tsf,
2114
	.set_tsf 	    = ath9k_set_tsf,
2115
	.reset_tsf 	    = ath9k_reset_tsf,
2116
	.ampdu_action       = ath9k_ampdu_action,
2117 2118
	.sw_scan_start      = ath9k_sw_scan_start,
	.sw_scan_complete   = ath9k_sw_scan_complete,
J
Johannes Berg 已提交
2119
	.rfkill_poll        = ath9k_rfkill_poll_state,
2120
	.set_coverage_class = ath9k_set_coverage_class,
2121
};