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

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

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
	if (sc->curtxpow != sc->config.txpowlimit) {
26
		ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
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
	unsigned long flags;
96
	enum ath9k_power_mode power_mode;
97 98 99 100 101

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

102
	power_mode = sc->sc_ah->power_mode;
103
	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
104

105 106 107 108 109
	/*
	 * 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.
	 */
110 111 112 113 114 115
	if (power_mode != ATH9K_PM_AWAKE) {
		spin_lock(&common->cc_lock);
		ath_hw_cycle_counters_update(common);
		memset(&common->cc_survey, 0, sizeof(common->cc_survey));
		spin_unlock(&common->cc_lock);
	}
116

117 118 119 120 121 122
 unlock:
	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}

void ath9k_ps_restore(struct ath_softc *sc)
{
123
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
124 125 126 127 128 129
	unsigned long flags;

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

130 131 132 133
	spin_lock(&common->cc_lock);
	ath_hw_cycle_counters_update(common);
	spin_unlock(&common->cc_lock);

134 135 136 137
	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 已提交
138 139 140
			      PS_WAIT_FOR_CAB |
			      PS_WAIT_FOR_PSPOLL_DATA |
			      PS_WAIT_FOR_TX_ACK)))
141
		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
142 143 144 145 146

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

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
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));
}

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
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;

189 190 191
	if (!ah->curchan)
		return;

192 193
	if (ah->power_mode == ATH9K_PM_AWAKE)
		ath_hw_cycle_counters_update(common);
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209

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

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

230 231 232 233 234
	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);

235 236
	ath9k_ps_wakeup(sc);

237 238
	spin_lock_bh(&sc->sc_pcu_lock);

239 240 241 242 243 244 245 246 247
	/*
	 * 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.
	 */
248
	ath9k_hw_disable_interrupts(ah);
S
Sujith 已提交
249
	ath_drain_all_txq(sc, false);
250

251
	stopped = ath_stoprecv(sc);
S
Sujith 已提交
252

253 254 255
	/* XXX: do not flush receive queue here. We don't want
	 * to flush data frames already in queue because of
	 * changing channel. */
S
Sujith 已提交
256

257
	if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
258 259
		fastcc = false;

260 261 262
	if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
		caldata = &aphy->caldata;

J
Joe Perches 已提交
263 264 265 266 267
	ath_dbg(common, ATH_DBG_CONFIG,
		"(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
		sc->sc_ah->curchan->channel,
		channel->center_freq, conf_is_ht40(conf),
		fastcc);
S
Sujith 已提交
268

269
	r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
270
	if (r) {
271 272 273
		ath_err(common,
			"Unable to reset channel (%u MHz), reset status %d\n",
			channel->center_freq, r);
274
		goto ps_restore;
S
Sujith 已提交
275
	}
276 277

	if (ath_startrecv(sc) != 0) {
278
		ath_err(common, "Unable to restart recv logic\n");
279 280
		r = -EIO;
		goto ps_restore;
281 282 283
	}

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

286 287
	if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
		ath_beacon_config(sc, NULL);
288
		ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
289
		ath_start_ani(common);
290 291
	}

292
 ps_restore:
293 294
	spin_unlock_bh(&sc->sc_pcu_lock);

295
	ath9k_ps_restore(sc);
296
	return r;
S
Sujith 已提交
297 298
}

299 300 301
static void ath_paprd_activate(struct ath_softc *sc)
{
	struct ath_hw *ah = sc->sc_ah;
302
	struct ath9k_hw_cal_data *caldata = ah->caldata;
303
	struct ath_common *common = ath9k_hw_common(ah);
304 305
	int chain;

306
	if (!caldata || !caldata->paprd_done)
307 308 309
		return;

	ath9k_ps_wakeup(sc);
310
	ar9003_paprd_enable(ah, false);
311
	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
312
		if (!(common->tx_chainmask & BIT(chain)))
313 314
			continue;

315
		ar9003_paprd_populate_single_table(ah, caldata, chain);
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
	}

	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;
333
	struct ath9k_hw_cal_data *caldata = ah->caldata;
334
	struct ath_common *common = ath9k_hw_common(ah);
335
	int ftype;
336 337 338 339 340 341
	int chain_ok = 0;
	int chain;
	int len = 1800;
	int time_left;
	int i;

342 343 344
	if (!caldata)
		return;

345 346 347 348 349 350 351 352 353 354 355
	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);
356
	hdr->duration_id = cpu_to_le16(10);
357 358 359 360 361
	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));
362
	txctl.txq = sc->tx.txq_map[WME_AC_BE];
363

364
	ath9k_ps_wakeup(sc);
365 366
	ar9003_paprd_init_table(ah);
	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
367
		if (!(common->tx_chainmask & BIT(chain)))
368 369 370 371 372 373 374 375 376 377 378 379
			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);
380
		sc->paprd_pending = true;
381 382 383 384 385 386
		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,
387
				msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
388
		sc->paprd_pending = false;
389
		if (!time_left) {
J
Joe Perches 已提交
390 391 392
			ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
				"Timeout waiting for paprd training on TX chain %d\n",
				chain);
393
			goto fail_paprd;
394 395 396 397 398
		}

		if (!ar9003_paprd_is_done(ah))
			break;

399
		if (ar9003_paprd_create_curve(ah, caldata, chain) != 0)
400 401 402 403 404 405 406
			break;

		chain_ok = 1;
	}
	kfree_skb(skb);

	if (chain_ok) {
407
		caldata->paprd_done = true;
408 409 410
		ath_paprd_activate(sc);
	}

411
fail_paprd:
412 413 414
	ath9k_ps_restore(sc);
}

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

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

439 440
	short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
		ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
S
Sujith 已提交
441

442 443 444 445 446 447
	/* Only calibrate if awake */
	if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
		goto set_timer;

	ath9k_ps_wakeup(sc);

S
Sujith 已提交
448
	/* Long calibration runs independently of short calibration. */
449
	if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
S
Sujith 已提交
450
		longcal = true;
J
Joe Perches 已提交
451
		ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
452
		common->ani.longcal_timer = timestamp;
S
Sujith 已提交
453 454
	}

S
Sujith 已提交
455
	/* Short calibration applies only while caldone is false */
456 457
	if (!common->ani.caldone) {
		if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
S
Sujith 已提交
458
			shortcal = true;
J
Joe Perches 已提交
459 460
			ath_dbg(common, ATH_DBG_ANI,
				"shortcal @%lu\n", jiffies);
461 462
			common->ani.shortcal_timer = timestamp;
			common->ani.resetcal_timer = timestamp;
S
Sujith 已提交
463 464
		}
	} else {
465
		if ((timestamp - common->ani.resetcal_timer) >=
S
Sujith 已提交
466
		    ATH_RESTART_CALINTERVAL) {
467 468 469
			common->ani.caldone = ath9k_hw_reset_calvalid(ah);
			if (common->ani.caldone)
				common->ani.resetcal_timer = timestamp;
S
Sujith 已提交
470 471 472 473
		}
	}

	/* Verify whether we must check ANI */
