hw.c 97.7 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 18 19
 *
 * 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/io.h>
#include <asm/unaligned.h>

20
#include "hw.h"
21
#include "hw-ops.h"
22
#include "rc.h"
23 24 25
#include "ar5008_initvals.h"
#include "ar9001_initvals.h"
#include "ar9002_initvals.h"
26
#include "ar9003_initvals.h"
27

28 29 30
#define ATH9K_CLOCK_RATE_CCK		22
#define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
#define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
31

32
static void ar9002_hw_attach_ops(struct ath_hw *ah);
33
static void ar9003_hw_attach_ops(struct ath_hw *ah);
34

35
static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
36

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
MODULE_AUTHOR("Atheros Communications");
MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");

static int __init ath9k_init(void)
{
	return 0;
}
module_init(ath9k_init);

static void __exit ath9k_exit(void)
{
	return;
}
module_exit(ath9k_exit);

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
/* Private hardware callbacks */

static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
{
	ath9k_hw_private_ops(ah)->init_cal_settings(ah);
}

static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
{
	ath9k_hw_private_ops(ah)->init_mode_regs(ah);
}

static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
{
	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);

	return priv_ops->macversion_supported(ah->hw_version.macVersion);
}

73 74 75 76 77 78
static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
					struct ath9k_channel *chan)
{
	return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
}

S
Sujith 已提交
79 80 81
/********************/
/* Helper Functions */
/********************/
82

83
static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
S
Sujith 已提交
84
{
85
	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
86

87
	if (!ah->curchan) /* should really check for CCK instead */
88 89 90 91
		return usecs *ATH9K_CLOCK_RATE_CCK;
	if (conf->channel->band == IEEE80211_BAND_2GHZ)
		return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
	return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
S
Sujith 已提交
92 93
}

94
static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
S
Sujith 已提交
95
{
96
	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
97

98
	if (conf_is_ht40(conf))
S
Sujith 已提交
99 100 101 102
		return ath9k_hw_mac_clks(ah, usecs) * 2;
	else
		return ath9k_hw_mac_clks(ah, usecs);
}
103

S
Sujith 已提交
104
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
105 106 107
{
	int i;

S
Sujith 已提交
108 109 110
	BUG_ON(timeout < AH_TIME_QUANTUM);

	for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
111 112 113 114 115
		if ((REG_READ(ah, reg) & mask) == val)
			return true;

		udelay(AH_TIME_QUANTUM);
	}
S
Sujith 已提交
116

117 118 119
	ath_print(ath9k_hw_common(ah), ATH_DBG_ANY,
		  "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
		  timeout, reg, REG_READ(ah, reg), mask, val);
120

S
Sujith 已提交
121
	return false;
122
}
123
EXPORT_SYMBOL(ath9k_hw_wait);
124 125 126 127 128 129 130 131 132 133 134 135 136

u32 ath9k_hw_reverse_bits(u32 val, u32 n)
{
	u32 retval;
	int i;

	for (i = 0, retval = 0; i < n; i++) {
		retval = (retval << 1) | (val & 1);
		val >>= 1;
	}
	return retval;
}

137
bool ath9k_get_channel_edges(struct ath_hw *ah,
S
Sujith 已提交
138 139
			     u16 flags, u16 *low,
			     u16 *high)
140
{
141
	struct ath9k_hw_capabilities *pCap = &ah->caps;
142

S
Sujith 已提交
143 144 145 146
	if (flags & CHANNEL_5GHZ) {
		*low = pCap->low_5ghz_chan;
		*high = pCap->high_5ghz_chan;
		return true;
147
	}
S
Sujith 已提交
148 149 150 151 152 153
	if ((flags & CHANNEL_2GHZ)) {
		*low = pCap->low_2ghz_chan;
		*high = pCap->high_2ghz_chan;
		return true;
	}
	return false;
154 155
}

156
u16 ath9k_hw_computetxtime(struct ath_hw *ah,
157
			   u8 phy, int kbps,
S
Sujith 已提交
158 159
			   u32 frameLen, u16 rateix,
			   bool shortPreamble)
160
{
S
Sujith 已提交
161
	u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
162

S
Sujith 已提交
163 164
	if (kbps == 0)
		return 0;
165

166
	switch (phy) {
S
Sujith 已提交
167
	case WLAN_RC_PHY_CCK:
S
Sujith 已提交
168
		phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
169
		if (shortPreamble)
S
Sujith 已提交
170 171 172 173
			phyTime >>= 1;
		numBits = frameLen << 3;
		txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
		break;
S
Sujith 已提交
174
	case WLAN_RC_PHY_OFDM:
175
		if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
S
Sujith 已提交
176 177 178 179 180 181
			bitsPerSymbol =	(kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
			numBits = OFDM_PLCP_BITS + (frameLen << 3);
			numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
			txTime = OFDM_SIFS_TIME_QUARTER
				+ OFDM_PREAMBLE_TIME_QUARTER
				+ (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
182 183
		} else if (ah->curchan &&
			   IS_CHAN_HALF_RATE(ah->curchan)) {
S
Sujith 已提交
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
			bitsPerSymbol =	(kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
			numBits = OFDM_PLCP_BITS + (frameLen << 3);
			numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
			txTime = OFDM_SIFS_TIME_HALF +
				OFDM_PREAMBLE_TIME_HALF
				+ (numSymbols * OFDM_SYMBOL_TIME_HALF);
		} else {
			bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
			numBits = OFDM_PLCP_BITS + (frameLen << 3);
			numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
			txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
				+ (numSymbols * OFDM_SYMBOL_TIME);
		}
		break;
	default:
199
		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
200
			  "Unknown phy %u (rate ix %u)\n", phy, rateix);
S
Sujith 已提交
201 202 203
		txTime = 0;
		break;
	}
204

S
Sujith 已提交
205 206
	return txTime;
}
207
EXPORT_SYMBOL(ath9k_hw_computetxtime);
208

209
void ath9k_hw_get_channel_centers(struct ath_hw *ah,
S
Sujith 已提交
210 211
				  struct ath9k_channel *chan,
				  struct chan_centers *centers)
212
{
S
Sujith 已提交
213
	int8_t extoff;
214

S
Sujith 已提交
215 216 217 218
	if (!IS_CHAN_HT40(chan)) {
		centers->ctl_center = centers->ext_center =
			centers->synth_center = chan->channel;
		return;
219 220
	}

S
Sujith 已提交
221 222 223 224 225 226 227 228 229 230
	if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
	    (chan->chanmode == CHANNEL_G_HT40PLUS)) {
		centers->synth_center =
			chan->channel + HT40_CHANNEL_CENTER_SHIFT;
		extoff = 1;
	} else {
		centers->synth_center =
			chan->channel - HT40_CHANNEL_CENTER_SHIFT;
		extoff = -1;
	}
231

S
Sujith 已提交
232 233
	centers->ctl_center =
		centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
234
	/* 25 MHz spacing is supported by hw but not on upper layers */
S
Sujith 已提交
235
	centers->ext_center =
236
		centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
237 238
}

S
Sujith 已提交
239 240 241 242
/******************/
/* Chip Revisions */
/******************/

243
static void ath9k_hw_read_revisions(struct ath_hw *ah)
244
{
S
Sujith 已提交
245
	u32 val;
246

S
Sujith 已提交
247
	val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
248

S
Sujith 已提交
249 250
	if (val == 0xFF) {
		val = REG_READ(ah, AR_SREV);
251 252 253
		ah->hw_version.macVersion =
			(val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
		ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
254
		ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
S
Sujith 已提交
255 256
	} else {
		if (!AR_SREV_9100(ah))
257
			ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
258

259
		ah->hw_version.macRev = val & AR_SREV_REVISION;
260

261
		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
262
			ah->is_pciexpress = true;
S
Sujith 已提交
263
	}
264 265
}

266
static int ath9k_hw_get_radiorev(struct ath_hw *ah)
267
{
S
Sujith 已提交
268 269
	u32 val;
	int i;
270

S
Sujith 已提交
271
	REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
272

S
Sujith 已提交
273 274 275 276
	for (i = 0; i < 8; i++)
		REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
	val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
	val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
277

S
Sujith 已提交
278
	return ath9k_hw_reverse_bits(val, 8);
279 280
}

S
Sujith 已提交
281 282 283 284
/************************************/
/* HW Attach, Detach, Init Routines */
/************************************/

285
static void ath9k_hw_disablepcie(struct ath_hw *ah)
286
{
287
	if (AR_SREV_9100(ah))
S
Sujith 已提交
288
		return;
289

S
Sujith 已提交
290 291 292 293 294 295 296 297 298
	REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
	REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
	REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
	REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
	REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
	REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
	REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
	REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
	REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
299

S
Sujith 已提交
300
	REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
301 302
}

303
/* This should work for all families including legacy */
304
static bool ath9k_hw_chip_test(struct ath_hw *ah)
305
{
306
	struct ath_common *common = ath9k_hw_common(ah);
307
	u32 regAddr[2] = { AR_STA_ID0 };
S
Sujith 已提交
308 309 310 311 312
	u32 regHold[2];
	u32 patternData[4] = { 0x55555555,
			       0xaaaaaaaa,
			       0x66666666,
			       0x99999999 };
313
	int i, j, loop_max;
314

315 316 317 318 319 320 321
	if (!AR_SREV_9300_20_OR_LATER(ah)) {
		loop_max = 2;
		regAddr[1] = AR_PHY_BASE + (8 << 2);
	} else
		loop_max = 1;

	for (i = 0; i < loop_max; i++) {
S
Sujith 已提交
322 323
		u32 addr = regAddr[i];
		u32 wrData, rdData;
324

S
Sujith 已提交
325 326 327 328 329 330
		regHold[i] = REG_READ(ah, addr);
		for (j = 0; j < 0x100; j++) {
			wrData = (j << 16) | j;
			REG_WRITE(ah, addr, wrData);
			rdData = REG_READ(ah, addr);
			if (rdData != wrData) {
331 332 333 334 335
				ath_print(common, ATH_DBG_FATAL,
					  "address test failed "
					  "addr: 0x%08x - wr:0x%08x != "
					  "rd:0x%08x\n",
					  addr, wrData, rdData);
S
Sujith 已提交
336 337 338 339 340 341 342 343
				return false;
			}
		}
		for (j = 0; j < 4; j++) {
			wrData = patternData[j];
			REG_WRITE(ah, addr, wrData);
			rdData = REG_READ(ah, addr);
			if (wrData != rdData) {
344 345 346 347 348
				ath_print(common, ATH_DBG_FATAL,
					  "address test failed "
					  "addr: 0x%08x - wr:0x%08x != "
					  "rd:0x%08x\n",
					  addr, wrData, rdData);
S
Sujith 已提交
349 350
				return false;
			}
351
		}
S
Sujith 已提交
352
		REG_WRITE(ah, regAddr[i], regHold[i]);
353
	}
S
Sujith 已提交
354
	udelay(100);
355

356 357 358
	return true;
}

359
static void ath9k_hw_init_config(struct ath_hw *ah)
S
Sujith 已提交
360 361
{
	int i;
362

363 364 365 366 367 368 369 370 371 372 373 374 375
	ah->config.dma_beacon_response_time = 2;
	ah->config.sw_beacon_response_time = 10;
	ah->config.additional_swba_backoff = 0;
	ah->config.ack_6mb = 0x0;
	ah->config.cwm_ignore_extcca = 0;
	ah->config.pcie_powersave_enable = 0;
	ah->config.pcie_clock_req = 0;
	ah->config.pcie_waen = 0;
	ah->config.analog_shiftreg = 1;
	ah->config.ofdm_trig_low = 200;
	ah->config.ofdm_trig_high = 500;
	ah->config.cck_trig_high = 200;
	ah->config.cck_trig_low = 100;
376 377 378 379 380 381 382

	/*
	 * For now ANI is disabled for AR9003, it is still
	 * being tested.
	 */
	if (!AR_SREV_9300_20_OR_LATER(ah))
		ah->config.enable_ani = 1;
383

S
Sujith 已提交
384
	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
385 386
		ah->config.spurchans[i][0] = AR_NO_SPUR;
		ah->config.spurchans[i][1] = AR_NO_SPUR;
387 388
	}

389 390 391 392 393
	if (ah->hw_version.devid != AR2427_DEVID_PCIE)
		ah->config.ht_enable = 1;
	else
		ah->config.ht_enable = 0;

S
Sujith 已提交
394
	ah->config.rx_intr_mitigation = true;
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412

	/*
	 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
	 * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
	 * This means we use it for all AR5416 devices, and the few
	 * minor PCI AR9280 devices out there.
	 *
	 * Serialization is required because these devices do not handle
	 * well the case of two concurrent reads/writes due to the latency
	 * involved. During one read/write another read/write can be issued
	 * on another CPU while the previous read/write may still be working
	 * on our hardware, if we hit this case the hardware poops in a loop.
	 * We prevent this by serializing reads and writes.
	 *
	 * This issue is not present on PCI-Express devices or pre-AR5416
	 * devices (legacy, 802.11abg).
	 */
	if (num_possible_cpus() > 1)
413
		ah->config.serialize_regmode = SER_REG_MODE_AUTO;
414 415
}

416
static void ath9k_hw_init_defaults(struct ath_hw *ah)
417
{
418 419 420 421 422 423
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);

	regulatory->country_code = CTRY_DEFAULT;
	regulatory->power_limit = MAX_RATE_POWER;
	regulatory->tp_scale = ATH9K_TP_SCALE_MAX;

424 425
	ah->hw_version.magic = AR5416_MAGIC;
	ah->hw_version.subvendorid = 0;
426 427 428 429 430

	ah->ah_flags = 0;
	if (!AR_SREV_9100(ah))
		ah->ah_flags = AH_USE_EEPROM;

431 432 433 434 435 436
	ah->atim_window = 0;
	ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
	ah->beacon_interval = 100;
	ah->enable_32kHz_clock = DONT_USE_32KHZ;
	ah->slottime = (u32) -1;
	ah->globaltxtimeout = (u32) -1;
437
	ah->power_mode = ATH9K_PM_UNDEFINED;
438 439
}

440
static int ath9k_hw_rf_claim(struct ath_hw *ah)
441
{
S
Sujith 已提交
442 443 444 445 446 447 448 449 450 451 452 453 454 455
	u32 val;

	REG_WRITE(ah, AR_PHY(0), 0x00000007);

	val = ath9k_hw_get_radiorev(ah);
	switch (val & AR_RADIO_SREV_MAJOR) {
	case 0:
		val = AR_RAD5133_SREV_MAJOR;
		break;
	case AR_RAD5133_SREV_MAJOR:
	case AR_RAD5122_SREV_MAJOR:
	case AR_RAD2133_SREV_MAJOR:
	case AR_RAD2122_SREV_MAJOR:
		break;
456
	default:
457 458 459
		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
			  "Radio Chip Rev 0x%02X not supported\n",
			  val & AR_RADIO_SREV_MAJOR);
S
Sujith 已提交
460
		return -EOPNOTSUPP;
461 462
	}

463
	ah->hw_version.analog5GhzRev = val;
464

S
Sujith 已提交
465
	return 0;
466 467
}

468
static int ath9k_hw_init_macaddr(struct ath_hw *ah)
469
{
470
	struct ath_common *common = ath9k_hw_common(ah);
471 472 473 474 475 476
	u32 sum;
	int i;
	u16 eeval;

	sum = 0;
	for (i = 0; i < 3; i++) {
S
Sujith 已提交
477
		eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
478
		sum += eeval;
479 480
		common->macaddr[2 * i] = eeval >> 8;
		common->macaddr[2 * i + 1] = eeval & 0xff;
481
	}
S
Sujith 已提交
482
	if (sum == 0 || sum == 0xffff * 3)
483 484 485 486 487
		return -EADDRNOTAVAIL;

	return 0;
}

