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

S
Sujith 已提交
21 22
static void ath_update_txpow(struct ath_softc *sc)
{
23
	struct ath_hw *ah = sc->sc_ah;
S
Sujith 已提交
24

S
Sujith 已提交
25 26
	if (sc->curtxpow != sc->config.txpowlimit) {
		ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
S
Sujith 已提交
27
		/* read back in case value is clamped */
F
Felix Fietkau 已提交
28
		sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
S
Sujith 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
	}
}

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

67 68 69 70 71 72 73 74 75 76 77 78 79
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 已提交
80
bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
81 82 83 84
{
	unsigned long flags;
	bool ret;

85 86 87
	spin_lock_irqsave(&sc->sc_pm_lock, flags);
	ret = ath9k_hw_setpower(sc->sc_ah, mode);
	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
88 89 90 91

	return ret;
}

92 93
void ath9k_ps_wakeup(struct ath_softc *sc)
{
94
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
95 96 97 98 99 100
	unsigned long flags;

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

101
	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
102

103 104 105 106 107 108 109 110 111 112
	/*
	 * While the hardware is asleep, the cycle counters contain no
	 * useful data. Better clear them now so that they don't mess up
	 * survey data results.
	 */
	spin_lock(&common->cc_lock);
	ath_hw_cycle_counters_update(common);
	memset(&common->cc_survey, 0, sizeof(common->cc_survey));
	spin_unlock(&common->cc_lock);

113 114 115 116 117 118
 unlock:
	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}

void ath9k_ps_restore(struct ath_softc *sc)
{
119
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
120 121 122 123 124 125
	unsigned long flags;

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

126 127 128 129
	spin_lock(&common->cc_lock);
	ath_hw_cycle_counters_update(common);
	spin_unlock(&common->cc_lock);

130 131 132 133
	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 已提交
134 135 136
			      PS_WAIT_FOR_CAB |
			      PS_WAIT_FOR_PSPOLL_DATA |
			      PS_WAIT_FOR_TX_ACK)))
137
		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
138 139 140 141 142

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

143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
static void ath_start_ani(struct ath_common *common)
{
	struct ath_hw *ah = common->ah;
	unsigned long timestamp = jiffies_to_msecs(jiffies);
	struct ath_softc *sc = (struct ath_softc *) common->priv;

	if (!(sc->sc_flags & SC_OP_ANI_RUN))
		return;

	if (sc->sc_flags & SC_OP_OFFCHANNEL)
		return;

	common->ani.longcal_timer = timestamp;
	common->ani.shortcal_timer = timestamp;
	common->ani.checkani_timer = timestamp;

	mod_timer(&common->ani.timer,
		  jiffies +
			msecs_to_jiffies((u32)ah->config.ani_poll_interval));
}

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
static void ath_update_survey_nf(struct ath_softc *sc, int channel)
{
	struct ath_hw *ah = sc->sc_ah;
	struct ath9k_channel *chan = &ah->channels[channel];
	struct survey_info *survey = &sc->survey[channel];

	if (chan->noisefloor) {
		survey->filled |= SURVEY_INFO_NOISE_DBM;
		survey->noise = chan->noisefloor;
	}
}

static void ath_update_survey_stats(struct ath_softc *sc)
{
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
	int pos = ah->curchan - &ah->channels[0];
	struct survey_info *survey = &sc->survey[pos];
	struct ath_cycle_counters *cc = &common->cc_survey;
	unsigned int div = common->clockrate * 1000;

185 186
	if (ah->power_mode == ATH9K_PM_AWAKE)
		ath_hw_cycle_counters_update(common);
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202

	if (cc->cycles > 0) {
		survey->filled |= SURVEY_INFO_CHANNEL_TIME |
			SURVEY_INFO_CHANNEL_TIME_BUSY |
			SURVEY_INFO_CHANNEL_TIME_RX |
			SURVEY_INFO_CHANNEL_TIME_TX;
		survey->channel_time += cc->cycles / div;
		survey->channel_time_busy += cc->rx_busy / div;
		survey->channel_time_rx += cc->rx_frame / div;
		survey->channel_time_tx += cc->tx_frame / div;
	}
	memset(cc, 0, sizeof(*cc));

	ath_update_survey_nf(sc, pos);
}

S
Sujith 已提交
203 204 205 206 207
/*
 * 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.
*/
208 209
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
		    struct ath9k_channel *hchan)
S
Sujith 已提交
210
{
211
	struct ath_wiphy *aphy = hw->priv;
212
	struct ath_hw *ah = sc->sc_ah;
213
	struct ath_common *common = ath9k_hw_common(ah);
L
Luis R. Rodriguez 已提交
214
	struct ieee80211_conf *conf = &common->hw->conf;
S
Sujith 已提交
215
	bool fastcc = true, stopped;
216
	struct ieee80211_channel *channel = hw->conf.channel;
217
	struct ath9k_hw_cal_data *caldata = NULL;
218
	int r;
S
Sujith 已提交
219 220 221 222

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

223 224 225 226 227
	del_timer_sync(&common->ani.timer);
	cancel_work_sync(&sc->paprd_work);
	cancel_work_sync(&sc->hw_check_work);
	cancel_delayed_work_sync(&sc->tx_complete_work);

228 229
	ath9k_ps_wakeup(sc);

230 231 232 233 234 235 236 237 238 239
	/*
	 * 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 已提交
240
	ath_drain_all_txq(sc, false);
241
	stopped = ath_stoprecv(sc);
S
Sujith 已提交
242

243 244 245
	/* XXX: do not flush receive queue here. We don't want
	 * to flush data frames already in queue because of
	 * changing channel. */
S
Sujith 已提交
246

247
	if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
248 249
		fastcc = false;

250 251 252
	if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
		caldata = &aphy->caldata;

253
	ath_print(common, ATH_DBG_CONFIG,
254
		  "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
255
		  sc->sc_ah->curchan->channel,
256 257
		  channel->center_freq, conf_is_ht40(conf),
		  fastcc);
S
Sujith 已提交
258

259 260
	spin_lock_bh(&sc->sc_resetlock);

261
	r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
262
	if (r) {
263
		ath_print(common, ATH_DBG_FATAL,
264
			  "Unable to reset channel (%u MHz), "
265 266
			  "reset status %d\n",
			  channel->center_freq, r);
267
		spin_unlock_bh(&sc->sc_resetlock);
268
		goto ps_restore;
S
Sujith 已提交
269
	}
270 271 272
	spin_unlock_bh(&sc->sc_resetlock);

	if (ath_startrecv(sc) != 0) {
273 274
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to restart recv logic\n");
275 276
		r = -EIO;
		goto ps_restore;
277 278 279
	}

	ath_update_txpow(sc);
P
Pavel Roskin 已提交
280
	ath9k_hw_set_interrupts(ah, ah->imask);
281

282 283
	if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
		ath_beacon_config(sc, NULL);
284
		ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
285
		ath_start_ani(common);
286 287
	}

288
 ps_restore:
289
	ath9k_ps_restore(sc);
290
	return r;
S
Sujith 已提交
291 292
}

293 294 295
static void ath_paprd_activate(struct ath_softc *sc)
{
	struct ath_hw *ah = sc->sc_ah;
296
	struct ath9k_hw_cal_data *caldata = ah->caldata;
297
	struct ath_common *common = ath9k_hw_common(ah);
298 299
	int chain;

300
	if (!caldata || !caldata->paprd_done)
301 302 303
		return;

	ath9k_ps_wakeup(sc);
304
	ar9003_paprd_enable(ah, false);
305
	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
306
		if (!(common->tx_chainmask & BIT(chain)))
307 308
			continue;

309
		ar9003_paprd_populate_single_table(ah, caldata, chain);
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
	}

	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;
327
	struct ath9k_hw_cal_data *caldata = ah->caldata;
328
	struct ath_common *common = ath9k_hw_common(ah);