474 475
	if ((timestamp - common->ani.checkani_timer) >=
	     ah->config.ani_poll_interval) {
S
Sujith 已提交
476
		aniflag = true;
477
		common->ani.checkani_timer = timestamp;
S
Sujith 已提交
478 479 480 481 482
	}

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

		/* Perform calibration if necessary */
		if (longcal || shortcal) {
492
			common->ani.caldone =
493 494 495 496
				ath9k_hw_calibrate(ah,
						   ah->curchan,
						   common->rx_chainmask,
						   longcal);
S
Sujith 已提交
497 498 499
		}
	}

500 501
	ath9k_ps_restore(sc);

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

515
	mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
516 517
	if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
		if (!ah->caldata->paprd_done)
518 519 520 521
			ieee80211_queue_work(sc->hw, &sc->paprd_work);
		else
			ath_paprd_activate(sc);
	}
S
Sujith 已提交
522 523 524 525 526
}

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

535
	if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
536
	    (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
537 538
		common->tx_chainmask = ah->caps.tx_chainmask;
		common->rx_chainmask = ah->caps.rx_chainmask;
S
Sujith 已提交
539
	} else {
540 541
		common->tx_chainmask = 1;
		common->rx_chainmask = 1;
S
Sujith 已提交
542 543
	}

J
Joe Perches 已提交
544 545 546 547
	ath_dbg(common, ATH_DBG_CONFIG,
		"tx chmask: %d, rx chmask: %d\n",
		common->tx_chainmask,
		common->rx_chainmask);
S
Sujith 已提交
548 549 550 551 552
}

static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
{
	struct ath_node *an;
553
	struct ath_hw *ah = sc->sc_ah;
S
Sujith 已提交
554 555
	an = (struct ath_node *)sta->drv_priv;

556 557 558
	if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM)
		sc->sc_flags |= SC_OP_ENABLE_APM;

559
	if (sc->sc_flags & SC_OP_TXAGGR) {
S
Sujith 已提交
560
		ath_tx_node_init(sc, an);
S
Sujith 已提交
561
		an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
562 563 564
				     sta->ht_cap.ampdu_factor);
		an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
	}
S
Sujith 已提交
565 566 567 568 569 570 571 572 573 574
}

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

575 576 577 578 579 580 581 582 583 584 585 586 587
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);
	}
588
	ath_reset(sc, true);
589 590 591 592 593

out:
	ath9k_ps_restore(sc);
}

S
Sujith 已提交
594
void ath9k_tasklet(unsigned long data)
S
Sujith 已提交
595 596
{
	struct ath_softc *sc = (struct ath_softc *)data;
597
	struct ath_hw *ah = sc->sc_ah;
598
	struct ath_common *common = ath9k_hw_common(ah);
599

S
Sujith 已提交
600
	u32 status = sc->intrstatus;
F
Felix Fietkau 已提交
601
	u32 rxmask;
S
Sujith 已提交
602

603 604
	ath9k_ps_wakeup(sc);

605
	if (status & ATH9K_INT_FATAL) {
606
		ath_reset(sc, true);
607
		ath9k_ps_restore(sc);
S
Sujith 已提交
608
		return;
S
Sujith 已提交
609
	}
S
Sujith 已提交
610

611 612
	spin_lock_bh(&sc->sc_pcu_lock);

613 614 615
	if (!ath9k_hw_check_alive(ah))
		ieee80211_queue_work(sc->hw, &sc->hw_check_work);

F
Felix Fietkau 已提交
616 617 618 619 620 621 622 623 624 625 626 627 628
	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
		rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
			  ATH9K_INT_RXORN);
	else
		rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);

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

		ath_rx_tasklet(sc, 0, false);
S
Sujith 已提交
629 630
	}

631 632 633 634 635 636
	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 已提交
637

638
	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
639 640 641 642
		/*
		 * TSF sync does not look correct; remain awake to sync with
		 * the next Beacon.
		 */
J
Joe Perches 已提交
643 644
		ath_dbg(common, ATH_DBG_PS,
			"TSFOOR - Sync with next Beacon\n");
S
Sujith 已提交
645
		sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
646 647
	}

648
	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
649 650 651
		if (status & ATH9K_INT_GENTIMER)
			ath_gen_timer_isr(sc->sc_ah);

S
Sujith 已提交
652
	/* re-enable hardware interrupt */
653
	ath9k_hw_enable_interrupts(ah);
654 655

	spin_unlock_bh(&sc->sc_pcu_lock);
656
	ath9k_ps_restore(sc);
S
Sujith 已提交
657 658
}

659
irqreturn_t ath_isr(int irq, void *dev)
S
Sujith 已提交
660
{
S
Sujith 已提交
661 662 663 664 665
#define SCHED_INTR (				\
		ATH9K_INT_FATAL |		\
		ATH9K_INT_RXORN |		\
		ATH9K_INT_RXEOL |		\
		ATH9K_INT_RX |			\
F
Felix Fietkau 已提交
666 667
		ATH9K_INT_RXLP |		\
		ATH9K_INT_RXHP |		\
S
Sujith 已提交
668 669 670
		ATH9K_INT_TX |			\
		ATH9K_INT_BMISS |		\
		ATH9K_INT_CST |			\
671 672
		ATH9K_INT_TSFOOR |		\
		ATH9K_INT_GENTIMER)
S
Sujith 已提交
673

S
Sujith 已提交
674
	struct ath_softc *sc = dev;
675
	struct ath_hw *ah = sc->sc_ah;
676
	struct ath_common *common = ath9k_hw_common(ah);
S
Sujith 已提交
677 678 679
	enum ath9k_int status;
	bool sched = false;

S
Sujith 已提交
680 681 682 683 684 685 686
	/*
	 * 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 已提交
687

S
Sujith 已提交
688 689 690

	/* shared irq, not for us */

691
	if (!ath9k_hw_intrpend(ah))
S
Sujith 已提交
692 693 694 695 696 697 698 699 700
		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 已提交
701
	status &= ah->imask;	/* discard unasked-for bits */
S
Sujith 已提交
702

S
Sujith 已提交
703 704 705 706
	/*
	 * If there are no status bits set, then this interrupt was not
	 * for me (should have been caught above).
	 */
707
	if (!status)
S
Sujith 已提交
708
		return IRQ_NONE;
S
Sujith 已提交
709

S
Sujith 已提交
710 711 712 713 714 715 716 717 718 719
	/* 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 已提交
720 721
	if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
	    !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
S
Sujith 已提交
722 723
		goto chip_reset;

724 725
	if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
	    (status & ATH9K_INT_BB_WATCHDOG)) {
726 727 728

		spin_lock(&common->cc_lock);
		ath_hw_cycle_counters_update(common);
729
		ar9003_hw_bb_watchdog_dbg_info(ah);
730 731
		spin_unlock(&common->cc_lock);

732 733 734
		goto chip_reset;
	}

S
Sujith 已提交
735 736 737 738 739 740
	if (status & ATH9K_INT_SWBA)
		tasklet_schedule(&sc->bcon_tasklet);

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

F
Felix Fietkau 已提交
741 742 743 744 745 746 747
	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 已提交
748
	if (status & ATH9K_INT_MIB) {
S
Sujith 已提交
749
		/*
S
Sujith 已提交
750 751 752
		 * Disable interrupts until we service the MIB
		 * interrupt; otherwise it will continue to
		 * fire.
S
Sujith 已提交
753
		 */
