main.c 50.4 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

S
Sujith 已提交
55 56
	if (sc->curtxpow != sc->config.txpowlimit) {
		ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
S
Sujith 已提交
57
		/* read back in case value is clamped */
F
Felix Fietkau 已提交
58
		sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
S
Sujith 已提交
59 60 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
	}
}

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;
	}
}

97 98 99 100 101 102 103 104 105 106 107 108 109
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 已提交
110
bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
111 112 113 114
{
	unsigned long flags;
	bool ret;

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

	return ret;
}

122 123 124 125 126 127 128 129
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;

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

 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;

144 145 146 147
	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 已提交
148 149 150
			      PS_WAIT_FOR_CAB |
			      PS_WAIT_FOR_PSPOLL_DATA |
			      PS_WAIT_FOR_TX_ACK)))
151
		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
152 153 154 155 156

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

S
Sujith 已提交
157 158 159 160 161
/*
 * 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.
*/
162 163
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
		    struct ath9k_channel *hchan)
S
Sujith 已提交
164
{
165
	struct ath_hw *ah = sc->sc_ah;
166
	struct ath_common *common = ath9k_hw_common(ah);
L
Luis R. Rodriguez 已提交
167
	struct ieee80211_conf *conf = &common->hw->conf;
S
Sujith 已提交
168
	bool fastcc = true, stopped;
169 170
	struct ieee80211_channel *channel = hw->conf.channel;
	int r;
S
Sujith 已提交
171 172 173 174

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

175 176
	ath9k_ps_wakeup(sc);

177 178 179 180 181 182 183 184 185 186
	/*
	 * 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 已提交
187
	ath_drain_all_txq(sc, false);
188
	stopped = ath_stoprecv(sc);
S
Sujith 已提交
189

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

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

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

202 203 204 205
	spin_lock_bh(&sc->sc_resetlock);

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

	sc->sc_flags &= ~SC_OP_FULL_RESET;

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

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

 ps_restore:
229
	ath9k_ps_restore(sc);
230
	return r;
S
Sujith 已提交
231 232
}

233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
static void ath_paprd_activate(struct ath_softc *sc)
{
	struct ath_hw *ah = sc->sc_ah;
	int chain;

	if (!ah->curchan->paprd_done)
		return;

	ath9k_ps_wakeup(sc);
	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
		if (!(ah->caps.tx_chainmask & BIT(chain)))
			continue;

		ar9003_paprd_populate_single_table(ah, ah->curchan, chain);
	}

	ar9003_paprd_enable(ah, true);
	ath9k_ps_restore(sc);
}

void ath_paprd_calibrate(struct work_struct *work)
{
	struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
	struct ieee80211_hw *hw = sc->hw;
	struct ath_hw *ah = sc->sc_ah;
	struct ieee80211_hdr *hdr;
	struct sk_buff *skb = NULL;
	struct ieee80211_tx_info *tx_info;
	int band = hw->conf.channel->band;
	struct ieee80211_supported_band *sband = &sc->sbands[band];
	struct ath_tx_control txctl;
	int qnum, ftype;
	int chain_ok = 0;
	int chain;
	int len = 1800;
	int time_left;
	int i;

	skb = alloc_skb(len, GFP_KERNEL);
	if (!skb)
		return;

	tx_info = IEEE80211_SKB_CB(skb);

	skb_put(skb, len);
	memset(skb->data, 0, len);
	hdr = (struct ieee80211_hdr *)skb->data;
	ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC;
	hdr->frame_control = cpu_to_le16(ftype);
	hdr->duration_id = 10;
	memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
	memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
	memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);

	memset(&txctl, 0, sizeof(txctl));
	qnum = sc->tx.hwq_map[WME_AC_BE];
	txctl.txq = &sc->tx.txq[qnum];

291
	ath9k_ps_wakeup(sc);
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
	ar9003_paprd_init_table(ah);
	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
		if (!(ah->caps.tx_chainmask & BIT(chain)))
			continue;

		chain_ok = 0;
		memset(tx_info, 0, sizeof(*tx_info));
		tx_info->band = band;

		for (i = 0; i < 4; i++) {
			tx_info->control.rates[i].idx = sband->n_bitrates - 1;
			tx_info->control.rates[i].count = 6;
		}

		init_completion(&sc->paprd_complete);
		ar9003_paprd_setup_gain_table(ah, chain);
		txctl.paprd = BIT(chain);
		if (ath_tx_start(hw, skb, &txctl) != 0)
			break;

		time_left = wait_for_completion_timeout(&sc->paprd_complete,
313
				msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
314 315 316 317 318
		if (!time_left) {
			ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
				  "Timeout waiting for paprd training on "
				  "TX chain %d\n",
				  chain);
319
			goto fail_paprd;
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
		}

		if (!ar9003_paprd_is_done(ah))
			break;

		if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0)
			break;

		chain_ok = 1;
	}
	kfree_skb(skb);

	if (chain_ok) {
		ah->curchan->paprd_done = true;
		ath_paprd_activate(sc);
	}

337
fail_paprd:
338 339 340
	ath9k_ps_restore(sc);
}

S
Sujith 已提交
341 342 343 344 345 346 347
/*
 *  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 已提交
348
void ath_ani_calibrate(unsigned long data)
S
Sujith 已提交
349
{
350 351
	struct ath_softc *sc = (struct ath_softc *)data;
	struct ath_hw *ah = sc->sc_ah;
352
	struct ath_common *common = ath9k_hw_common(ah);
S
Sujith 已提交
353 354 355 356
	bool longcal = false;
	bool shortcal = false;
	bool aniflag = false;
	unsigned int timestamp = jiffies_to_msecs(jiffies);
357
	u32 cal_interval, short_cal_interval;
S
Sujith 已提交
358

359 360
	short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
		ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
S
Sujith 已提交
361

362 363 364 365 366 367
	/* Only calibrate if awake */
	if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
		goto set_timer;

	ath9k_ps_wakeup(sc);

S
Sujith 已提交
368
	/* Long calibration runs independently of short calibration. */
369
	if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
S
Sujith 已提交
370
		longcal = true;
371
		ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
372
		common->ani.longcal_timer = timestamp;
S
Sujith 已提交
373 374
	}

S
Sujith 已提交
375
	/* Short calibration applies only while caldone is false */
376 377
	if (!common->ani.caldone) {
		if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
S
Sujith 已提交
378
			shortcal = true;
379 380
			ath_print(common, ATH_DBG_ANI,
				  "shortcal @%lu\n", jiffies);
381 382
			common->ani.shortcal_timer = timestamp;
			common->ani.resetcal_timer = timestamp;
S
Sujith 已提交
383 384
		}
	} else {
385
		if ((timestamp - common->ani.resetcal_timer) >=
S
Sujith 已提交
386
		    ATH_RESTART_CALINTERVAL) {
387 388 389
			common->ani.caldone = ath9k_hw_reset_calvalid(ah);
			if (common->ani.caldone)
				common->ani.resetcal_timer = timestamp;
S
Sujith 已提交
390 391 392 393
		}
	}

	/* Verify whether we must check ANI */