329 330 331 332 333 334 335
	int qnum, ftype;
	int chain_ok = 0;
	int chain;
	int len = 1800;
	int time_left;
	int i;

336 337 338
	if (!caldata)
		return;

339 340 341 342 343 344 345 346 347 348 349
	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);
350
	hdr->duration_id = cpu_to_le16(10);
351 352 353 354 355 356 357 358
	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];

359
	ath9k_ps_wakeup(sc);
360 361
	ar9003_paprd_init_table(ah);
	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
362
		if (!(common->tx_chainmask & BIT(chain)))
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
			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,
381
				msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
382 383 384 385 386
		if (!time_left) {
			ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
				  "Timeout waiting for paprd training on "
				  "TX chain %d\n",
				  chain);
387
			goto fail_paprd;
388 389 390 391 392
		}

		if (!ar9003_paprd_is_done(ah))
			break;

393
		if (ar9003_paprd_create_curve(ah, caldata, chain) != 0)
394 395 396 397 398 399 400
			break;

		chain_ok = 1;
	}
	kfree_skb(skb);

	if (chain_ok) {
401
		caldata->paprd_done = true;
402 403 404
		ath_paprd_activate(sc);
	}

405
fail_paprd:
406 407 408
	ath9k_ps_restore(sc);
}

S
Sujith 已提交
409 410 411 412 413 414 415
/*
 *  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 已提交
416
void ath_ani_calibrate(unsigned long data)
S
Sujith 已提交
417
{
418 419
	struct ath_softc *sc = (struct ath_softc *)data;
	struct ath_hw *ah = sc->sc_ah;
420
	struct ath_common *common = ath9k_hw_common(ah);
S
Sujith 已提交
421 422 423 424
	bool longcal = false;
	bool shortcal = false;
	bool aniflag = false;
	unsigned int timestamp = jiffies_to_msecs(jiffies);
425
	u32 cal_interval, short_cal_interval, long_cal_interval;
426
	unsigned long flags;
427 428 429 430 431

	if (ah->caldata && ah->caldata->nfcal_interference)
		long_cal_interval = ATH_LONG_CALINTERVAL_INT;
	else
		long_cal_interval = ATH_LONG_CALINTERVAL;
S
Sujith 已提交
432

433 434
	short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
		ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
S
Sujith 已提交
435

436 437 438 439 440 441
	/* Only calibrate if awake */
	if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
		goto set_timer;

	ath9k_ps_wakeup(sc);

S
Sujith 已提交
442
	/* Long calibration runs independently of short calibration. */
443
	if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
S
Sujith 已提交
444
		longcal = true;
445
		ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
446
		common->ani.longcal_timer = timestamp;
S
Sujith 已提交
447 448
	}

S
Sujith 已提交
449
	/* Short calibration applies only while caldone is false */
450 451
	if (!common->ani.caldone) {
		if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
S
Sujith 已提交
452
			shortcal = true;
453 454
			ath_print(common, ATH_DBG_ANI,
				  "shortcal @%lu\n", jiffies);
455 456
			common->ani.shortcal_timer = timestamp;
			common->ani.resetcal_timer = timestamp;
S
Sujith 已提交
457 458
		}
	} else {
459
		if ((timestamp - common->ani.resetcal_timer) >=
S
Sujith 已提交
460
		    ATH_RESTART_CALINTERVAL) {
461 462 463
			common->ani.caldone = ath9k_hw_reset_calvalid(ah);
			if (common->ani.caldone)
				common->ani.resetcal_timer = timestamp;
S
Sujith 已提交
464 465 466 467
		}
	}

	/* Verify whether we must check ANI */
468 469
	if ((timestamp - common->ani.checkani_timer) >=
	     ah->config.ani_poll_interval) {
S
Sujith 已提交
470
		aniflag = true;
471
		common->ani.checkani_timer = timestamp;
S
Sujith 已提交
472 473 474 475 476
	}

	/* Skip all processing if there's nothing to do. */
	if (longcal || shortcal || aniflag) {
		/* Call ANI routine if necessary */
477 478
		if (aniflag) {
			spin_lock_irqsave(&common->cc_lock, flags);
479
			ath9k_hw_ani_monitor(ah, ah->curchan);
480
			ath_update_survey_stats(sc);
481 482
			spin_unlock_irqrestore(&common->cc_lock, flags);
		}
S
Sujith 已提交
483 484 485

		/* Perform calibration if necessary */
		if (longcal || shortcal) {
486
			common->ani.caldone =
487 488 489 490
				ath9k_hw_calibrate(ah,
						   ah->curchan,
						   common->rx_chainmask,
						   longcal);
S
Sujith 已提交
491 492 493
		}
	}

494 495
	ath9k_ps_restore(sc);

496
set_timer:
S
Sujith 已提交
497 498 499 500 501
	/*
	* Set timer interval based on previous results.
	* The interval must be the shortest necessary to satisfy ANI,
	* short calibration and long calibration.
	*/
502
	cal_interval = ATH_LONG_CALINTERVAL;
503
	if (sc->sc_ah->config.enable_ani)
504 505
		cal_interval = min(cal_interval,
				   (u32)ah->config.ani_poll_interval);
506
	if (!common->ani.caldone)
507
		cal_interval = min(cal_interval, (u32)short_cal_interval);
S
Sujith 已提交
508

509
	mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
510 511
	if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
		if (!ah->caldata->paprd_done)
512 513 514 515
			ieee80211_queue_work(sc->hw, &sc->paprd_work);
		else
			ath_paprd_activate(sc);
	}
S
Sujith 已提交
516 517 518 519 520
}

/*
 * Update tx/rx chainmask. For legacy association,
 * hard code chainmask to 1x1, for 11n association, use
521 522
 * the chainmask configuration, for bt coexistence, use
 * the chainmask configuration even in legacy mode.
S
Sujith 已提交
523
 */
524
void ath_update_chainmask(struct ath_softc *sc, int is_ht)
S
Sujith 已提交
525
{
526
	struct ath_hw *ah = sc->sc_ah;
527
	struct ath_common *common = ath9k_hw_common(ah);
528

529
	if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
530
	    (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
531 532
		common->tx_chainmask = ah->caps.tx_chainmask;
		common->rx_chainmask = ah->caps.rx_chainmask;
S
Sujith 已提交
533
	} else {
534 535
		common->tx_chainmask = 1;
		common->rx_chainmask = 1;
S
Sujith 已提交
536 537
	}

538
	ath_print(common, ATH_DBG_CONFIG,
539
		  "tx chmask: %d, rx chmask: %d\n",
540 541
		  common->tx_chainmask,
		  common->rx_chainmask);
S
Sujith 已提交
542 543 544 545 546 547 548 549
}

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

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

550
	if (sc->sc_flags & SC_OP_TXAGGR) {
S
Sujith 已提交
551
		ath_tx_node_init(sc, an);
S
Sujith 已提交
552
		an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
553 554
				     sta->ht_cap.ampdu_factor);
		an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
555
		an->last_rssi = ATH_RSSI_DUMMY_MARKER;
556
	}
S
Sujith 已提交
557 558 559 560 561 562 563 564 565 566
}

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

567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
void ath_hw_check(struct work_struct *work)
{
	struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
	int i;

	ath9k_ps_wakeup(sc);

	for (i = 0; i < 3; i++) {
		if (ath9k_hw_check_alive(sc->sc_ah))
			goto out;

		msleep(1);
	}
	ath_reset(sc, false);

out:
	ath9k_ps_restore(sc);
}