754
		ath9k_hw_disable_interrupts(ah);
S
Sujith 已提交
755 756 757 758 759
		/*
		 * Let the hal handle the event. We assume
		 * it will clear whatever condition caused
		 * the interrupt.
		 */
760
		spin_lock(&common->cc_lock);
761
		ath9k_hw_proc_mib_event(ah);
762
		spin_unlock(&common->cc_lock);
763
		ath9k_hw_enable_interrupts(ah);
S
Sujith 已提交
764
	}
S
Sujith 已提交
765

766 767
	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
		if (status & ATH9K_INT_TIM_TIMER) {
768 769
			if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle))
				goto chip_reset;
S
Sujith 已提交
770 771
			/* Clear RxAbort bit so that we can
			 * receive frames */
772
			ath9k_setpower(sc, ATH9K_PM_AWAKE);
773
			ath9k_hw_setrxabort(sc->sc_ah, 0);
S
Sujith 已提交
774
			sc->ps_flags |= PS_WAIT_FOR_BEACON;
S
Sujith 已提交
775
		}
S
Sujith 已提交
776 777

chip_reset:
S
Sujith 已提交
778

779 780
	ath_debug_stat_interrupt(sc, status);

S
Sujith 已提交
781
	if (sched) {
782 783
		/* turn off every interrupt */
		ath9k_hw_disable_interrupts(ah);
S
Sujith 已提交
784 785 786 787
		tasklet_schedule(&sc->intr_tq);
	}

	return IRQ_HANDLED;
S
Sujith 已提交
788 789

#undef SCHED_INTR
S
Sujith 已提交
790 791
}

792
static u32 ath_get_extchanmode(struct ath_softc *sc,
793
			       struct ieee80211_channel *chan,
S
Sujith 已提交
794
			       enum nl80211_channel_type channel_type)
795 796 797 798 799
{
	u32 chanmode = 0;

	switch (chan->band) {
	case IEEE80211_BAND_2GHZ:
S
Sujith 已提交
800 801 802
		switch(channel_type) {
		case NL80211_CHAN_NO_HT:
		case NL80211_CHAN_HT20:
803
			chanmode = CHANNEL_G_HT20;
S
Sujith 已提交
804 805
			break;
		case NL80211_CHAN_HT40PLUS:
806
			chanmode = CHANNEL_G_HT40PLUS;
S
Sujith 已提交
807 808
			break;
		case NL80211_CHAN_HT40MINUS:
809
			chanmode = CHANNEL_G_HT40MINUS;
S
Sujith 已提交
810 811
			break;
		}
812 813
		break;
	case IEEE80211_BAND_5GHZ:
S
Sujith 已提交
814 815 816
		switch(channel_type) {
		case NL80211_CHAN_NO_HT:
		case NL80211_CHAN_HT20:
817
			chanmode = CHANNEL_A_HT20;
S
Sujith 已提交
818 819
			break;
		case NL80211_CHAN_HT40PLUS:
820
			chanmode = CHANNEL_A_HT40PLUS;
S
Sujith 已提交
821 822
			break;
		case NL80211_CHAN_HT40MINUS:
823
			chanmode = CHANNEL_A_HT40MINUS;
S
Sujith 已提交
824 825
			break;
		}
826 827 828 829 830 831 832 833
		break;
	default:
		break;
	}

	return chanmode;
}

834
static void ath9k_bss_assoc_info(struct ath_softc *sc,
835
				 struct ieee80211_hw *hw,
S
Sujith 已提交
836
				 struct ieee80211_vif *vif,
837
				 struct ieee80211_bss_conf *bss_conf)
838
{
839
	struct ath_wiphy *aphy = hw->priv;
840
	struct ath_hw *ah = sc->sc_ah;
841
	struct ath_common *common = ath9k_hw_common(ah);
842

843
	if (bss_conf->assoc) {
J
Joe Perches 已提交
844 845 846
		ath_dbg(common, ATH_DBG_CONFIG,
			"Bss Info ASSOC %d, bssid: %pM\n",
			bss_conf->aid, common->curbssid);
847

848
		/* New association, store aid */
849
		common->curaid = bss_conf->aid;
850
		ath9k_hw_write_associd(ah);
851 852 853 854 855 856

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

859
		/* Configure the beacon */
860
		ath_beacon_config(sc, vif);
861

862
		/* Reset rssi stats */
863
		aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
864
		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
865

866
		sc->sc_flags |= SC_OP_ANI_RUN;
867
		ath_start_ani(common);
868
	} else {
J
Joe Perches 已提交
869
		ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
870
		common->curaid = 0;
871
		/* Stop ANI */
872
		sc->sc_flags &= ~SC_OP_ANI_RUN;
873
		del_timer_sync(&common->ani.timer);
874
	}
875
}
876