394 395
	if ((timestamp - common->ani.checkani_timer) >=
	     ah->config.ani_poll_interval) {
S
Sujith 已提交
396
		aniflag = true;
397
		common->ani.checkani_timer = timestamp;
S
Sujith 已提交
398 399 400 401 402 403
	}

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

		/* Perform calibration if necessary */
		if (longcal || shortcal) {
408
			common->ani.caldone =
409 410 411 412
				ath9k_hw_calibrate(ah,
						   ah->curchan,
						   common->rx_chainmask,
						   longcal);
S
Sujith 已提交
413 414

			if (longcal)
415
				common->ani.noise_floor = ath9k_hw_getchan_noise(ah,
S
Sujith 已提交
416 417
								     ah->curchan);

418 419 420 421
			ath_print(common, ATH_DBG_ANI,
				  " calibrate chan %u/%x nf: %d\n",
				  ah->curchan->channel,
				  ah->curchan->channelFlags,
422
				  common->ani.noise_floor);
S
Sujith 已提交
423 424 425
		}
	}

426 427
	ath9k_ps_restore(sc);

428
set_timer:
S
Sujith 已提交
429 430 431 432 433
	/*
	* Set timer interval based on previous results.
	* The interval must be the shortest necessary to satisfy ANI,
	* short calibration and long calibration.
	*/
434
	cal_interval = ATH_LONG_CALINTERVAL;
435
	if (sc->sc_ah->config.enable_ani)
436 437
		cal_interval = min(cal_interval,
				   (u32)ah->config.ani_poll_interval);
438
	if (!common->ani.caldone)
439
		cal_interval = min(cal_interval, (u32)short_cal_interval);
S
Sujith 已提交
440

441
	mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
442 443 444 445 446 447 448
	if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
	    !(sc->sc_flags & SC_OP_SCANNING)) {
		if (!sc->sc_ah->curchan->paprd_done)
			ieee80211_queue_work(sc->hw, &sc->paprd_work);
		else
			ath_paprd_activate(sc);
	}
S
Sujith 已提交
449 450
}

451
static void ath_start_ani(struct ath_common *common)
S
Sujith 已提交
452
{
453
	struct ath_hw *ah = common->ah;
S
Sujith 已提交
454
	unsigned long timestamp = jiffies_to_msecs(jiffies);
455 456 457 458
	struct ath_softc *sc = (struct ath_softc *) common->priv;

	if (!(sc->sc_flags & SC_OP_ANI_RUN))
		return;
S
Sujith 已提交
459

460 461 462
	common->ani.longcal_timer = timestamp;
	common->ani.shortcal_timer = timestamp;
	common->ani.checkani_timer = timestamp;
S
Sujith 已提交
463

464
	mod_timer(&common->ani.timer,
465 466
		  jiffies +
			msecs_to_jiffies((u32)ah->config.ani_poll_interval));
S
Sujith 已提交
467 468
}

S
Sujith 已提交
469 470 471
/*
 * Update tx/rx chainmask. For legacy association,
 * hard code chainmask to 1x1, for 11n association, use
472 473
 * the chainmask configuration, for bt coexistence, use
 * the chainmask configuration even in legacy mode.
S
Sujith 已提交
474
 */
475
void ath_update_chainmask(struct ath_softc *sc, int is_ht)
S
Sujith 已提交
476
{
477
	struct ath_hw *ah = sc->sc_ah;
478
	struct ath_common *common = ath9k_hw_common(ah);
479

480
	if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
481
	    (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
482 483
		common->tx_chainmask = ah->caps.tx_chainmask;
		common->rx_chainmask = ah->caps.rx_chainmask;
S
Sujith 已提交
484
	} else {
485 486
		common->tx_chainmask = 1;
		common->rx_chainmask = 1;
S
Sujith 已提交
487 488
	}

489
	ath_print(common, ATH_DBG_CONFIG,
490
		  "tx chmask: %d, rx chmask: %d\n",
491 492
		  common->tx_chainmask,
		  common->rx_chainmask);
S
Sujith 已提交
493 494 495 496 497 498 499 500
}

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

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

501
	if (sc->sc_flags & SC_OP_TXAGGR) {
S
Sujith 已提交
502
		ath_tx_node_init(sc, an);
S
Sujith 已提交
503
		an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
504 505
				     sta->ht_cap.ampdu_factor);
		an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
506
		an->last_rssi = ATH_RSSI_DUMMY_MARKER;
507
	}
S
Sujith 已提交
508 509 510 511 512 513 514 515 516 517
}

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 已提交
518
void ath9k_tasklet(unsigned long data)
S
Sujith 已提交
519 520
{
	struct ath_softc *sc = (struct ath_softc *)data;
521
	struct ath_hw *ah = sc->sc_ah;
522
	struct ath_common *common = ath9k_hw_common(ah);
523

S
Sujith 已提交
524
	u32 status = sc->intrstatus;
F
Felix Fietkau 已提交
525
	u32 rxmask;
S
Sujith 已提交
526

527 528
	ath9k_ps_wakeup(sc);

529 530
	if ((status & ATH9K_INT_FATAL) ||
	    !ath9k_hw_check_alive(ah)) {
S
Sujith 已提交
531
		ath_reset(sc, false);
532
		ath9k_ps_restore(sc);
S
Sujith 已提交
533
		return;
S
Sujith 已提交
534
	}
S
Sujith 已提交
535

F
Felix Fietkau 已提交
536 537 538 539 540 541 542
	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 已提交
543
		spin_lock_bh(&sc->rx.rxflushlock);
F
Felix Fietkau 已提交
544 545 546 547 548 549 550

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

554 555 556 557 558 559
	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 已提交
560

561
	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
562 563 564 565
		/*
		 * TSF sync does not look correct; remain awake to sync with
		 * the next Beacon.
		 */
566 567
		ath_print(common, ATH_DBG_PS,
			  "TSFOOR - Sync with next Beacon\n");
S
Sujith 已提交
568
		sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
569 570
	}

571
	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
572 573 574
		if (status & ATH9K_INT_GENTIMER)
			ath_gen_timer_isr(sc->sc_ah);

S
Sujith 已提交
575
	/* re-enable hardware interrupt */
P
Pavel Roskin 已提交
576
	ath9k_hw_set_interrupts(ah, ah->imask);
577
	ath9k_ps_restore(sc);
S
Sujith 已提交
578 579
}

580
irqreturn_t ath_isr(int irq, void *dev)
S
Sujith 已提交
581
{
S
Sujith 已提交
582 583 584 585 586
#define SCHED_INTR (				\
		ATH9K_INT_FATAL |		\
		ATH9K_INT_RXORN |		\
		ATH9K_INT_RXEOL |		\
		ATH9K_INT_RX |			\
F
Felix Fietkau 已提交
587 588
		ATH9K_INT_RXLP |		\
		ATH9K_INT_RXHP |		\
S
Sujith 已提交
589 590 591
		ATH9K_INT_TX |			\
		ATH9K_INT_BMISS |		\
		ATH9K_INT_CST |			\
592 593
		ATH9K_INT_TSFOOR |		\
		ATH9K_INT_GENTIMER)
S
Sujith 已提交
594

S
Sujith 已提交
595
	struct ath_softc *sc = dev;
596
	struct ath_hw *ah = sc->sc_ah;