S
Sujith 已提交
586
void ath9k_tasklet(unsigned long data)
S
Sujith 已提交
587 588
{
	struct ath_softc *sc = (struct ath_softc *)data;
589
	struct ath_hw *ah = sc->sc_ah;
590
	struct ath_common *common = ath9k_hw_common(ah);
591

S
Sujith 已提交
592
	u32 status = sc->intrstatus;
F
Felix Fietkau 已提交
593
	u32 rxmask;
S
Sujith 已提交
594

595 596
	ath9k_ps_wakeup(sc);

597
	if (status & ATH9K_INT_FATAL) {
S
Sujith 已提交
598
		ath_reset(sc, false);
599
		ath9k_ps_restore(sc);
S
Sujith 已提交
600
		return;
S
Sujith 已提交
601
	}
S
Sujith 已提交
602

603 604 605
	if (!ath9k_hw_check_alive(ah))
		ieee80211_queue_work(sc->hw, &sc->hw_check_work);

F
Felix Fietkau 已提交
606 607 608 609 610 611 612
	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 已提交
613
		spin_lock_bh(&sc->rx.rxflushlock);
F
Felix Fietkau 已提交
614 615 616 617 618 619 620

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

624 625 626 627 628 629
	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 已提交
630

631
	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
632 633 634 635
		/*
		 * TSF sync does not look correct; remain awake to sync with
		 * the next Beacon.
		 */
636 637
		ath_print(common, ATH_DBG_PS,
			  "TSFOOR - Sync with next Beacon\n");
S
Sujith 已提交
638
		sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
639 640
	}

641
	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
642 643 644
		if (status & ATH9K_INT_GENTIMER)
			ath_gen_timer_isr(sc->sc_ah);

S
Sujith 已提交
645
	/* re-enable hardware interrupt */
P
Pavel Roskin 已提交
646
	ath9k_hw_set_interrupts(ah, ah->imask);
647
	ath9k_ps_restore(sc);
S
Sujith 已提交
648 649
}

650
irqreturn_t ath_isr(int irq, void *dev)
S
Sujith 已提交
651
{
S
Sujith 已提交
652 653 654 655 656
#define SCHED_INTR (				\
		ATH9K_INT_FATAL |		\
		ATH9K_INT_RXORN |		\
		ATH9K_INT_RXEOL |		\
		ATH9K_INT_RX |			\
F
Felix Fietkau 已提交
657 658
		ATH9K_INT_RXLP |		\
		ATH9K_INT_RXHP |		\
S
Sujith 已提交
659 660 661
		ATH9K_INT_TX |			\
		ATH9K_INT_BMISS |		\
		ATH9K_INT_CST |			\
662 663
		ATH9K_INT_TSFOOR |		\
		ATH9K_INT_GENTIMER)
S
Sujith 已提交
664

S
Sujith 已提交
665
	struct ath_softc *sc = dev;
666
	struct ath_hw *ah = sc->sc_ah;
667
	struct ath_common *common = ath9k_hw_common(ah);
S
Sujith 已提交
668 669 670
	enum ath9k_int status;
	bool sched = false;

S
Sujith 已提交
671 672 673 674 675 676 677
	/*
	 * 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 已提交
678

S
Sujith 已提交
679 680 681

	/* shared irq, not for us */

682
	if (!ath9k_hw_intrpend(ah))
S
Sujith 已提交
683 684 685 686 687 688 689 690 691
		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 已提交
692
	status &= ah->imask;	/* discard unasked-for bits */
S
Sujith 已提交
693

S
Sujith 已提交
694 695 696 697
	/*
	 * If there are no status bits set, then this interrupt was not
	 * for me (should have been caught above).
	 */
698
	if (!status)
S
Sujith 已提交
699
		return IRQ_NONE;
S
Sujith 已提交
700

S
Sujith 已提交
701 702 703 704 705 706 707 708 709 710
	/* 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 已提交
711 712
	if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
	    !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
S
Sujith 已提交
713 714
		goto chip_reset;

715 716
	if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
	    (status & ATH9K_INT_BB_WATCHDOG)) {
717 718 719

		spin_lock(&common->cc_lock);
		ath_hw_cycle_counters_update(common);
720
		ar9003_hw_bb_watchdog_dbg_info(ah);
721 722
		spin_unlock(&common->cc_lock);

723 724 725
		goto chip_reset;
	}

S
Sujith 已提交
726 727 728 729 730 731
	if (status & ATH9K_INT_SWBA)
		tasklet_schedule(&sc->bcon_tasklet);

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

F
Felix Fietkau 已提交
732 733 734 735 736 737 738
	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 已提交
739
	if (status & ATH9K_INT_MIB) {
S
Sujith 已提交
740
		/*
S
Sujith 已提交
741 742 743
		 * Disable interrupts until we service the MIB
		 * interrupt; otherwise it will continue to
		 * fire.
S
Sujith 已提交
744
		 */
S
Sujith 已提交
745 746 747 748 749 750
		ath9k_hw_set_interrupts(ah, 0);
		/*
		 * Let the hal handle the event. We assume
		 * it will clear whatever condition caused
		 * the interrupt.
		 */
751
		spin_lock(&common->cc_lock);
752
		ath9k_hw_proc_mib_event(ah);
753
		spin_unlock(&common->cc_lock);
P
Pavel Roskin 已提交
754
		ath9k_hw_set_interrupts(ah, ah->imask);
S
Sujith 已提交
755
	}
S
Sujith 已提交
756

757 758
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
		if (status & ATH9K_INT_TIM_TIMER) {
S
Sujith 已提交
759 760
			/* Clear RxAbort bit so that we can
			 * receive frames */
761
			ath9k_setpower(sc, ATH9K_PM_AWAKE);
762
			ath9k_hw_setrxabort(sc->sc_ah, 0);
S
Sujith 已提交
763
			sc->ps_flags |= PS_WAIT_FOR_BEACON;
S
Sujith 已提交
764
		}
S
Sujith 已提交
765 766

chip_reset:
S
Sujith 已提交
767

768 769
	ath_debug_stat_interrupt(sc, status);

S
Sujith 已提交
770 771
	if (sched) {
		/* turn off every interrupt except SWBA */
P
Pavel Roskin 已提交
772
		ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
S
Sujith 已提交
773 774 775 776
		tasklet_schedule(&sc->intr_tq);
	}

	return IRQ_HANDLED;
S
Sujith 已提交
777 778

#undef SCHED_INTR
S
Sujith 已提交
779 780
}

781
static u32 ath_get_extchanmode(struct ath_softc *sc,
782
			       struct ieee80211_channel *chan,
S
Sujith 已提交
783
			       enum nl80211_channel_type channel_type)
784 785 786 787 788
{
	u32 chanmode = 0;

	switch (chan->band) {
	case IEEE80211_BAND_2GHZ:
S
Sujith 已提交
789 790 791
		switch(channel_type) {
		case NL80211_CHAN_NO_HT:
		case NL80211_CHAN_HT20:
792
			chanmode = CHANNEL_G_HT20;
S
Sujith 已提交
793 794
			break;
		case NL80211_CHAN_HT40PLUS:
795
			chanmode = CHANNEL_G_HT40PLUS;
S
Sujith 已提交
796 797
			break;
		case NL80211_CHAN_HT40MINUS:
798
			chanmode = CHANNEL_G_HT40MINUS;
S
Sujith 已提交
799 800
			break;
		}
801 802
		break;
	case IEEE80211_BAND_5GHZ:
S
Sujith 已提交
803 804 805
		switch(channel_type) {
		case NL80211_CHAN_NO_HT:
		case NL80211_CHAN_HT20:
806
			chanmode = CHANNEL_A_HT20;
S
Sujith 已提交
807 808
			break;
		case NL80211_CHAN_HT40PLUS:
809
			chanmode = CHANNEL_A_HT40PLUS;
S
Sujith 已提交
810 811
			break;
		case NL80211_CHAN_HT40MINUS:
812
			chanmode = CHANNEL_A_HT40MINUS;
S
Sujith 已提交
813 814
			break;
		}
815 816 817 818 819 820 821 822
		break;
	default:
		break;
	}

	return chanmode;
}

823
static void ath9k_bss_assoc_info(struct ath_softc *sc,
S
Sujith 已提交
824
				 struct ieee80211_vif *vif,
825
				 struct ieee80211_bss_conf *bss_conf)