877
void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
878
{
879
	struct ath_hw *ah = sc->sc_ah;
880
	struct ath_common *common = ath9k_hw_common(ah);
881
	struct ieee80211_channel *channel = hw->conf.channel;
882
	int r;
883

884
	ath9k_ps_wakeup(sc);
885 886
	spin_lock_bh(&sc->sc_pcu_lock);

V
Vivek Natarajan 已提交
887
	ath9k_hw_configpcipowersave(ah, 0, 0);
888

889 890 891
	if (!ah->curchan)
		ah->curchan = ath_get_curchannel(sc, sc->hw);

892
	r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
893
	if (r) {
894 895 896
		ath_err(common,
			"Unable to reset channel (%u MHz), reset status %d\n",
			channel->center_freq, r);
897 898 899 900
	}

	ath_update_txpow(sc);
	if (ath_startrecv(sc) != 0) {
901
		ath_err(common, "Unable to restart recv logic\n");
902
		spin_unlock_bh(&sc->sc_pcu_lock);
903 904 905
		return;
	}
	if (sc->sc_flags & SC_OP_BEACONS)
906
		ath_beacon_config(sc, NULL);	/* restart beacons */
907 908

	/* Re-Enable  interrupts */
P
Pavel Roskin 已提交
909
	ath9k_hw_set_interrupts(ah, ah->imask);
910 911

	/* Enable LED */
912
	ath9k_hw_cfg_output(ah, ah->led_pin,
913
			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
914
	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
915

916
	ieee80211_wake_queues(hw);
917 918
	spin_unlock_bh(&sc->sc_pcu_lock);

919
	ath9k_ps_restore(sc);
920 921
}

922
void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
923
{
924
	struct ath_hw *ah = sc->sc_ah;
925
	struct ieee80211_channel *channel = hw->conf.channel;
926
	int r;
927

928
	ath9k_ps_wakeup(sc);
929 930
	spin_lock_bh(&sc->sc_pcu_lock);

931
	ieee80211_stop_queues(hw);
932

933 934 935 936 937 938 939 940
	/*
	 * 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);
	}
941 942

	/* Disable interrupts */
943
	ath9k_hw_disable_interrupts(ah);
944

S
Sujith 已提交
945
	ath_drain_all_txq(sc, false);	/* clear pending tx frames */
946

947 948 949
	ath_stoprecv(sc);		/* turn off frame recv */
	ath_flushrecv(sc);		/* flush recv queue */

950
	if (!ah->curchan)
951
		ah->curchan = ath_get_curchannel(sc, hw);
952

953
	r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
954
	if (r) {
955 956 957
		ath_err(ath9k_hw_common(sc->sc_ah),
			"Unable to reset channel (%u MHz), reset status %d\n",
			channel->center_freq, r);
958 959 960
	}

	ath9k_hw_phy_disable(ah);
961

V
Vivek Natarajan 已提交
962
	ath9k_hw_configpcipowersave(ah, 1, 1);
963 964

	spin_unlock_bh(&sc->sc_pcu_lock);
965
	ath9k_ps_restore(sc);
966

967
	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
968 969
}

S
Sujith 已提交
970 971
int ath_reset(struct ath_softc *sc, bool retry_tx)
{
972
	struct ath_hw *ah = sc->sc_ah;
973
	struct ath_common *common = ath9k_hw_common(ah);
974
	struct ieee80211_hw *hw = sc->hw;
975
	int r;
S
Sujith 已提交
976

S
Sujith 已提交
977 978 979
	/* Stop ANI */
	del_timer_sync(&common->ani.timer);

980 981
	spin_lock_bh(&sc->sc_pcu_lock);

S
Sujith 已提交
982 983
	ieee80211_stop_queues(hw);

984
	ath9k_hw_disable_interrupts(ah);
S
Sujith 已提交
985
	ath_drain_all_txq(sc, retry_tx);
986

S
Sujith 已提交
987 988 989
	ath_stoprecv(sc);
	ath_flushrecv(sc);

990
	r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
991
	if (r)
992 993
		ath_err(common,
			"Unable to reset hardware; reset status %d\n", r);
S
Sujith 已提交
994 995

	if (ath_startrecv(sc) != 0)
996
		ath_err(common, "Unable to start recv logic\n");
S
Sujith 已提交
997 998 999 1000 1001 1002 1003 1004

	/*
	 * 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);

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

P
Pavel Roskin 已提交
1008
	ath9k_hw_set_interrupts(ah, ah->imask);
S
Sujith 已提交
1009 1010 1011 1012 1013

	if (retry_tx) {
		int i;
		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
			if (ATH_TXQ_SETUP(sc, i)) {
S
Sujith 已提交
1014 1015 1016
				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 已提交
1017 1018 1019 1020
			}
		}
	}

S
Sujith 已提交
1021
	ieee80211_wake_queues(hw);
1022
	spin_unlock_bh(&sc->sc_pcu_lock);
S
Sujith 已提交
1023

S
Sujith 已提交
1024 1025 1026
	/* Start ANI */
	ath_start_ani(common);

1027
	return r;
S
Sujith 已提交
1028 1029
}

1030 1031
/* XXX: Remove me once we don't depend on ath9k_channel for all
 * this redundant data */
1032 1033
void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
			   struct ath9k_channel *ichan)
1034 1035 1036 1037 1038 1039 1040 1041 1042
{
	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 已提交
1043
		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
1044 1045 1046 1047 1048
	} else {
		ichan->chanmode = CHANNEL_A;
		ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
	}

L
Luis R. Rodriguez 已提交
1049
	if (conf_is_ht(conf))
1050 1051 1052 1053
		ichan->chanmode = ath_get_extchanmode(sc, chan,
					    conf->channel_type);
}

S
Sujith 已提交
1054 1055 1056 1057
/**********************/
/* mac80211 callbacks */
/**********************/

1058
static int ath9k_start(struct ieee80211_hw *hw)
1059
{
1060 1061
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1062
	struct ath_hw *ah = sc->sc_ah;
1063
	struct ath_common *common = ath9k_hw_common(ah);
1064
	struct ieee80211_channel *curchan = hw->conf.channel;
S
Sujith 已提交
1065
	struct ath9k_channel *init_channel;
1066
	int r;
1067

J
Joe Perches 已提交
1068 1069 1070
	ath_dbg(common, ATH_DBG_CONFIG,
		"Starting driver with initial channel: %d MHz\n",
		curchan->center_freq);
1071

1072 1073
	mutex_lock(&sc->mutex);

1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
	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;

1095
	/* setup initial channel */
1096

1097
	sc->chan_idx = curchan->hw_value;
1098

1099
	init_channel = ath_get_curchannel(sc, hw);
S
Sujith 已提交
1100 1101

	/* Reset SERDES registers */
1102
	ath9k_hw_configpcipowersave(ah, 0, 0);
S
Sujith 已提交
1103 1104 1105 1106 1107 1108 1109 1110

	/*
	 * 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.
	 */
1111
	spin_lock_bh(&sc->sc_pcu_lock);
1112
	r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
1113
	if (r) {
1114 1115 1116
		ath_err(common,
			"Unable to reset hardware; reset status %d (freq %u MHz)\n",
			r, curchan->center_freq);
1117
		spin_unlock_bh(&sc->sc_pcu_lock);
1118
		goto mutex_unlock;
S
Sujith 已提交
1119 1120 1121 1122 1123 1124 1125
	}

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

S
Sujith 已提交
1127 1128 1129 1130 1131 1132 1133 1134
	/*
	 * 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) {
1135
		ath_err(common, "Unable to start recv logic\n");
1136
		r = -EIO;
1137
		spin_unlock_bh(&sc->sc_pcu_lock);
1138
		goto mutex_unlock;
1139
	}
1140
	spin_unlock_bh(&sc->sc_pcu_lock);
1141

S
Sujith 已提交
1142
	/* Setup our intr mask. */
F
Felix Fietkau 已提交
1143 1144 1145 1146 1147
	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)
1148 1149 1150
		ah->imask |= ATH9K_INT_RXHP |
			     ATH9K_INT_RXLP |
			     ATH9K_INT_BB_WATCHDOG;
F
Felix Fietkau 已提交
1151 1152
	else
		ah->imask |= ATH9K_INT_RX;
S
Sujith 已提交
1153

1154
	ah->imask |= ATH9K_INT_GTT;
S
Sujith 已提交
1155

1156
	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
P
Pavel Roskin 已提交
1157
		ah->imask |= ATH9K_INT_CST;
S
Sujith 已提交
1158 1159

	sc->sc_flags &= ~SC_OP_INVALID;
1160
	sc->sc_ah->is_monitoring = false;
S
Sujith 已提交
1161 1162

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

1166
	ieee80211_wake_queues(hw);
S
Sujith 已提交
1167

1168
	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
1169