S
Sujith 已提交
597 598 599
	enum ath9k_int status;
	bool sched = false;

S
Sujith 已提交
600 601 602 603 604 605 606
	/*
	 * 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 已提交
607

S
Sujith 已提交
608 609 610

	/* shared irq, not for us */

611
	if (!ath9k_hw_intrpend(ah))
S
Sujith 已提交
612 613 614 615 616 617 618 619 620
		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 已提交
621
	status &= ah->imask;	/* discard unasked-for bits */
S
Sujith 已提交
622

S
Sujith 已提交
623 624 625 626
	/*
	 * If there are no status bits set, then this interrupt was not
	 * for me (should have been caught above).
	 */
627
	if (!status)
S
Sujith 已提交
628
		return IRQ_NONE;
S
Sujith 已提交
629

S
Sujith 已提交
630 631 632 633 634 635 636 637 638 639
	/* 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 已提交
640 641
	if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
	    !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
S
Sujith 已提交
642 643
		goto chip_reset;

644 645 646 647 648 649
	if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
	    (status & ATH9K_INT_BB_WATCHDOG)) {
		ar9003_hw_bb_watchdog_dbg_info(ah);
		goto chip_reset;
	}

S
Sujith 已提交
650 651 652 653 654 655
	if (status & ATH9K_INT_SWBA)
		tasklet_schedule(&sc->bcon_tasklet);

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

F
Felix Fietkau 已提交
656 657 658 659 660 661 662
	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 已提交
663
	if (status & ATH9K_INT_MIB) {
S
Sujith 已提交
664
		/*
S
Sujith 已提交
665 666 667
		 * Disable interrupts until we service the MIB
		 * interrupt; otherwise it will continue to
		 * fire.
S
Sujith 已提交
668
		 */
S
Sujith 已提交
669 670 671 672 673 674
		ath9k_hw_set_interrupts(ah, 0);
		/*
		 * Let the hal handle the event. We assume
		 * it will clear whatever condition caused
		 * the interrupt.
		 */
675
		ath9k_hw_procmibevent(ah);
P
Pavel Roskin 已提交
676
		ath9k_hw_set_interrupts(ah, ah->imask);
S
Sujith 已提交
677
	}
S
Sujith 已提交
678

679 680
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
		if (status & ATH9K_INT_TIM_TIMER) {
S
Sujith 已提交
681 682
			/* Clear RxAbort bit so that we can
			 * receive frames */
683
			ath9k_setpower(sc, ATH9K_PM_AWAKE);
684
			ath9k_hw_setrxabort(sc->sc_ah, 0);
S
Sujith 已提交
685
			sc->ps_flags |= PS_WAIT_FOR_BEACON;
S
Sujith 已提交
686
		}
S
Sujith 已提交
687 688

chip_reset:
S
Sujith 已提交
689

690 691
	ath_debug_stat_interrupt(sc, status);

S
Sujith 已提交
692 693
	if (sched) {
		/* turn off every interrupt except SWBA */
P
Pavel Roskin 已提交
694
		ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
S
Sujith 已提交
695 696 697 698
		tasklet_schedule(&sc->intr_tq);
	}

	return IRQ_HANDLED;
S
Sujith 已提交
699 700

#undef SCHED_INTR
S
Sujith 已提交
701 702
}

703
static u32 ath_get_extchanmode(struct ath_softc *sc,
704
			       struct ieee80211_channel *chan,
S
Sujith 已提交
705
			       enum nl80211_channel_type channel_type)
706 707 708 709 710
{
	u32 chanmode = 0;

	switch (chan->band) {
	case IEEE80211_BAND_2GHZ:
S
Sujith 已提交
711 712 713
		switch(channel_type) {
		case NL80211_CHAN_NO_HT:
		case NL80211_CHAN_HT20:
714
			chanmode = CHANNEL_G_HT20;
S
Sujith 已提交
715 716
			break;
		case NL80211_CHAN_HT40PLUS:
717
			chanmode = CHANNEL_G_HT40PLUS;
S
Sujith 已提交
718 719
			break;
		case NL80211_CHAN_HT40MINUS:
720
			chanmode = CHANNEL_G_HT40MINUS;
S
Sujith 已提交
721 722
			break;
		}
723 724
		break;
	case IEEE80211_BAND_5GHZ:
S
Sujith 已提交
725 726 727
		switch(channel_type) {
		case NL80211_CHAN_NO_HT:
		case NL80211_CHAN_HT20:
728
			chanmode = CHANNEL_A_HT20;
S
Sujith 已提交
729 730
			break;
		case NL80211_CHAN_HT40PLUS:
731
			chanmode = CHANNEL_A_HT40PLUS;
S
Sujith 已提交
732 733
			break;
		case NL80211_CHAN_HT40MINUS:
734
			chanmode = CHANNEL_A_HT40MINUS;
S
Sujith 已提交
735 736
			break;
		}
737 738 739 740 741 742 743 744
		break;
	default:
		break;
	}

	return chanmode;
}

745
static void ath9k_bss_assoc_info(struct ath_softc *sc,
S
Sujith 已提交
746
				 struct ieee80211_vif *vif,
747
				 struct ieee80211_bss_conf *bss_conf)
748
{
749
	struct ath_hw *ah = sc->sc_ah;
750
	struct ath_common *common = ath9k_hw_common(ah);
751

752
	if (bss_conf->assoc) {
753 754 755
		ath_print(common, ATH_DBG_CONFIG,
			  "Bss Info ASSOC %d, bssid: %pM\n",
			   bss_conf->aid, common->curbssid);
756

757
		/* New association, store aid */
758
		common->curaid = bss_conf->aid;
759
		ath9k_hw_write_associd(ah);
760 761 762 763 764 765

		/*
		 * 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 已提交
766
		sc->ps_flags |= PS_BEACON_SYNC;
767

768
		/* Configure the beacon */
769
		ath_beacon_config(sc, vif);
770

771
		/* Reset rssi stats */
772
		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
773

774
		sc->sc_flags |= SC_OP_ANI_RUN;
775
		ath_start_ani(common);
776
	} else {
777
		ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
778
		common->curaid = 0;
779
		/* Stop ANI */
780
		sc->sc_flags &= ~SC_OP_ANI_RUN;
781
		del_timer_sync(&common->ani.timer);
782
	}
783
}
784