826
{
827
	struct ath_hw *ah = sc->sc_ah;
828
	struct ath_common *common = ath9k_hw_common(ah);
829

830
	if (bss_conf->assoc) {
831 832 833
		ath_print(common, ATH_DBG_CONFIG,
			  "Bss Info ASSOC %d, bssid: %pM\n",
			   bss_conf->aid, common->curbssid);
834

835
		/* New association, store aid */
836
		common->curaid = bss_conf->aid;
837
		ath9k_hw_write_associd(ah);
838 839 840 841 842 843

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

846
		/* Configure the beacon */
847
		ath_beacon_config(sc, vif);
848

849
		/* Reset rssi stats */
850
		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
851

852
		sc->sc_flags |= SC_OP_ANI_RUN;
853
		ath_start_ani(common);
854
	} else {
855
		ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
856
		common->curaid = 0;
857
		/* Stop ANI */
858
		sc->sc_flags &= ~SC_OP_ANI_RUN;
859
		del_timer_sync(&common->ani.timer);
860
	}
861
}
862

863
void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
864
{
865
	struct ath_hw *ah = sc->sc_ah;
866
	struct ath_common *common = ath9k_hw_common(ah);
867
	struct ieee80211_channel *channel = hw->conf.channel;
868
	int r;
869

870
	ath9k_ps_wakeup(sc);
V
Vivek Natarajan 已提交
871
	ath9k_hw_configpcipowersave(ah, 0, 0);
872

873 874 875
	if (!ah->curchan)
		ah->curchan = ath_get_curchannel(sc, sc->hw);

S
Sujith 已提交
876
	spin_lock_bh(&sc->sc_resetlock);
877
	r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
878
	if (r) {
879
		ath_print(common, ATH_DBG_FATAL,
880
			  "Unable to reset channel (%u MHz), "
881 882
			  "reset status %d\n",
			  channel->center_freq, r);
883 884 885 886 887
	}
	spin_unlock_bh(&sc->sc_resetlock);

	ath_update_txpow(sc);
	if (ath_startrecv(sc) != 0) {
888 889
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to restart recv logic\n");
890 891 892 893
		return;
	}

	if (sc->sc_flags & SC_OP_BEACONS)
894
		ath_beacon_config(sc, NULL);	/* restart beacons */
895 896

	/* Re-Enable  interrupts */
P
Pavel Roskin 已提交
897
	ath9k_hw_set_interrupts(ah, ah->imask);
898 899

	/* Enable LED */
900
	ath9k_hw_cfg_output(ah, ah->led_pin,
901
			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
902
	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
903

904
	ieee80211_wake_queues(hw);
905
	ath9k_ps_restore(sc);
906 907
}

908
void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
909
{
910
	struct ath_hw *ah = sc->sc_ah;
911
	struct ieee80211_channel *channel = hw->conf.channel;
912
	int r;
913

914
	ath9k_ps_wakeup(sc);
915
	ieee80211_stop_queues(hw);
916

917 918 919 920 921 922 923 924
	/*
	 * Keep the LED on when the radio is disabled
	 * during idle unassociated state.
	 */
	if (!sc->ps_idle) {
		ath9k_hw_set_gpio(ah, ah->led_pin, 1);
		ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
	}
925 926 927 928

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

S
Sujith 已提交
929
	ath_drain_all_txq(sc, false);	/* clear pending tx frames */
930 931 932
	ath_stoprecv(sc);		/* turn off frame recv */
	ath_flushrecv(sc);		/* flush recv queue */

933
	if (!ah->curchan)
934
		ah->curchan = ath_get_curchannel(sc, hw);
935

936
	spin_lock_bh(&sc->sc_resetlock);
937
	r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
938
	if (r) {
939
		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
940
			  "Unable to reset channel (%u MHz), "
941 942
			  "reset status %d\n",
			  channel->center_freq, r);
943 944 945 946
	}
	spin_unlock_bh(&sc->sc_resetlock);

	ath9k_hw_phy_disable(ah);
V
Vivek Natarajan 已提交
947
	ath9k_hw_configpcipowersave(ah, 1, 1);
948
	ath9k_ps_restore(sc);
949
	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
950 951
}

S
Sujith 已提交
952 953
int ath_reset(struct ath_softc *sc, bool retry_tx)
{
954
	struct ath_hw *ah = sc->sc_ah;
955
	struct ath_common *common = ath9k_hw_common(ah);
956
	struct ieee80211_hw *hw = sc->hw;
957
	int r;
S
Sujith 已提交
958

S
Sujith 已提交
959 960 961
	/* Stop ANI */
	del_timer_sync(&common->ani.timer);

S
Sujith 已提交
962 963
	ieee80211_stop_queues(hw);

S
Sujith 已提交
964
	ath9k_hw_set_interrupts(ah, 0);
S
Sujith 已提交
965
	ath_drain_all_txq(sc, retry_tx);
S
Sujith 已提交
966 967 968 969
	ath_stoprecv(sc);
	ath_flushrecv(sc);

	spin_lock_bh(&sc->sc_resetlock);
970
	r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
971
	if (r)
972 973
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to reset hardware; reset status %d\n", r);
S
Sujith 已提交
974 975 976
	spin_unlock_bh(&sc->sc_resetlock);

	if (ath_startrecv(sc) != 0)
977 978
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to start recv logic\n");
S
Sujith 已提交
979 980 981 982 983 984 985 986

	/*
	 * 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.
	 */
	ath_update_txpow(sc);

987
	if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
988
		ath_beacon_config(sc, NULL);	/* restart beacons */
S
Sujith 已提交
989

P
Pavel Roskin 已提交
990
	ath9k_hw_set_interrupts(ah, ah->imask);
S
Sujith 已提交
991 992 993 994 995

	if (retry_tx) {
		int i;
		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
			if (ATH_TXQ_SETUP(sc, i)) {
S
Sujith 已提交
996 997 998
				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 已提交
999 1000 1001 1002
			}
		}
	}

S
Sujith 已提交
1003 1004
	ieee80211_wake_queues(hw);

S
Sujith 已提交
1005 1006 1007
	/* Start ANI */
	ath_start_ani(common);

1008
	return r;
S
Sujith 已提交
1009 1010
}

1011
static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
S
Sujith 已提交
1012 1013 1014 1015 1016
{
	int qnum;

	switch (queue) {
	case 0:
1017
		qnum = sc->tx.hwq_map[WME_AC_VO];
S
Sujith 已提交
1018 1019
		break;
	case 1:
1020
		qnum = sc->tx.hwq_map[WME_AC_VI];
S
Sujith 已提交
1021 1022
		break;
	case 2:
1023
		qnum = sc->tx.hwq_map[WME_AC_BE];
S
Sujith 已提交
1024 1025
		break;
	case 3:
1026
		qnum = sc->tx.hwq_map[WME_AC_BK];
S
Sujith 已提交
1027 1028
		break;
	default:
1029
		qnum = sc->tx.hwq_map[WME_AC_BE];
S
Sujith 已提交
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
		break;
	}

	return qnum;
}

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

	switch (queue) {
1041
	case WME_AC_VO:
S
Sujith 已提交
1042 1043
		qnum = 0;
		break;
1044
	case WME_AC_VI:
S
Sujith 已提交
1045 1046
		qnum = 1;
		break;
1047
	case WME_AC_BE:
S
Sujith 已提交
1048 1049
		qnum = 2;
		break;
1050
	case WME_AC_BK:
S
Sujith 已提交
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
		qnum = 3;
		break;
	default:
		qnum = -1;
		break;
	}

	return qnum;
}

1061 1062
/* XXX: Remove me once we don't depend on ath9k_channel for all
 * this redundant data */
1063 1064
void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
			   struct ath9k_channel *ichan)
1065 1066 1067 1068 1069 1070 1071 1072 1073
{
	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 已提交
1074
		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
1075 1076 1077 1078 1079
	} else {
		ichan->chanmode = CHANNEL_A;
		ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
	}

