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

#include <linux/io.h>
18
#include <linux/slab.h>
19
20
#include <asm/unaligned.h>

21
#include "hw.h"
22
#include "hw-ops.h"
23
#include "rc.h"
24
#include "ar9003_mac.h"
25

26
static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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);

45
46
47
48
49
50
51
52
53
54
55
56
/* 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);
}

57
58
59
60
61
62
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);
}

63
64
65
66
67
68
69
70
static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
{
	if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs)
		return;

	ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
}

71
72
73
74
75
76
77
78
79
static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
{
	/* You will not have this callback if using the old ANI */
	if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs)
		return;

	ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah);
}

Sujith's avatar
Sujith committed
80
81
82
/********************/
/* Helper Functions */
/********************/
83

84
static void ath9k_hw_set_clockrate(struct ath_hw *ah)
Sujith's avatar
Sujith committed
85
{
86
	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
87
88
	struct ath_common *common = ath9k_hw_common(ah);
	unsigned int clockrate;
89

90
	if (!ah->curchan) /* should really check for CCK instead */
91
92
93
94
95
		clockrate = ATH9K_CLOCK_RATE_CCK;
	else if (conf->channel->band == IEEE80211_BAND_2GHZ)
		clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
	else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
		clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
96
	else
97
98
99
100
101
102
		clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;

	if (conf_is_ht40(conf))
		clockrate *= 2;

	common->clockrate = clockrate;
Sujith's avatar
Sujith committed
103
104
}

105
static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
Sujith's avatar
Sujith committed
106
{
107
	struct ath_common *common = ath9k_hw_common(ah);
108

109
	return usecs * common->clockrate;
Sujith's avatar
Sujith committed
110
}
111

Sujith's avatar
Sujith committed
112
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
113
114
115
{
	int i;

Sujith's avatar
Sujith committed
116
117
118
	BUG_ON(timeout < AH_TIME_QUANTUM);

	for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
119
120
121
122
123
		if ((REG_READ(ah, reg) & mask) == val)
			return true;

		udelay(AH_TIME_QUANTUM);
	}
Sujith's avatar
Sujith committed
124

125
126
127
	ath_dbg(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);
128

Sujith's avatar
Sujith committed
129
	return false;
130
}
131
EXPORT_SYMBOL(ath9k_hw_wait);
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
			  int column, unsigned int *writecnt)
{
	int r;

	ENABLE_REGWRITE_BUFFER(ah);
	for (r = 0; r < array->ia_rows; r++) {
		REG_WRITE(ah, INI_RA(array, r, 0),
			  INI_RA(array, r, column));
		DO_DELAY(*writecnt);
	}
	REGWRITE_BUFFER_FLUSH(ah);
}

147
148
149
150
151
152
153
154
155
156
157
158
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;
}

159
u16 ath9k_hw_computetxtime(struct ath_hw *ah,
160
			   u8 phy, int kbps,
Sujith's avatar
Sujith committed
161
162
			   u32 frameLen, u16 rateix,
			   bool shortPreamble)
163
{
Sujith's avatar
Sujith committed
164
	u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
165

Sujith's avatar
Sujith committed
166
167
	if (kbps == 0)
		return 0;
168

169
	switch (phy) {
Sujith's avatar
Sujith committed
170
	case WLAN_RC_PHY_CCK:
Sujith's avatar
Sujith committed
171
		phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
172
		if (shortPreamble)
Sujith's avatar
Sujith committed
173
174
175
176
			phyTime >>= 1;
		numBits = frameLen << 3;
		txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
		break;
Sujith's avatar
Sujith committed
177
	case WLAN_RC_PHY_OFDM:
178
		if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
Sujith's avatar
Sujith committed
179
180
181
182
183
184
			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);
185
186
		} else if (ah->curchan &&
			   IS_CHAN_HALF_RATE(ah->curchan)) {
Sujith's avatar
Sujith committed
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
			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:
202
203
		ath_err(ath9k_hw_common(ah),
			"Unknown phy %u (rate ix %u)\n", phy, rateix);
Sujith's avatar
Sujith committed
204
205
206
		txTime = 0;
		break;
	}