785
void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
786
{
787
	struct ath_hw *ah = sc->sc_ah;
788
	struct ath_common *common = ath9k_hw_common(ah);
789
	struct ieee80211_channel *channel = hw->conf.channel;
790
	int r;
791

792
	ath9k_ps_wakeup(sc);
V
Vivek Natarajan 已提交
793
	ath9k_hw_configpcipowersave(ah, 0, 0);
794

795 796 797
	if (!ah->curchan)
		ah->curchan = ath_get_curchannel(sc, sc->hw);

S
Sujith 已提交
798
	spin_lock_bh(&sc->sc_resetlock);
799
	r = ath9k_hw_reset(ah, ah->curchan, false);
800
	if (r) {
801
		ath_print(common, ATH_DBG_FATAL,
802
			  "Unable to reset channel (%u MHz), "
803 804
			  "reset status %d\n",
			  channel->center_freq, r);
805 806 807 808 809
	}
	spin_unlock_bh(&sc->sc_resetlock);

	ath_update_txpow(sc);
	if (ath_startrecv(sc) != 0) {
810 811
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to restart recv logic\n");
812 813 814 815
		return;
	}

	if (sc->sc_flags & SC_OP_BEACONS)
816
		ath_beacon_config(sc, NULL);	/* restart beacons */
817 818

	/* Re-Enable  interrupts */
P
Pavel Roskin 已提交
819
	ath9k_hw_set_interrupts(ah, ah->imask);
820 821

	/* Enable LED */
822
	ath9k_hw_cfg_output(ah, ah->led_pin,
823
			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
824
	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
825

826
	ieee80211_wake_queues(hw);
827
	ath9k_ps_restore(sc);
828 829
}

830
void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
831
{
832
	struct ath_hw *ah = sc->sc_ah;
833
	struct ieee80211_channel *channel = hw->conf.channel;
834
	int r;
835

836
	ath9k_ps_wakeup(sc);
837
	ieee80211_stop_queues(hw);
838 839

	/* Disable LED */
840 841
	ath9k_hw_set_gpio(ah, ah->led_pin, 1);
	ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
842 843 844 845

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

S
Sujith 已提交
846
	ath_drain_all_txq(sc, false);	/* clear pending tx frames */
847 848 849
	ath_stoprecv(sc);		/* turn off frame recv */
	ath_flushrecv(sc);		/* flush recv queue */

850
	if (!ah->curchan)
851
		ah->curchan = ath_get_curchannel(sc, hw);
852

853
	spin_lock_bh(&sc->sc_resetlock);
854
	r = ath9k_hw_reset(ah, ah->curchan, false);
855
	if (r) {
856
		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
857
			  "Unable to reset channel (%u MHz), "
858 859
			  "reset status %d\n",
			  channel->center_freq, r);
860 861 862 863
	}
	spin_unlock_bh(&sc->sc_resetlock);

	ath9k_hw_phy_disable(ah);
V
Vivek Natarajan 已提交
864
	ath9k_hw_configpcipowersave(ah, 1, 1);
865
	ath9k_ps_restore(sc);
866
	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
867 868
}

S
Sujith 已提交
869 870
int ath_reset(struct ath_softc *sc, bool retry_tx)
{
871
	struct ath_hw *ah = sc->sc_ah;
872
	struct ath_common *common = ath9k_hw_common(ah);
873
	struct ieee80211_hw *hw = sc->hw;
874
	int r;
S
Sujith 已提交
875

S
Sujith 已提交
876 877 878
	/* Stop ANI */
	del_timer_sync(&common->ani.timer);

S
Sujith 已提交
879 880
	ieee80211_stop_queues(hw);

S
Sujith 已提交
881
	ath9k_hw_set_interrupts(ah, 0);
S
Sujith 已提交
882
	ath_drain_all_txq(sc, retry_tx);
S
Sujith 已提交
883 884 885 886
	ath_stoprecv(sc);
	ath_flushrecv(sc);

	spin_lock_bh(&sc->sc_resetlock);
887
	r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
888
	if (r)
889 890
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to reset hardware; reset status %d\n", r);
S
Sujith 已提交
891 892 893
	spin_unlock_bh(&sc->sc_resetlock);

	if (ath_startrecv(sc) != 0)
894 895
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to start recv logic\n");
S
Sujith 已提交
896 897 898 899 900 901

	/*
	 * 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.
	 */
902
	ath_cache_conf_rate(sc, &hw->conf);
S
Sujith 已提交
903 904 905 906

	ath_update_txpow(sc);

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

P
Pavel Roskin 已提交
909
	ath9k_hw_set_interrupts(ah, ah->imask);
S
Sujith 已提交
910 911 912 913 914

	if (retry_tx) {
		int i;
		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
			if (ATH_TXQ_SETUP(sc, i)) {
S
Sujith 已提交
915 916 917
				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 已提交
918 919 920 921
			}
		}
	}

S
Sujith 已提交
922 923
	ieee80211_wake_queues(hw);

S
Sujith 已提交
924 925 926
	/* Start ANI */
	ath_start_ani(common);

927
	return r;
S
Sujith 已提交
928 929
}

930
static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
S
Sujith 已提交
931 932 933 934 935
{
	int qnum;

	switch (queue) {
	case 0:
936
		qnum = sc->tx.hwq_map[WME_AC_VO];
S
Sujith 已提交
937 938
		break;
	case 1:
939
		qnum = sc->tx.hwq_map[WME_AC_VI];
S
Sujith 已提交
940 941
		break;
	case 2:
942
		qnum = sc->tx.hwq_map[WME_AC_BE];
S
Sujith 已提交
943 944
		break;
	case 3:
945
		qnum = sc->tx.hwq_map[WME_AC_BK];
S
Sujith 已提交
946 947
		break;
	default:
948
		qnum = sc->tx.hwq_map[WME_AC_BE];
S
Sujith 已提交
949 950 951 952 953 954 955 956 957 958 959
		break;
	}

	return qnum;
}

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

	switch (queue) {
960
	case WME_AC_VO:
S
Sujith 已提交
961 962
		qnum = 0;
		break;
963
	case WME_AC_VI:
S
Sujith 已提交
964 965
		qnum = 1;
		break;
966
	case WME_AC_BE:
S
Sujith 已提交
967 968
		qnum = 2;
		break;
969
	case WME_AC_BK:
S
Sujith 已提交
970 971 972 973 974 975 976 977 978 979
		qnum = 3;
		break;
	default:
		qnum = -1;
		break;
	}

	return qnum;
}

980 981
/* XXX: Remove me once we don't depend on ath9k_channel for all
 * this redundant data */
982 983
void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
			   struct ath9k_channel *ichan)
984 985 986 987 988 989 990 991 992
{
	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 已提交
993
		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
994 995 996 997 998
	} else {
		ichan->chanmode = CHANNEL_A;
		ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
	}

L
Luis R. Rodriguez 已提交
999
	if (conf_is_ht(conf))
1000 1001 1002 1003
		ichan->chanmode = ath_get_extchanmode(sc, chan,
					    conf->channel_type);
}

S
Sujith 已提交
1004 1005 1006 1007
/**********************/
/* mac80211 callbacks */
/**********************/

1008
static int ath9k_start(struct ieee80211_hw *hw)
1009
{
1010 1011
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1012
	struct ath_hw *ah = sc->sc_ah;
1013
	struct ath_common *common = ath9k_hw_common(ah);
1014
	struct ieee80211_channel *curchan = hw->conf.channel;
S
Sujith 已提交
1015
	struct ath9k_channel *init_channel;
1016
	int r;
1017

1018 1019 1020
	ath_print(common, ATH_DBG_CONFIG,
		  "Starting driver with initial channel: %d MHz\n",
		  curchan->center_freq);
1021

1022 1023
	mutex_lock(&sc->mutex);

1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
	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;

1045
	/* setup initial channel */
1046

1047
	sc->chan_idx = curchan->hw_value;
1048

1049
	init_channel = ath_get_curchannel(sc, hw);
S
Sujith 已提交
1050 1051

	/* Reset SERDES registers */
1052
	ath9k_hw_configpcipowersave(ah, 0, 0);
S
Sujith 已提交
1053 1054 1055 1056 1057 1058 1059 1060 1061

	/*
	 * 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);
1062
	r = ath9k_hw_reset(ah, init_channel, false);
1063
	if (r) {
1064 1065 1066 1067
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to reset hardware; reset status %d "
			  "(freq %u MHz)\n", r,
			  curchan->center_freq);
S
Sujith 已提交
1068
		spin_unlock_bh(&sc->sc_resetlock);
1069
		goto mutex_unlock;
S
Sujith 已提交
1070 1071 1072 1073 1074 1075 1076 1077
	}
	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);
1078

S
Sujith 已提交
1079 1080 1081 1082 1083 1084 1085 1086
	/*
	 * 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) {
1087 1088
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to start recv logic\n");
1089 1090
		r = -EIO;
		goto mutex_unlock;
1091
	}
1092

S
Sujith 已提交
1093
	/* Setup our intr mask. */
F
Felix Fietkau 已提交
1094 1095 1096 1097 1098
	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)