L
Luis R. Rodriguez 已提交
1080
	if (conf_is_ht(conf))
1081 1082 1083 1084
		ichan->chanmode = ath_get_extchanmode(sc, chan,
					    conf->channel_type);
}

S
Sujith 已提交
1085 1086 1087 1088
/**********************/
/* mac80211 callbacks */
/**********************/

1089
static int ath9k_start(struct ieee80211_hw *hw)
1090
{
1091 1092
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1093
	struct ath_hw *ah = sc->sc_ah;
1094
	struct ath_common *common = ath9k_hw_common(ah);
1095
	struct ieee80211_channel *curchan = hw->conf.channel;
S
Sujith 已提交
1096
	struct ath9k_channel *init_channel;
1097
	int r;
1098

1099 1100 1101
	ath_print(common, ATH_DBG_CONFIG,
		  "Starting driver with initial channel: %d MHz\n",
		  curchan->center_freq);
1102

1103 1104
	mutex_lock(&sc->mutex);

1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125
	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;

1126
	/* setup initial channel */
1127

1128
	sc->chan_idx = curchan->hw_value;
1129

1130
	init_channel = ath_get_curchannel(sc, hw);
S
Sujith 已提交
1131 1132

	/* Reset SERDES registers */
1133
	ath9k_hw_configpcipowersave(ah, 0, 0);
S
Sujith 已提交
1134 1135 1136 1137 1138 1139 1140 1141 1142

	/*
	 * 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);
1143
	r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
1144
	if (r) {
1145 1146 1147 1148
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to reset hardware; reset status %d "
			  "(freq %u MHz)\n", r,
			  curchan->center_freq);
S
Sujith 已提交
1149
		spin_unlock_bh(&sc->sc_resetlock);
1150
		goto mutex_unlock;
S
Sujith 已提交
1151 1152 1153 1154 1155 1156 1157 1158
	}
	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);
1159

S
Sujith 已提交
1160 1161 1162 1163 1164 1165 1166 1167
	/*
	 * 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) {
1168 1169
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to start recv logic\n");
1170 1171
		r = -EIO;
		goto mutex_unlock;
1172
	}
1173

S
Sujith 已提交
1174
	/* Setup our intr mask. */
F
Felix Fietkau 已提交
1175 1176 1177 1178 1179
	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)
1180 1181 1182
		ah->imask |= ATH9K_INT_RXHP |
			     ATH9K_INT_RXLP |
			     ATH9K_INT_BB_WATCHDOG;
F
Felix Fietkau 已提交
1183 1184
	else
		ah->imask |= ATH9K_INT_RX;
S
Sujith 已提交
1185

1186
	ah->imask |= ATH9K_INT_GTT;
S
Sujith 已提交
1187

1188
	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
P
Pavel Roskin 已提交
1189
		ah->imask |= ATH9K_INT_CST;
S
Sujith 已提交
1190 1191 1192 1193

	sc->sc_flags &= ~SC_OP_INVALID;

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

1197
	ieee80211_wake_queues(hw);
S
Sujith 已提交
1198

1199
	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
1200

1201 1202
	if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
	    !ah->btcoex_hw.enabled) {
1203 1204
		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
					   AR_STOMP_LOW_WLAN_WGHT);
1205
		ath9k_hw_btcoex_enable(ah);
1206

1207 1208
		if (common->bus_ops->bt_coex_prep)
			common->bus_ops->bt_coex_prep(common);
1209
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1210
			ath9k_btcoex_timer_resume(sc);
1211 1212
	}

1213 1214 1215
mutex_unlock:
	mutex_unlock(&sc->mutex);

1216
	return r;
1217 1218
}

1219 1220
static int ath9k_tx(struct ieee80211_hw *hw,
		    struct sk_buff *skb)
1221
{
S
Sujith 已提交
1222
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1223 1224
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1225
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
S
Sujith 已提交
1226
	struct ath_tx_control txctl;
1227 1228
	int padpos, padsize;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1229
	int qnum;
S
Sujith 已提交
1230

1231
	if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
1232 1233 1234
		ath_print(common, ATH_DBG_XMIT,
			  "ath9k: %s: TX in unexpected wiphy state "
			  "%d\n", wiphy_name(hw->wiphy), aphy->state);
1235 1236 1237
		goto exit;
	}

1238
	if (sc->ps_enabled) {
1239 1240 1241 1242 1243 1244 1245
		/*
		 * 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)) {
1246 1247
			ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame "
				  "while in PS mode\n");
1248 1249 1250 1251
			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
		}
	}

1252 1253 1254 1255 1256 1257 1258
	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);
1259 1260
		if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
			ath9k_hw_setrxabort(sc->sc_ah, 0);
1261
		if (ieee80211_is_pspoll(hdr->frame_control)) {
1262 1263
			ath_print(common, ATH_DBG_PS,
				  "Sending PS-Poll to pick a buffered frame\n");
S
Sujith 已提交
1264
			sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
1265
		} else {
1266 1267
			ath_print(common, ATH_DBG_PS,
				  "Wake up to complete TX\n");
S
Sujith 已提交
1268
			sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
1269 1270 1271 1272 1273 1274 1275 1276 1277
		}
		/*
		 * 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 已提交
1278
	memset(&txctl, 0, sizeof(struct ath_tx_control));
1279

1280 1281 1282 1283 1284 1285 1286
	/*
	 * 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 已提交
1287
			sc->tx.seq_no += 0x10;
1288
		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
S
Sujith 已提交
1289
		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
1290
	}
1291

1292
	/* Add the padding after the header if this is not already done */
1293 1294 1295
	padpos = ath9k_cmn_padpos(hdr->frame_control);
	padsize = padpos & 3;
	if (padsize && skb->len>padpos) {
1296 1297 1298
		if (skb_headroom(skb) < padsize)
			return -1;
		skb_push(skb, padsize);
1299
		memmove(skb->data, skb->data + padsize, padpos);
1300 1301
	}

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

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

1307
	if (ath_tx_start(hw, skb, &txctl) != 0) {
1308
		ath_print(common, ATH_DBG_XMIT, "TX failed\n");
S
Sujith 已提交
1309
		goto exit;
1310 1311
	}

S
Sujith 已提交
1312 1313 1314
	return 0;
exit:
	dev_kfree_skb_any(skb);
1315
	return 0;
1316 1317
}

1318
static void ath9k_stop(struct ieee80211_hw *hw)
1319
{
1320 1321
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1322
	struct ath_hw *ah = sc->sc_ah;
1323
	struct ath_common *common = ath9k_hw_common(ah);
1324
	int i;
1325

S
Sujith 已提交
1326 1327
	mutex_lock(&sc->mutex);

1328 1329
	aphy->state = ATH_WIPHY_INACTIVE;

1330 1331 1332
	if (led_blink)
		cancel_delayed_work_sync(&sc->ath_led_blink_work);

1333
	cancel_delayed_work_sync(&sc->tx_complete_work);
1334
	cancel_work_sync(&sc->paprd_work);
1335
	cancel_work_sync(&sc->hw_check_work);
1336

1337 1338 1339 1340 1341 1342
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i])
			break;
	}

	if (i == sc->num_sec_wiphy) {
1343 1344 1345 1346
		cancel_delayed_work_sync(&sc->wiphy_work);
		cancel_work_sync(&sc->chan_work);
	}

S
Sujith 已提交
1347
	if (sc->sc_flags & SC_OP_INVALID) {
1348
		ath_print(common, ATH_DBG_ANY, "Device not present\n");
S
Sujith 已提交
1349
		mutex_unlock(&sc->mutex);
S
Sujith 已提交
1350 1351
		return;
	}
1352

1353 1354 1355 1356 1357
	if (ath9k_wiphy_started(sc)) {
		mutex_unlock(&sc->mutex);
		return; /* another wiphy still in use */
	}

1358 1359 1360
	/* Ensure HW is awake when we try to shut it down. */
	ath9k_ps_wakeup(sc);