207

Sujith's avatar
Sujith committed
208
209
	return txTime;
}
210
EXPORT_SYMBOL(ath9k_hw_computetxtime);
211

212
void ath9k_hw_get_channel_centers(struct ath_hw *ah,
Sujith's avatar
Sujith committed
213
214
				  struct ath9k_channel *chan,
				  struct chan_centers *centers)
215
{
Sujith's avatar
Sujith committed
216
	int8_t extoff;
217

Sujith's avatar
Sujith committed
218
219
220
221
	if (!IS_CHAN_HT40(chan)) {
		centers->ctl_center = centers->ext_center =
			centers->synth_center = chan->channel;
		return;
222
223
	}

Sujith's avatar
Sujith committed
224
225
226
227
228
229
230
231
232
233
	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;
	}
234

Sujith's avatar
Sujith committed
235
236
	centers->ctl_center =
		centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
237
	/* 25 MHz spacing is supported by hw but not on upper layers */
Sujith's avatar
Sujith committed
238
	centers->ext_center =
239
		centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
240
241
}

Sujith's avatar
Sujith committed
242
243
244
245
/******************/
/* Chip Revisions */
/******************/

246
static void ath9k_hw_read_revisions(struct ath_hw *ah)
247
{
Sujith's avatar
Sujith committed
248
	u32 val;
249

250
251
252
253
254
255
256
257
258
259
260
	switch (ah->hw_version.devid) {
	case AR5416_AR9100_DEVID:
		ah->hw_version.macVersion = AR_SREV_VERSION_9100;
		break;
	case AR9300_DEVID_AR9340:
		ah->hw_version.macVersion = AR_SREV_VERSION_9340;
		val = REG_READ(ah, AR_SREV);
		ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
		return;
	}

Sujith's avatar
Sujith committed
261
	val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
262

Sujith's avatar
Sujith committed
263
264
	if (val == 0xFF) {
		val = REG_READ(ah, AR_SREV);
265
266
267
		ah->hw_version.macVersion =
			(val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
		ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
268
		ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
Sujith's avatar
Sujith committed
269
270
	} else {
		if (!AR_SREV_9100(ah))
271
			ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
272

273
		ah->hw_version.macRev = val & AR_SREV_REVISION;
274

275
		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
276
			ah->is_pciexpress = true;
Sujith's avatar
Sujith committed
277
	}
278
279
}

Sujith's avatar
Sujith committed
280
281
282
283
/************************************/
/* HW Attach, Detach, Init Routines */
/************************************/

284
static void ath9k_hw_disablepcie(struct ath_hw *ah)
285
{
286
	if (!AR_SREV_5416(ah))
Sujith's avatar
Sujith committed
287
		return;
288

Sujith's avatar
Sujith committed
289
290
291
292
293
294
295
296
297
	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);
298

Sujith's avatar
Sujith committed
299
	REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
300
301
}

302
/* This should work for all families including legacy */
303
static bool ath9k_hw_chip_test(struct ath_hw *ah)
304
{
305
	struct ath_common *common = ath9k_hw_common(ah);
306
	u32 regAddr[2] = { AR_STA_ID0 };
Sujith's avatar
Sujith committed
307
	u32 regHold[2];
Joe Perches's avatar
Joe Perches committed
308
309
310
	static const u32 patternData[4] = {
		0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999
	};
311
	int i, j, loop_max;
312

313
314
315
316
317
318
319
	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++) {
Sujith's avatar
Sujith committed
320
321
		u32 addr = regAddr[i];
		u32 wrData, rdData;
322

Sujith's avatar
Sujith committed
323
324
325
326
327
328
		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) {
329
330
331
				ath_err(common,
					"address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
					addr, wrData, rdData);
Sujith's avatar
Sujith committed
332
333
334
335
336
337
338
339
				return false;
			}
		}
		for (j = 0; j < 4; j++) {
			wrData = patternData[j];
			REG_WRITE(ah, addr, wrData);
			rdData = REG_READ(ah, addr);
			if (wrData != rdData) {
340
341
342
				ath_err(common,
					"address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
					addr, wrData, rdData);
Sujith's avatar
Sujith committed
343
344
				return false;
			}
345
		}