488
static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
489 490 491
{
	u32 rxgain_type;

S
Sujith 已提交
492 493
	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
		rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
494 495

		if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
496
			INIT_INI_ARRAY(&ah->iniModesRxGain,
497 498 499
			ar9280Modes_backoff_13db_rxgain_9280_2,
			ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
		else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
500
			INIT_INI_ARRAY(&ah->iniModesRxGain,
501 502 503
			ar9280Modes_backoff_23db_rxgain_9280_2,
			ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
		else
504
			INIT_INI_ARRAY(&ah->iniModesRxGain,
505 506
			ar9280Modes_original_rxgain_9280_2,
			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
507
	} else {
508
		INIT_INI_ARRAY(&ah->iniModesRxGain,
509 510
			ar9280Modes_original_rxgain_9280_2,
			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
511
	}
512 513
}

514
static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
515 516 517
{
	u32 txgain_type;

S
Sujith 已提交
518 519
	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
		txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
520 521

		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
522
			INIT_INI_ARRAY(&ah->iniModesTxGain,
523 524 525
			ar9280Modes_high_power_tx_gain_9280_2,
			ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
		else
526
			INIT_INI_ARRAY(&ah->iniModesTxGain,
527 528
			ar9280Modes_original_tx_gain_9280_2,
			ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
529
	} else {
530
		INIT_INI_ARRAY(&ah->iniModesTxGain,
531 532
		ar9280Modes_original_tx_gain_9280_2,
		ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
533
	}
534 535
}

536
static int ath9k_hw_post_init(struct ath_hw *ah)
537
{
S
Sujith 已提交
538
	int ecode;
539

S
Sujith 已提交
540 541 542 543
	if (!AR_SREV_9271(ah)) {
		if (!ath9k_hw_chip_test(ah))
			return -ENODEV;
	}
544

S
Sujith 已提交
545 546
	ecode = ath9k_hw_rf_claim(ah);
	if (ecode != 0)
547 548
		return ecode;

549
	ecode = ath9k_hw_eeprom_init(ah);
S
Sujith 已提交
550 551
	if (ecode != 0)
		return ecode;
552

553 554 555 556
	ath_print(ath9k_hw_common(ah), ATH_DBG_CONFIG,
		  "Eeprom VER: %d, REV: %d\n",
		  ah->eep_ops->get_eeprom_ver(ah),
		  ah->eep_ops->get_eeprom_rev(ah));
557

558 559 560 561 562 563
	ecode = ath9k_hw_rf_alloc_ext_banks(ah);
	if (ecode) {
		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
			  "Failed allocating banks for "
			  "external radio\n");
		return ecode;
564
	}
565

S
Sujith 已提交
566 567
	if (!AR_SREV_9100(ah)) {
		ath9k_hw_ani_setup(ah);
568
		ath9k_hw_ani_init(ah);
569 570 571 572 573
	}

	return 0;
}

574
static bool ar9002_hw_macversion_supported(u32 macversion)
575 576 577 578 579 580 581 582 583
{
	switch (macversion) {
	case AR_SREV_VERSION_5416_PCI:
	case AR_SREV_VERSION_5416_PCIE:
	case AR_SREV_VERSION_9160:
	case AR_SREV_VERSION_9100:
	case AR_SREV_VERSION_9280:
	case AR_SREV_VERSION_9285:
	case AR_SREV_VERSION_9287:
584
	case AR_SREV_VERSION_9271:
585
		return true;
586 587 588 589 590 591
	default:
		break;
	}
	return false;
}

592 593 594 595 596 597 598 599 600 601 602
static bool ar9003_hw_macversion_supported(u32 macversion)
{
	switch (macversion) {
	case AR_SREV_VERSION_9300:
		return true;
	default:
		break;
	}
	return false;
}

603
static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
604
{
S
Sujith 已提交
605 606
	if (AR_SREV_9160_10_OR_LATER(ah)) {
		if (AR_SREV_9280_10_OR_LATER(ah)) {
607 608
			ah->iq_caldata.calData = &iq_cal_single_sample;
			ah->adcgain_caldata.calData =
S
Sujith 已提交
609
				&adc_gain_cal_single_sample;
610
			ah->adcdc_caldata.calData =
S
Sujith 已提交
611
				&adc_dc_cal_single_sample;
612
			ah->adcdc_calinitdata.calData =
S
Sujith 已提交
613 614
				&adc_init_dc_cal;
		} else {
615 616
			ah->iq_caldata.calData = &iq_cal_multi_sample;
			ah->adcgain_caldata.calData =
S
Sujith 已提交
617
				&adc_gain_cal_multi_sample;
618
			ah->adcdc_caldata.calData =
S
Sujith 已提交
619
				&adc_dc_cal_multi_sample;
620
			ah->adcdc_calinitdata.calData =
S
Sujith 已提交
621 622
				&adc_init_dc_cal;
		}
623
		ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
S
Sujith 已提交
624
	}
625
}
626

627
static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
628
{
629
	if (AR_SREV_9271(ah)) {
630 631 632 633
		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
			       ARRAY_SIZE(ar9271Modes_9271), 6);
		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
			       ARRAY_SIZE(ar9271Common_9271), 2);
634 635 636 637 638 639
		INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
			       ar9271Common_normal_cck_fir_coeff_9271,
			       ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
		INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
			       ar9271Common_japan_2484_cck_fir_coeff_9271,
			       ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
640 641 642
		INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
			       ar9271Modes_9271_1_0_only,
			       ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
643 644 645 646 647 648 649 650
		INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
			       ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
		INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
			       ar9271Modes_high_power_tx_gain_9271,
			       ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
		INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
			       ar9271Modes_normal_power_tx_gain_9271,
			       ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
651 652 653
		return;
	}

654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
	if (AR_SREV_9287_11_OR_LATER(ah)) {
		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
				ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
				ARRAY_SIZE(ar9287Common_9287_1_1), 2);
		if (ah->config.pcie_clock_req)
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
			ar9287PciePhy_clkreq_off_L1_9287_1_1,
			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
		else
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
			ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
					2);
	} else if (AR_SREV_9287_10_OR_LATER(ah)) {
		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
				ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
				ARRAY_SIZE(ar9287Common_9287_1_0), 2);

		if (ah->config.pcie_clock_req)
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
			ar9287PciePhy_clkreq_off_L1_9287_1_0,
			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
		else
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
			ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
				  2);
	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
684

685

686
		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
687
			       ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
688
		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
689 690
			       ARRAY_SIZE(ar9285Common_9285_1_2), 2);

691 692
		if (ah->config.pcie_clock_req) {
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
693 694 695
			ar9285PciePhy_clkreq_off_L1_9285_1_2,
			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
		} else {
696
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
697 698 699 700 701
			ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
				  2);
		}
	} else if (AR_SREV_9285_10_OR_LATER(ah)) {
702
		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
703
			       ARRAY_SIZE(ar9285Modes_9285), 6);
704
		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
705 706
			       ARRAY_SIZE(ar9285Common_9285), 2);

707 708
		if (ah->config.pcie_clock_req) {
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
709 710 711
			ar9285PciePhy_clkreq_off_L1_9285,
			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
		} else {
712
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
713 714 715 716
			ar9285PciePhy_clkreq_always_on_L1_9285,
			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
		}
	} else if (AR_SREV_9280_20_OR_LATER(ah)) {
717
		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
S
Sujith 已提交
718
			       ARRAY_SIZE(ar9280Modes_9280_2), 6);
719
		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
S
Sujith 已提交
720
			       ARRAY_SIZE(ar9280Common_9280_2), 2);
721

722 723
		if (ah->config.pcie_clock_req) {
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
S
Sujith 已提交
724 725 726
			       ar9280PciePhy_clkreq_off_L1_9280,
			       ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
		} else {
727
			INIT_INI_ARRAY(&ah->iniPcieSerdes,
S
Sujith 已提交
728 729 730
			       ar9280PciePhy_clkreq_always_on_L1_9280,
			       ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
		}
731
		INIT_INI_ARRAY(&ah->iniModesAdditional,
S
Sujith 已提交
732 733 734
			       ar9280Modes_fast_clock_9280_2,
			       ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
735
		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
S
Sujith 已提交
736
			       ARRAY_SIZE(ar9280Modes_9280), 6);
737
		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
S
Sujith 已提交
738 739
			       ARRAY_SIZE(ar9280Common_9280), 2);
	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
740
		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
S
Sujith 已提交
741
			       ARRAY_SIZE(ar5416Modes_9160), 6);
742
		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
S
Sujith 已提交
743
			       ARRAY_SIZE(ar5416Common_9160), 2);
744
		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
S
Sujith 已提交
745
			       ARRAY_SIZE(ar5416Bank0_9160), 2);
746
		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
S
Sujith 已提交
747
			       ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
748
		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
S
Sujith 已提交
749
			       ARRAY_SIZE(ar5416Bank1_9160), 2);
750
		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
S
Sujith 已提交
751
			       ARRAY_SIZE(ar5416Bank2_9160), 2);
752
		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
S
Sujith 已提交
753
			       ARRAY_SIZE(ar5416Bank3_9160), 3);
754
		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
S
Sujith 已提交
755
			       ARRAY_SIZE(ar5416Bank6_9160), 3);
756
		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
S
Sujith 已提交
757
			       ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
758
		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
S
Sujith 已提交
759 760
			       ARRAY_SIZE(ar5416Bank7_9160), 2);
		if (AR_SREV_9160_11(ah)) {
761
			INIT_INI_ARRAY(&ah->iniAddac,
S
Sujith 已提交
762 763 764
				       ar5416Addac_91601_1,
				       ARRAY_SIZE(ar5416Addac_91601_1), 2);
		} else {
765
			INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
S
Sujith 已提交
766 767 768
				       ARRAY_SIZE(ar5416Addac_9160), 2);
		}
	} else if (AR_SREV_9100_OR_LATER(ah)) {
769
		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
S
Sujith 已提交
770
			       ARRAY_SIZE(ar5416Modes_9100), 6);
771
		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
S
Sujith 已提交
772
			       ARRAY_SIZE(ar5416Common_9100), 2);
773
		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
S
Sujith 已提交
774
			       ARRAY_SIZE(ar5416Bank0_9100), 2);
775
		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
S
Sujith 已提交
776
			       ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
777
		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
S
Sujith 已提交
778
			       ARRAY_SIZE(ar5416Bank1_9100), 2);
779
		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
S
Sujith 已提交
780
			       ARRAY_SIZE(ar5416Bank2_9100), 2);
781
		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
S
Sujith 已提交
782
			       ARRAY_SIZE(ar5416Bank3_9100), 3);
783
		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
S
Sujith 已提交
784
			       ARRAY_SIZE(ar5416Bank6_9100), 3);
785
		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
S
Sujith 已提交
786
			       ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
787
		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
S
Sujith 已提交
788
			       ARRAY_SIZE(ar5416Bank7_9100), 2);
789
		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
S
Sujith 已提交
790 791
			       ARRAY_SIZE(ar5416Addac_9100), 2);
	} else {
792
		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
S
Sujith 已提交
793
			       ARRAY_SIZE(ar5416Modes), 6);
794
		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
S
Sujith 已提交
795
			       ARRAY_SIZE(ar5416Common), 2);
796
		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
S
Sujith 已提交
797
			       ARRAY_SIZE(ar5416Bank0), 2);
798
		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
S
Sujith 已提交
799
			       ARRAY_SIZE(ar5416BB_RfGain), 3);
800
		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
S
Sujith 已提交
801
			       ARRAY_SIZE(ar5416Bank1), 2);
802
		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
S
Sujith 已提交
803
			       ARRAY_SIZE(ar5416Bank2), 2);
804
		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
S
Sujith 已提交
805
			       ARRAY_SIZE(ar5416Bank3), 3);
806
		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
S
Sujith 已提交
807
			       ARRAY_SIZE(ar5416Bank6), 3);
808
		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
S
Sujith 已提交
809
			       ARRAY_SIZE(ar5416Bank6TPC), 3);
810
		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
S
Sujith 已提交
811
			       ARRAY_SIZE(ar5416Bank7), 2);
812
		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
S
Sujith 已提交
813
			       ARRAY_SIZE(ar5416Addac), 2);
814
	}
815
}
816

817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
	/* mac */
	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
		       ar9300_2p0_mac_core,
		       ARRAY_SIZE(ar9300_2p0_mac_core), 2);
	INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
		       ar9300_2p0_mac_postamble,
		       ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);

	/* bb */
	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
		       ar9300_2p0_baseband_core,
		       ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
	INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
		       ar9300_2p0_baseband_postamble,
		       ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);

	/* radio */
	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
		       ar9300_2p0_radio_core,
		       ARRAY_SIZE(ar9300_2p0_radio_core), 2);
	INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
		       ar9300_2p0_radio_postamble,
		       ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);

	/* soc */
	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
		       ar9300_2p0_soc_preamble,
		       ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
	INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
		       ar9300_2p0_soc_postamble,
		       ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);

	/* rx/tx gain */
	INIT_INI_ARRAY(&ah->iniModesRxGain,
		       ar9300Common_rx_gain_table_2p0,
		       ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
	INIT_INI_ARRAY(&ah->iniModesTxGain,
		       ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
		       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
		       5);

	/* Load PCIE SERDES settings from INI */

	/* Awake Setting */

	INIT_INI_ARRAY(&ah->iniPcieSerdes,
		       ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
		       ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
		       2);

	/* Sleep Setting */

	INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
		       ar9300PciePhy_clkreq_enable_L1_2p0,
		       ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
		       2);

	/* Fast clock modal settings */
	INIT_INI_ARRAY(&ah->iniModesAdditional,
		       ar9300Modes_fast_clock_2p0,
		       ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
		       3);
}