1170 1171
	if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
	    !ah->btcoex_hw.enabled) {
1172 1173
		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
					   AR_STOMP_LOW_WLAN_WGHT);
1174
		ath9k_hw_btcoex_enable(ah);
1175

1176 1177
		if (common->bus_ops->bt_coex_prep)
			common->bus_ops->bt_coex_prep(common);
1178
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1179
			ath9k_btcoex_timer_resume(sc);
1180 1181
	}

1182
	pm_qos_update_request(&sc->pm_qos_req, 55);
1183

1184 1185 1186
	if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
		common->bus_ops->extn_synch_en(common);

1187 1188 1189
mutex_unlock:
	mutex_unlock(&sc->mutex);

1190
	return r;
1191 1192
}

1193 1194
static int ath9k_tx(struct ieee80211_hw *hw,
		    struct sk_buff *skb)
1195
{
1196 1197
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1198
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
S
Sujith 已提交
1199
	struct ath_tx_control txctl;
1200
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
S
Sujith 已提交
1201

1202
	if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
J
Joe Perches 已提交
1203 1204 1205
		ath_dbg(common, ATH_DBG_XMIT,
			"ath9k: %s: TX in unexpected wiphy state %d\n",
			wiphy_name(hw->wiphy), aphy->state);
1206 1207 1208
		goto exit;
	}

1209
	if (sc->ps_enabled) {
1210 1211 1212 1213 1214 1215 1216
		/*
		 * 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)) {
J
Joe Perches 已提交
1217 1218
			ath_dbg(common, ATH_DBG_PS,
				"Add PM=1 for a TX frame while in PS mode\n");
1219 1220 1221 1222
			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
		}
	}

1223 1224 1225 1226 1227 1228 1229
	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);
1230 1231
		if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
			ath9k_hw_setrxabort(sc->sc_ah, 0);
1232
		if (ieee80211_is_pspoll(hdr->frame_control)) {
J
Joe Perches 已提交
1233 1234
			ath_dbg(common, ATH_DBG_PS,
				"Sending PS-Poll to pick a buffered frame\n");
S
Sujith 已提交
1235
			sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
1236
		} else {
J
Joe Perches 已提交
1237 1238
			ath_dbg(common, ATH_DBG_PS,
				"Wake up to complete TX\n");
S
Sujith 已提交
1239
			sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
1240 1241 1242 1243 1244 1245 1246 1247 1248
		}
		/*
		 * 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 已提交
1249
	memset(&txctl, 0, sizeof(struct ath_tx_control));
1250
	txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
S
Sujith 已提交
1251

J
Joe Perches 已提交
1252
	ath_dbg(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
1253

1254
	if (ath_tx_start(hw, skb, &txctl) != 0) {
J
Joe Perches 已提交
1255
		ath_dbg(common, ATH_DBG_XMIT, "TX failed\n");
S
Sujith 已提交
1256
		goto exit;
1257 1258
	}

S
Sujith 已提交
1259 1260 1261
	return 0;
exit:
	dev_kfree_skb_any(skb);
1262
	return 0;
1263 1264
}

1265
static void ath9k_stop(struct ieee80211_hw *hw)
1266
{
1267 1268
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1269
	struct ath_hw *ah = sc->sc_ah;
1270
	struct ath_common *common = ath9k_hw_common(ah);
1271
	int i;
1272

S
Sujith 已提交
1273 1274
	mutex_lock(&sc->mutex);

1275 1276
	aphy->state = ATH_WIPHY_INACTIVE;

1277 1278 1279
	if (led_blink)
		cancel_delayed_work_sync(&sc->ath_led_blink_work);

1280
	cancel_delayed_work_sync(&sc->tx_complete_work);
1281
	cancel_work_sync(&sc->paprd_work);
1282
	cancel_work_sync(&sc->hw_check_work);
1283

1284 1285 1286 1287 1288 1289
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i])
			break;
	}

	if (i == sc->num_sec_wiphy) {
1290 1291 1292 1293
		cancel_delayed_work_sync(&sc->wiphy_work);
		cancel_work_sync(&sc->chan_work);
	}

S
Sujith 已提交
1294
	if (sc->sc_flags & SC_OP_INVALID) {
J
Joe Perches 已提交
1295
		ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
S
Sujith 已提交
1296
		mutex_unlock(&sc->mutex);
S
Sujith 已提交
1297 1298
		return;
	}
1299

1300 1301 1302 1303 1304
	if (ath9k_wiphy_started(sc)) {
		mutex_unlock(&sc->mutex);
		return; /* another wiphy still in use */
	}

1305 1306 1307
	/* Ensure HW is awake when we try to shut it down. */
	ath9k_ps_wakeup(sc);

1308
	if (ah->btcoex_hw.enabled) {
1309
		ath9k_hw_btcoex_disable(ah);
1310
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1311
			ath9k_btcoex_timer_pause(sc);
1312 1313
	}

1314 1315
	spin_lock_bh(&sc->sc_pcu_lock);

S
Sujith 已提交
1316 1317
	/* make sure h/w will not generate any interrupt
	 * before setting the invalid flag. */
1318
	ath9k_hw_disable_interrupts(ah);
S
Sujith 已提交
1319 1320

	if (!(sc->sc_flags & SC_OP_INVALID)) {
S
Sujith 已提交
1321
		ath_drain_all_txq(sc, false);
S
Sujith 已提交
1322
		ath_stoprecv(sc);
1323
		ath9k_hw_phy_disable(ah);
1324
	} else
S
Sujith 已提交
1325
		sc->rx.rxlink = NULL;
S
Sujith 已提交
1326 1327

	/* disable HAL and put h/w to sleep */
1328 1329
	ath9k_hw_disable(ah);
	ath9k_hw_configpcipowersave(ah, 1, 1);
1330 1331 1332

	spin_unlock_bh(&sc->sc_pcu_lock);

1333 1334 1335
	ath9k_ps_restore(sc);

	/* Finally, put the chip in FULL SLEEP mode */
1336
	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
S
Sujith 已提交
1337 1338

	sc->sc_flags |= SC_OP_INVALID;
1339

1340
	pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
1341

1342 1343
	mutex_unlock(&sc->mutex);

J
Joe Perches 已提交
1344
	ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
1345 1346
}

1347
static int ath9k_add_interface(struct ieee80211_hw *hw,
1348
			       struct ieee80211_vif *vif)