Sujith's avatar
Sujith committed
346
		REG_WRITE(ah, regAddr[i], regHold[i]);
347
	}
Sujith's avatar
Sujith committed
348
	udelay(100);
349

350
351
352
	return true;
}

353
static void ath9k_hw_init_config(struct ath_hw *ah)
Sujith's avatar
Sujith committed
354
355
{
	int i;
356

357
358
359
360
361
362
363
364
365
	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;
366
	ah->config.enable_ani = true;
367

Sujith's avatar
Sujith committed
368
	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
369
370
		ah->config.spurchans[i][0] = AR_NO_SPUR;
		ah->config.spurchans[i][1] = AR_NO_SPUR;
371
372
	}

373
374
375
	/* PAPRD needs some more work to be enabled */
	ah->config.paprd_disable = 1;

Sujith's avatar
Sujith committed
376
	ah->config.rx_intr_mitigation = true;
377
	ah->config.pcieSerDesWrite = true;
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

	/*
	 * 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)
396
		ah->config.serialize_regmode = SER_REG_MODE_AUTO;
397
398
}

399
static void ath9k_hw_init_defaults(struct ath_hw *ah)
400
{
401
402
403
404
405
406
	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;

407
408
	ah->hw_version.magic = AR5416_MAGIC;
	ah->hw_version.subvendorid = 0;
409

410
	ah->atim_window = 0;
411
412
413
	ah->sta_id1_defaults =
		AR_STA_ID1_CRPT_MIC_ENABLE |
		AR_STA_ID1_MCAST_KSRCH;
414
415
	if (AR_SREV_9100(ah))
		ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
416
	ah->enable_32kHz_clock = DONT_USE_32KHZ;
417
	ah->slottime = 20;
418
	ah->globaltxtimeout = (u32) -1;
419
	ah->power_mode = ATH9K_PM_UNDEFINED;
420
421
}

422
static int ath9k_hw_init_macaddr(struct ath_hw *ah)
423
{
424
	struct ath_common *common = ath9k_hw_common(ah);
425
426
427
	u32 sum;
	int i;
	u16 eeval;
Joe Perches's avatar
Joe Perches committed
428
	static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
429
430
431

	sum = 0;
	for (i = 0; i < 3; i++) {
432
		eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]);
433
		sum += eeval;
434
435
		common->macaddr[2 * i] = eeval >> 8;
		common->macaddr[2 * i + 1] = eeval & 0xff;
436
	}
Sujith's avatar
Sujith committed
437
	if (sum == 0 || sum == 0xffff * 3)
438
439
440
441
442
		return -EADDRNOTAVAIL;

	return 0;
}

443
static int ath9k_hw_post_init(struct ath_hw *ah)
444
{
Sujith Manoharan's avatar
Sujith Manoharan committed
445
	struct ath_common *common = ath9k_hw_common(ah);
Sujith's avatar
Sujith committed
446
	int ecode;
447

Sujith Manoharan's avatar
Sujith Manoharan committed
448
	if (common->bus_ops->ath_bus_type != ATH_USB) {
Sujith's avatar
Sujith committed
449
450
451
		if (!ath9k_hw_chip_test(ah))
			return -ENODEV;
	}
452

453
454
455
456
457
	if (!AR_SREV_9300_20_OR_LATER(ah)) {
		ecode = ar9002_hw_rf_claim(ah);
		if (ecode != 0)
			return ecode;
	}
458

459
	ecode = ath9k_hw_eeprom_init(ah);
Sujith's avatar
Sujith committed
460
461
	if (ecode != 0)
		return ecode;
462

463
464
465
466
	ath_dbg(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));
467

468
469
	ecode = ath9k_hw_rf_alloc_ext_banks(ah);
	if (ecode) {
470
471
		ath_err(ath9k_hw_common(ah),
			"Failed allocating banks for external radio\n");
472
		ath9k_hw_rf_free_ext_banks(ah);
473
		return ecode;
474
	}
475

476
	if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
Sujith's avatar
Sujith committed
477
		ath9k_hw_ani_setup(ah);
478
		ath9k_hw_ani_init(ah);
479
480
481
482
483
	}

	return 0;
}

484
static void ath9k_hw_attach_ops(struct ath_hw *ah)
485
{
486
487
488
489
	if (AR_SREV_9300_20_OR_LATER(ah))
		ar9003_hw_attach_ops(ah);
	else
		ar9002_hw_attach_ops(ah);
490
491
}

492
493
/* Called for all hardware families */
static int __ath9k_hw_init(struct ath_hw *ah)
494
{
495
	struct ath_common *common = ath9k_hw_common(ah);
496
	int r = 0;
497

498
499
	ath9k_hw_read_revisions(ah);

500
501
502
503
504
505
506
507
508
	/*
	 * Read back AR_WA into a permanent copy and set bits 14 and 17.
	 * We need to do this to avoid RMW of this register. We cannot
	 * read the reg when chip is asleep.
	 */
	ah->WARegVal = REG_READ(ah, AR_WA);
	ah->WARegVal |= (AR_WA_D3_L1_DISABLE |
			 AR_WA_ASPM_TIMER_BASED_DISABLE);

509
	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
510
		ath_err(common, "Couldn't reset chip\n");
511
		return -EIO;
512
513
	}