1099 1100 1101
		ah->imask |= ATH9K_INT_RXHP |
			     ATH9K_INT_RXLP |
			     ATH9K_INT_BB_WATCHDOG;
F
Felix Fietkau 已提交
1102 1103
	else
		ah->imask |= ATH9K_INT_RX;
S
Sujith 已提交
1104

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

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

1111
	ath_cache_conf_rate(sc, &hw->conf);
S
Sujith 已提交
1112 1113 1114 1115

	sc->sc_flags &= ~SC_OP_INVALID;

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

1119
	ieee80211_wake_queues(hw);
S
Sujith 已提交
1120

1121
	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
1122

1123 1124
	if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
	    !ah->btcoex_hw.enabled) {
1125 1126
		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
					   AR_STOMP_LOW_WLAN_WGHT);
1127
		ath9k_hw_btcoex_enable(ah);
1128

1129 1130
		if (common->bus_ops->bt_coex_prep)
			common->bus_ops->bt_coex_prep(common);
1131
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1132
			ath9k_btcoex_timer_resume(sc);
1133 1134
	}

1135 1136 1137
mutex_unlock:
	mutex_unlock(&sc->mutex);

1138
	return r;
1139 1140
}

1141 1142
static int ath9k_tx(struct ieee80211_hw *hw,
		    struct sk_buff *skb)
1143
{
S
Sujith 已提交
1144
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1145 1146
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1147
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
S
Sujith 已提交
1148
	struct ath_tx_control txctl;
1149 1150
	int padpos, padsize;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1151
	int qnum;
S
Sujith 已提交
1152

1153
	if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
1154 1155 1156
		ath_print(common, ATH_DBG_XMIT,
			  "ath9k: %s: TX in unexpected wiphy state "
			  "%d\n", wiphy_name(hw->wiphy), aphy->state);
1157 1158 1159
		goto exit;
	}

1160
	if (sc->ps_enabled) {
1161 1162 1163 1164 1165 1166 1167
		/*
		 * 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)) {
1168 1169
			ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame "
				  "while in PS mode\n");
1170 1171 1172 1173
			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
		}
	}

1174 1175 1176 1177 1178 1179 1180
	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);
1181 1182
		if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
			ath9k_hw_setrxabort(sc->sc_ah, 0);
1183
		if (ieee80211_is_pspoll(hdr->frame_control)) {
1184 1185
			ath_print(common, ATH_DBG_PS,
				  "Sending PS-Poll to pick a buffered frame\n");
S
Sujith 已提交
1186
			sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
1187
		} else {
1188 1189
			ath_print(common, ATH_DBG_PS,
				  "Wake up to complete TX\n");
S
Sujith 已提交
1190
			sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
1191 1192 1193 1194 1195 1196 1197 1198 1199
		}
		/*
		 * 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 已提交
1200
	memset(&txctl, 0, sizeof(struct ath_tx_control));
1201

1202 1203 1204 1205 1206 1207 1208
	/*
	 * 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 已提交
1209
			sc->tx.seq_no += 0x10;
1210
		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
S
Sujith 已提交
1211
		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
1212
	}
1213

1214
	/* Add the padding after the header if this is not already done */
1215 1216 1217
	padpos = ath9k_cmn_padpos(hdr->frame_control);
	padsize = padpos & 3;
	if (padsize && skb->len>padpos) {
1218 1219 1220
		if (skb_headroom(skb) < padsize)
			return -1;
		skb_push(skb, padsize);
1221
		memmove(skb->data, skb->data + padsize, padpos);
1222 1223
	}

1224 1225
	qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
	txctl.txq = &sc->tx.txq[qnum];
S
Sujith 已提交
1226

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

1229
	if (ath_tx_start(hw, skb, &txctl) != 0) {
1230
		ath_print(common, ATH_DBG_XMIT, "TX failed\n");
S
Sujith 已提交
1231
		goto exit;
1232 1233
	}

S
Sujith 已提交
1234 1235 1236
	return 0;
exit:
	dev_kfree_skb_any(skb);
1237
	return 0;
1238 1239
}

1240
static void ath9k_stop(struct ieee80211_hw *hw)
1241
{
1242 1243
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1244
	struct ath_hw *ah = sc->sc_ah;
1245
	struct ath_common *common = ath9k_hw_common(ah);
1246

S
Sujith 已提交
1247 1248
	mutex_lock(&sc->mutex);

1249 1250
	aphy->state = ATH_WIPHY_INACTIVE;

1251 1252 1253
	if (led_blink)
		cancel_delayed_work_sync(&sc->ath_led_blink_work);

1254
	cancel_delayed_work_sync(&sc->tx_complete_work);
1255
	cancel_work_sync(&sc->paprd_work);
1256 1257 1258 1259 1260 1261

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

S
Sujith 已提交
1262
	if (sc->sc_flags & SC_OP_INVALID) {
1263
		ath_print(common, ATH_DBG_ANY, "Device not present\n");
S
Sujith 已提交
1264
		mutex_unlock(&sc->mutex);
S
Sujith 已提交
1265 1266
		return;
	}
1267

1268 1269 1270 1271 1272
	if (ath9k_wiphy_started(sc)) {
		mutex_unlock(&sc->mutex);
		return; /* another wiphy still in use */
	}

1273 1274 1275
	/* Ensure HW is awake when we try to shut it down. */
	ath9k_ps_wakeup(sc);

1276
	if (ah->btcoex_hw.enabled) {
1277
		ath9k_hw_btcoex_disable(ah);
1278
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1279
			ath9k_btcoex_timer_pause(sc);
1280 1281
	}

S
Sujith 已提交
1282 1283
	/* make sure h/w will not generate any interrupt
	 * before setting the invalid flag. */
1284
	ath9k_hw_set_interrupts(ah, 0);
S
Sujith 已提交
1285 1286

	if (!(sc->sc_flags & SC_OP_INVALID)) {
S
Sujith 已提交
1287
		ath_drain_all_txq(sc, false);
S
Sujith 已提交
1288
		ath_stoprecv(sc);
1289
		ath9k_hw_phy_disable(ah);
S
Sujith 已提交
1290
	} else
S
Sujith 已提交
1291
		sc->rx.rxlink = NULL;
S
Sujith 已提交
1292 1293

	/* disable HAL and put h/w to sleep */
1294 1295
	ath9k_hw_disable(ah);
	ath9k_hw_configpcipowersave(ah, 1, 1);
1296 1297 1298
	ath9k_ps_restore(sc);

	/* Finally, put the chip in FULL SLEEP mode */
1299
	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
S
Sujith 已提交
1300 1301

	sc->sc_flags |= SC_OP_INVALID;
1302

1303 1304
	mutex_unlock(&sc->mutex);

1305
	ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1306 1307
}