888 889
static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
{
890
	if (AR_SREV_9287_11_OR_LATER(ah))
891 892 893 894 895 896 897 898 899 900
		INIT_INI_ARRAY(&ah->iniModesRxGain,
		ar9287Modes_rx_gain_9287_1_1,
		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
	else if (AR_SREV_9287_10(ah))
		INIT_INI_ARRAY(&ah->iniModesRxGain,
		ar9287Modes_rx_gain_9287_1_0,
		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
	else if (AR_SREV_9280_20(ah))
		ath9k_hw_init_rxgain_ini(ah);

901
	if (AR_SREV_9287_11_OR_LATER(ah)) {
902 903 904 905 906 907 908 909 910 911
		INIT_INI_ARRAY(&ah->iniModesTxGain,
		ar9287Modes_tx_gain_9287_1_1,
		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
	} else if (AR_SREV_9287_10(ah)) {
		INIT_INI_ARRAY(&ah->iniModesTxGain,
		ar9287Modes_tx_gain_9287_1_0,
		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
	} else if (AR_SREV_9280_20(ah)) {
		ath9k_hw_init_txgain_ini(ah);
	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
912 913 914 915
		u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);

		/* txgain table */
		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
916 917 918 919 920 921 922 923 924 925 926
			if (AR_SREV_9285E_20(ah)) {
				INIT_INI_ARRAY(&ah->iniModesTxGain,
				ar9285Modes_XE2_0_high_power,
				ARRAY_SIZE(
				  ar9285Modes_XE2_0_high_power), 6);
			} else {
				INIT_INI_ARRAY(&ah->iniModesTxGain,
				ar9285Modes_high_power_tx_gain_9285_1_2,
				ARRAY_SIZE(
				  ar9285Modes_high_power_tx_gain_9285_1_2), 6);
			}
927
		} else {
928 929 930 931 932 933 934 935 936 937 938
			if (AR_SREV_9285E_20(ah)) {
				INIT_INI_ARRAY(&ah->iniModesTxGain,
				ar9285Modes_XE2_0_normal_power,
				ARRAY_SIZE(
				  ar9285Modes_XE2_0_normal_power), 6);
			} else {
				INIT_INI_ARRAY(&ah->iniModesTxGain,
				ar9285Modes_original_tx_gain_9285_1_2,
				ARRAY_SIZE(
				  ar9285Modes_original_tx_gain_9285_1_2), 6);
			}
939 940
		}
	}
941
}
942

943
static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
944
{
945 946
	struct base_eep_header *pBase = &(ah->eeprom.def.baseEepHeader);
	struct ath_common *common = ath9k_hw_common(ah);
947

948
	ah->need_an_top2_fixup = (ah->hw_version.devid == AR9280_DEVID_PCI) &&
949
				 !AR_SREV_9285(ah) && !AR_SREV_9271(ah) &&
950 951
				 ((pBase->version & 0xff) > 0x0a) &&
				 (pBase->pwdclkind == 0);
952

953 954 955
	if (ah->need_an_top2_fixup)
		ath_print(common, ATH_DBG_EEPROM,
			  "needs fixup for AR_AN_TOP2 register\n");
956 957
}

958 959 960 961 962 963 964 965
static void ath9k_hw_attach_ops(struct ath_hw *ah)
{
	if (AR_SREV_9300_20_OR_LATER(ah))
		ar9003_hw_attach_ops(ah);
	else
		ar9002_hw_attach_ops(ah);
}

966 967
/* Called for all hardware families */
static int __ath9k_hw_init(struct ath_hw *ah)
968
{
969
	struct ath_common *common = ath9k_hw_common(ah);
970
	int r = 0;
971

972 973
	if (ah->hw_version.devid == AR5416_AR9100_DEVID)
		ah->hw_version.macVersion = AR_SREV_VERSION_9100;
974 975

	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
976 977
		ath_print(common, ATH_DBG_FATAL,
			  "Couldn't reset chip\n");
978
		return -EIO;
979 980
	}

981 982 983
	ath9k_hw_init_defaults(ah);
	ath9k_hw_init_config(ah);

984
	ath9k_hw_attach_ops(ah);
985

986
	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
987
		ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
988
		return -EIO;
989 990 991 992 993 994 995 996 997 998 999 1000 1001
	}

	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
		    (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
			ah->config.serialize_regmode =
				SER_REG_MODE_ON;
		} else {
			ah->config.serialize_regmode =
				SER_REG_MODE_OFF;
		}
	}

1002
	ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
1003 1004
		ah->config.serialize_regmode);

1005 1006 1007 1008 1009
	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
		ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
	else
		ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;

1010
	if (!ath9k_hw_macversion_supported(ah)) {
1011 1012 1013 1014
		ath_print(common, ATH_DBG_FATAL,
			  "Mac Chip Rev 0x%02x.%x is not supported by "
			  "this driver\n", ah->hw_version.macVersion,
			  ah->hw_version.macRev);
1015
		return -EOPNOTSUPP;
1016 1017 1018 1019 1020 1021 1022
	}

	if (AR_SREV_9100(ah)) {
		ah->iq_caldata.calData = &iq_cal_multi_sample;
		ah->supp_cals = IQ_MISMATCH_CAL;
		ah->is_pciexpress = false;
	}
1023 1024 1025 1026

	if (AR_SREV_9271(ah))
		ah->is_pciexpress = false;

1027 1028 1029 1030
	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
	ath9k_hw_init_cal_settings(ah);

	ah->ani_function = ATH9K_ANI_ALL;
1031
	if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
1032 1033 1034 1035 1036
		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;

	ath9k_hw_init_mode_regs(ah);

	if (ah->is_pciexpress)
V
Vivek Natarajan 已提交
1037
		ath9k_hw_configpcipowersave(ah, 0, 0);
1038 1039 1040
	else
		ath9k_hw_disablepcie(ah);

S
Sujith 已提交
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
	/* Support for Japan ch.14 (2484) spread */
	if (AR_SREV_9287_11_OR_LATER(ah)) {
		INIT_INI_ARRAY(&ah->iniCckfirNormal,
		       ar9287Common_normal_cck_fir_coeff_92871_1,
		       ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), 2);
		INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
		       ar9287Common_japan_2484_cck_fir_coeff_92871_1,
		       ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), 2);
	}

1051
	r = ath9k_hw_post_init(ah);
1052
	if (r)
1053
		return r;
1054 1055

	ath9k_hw_init_mode_gain_regs(ah);
1056 1057 1058 1059
	r = ath9k_hw_fill_cap_info(ah);
	if (r)
		return r;

1060
	ath9k_hw_init_eeprom_fix(ah);
1061

1062 1063
	r = ath9k_hw_init_macaddr(ah);
	if (r) {
1064 1065
		ath_print(common, ATH_DBG_FATAL,
			  "Failed to initialize MAC address\n");
1066
		return r;
1067 1068
	}

1069
	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
1070
		ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
S
Sujith 已提交
1071
	else
1072
		ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
1073

1074 1075 1076
	if (AR_SREV_9300_20_OR_LATER(ah))
		ar9003_hw_set_nf_limits(ah);

S
Sujith 已提交
1077
	ath9k_init_nfcal_hist_buffer(ah);
1078

1079 1080
	common->state = ATH_HW_INITIALIZED;

1081
	return 0;
1082 1083
}

1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
int ath9k_hw_init(struct ath_hw *ah)
{
	int ret;
	struct ath_common *common = ath9k_hw_common(ah);

	/* These are all the AR5008/AR9001/AR9002 hardware family of chipsets */
	switch (ah->hw_version.devid) {
	case AR5416_DEVID_PCI:
	case AR5416_DEVID_PCIE:
	case AR5416_AR9100_DEVID:
	case AR9160_DEVID_PCI:
	case AR9280_DEVID_PCI:
	case AR9280_DEVID_PCIE:
	case AR9285_DEVID_PCIE:
1098 1099
	case AR9287_DEVID_PCI:
	case AR9287_DEVID_PCIE:
1100
	case AR2427_DEVID_PCIE:
1101
	case AR9300_DEVID_PCIE:
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
		break;
	default:
		if (common->bus_ops->ath_bus_type == ATH_USB)
			break;
		ath_print(common, ATH_DBG_FATAL,
			  "Hardware device ID 0x%04x not supported\n",
			  ah->hw_version.devid);
		return -EOPNOTSUPP;
	}

	ret = __ath9k_hw_init(ah);
	if (ret) {
		ath_print(common, ATH_DBG_FATAL,
			  "Unable to initialize hardware; "
			  "initialization status: %d\n", ret);
		return ret;
	}

	return 0;
}
EXPORT_SYMBOL(ath9k_hw_init);

1124
static void ath9k_hw_init_qos(struct ath_hw *ah)
1125
{
S
Sujith 已提交
1126 1127
	REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
	REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
1128

S
Sujith 已提交
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
	REG_WRITE(ah, AR_QOS_NO_ACK,
		  SM(2, AR_QOS_NO_ACK_TWO_BIT) |
		  SM(5, AR_QOS_NO_ACK_BIT_OFF) |
		  SM(0, AR_QOS_NO_ACK_BYTE_OFF));

	REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
	REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
	REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
	REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
	REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
1139 1140
}

1141
static void ath9k_hw_init_pll(struct ath_hw *ah,
S
Sujith 已提交
1142
			      struct ath9k_channel *chan)
1143
{
1144
	u32 pll = ath9k_hw_compute_pll_control(ah, chan);
1145

1146
	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
1147

1148 1149
	/* Switch the core clock for ar9271 to 117Mhz */
	if (AR_SREV_9271(ah)) {
1150 1151
		udelay(500);
		REG_WRITE(ah, 0x50040, 0x304);
1152 1153
	}

S
Sujith 已提交
1154 1155 1156
	udelay(RTC_PLL_SETTLE_DELAY);

	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
1157 1158
}

1159
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1160
					  enum nl80211_iftype opmode)
1161
{
1162
	u32 imr_reg = AR_IMR_TXERR |
S
Sujith 已提交
1163 1164 1165 1166
		AR_IMR_TXURN |
		AR_IMR_RXERR |
		AR_IMR_RXORN |
		AR_IMR_BCNMISC;
1167

S
Sujith 已提交
1168
	if (ah->config.rx_intr_mitigation)
1169
		imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
1170
	else
1171
		imr_reg |= AR_IMR_RXOK;
1172

1173
	imr_reg |= AR_IMR_TXOK;
1174

1175
	if (opmode == NL80211_IFTYPE_AP)
1176
		imr_reg |= AR_IMR_MIB;
1177

1178
	REG_WRITE(ah, AR_IMR, imr_reg);
1179 1180
	ah->imrs2_reg |= AR_IMR_S2_GTT;
	REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
1181

S
Sujith 已提交
1182 1183 1184 1185 1186
	if (!AR_SREV_9100(ah)) {
		REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
		REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
	}
1187 1188
}

1189
static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
1190
{
1191 1192 1193
	u32 val = ath9k_hw_mac_to_clks(ah, us);
	val = min(val, (u32) 0xFFFF);
	REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
1194 1195
}

1196
static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
1197
{
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207
	u32 val = ath9k_hw_mac_to_clks(ah, us);
	val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
	REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
}

static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
{
	u32 val = ath9k_hw_mac_to_clks(ah, us);
	val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
	REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
1208
}
S
Sujith 已提交
1209

1210
static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
1211 1212
{
	if (tu > 0xFFFF) {
1213 1214
		ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
			  "bad global tx timeout %u\n", tu);
1215
		ah->globaltxtimeout = (u32) -1;
1216 1217 1218
		return false;
	} else {
		REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
1219
		ah->globaltxtimeout = tu;
1220 1221 1222 1223
		return true;
	}
}

1224
void ath9k_hw_init_global_settings(struct ath_hw *ah)
1225
{
1226 1227
	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
	int acktimeout;
1228
	int slottime;
1229 1230
	int sifstime;

1231 1232
	ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
		  ah->misc_mode);
1233

1234
	if (ah->misc_mode != 0)
S
Sujith 已提交
1235
		REG_WRITE(ah, AR_PCU_MISC,
1236
			  REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
1237 1238 1239 1240 1241 1242

	if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
		sifstime = 16;
	else
		sifstime = 10;

1243 1244 1245
	/* As defined by IEEE 802.11-2007 17.3.8.6 */
	slottime = ah->slottime + 3 * ah->coverage_class;
	acktimeout = slottime + sifstime;
1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256

	/*
	 * Workaround for early ACK timeouts, add an offset to match the
	 * initval's 64us ack timeout value.
	 * This was initially only meant to work around an issue with delayed
	 * BA frames in some implementations, but it has been found to fix ACK
	 * timeout issues in other cases as well.
	 */
	if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
		acktimeout += 64 - sifstime - ah->slottime;

1257
	ath9k_hw_setslottime(ah, slottime);
1258 1259
	ath9k_hw_set_ack_timeout(ah, acktimeout);
	ath9k_hw_set_cts_timeout(ah, acktimeout);
1260 1261
	if (ah->globaltxtimeout != (u32) -1)
		ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
S
Sujith 已提交
1262
}
1263
EXPORT_SYMBOL(ath9k_hw_init_global_settings);
S
Sujith 已提交
1264

S
Sujith 已提交
1265
void ath9k_hw_deinit(struct ath_hw *ah)
S
Sujith 已提交
1266
{
1267 1268
	struct ath_common *common = ath9k_hw_common(ah);

S
Sujith 已提交
1269
	if (common->state < ATH_HW_INITIALIZED)
1270 1271
		goto free_hw;

S
Sujith 已提交
1272
	if (!AR_SREV_9100(ah))
1273
		ath9k_hw_ani_disable(ah);
S
Sujith 已提交
1274

1275
	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
1276 1277

free_hw:
1278
	ath9k_hw_rf_free_ext_banks(ah);
S
Sujith 已提交
1279
}
S
Sujith 已提交
1280
EXPORT_SYMBOL(ath9k_hw_deinit);
S
Sujith 已提交
1281 1282 1283 1284 1285

/*******/
/* INI */
/*******/

1286
u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
{
	u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);

	if (IS_CHAN_B(chan))
		ctl |= CTL_11B;
	else if (IS_CHAN_G(chan))
		ctl |= CTL_11G;
	else
		ctl |= CTL_11A;

	return ctl;
}

S
Sujith 已提交
1300 1301 1302 1303
/****************************************/
/* Reset and Channel Switching Routines */
/****************************************/

1304
static inline void ath9k_hw_set_dma(struct ath_hw *ah)
S
Sujith 已提交
1305 1306 1307
{
	u32 regval;

1308 1309 1310
	/*
	 * set AHB_MODE not to do cacheline prefetches
	*/
S
Sujith 已提交
1311 1312 1313
	regval = REG_READ(ah, AR_AHB_MODE);
	REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);

1314 1315 1316
	/*
	 * let mac dma reads be in 128 byte chunks
	 */
S
Sujith 已提交
1317 1318 1319
	regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
	REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);

1320 1321 1322 1323 1324
	/*
	 * Restore TX Trigger Level to its pre-reset value.
	 * The initial value depends on whether aggregation is enabled, and is
	 * adjusted whenever underruns are detected.
	 */
1325
	REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
S
Sujith 已提交
1326

1327 1328 1329
	/*
	 * let mac dma writes be in 128 byte chunks
	 */
S
Sujith 已提交
1330 1331 1332
	regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
	REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);

1333 1334 1335
	/*
	 * Setup receive FIFO threshold to hold off TX activities
	 */
S
Sujith 已提交
1336 1337
	REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);

1338 1339 1340 1341
	/*
	 * reduce the number of usable entries in PCU TXBUF to avoid
	 * wrap around issues.
	 */
S
Sujith 已提交
1342
	if (AR_SREV_9285(ah)) {
1343 1344 1345 1346
		/* For AR9285 the number of Fifos are reduced to half.
		 * So set the usable tx buf size also to half to
		 * avoid data/delimiter underruns
		 */
S
Sujith 已提交
1347 1348
		REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
			  AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
1349
	} else if (!AR_SREV_9271(ah)) {
S
Sujith 已提交
1350 1351 1352 1353 1354
		REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
			  AR_PCU_TXBUF_CTRL_USABLE_SIZE);
	}
}

1355
static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
S
Sujith 已提交
1356 1357 1358 1359 1360 1361
{
	u32 val;

	val = REG_READ(ah, AR_STA_ID1);
	val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
	switch (opmode) {
1362
	case NL80211_IFTYPE_AP:
S
Sujith 已提交
1363 1364 1365
		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
			  | AR_STA_ID1_KSRCH_MODE);
		REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1366
		break;
1367
	case NL80211_IFTYPE_ADHOC:
1368
	case NL80211_IFTYPE_MESH_POINT:
S
Sujith 已提交
1369 1370 1371
		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
			  | AR_STA_ID1_KSRCH_MODE);
		REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1372
		break;
1373 1374
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_MONITOR:
S
Sujith 已提交
1375
		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1376
		break;
S
Sujith 已提交
1377 1378 1379
	}
}

1380 1381
void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
				   u32 *coef_mantissa, u32 *coef_exponent)
S
Sujith 已提交
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396
{
	u32 coef_exp, coef_man;

	for (coef_exp = 31; coef_exp > 0; coef_exp--)
		if ((coef_scaled >> coef_exp) & 0x1)
			break;

	coef_exp = 14 - (coef_exp - COEF_SCALE_S);

	coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));

	*coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
	*coef_exponent = coef_exp - 16;
}