514
515
516
	ath9k_hw_init_defaults(ah);
	ath9k_hw_init_config(ah);

517
	ath9k_hw_attach_ops(ah);
518

519
	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
520
		ath_err(common, "Couldn't wakeup chip\n");
521
		return -EIO;
522
523
524
525
	}

	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
526
527
		    ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
		     !ah->is_pciexpress)) {
528
529
530
531
532
533
534
535
			ah->config.serialize_regmode =
				SER_REG_MODE_ON;
		} else {
			ah->config.serialize_regmode =
				SER_REG_MODE_OFF;
		}
	}

536
	ath_dbg(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
537
538
		ah->config.serialize_regmode);

539
540
541
542
543
	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;

544
545
546
547
548
549
550
551
552
553
554
	switch (ah->hw_version.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:
	case AR_SREV_VERSION_9271:
	case AR_SREV_VERSION_9300:
	case AR_SREV_VERSION_9485:
555
	case AR_SREV_VERSION_9340:
556
557
		break;
	default:
558
559
560
		ath_err(common,
			"Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
			ah->hw_version.macVersion, ah->hw_version.macRev);
561
		return -EOPNOTSUPP;
562
563
	}

564
	if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah))
565
566
		ah->is_pciexpress = false;

567
568
569
570
	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
	ath9k_hw_init_cal_settings(ah);

	ah->ani_function = ATH9K_ANI_ALL;
571
	if (AR_SREV_9280_20_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
572
		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
573
574
	if (!AR_SREV_9300_20_OR_LATER(ah))
		ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
575
576
577

	ath9k_hw_init_mode_regs(ah);

578

579
	if (ah->is_pciexpress)
580
		ath9k_hw_configpcipowersave(ah, 0, 0);
581
582
583
	else
		ath9k_hw_disablepcie(ah);

584
585
	if (!AR_SREV_9300_20_OR_LATER(ah))
		ar9002_hw_cck_chan14_spread(ah);
Sujith's avatar
Sujith committed
586

587
	r = ath9k_hw_post_init(ah);
588
	if (r)
589
		return r;
590
591

	ath9k_hw_init_mode_gain_regs(ah);
592
593
594
595
	r = ath9k_hw_fill_cap_info(ah);
	if (r)
		return r;

596
597
	r = ath9k_hw_init_macaddr(ah);
	if (r) {
598
		ath_err(common, "Failed to initialize MAC address\n");
599
		return r;
600
601
	}

602
	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
603
		ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
Sujith's avatar
Sujith committed
604
	else
605
		ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
606

607
	ah->bb_watchdog_timeout_ms = 25;
608

609
610
	common->state = ATH_HW_INITIALIZED;

611
	return 0;
612
613
}