1308
static int ath9k_add_interface(struct ieee80211_hw *hw,
1309
			       struct ieee80211_vif *vif)
1310
{
1311 1312
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
P
Pavel Roskin 已提交
1313 1314
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
1315
	struct ath_vif *avp = (void *)vif->drv_priv;
1316
	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
1317
	int ret = 0;
1318

1319 1320
	mutex_lock(&sc->mutex);

P
Pavel Roskin 已提交
1321
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
1322 1323 1324 1325 1326
	    sc->nvifs > 0) {
		ret = -ENOBUFS;
		goto out;
	}

1327
	switch (vif->type) {
1328
	case NL80211_IFTYPE_STATION:
1329
		ic_opmode = NL80211_IFTYPE_STATION;
1330
		break;
1331 1332
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_AP:
1333
	case NL80211_IFTYPE_MESH_POINT:
1334 1335 1336 1337
		if (sc->nbcnvifs >= ATH_BCBUF) {
			ret = -ENOBUFS;
			goto out;
		}
1338
		ic_opmode = vif->type;
1339 1340
		break;
	default:
1341
		ath_print(common, ATH_DBG_FATAL,
1342
			"Interface type %d not yet supported\n", vif->type);
1343 1344
		ret = -EOPNOTSUPP;
		goto out;
1345 1346
	}

1347 1348
	ath_print(common, ATH_DBG_CONFIG,
		  "Attach a VIF of type: %d\n", ic_opmode);
1349

S
Sujith 已提交
1350
	/* Set the VIF opmode */
S
Sujith 已提交
1351 1352 1353
	avp->av_opmode = ic_opmode;
	avp->av_bslot = -1;

1354
	sc->nvifs++;
1355

P
Pavel Roskin 已提交
1356
	if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
1357 1358
		ath9k_set_bssid_mask(hw);

1359 1360 1361
	if (sc->nvifs > 1)
		goto out; /* skip global settings for secondary vif */

S
Sujith 已提交
1362
	if (ic_opmode == NL80211_IFTYPE_AP) {
P
Pavel Roskin 已提交
1363
		ath9k_hw_set_tsfadjust(ah, 1);
S
Sujith 已提交
1364 1365
		sc->sc_flags |= SC_OP_TSF_RESET;
	}
S
Sujith 已提交
1366 1367

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

1370 1371 1372 1373
	/*
	 * Enable MIB interrupts when there are hardware phy counters.
	 * Note we only do this (at the moment) for station mode.
	 */
1374 1375 1376
	if ((vif->type == NL80211_IFTYPE_STATION) ||
	    (vif->type == NL80211_IFTYPE_ADHOC) ||
	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
1377 1378
		if (ah->config.enable_ani)
			ah->imask |= ATH9K_INT_MIB;
P
Pavel Roskin 已提交
1379
		ah->imask |= ATH9K_INT_TSFOOR;
1380 1381
	}

P
Pavel Roskin 已提交
1382
	ath9k_hw_set_interrupts(ah, ah->imask);
1383

1384 1385
	if (vif->type == NL80211_IFTYPE_AP    ||
	    vif->type == NL80211_IFTYPE_ADHOC ||
1386 1387
	    vif->type == NL80211_IFTYPE_MONITOR) {
		sc->sc_flags |= SC_OP_ANI_RUN;
1388
		ath_start_ani(common);
1389
	}
1390

1391
out:
1392
	mutex_unlock(&sc->mutex);
1393
	return ret;
1394 1395
}

1396
static void ath9k_remove_interface(struct ieee80211_hw *hw,
1397
				   struct ieee80211_vif *vif)
1398
{
1399 1400
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1401
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1402
	struct ath_vif *avp = (void *)vif->drv_priv;
1403
	int i;
1404

1405
	ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1406

1407 1408
	mutex_lock(&sc->mutex);

1409
	/* Stop ANI */
1410
	sc->sc_flags &= ~SC_OP_ANI_RUN;
1411
	del_timer_sync(&common->ani.timer);
J
Jouni Malinen 已提交
1412

1413
	/* Reclaim beacon resources */
1414 1415 1416
	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
1417
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
1418
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1419
		ath9k_ps_restore(sc);
J
Jouni Malinen 已提交
1420
	}
1421

1422
	ath_beacon_return(sc, avp);
1423
	sc->sc_flags &= ~SC_OP_BEACONS;
1424

1425
	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
1426
		if (sc->beacon.bslot[i] == vif) {
1427 1428 1429
			printk(KERN_DEBUG "%s: vif had allocated beacon "
			       "slot\n", __func__);
			sc->beacon.bslot[i] = NULL;
1430
			sc->beacon.bslot_aphy[i] = NULL;
1431 1432 1433
		}
	}

S
Sujith 已提交
1434
	sc->nvifs--;
1435 1436

	mutex_unlock(&sc->mutex);
1437 1438
}

1439 1440
void ath9k_enable_ps(struct ath_softc *sc)
{
P
Pavel Roskin 已提交
1441 1442
	struct ath_hw *ah = sc->sc_ah;

1443
	sc->ps_enabled = true;
P
Pavel Roskin 已提交
1444 1445 1446 1447
	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);
1448
		}
1449
		ath9k_hw_setrxabort(ah, 1);
1450 1451 1452
	}
}

1453
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1454
{
1455 1456
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1457
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1458
	struct ieee80211_conf *conf = &hw->conf;
1459
	struct ath_hw *ah = sc->sc_ah;
1460
	bool disable_radio;
1461

1462
	mutex_lock(&sc->mutex);
1463

1464 1465 1466 1467 1468 1469
	/*
	 * 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.
	 */
1470
	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1471 1472 1473
		bool enable_radio;
		bool all_wiphys_idle;
		bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1474 1475 1476

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

1479
		enable_radio = (!idle && all_wiphys_idle);
1480 1481 1482 1483 1484 1485 1486

		/*
		 * 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.
		 */
1487 1488
		spin_unlock_bh(&sc->wiphy_lock);

1489
		if (enable_radio) {
1490
			sc->ps_idle = false;
1491
			ath_radio_enable(sc, hw);
1492 1493
			ath_print(common, ATH_DBG_CONFIG,
				  "not-idle: enabling radio\n");
1494 1495 1496
		}
	}

1497 1498 1499 1500 1501 1502
	/*
	 * 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.
	 */