1397
static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
S
Sujith 已提交
1398 1399 1400 1401
{
	u32 rst_flags;
	u32 tmpReg;

1402 1403 1404 1405 1406 1407 1408 1409
	if (AR_SREV_9100(ah)) {
		u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
		val &= ~AR_RTC_DERIVED_CLK_PERIOD;
		val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
		REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
		(void)REG_READ(ah, AR_RTC_DERIVED_CLK);
	}

S
Sujith 已提交
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420
	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
		  AR_RTC_FORCE_WAKE_ON_INT);

	if (AR_SREV_9100(ah)) {
		rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
			AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
	} else {
		tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
		if (tmpReg &
		    (AR_INTR_SYNC_LOCAL_TIMEOUT |
		     AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1421
			u32 val;
S
Sujith 已提交
1422
			REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1423 1424 1425 1426 1427 1428 1429

			val = AR_RC_HOSTIF;
			if (!AR_SREV_9300_20_OR_LATER(ah))
				val |= AR_RC_AHB;
			REG_WRITE(ah, AR_RC, val);

		} else if (!AR_SREV_9300_20_OR_LATER(ah))
S
Sujith 已提交
1430 1431 1432 1433 1434 1435 1436
			REG_WRITE(ah, AR_RC, AR_RC_AHB);

		rst_flags = AR_RTC_RC_MAC_WARM;
		if (type == ATH9K_RESET_COLD)
			rst_flags |= AR_RTC_RC_MAC_COLD;
	}

1437
	REG_WRITE(ah, AR_RTC_RC, rst_flags);
S
Sujith 已提交
1438 1439
	udelay(50);

1440
	REG_WRITE(ah, AR_RTC_RC, 0);
S
Sujith 已提交
1441
	if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
1442 1443
		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
			  "RTC stuck in MAC reset\n");
S
Sujith 已提交
1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455
		return false;
	}

	if (!AR_SREV_9100(ah))
		REG_WRITE(ah, AR_RC, 0);

	if (AR_SREV_9100(ah))
		udelay(50);

	return true;
}

1456
static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
S
Sujith 已提交
1457 1458 1459 1460
{
	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
		  AR_RTC_FORCE_WAKE_ON_INT);

1461
	if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
1462 1463
		REG_WRITE(ah, AR_RC, AR_RC_AHB);

1464
	REG_WRITE(ah, AR_RTC_RESET, 0);
1465

1466 1467 1468 1469
	if (!AR_SREV_9300_20_OR_LATER(ah))
		udelay(2);

	if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
1470 1471
		REG_WRITE(ah, AR_RC, 0);

1472
	REG_WRITE(ah, AR_RTC_RESET, 1);
S
Sujith 已提交
1473 1474 1475 1476

	if (!ath9k_hw_wait(ah,
			   AR_RTC_STATUS,
			   AR_RTC_STATUS_M,
S
Sujith 已提交
1477 1478
			   AR_RTC_STATUS_ON,
			   AH_WAIT_TIMEOUT)) {
1479 1480
		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
			  "RTC not waking up\n");
S
Sujith 已提交
1481
		return false;
1482 1483
	}

S
Sujith 已提交
1484 1485 1486 1487 1488
	ath9k_hw_read_revisions(ah);

	return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
}

1489
static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
S
Sujith 已提交
1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502
{
	REG_WRITE(ah, AR_RTC_FORCE_WAKE,
		  AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);

	switch (type) {
	case ATH9K_RESET_POWER_ON:
		return ath9k_hw_set_reset_power_on(ah);
	case ATH9K_RESET_WARM:
	case ATH9K_RESET_COLD:
		return ath9k_hw_set_reset(ah, type);
	default:
		return false;
	}
1503 1504
}

1505
static bool ath9k_hw_chip_reset(struct ath_hw *ah,
S
Sujith 已提交
1506
				struct ath9k_channel *chan)
1507
{
1508
	if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) {
1509 1510 1511
		if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
			return false;
	} else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
S
Sujith 已提交
1512
		return false;
1513

1514
	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
S
Sujith 已提交
1515
		return false;
1516

1517
	ah->chip_fullsleep = false;
S
Sujith 已提交
1518 1519
	ath9k_hw_init_pll(ah, chan);
	ath9k_hw_set_rfmode(ah, chan);
1520

S
Sujith 已提交
1521
	return true;
1522 1523
}

1524
static bool ath9k_hw_channel_change(struct ath_hw *ah,
L
Luis R. Rodriguez 已提交
1525
				    struct ath9k_channel *chan)
1526
{
1527
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1528
	struct ath_common *common = ath9k_hw_common(ah);
1529
	struct ieee80211_channel *channel = chan->chan;
1530
	u32 qnum;
1531
	int r;
1532 1533 1534

	for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
		if (ath9k_hw_numtxpending(ah, qnum)) {
1535 1536 1537
			ath_print(common, ATH_DBG_QUEUE,
				  "Transmit frames pending on "
				  "queue %d\n", qnum);
1538 1539 1540 1541
			return false;
		}
	}

1542
	if (!ath9k_hw_rfbus_req(ah)) {
1543 1544
		ath_print(common, ATH_DBG_FATAL,
			  "Could not kill baseband RX\n");
1545 1546 1547
		return false;
	}

1548
	ath9k_hw_set_channel_regs(ah, chan);
1549

1550
	r = ath9k_hw_rf_set_freq(ah, chan);
1551 1552 1553 1554
	if (r) {
		ath_print(common, ATH_DBG_FATAL,
			  "Failed to set channel\n");
		return false;
1555 1556
	}

1557
	ah->eep_ops->set_txpower(ah, chan,
1558
			     ath9k_regd_get_ctl(regulatory, chan),
S
Sujith 已提交
1559 1560 1561
			     channel->max_antenna_gain * 2,
			     channel->max_power * 2,
			     min((u32) MAX_RATE_POWER,
1562
			     (u32) regulatory->power_limit));
1563

1564
	ath9k_hw_rfbus_done(ah);
1565

S
Sujith 已提交
1566 1567 1568
	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
		ath9k_hw_set_delta_slope(ah, chan);

1569
	ath9k_hw_spur_mitigate_freq(ah, chan);
S
Sujith 已提交
1570 1571 1572 1573 1574 1575 1576

	if (!chan->oneTimeCalsDone)
		chan->oneTimeCalsDone = true;

	return true;
}

1577
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1578
		    bool bChannelChange)
1579
{
1580
	struct ath_common *common = ath9k_hw_common(ah);
1581
	u32 saveLedState;
1582
	struct ath9k_channel *curchan = ah->curchan;
1583 1584
	u32 saveDefAntenna;
	u32 macStaId1;
S
Sujith 已提交
1585
	u64 tsf = 0;
1586
	int i, r;
1587

1588 1589
	ah->txchainmask = common->tx_chainmask;
	ah->rxchainmask = common->rx_chainmask;
1590

1591
	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
1592
		return -EIO;
1593

1594
	if (curchan && !ah->chip_fullsleep)
1595 1596 1597
		ath9k_hw_getnf(ah, curchan);

	if (bChannelChange &&
1598 1599 1600
	    (ah->chip_fullsleep != true) &&
	    (ah->curchan != NULL) &&
	    (chan->channel != ah->curchan->channel) &&
1601
	    ((chan->channelFlags & CHANNEL_ALL) ==
1602
	     (ah->curchan->channelFlags & CHANNEL_ALL)) &&
1603 1604
	     !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) ||
	     IS_CHAN_A_5MHZ_SPACED(ah->curchan))) {
1605

L
Luis R. Rodriguez 已提交
1606
		if (ath9k_hw_channel_change(ah, chan)) {
1607
			ath9k_hw_loadnf(ah, ah->curchan);
1608
			ath9k_hw_start_nfcal(ah);
1609
			return 0;
1610 1611 1612 1613 1614 1615 1616 1617 1618
		}
	}

	saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
	if (saveDefAntenna == 0)
		saveDefAntenna = 1;

	macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;

S
Sujith 已提交
1619 1620 1621 1622
	/* For chips on which RTC reset is done, save TSF before it gets cleared */
	if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
		tsf = ath9k_hw_gettsf64(ah);

1623 1624 1625 1626 1627 1628
	saveLedState = REG_READ(ah, AR_CFG_LED) &
		(AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
		 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);

	ath9k_hw_mark_phy_inactive(ah);

1629
	/* Only required on the first reset */
1630 1631 1632 1633 1634 1635 1636
	if (AR_SREV_9271(ah) && ah->htc_reset_init) {
		REG_WRITE(ah,
			  AR9271_RESET_POWER_DOWN_CONTROL,
			  AR9271_RADIO_RF_RST);
		udelay(50);
	}

1637
	if (!ath9k_hw_chip_reset(ah, chan)) {
1638
		ath_print(common, ATH_DBG_FATAL, "Chip reset failed\n");
1639
		return -EINVAL;
1640 1641
	}

1642
	/* Only required on the first reset */
1643 1644 1645 1646 1647 1648 1649 1650
	if (AR_SREV_9271(ah) && ah->htc_reset_init) {
		ah->htc_reset_init = false;
		REG_WRITE(ah,
			  AR9271_RESET_POWER_DOWN_CONTROL,
			  AR9271_GATE_MAC_CTL);
		udelay(50);
	}

S
Sujith 已提交
1651 1652 1653 1654
	/* Restore TSF */
	if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
		ath9k_hw_settsf64(ah, tsf);

1655 1656
	if (AR_SREV_9280_10_OR_LATER(ah))
		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
1657

L
Luis R. Rodriguez 已提交
1658
	r = ath9k_hw_process_ini(ah, chan);
1659 1660
	if (r)
		return r;
1661

1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678
	/* Setup MFP options for CCMP */
	if (AR_SREV_9280_20_OR_LATER(ah)) {
		/* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
		 * frames when constructing CCMP AAD. */
		REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
			      0xc7ff);
		ah->sw_mgmt_crypto = false;
	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
		/* Disable hardware crypto for management frames */
		REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
			    AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
			    AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
		ah->sw_mgmt_crypto = true;
	} else
		ah->sw_mgmt_crypto = true;

1679 1680 1681
	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
		ath9k_hw_set_delta_slope(ah, chan);

1682
	ath9k_hw_spur_mitigate_freq(ah, chan);
1683
	ah->eep_ops->set_board_values(ah, chan);
1684

1685 1686
	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
	REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
1687 1688
		  | macStaId1
		  | AR_STA_ID1_RTS_USE_DEF
1689
		  | (ah->config.
1690
		     ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
1691 1692
		  | ah->sta_id1_defaults);
	ath9k_hw_set_operating_mode(ah, ah->opmode);
1693

1694
	ath_hw_setbssidmask(common);
1695 1696 1697

	REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);

1698
	ath9k_hw_write_associd(ah);
1699 1700 1701 1702 1703

	REG_WRITE(ah, AR_ISR, ~0);

	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);

1704
	r = ath9k_hw_rf_set_freq(ah, chan);
1705 1706
	if (r)
		return r;
1707 1708 1709 1710

	for (i = 0; i < AR_NUM_DCU; i++)
		REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);

1711 1712
	ah->intr_txqs = 0;
	for (i = 0; i < ah->caps.total_queues; i++)
1713 1714
		ath9k_hw_resettxqueue(ah, i);

1715
	ath9k_hw_init_interrupt_masks(ah, ah->opmode);
1716 1717
	ath9k_hw_init_qos(ah);

1718
	if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1719
		ath9k_enable_rfkill(ah);
J
Johannes Berg 已提交
1720

1721
	ath9k_hw_init_global_settings(ah);
1722

1723
	if (AR_SREV_9287_12_OR_LATER(ah)) {
1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738
		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
			  AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
		REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
			  AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
		REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
			  AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);

		REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
		REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);

		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
	}
1739
	if (AR_SREV_9287_12_OR_LATER(ah)) {
1740 1741 1742 1743
		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
				AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
	}

1744 1745 1746 1747 1748 1749 1750
	REG_WRITE(ah, AR_STA_ID1,
		  REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);

	ath9k_hw_set_dma(ah);

	REG_WRITE(ah, AR_OBS, 8);

S
Sujith 已提交
1751
	if (ah->config.rx_intr_mitigation) {
1752 1753 1754 1755 1756 1757
		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
	}

	ath9k_hw_init_bb(ah, chan);

1758
	if (!ath9k_hw_init_cal(ah, chan))
1759
		return -EIO;
1760

1761
	ath9k_hw_restore_chainmask(ah);
1762 1763
	REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);

1764 1765 1766
	/*
	 * For big endian systems turn on swapping for descriptors
	 */
1767 1768 1769 1770
	if (AR_SREV_9100(ah)) {
		u32 mask;
		mask = REG_READ(ah, AR_CFG);
		if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
1771
			ath_print(common, ATH_DBG_RESET,
S
Sujith 已提交
1772
				"CFG Byte Swap Set 0x%x\n", mask);
1773 1774 1775 1776
		} else {
			mask =
				INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
			REG_WRITE(ah, AR_CFG, mask);
1777
			ath_print(common, ATH_DBG_RESET,
S
Sujith 已提交
1778
				"Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
1779 1780
		}
	} else {
1781 1782 1783
		/* Configure AR9271 target WLAN */
                if (AR_SREV_9271(ah))
			REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
1784
#ifdef __BIG_ENDIAN
1785 1786
                else
			REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
1787 1788 1789
#endif
	}

1790
	if (ah->btcoex_hw.enabled)
1791 1792
		ath9k_hw_btcoex_enable(ah);

1793
	return 0;
1794
}
1795
EXPORT_SYMBOL(ath9k_hw_reset);
1796

S
Sujith 已提交
1797 1798 1799
/************************/
/* Key Cache Management */
/************************/
1800

1801
bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
1802
{
S
Sujith 已提交
1803
	u32 keyType;
1804

1805
	if (entry >= ah->caps.keycache_size) {
1806 1807
		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
			  "keychache entry %u out of range\n", entry);
1808 1809 1810
		return false;
	}

S
Sujith 已提交
1811
	keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
1812

S
Sujith 已提交
1813 1814 1815 1816 1817 1818 1819 1820
	REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
	REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
	REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
	REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
	REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
	REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
1821

S
Sujith 已提交
1822 1823
	if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
		u16 micentry = entry + 64;
1824

S
Sujith 已提交
1825 1826 1827 1828
		REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
		REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
		REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
		REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
1829 1830 1831 1832 1833

	}

	return true;
}
1834
EXPORT_SYMBOL(ath9k_hw_keyreset);
1835

1836
bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
1837
{
S
Sujith 已提交
1838
	u32 macHi, macLo;
1839

1840
	if (entry >= ah->caps.keycache_size) {
1841 1842
		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
			  "keychache entry %u out of range\n", entry);
S
Sujith 已提交
1843
		return false;
1844 1845
	}

S
Sujith 已提交
1846 1847 1848 1849 1850 1851 1852 1853 1854
	if (mac != NULL) {
		macHi = (mac[5] << 8) | mac[4];
		macLo = (mac[3] << 24) |
			(mac[2] << 16) |
			(mac[1] << 8) |
			mac[0];
		macLo >>= 1;
		macLo |= (macHi & 1) << 31;
		macHi >>= 1;
1855
	} else {
S
Sujith 已提交
1856
		macLo = macHi = 0;
1857
	}
S
Sujith 已提交
1858 1859
	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
1860

S
Sujith 已提交
1861
	return true;
1862
}
1863
EXPORT_SYMBOL(ath9k_hw_keysetmac);
1864

1865
bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
S
Sujith 已提交
1866
				 const struct ath9k_keyval *k,
J
Jouni Malinen 已提交
1867
				 const u8 *mac)