1361
	if (ah->btcoex_hw.enabled) {
1362
		ath9k_hw_btcoex_disable(ah);
1363
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1364
			ath9k_btcoex_timer_pause(sc);
1365 1366
	}

S
Sujith 已提交
1367 1368
	/* make sure h/w will not generate any interrupt
	 * before setting the invalid flag. */
1369
	ath9k_hw_set_interrupts(ah, 0);
S
Sujith 已提交
1370 1371

	if (!(sc->sc_flags & SC_OP_INVALID)) {
S
Sujith 已提交
1372
		ath_drain_all_txq(sc, false);
S
Sujith 已提交
1373
		ath_stoprecv(sc);
1374
		ath9k_hw_phy_disable(ah);
S
Sujith 已提交
1375
	} else
S
Sujith 已提交
1376
		sc->rx.rxlink = NULL;
S
Sujith 已提交
1377 1378

	/* disable HAL and put h/w to sleep */
1379 1380
	ath9k_hw_disable(ah);
	ath9k_hw_configpcipowersave(ah, 1, 1);
1381 1382 1383
	ath9k_ps_restore(sc);

	/* Finally, put the chip in FULL SLEEP mode */
1384
	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
S
Sujith 已提交
1385 1386

	sc->sc_flags |= SC_OP_INVALID;
1387

1388 1389
	mutex_unlock(&sc->mutex);

1390
	ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1391 1392
}

1393
static int ath9k_add_interface(struct ieee80211_hw *hw,
1394
			       struct ieee80211_vif *vif)
1395
{
1396 1397
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
P
Pavel Roskin 已提交
1398 1399
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
1400
	struct ath_vif *avp = (void *)vif->drv_priv;
1401
	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
1402
	int ret = 0;
1403

1404 1405
	mutex_lock(&sc->mutex);

1406
	switch (vif->type) {
1407
	case NL80211_IFTYPE_STATION:
1408
		ic_opmode = NL80211_IFTYPE_STATION;
1409
		break;
B
Bill Jordan 已提交
1410 1411 1412
	case NL80211_IFTYPE_WDS:
		ic_opmode = NL80211_IFTYPE_WDS;
		break;
1413 1414
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_AP:
1415
	case NL80211_IFTYPE_MESH_POINT:
1416 1417 1418 1419
		if (sc->nbcnvifs >= ATH_BCBUF) {
			ret = -ENOBUFS;
			goto out;
		}
1420
		ic_opmode = vif->type;
1421 1422
		break;
	default:
1423
		ath_print(common, ATH_DBG_FATAL,
1424
			"Interface type %d not yet supported\n", vif->type);
1425 1426
		ret = -EOPNOTSUPP;
		goto out;
1427 1428
	}

1429 1430
	ath_print(common, ATH_DBG_CONFIG,
		  "Attach a VIF of type: %d\n", ic_opmode);
1431

S
Sujith 已提交
1432
	/* Set the VIF opmode */
S
Sujith 已提交
1433 1434 1435
	avp->av_opmode = ic_opmode;
	avp->av_bslot = -1;

1436
	sc->nvifs++;
1437

1438
	ath9k_set_bssid_mask(hw, vif);
1439

1440 1441 1442
	if (sc->nvifs > 1)
		goto out; /* skip global settings for secondary vif */

S
Sujith 已提交
1443
	if (ic_opmode == NL80211_IFTYPE_AP) {
P
Pavel Roskin 已提交
1444
		ath9k_hw_set_tsfadjust(ah, 1);
S
Sujith 已提交
1445 1446
		sc->sc_flags |= SC_OP_TSF_RESET;
	}
S
Sujith 已提交
1447 1448

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

1451 1452 1453 1454
	/*
	 * Enable MIB interrupts when there are hardware phy counters.
	 * Note we only do this (at the moment) for station mode.
	 */
1455 1456 1457
	if ((vif->type == NL80211_IFTYPE_STATION) ||
	    (vif->type == NL80211_IFTYPE_ADHOC) ||
	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
1458 1459
		if (ah->config.enable_ani)
			ah->imask |= ATH9K_INT_MIB;
P
Pavel Roskin 已提交
1460
		ah->imask |= ATH9K_INT_TSFOOR;
1461 1462
	}

P
Pavel Roskin 已提交
1463
	ath9k_hw_set_interrupts(ah, ah->imask);
1464

1465 1466
	if (vif->type == NL80211_IFTYPE_AP    ||
	    vif->type == NL80211_IFTYPE_ADHOC ||
1467 1468
	    vif->type == NL80211_IFTYPE_MONITOR) {
		sc->sc_flags |= SC_OP_ANI_RUN;
1469
		ath_start_ani(common);
1470
	}
1471

1472
out:
1473
	mutex_unlock(&sc->mutex);
1474
	return ret;
1475 1476
}

1477
static void ath9k_remove_interface(struct ieee80211_hw *hw,
1478
				   struct ieee80211_vif *vif)
1479
{
1480 1481
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1482
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1483
	struct ath_vif *avp = (void *)vif->drv_priv;
1484
	int i;
1485

1486
	ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1487

1488 1489
	mutex_lock(&sc->mutex);

1490
	/* Stop ANI */
1491
	sc->sc_flags &= ~SC_OP_ANI_RUN;
1492
	del_timer_sync(&common->ani.timer);
J
Jouni Malinen 已提交
1493

1494
	/* Reclaim beacon resources */
1495 1496 1497
	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
1498
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
1499
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1500
		ath9k_ps_restore(sc);
J
Jouni Malinen 已提交
1501
	}
1502

1503
	ath_beacon_return(sc, avp);
1504
	sc->sc_flags &= ~SC_OP_BEACONS;
1505

1506
	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
1507
		if (sc->beacon.bslot[i] == vif) {
1508 1509 1510
			printk(KERN_DEBUG "%s: vif had allocated beacon "
			       "slot\n", __func__);
			sc->beacon.bslot[i] = NULL;
1511
			sc->beacon.bslot_aphy[i] = NULL;
1512 1513 1514
		}
	}

S
Sujith 已提交
1515
	sc->nvifs--;
1516 1517

	mutex_unlock(&sc->mutex);
1518 1519
}

1520
static void ath9k_enable_ps(struct ath_softc *sc)
1521
{
P
Pavel Roskin 已提交
1522 1523
	struct ath_hw *ah = sc->sc_ah;

1524
	sc->ps_enabled = true;
P
Pavel Roskin 已提交
1525 1526 1527 1528
	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);
1529
		}
1530
		ath9k_hw_setrxabort(ah, 1);
1531 1532 1533
	}
}

1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553
static void ath9k_disable_ps(struct ath_softc *sc)
{
	struct ath_hw *ah = sc->sc_ah;

	sc->ps_enabled = false;
	ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
		ath9k_hw_setrxabort(ah, 0);
		sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
				  PS_WAIT_FOR_CAB |
				  PS_WAIT_FOR_PSPOLL_DATA |
				  PS_WAIT_FOR_TX_ACK);
		if (ah->imask & ATH9K_INT_TIM_TIMER) {
			ah->imask &= ~ATH9K_INT_TIM_TIMER;
			ath9k_hw_set_interrupts(ah, ah->imask);
		}
	}

}

1554
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1555
{
1556 1557
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1558 1559
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
1560
	struct ieee80211_conf *conf = &hw->conf;
1561
	bool disable_radio;
1562

1563
	mutex_lock(&sc->mutex);
1564

1565 1566 1567 1568 1569 1570
	/*
	 * 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.
	 */
1571
	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1572 1573 1574
		bool enable_radio;
		bool all_wiphys_idle;
		bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1575 1576 1577

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

1580
		enable_radio = (!idle && all_wiphys_idle);
1581 1582 1583 1584 1585 1586 1587

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

1590
		if (enable_radio) {
1591
			sc->ps_idle = false;
1592
			ath_radio_enable(sc, hw);
1593 1594
			ath_print(common, ATH_DBG_CONFIG,
				  "not-idle: enabling radio\n");
1595 1596 1597
		}
	}