614
int ath9k_hw_init(struct ath_hw *ah)
615
{
616
617
	int ret;
	struct ath_common *common = ath9k_hw_common(ah);
618

619
620
621
622
623
624
625
626
627
	/* 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:
628
629
	case AR9287_DEVID_PCI:
	case AR9287_DEVID_PCIE:
630
	case AR2427_DEVID_PCIE:
631
	case AR9300_DEVID_PCIE:
632
	case AR9300_DEVID_AR9485_PCIE:
633
	case AR9300_DEVID_AR9340:
634
635
636
637
		break;
	default:
		if (common->bus_ops->ath_bus_type == ATH_USB)
			break;
638
639
		ath_err(common, "Hardware device ID 0x%04x not supported\n",
			ah->hw_version.devid);
640
641
		return -EOPNOTSUPP;
	}
642

643
644
	ret = __ath9k_hw_init(ah);
	if (ret) {
645
646
647
		ath_err(common,
			"Unable to initialize hardware; initialization status: %d\n",
			ret);
648
649
		return ret;
	}
650

651
	return 0;
652
}
653
EXPORT_SYMBOL(ath9k_hw_init);
654

655
static void ath9k_hw_init_qos(struct ath_hw *ah)
656
{
657
658
	ENABLE_REGWRITE_BUFFER(ah);

Sujith's avatar
Sujith committed
659
660
	REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
	REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
661

Sujith's avatar
Sujith committed
662
663
664
665
666
667
668
669
670
671
	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);
672
673

	REGWRITE_BUFFER_FLUSH(ah);
674
675
}

676
677
unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
{
678
679
680
	REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
	udelay(100);
	REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
681

682
683
	while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
		udelay(100);
684

685
	return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
686
687
688
}
EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);

689
#define DPLL3_PHASE_SHIFT_VAL 0x1
690
static void ath9k_hw_init_pll(struct ath_hw *ah,
Sujith's avatar
Sujith committed
691
			      struct ath9k_channel *chan)
692
{
693
694
	u32 pll;

695
696
	if (AR_SREV_9485(ah)) {

697
698
699
700
701
702
703
		/* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
			      AR_CH0_BB_DPLL2_PLL_PWD, 0x1);
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
			      AR_CH0_DPLL2_KD, 0x40);
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
			      AR_CH0_DPLL2_KI, 0x4);
704

705
706
707
708
709
710
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
			      AR_CH0_BB_DPLL1_REFDIV, 0x5);
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
			      AR_CH0_BB_DPLL1_NINI, 0x58);
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
			      AR_CH0_BB_DPLL1_NFRAC, 0x0);
711
712

		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
713
714
715
			      AR_CH0_BB_DPLL2_OUTDIV, 0x1);
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
			      AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1);
716
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
717
			      AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1);
718

719
		/* program BB PLL phase_shift to 0x6 */
720
		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
721
722
723
724
			      AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6);

		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
			      AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
725
		udelay(1000);
726
727
728

		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
			      AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
	} else if (AR_SREV_9340(ah)) {
		u32 regval, pll2_divint, pll2_divfrac, refdiv;

		REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
		udelay(1000);

		REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
		udelay(100);

		if (ah->is_clk_25mhz) {
			pll2_divint = 0x54;
			pll2_divfrac = 0x1eb85;
			refdiv = 3;
		} else {
			pll2_divint = 88;
			pll2_divfrac = 0;
			refdiv = 5;
		}

		regval = REG_READ(ah, AR_PHY_PLL_MODE);
		regval |= (0x1 << 16);
		REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
		udelay(100);

		REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) |
			  (pll2_divint << 18) | pll2_divfrac);
		udelay(100);

		regval = REG_READ(ah, AR_PHY_PLL_MODE);
		regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) |
			 (0x4 << 26) | (0x18 << 19);
		REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
		REG_WRITE(ah, AR_PHY_PLL_MODE,
			  REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
		udelay(1000);
764
	}