1503 1504
	if (changed & IEEE80211_CONF_CHANGE_PS) {
		if (conf->flags & IEEE80211_CONF_PS) {
S
Sujith 已提交
1505
			sc->ps_flags |= PS_ENABLED;
1506 1507 1508 1509
			/*
			 * At this point we know hardware has received an ACK
			 * of a previously sent null data frame.
			 */
S
Sujith 已提交
1510 1511
			if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
				sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
1512
				ath9k_enable_ps(sc);
1513
                        }
1514
		} else {
1515
			sc->ps_enabled = false;
S
Sujith 已提交
1516 1517
			sc->ps_flags &= ~(PS_ENABLED |
					  PS_NULLFUNC_COMPLETED);
1518
			ath9k_setpower(sc, ATH9K_PM_AWAKE);
1519 1520 1521
			if (!(ah->caps.hw_caps &
			      ATH9K_HW_CAP_AUTOSLEEP)) {
				ath9k_hw_setrxabort(sc->sc_ah, 0);
S
Sujith 已提交
1522 1523 1524 1525
				sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
						  PS_WAIT_FOR_CAB |
						  PS_WAIT_FOR_PSPOLL_DATA |
						  PS_WAIT_FOR_TX_ACK);
P
Pavel Roskin 已提交
1526 1527
				if (ah->imask & ATH9K_INT_TIM_TIMER) {
					ah->imask &= ~ATH9K_INT_TIM_TIMER;
1528
					ath9k_hw_set_interrupts(sc->sc_ah,
P
Pavel Roskin 已提交
1529
							ah->imask);
1530
				}
1531 1532 1533 1534
			}
		}
	}

S
Sujith 已提交
1535 1536 1537 1538 1539 1540 1541 1542
	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;
		}
	}

1543
	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1544
		struct ieee80211_channel *curchan = hw->conf.channel;
1545
		int pos = curchan->hw_value;
J
Johannes Berg 已提交
1546

1547 1548 1549
		aphy->chan_idx = pos;
		aphy->chan_is_ht = conf_is_ht(conf);

1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
		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;
		}
1560

1561 1562
		ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
			  curchan->center_freq);
1563

1564
		/* XXX: remove me eventualy */
1565
		ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
1566

1567
		ath_update_chainmask(sc, conf_is_ht(conf));
S
Sujith 已提交
1568

1569
		if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
1570 1571
			ath_print(common, ATH_DBG_FATAL,
				  "Unable to set channel\n");
1572
			mutex_unlock(&sc->mutex);
1573 1574
			return -EINVAL;
		}
S
Sujith 已提交
1575
	}
1576

1577
skip_chan_change:
1578
	if (changed & IEEE80211_CONF_CHANGE_POWER) {
S
Sujith 已提交
1579
		sc->config.txpowlimit = 2 * conf->power_level;
1580 1581
		ath_update_txpow(sc);
	}
1582

1583 1584 1585 1586
	spin_lock_bh(&sc->wiphy_lock);
	disable_radio = ath9k_all_wiphys_idle(sc);
	spin_unlock_bh(&sc->wiphy_lock);

1587
	if (disable_radio) {
1588
		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
1589
		sc->ps_idle = true;
1590
		ath_radio_disable(sc, hw);
1591 1592
	}

1593
	mutex_unlock(&sc->mutex);
1594

1595 1596 1597
	return 0;
}

1598 1599 1600 1601
#define SUPPORTED_FILTERS			\
	(FIF_PROMISC_IN_BSS |			\
	FIF_ALLMULTI |				\
	FIF_CONTROL |				\
1602
	FIF_PSPOLL |				\
1603 1604 1605
	FIF_OTHER_BSS |				\
	FIF_BCN_PRBRESP_PROMISC |		\
	FIF_FCSFAIL)
1606

1607 1608 1609 1610
/* FIXME: sc->sc_full_reset ? */
static void ath9k_configure_filter(struct ieee80211_hw *hw,
				   unsigned int changed_flags,
				   unsigned int *total_flags,
1611
				   u64 multicast)
1612
{
1613 1614
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1615
	u32 rfilt;
1616

1617 1618
	changed_flags &= SUPPORTED_FILTERS;
	*total_flags &= SUPPORTED_FILTERS;
1619

S
Sujith 已提交
1620
	sc->rx.rxfilter = *total_flags;
1621
	ath9k_ps_wakeup(sc);
1622 1623
	rfilt = ath_calcrxfilter(sc);
	ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
1624
	ath9k_ps_restore(sc);
1625

1626 1627
	ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
		  "Set HW RX filter: 0x%x\n", rfilt);
1628
}
1629

1630 1631 1632
static int ath9k_sta_add(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta)
1633
{
1634 1635
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1636

1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651
	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;
1652 1653
}

1654
static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
1655
			 const struct ieee80211_tx_queue_params *params)
1656
{
1657 1658
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1659
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1660 1661
	struct ath9k_tx_queue_info qi;
	int ret = 0, qnum;
1662

1663 1664
	if (queue >= WME_NUM_AC)
		return 0;
1665

1666 1667
	mutex_lock(&sc->mutex);

1668 1669
	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));

1670 1671 1672 1673 1674
	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);
1675

1676 1677 1678 1679 1680
	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);
1681

1682 1683
	ret = ath_txq_update(sc, qnum, &qi);
	if (ret)
1684
		ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1685

1686
	if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
1687
		if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
1688 1689
			ath_beaconq_config(sc);

1690 1691
	mutex_unlock(&sc->mutex);

1692 1693
	return ret;
}
1694

1695 1696
static int ath9k_set_key(struct ieee80211_hw *hw,
			 enum set_key_cmd cmd,
1697 1698
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta,
1699 1700
			 struct ieee80211_key_conf *key)
{
1701 1702
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1703
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1704
	int ret = 0;
1705

1706 1707 1708
	if (modparam_nohwcrypt)
		return -ENOSPC;

1709
	mutex_lock(&sc->mutex);
1710
	ath9k_ps_wakeup(sc);
1711
	ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1712

1713 1714
	switch (cmd) {
	case SET_KEY:
1715
		ret = ath9k_cmn_key_config(common, vif, sta, key);
1716 1717
		if (ret >= 0) {
			key->hw_key_idx = ret;
1718 1719 1720 1721
			/* 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;
1722 1723
			if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
				key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1724
			ret = 0;
1725 1726 1727
		}
		break;
	case DISABLE_KEY:
1728
		ath9k_cmn_key_delete(common, key);
1729 1730 1731 1732
		break;
	default:
		ret = -EINVAL;
	}
1733

1734
	ath9k_ps_restore(sc);
1735 1736
	mutex_unlock(&sc->mutex);

1737 1738
	return ret;
}
1739

1740 1741 1742 1743 1744
static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_bss_conf *bss_conf,
				   u32 changed)
{
1745 1746
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1747
	struct ath_hw *ah = sc->sc_ah;
1748
	struct ath_common *common = ath9k_hw_common(ah);
1749
	struct ath_vif *avp = (void *)vif->drv_priv;
1750
	int slottime;
S
Sujith 已提交
1751
	int error;
1752

1753 1754
	mutex_lock(&sc->mutex);

S
Sujith 已提交
1755 1756 1757 1758
	if (changed & BSS_CHANGED_BSSID) {
		/* Set BSSID */
		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
		memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
1759
		common->curaid = 0;
1760
		ath9k_hw_write_associd(ah);
1761

S
Sujith 已提交
1762 1763
		/* Set aggregation protection mode parameters */
		sc->config.ath_aggr_prot = 0;
1764

S
Sujith 已提交
1765 1766 1767
		/* Only legacy IBSS for now */
		if (vif->type == NL80211_IFTYPE_ADHOC)
			ath_update_chainmask(sc, 0);
1768

S
Sujith 已提交
1769 1770 1771
		ath_print(common, ATH_DBG_CONFIG,
			  "BSSID: %pM aid: 0x%x\n",
			  common->curbssid, common->curaid);
1772

S
Sujith 已提交
1773 1774 1775
		/* need to reconfigure the beacon */
		sc->sc_flags &= ~SC_OP_BEACONS ;
	}
1776

S
Sujith 已提交
1777 1778 1779 1780 1781 1782 1783
	/* 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);
1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802
	}

	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);
		}
1803 1804
	}

S
Sujith 已提交
1805 1806 1807
	/* Disable transmission of beacons */
	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1808

S
Sujith 已提交
1809 1810 1811 1812 1813 1814 1815 1816 1817
	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);
1818 1819 1820
			error = ath_beacon_alloc(aphy, vif);
			if (!error)
				ath_beacon_config(sc, vif);
S
Sujith 已提交
1821 1822
		} else {
			ath_beacon_config(sc, vif);
1823 1824 1825
		}
	}