1868
{
1869
	const struct ath9k_hw_capabilities *pCap = &ah->caps;
1870
	struct ath_common *common = ath9k_hw_common(ah);
S
Sujith 已提交
1871 1872
	u32 key0, key1, key2, key3, key4;
	u32 keyType;
1873

S
Sujith 已提交
1874
	if (entry >= pCap->keycache_size) {
1875 1876
		ath_print(common, ATH_DBG_FATAL,
			  "keycache entry %u out of range\n", entry);
S
Sujith 已提交
1877
		return false;
1878 1879
	}

S
Sujith 已提交
1880 1881 1882 1883 1884 1885
	switch (k->kv_type) {
	case ATH9K_CIPHER_AES_OCB:
		keyType = AR_KEYTABLE_TYPE_AES;
		break;
	case ATH9K_CIPHER_AES_CCM:
		if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
1886 1887 1888
			ath_print(common, ATH_DBG_ANY,
				  "AES-CCM not supported by mac rev 0x%x\n",
				  ah->hw_version.macRev);
S
Sujith 已提交
1889 1890 1891 1892 1893 1894 1895 1896
			return false;
		}
		keyType = AR_KEYTABLE_TYPE_CCM;
		break;
	case ATH9K_CIPHER_TKIP:
		keyType = AR_KEYTABLE_TYPE_TKIP;
		if (ATH9K_IS_MIC_ENABLED(ah)
		    && entry + 64 >= pCap->keycache_size) {
1897 1898
			ath_print(common, ATH_DBG_ANY,
				  "entry %u inappropriate for TKIP\n", entry);
S
Sujith 已提交
1899 1900 1901 1902
			return false;
		}
		break;
	case ATH9K_CIPHER_WEP:
1903
		if (k->kv_len < WLAN_KEY_LEN_WEP40) {
1904 1905
			ath_print(common, ATH_DBG_ANY,
				  "WEP key length %u too small\n", k->kv_len);
S
Sujith 已提交
1906 1907
			return false;
		}
1908
		if (k->kv_len <= WLAN_KEY_LEN_WEP40)
S
Sujith 已提交
1909
			keyType = AR_KEYTABLE_TYPE_40;
1910
		else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
S
Sujith 已提交
1911 1912 1913 1914 1915 1916 1917 1918
			keyType = AR_KEYTABLE_TYPE_104;
		else
			keyType = AR_KEYTABLE_TYPE_128;
		break;
	case ATH9K_CIPHER_CLR:
		keyType = AR_KEYTABLE_TYPE_CLR;
		break;
	default:
1919 1920
		ath_print(common, ATH_DBG_FATAL,
			  "cipher %u not supported\n", k->kv_type);
S
Sujith 已提交
1921
		return false;
1922 1923
	}

J
Jouni Malinen 已提交
1924 1925 1926 1927 1928
	key0 = get_unaligned_le32(k->kv_val + 0);
	key1 = get_unaligned_le16(k->kv_val + 4);
	key2 = get_unaligned_le32(k->kv_val + 6);
	key3 = get_unaligned_le16(k->kv_val + 10);
	key4 = get_unaligned_le32(k->kv_val + 12);
1929
	if (k->kv_len <= WLAN_KEY_LEN_WEP104)
S
Sujith 已提交
1930
		key4 &= 0xff;
1931

1932 1933 1934 1935 1936 1937 1938
	/*
	 * Note: Key cache registers access special memory area that requires
	 * two 32-bit writes to actually update the values in the internal
	 * memory. Consequently, the exact order and pairs used here must be
	 * maintained.
	 */

S
Sujith 已提交
1939 1940
	if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
		u16 micentry = entry + 64;
1941

1942 1943 1944 1945 1946 1947
		/*
		 * Write inverted key[47:0] first to avoid Michael MIC errors
		 * on frames that could be sent or received at the same time.
		 * The correct key will be written in the end once everything
		 * else is ready.
		 */
S
Sujith 已提交
1948 1949
		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
1950 1951

		/* Write key[95:48] */
S
Sujith 已提交
1952 1953
		REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
		REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
1954 1955

		/* Write key[127:96] and key type */
S
Sujith 已提交
1956 1957
		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
1958 1959

		/* Write MAC address for the entry */
S
Sujith 已提交
1960
		(void) ath9k_hw_keysetmac(ah, entry, mac);
1961

1962
		if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974
			/*
			 * TKIP uses two key cache entries:
			 * Michael MIC TX/RX keys in the same key cache entry
			 * (idx = main index + 64):
			 * key0 [31:0] = RX key [31:0]
			 * key1 [15:0] = TX key [31:16]
			 * key1 [31:16] = reserved
			 * key2 [31:0] = RX key [63:32]
			 * key3 [15:0] = TX key [15:0]
			 * key3 [31:16] = reserved
			 * key4 [31:0] = TX key [63:32]
			 */
S
Sujith 已提交
1975
			u32 mic0, mic1, mic2, mic3, mic4;
1976

S
Sujith 已提交
1977 1978 1979 1980 1981
			mic0 = get_unaligned_le32(k->kv_mic + 0);
			mic2 = get_unaligned_le32(k->kv_mic + 4);
			mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
			mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
			mic4 = get_unaligned_le32(k->kv_txmic + 4);
1982 1983

			/* Write RX[31:0] and TX[31:16] */
S
Sujith 已提交
1984 1985
			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
1986 1987

			/* Write RX[63:32] and TX[15:0] */
S
Sujith 已提交
1988 1989
			REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
			REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
1990 1991

			/* Write TX[63:32] and keyType(reserved) */
S
Sujith 已提交
1992 1993 1994
			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
				  AR_KEYTABLE_TYPE_CLR);
1995

S
Sujith 已提交
1996
		} else {
1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
			/*
			 * TKIP uses four key cache entries (two for group
			 * keys):
			 * Michael MIC TX/RX keys are in different key cache
			 * entries (idx = main index + 64 for TX and
			 * main index + 32 + 96 for RX):
			 * key0 [31:0] = TX/RX MIC key [31:0]
			 * key1 [31:0] = reserved
			 * key2 [31:0] = TX/RX MIC key [63:32]
			 * key3 [31:0] = reserved
			 * key4 [31:0] = reserved
			 *
			 * Upper layer code will call this function separately
			 * for TX and RX keys when these registers offsets are
			 * used.
			 */
S
Sujith 已提交
2013
			u32 mic0, mic2;
2014

S
Sujith 已提交
2015 2016
			mic0 = get_unaligned_le32(k->kv_mic + 0);
			mic2 = get_unaligned_le32(k->kv_mic + 4);
2017 2018

			/* Write MIC key[31:0] */
S
Sujith 已提交
2019 2020
			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
2021 2022

			/* Write MIC key[63:32] */
S
Sujith 已提交
2023 2024
			REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
			REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
2025 2026

			/* Write TX[63:32] and keyType(reserved) */
S
Sujith 已提交
2027 2028 2029 2030
			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
				  AR_KEYTABLE_TYPE_CLR);
		}
2031 2032

		/* MAC address registers are reserved for the MIC entry */
S
Sujith 已提交
2033 2034
		REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
		REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
2035 2036 2037 2038 2039 2040

		/*
		 * Write the correct (un-inverted) key[47:0] last to enable
		 * TKIP now that all other registers are set with correct
		 * values.
		 */
S
Sujith 已提交
2041 2042 2043
		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
	} else {
2044
		/* Write key[47:0] */
S
Sujith 已提交
2045 2046
		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
2047 2048

		/* Write key[95:48] */
S
Sujith 已提交
2049 2050
		REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
		REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
2051 2052

		/* Write key[127:96] and key type */
S
Sujith 已提交
2053 2054
		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
2055

2056
		/* Write MAC address for the entry */
S
Sujith 已提交
2057 2058
		(void) ath9k_hw_keysetmac(ah, entry, mac);
	}
2059 2060 2061

	return true;
}
2062
EXPORT_SYMBOL(ath9k_hw_set_keycache_entry);
2063

2064
bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
2065
{
2066
	if (entry < ah->caps.keycache_size) {
S
Sujith 已提交
2067 2068 2069 2070 2071
		u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
		if (val & AR_KEYTABLE_VALID)
			return true;
	}
	return false;
2072
}
2073
EXPORT_SYMBOL(ath9k_hw_keyisvalid);
2074

S
Sujith 已提交
2075 2076 2077 2078
/******************************/
/* Power Management (Chipset) */
/******************************/

2079 2080 2081 2082
/*
 * Notify Power Mgt is disabled in self-generated frames.
 * If requested, force chip to sleep.
 */
2083
static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
2084
{
S
Sujith 已提交
2085 2086
	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
	if (setChip) {
2087 2088 2089 2090
		/*
		 * Clear the RTC force wake bit to allow the
		 * mac to go to sleep.
		 */
S
Sujith 已提交
2091 2092
		REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
			    AR_RTC_FORCE_WAKE_EN);
2093
		if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
S
Sujith 已提交
2094
			REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
2095

2096
		/* Shutdown chip. Active low */
2097
		if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
S
Sujith 已提交
2098 2099
			REG_CLR_BIT(ah, (AR_RTC_RESET),
				    AR_RTC_RESET_EN);
S
Sujith 已提交
2100
	}
2101 2102
}

2103 2104 2105 2106 2107
/*
 * Notify Power Management is enabled in self-generating
 * frames. If request, set power mode of chip to
 * auto/normal.  Duration in units of 128us (1/8 TU).
 */
2108
static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
2109
{
S
Sujith 已提交
2110 2111
	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
	if (setChip) {
2112
		struct ath9k_hw_capabilities *pCap = &ah->caps;
2113

S
Sujith 已提交
2114
		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2115
			/* Set WakeOnInterrupt bit; clear ForceWake bit */
S
Sujith 已提交
2116 2117 2118
			REG_WRITE(ah, AR_RTC_FORCE_WAKE,
				  AR_RTC_FORCE_WAKE_ON_INT);
		} else {
2119 2120 2121 2122
			/*
			 * Clear the RTC force wake bit to allow the
			 * mac to go to sleep.
			 */
S
Sujith 已提交
2123 2124
			REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
				    AR_RTC_FORCE_WAKE_EN);
2125 2126 2127 2128
		}
	}
}

2129
static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
2130
{
S
Sujith 已提交
2131 2132
	u32 val;
	int i;
2133

S
Sujith 已提交
2134 2135 2136 2137 2138 2139 2140
	if (setChip) {
		if ((REG_READ(ah, AR_RTC_STATUS) &
		     AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
			if (ath9k_hw_set_reset_reg(ah,
					   ATH9K_RESET_POWER_ON) != true) {
				return false;
			}
2141 2142
			if (!AR_SREV_9300_20_OR_LATER(ah))
				ath9k_hw_init_pll(ah, NULL);
S
Sujith 已提交
2143 2144 2145 2146
		}
		if (AR_SREV_9100(ah))
			REG_SET_BIT(ah, AR_RTC_RESET,
				    AR_RTC_RESET_EN);
2147

S
Sujith 已提交
2148 2149 2150
		REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
			    AR_RTC_FORCE_WAKE_EN);
		udelay(50);
2151

S
Sujith 已提交
2152 2153 2154 2155 2156 2157 2158
		for (i = POWER_UP_TIME / 50; i > 0; i--) {
			val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
			if (val == AR_RTC_STATUS_ON)
				break;
			udelay(50);
			REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
				    AR_RTC_FORCE_WAKE_EN);
2159
		}
S
Sujith 已提交
2160
		if (i == 0) {
2161 2162 2163
			ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
				  "Failed to wakeup in %uus\n",
				  POWER_UP_TIME / 20);
S
Sujith 已提交
2164
			return false;
2165 2166 2167
		}
	}

S
Sujith 已提交
2168
	REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
2169

S
Sujith 已提交
2170
	return true;
2171 2172
}

2173
bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
2174
{
2175
	struct ath_common *common = ath9k_hw_common(ah);
2176
	int status = true, setChip = true;
S
Sujith 已提交
2177 2178 2179 2180 2181 2182 2183
	static const char *modes[] = {
		"AWAKE",
		"FULL-SLEEP",
		"NETWORK SLEEP",
		"UNDEFINED"
	};

2184 2185 2186
	if (ah->power_mode == mode)
		return status;

2187 2188
	ath_print(common, ATH_DBG_RESET, "%s -> %s\n",
		  modes[ah->power_mode], modes[mode]);
S
Sujith 已提交
2189 2190 2191 2192 2193 2194 2195

	switch (mode) {
	case ATH9K_PM_AWAKE:
		status = ath9k_hw_set_power_awake(ah, setChip);
		break;
	case ATH9K_PM_FULL_SLEEP:
		ath9k_set_power_sleep(ah, setChip);
2196
		ah->chip_fullsleep = true;
S
Sujith 已提交
2197 2198 2199 2200
		break;
	case ATH9K_PM_NETWORK_SLEEP:
		ath9k_set_power_network_sleep(ah, setChip);
		break;
2201
	default:
2202 2203
		ath_print(common, ATH_DBG_FATAL,
			  "Unknown power mode %u\n", mode);
2204 2205
		return false;
	}
2206
	ah->power_mode = mode;
S
Sujith 已提交
2207 2208

	return status;
2209
}
2210
EXPORT_SYMBOL(ath9k_hw_setpower);
2211

2212 2213 2214 2215 2216 2217 2218 2219 2220
/*
 * Helper for ASPM support.
 *
 * Disable PLL when in L0s as well as receiver clock when in L1.
 * This power saving option must be enabled through the SerDes.
 *
 * Programming the SerDes must go through the same 288 bit serial shift
 * register as the other analog registers.  Hence the 9 writes.
 */
2221 2222 2223
static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
					 int restore,
					 int power_off)
2224
{
S
Sujith 已提交
2225
	u8 i;
V
Vivek Natarajan 已提交
2226
	u32 val;
2227

2228
	if (ah->is_pciexpress != true)
S
Sujith 已提交
2229
		return;
2230

2231
	/* Do not touch SerDes registers */
2232
	if (ah->config.pcie_powersave_enable == 2)
S
Sujith 已提交
2233 2234
		return;

2235
	/* Nothing to do on restore for 11N */
V
Vivek Natarajan 已提交
2236 2237 2238 2239 2240
	if (!restore) {
		if (AR_SREV_9280_20_OR_LATER(ah)) {
			/*
			 * AR9280 2.0 or later chips use SerDes values from the
			 * initvals.h initialized depending on chipset during
2241
			 * __ath9k_hw_init()
V
Vivek Natarajan 已提交
2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
			 */
			for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
				REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
					  INI_RA(&ah->iniPcieSerdes, i, 1));
			}
		} else if (AR_SREV_9280(ah) &&
			   (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
			REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
			REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);

			/* RX shut off when elecidle is asserted */
			REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
			REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
			REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);

			/* Shut off CLKREQ active in L1 */
			if (ah->config.pcie_clock_req)
				REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
			else
				REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
S
Sujith 已提交
2262

V
Vivek Natarajan 已提交
2263 2264 2265
			REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
			REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
			REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
S
Sujith 已提交
2266

V
Vivek Natarajan 已提交
2267 2268
			/* Load the new settings */
			REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
S
Sujith 已提交
2269

V
Vivek Natarajan 已提交
2270 2271 2272
		} else {
			REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
			REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
S
Sujith 已提交
2273

V
Vivek Natarajan 已提交
2274 2275 2276 2277
			/* RX shut off when elecidle is asserted */
			REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
			REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
			REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
S
Sujith 已提交
2278

V
Vivek Natarajan 已提交
2279 2280 2281 2282 2283
			/*
			 * Ignore ah->ah_config.pcie_clock_req setting for
			 * pre-AR9280 11n
			 */
			REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
2284

V
Vivek Natarajan 已提交
2285 2286 2287
			REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
			REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
			REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
2288

V
Vivek Natarajan 已提交
2289 2290 2291
			/* Load the new settings */
			REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
		}