765
766

	pll = ath9k_hw_compute_pll_control(ah, chan);
767

768
	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
769

770
	if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
771
772
		udelay(1000);

773
774
	/* Switch the core clock for ar9271 to 117Mhz */
	if (AR_SREV_9271(ah)) {
775
776
		udelay(500);
		REG_WRITE(ah, 0x50040, 0x304);
777
778
	}

Sujith's avatar
Sujith committed
779
780
781
	udelay(RTC_PLL_SETTLE_DELAY);

	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
782
783
784
785
786
787
788
789
790
791
792
793
794

	if (AR_SREV_9340(ah)) {
		if (ah->is_clk_25mhz) {
			REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
			REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
			REG_WRITE(ah,  AR_SLP32_INC, 0x0001e7ae);
		} else {
			REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
			REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
			REG_WRITE(ah,  AR_SLP32_INC, 0x0001e800);
		}
		udelay(100);
	}
795
796
}

797
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
798
					  enum nl80211_iftype opmode)
799
{
800
	u32 sync_default = AR_INTR_SYNC_DEFAULT;
801
	u32 imr_reg = AR_IMR_TXERR |
Sujith's avatar
Sujith committed
802
803
804
805
		AR_IMR_TXURN |
		AR_IMR_RXERR |
		AR_IMR_RXORN |
		AR_IMR_BCNMISC;
806

807
808
809
	if (AR_SREV_9340(ah))
		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;

810
811
812
813
814
815
	if (AR_SREV_9300_20_OR_LATER(ah)) {
		imr_reg |= AR_IMR_RXOK_HP;
		if (ah->config.rx_intr_mitigation)
			imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
		else
			imr_reg |= AR_IMR_RXOK_LP;
816

817
818
819
820
821
822
	} else {
		if (ah->config.rx_intr_mitigation)
			imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
		else
			imr_reg |= AR_IMR_RXOK;
	}
823

824
825
826
827
	if (ah->config.tx_intr_mitigation)
		imr_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
	else
		imr_reg |= AR_IMR_TXOK;
828

829
	if (opmode == NL80211_IFTYPE_AP)
830
		imr_reg |= AR_IMR_MIB;
831

832
833
	ENABLE_REGWRITE_BUFFER(ah);

834
	REG_WRITE(ah, AR_IMR, imr_reg);
835
836
	ah->imrs2_reg |= AR_IMR_S2_GTT;
	REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
837

Sujith's avatar
Sujith committed
838
839
	if (!AR_SREV_9100(ah)) {
		REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
840
		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
Sujith's avatar
Sujith committed
841
842
		REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
	}
843

844
845
	REGWRITE_BUFFER_FLUSH(ah);

846
847
848
849
850
851
	if (AR_SREV_9300_20_OR_LATER(ah)) {
		REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
		REG_WRITE(ah, AR_INTR_PRIO_ASYNC_MASK, 0);
		REG_WRITE(ah, AR_INTR_PRIO_SYNC_ENABLE, 0);
		REG_WRITE(ah, AR_INTR_PRIO_SYNC_MASK, 0);
	}
852
853
}

854
static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
855
{
856
857
858
	u32 val = ath9k_hw_mac_to_clks(ah, us);
	val = min(val, (u32) 0xFFFF);
	REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
859
860
}

861
static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
862
{
863
864
865
866
867
868
869
870
871
872
	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);
873
}
Sujith's avatar
Sujith committed
874

875
static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
876
877
{
	if (tu > 0xFFFF) {
878
879
		ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT,
			"bad global tx timeout %u\n", tu);
880
		ah->globaltxtimeout = (u32) -1;
881
882
883
		return false;
	} else {
		REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
884
		ah->globaltxtimeout = tu;
885
886
887
888
		return true;
	}
}