1598 1599 1600 1601 1602 1603
	/*
	 * 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.
	 */
1604
	if (changed & IEEE80211_CONF_CHANGE_PS) {
1605 1606
		unsigned long flags;
		spin_lock_irqsave(&sc->sc_pm_lock, flags);
1607 1608
		if (conf->flags & IEEE80211_CONF_PS)
			ath9k_enable_ps(sc);
1609 1610
		else
			ath9k_disable_ps(sc);
1611
		spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1612 1613
	}

S
Sujith 已提交
1614 1615 1616 1617 1618 1619 1620 1621
	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;
		}
	}

1622
	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1623
		struct ieee80211_channel *curchan = hw->conf.channel;
1624
		int pos = curchan->hw_value;
1625 1626 1627 1628 1629
		int old_pos = -1;
		unsigned long flags;

		if (ah->curchan)
			old_pos = ah->curchan - &ah->channels[0];
J
Johannes Berg 已提交
1630

1631 1632
		aphy->chan_idx = pos;
		aphy->chan_is_ht = conf_is_ht(conf);
1633 1634 1635 1636
		if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
			sc->sc_flags |= SC_OP_OFFCHANNEL;
		else
			sc->sc_flags &= ~SC_OP_OFFCHANNEL;
1637

1638 1639 1640 1641 1642 1643 1644 1645 1646 1647
		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;
		}
1648

1649 1650
		ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
			  curchan->center_freq);
1651

1652
		/* XXX: remove me eventualy */
1653
		ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
1654

1655
		ath_update_chainmask(sc, conf_is_ht(conf));
S
Sujith 已提交
1656

1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
		/* update survey stats for the old channel before switching */
		spin_lock_irqsave(&common->cc_lock, flags);
		ath_update_survey_stats(sc);
		spin_unlock_irqrestore(&common->cc_lock, flags);

		/*
		 * If the operating channel changes, change the survey in-use flags
		 * along with it.
		 * Reset the survey data for the new channel, unless we're switching
		 * back to the operating channel from an off-channel operation.
		 */
		if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
		    sc->cur_survey != &sc->survey[pos]) {

			if (sc->cur_survey)
				sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;

			sc->cur_survey = &sc->survey[pos];

			memset(sc->cur_survey, 0, sizeof(struct survey_info));
			sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
		} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
			memset(&sc->survey[pos], 0, sizeof(struct survey_info));
		}

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;
		}
1688 1689 1690 1691 1692 1693 1694 1695

		/*
		 * The most recent snapshot of channel->noisefloor for the old
		 * channel is only available after the hardware reset. Copy it to
		 * the survey stats now.
		 */
		if (old_pos >= 0)
			ath_update_survey_nf(sc, old_pos);
S
Sujith 已提交
1696
	}
1697

1698
skip_chan_change:
1699
	if (changed & IEEE80211_CONF_CHANGE_POWER) {
S
Sujith 已提交
1700
		sc->config.txpowlimit = 2 * conf->power_level;
1701 1702
		ath_update_txpow(sc);
	}
1703

1704 1705 1706 1707
	spin_lock_bh(&sc->wiphy_lock);
	disable_radio = ath9k_all_wiphys_idle(sc);
	spin_unlock_bh(&sc->wiphy_lock);

1708
	if (disable_radio) {
1709
		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
1710
		sc->ps_idle = true;
1711
		ath_radio_disable(sc, hw);
1712 1713
	}

1714
	mutex_unlock(&sc->mutex);
1715

1716 1717 1718
	return 0;
}

1719 1720 1721 1722
#define SUPPORTED_FILTERS			\
	(FIF_PROMISC_IN_BSS |			\
	FIF_ALLMULTI |				\
	FIF_CONTROL |				\
1723
	FIF_PSPOLL |				\
1724 1725
	FIF_OTHER_BSS |				\
	FIF_BCN_PRBRESP_PROMISC |		\
1726
	FIF_PROBE_REQ |				\
1727
	FIF_FCSFAIL)
1728

1729 1730 1731 1732
/* FIXME: sc->sc_full_reset ? */
static void ath9k_configure_filter(struct ieee80211_hw *hw,
				   unsigned int changed_flags,
				   unsigned int *total_flags,
1733
				   u64 multicast)
1734
{
1735 1736
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1737
	u32 rfilt;
1738

1739 1740
	changed_flags &= SUPPORTED_FILTERS;
	*total_flags &= SUPPORTED_FILTERS;
1741

S
Sujith 已提交
1742
	sc->rx.rxfilter = *total_flags;
1743
	ath9k_ps_wakeup(sc);
1744 1745
	rfilt = ath_calcrxfilter(sc);
	ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
1746
	ath9k_ps_restore(sc);
1747

1748 1749
	ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
		  "Set HW RX filter: 0x%x\n", rfilt);
1750
}
1751

1752 1753 1754
static int ath9k_sta_add(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta)
1755
{
1756 1757
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1758

1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773
	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;
1774 1775
}

1776
static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
1777
			 const struct ieee80211_tx_queue_params *params)
1778
{
1779 1780
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1781
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1782 1783
	struct ath9k_tx_queue_info qi;
	int ret = 0, qnum;
1784

1785 1786
	if (queue >= WME_NUM_AC)
		return 0;
1787

1788 1789
	mutex_lock(&sc->mutex);

1790 1791
	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));

1792 1793 1794 1795 1796
	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);
1797

1798 1799 1800 1801 1802
	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);
1803

1804 1805
	ret = ath_txq_update(sc, qnum, &qi);
	if (ret)
1806
		ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1807

1808
	if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
1809
		if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
1810 1811
			ath_beaconq_config(sc);

1812 1813
	mutex_unlock(&sc->mutex);

1814 1815
	return ret;
}
1816

1817 1818
static int ath9k_set_key(struct ieee80211_hw *hw,
			 enum set_key_cmd cmd,
1819 1820
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta,
1821 1822
			 struct ieee80211_key_conf *key)
{
1823 1824
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1825
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1826
	int ret = 0;
1827

1828 1829 1830
	if (modparam_nohwcrypt)
		return -ENOSPC;

1831
	mutex_lock(&sc->mutex);
1832
	ath9k_ps_wakeup(sc);
1833
	ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1834

1835 1836
	switch (cmd) {
	case SET_KEY:
1837
		ret = ath_key_config(common, vif, sta, key);
1838 1839
		if (ret >= 0) {
			key->hw_key_idx = ret;
1840 1841
			/* push IV and Michael MIC generation to stack */
			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1842
			if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1843
				key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1844 1845
			if (sc->sc_ah->sw_mgmt_crypto &&
			    key->cipher == WLAN_CIPHER_SUITE_CCMP)
1846
				key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1847
			ret = 0;
1848 1849 1850
		}
		break;
	case DISABLE_KEY:
1851
		ath_key_delete(common, key);
1852 1853 1854 1855
		break;
	default:
		ret = -EINVAL;
	}
1856

1857
	ath9k_ps_restore(sc);
1858 1859
	mutex_unlock(&sc->mutex);

1860 1861
	return ret;
}
1862