2292

V
Vivek Natarajan 已提交
2293
		udelay(1000);
2294

V
Vivek Natarajan 已提交
2295 2296
		/* set bit 19 to allow forcing of pcie core into L1 state */
		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
2297

V
Vivek Natarajan 已提交
2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319
		/* Several PCIe massages to ensure proper behaviour */
		if (ah->config.pcie_waen) {
			val = ah->config.pcie_waen;
			if (!power_off)
				val &= (~AR_WA_D3_L1_DISABLE);
		} else {
			if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
			    AR_SREV_9287(ah)) {
				val = AR9285_WA_DEFAULT;
				if (!power_off)
					val &= (~AR_WA_D3_L1_DISABLE);
			} else if (AR_SREV_9280(ah)) {
				/*
				 * On AR9280 chips bit 22 of 0x4004 needs to be
				 * set otherwise card may disappear.
				 */
				val = AR9280_WA_DEFAULT;
				if (!power_off)
					val &= (~AR_WA_D3_L1_DISABLE);
			} else
				val = AR_WA_DEFAULT;
		}
2320

V
Vivek Natarajan 已提交
2321 2322
		REG_WRITE(ah, AR_WA, val);
	}
S
Sujith 已提交
2323

V
Vivek Natarajan 已提交
2324
	if (power_off) {
2325
		/*
V
Vivek Natarajan 已提交
2326 2327 2328 2329
		 * Set PCIe workaround bits
		 * bit 14 in WA register (disable L1) should only
		 * be set when device enters D3 and be cleared
		 * when device comes back to D0.
2330
		 */
V
Vivek Natarajan 已提交
2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342
		if (ah->config.pcie_waen) {
			if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
				REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
		} else {
			if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
			      AR_SREV_9287(ah)) &&
			     (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
			    (AR_SREV_9280(ah) &&
			     (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
				REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
			}
		}
S
Sujith 已提交
2343
	}
2344 2345
}

S
Sujith 已提交
2346 2347 2348 2349
/**********************/
/* Interrupt Handling */
/**********************/

2350
bool ath9k_hw_intrpend(struct ath_hw *ah)
2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367
{
	u32 host_isr;

	if (AR_SREV_9100(ah))
		return true;

	host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
	if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
		return true;

	host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
	if ((host_isr & AR_INTR_SYNC_DEFAULT)
	    && (host_isr != AR_INTR_SPURIOUS))
		return true;

	return false;
}
2368
EXPORT_SYMBOL(ath9k_hw_intrpend);
2369

2370
bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
2371 2372 2373
{
	u32 isr = 0;
	u32 mask2 = 0;
2374
	struct ath9k_hw_capabilities *pCap = &ah->caps;
2375 2376
	u32 sync_cause = 0;
	bool fatal_int = false;
2377
	struct ath_common *common = ath9k_hw_common(ah);
2378 2379 2380 2381 2382 2383 2384 2385 2386

	if (!AR_SREV_9100(ah)) {
		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
			if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
			    == AR_RTC_STATUS_ON) {
				isr = REG_READ(ah, AR_ISR);
			}
		}

S
Sujith 已提交
2387 2388
		sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
			AR_INTR_SYNC_DEFAULT;
2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414

		*masked = 0;

		if (!isr && !sync_cause)
			return false;
	} else {
		*masked = 0;
		isr = REG_READ(ah, AR_ISR);
	}

	if (isr) {
		if (isr & AR_ISR_BCNMISC) {
			u32 isr2;
			isr2 = REG_READ(ah, AR_ISR_S2);
			if (isr2 & AR_ISR_S2_TIM)
				mask2 |= ATH9K_INT_TIM;
			if (isr2 & AR_ISR_S2_DTIM)
				mask2 |= ATH9K_INT_DTIM;
			if (isr2 & AR_ISR_S2_DTIMSYNC)
				mask2 |= ATH9K_INT_DTIMSYNC;
			if (isr2 & (AR_ISR_S2_CABEND))
				mask2 |= ATH9K_INT_CABEND;
			if (isr2 & AR_ISR_S2_GTT)
				mask2 |= ATH9K_INT_GTT;
			if (isr2 & AR_ISR_S2_CST)
				mask2 |= ATH9K_INT_CST;
2415 2416
			if (isr2 & AR_ISR_S2_TSFOOR)
				mask2 |= ATH9K_INT_TSFOOR;
2417 2418 2419 2420 2421 2422 2423 2424 2425 2426
		}

		isr = REG_READ(ah, AR_ISR_RAC);
		if (isr == 0xffffffff) {
			*masked = 0;
			return false;
		}

		*masked = isr & ATH9K_INT_COMMON;

S
Sujith 已提交
2427
		if (ah->config.rx_intr_mitigation) {
2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441
			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
				*masked |= ATH9K_INT_RX;
		}

		if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
			*masked |= ATH9K_INT_RX;
		if (isr &
		    (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
		     AR_ISR_TXEOL)) {
			u32 s0_s, s1_s;

			*masked |= ATH9K_INT_TX;

			s0_s = REG_READ(ah, AR_ISR_S0_S);
2442 2443
			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
2444 2445

			s1_s = REG_READ(ah, AR_ISR_S1_S);
2446 2447
			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
2448 2449 2450
		}

		if (isr & AR_ISR_RXORN) {
2451 2452
			ath_print(common, ATH_DBG_INTERRUPT,
				  "receive FIFO overrun interrupt\n");
2453 2454 2455
		}

		if (!AR_SREV_9100(ah)) {
2456
			if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2457 2458 2459 2460 2461 2462 2463 2464
				u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
				if (isr5 & AR_ISR_S5_TIM_TIMER)
					*masked |= ATH9K_INT_TIM_TIMER;
			}
		}

		*masked |= mask2;
	}
S
Sujith 已提交
2465

2466 2467
	if (AR_SREV_9100(ah))
		return true;
S
Sujith 已提交
2468

2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485
	if (isr & AR_ISR_GENTMR) {
		u32 s5_s;

		s5_s = REG_READ(ah, AR_ISR_S5_S);
		if (isr & AR_ISR_GENTMR) {
			ah->intr_gen_timer_trigger =
				MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);

			ah->intr_gen_timer_thresh =
				MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);

			if (ah->intr_gen_timer_trigger)
				*masked |= ATH9K_INT_GENTIMER;

		}
	}

2486 2487 2488 2489 2490 2491 2492 2493
	if (sync_cause) {
		fatal_int =
			(sync_cause &
			 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
			? true : false;

		if (fatal_int) {
			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
2494 2495
				ath_print(common, ATH_DBG_ANY,
					  "received PCI FATAL interrupt\n");
2496 2497
			}
			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
2498 2499
				ath_print(common, ATH_DBG_ANY,
					  "received PCI PERR interrupt\n");
2500
			}
2501
			*masked |= ATH9K_INT_FATAL;
2502 2503
		}
		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
2504 2505
			ath_print(common, ATH_DBG_INTERRUPT,
				  "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
2506 2507 2508 2509 2510
			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
			REG_WRITE(ah, AR_RC, 0);
			*masked |= ATH9K_INT_FATAL;
		}
		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
2511 2512
			ath_print(common, ATH_DBG_INTERRUPT,
				  "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
2513 2514 2515 2516 2517
		}

		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
	}
S
Sujith 已提交
2518

2519 2520
	return true;
}
2521
EXPORT_SYMBOL(ath9k_hw_getisr);
2522

2523
enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2524
{
2525
	enum ath9k_int omask = ah->imask;
2526
	u32 mask, mask2;
2527
	struct ath9k_hw_capabilities *pCap = &ah->caps;
2528
	struct ath_common *common = ath9k_hw_common(ah);
2529

2530
	ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
2531 2532

	if (omask & ATH9K_INT_GLOBAL) {
2533
		ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548
		REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
		(void) REG_READ(ah, AR_IER);
		if (!AR_SREV_9100(ah)) {
			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
			(void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);

			REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
			(void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
		}
	}

	mask = ints & ATH9K_INT_COMMON;
	mask2 = 0;

	if (ints & ATH9K_INT_TX) {
2549
		if (ah->txok_interrupt_mask)
2550
			mask |= AR_IMR_TXOK;
2551
		if (ah->txdesc_interrupt_mask)
2552
			mask |= AR_IMR_TXDESC;
2553
		if (ah->txerr_interrupt_mask)
2554
			mask |= AR_IMR_TXERR;
2555
		if (ah->txeol_interrupt_mask)
2556 2557 2558 2559
			mask |= AR_IMR_TXEOL;
	}
	if (ints & ATH9K_INT_RX) {
		mask |= AR_IMR_RXERR;
S
Sujith 已提交
2560
		if (ah->config.rx_intr_mitigation)
2561 2562 2563
			mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
		else
			mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
2564
		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576
			mask |= AR_IMR_GENTMR;
	}

	if (ints & (ATH9K_INT_BMISC)) {
		mask |= AR_IMR_BCNMISC;
		if (ints & ATH9K_INT_TIM)
			mask2 |= AR_IMR_S2_TIM;
		if (ints & ATH9K_INT_DTIM)
			mask2 |= AR_IMR_S2_DTIM;
		if (ints & ATH9K_INT_DTIMSYNC)
			mask2 |= AR_IMR_S2_DTIMSYNC;
		if (ints & ATH9K_INT_CABEND)
2577 2578 2579
			mask2 |= AR_IMR_S2_CABEND;
		if (ints & ATH9K_INT_TSFOOR)
			mask2 |= AR_IMR_S2_TSFOOR;
2580 2581 2582 2583 2584 2585 2586 2587 2588 2589
	}

	if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
		mask |= AR_IMR_BCNMISC;
		if (ints & ATH9K_INT_GTT)
			mask2 |= AR_IMR_S2_GTT;
		if (ints & ATH9K_INT_CST)
			mask2 |= AR_IMR_S2_CST;
	}

2590
	ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
2591
	REG_WRITE(ah, AR_IMR, mask);
2592 2593 2594 2595 2596
	ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
			   AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
			   AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
	ah->imrs2_reg |= mask2;
	REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
2597

2598
	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2599 2600 2601 2602 2603 2604 2605
		if (ints & ATH9K_INT_TIM_TIMER)
			REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
		else
			REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
	}

	if (ints & ATH9K_INT_GLOBAL) {
2606
		ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618
		REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
		if (!AR_SREV_9100(ah)) {
			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
				  AR_INTR_MAC_IRQ);
			REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);


			REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
				  AR_INTR_SYNC_DEFAULT);
			REG_WRITE(ah, AR_INTR_SYNC_MASK,
				  AR_INTR_SYNC_DEFAULT);
		}
2619 2620
		ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
			  REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
2621 2622 2623 2624
	}

	return omask;
}
2625
EXPORT_SYMBOL(ath9k_hw_set_interrupts);
2626

S
Sujith 已提交
2627 2628 2629 2630
/*******************/
/* Beacon Handling */
/*******************/

2631
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
2632 2633 2634
{
	int flags = 0;

2635
	ah->beacon_interval = beacon_period;
2636

2637
	switch (ah->opmode) {
2638 2639
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_MONITOR:
2640 2641 2642 2643 2644
		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
		REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
		flags |= AR_TBTT_TIMER_EN;
		break;
2645
	case NL80211_IFTYPE_ADHOC:
2646
	case NL80211_IFTYPE_MESH_POINT:
2647 2648 2649 2650
		REG_SET_BIT(ah, AR_TXCFG,
			    AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
		REG_WRITE(ah, AR_NEXT_NDP_TIMER,
			  TU_TO_USEC(next_beacon +
2651 2652
				     (ah->atim_window ? ah->
				      atim_window : 1)));
2653
		flags |= AR_NDP_TIMER_EN;
2654
	case NL80211_IFTYPE_AP:
2655 2656 2657
		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
			  TU_TO_USEC(next_beacon -
2658
				     ah->config.
2659
				     dma_beacon_response_time));
2660 2661
		REG_WRITE(ah, AR_NEXT_SWBA,
			  TU_TO_USEC(next_beacon -
2662
				     ah->config.
2663
				     sw_beacon_response_time));
2664 2665 2666
		flags |=
			AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
		break;
2667
	default:
2668 2669 2670
		ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON,
			  "%s: unsupported opmode: %d\n",
			  __func__, ah->opmode);
2671 2672
		return;
		break;
2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686
	}

	REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
	REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
	REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
	REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));

	beacon_period &= ~ATH9K_BEACON_ENA;
	if (beacon_period & ATH9K_BEACON_RESET_TSF) {
		ath9k_hw_reset_tsf(ah);
	}

	REG_SET_BIT(ah, AR_TIMER_MODE, flags);
}
2687
EXPORT_SYMBOL(ath9k_hw_beaconinit);
2688

2689
void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
S
Sujith 已提交
2690
				    const struct ath9k_beacon_state *bs)
2691 2692
{
	u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
2693
	struct ath9k_hw_capabilities *pCap = &ah->caps;
2694
	struct ath_common *common = ath9k_hw_common(ah);
2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719

	REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));

	REG_WRITE(ah, AR_BEACON_PERIOD,
		  TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
	REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
		  TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));

	REG_RMW_FIELD(ah, AR_RSSI_THR,
		      AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);

	beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;

	if (bs->bs_sleepduration > beaconintval)
		beaconintval = bs->bs_sleepduration;

	dtimperiod = bs->bs_dtimperiod;
	if (bs->bs_sleepduration > dtimperiod)
		dtimperiod = bs->bs_sleepduration;

	if (beaconintval == dtimperiod)
		nextTbtt = bs->bs_nextdtim;
	else
		nextTbtt = bs->bs_nexttbtt;