1349
{
1350 1351
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
P
Pavel Roskin 已提交
1352 1353
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
1354
	struct ath_vif *avp = (void *)vif->drv_priv;
1355
	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
1356
	int ret = 0;
1357

1358 1359
	mutex_lock(&sc->mutex);

1360
	switch (vif->type) {
1361
	case NL80211_IFTYPE_STATION:
1362
		ic_opmode = NL80211_IFTYPE_STATION;
1363
		break;
B
Bill Jordan 已提交
1364 1365 1366
	case NL80211_IFTYPE_WDS:
		ic_opmode = NL80211_IFTYPE_WDS;
		break;
1367 1368
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_AP:
1369
	case NL80211_IFTYPE_MESH_POINT:
1370 1371 1372 1373
		if (sc->nbcnvifs >= ATH_BCBUF) {
			ret = -ENOBUFS;
			goto out;
		}
1374
		ic_opmode = vif->type;
1375 1376
		break;
	default:
1377 1378
		ath_err(common, "Interface type %d not yet supported\n",
			vif->type);
1379 1380
		ret = -EOPNOTSUPP;
		goto out;
1381 1382
	}

J
Joe Perches 已提交
1383 1384
	ath_dbg(common, ATH_DBG_CONFIG,
		"Attach a VIF of type: %d\n", ic_opmode);
1385

S
Sujith 已提交
1386
	/* Set the VIF opmode */
S
Sujith 已提交
1387 1388 1389
	avp->av_opmode = ic_opmode;
	avp->av_bslot = -1;

1390
	sc->nvifs++;
1391

1392
	ath9k_set_bssid_mask(hw, vif);
1393

1394 1395 1396
	if (sc->nvifs > 1)
		goto out; /* skip global settings for secondary vif */

S
Sujith 已提交
1397
	if (ic_opmode == NL80211_IFTYPE_AP) {
P
Pavel Roskin 已提交
1398
		ath9k_hw_set_tsfadjust(ah, 1);
S
Sujith 已提交
1399 1400
		sc->sc_flags |= SC_OP_TSF_RESET;
	}
S
Sujith 已提交
1401 1402

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

1405 1406 1407 1408
	/*
	 * Enable MIB interrupts when there are hardware phy counters.
	 * Note we only do this (at the moment) for station mode.
	 */
1409 1410 1411
	if ((vif->type == NL80211_IFTYPE_STATION) ||
	    (vif->type == NL80211_IFTYPE_ADHOC) ||
	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
1412 1413
		if (ah->config.enable_ani)
			ah->imask |= ATH9K_INT_MIB;
P
Pavel Roskin 已提交
1414
		ah->imask |= ATH9K_INT_TSFOOR;
1415 1416
	}

P
Pavel Roskin 已提交
1417
	ath9k_hw_set_interrupts(ah, ah->imask);
1418

1419
	if (vif->type == NL80211_IFTYPE_AP    ||
1420
	    vif->type == NL80211_IFTYPE_ADHOC) {
1421
		sc->sc_flags |= SC_OP_ANI_RUN;
1422
		ath_start_ani(common);
1423
	}
1424

1425
out:
1426
	mutex_unlock(&sc->mutex);
1427
	return ret;
1428 1429
}

1430
static void ath9k_remove_interface(struct ieee80211_hw *hw,
1431
				   struct ieee80211_vif *vif)
1432
{
1433 1434
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1435
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1436
	struct ath_vif *avp = (void *)vif->drv_priv;
1437
	bool bs_valid = false;
1438
	int i;
1439

J
Joe Perches 已提交
1440
	ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
1441

1442 1443
	mutex_lock(&sc->mutex);

1444
	/* Stop ANI */
1445
	sc->sc_flags &= ~SC_OP_ANI_RUN;
1446
	del_timer_sync(&common->ani.timer);
J
Jouni Malinen 已提交
1447

1448
	/* Reclaim beacon resources */
1449 1450 1451
	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
1452
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
1453
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1454
		ath9k_ps_restore(sc);
J
Jouni Malinen 已提交
1455
	}
1456

1457
	ath_beacon_return(sc, avp);
1458
	sc->sc_flags &= ~SC_OP_BEACONS;
1459

1460
	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
1461
		if (sc->beacon.bslot[i] == vif) {
1462 1463 1464
			printk(KERN_DEBUG "%s: vif had allocated beacon "
			       "slot\n", __func__);
			sc->beacon.bslot[i] = NULL;
1465
			sc->beacon.bslot_aphy[i] = NULL;
1466 1467 1468 1469 1470 1471 1472 1473 1474
		} else if (sc->beacon.bslot[i])
			bs_valid = true;
	}
	if (!bs_valid && (sc->sc_ah->imask & ATH9K_INT_SWBA)) {
		/* Disable SWBA interrupt */
		sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
		ath9k_ps_wakeup(sc);
		ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
		ath9k_ps_restore(sc);
1475 1476
	}

S
Sujith 已提交
1477
	sc->nvifs--;
1478 1479

	mutex_unlock(&sc->mutex);
1480 1481
}

1482
static void ath9k_enable_ps(struct ath_softc *sc)
1483
{
P
Pavel Roskin 已提交
1484 1485
	struct ath_hw *ah = sc->sc_ah;

1486
	sc->ps_enabled = true;
P
Pavel Roskin 已提交
1487 1488 1489 1490
	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);
1491
		}
1492
		ath9k_hw_setrxabort(ah, 1);
1493 1494 1495
	}
}

1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515
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);
		}
	}

}

1516
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1517
{
1518 1519
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1520 1521
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
1522
	struct ieee80211_conf *conf = &hw->conf;
1523
	bool disable_radio;
1524

1525
	mutex_lock(&sc->mutex);
1526

1527 1528 1529 1530 1531 1532
	/*
	 * 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.
	 */
1533
	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1534 1535 1536
		bool enable_radio;
		bool all_wiphys_idle;
		bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1537 1538 1539

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

1542
		enable_radio = (!idle && all_wiphys_idle);
1543 1544 1545 1546 1547 1548 1549

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

1552
		if (enable_radio) {
1553
			sc->ps_idle = false;
1554
			ath_radio_enable(sc, hw);
J
Joe Perches 已提交
1555 1556
			ath_dbg(common, ATH_DBG_CONFIG,
				"not-idle: enabling radio\n");
1557 1558 1559
		}
	}

1560 1561 1562 1563 1564 1565
	/*
	 * 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.
	 */
1566
	if (changed & IEEE80211_CONF_CHANGE_PS) {
1567 1568
		unsigned long flags;
		spin_lock_irqsave(&sc->sc_pm_lock, flags);
1569 1570
		if (conf->flags & IEEE80211_CONF_PS)
			ath9k_enable_ps(sc);
1571 1572
		else
			ath9k_disable_ps(sc);
1573
		spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1574 1575
	}

S
Sujith 已提交
1576 1577
	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
		if (conf->flags & IEEE80211_CONF_MONITOR) {
J
Joe Perches 已提交
1578 1579
			ath_dbg(common, ATH_DBG_CONFIG,
				"Monitor mode is enabled\n");
1580 1581
			sc->sc_ah->is_monitoring = true;
		} else {
J
Joe Perches 已提交
1582 1583
			ath_dbg(common, ATH_DBG_CONFIG,
				"Monitor mode is disabled\n");
1584
			sc->sc_ah->is_monitoring = false;
S
Sujith 已提交
1585 1586 1587
		}
	}

1588
	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1589
		struct ieee80211_channel *curchan = hw->conf.channel;
1590
		int pos = curchan->hw_value;
1591 1592 1593 1594 1595
		int old_pos = -1;
		unsigned long flags;

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

1597 1598
		aphy->chan_idx = pos;
		aphy->chan_is_ht = conf_is_ht(conf);