1863 1864 1865 1866 1867
static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_bss_conf *bss_conf,
				   u32 changed)
{
1868 1869
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1870
	struct ath_hw *ah = sc->sc_ah;
1871
	struct ath_common *common = ath9k_hw_common(ah);
1872
	struct ath_vif *avp = (void *)vif->drv_priv;
1873
	int slottime;
S
Sujith 已提交
1874
	int error;
1875

1876 1877
	mutex_lock(&sc->mutex);

S
Sujith 已提交
1878 1879 1880 1881
	if (changed & BSS_CHANGED_BSSID) {
		/* Set BSSID */
		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
		memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
1882
		common->curaid = 0;
1883
		ath9k_hw_write_associd(ah);
1884

S
Sujith 已提交
1885 1886
		/* Set aggregation protection mode parameters */
		sc->config.ath_aggr_prot = 0;
1887

S
Sujith 已提交
1888 1889 1890
		/* Only legacy IBSS for now */
		if (vif->type == NL80211_IFTYPE_ADHOC)
			ath_update_chainmask(sc, 0);
1891

S
Sujith 已提交
1892 1893 1894
		ath_print(common, ATH_DBG_CONFIG,
			  "BSSID: %pM aid: 0x%x\n",
			  common->curbssid, common->curaid);
1895

S
Sujith 已提交
1896 1897 1898
		/* need to reconfigure the beacon */
		sc->sc_flags &= ~SC_OP_BEACONS ;
	}
1899

S
Sujith 已提交
1900 1901 1902 1903 1904 1905 1906
	/* 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);
1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925
	}

	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);
		}
1926 1927
	}

S
Sujith 已提交
1928 1929 1930
	/* Disable transmission of beacons */
	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1931

S
Sujith 已提交
1932 1933 1934 1935 1936 1937 1938 1939 1940
	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);
1941 1942 1943
			error = ath_beacon_alloc(aphy, vif);
			if (!error)
				ath_beacon_config(sc, vif);
S
Sujith 已提交
1944 1945
		} else {
			ath_beacon_config(sc, vif);
1946 1947 1948
		}
	}

1949
	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1950 1951
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
			  bss_conf->use_short_preamble);
1952 1953 1954 1955 1956
		if (bss_conf->use_short_preamble)
			sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
		else
			sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
	}
1957

1958
	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1959 1960
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
			  bss_conf->use_cts_prot);
1961 1962 1963 1964 1965 1966
		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;
	}
1967

1968
	if (changed & BSS_CHANGED_ASSOC) {
1969
		ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1970
			bss_conf->assoc);
S
Sujith 已提交
1971
		ath9k_bss_assoc_info(sc, vif, bss_conf);
1972
	}
1973 1974

	mutex_unlock(&sc->mutex);
1975
}
1976

1977 1978 1979
static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
{
	u64 tsf;
1980 1981
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1982

1983 1984 1985
	mutex_lock(&sc->mutex);
	tsf = ath9k_hw_gettsf64(sc->sc_ah);
	mutex_unlock(&sc->mutex);
1986

1987 1988
	return tsf;
}
1989

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

1995 1996 1997
	mutex_lock(&sc->mutex);
	ath9k_hw_settsf64(sc->sc_ah, tsf);
	mutex_unlock(&sc->mutex);
1998 1999
}

2000 2001
static void ath9k_reset_tsf(struct ieee80211_hw *hw)
{
2002 2003
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
2004

2005
	mutex_lock(&sc->mutex);
2006 2007

	ath9k_ps_wakeup(sc);
2008
	ath9k_hw_reset_tsf(sc->sc_ah);
2009 2010
	ath9k_ps_restore(sc);

2011
	mutex_unlock(&sc->mutex);
2012
}
2013

2014
static int ath9k_ampdu_action(struct ieee80211_hw *hw,
2015
			      struct ieee80211_vif *vif,
2016 2017 2018
			      enum ieee80211_ampdu_mlme_action action,
			      struct ieee80211_sta *sta,
			      u16 tid, u16 *ssn)
2019
{
2020 2021
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
2022
	int ret = 0;
2023

2024 2025
	local_bh_disable();

2026 2027
	switch (action) {
	case IEEE80211_AMPDU_RX_START:
2028 2029
		if (!(sc->sc_flags & SC_OP_RXAGGR))
			ret = -ENOTSUPP;
2030 2031 2032 2033
		break;
	case IEEE80211_AMPDU_RX_STOP:
		break;
	case IEEE80211_AMPDU_TX_START:
2034
		ath9k_ps_wakeup(sc);
2035 2036 2037
		ret = ath_tx_aggr_start(sc, sta, tid, ssn);
		if (!ret)
			ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2038
		ath9k_ps_restore(sc);
2039 2040
		break;
	case IEEE80211_AMPDU_TX_STOP:
2041
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
2042
		ath_tx_aggr_stop(sc, sta, tid);
2043
		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2044
		ath9k_ps_restore(sc);
2045
		break;
2046
	case IEEE80211_AMPDU_TX_OPERATIONAL:
2047
		ath9k_ps_wakeup(sc);
2048
		ath_tx_aggr_resume(sc, sta, tid);
2049
		ath9k_ps_restore(sc);
2050
		break;
2051
	default:
2052 2053
		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
			  "Unknown AMPDU action\n");
2054 2055
	}

2056 2057
	local_bh_enable();

2058
	return ret;
2059 2060
}

2061 2062 2063 2064 2065
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;
2066
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2067
	struct ieee80211_supported_band *sband;
2068 2069 2070 2071 2072 2073 2074
	struct ieee80211_channel *chan;
	unsigned long flags;
	int pos;

	spin_lock_irqsave(&common->cc_lock, flags);
	if (idx == 0)
		ath_update_survey_stats(sc);
2075 2076 2077 2078 2079 2080

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

2082 2083
	if (!sband)
		sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
2084

2085 2086 2087
	if (!sband || idx >= sband->n_channels) {
		spin_unlock_irqrestore(&common->cc_lock, flags);
		return -ENOENT;
2088
	}
2089

2090 2091 2092 2093 2094 2095
	chan = &sband->channels[idx];
	pos = chan->hw_value;
	memcpy(survey, &sc->survey[pos], sizeof(*survey));
	survey->channel = chan;
	spin_unlock_irqrestore(&common->cc_lock, flags);

2096 2097 2098
	return 0;
}

2099 2100
static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
{
2101 2102
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
2103

2104
	mutex_lock(&sc->mutex);
2105 2106
	if (ath9k_wiphy_scanning(sc)) {
		/*
2107 2108 2109 2110 2111
		 * There is a race here in mac80211 but fixing it requires
		 * we revisit how we handle the scan complete callback.
		 * After mac80211 fixes we will not have configured hardware
		 * to the home channel nor would we have configured the RX
		 * filter yet.
2112
		 */
2113
		mutex_unlock(&sc->mutex);
2114 2115 2116 2117 2118
		return;
	}

	aphy->state = ATH_WIPHY_SCAN;
	ath9k_wiphy_pause_all_forced(sc, aphy);
2119
	mutex_unlock(&sc->mutex);
2120 2121
}

2122 2123 2124 2125
/*
 * XXX: this requires a revisit after the driver
 * scan_complete gets moved to another place/removed in mac80211.
 */
2126 2127
static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
{
2128 2129
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
2130

2131
	mutex_lock(&sc->mutex);
2132
	aphy->state = ATH_WIPHY_ACTIVE;
2133
	mutex_unlock(&sc->mutex);
2134 2135
}

2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147
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);
}

2148
struct ieee80211_ops ath9k_ops = {
2149 2150 2151 2152 2153 2154 2155
	.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,
2156 2157
	.sta_add	    = ath9k_sta_add,
	.sta_remove	    = ath9k_sta_remove,
2158 2159 2160 2161
	.conf_tx 	    = ath9k_conf_tx,
	.bss_info_changed   = ath9k_bss_info_changed,
	.set_key            = ath9k_set_key,
	.get_tsf 	    = ath9k_get_tsf,
2162
	.set_tsf 	    = ath9k_set_tsf,
2163
	.reset_tsf 	    = ath9k_reset_tsf,
2164
	.ampdu_action       = ath9k_ampdu_action,
2165
	.get_survey	    = ath9k_get_survey,
2166 2167
	.sw_scan_start      = ath9k_sw_scan_start,
	.sw_scan_complete   = ath9k_sw_scan_complete,
J
Johannes Berg 已提交
2168
	.rfkill_poll        = ath9k_rfkill_poll_state,
2169
	.set_coverage_class = ath9k_set_coverage_class,
2170
};