2720 2721 2722 2723
	ath_print(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
	ath_print(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
	ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
	ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
2724

S
Sujith 已提交
2725 2726 2727
	REG_WRITE(ah, AR_NEXT_DTIM,
		  TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
	REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
2728

S
Sujith 已提交
2729 2730 2731
	REG_WRITE(ah, AR_SLEEP1,
		  SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
		  | AR_SLEEP1_ASSUME_DTIM);
2732

S
Sujith 已提交
2733 2734 2735 2736
	if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
		beacontimeout = (BEACON_TIMEOUT_VAL << 3);
	else
		beacontimeout = MIN_BEACON_TIMEOUT_VAL;
2737

S
Sujith 已提交
2738 2739
	REG_WRITE(ah, AR_SLEEP2,
		  SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
2740

S
Sujith 已提交
2741 2742
	REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
	REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
2743

S
Sujith 已提交
2744 2745 2746
	REG_SET_BIT(ah, AR_TIMER_MODE,
		    AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
		    AR_DTIM_TIMER_EN);
2747

2748 2749
	/* TSF Out of Range Threshold */
	REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
2750
}
2751
EXPORT_SYMBOL(ath9k_hw_set_sta_beacon_timers);
2752

S
Sujith 已提交
2753 2754 2755 2756
/*******************/
/* HW Capabilities */
/*******************/

2757
int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2758
{
2759
	struct ath9k_hw_capabilities *pCap = &ah->caps;
2760
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
2761
	struct ath_common *common = ath9k_hw_common(ah);
2762
	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
2763

S
Sujith 已提交
2764
	u16 capField = 0, eeval;
2765

S
Sujith 已提交
2766
	eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
2767
	regulatory->current_rd = eeval;
2768

S
Sujith 已提交
2769
	eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
2770 2771
	if (AR_SREV_9285_10_OR_LATER(ah))
		eeval |= AR9285_RDEXT_DEFAULT;
2772
	regulatory->current_rd_ext = eeval;
2773

S
Sujith 已提交
2774
	capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
S
Sujith 已提交
2775

2776
	if (ah->opmode != NL80211_IFTYPE_AP &&
2777
	    ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
2778 2779 2780 2781 2782
		if (regulatory->current_rd == 0x64 ||
		    regulatory->current_rd == 0x65)
			regulatory->current_rd += 5;
		else if (regulatory->current_rd == 0x41)
			regulatory->current_rd = 0x43;
2783 2784
		ath_print(common, ATH_DBG_REGULATORY,
			  "regdomain mapped to 0x%x\n", regulatory->current_rd);
S
Sujith 已提交
2785
	}
2786

S
Sujith 已提交
2787
	eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
2788 2789 2790 2791 2792 2793
	if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
		ath_print(common, ATH_DBG_FATAL,
			  "no band has been marked as supported in EEPROM.\n");
		return -EINVAL;
	}

S
Sujith 已提交
2794
	bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
2795

S
Sujith 已提交
2796 2797
	if (eeval & AR5416_OPFLAGS_11A) {
		set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
2798
		if (ah->config.ht_enable) {
S
Sujith 已提交
2799 2800 2801 2802 2803 2804 2805 2806 2807
			if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
				set_bit(ATH9K_MODE_11NA_HT20,
					pCap->wireless_modes);
			if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
				set_bit(ATH9K_MODE_11NA_HT40PLUS,
					pCap->wireless_modes);
				set_bit(ATH9K_MODE_11NA_HT40MINUS,
					pCap->wireless_modes);
			}
2808 2809 2810
		}
	}

S
Sujith 已提交
2811 2812
	if (eeval & AR5416_OPFLAGS_11G) {
		set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
2813
		if (ah->config.ht_enable) {
S
Sujith 已提交
2814 2815 2816 2817 2818 2819 2820 2821 2822 2823
			if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
				set_bit(ATH9K_MODE_11NG_HT20,
					pCap->wireless_modes);
			if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
				set_bit(ATH9K_MODE_11NG_HT40PLUS,
					pCap->wireless_modes);
				set_bit(ATH9K_MODE_11NG_HT40MINUS,
					pCap->wireless_modes);
			}
		}
2824
	}
S
Sujith 已提交
2825

S
Sujith 已提交
2826
	pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
2827 2828 2829 2830
	/*
	 * For AR9271 we will temporarilly uses the rx chainmax as read from
	 * the EEPROM.
	 */
2831
	if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
2832 2833 2834
	    !(eeval & AR5416_OPFLAGS_11A) &&
	    !(AR_SREV_9271(ah)))
		/* CB71: GPIO 0 is pulled down to indicate 3 rx chains */
2835 2836
		pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
	else
2837
		/* Use rx_chainmask from EEPROM. */
2838
		pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
2839

2840
	if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
2841
		ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
2842

S
Sujith 已提交
2843 2844
	pCap->low_2ghz_chan = 2312;
	pCap->high_2ghz_chan = 2732;
2845

S
Sujith 已提交
2846 2847
	pCap->low_5ghz_chan = 4920;
	pCap->high_5ghz_chan = 6100;
2848

S
Sujith 已提交
2849 2850 2851
	pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
	pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
	pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
2852

S
Sujith 已提交
2853 2854 2855
	pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
	pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
	pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
2856

2857
	if (ah->config.ht_enable)
S
Sujith 已提交
2858 2859 2860
		pCap->hw_caps |= ATH9K_HW_CAP_HT;
	else
		pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
2861

S
Sujith 已提交
2862 2863 2864 2865
	pCap->hw_caps |= ATH9K_HW_CAP_GTT;
	pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
	pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
	pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
2866

S
Sujith 已提交
2867 2868 2869 2870 2871
	if (capField & AR_EEPROM_EEPCAP_MAXQCU)
		pCap->total_queues =
			MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
	else
		pCap->total_queues = ATH9K_NUM_TX_QUEUES;
2872

S
Sujith 已提交
2873 2874 2875 2876 2877
	if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
		pCap->keycache_size =
			1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
	else
		pCap->keycache_size = AR_KEYTABLE_SIZE;
2878

S
Sujith 已提交
2879
	pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
2880 2881 2882 2883 2884

	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
		pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
	else
		pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
2885

2886 2887 2888
	if (AR_SREV_9271(ah))
		pCap->num_gpio_pins = AR9271_NUM_GPIO;
	else if (AR_SREV_9285_10_OR_LATER(ah))
2889 2890
		pCap->num_gpio_pins = AR9285_NUM_GPIO;
	else if (AR_SREV_9280_10_OR_LATER(ah))
S
Sujith 已提交
2891 2892 2893
		pCap->num_gpio_pins = AR928X_NUM_GPIO;
	else
		pCap->num_gpio_pins = AR_NUM_GPIO;
2894

S
Sujith 已提交
2895 2896 2897 2898 2899
	if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
		pCap->hw_caps |= ATH9K_HW_CAP_CST;
		pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
	} else {
		pCap->rts_aggr_limit = (8 * 1024);
2900 2901
	}

S
Sujith 已提交
2902 2903
	pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;

2904
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
2905 2906 2907 2908 2909 2910
	ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
	if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
		ah->rfkill_gpio =
			MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
		ah->rfkill_polarity =
			MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
S
Sujith 已提交
2911 2912

		pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
2913
	}
S
Sujith 已提交
2914
#endif
2915 2916 2917 2918
	if (AR_SREV_9271(ah))
		pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
	else
		pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
2919

2920
	if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
S
Sujith 已提交
2921 2922 2923
		pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
	else
		pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
2924

2925
	if (regulatory->current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
S
Sujith 已提交
2926 2927 2928 2929 2930
		pCap->reg_cap =
			AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
			AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
			AR_EEPROM_EEREGCAP_EN_KK_U2 |
			AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
2931
	} else {
S
Sujith 已提交
2932 2933 2934
		pCap->reg_cap =
			AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
			AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
2935 2936
	}

2937 2938 2939 2940
	/* Advertise midband for AR5416 with FCC midband set in eeprom */
	if (regulatory->current_rd_ext & (1 << REG_EXT_FCC_MIDBAND) &&
	    AR_SREV_5416(ah))
		pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
S
Sujith 已提交
2941 2942

	pCap->num_antcfg_5ghz =
S
Sujith 已提交
2943
		ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
S
Sujith 已提交
2944
	pCap->num_antcfg_2ghz =
S
Sujith 已提交
2945
		ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
2946

2947
	if (AR_SREV_9280_10_OR_LATER(ah) &&
2948
	    ath9k_hw_btcoex_supported(ah)) {
2949 2950
		btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
		btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
2951

2952
		if (AR_SREV_9285(ah)) {
2953 2954
			btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
			btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO;
2955
		} else {
2956
			btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
2957
		}
2958
	} else {
2959
		btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
2960
	}
2961

2962
	if (AR_SREV_9300_20_OR_LATER(ah)) {
2963
		pCap->hw_caps |= ATH9K_HW_CAP_EDMA;
2964 2965 2966
		pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
		pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
		pCap->rx_status_len = sizeof(struct ar9003_rxs);
2967 2968 2969
		pCap->tx_desc_len = sizeof(struct ar9003_txc);
	} else {
		pCap->tx_desc_len = sizeof(struct ath_desc);
2970
	}
2971

2972
	return 0;
2973 2974
}

2975
bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
S
Sujith 已提交
2976
			    u32 capability, u32 *result)
2977
{
2978
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
S
Sujith 已提交
2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996
	switch (type) {
	case ATH9K_CAP_CIPHER:
		switch (capability) {
		case ATH9K_CIPHER_AES_CCM:
		case ATH9K_CIPHER_AES_OCB:
		case ATH9K_CIPHER_TKIP:
		case ATH9K_CIPHER_WEP:
		case ATH9K_CIPHER_MIC:
		case ATH9K_CIPHER_CLR:
			return true;
		default:
			return false;
		}
	case ATH9K_CAP_TKIP_MIC:
		switch (capability) {
		case 0:
			return true;
		case 1:
2997
			return (ah->sta_id1_defaults &
S
Sujith 已提交
2998 2999 3000 3001
				AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
			false;
		}
	case ATH9K_CAP_TKIP_SPLIT:
3002
		return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
S
Sujith 已提交
3003 3004 3005 3006 3007 3008 3009 3010 3011
			false : true;
	case ATH9K_CAP_MCAST_KEYSRCH:
		switch (capability) {
		case 0:
			return true;
		case 1:
			if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
				return false;
			} else {
3012
				return (ah->sta_id1_defaults &
S
Sujith 已提交
3013 3014 3015 3016 3017 3018 3019 3020 3021 3022
					AR_STA_ID1_MCAST_KSRCH) ? true :
					false;
			}
		}
		return false;
	case ATH9K_CAP_TXPOW:
		switch (capability) {
		case 0:
			return 0;
		case 1:
3023
			*result = regulatory->power_limit;
S
Sujith 已提交
3024 3025
			return 0;
		case 2:
3026
			*result = regulatory->max_power_level;
S
Sujith 已提交
3027 3028
			return 0;
		case 3:
3029
			*result = regulatory->tp_scale;
S
Sujith 已提交
3030 3031 3032
			return 0;
		}
		return false;
3033 3034 3035 3036
	case ATH9K_CAP_DS:
		return (AR_SREV_9280_20_OR_LATER(ah) &&
			(ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
			? false : true;
S
Sujith 已提交
3037 3038
	default:
		return false;
3039 3040
	}
}
3041
EXPORT_SYMBOL(ath9k_hw_getcapability);
3042

3043
bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
S
Sujith 已提交
3044
			    u32 capability, u32 setting, int *status)
3045
{
S
Sujith 已提交
3046 3047 3048
	switch (type) {
	case ATH9K_CAP_TKIP_MIC:
		if (setting)
3049
			ah->sta_id1_defaults |=
S
Sujith 已提交
3050 3051
				AR_STA_ID1_CRPT_MIC_ENABLE;
		else
3052
			ah->sta_id1_defaults &=
S
Sujith 已提交
3053 3054 3055 3056
				~AR_STA_ID1_CRPT_MIC_ENABLE;
		return true;
	case ATH9K_CAP_MCAST_KEYSRCH:
		if (setting)
3057
			ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
S
Sujith 已提交
3058
		else
3059
			ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
S
Sujith 已提交
3060 3061 3062
		return true;
	default:
		return false;
3063 3064
	}
}
3065
EXPORT_SYMBOL(ath9k_hw_setcapability);
3066

S
Sujith 已提交
3067 3068 3069
/****************************/
/* GPIO / RFKILL / Antennae */
/****************************/
3070

3071
static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
S
Sujith 已提交
3072 3073 3074 3075
					 u32 gpio, u32 type)
{
	int addr;
	u32 gpio_shift, tmp;
3076

S
Sujith 已提交
3077 3078 3079 3080 3081 3082
	if (gpio > 11)
		addr = AR_GPIO_OUTPUT_MUX3;
	else if (gpio > 5)
		addr = AR_GPIO_OUTPUT_MUX2;
	else
		addr = AR_GPIO_OUTPUT_MUX1;
3083

S
Sujith 已提交
3084
	gpio_shift = (gpio % 6) * 5;
3085

S
Sujith 已提交
3086 3087 3088 3089
	if (AR_SREV_9280_20_OR_LATER(ah)
	    || (addr != AR_GPIO_OUTPUT_MUX1)) {
		REG_RMW(ah, addr, (type << gpio_shift),
			(0x1f << gpio_shift));
3090
	} else {
S
Sujith 已提交
3091 3092 3093 3094 3095
		tmp = REG_READ(ah, addr);
		tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
		tmp &= ~(0x1f << gpio_shift);
		tmp |= (type << gpio_shift);
		REG_WRITE(ah, addr, tmp);
3096 3097 3098
	}
}

3099
void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
3100
{
S
Sujith 已提交
3101
	u32 gpio_shift;
3102

3103
	BUG_ON(gpio >= ah->caps.num_gpio_pins);
3104

S
Sujith 已提交
3105
	gpio_shift = gpio << 1;
3106

S
Sujith 已提交
3107 3108 3109 3110
	REG_RMW(ah,
		AR_GPIO_OE_OUT,
		(AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
		(AR_GPIO_OE_OUT_DRV << gpio_shift));
3111
}
3112
EXPORT_SYMBOL(ath9k_hw_cfg_gpio_input);
3113

3114
u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
3115
{
3116 3117 3118
#define MS_REG_READ(x, y) \
	(MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))

3119
	if (gpio >= ah->caps.num_gpio_pins)
S
Sujith 已提交
3120
		return 0xffffffff;
3121

3122 3123 3124
	if (AR_SREV_9300_20_OR_LATER(ah))
		return MS_REG_READ(AR9300, gpio) != 0;
	else if (AR_SREV_9271(ah))
3125 3126
		return MS_REG_READ(AR9271, gpio) != 0;
	else if (AR_SREV_9287_10_OR_LATER(ah))
3127 3128
		return MS_REG_READ(AR9287, gpio) != 0;
	else if (AR_SREV_9285_10_OR_LATER(ah))
3129 3130 3131 3132 3133
		return MS_REG_READ(AR9285, gpio) != 0;
	else if (AR_SREV_9280_10_OR_LATER(ah))
		return MS_REG_READ(AR928X, gpio) != 0;
	else
		return MS_REG_READ(AR, gpio) != 0;
3134
}
3135
EXPORT_SYMBOL(ath9k_hw_gpio_get);
3136

3137
void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
S
Sujith 已提交
3138
			 u32 ah_signal_type)
3139
{
S
Sujith 已提交
3140
	u32 gpio_shift;
3141

S
Sujith 已提交
3142
	ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
3143

S
Sujith 已提交
3144
	gpio_shift = 2 * gpio;
3145

S
Sujith 已提交
3146 3147 3148 3149
	REG_RMW(ah,
		AR_GPIO_OE_OUT,
		(AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
		(AR_GPIO_OE_OUT_DRV << gpio_shift));
3150
}
3151
EXPORT_SYMBOL(ath9k_hw_cfg_output);
3152

3153
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
3154
{
3155 3156 3157
	if (AR_SREV_9271(ah))
		val = ~val;

S
Sujith 已提交
3158 3159
	REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
		AR_GPIO_BIT(gpio));
3160
}
3161
EXPORT_SYMBOL(ath9k_hw_set_gpio);
3162

3163
u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
3164
{
S
Sujith 已提交
3165
	return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
3166
}
3167
EXPORT_SYMBOL(ath9k_hw_getdefantenna);
3168

3169
void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
3170
{
S
Sujith 已提交
3171
	REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
3172
}
3173
EXPORT_SYMBOL(ath9k_hw_setantenna);
3174

S
Sujith 已提交
3175 3176 3177 3178
/*********************/
/* General Operation */
/*********************/

3179
u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
3180
{
S
Sujith 已提交
3181 3182
	u32 bits = REG_READ(ah, AR_RX_FILTER);
	u32 phybits = REG_READ(ah, AR_PHY_ERR);
3183

S
Sujith 已提交
3184 3185 3186 3187
	if (phybits & AR_PHY_ERR_RADAR)
		bits |= ATH9K_RX_FILTER_PHYRADAR;
	if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
		bits |= ATH9K_RX_FILTER_PHYERR;
S
Sujith 已提交
3188

S
Sujith 已提交
3189
	return bits;
3190
}
3191
EXPORT_SYMBOL(ath9k_hw_getrxfilter);
3192