1599 1600 1601 1602
		if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
			sc->sc_flags |= SC_OP_OFFCHANNEL;
		else
			sc->sc_flags &= ~SC_OP_OFFCHANNEL;
1603

1604 1605 1606 1607 1608 1609 1610 1611 1612 1613
		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;
		}
1614

J
Joe Perches 已提交
1615 1616
		ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
			curchan->center_freq);
1617

1618
		/* XXX: remove me eventualy */
1619
		ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
1620

1621
		ath_update_chainmask(sc, conf_is_ht(conf));
S
Sujith 已提交
1622

1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647
		/* 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));
		}

1648
		if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
1649
			ath_err(common, "Unable to set channel\n");
1650
			mutex_unlock(&sc->mutex);
1651 1652
			return -EINVAL;
		}
1653 1654 1655 1656 1657 1658 1659 1660

		/*
		 * 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 已提交
1661
	}
1662

1663
skip_chan_change:
1664
	if (changed & IEEE80211_CONF_CHANGE_POWER) {
S
Sujith 已提交
1665
		sc->config.txpowlimit = 2 * conf->power_level;
1666 1667
		ath_update_txpow(sc);
	}
1668

1669 1670 1671 1672
	spin_lock_bh(&sc->wiphy_lock);
	disable_radio = ath9k_all_wiphys_idle(sc);
	spin_unlock_bh(&sc->wiphy_lock);

1673
	if (disable_radio) {
J
Joe Perches 已提交
1674
		ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
1675
		sc->ps_idle = true;
1676
		ath_radio_disable(sc, hw);
1677 1678
	}

1679
	mutex_unlock(&sc->mutex);
1680

1681 1682 1683
	return 0;
}

1684 1685 1686 1687
#define SUPPORTED_FILTERS			\
	(FIF_PROMISC_IN_BSS |			\
	FIF_ALLMULTI |				\
	FIF_CONTROL |				\
1688
	FIF_PSPOLL |				\
1689 1690
	FIF_OTHER_BSS |				\
	FIF_BCN_PRBRESP_PROMISC |		\
1691
	FIF_PROBE_REQ |				\
1692
	FIF_FCSFAIL)
1693

1694 1695 1696 1697
/* FIXME: sc->sc_full_reset ? */
static void ath9k_configure_filter(struct ieee80211_hw *hw,
				   unsigned int changed_flags,
				   unsigned int *total_flags,
1698
				   u64 multicast)
1699
{
1700 1701
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1702
	u32 rfilt;
1703

1704 1705
	changed_flags &= SUPPORTED_FILTERS;
	*total_flags &= SUPPORTED_FILTERS;
1706

S
Sujith 已提交
1707
	sc->rx.rxfilter = *total_flags;
1708
	ath9k_ps_wakeup(sc);
1709 1710
	rfilt = ath_calcrxfilter(sc);
	ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
1711
	ath9k_ps_restore(sc);
1712

J
Joe Perches 已提交
1713 1714
	ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
		"Set HW RX filter: 0x%x\n", rfilt);
1715
}
1716

1717 1718 1719
static int ath9k_sta_add(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta)
1720
{
1721 1722
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1723

1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738
	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;
1739 1740
}

1741
static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
1742
			 const struct ieee80211_tx_queue_params *params)
1743
{
1744 1745
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1746
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1747
	struct ath_txq *txq;
1748
	struct ath9k_tx_queue_info qi;
1749
	int ret = 0;
1750

1751 1752
	if (queue >= WME_NUM_AC)
		return 0;
1753

1754 1755
	txq = sc->tx.txq_map[queue];

1756 1757
	mutex_lock(&sc->mutex);

1758 1759
	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));

1760 1761 1762 1763
	qi.tqi_aifs = params->aifs;
	qi.tqi_cwmin = params->cw_min;
	qi.tqi_cwmax = params->cw_max;
	qi.tqi_burstTime = params->txop;
1764

J
Joe Perches 已提交
1765 1766 1767 1768
	ath_dbg(common, ATH_DBG_CONFIG,
		"Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
		queue, txq->axq_qnum, params->aifs, params->cw_min,
		params->cw_max, params->txop);
1769

1770
	ret = ath_txq_update(sc, txq->axq_qnum, &qi);
1771
	if (ret)
1772
		ath_err(common, "TXQ Update failed\n");
1773

1774
	if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
1775
		if (queue == WME_AC_BE && !ret)
1776 1777
			ath_beaconq_config(sc);

1778 1779
	mutex_unlock(&sc->mutex);

1780 1781
	return ret;
}
1782

1783 1784
static int ath9k_set_key(struct ieee80211_hw *hw,
			 enum set_key_cmd cmd,
1785 1786
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta,
1787 1788
			 struct ieee80211_key_conf *key)
{
1789 1790
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1791
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1792
	int ret = 0;
1793

1794 1795 1796
	if (modparam_nohwcrypt)
		return -ENOSPC;

1797
	mutex_lock(&sc->mutex);
1798
	ath9k_ps_wakeup(sc);
J
Joe Perches 已提交
1799
	ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
1800

1801 1802
	switch (cmd) {
	case SET_KEY:
1803
		ret = ath_key_config(common, vif, sta, key);
1804 1805
		if (ret >= 0) {
			key->hw_key_idx = ret;
1806 1807
			/* push IV and Michael MIC generation to stack */
			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1808
			if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1809
				key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1810 1811
			if (sc->sc_ah->sw_mgmt_crypto &&
			    key->cipher == WLAN_CIPHER_SUITE_CCMP)
1812
				key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1813
			ret = 0;
1814 1815 1816
		}
		break;
	case DISABLE_KEY:
1817
		ath_key_delete(common, key);
1818 1819 1820 1821
		break;
	default:
		ret = -EINVAL;
	}
1822

1823
	ath9k_ps_restore(sc);
1824 1825
	mutex_unlock(&sc->mutex);

1826 1827
	return ret;
}
1828

1829 1830 1831 1832 1833
static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_bss_conf *bss_conf,
				   u32 changed)
{
1834 1835
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1836
	struct ath_hw *ah = sc->sc_ah;
1837
	struct ath_common *common = ath9k_hw_common(ah);
1838
	struct ath_vif *avp = (void *)vif->drv_priv;
1839
	int slottime;
S
Sujith 已提交
1840
	int error;
1841

1842 1843
	mutex_lock(&sc->mutex);

S
Sujith 已提交
1844 1845 1846 1847
	if (changed & BSS_CHANGED_BSSID) {
		/* Set BSSID */
		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
		memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
1848
		common->curaid = 0;
1849
		ath9k_hw_write_associd(ah);
1850

S
Sujith 已提交
1851 1852
		/* Set aggregation protection mode parameters */
		sc->config.ath_aggr_prot = 0;
1853

S
Sujith 已提交
1854 1855 1856
		/* Only legacy IBSS for now */
		if (vif->type == NL80211_IFTYPE_ADHOC)
			ath_update_chainmask(sc, 0);
1857

J
Joe Perches 已提交
1858 1859
		ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
			common->curbssid, common->curaid);
1860

S
Sujith 已提交
1861 1862 1863
		/* need to reconfigure the beacon */
		sc->sc_flags &= ~SC_OP_BEACONS ;
	}