1826
	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1827 1828
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
			  bss_conf->use_short_preamble);
1829 1830 1831 1832 1833
		if (bss_conf->use_short_preamble)
			sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
		else
			sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
	}
1834

1835
	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1836 1837
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
			  bss_conf->use_cts_prot);
1838 1839 1840 1841 1842 1843
		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;
	}
1844

1845
	if (changed & BSS_CHANGED_ASSOC) {
1846
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1847
			bss_conf->assoc);
S
Sujith 已提交
1848
		ath9k_bss_assoc_info(sc, vif, bss_conf);
1849
	}
1850 1851

	mutex_unlock(&sc->mutex);
1852
}
1853

1854 1855 1856
static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
{
	u64 tsf;
1857 1858
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1859

1860 1861 1862
	mutex_lock(&sc->mutex);
	tsf = ath9k_hw_gettsf64(sc->sc_ah);
	mutex_unlock(&sc->mutex);
1863

1864 1865
	return tsf;
}
1866

1867 1868
static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
1869 1870
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1871

1872 1873 1874
	mutex_lock(&sc->mutex);
	ath9k_hw_settsf64(sc->sc_ah, tsf);
	mutex_unlock(&sc->mutex);
1875 1876
}

1877 1878
static void ath9k_reset_tsf(struct ieee80211_hw *hw)
{
1879 1880
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1881

1882
	mutex_lock(&sc->mutex);
1883 1884

	ath9k_ps_wakeup(sc);
1885
	ath9k_hw_reset_tsf(sc->sc_ah);
1886 1887
	ath9k_ps_restore(sc);

1888
	mutex_unlock(&sc->mutex);
1889
}
1890

1891
static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1892
			      struct ieee80211_vif *vif,
1893 1894 1895
			      enum ieee80211_ampdu_mlme_action action,
			      struct ieee80211_sta *sta,
			      u16 tid, u16 *ssn)
1896
{
1897 1898
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1899
	int ret = 0;
1900

1901 1902
	local_bh_disable();

1903 1904
	switch (action) {
	case IEEE80211_AMPDU_RX_START:
1905 1906
		if (!(sc->sc_flags & SC_OP_RXAGGR))
			ret = -ENOTSUPP;
1907 1908 1909 1910
		break;
	case IEEE80211_AMPDU_RX_STOP:
		break;
	case IEEE80211_AMPDU_TX_START:
1911
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
1912
		ath_tx_aggr_start(sc, sta, tid, ssn);
1913
		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1914
		ath9k_ps_restore(sc);
1915 1916
		break;
	case IEEE80211_AMPDU_TX_STOP:
1917
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
1918
		ath_tx_aggr_stop(sc, sta, tid);
1919
		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1920
		ath9k_ps_restore(sc);
1921
		break;
1922
	case IEEE80211_AMPDU_TX_OPERATIONAL:
1923
		ath9k_ps_wakeup(sc);
1924
		ath_tx_aggr_resume(sc, sta, tid);
1925
		ath9k_ps_restore(sc);
1926
		break;
1927
	default:
1928 1929
		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
			  "Unknown AMPDU action\n");
1930 1931
	}

1932 1933
	local_bh_enable();

1934
	return ret;
1935 1936
}

1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955
static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
			     struct survey_info *survey)
{
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
	struct ieee80211_conf *conf = &hw->conf;

	 if (idx != 0)
		return -ENOENT;

	survey->channel = conf->channel;
	survey->filled = SURVEY_INFO_NOISE_DBM;
	survey->noise = common->ani.noise_floor;

	return 0;
}

1956 1957
static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
{
1958 1959
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
S
Sujith 已提交
1960
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1961

1962
	mutex_lock(&sc->mutex);
1963 1964 1965 1966 1967 1968 1969
	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.
		 */
1970
		mutex_unlock(&sc->mutex);
1971 1972 1973 1974 1975
		return;
	}

	aphy->state = ATH_WIPHY_SCAN;
	ath9k_wiphy_pause_all_forced(sc, aphy);
1976
	sc->sc_flags |= SC_OP_SCANNING;
S
Sujith 已提交
1977
	del_timer_sync(&common->ani.timer);
1978
	cancel_work_sync(&sc->paprd_work);
S
Sujith 已提交
1979
	cancel_delayed_work_sync(&sc->tx_complete_work);
1980
	mutex_unlock(&sc->mutex);
1981 1982 1983 1984
}

static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
{
1985 1986
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
S
Sujith 已提交
1987
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1988

1989
	mutex_lock(&sc->mutex);
1990
	aphy->state = ATH_WIPHY_ACTIVE;
1991
	sc->sc_flags &= ~SC_OP_SCANNING;
S
Sujith 已提交
1992
	sc->sc_flags |= SC_OP_FULL_RESET;
S
Sujith 已提交
1993
	ath_start_ani(common);
S
Sujith 已提交
1994
	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
1995
	ath_beacon_config(sc, NULL);
1996
	mutex_unlock(&sc->mutex);
1997 1998
}

1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
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);
}

2011
struct ieee80211_ops ath9k_ops = {
2012 2013 2014 2015 2016 2017 2018
	.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,
2019 2020
	.sta_add	    = ath9k_sta_add,
	.sta_remove	    = ath9k_sta_remove,
2021 2022 2023 2024
	.conf_tx 	    = ath9k_conf_tx,
	.bss_info_changed   = ath9k_bss_info_changed,
	.set_key            = ath9k_set_key,
	.get_tsf 	    = ath9k_get_tsf,
2025
	.set_tsf 	    = ath9k_set_tsf,
2026
	.reset_tsf 	    = ath9k_reset_tsf,
2027
	.ampdu_action       = ath9k_ampdu_action,
2028
	.get_survey	    = ath9k_get_survey,
2029 2030
	.sw_scan_start      = ath9k_sw_scan_start,
	.sw_scan_complete   = ath9k_sw_scan_complete,
J
Johannes Berg 已提交
2031
	.rfkill_poll        = ath9k_rfkill_poll_state,
2032
	.set_coverage_class = ath9k_set_coverage_class,
2033
};