3193
void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
3194
{
S
Sujith 已提交
3195
	u32 phybits;
3196

S
Sujith 已提交
3197 3198
	REG_WRITE(ah, AR_RX_FILTER, bits);

S
Sujith 已提交
3199 3200 3201 3202 3203 3204
	phybits = 0;
	if (bits & ATH9K_RX_FILTER_PHYRADAR)
		phybits |= AR_PHY_ERR_RADAR;
	if (bits & ATH9K_RX_FILTER_PHYERR)
		phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
	REG_WRITE(ah, AR_PHY_ERR, phybits);
3205

S
Sujith 已提交
3206 3207 3208 3209 3210 3211 3212
	if (phybits)
		REG_WRITE(ah, AR_RXCFG,
			  REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
	else
		REG_WRITE(ah, AR_RXCFG,
			  REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
}
3213
EXPORT_SYMBOL(ath9k_hw_setrxfilter);
3214

3215
bool ath9k_hw_phy_disable(struct ath_hw *ah)
S
Sujith 已提交
3216
{
3217 3218 3219 3220 3221
	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
		return false;

	ath9k_hw_init_pll(ah, NULL);
	return true;
S
Sujith 已提交
3222
}
3223
EXPORT_SYMBOL(ath9k_hw_phy_disable);
3224

3225
bool ath9k_hw_disable(struct ath_hw *ah)
S
Sujith 已提交
3226
{
3227
	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
S
Sujith 已提交
3228
		return false;
3229

3230 3231 3232 3233 3234
	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD))
		return false;

	ath9k_hw_init_pll(ah, NULL);
	return true;
3235
}
3236
EXPORT_SYMBOL(ath9k_hw_disable);
3237

3238
void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
3239
{
3240
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
3241
	struct ath9k_channel *chan = ah->curchan;
3242
	struct ieee80211_channel *channel = chan->chan;
3243

3244
	regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
3245

3246
	ah->eep_ops->set_txpower(ah, chan,
3247
				 ath9k_regd_get_ctl(regulatory, chan),
3248 3249 3250
				 channel->max_antenna_gain * 2,
				 channel->max_power * 2,
				 min((u32) MAX_RATE_POWER,
3251
				 (u32) regulatory->power_limit));
3252
}
3253
EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
3254

3255
void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
3256
{
3257
	memcpy(ath9k_hw_common(ah)->macaddr, mac, ETH_ALEN);
3258
}
3259
EXPORT_SYMBOL(ath9k_hw_setmac);
3260

3261
void ath9k_hw_setopmode(struct ath_hw *ah)
3262
{
3263
	ath9k_hw_set_operating_mode(ah, ah->opmode);
3264
}
3265
EXPORT_SYMBOL(ath9k_hw_setopmode);
3266

3267
void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
3268
{
S
Sujith 已提交
3269 3270
	REG_WRITE(ah, AR_MCAST_FIL0, filter0);
	REG_WRITE(ah, AR_MCAST_FIL1, filter1);
3271
}
3272
EXPORT_SYMBOL(ath9k_hw_setmcastfilter);
3273

3274
void ath9k_hw_write_associd(struct ath_hw *ah)
3275
{
3276 3277 3278 3279 3280
	struct ath_common *common = ath9k_hw_common(ah);

	REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(common->curbssid));
	REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(common->curbssid + 4) |
		  ((common->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
3281
}
3282
EXPORT_SYMBOL(ath9k_hw_write_associd);
3283

3284
u64 ath9k_hw_gettsf64(struct ath_hw *ah)
3285
{
S
Sujith 已提交
3286
	u64 tsf;
3287

S
Sujith 已提交
3288 3289
	tsf = REG_READ(ah, AR_TSF_U32);
	tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
3290

S
Sujith 已提交
3291 3292
	return tsf;
}
3293
EXPORT_SYMBOL(ath9k_hw_gettsf64);
3294

3295
void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
3296 3297
{
	REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
A
Alina Friedrichsen 已提交
3298
	REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
3299
}
3300
EXPORT_SYMBOL(ath9k_hw_settsf64);
3301

3302
void ath9k_hw_reset_tsf(struct ath_hw *ah)
S
Sujith 已提交
3303
{
3304 3305
	if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0,
			   AH_TSF_WRITE_TIMEOUT))
3306 3307
		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
			  "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
3308

S
Sujith 已提交
3309 3310
	REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
}
3311
EXPORT_SYMBOL(ath9k_hw_reset_tsf);
3312

S
Sujith 已提交
3313
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
S
Sujith 已提交
3314 3315
{
	if (setting)
3316
		ah->misc_mode |= AR_PCU_TX_ADD_TSF;
S
Sujith 已提交
3317
	else
3318
		ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
S
Sujith 已提交
3319
}
3320
EXPORT_SYMBOL(ath9k_hw_set_tsfadjust);
3321

3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336
/*
 *  Extend 15-bit time stamp from rx descriptor to
 *  a full 64-bit TSF using the current h/w TSF.
*/
u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp)
{
	u64 tsf;

	tsf = ath9k_hw_gettsf64(ah);
	if ((tsf & 0x7fff) < rstamp)
		tsf -= 0x8000;
	return (tsf & ~0x7fff) | rstamp;
}
EXPORT_SYMBOL(ath9k_hw_extend_tsf);

L
Luis R. Rodriguez 已提交
3337
void ath9k_hw_set11nmac2040(struct ath_hw *ah)
S
Sujith 已提交
3338
{
L
Luis R. Rodriguez 已提交
3339
	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
S
Sujith 已提交
3340 3341
	u32 macmode;

L
Luis R. Rodriguez 已提交
3342
	if (conf_is_ht40(conf) && !ah->config.cwm_ignore_extcca)
S
Sujith 已提交
3343 3344 3345
		macmode = AR_2040_JOINED_RX_CLEAR;
	else
		macmode = 0;
3346

S
Sujith 已提交
3347
	REG_WRITE(ah, AR_2040_MODE, macmode);
3348
}
3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394

/* HW Generic timers configuration */

static const struct ath_gen_timer_configuration gen_tmr_configuration[] =
{
	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
	{AR_NEXT_NDP2_TIMER, AR_NDP2_PERIOD, AR_NDP2_TIMER_MODE, 0x0001},
	{AR_NEXT_NDP2_TIMER + 1*4, AR_NDP2_PERIOD + 1*4,
				AR_NDP2_TIMER_MODE, 0x0002},
	{AR_NEXT_NDP2_TIMER + 2*4, AR_NDP2_PERIOD + 2*4,
				AR_NDP2_TIMER_MODE, 0x0004},
	{AR_NEXT_NDP2_TIMER + 3*4, AR_NDP2_PERIOD + 3*4,
				AR_NDP2_TIMER_MODE, 0x0008},
	{AR_NEXT_NDP2_TIMER + 4*4, AR_NDP2_PERIOD + 4*4,
				AR_NDP2_TIMER_MODE, 0x0010},
	{AR_NEXT_NDP2_TIMER + 5*4, AR_NDP2_PERIOD + 5*4,
				AR_NDP2_TIMER_MODE, 0x0020},
	{AR_NEXT_NDP2_TIMER + 6*4, AR_NDP2_PERIOD + 6*4,
				AR_NDP2_TIMER_MODE, 0x0040},
	{AR_NEXT_NDP2_TIMER + 7*4, AR_NDP2_PERIOD + 7*4,
				AR_NDP2_TIMER_MODE, 0x0080}
};

/* HW generic timer primitives */

/* compute and clear index of rightmost 1 */
static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
{
	u32 b;

	b = *mask;
	b &= (0-b);
	*mask &= ~b;
	b *= debruijn32;
	b >>= 27;

	return timer_table->gen_timer_index[b];
}

3395
u32 ath9k_hw_gettsf32(struct ath_hw *ah)
3396 3397 3398
{
	return REG_READ(ah, AR_TSF_L32);
}
3399
EXPORT_SYMBOL(ath9k_hw_gettsf32);
3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412

struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
					  void (*trigger)(void *),
					  void (*overflow)(void *),
					  void *arg,
					  u8 timer_index)
{
	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
	struct ath_gen_timer *timer;

	timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL);

	if (timer == NULL) {
3413 3414 3415
		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
			  "Failed to allocate memory"
			  "for hw timer[%d]\n", timer_index);
3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427
		return NULL;
	}

	/* allocate a hardware generic timer slot */
	timer_table->timers[timer_index] = timer;
	timer->index = timer_index;
	timer->trigger = trigger;
	timer->overflow = overflow;
	timer->arg = arg;

	return timer;
}
3428
EXPORT_SYMBOL(ath_gen_timer_alloc);
3429

3430 3431 3432 3433
void ath9k_hw_gen_timer_start(struct ath_hw *ah,
			      struct ath_gen_timer *timer,
			      u32 timer_next,
			      u32 timer_period)
3434 3435 3436 3437 3438 3439 3440 3441 3442 3443
{
	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
	u32 tsf;

	BUG_ON(!timer_period);

	set_bit(timer->index, &timer_table->timer_mask.timer_bits);

	tsf = ath9k_hw_gettsf32(ah);

3444 3445 3446
	ath_print(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
		  "curent tsf %x period %x"
		  "timer_next %x\n", tsf, timer_period, timer_next);
3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469

	/*
	 * Pull timer_next forward if the current TSF already passed it
	 * because of software latency
	 */
	if (timer_next < tsf)
		timer_next = tsf + timer_period;

	/*
	 * Program generic timer registers
	 */
	REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr,
		 timer_next);
	REG_WRITE(ah, gen_tmr_configuration[timer->index].period_addr,
		  timer_period);
	REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
		    gen_tmr_configuration[timer->index].mode_mask);

	/* Enable both trigger and thresh interrupt masks */
	REG_SET_BIT(ah, AR_IMR_S5,
		(SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
		SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
}
3470
EXPORT_SYMBOL(ath9k_hw_gen_timer_start);
3471

3472
void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491
{
	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;

	if ((timer->index < AR_FIRST_NDP_TIMER) ||
		(timer->index >= ATH_MAX_GEN_TIMER)) {
		return;
	}

	/* Clear generic timer enable bits. */
	REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
			gen_tmr_configuration[timer->index].mode_mask);

	/* Disable both trigger and thresh interrupt masks */
	REG_CLR_BIT(ah, AR_IMR_S5,
		(SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
		SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));

	clear_bit(timer->index, &timer_table->timer_mask.timer_bits);
}
3492
EXPORT_SYMBOL(ath9k_hw_gen_timer_stop);
3493 3494 3495 3496 3497 3498 3499 3500 3501

void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer)
{
	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;

	/* free the hardware generic timer slot */
	timer_table->timers[timer->index] = NULL;
	kfree(timer);
}
3502
EXPORT_SYMBOL(ath_gen_timer_free);
3503 3504 3505 3506 3507 3508 3509 3510

/*
 * Generic Timer Interrupts handling
 */
void ath_gen_timer_isr(struct ath_hw *ah)
{
	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
	struct ath_gen_timer *timer;
3511
	struct ath_common *common = ath9k_hw_common(ah);
3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525
	u32 trigger_mask, thresh_mask, index;

	/* get hardware generic timer interrupt status */
	trigger_mask = ah->intr_gen_timer_trigger;
	thresh_mask = ah->intr_gen_timer_thresh;
	trigger_mask &= timer_table->timer_mask.val;
	thresh_mask &= timer_table->timer_mask.val;

	trigger_mask &= ~thresh_mask;

	while (thresh_mask) {
		index = rightmost_index(timer_table, &thresh_mask);
		timer = timer_table->timers[index];
		BUG_ON(!timer);
3526 3527
		ath_print(common, ATH_DBG_HWTIMER,
			  "TSF overflow for Gen timer %d\n", index);
3528 3529 3530 3531 3532 3533 3534
		timer->overflow(timer->arg);
	}

	while (trigger_mask) {
		index = rightmost_index(timer_table, &trigger_mask);
		timer = timer_table->timers[index];
		BUG_ON(!timer);
3535 3536
		ath_print(common, ATH_DBG_HWTIMER,
			  "Gen timer[%d] trigger\n", index);
3537 3538 3539
		timer->trigger(timer->arg);
	}
}
3540
EXPORT_SYMBOL(ath_gen_timer_isr);
3541

3542 3543 3544 3545 3546 3547 3548 3549 3550 3551
/********/
/* HTC  */
/********/

void ath9k_hw_htc_resetinit(struct ath_hw *ah)
{
	ah->htc_reset_init = true;
}
EXPORT_SYMBOL(ath9k_hw_htc_resetinit);

3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563
static struct {
	u32 version;
	const char * name;
} ath_mac_bb_names[] = {
	/* Devices with external radios */
	{ AR_SREV_VERSION_5416_PCI,	"5416" },
	{ AR_SREV_VERSION_5416_PCIE,	"5418" },
	{ AR_SREV_VERSION_9100,		"9100" },
	{ AR_SREV_VERSION_9160,		"9160" },
	/* Single-chip solutions */
	{ AR_SREV_VERSION_9280,		"9280" },
	{ AR_SREV_VERSION_9285,		"9285" },
3564 3565
	{ AR_SREV_VERSION_9287,         "9287" },
	{ AR_SREV_VERSION_9271,         "9271" },
3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582
};

/* For devices with external radios */
static struct {
	u16 version;
	const char * name;
} ath_rf_names[] = {
	{ 0,				"5133" },
	{ AR_RAD5133_SREV_MAJOR,	"5133" },
	{ AR_RAD5122_SREV_MAJOR,	"5122" },
	{ AR_RAD2133_SREV_MAJOR,	"2133" },
	{ AR_RAD2122_SREV_MAJOR,	"2122" }
};

/*
 * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
 */
3583
static const char *ath9k_hw_mac_bb_name(u32 mac_bb_version)
3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599
{
	int i;

	for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
		if (ath_mac_bb_names[i].version == mac_bb_version) {
			return ath_mac_bb_names[i].name;
		}
	}

	return "????";
}

/*
 * Return the RF name. "????" is returned if the RF is unknown.
 * Used for devices with external radios.
 */
3600
static const char *ath9k_hw_rf_name(u16 rf_version)
3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611
{
	int i;

	for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
		if (ath_rf_names[i].version == rf_version) {
			return ath_rf_names[i].name;
		}
	}

	return "????";
}
3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636

void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len)
{
	int used;

	/* chipsets >= AR9280 are single-chip */
	if (AR_SREV_9280_10_OR_LATER(ah)) {
		used = snprintf(hw_name, len,
			       "Atheros AR%s Rev:%x",
			       ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
			       ah->hw_version.macRev);
	}
	else {
		used = snprintf(hw_name, len,
			       "Atheros AR%s MAC/BB Rev:%x AR%s RF Rev:%x",
			       ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
			       ah->hw_version.macRev,
			       ath9k_hw_rf_name((ah->hw_version.analog5GhzRev &
						AR_RADIO_SREV_MAJOR)),
			       ah->hw_version.phyRev);
	}

	hw_name[used] = '\0';
}
EXPORT_SYMBOL(ath9k_hw_name);
3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648

/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
static void ar9002_hw_attach_ops(struct ath_hw *ah)
{
	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
	struct ath_hw_ops *ops = ath9k_hw_ops(ah);

	priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
	priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
	priv_ops->macversion_supported = ar9002_hw_macversion_supported;

	ops->config_pci_powersave = ar9002_hw_configpcipowersave;
3649

3650
	ar5008_hw_attach_phy_ops(ah);
3651 3652
	if (AR_SREV_9280_10_OR_LATER(ah))
		ar9002_hw_attach_phy_ops(ah);
3653 3654

	ar9002_hw_attach_mac_ops(ah);
3655 3656 3657 3658 3659
}

/* Sets up the AR9003 hardware familiy callbacks */
static void ar9003_hw_attach_ops(struct ath_hw *ah)
{
3660 3661
	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);

3662
	priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
3663 3664
	priv_ops->macversion_supported = ar9003_hw_macversion_supported;

3665
	ar9003_hw_attach_phy_ops(ah);
3666 3667

	ar9003_hw_attach_mac_ops(ah);
3668
}