1864

S
Sujith 已提交
1865 1866 1867 1868 1869 1870 1871
	/* 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);
1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890
	}

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

S
Sujith 已提交
1893 1894 1895
	/* Disable transmission of beacons */
	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1896

S
Sujith 已提交
1897 1898 1899 1900 1901 1902 1903 1904 1905
	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);
1906 1907 1908
			error = ath_beacon_alloc(aphy, vif);
			if (!error)
				ath_beacon_config(sc, vif);
S
Sujith 已提交
1909 1910
		} else {
			ath_beacon_config(sc, vif);
1911 1912 1913
		}
	}

1914
	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
J
Joe Perches 已提交
1915 1916
		ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
			bss_conf->use_short_preamble);
1917 1918 1919 1920 1921
		if (bss_conf->use_short_preamble)
			sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
		else
			sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
	}
1922

1923
	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
J
Joe Perches 已提交
1924 1925
		ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
			bss_conf->use_cts_prot);
1926 1927 1928 1929 1930 1931
		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;
	}
1932

1933
	if (changed & BSS_CHANGED_ASSOC) {
J
Joe Perches 已提交
1934
		ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1935
			bss_conf->assoc);
1936
		ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
1937
	}
1938 1939

	mutex_unlock(&sc->mutex);
1940
}
1941

1942 1943 1944
static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
{
	u64 tsf;
1945 1946
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1947

1948 1949 1950
	mutex_lock(&sc->mutex);
	tsf = ath9k_hw_gettsf64(sc->sc_ah);
	mutex_unlock(&sc->mutex);
1951

1952 1953
	return tsf;
}
1954

1955 1956
static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
1957 1958
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1959

1960 1961 1962
	mutex_lock(&sc->mutex);
	ath9k_hw_settsf64(sc->sc_ah, tsf);
	mutex_unlock(&sc->mutex);
1963 1964
}

1965 1966
static void ath9k_reset_tsf(struct ieee80211_hw *hw)
{
1967 1968
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1969

1970
	mutex_lock(&sc->mutex);
1971 1972

	ath9k_ps_wakeup(sc);
1973
	ath9k_hw_reset_tsf(sc->sc_ah);
1974 1975
	ath9k_ps_restore(sc);

1976
	mutex_unlock(&sc->mutex);
1977
}
1978

1979
static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1980
			      struct ieee80211_vif *vif,
1981 1982 1983
			      enum ieee80211_ampdu_mlme_action action,
			      struct ieee80211_sta *sta,
			      u16 tid, u16 *ssn)
1984
{
1985 1986
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
1987
	int ret = 0;
1988

1989 1990
	local_bh_disable();

1991 1992
	switch (action) {
	case IEEE80211_AMPDU_RX_START:
1993 1994
		if (!(sc->sc_flags & SC_OP_RXAGGR))
			ret = -ENOTSUPP;
1995 1996 1997 1998
		break;
	case IEEE80211_AMPDU_RX_STOP:
		break;
	case IEEE80211_AMPDU_TX_START:
1999 2000 2001
		if (!(sc->sc_flags & SC_OP_TXAGGR))
			return -EOPNOTSUPP;

2002
		ath9k_ps_wakeup(sc);
2003 2004 2005
		ret = ath_tx_aggr_start(sc, sta, tid, ssn);
		if (!ret)
			ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2006
		ath9k_ps_restore(sc);
2007 2008
		break;
	case IEEE80211_AMPDU_TX_STOP:
2009
		ath9k_ps_wakeup(sc);
S
Sujith 已提交
2010
		ath_tx_aggr_stop(sc, sta, tid);
2011
		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2012
		ath9k_ps_restore(sc);
2013
		break;
2014
	case IEEE80211_AMPDU_TX_OPERATIONAL:
2015
		ath9k_ps_wakeup(sc);
2016
		ath_tx_aggr_resume(sc, sta, tid);
2017
		ath9k_ps_restore(sc);
2018
		break;
2019
	default:
2020
		ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
2021 2022
	}

2023 2024
	local_bh_enable();

2025
	return ret;
2026 2027
}

2028 2029 2030 2031 2032
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;
2033
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2034
	struct ieee80211_supported_band *sband;
2035 2036 2037 2038 2039 2040 2041
	struct ieee80211_channel *chan;
	unsigned long flags;
	int pos;

	spin_lock_irqsave(&common->cc_lock, flags);
	if (idx == 0)
		ath_update_survey_stats(sc);
2042 2043 2044 2045 2046 2047

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

2049 2050
	if (!sband)
		sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
2051

2052 2053 2054
	if (!sband || idx >= sband->n_channels) {
		spin_unlock_irqrestore(&common->cc_lock, flags);
		return -ENOENT;
2055
	}
2056

2057 2058 2059 2060 2061 2062
	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);

2063 2064 2065
	return 0;
}

2066 2067
static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
{
2068 2069
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
2070

2071
	mutex_lock(&sc->mutex);
2072 2073
	if (ath9k_wiphy_scanning(sc)) {
		/*
2074 2075 2076 2077 2078
		 * 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.
2079
		 */
2080
		mutex_unlock(&sc->mutex);
2081 2082 2083 2084 2085
		return;
	}

	aphy->state = ATH_WIPHY_SCAN;
	ath9k_wiphy_pause_all_forced(sc, aphy);
2086
	mutex_unlock(&sc->mutex);
2087 2088
}

2089 2090 2091 2092
/*
 * XXX: this requires a revisit after the driver
 * scan_complete gets moved to another place/removed in mac80211.
 */
2093 2094
static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
{
2095 2096
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
2097

2098
	mutex_lock(&sc->mutex);
2099
	aphy->state = ATH_WIPHY_ACTIVE;
2100
	mutex_unlock(&sc->mutex);
2101 2102
}

2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114
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);
}

2115
struct ieee80211_ops ath9k_ops = {
2116 2117 2118 2119 2120 2121 2122
	.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,
2123 2124
	.sta_add	    = ath9k_sta_add,
	.sta_remove	    = ath9k_sta_remove,
2125 2126 2127 2128
	.conf_tx 	    = ath9k_conf_tx,
	.bss_info_changed   = ath9k_bss_info_changed,
	.set_key            = ath9k_set_key,
	.get_tsf 	    = ath9k_get_tsf,
2129
	.set_tsf 	    = ath9k_set_tsf,
2130
	.reset_tsf 	    = ath9k_reset_tsf,
2131
	.ampdu_action       = ath9k_ampdu_action,
2132
	.get_survey	    = ath9k_get_survey,
2133 2134
	.sw_scan_start      = ath9k_sw_scan_start,
	.sw_scan_complete   = ath9k_sw_scan_complete,
J
Johannes Berg 已提交
2135
	.rfkill_poll        = ath9k_rfkill_poll_state,
2136
	.set_coverage_class = ath9k_set_coverage_class,
2137
};