889
void ath9k_hw_init_global_settings(struct ath_hw *ah)
890
{
891
892
	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
	int acktimeout;
893
	int slottime;
894
895
	int sifstime;

896
897
	ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
		ah->misc_mode);
898

899
	if (ah->misc_mode != 0)
900
		REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
901
902
903
904
905
906

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

907
908
909
	/* As defined by IEEE 802.11-2007 17.3.8.6 */
	slottime = ah->slottime + 3 * ah->coverage_class;
	acktimeout = slottime + sifstime;
910
911
912
913
914
915
916
917
918
919
920

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

921
	ath9k_hw_setslottime(ah, ah->slottime);
922
923
	ath9k_hw_set_ack_timeout(ah, acktimeout);
	ath9k_hw_set_cts_timeout(ah, acktimeout);
924
925
	if (ah->globaltxtimeout != (u32) -1)
		ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
Sujith's avatar
Sujith committed
926
}
927
EXPORT_SYMBOL(ath9k_hw_init_global_settings);
Sujith's avatar
Sujith committed
928

Sujith's avatar
Sujith committed
929
void ath9k_hw_deinit(struct ath_hw *ah)
Sujith's avatar
Sujith committed
930
{
931
932
	struct ath_common *common = ath9k_hw_common(ah);

Sujith's avatar
Sujith committed
933
	if (common->state < ATH_HW_INITIALIZED)
934
935
		goto free_hw;

936
	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
937
938

free_hw:
939
	ath9k_hw_rf_free_ext_banks(ah);
Sujith's avatar
Sujith committed
940
}
Sujith's avatar
Sujith committed
941
EXPORT_SYMBOL(ath9k_hw_deinit);
Sujith's avatar
Sujith committed
942
943
944
945
946

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

947
u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
948
949
950
951
952
953
954
955
956
957
958
959
960
{
	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;
}

Sujith's avatar
Sujith committed
961
962
963
964
/****************************************/
/* Reset and Channel Switching Routines */
/****************************************/

965
static inline void ath9k_hw_set_dma(struct ath_hw *ah)
Sujith's avatar
Sujith committed
966
{
967
	struct ath_common *common = ath9k_hw_common(ah);
Sujith's avatar
Sujith committed
968

969
970
	ENABLE_REGWRITE_BUFFER(ah);

971
972
973
	/*
	 * set AHB_MODE not to do cacheline prefetches
	*/
974
975
	if (!AR_SREV_9300_20_OR_LATER(ah))
		REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN);
Sujith's avatar
Sujith committed
976

977
978
979
	/*
	 * let mac dma reads be in 128 byte chunks
	 */
980
	REG_RMW(ah, AR_TXCFG, AR_TXCFG_DMASZ_128B, AR_TXCFG_DMASZ_MASK);
Sujith's avatar
Sujith committed
981

982
983
	REGWRITE_BUFFER_FLUSH(ah);

984
985
986
987
988
	/*
	 * 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.
	 */
989
990
	if (!AR_SREV_9300_20_OR_LATER(ah))
		REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
Sujith's avatar
Sujith committed
991

992
	ENABLE_REGWRITE_BUFFER(ah);
Sujith's avatar
Sujith committed
993

994
995
996
	/*
	 * let mac dma writes be in 128 byte chunks
	 */
997
	REG_RMW(ah, AR_RXCFG, AR_RXCFG_DMASZ_128B, AR_RXCFG_DMASZ_MASK);
Sujith's avatar
Sujith committed
998

999
1000
1001
	/*
	 * Setup receive FIFO threshold to hold off TX activities
	 */
Sujith's avatar
Sujith committed
1002
1003
	REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);

1004
1005
1006
1007
1008
1009
1010
1011
	if (AR_SREV_9300_20_OR_LATER(ah)) {
		REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
		REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);

		ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
			ah->caps.rx_status_len