xref: /freebsd/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c (revision 10b59a9b4add0320d52c15ce057dd697261e7dfc)
1 /*
2  * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
3  * Copyright (c) 2008 Atheros Communications, Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  *
17  * $FreeBSD$
18  */
19 #include "opt_ah.h"
20 
21 #include "ah.h"
22 #include "ah_internal.h"
23 #include "ah_devid.h"
24 
25 #include "ah_eeprom_v14.h"		/* XXX for tx/rx gain */
26 
27 #include "ar9002/ar9280.h"
28 #include "ar5416/ar5416reg.h"
29 #include "ar5416/ar5416phy.h"
30 
31 #include "ar9002/ar9280v1.ini"
32 #include "ar9002/ar9280v2.ini"
33 #include "ar9002/ar9280_olc.h"
34 
35 static const HAL_PERCAL_DATA ar9280_iq_cal = {		/* single sample */
36 	.calName = "IQ", .calType = IQ_MISMATCH_CAL,
37 	.calNumSamples	= MIN_CAL_SAMPLES,
38 	.calCountMax	= PER_MAX_LOG_COUNT,
39 	.calCollect	= ar5416IQCalCollect,
40 	.calPostProc	= ar5416IQCalibration
41 };
42 static const HAL_PERCAL_DATA ar9280_adc_gain_cal = {	/* single sample */
43 	.calName = "ADC Gain", .calType = ADC_GAIN_CAL,
44 	.calNumSamples	= MIN_CAL_SAMPLES,
45 	.calCountMax	= PER_MAX_LOG_COUNT,
46 	.calCollect	= ar5416AdcGainCalCollect,
47 	.calPostProc	= ar5416AdcGainCalibration
48 };
49 static const HAL_PERCAL_DATA ar9280_adc_dc_cal = {	/* single sample */
50 	.calName = "ADC DC", .calType = ADC_DC_CAL,
51 	.calNumSamples	= MIN_CAL_SAMPLES,
52 	.calCountMax	= PER_MAX_LOG_COUNT,
53 	.calCollect	= ar5416AdcDcCalCollect,
54 	.calPostProc	= ar5416AdcDcCalibration
55 };
56 static const HAL_PERCAL_DATA ar9280_adc_init_dc_cal = {
57 	.calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
58 	.calNumSamples	= MIN_CAL_SAMPLES,
59 	.calCountMax	= INIT_LOG_COUNT,
60 	.calCollect	= ar5416AdcDcCalCollect,
61 	.calPostProc	= ar5416AdcDcCalibration
62 };
63 
64 static void ar9280ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
65 static HAL_BOOL ar9280FillCapabilityInfo(struct ath_hal *ah);
66 static void ar9280WriteIni(struct ath_hal *ah,
67 	const struct ieee80211_channel *chan);
68 
69 static void
70 ar9280AniSetup(struct ath_hal *ah)
71 {
72 	/*
73 	 * These are the parameters from the AR5416 ANI code;
74 	 * they likely need quite a bit of adjustment for the
75 	 * AR9280.
76 	 */
77         static const struct ar5212AniParams aniparams = {
78                 .maxNoiseImmunityLevel  = 4,    /* levels 0..4 */
79                 .totalSizeDesired       = { -55, -55, -55, -55, -62 },
80                 .coarseHigh             = { -14, -14, -14, -14, -12 },
81                 .coarseLow              = { -64, -64, -64, -64, -70 },
82                 .firpwr                 = { -78, -78, -78, -78, -80 },
83                 .maxSpurImmunityLevel   = 2,
84                 .cycPwrThr1             = { 2, 4, 6 },
85                 .maxFirstepLevel        = 2,    /* levels 0..2 */
86                 .firstep                = { 0, 4, 8 },
87                 .ofdmTrigHigh           = 500,
88                 .ofdmTrigLow            = 200,
89                 .cckTrigHigh            = 200,
90                 .cckTrigLow             = 100,
91                 .rssiThrHigh            = 40,
92                 .rssiThrLow             = 7,
93                 .period                 = 100,
94         };
95 	/* NB: disable ANI noise immmunity for reliable RIFS rx */
96 	AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
97 
98         /* NB: ANI is not enabled yet */
99         ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
100 }
101 
102 void
103 ar9280InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
104 {
105 	uint32_t pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV);
106 
107 	if (AR_SREV_MERLIN_20(ah) &&
108 	    chan != AH_NULL && IEEE80211_IS_CHAN_5GHZ(chan)) {
109 		/*
110 		 * PLL WAR for Merlin 2.0/2.1
111 		 * When doing fast clock, set PLL to 0x142c
112 		 * Else, set PLL to 0x2850 to prevent reset-to-reset variation
113 		 */
114 		pll = IS_5GHZ_FAST_CLOCK_EN(ah, chan) ? 0x142c : 0x2850;
115 	} else if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
116 		pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV);
117 		if (chan != AH_NULL) {
118 			if (IEEE80211_IS_CHAN_HALF(chan))
119 				pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
120 			else if (IEEE80211_IS_CHAN_QUARTER(chan))
121 				pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
122 			if (IEEE80211_IS_CHAN_5GHZ(chan))
123 				pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV);
124 			else
125 				pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV);
126 		} else
127 			pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV);
128 	}
129 
130 	OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
131 	OS_DELAY(RTC_PLL_SETTLE_DELAY);
132 	OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK);
133 }
134 
135 /* XXX shouldn't be here! */
136 #define	EEP_MINOR(_ah) \
137 	(AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK)
138 
139 /*
140  * Attach for an AR9280 part.
141  */
142 static struct ath_hal *
143 ar9280Attach(uint16_t devid, HAL_SOFTC sc,
144 	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
145 	HAL_STATUS *status)
146 {
147 	struct ath_hal_9280 *ahp9280;
148 	struct ath_hal_5212 *ahp;
149 	struct ath_hal *ah;
150 	uint32_t val;
151 	HAL_STATUS ecode;
152 	HAL_BOOL rfStatus;
153 	int8_t pwr_table_offset;
154 	uint8_t pwr;
155 
156 	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
157 	    __func__, sc, (void*) st, (void*) sh);
158 
159 	/* NB: memory is returned zero'd */
160 	ahp9280 = ath_hal_malloc(sizeof (struct ath_hal_9280));
161 	if (ahp9280 == AH_NULL) {
162 		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
163 		    "%s: cannot allocate memory for state block\n", __func__);
164 		*status = HAL_ENOMEM;
165 		return AH_NULL;
166 	}
167 	ahp = AH5212(ahp9280);
168 	ah = &ahp->ah_priv.h;
169 
170 	ar5416InitState(AH5416(ah), devid, sc, st, sh, status);
171 
172 	/* XXX override with 9280 specific state */
173 	/* override 5416 methods for our needs */
174 	AH5416(ah)->ah_initPLL = ar9280InitPLL;
175 
176 	ah->ah_setAntennaSwitch		= ar9280SetAntennaSwitch;
177 	ah->ah_configPCIE		= ar9280ConfigPCIE;
178 
179 	AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal;
180 	AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal;
181 	AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal;
182 	AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal;
183 	AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
184 
185 	AH5416(ah)->ah_spurMitigate	= ar9280SpurMitigate;
186 	AH5416(ah)->ah_writeIni		= ar9280WriteIni;
187 	AH5416(ah)->ah_olcInit		= ar9280olcInit;
188 	AH5416(ah)->ah_olcTempCompensation = ar9280olcTemperatureCompensation;
189 	AH5416(ah)->ah_setPowerCalTable	= ar9280SetPowerCalTable;
190 
191 	AH5416(ah)->ah_rx_chainmask	= AR9280_DEFAULT_RXCHAINMASK;
192 	AH5416(ah)->ah_tx_chainmask	= AR9280_DEFAULT_TXCHAINMASK;
193 
194 	if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
195 		/* reset chip */
196 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
197 		    __func__);
198 		ecode = HAL_EIO;
199 		goto bad;
200 	}
201 
202 	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
203 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
204 		    __func__);
205 		ecode = HAL_EIO;
206 		goto bad;
207 	}
208 	/* Read Revisions from Chips before taking out of reset */
209 	val = OS_REG_READ(ah, AR_SREV);
210 	HALDEBUG(ah, HAL_DEBUG_ATTACH,
211 	    "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
212 	    __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
213 	    MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
214 	/* NB: include chip type to differentiate from pre-Sowl versions */
215 	AH_PRIVATE(ah)->ah_macVersion =
216 	    (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
217 	AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
218 	AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;
219 
220 	/* setup common ini data; rf backends handle remainder */
221 	if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
222 		HAL_INI_INIT(&ahp->ah_ini_modes, ar9280Modes_v2, 6);
223 		HAL_INI_INIT(&ahp->ah_ini_common, ar9280Common_v2, 2);
224 		HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
225 		    ar9280PciePhy_clkreq_always_on_L1_v2, 2);
226 		HAL_INI_INIT(&ahp9280->ah_ini_xmodes,
227 		    ar9280Modes_fast_clock_v2, 3);
228 	} else {
229 		HAL_INI_INIT(&ahp->ah_ini_modes, ar9280Modes_v1, 6);
230 		HAL_INI_INIT(&ahp->ah_ini_common, ar9280Common_v1, 2);
231 		HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
232 		    ar9280PciePhy_v1, 2);
233 	}
234 	ar5416AttachPCIE(ah);
235 
236 	ecode = ath_hal_v14EepromAttach(ah);
237 	if (ecode != HAL_OK)
238 		goto bad;
239 
240 	if (!ar5416ChipReset(ah, AH_NULL)) {	/* reset chip */
241 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
242 		ecode = HAL_EIO;
243 		goto bad;
244 	}
245 
246 	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
247 
248 	if (!ar5212ChipTest(ah)) {
249 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
250 		    __func__);
251 		ecode = HAL_ESELFTEST;
252 		goto bad;
253 	}
254 
255 	/*
256 	 * Set correct Baseband to analog shift
257 	 * setting to access analog chips.
258 	 */
259 	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
260 
261 	/* Read Radio Chip Rev Extract */
262 	AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
263 	switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
264         case AR_RAD2133_SREV_MAJOR:	/* Sowl: 2G/3x3 */
265 	case AR_RAD5133_SREV_MAJOR:	/* Sowl: 2+5G/3x3 */
266 		break;
267 	default:
268 		if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
269 			AH_PRIVATE(ah)->ah_analog5GhzRev =
270 				AR_RAD5133_SREV_MAJOR;
271 			break;
272 		}
273 #ifdef AH_DEBUG
274 		HALDEBUG(ah, HAL_DEBUG_ANY,
275 		    "%s: 5G Radio Chip Rev 0x%02X is not supported by "
276 		    "this driver\n", __func__,
277 		    AH_PRIVATE(ah)->ah_analog5GhzRev);
278 		ecode = HAL_ENOTSUPP;
279 		goto bad;
280 #endif
281 	}
282 	rfStatus = ar9280RfAttach(ah, &ecode);
283 	if (!rfStatus) {
284 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
285 		    __func__, ecode);
286 		goto bad;
287 	}
288 
289 	/* Enable fixup for AR_AN_TOP2 if necessary */
290 	/*
291 	 * The v14 EEPROM layer returns HAL_EIO if PWDCLKIND isn't supported
292 	 * by the EEPROM version.
293 	 *
294 	 * ath9k checks the EEPROM minor version is >= 0x0a here, instead of
295 	 * the abstracted EEPROM access layer.
296 	 */
297 	ecode = ath_hal_eepromGet(ah, AR_EEP_PWDCLKIND, &pwr);
298 	if (AR_SREV_MERLIN_20_OR_LATER(ah) && ecode == HAL_OK && pwr == 0) {
299 		printf("[ath] enabling AN_TOP2_FIXUP\n");
300 		AH5416(ah)->ah_need_an_top2_fixup = 1;
301 	}
302 
303         /*
304          * Check whether the power table offset isn't the default.
305          * This can occur with eeprom minor V21 or greater on Merlin.
306          */
307 	(void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset);
308 	if (pwr_table_offset != AR5416_PWR_TABLE_OFFSET_DB)
309 		ath_hal_printf(ah, "[ath]: default pwr offset: %d dBm != EEPROM pwr offset: %d dBm; curves will be adjusted.\n",
310 		    AR5416_PWR_TABLE_OFFSET_DB, (int) pwr_table_offset);
311 
312 	/* XXX check for >= minor ver 17 */
313 	if (AR_SREV_MERLIN_20(ah)) {
314 		/* setup rxgain table */
315 		switch (ath_hal_eepromGet(ah, AR_EEP_RXGAIN_TYPE, AH_NULL)) {
316 		case AR5416_EEP_RXGAIN_13dB_BACKOFF:
317 			HAL_INI_INIT(&ahp9280->ah_ini_rxgain,
318 			    ar9280Modes_backoff_13db_rxgain_v2, 6);
319 			break;
320 		case AR5416_EEP_RXGAIN_23dB_BACKOFF:
321 			HAL_INI_INIT(&ahp9280->ah_ini_rxgain,
322 			    ar9280Modes_backoff_23db_rxgain_v2, 6);
323 			break;
324 		case AR5416_EEP_RXGAIN_ORIG:
325 			HAL_INI_INIT(&ahp9280->ah_ini_rxgain,
326 			    ar9280Modes_original_rxgain_v2, 6);
327 			break;
328 		default:
329 			HALASSERT(AH_FALSE);
330 			goto bad;		/* XXX ? try to continue */
331 		}
332 	}
333 
334 	/* XXX check for >= minor ver 19 */
335 	if (AR_SREV_MERLIN_20(ah)) {
336 		/* setp txgain table */
337 		switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) {
338 		case AR5416_EEP_TXGAIN_HIGH_POWER:
339 			HAL_INI_INIT(&ahp9280->ah_ini_txgain,
340 			    ar9280Modes_high_power_tx_gain_v2, 6);
341 			break;
342 		case AR5416_EEP_TXGAIN_ORIG:
343 			HAL_INI_INIT(&ahp9280->ah_ini_txgain,
344 			    ar9280Modes_original_tx_gain_v2, 6);
345 			break;
346 		default:
347 			HALASSERT(AH_FALSE);
348 			goto bad;		/* XXX ? try to continue */
349 		}
350 	}
351 
352 	/*
353 	 * Got everything we need now to setup the capabilities.
354 	 */
355 	if (!ar9280FillCapabilityInfo(ah)) {
356 		ecode = HAL_EEREAD;
357 		goto bad;
358 	}
359 
360 	ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
361 	if (ecode != HAL_OK) {
362 		HALDEBUG(ah, HAL_DEBUG_ANY,
363 		    "%s: error getting mac address from EEPROM\n", __func__);
364 		goto bad;
365         }
366 	/* XXX How about the serial number ? */
367 	/* Read Reg Domain */
368 	AH_PRIVATE(ah)->ah_currentRD =
369 	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
370 	AH_PRIVATE(ah)->ah_currentRDext =
371 	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL);
372 
373 	/*
374 	 * ah_miscMode is populated by ar5416FillCapabilityInfo()
375 	 * starting from griffin. Set here to make sure that
376 	 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
377 	 * placed into hardware.
378 	 */
379 	if (ahp->ah_miscMode != 0)
380 		OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
381 
382 	ar9280AniSetup(ah);			/* Anti Noise Immunity */
383 
384 	/* Setup noise floor min/max/nominal values */
385 	AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ;
386 	AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ;
387 	AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ;
388 	AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ;
389 	AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ;
390 	AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ;
391 
392 	ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
393 
394 	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
395 
396 	return ah;
397 bad:
398 	if (ah != AH_NULL)
399 		ah->ah_detach(ah);
400 	if (status)
401 		*status = ecode;
402 	return AH_NULL;
403 }
404 
405 static void
406 ar9280ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
407 {
408 	if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
409 		ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
410 		OS_DELAY(1000);
411 		OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
412 		OS_REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
413 	}
414 }
415 
416 static void
417 ar9280WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
418 {
419 	u_int modesIndex, freqIndex;
420 	int regWrites = 0;
421 	int i;
422 	const HAL_INI_ARRAY *ia;
423 
424 	/* Setup the indices for the next set of register array writes */
425 	/* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
426 	if (IEEE80211_IS_CHAN_2GHZ(chan)) {
427 		freqIndex = 2;
428 		if (IEEE80211_IS_CHAN_HT40(chan))
429 			modesIndex = 3;
430 		else if (IEEE80211_IS_CHAN_108G(chan))
431 			modesIndex = 5;
432 		else
433 			modesIndex = 4;
434 	} else {
435 		freqIndex = 1;
436 		if (IEEE80211_IS_CHAN_HT40(chan) ||
437 		    IEEE80211_IS_CHAN_TURBO(chan))
438 			modesIndex = 2;
439 		else
440 			modesIndex = 1;
441 	}
442 
443 	/* Set correct Baseband to analog shift setting to access analog chips. */
444 	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
445 	OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
446 
447 	/*
448 	 * This is unwound because at the moment, there's a requirement
449 	 * for Merlin (and later, perhaps) to have a specific bit fixed
450 	 * in the AR_AN_TOP2 register before writing it.
451 	 */
452 	ia = &AH5212(ah)->ah_ini_modes;
453 #if 0
454 	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes,
455 	    modesIndex, regWrites);
456 #endif
457 	HALASSERT(modesIndex < ia->cols);
458 	for (i = 0; i < ia->rows; i++) {
459 		uint32_t reg = HAL_INI_VAL(ia, i, 0);
460 		uint32_t val = HAL_INI_VAL(ia, i, modesIndex);
461 
462 		if (reg == AR_AN_TOP2 && AH5416(ah)->ah_need_an_top2_fixup)
463 			val &= ~AR_AN_TOP2_PWDCLKIND;
464 
465 		OS_REG_WRITE(ah, reg, val);
466 
467 		/* Analog shift register delay seems needed for Merlin - PR kern/154220 */
468 		if (reg >= 0x7800 && reg < 0x7900)
469 			OS_DELAY(100);
470 
471 		DMA_YIELD(regWrites);
472 	}
473 
474 	if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
475 		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain,
476 		    modesIndex, regWrites);
477 		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain,
478 		    modesIndex, regWrites);
479 	}
480 	/* XXX Merlin 100us delay for shift registers */
481 	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common,
482 	    1, regWrites);
483 
484 	if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
485 		/* 5GHz channels w/ Fast Clock use different modal values */
486 		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes,
487 		    modesIndex, regWrites);
488 	}
489 }
490 
491 #define	AR_BASE_FREQ_2GHZ	2300
492 #define	AR_BASE_FREQ_5GHZ	4900
493 #define	AR_SPUR_FEEQ_BOUND_HT40	19
494 #define	AR_SPUR_FEEQ_BOUND_HT20	10
495 
496 void
497 ar9280SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan)
498 {
499     static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
500                 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 };
501     static const int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
502                 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 };
503     static int inc[4] = { 0, 100, 0, 0 };
504 
505     int bb_spur = AR_NO_SPUR;
506     int freq;
507     int bin, cur_bin;
508     int bb_spur_off, spur_subchannel_sd;
509     int spur_freq_sd;
510     int spur_delta_phase;
511     int denominator;
512     int upper, lower, cur_vit_mask;
513     int tmp, newVal;
514     int i;
515     CHAN_CENTERS centers;
516 
517     int8_t mask_m[123];
518     int8_t mask_p[123];
519     int8_t mask_amt;
520     int tmp_mask;
521     int cur_bb_spur;
522     HAL_BOOL is2GHz = IEEE80211_IS_CHAN_2GHZ(chan);
523 
524     OS_MEMZERO(&mask_m, sizeof(int8_t) * 123);
525     OS_MEMZERO(&mask_p, sizeof(int8_t) * 123);
526 
527     ar5416GetChannelCenters(ah, chan, &centers);
528     freq = centers.synth_center;
529 
530     /*
531      * Need to verify range +/- 9.38 for static ht20 and +/- 18.75 for ht40,
532      * otherwise spur is out-of-band and can be ignored.
533      */
534     for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
535         cur_bb_spur = ath_hal_getSpurChan(ah, i, is2GHz);
536         /* Get actual spur freq in MHz from EEPROM read value */
537         if (is2GHz) {
538             cur_bb_spur =  (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
539         } else {
540             cur_bb_spur =  (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
541         }
542 
543         if (AR_NO_SPUR == cur_bb_spur)
544             break;
545         cur_bb_spur = cur_bb_spur - freq;
546 
547         if (IEEE80211_IS_CHAN_HT40(chan)) {
548             if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
549                 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
550                 bb_spur = cur_bb_spur;
551                 break;
552             }
553         } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
554                    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
555             bb_spur = cur_bb_spur;
556             break;
557         }
558     }
559 
560     if (AR_NO_SPUR == bb_spur) {
561 #if 1
562         /*
563          * MRC CCK can interfere with beacon detection and cause deaf/mute.
564          * Disable MRC CCK for now.
565          */
566         OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
567 #else
568         /* Enable MRC CCK if no spur is found in this channel. */
569         OS_REG_SET_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
570 #endif
571         return;
572     } else {
573         /*
574          * For Merlin, spur can break CCK MRC algorithm. Disable CCK MRC if spur
575          * is found in this channel.
576          */
577         OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
578     }
579 
580     bin = bb_spur * 320;
581 
582     tmp = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0));
583 
584     newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
585         AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
586         AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
587         AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
588     OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0), newVal);
589 
590     newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
591         AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
592         AR_PHY_SPUR_REG_MASK_RATE_SELECT |
593         AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
594         SM(AR5416_SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
595     OS_REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
596 
597     /* Pick control or extn channel to cancel the spur */
598     if (IEEE80211_IS_CHAN_HT40(chan)) {
599         if (bb_spur < 0) {
600             spur_subchannel_sd = 1;
601             bb_spur_off = bb_spur + 10;
602         } else {
603             spur_subchannel_sd = 0;
604             bb_spur_off = bb_spur - 10;
605         }
606     } else {
607         spur_subchannel_sd = 0;
608         bb_spur_off = bb_spur;
609     }
610 
611     /*
612      * spur_delta_phase = bb_spur/40 * 2**21 for static ht20,
613      * /80 for dyn2040.
614      */
615     if (IEEE80211_IS_CHAN_HT40(chan))
616         spur_delta_phase = ((bb_spur * 262144) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
617     else
618         spur_delta_phase = ((bb_spur * 524288) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
619 
620     /*
621      * in 11A mode the denominator of spur_freq_sd should be 40 and
622      * it should be 44 in 11G
623      */
624     denominator = IEEE80211_IS_CHAN_2GHZ(chan) ? 44 : 40;
625     spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
626 
627     newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
628         SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
629         SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
630     OS_REG_WRITE(ah, AR_PHY_TIMING11, newVal);
631 
632     /* Choose to cancel between control and extension channels */
633     newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
634     OS_REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
635 
636     /*
637      * ============================================
638      * Set Pilot and Channel Masks
639      *
640      * pilot mask 1 [31:0] = +6..-26, no 0 bin
641      * pilot mask 2 [19:0] = +26..+7
642      *
643      * channel mask 1 [31:0] = +6..-26, no 0 bin
644      * channel mask 2 [19:0] = +26..+7
645      */
646     cur_bin = -6000;
647     upper = bin + 100;
648     lower = bin - 100;
649 
650     for (i = 0; i < 4; i++) {
651         int pilot_mask = 0;
652         int chan_mask  = 0;
653         int bp         = 0;
654         for (bp = 0; bp < 30; bp++) {
655             if ((cur_bin > lower) && (cur_bin < upper)) {
656                 pilot_mask = pilot_mask | 0x1 << bp;
657                 chan_mask  = chan_mask | 0x1 << bp;
658             }
659             cur_bin += 100;
660         }
661         cur_bin += inc[i];
662         OS_REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
663         OS_REG_WRITE(ah, chan_mask_reg[i], chan_mask);
664     }
665 
666     /* =================================================
667      * viterbi mask 1 based on channel magnitude
668      * four levels 0-3
669      *  - mask (-27 to 27) (reg 64,0x9900 to 67,0x990c)
670      *      [1 2 2 1] for -9.6 or [1 2 1] for +16
671      *  - enable_mask_ppm, all bins move with freq
672      *
673      *  - mask_select,    8 bits for rates (reg 67,0x990c)
674      *  - mask_rate_cntl, 8 bits for rates (reg 67,0x990c)
675      *      choose which mask to use mask or mask2
676      */
677 
678     /*
679      * viterbi mask 2  2nd set for per data rate puncturing
680      * four levels 0-3
681      *  - mask_select, 8 bits for rates (reg 67)
682      *  - mask (-27 to 27) (reg 98,0x9988 to 101,0x9994)
683      *      [1 2 2 1] for -9.6 or [1 2 1] for +16
684      */
685     cur_vit_mask = 6100;
686     upper        = bin + 120;
687     lower        = bin - 120;
688 
689     for (i = 0; i < 123; i++) {
690         if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
691             if ((abs(cur_vit_mask - bin)) < 75) {
692                 mask_amt = 1;
693             } else {
694                 mask_amt = 0;
695             }
696             if (cur_vit_mask < 0) {
697                 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
698             } else {
699                 mask_p[cur_vit_mask / 100] = mask_amt;
700             }
701         }
702         cur_vit_mask -= 100;
703     }
704 
705     tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
706           | (mask_m[48] << 26) | (mask_m[49] << 24)
707           | (mask_m[50] << 22) | (mask_m[51] << 20)
708           | (mask_m[52] << 18) | (mask_m[53] << 16)
709           | (mask_m[54] << 14) | (mask_m[55] << 12)
710           | (mask_m[56] << 10) | (mask_m[57] <<  8)
711           | (mask_m[58] <<  6) | (mask_m[59] <<  4)
712           | (mask_m[60] <<  2) | (mask_m[61] <<  0);
713     OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
714     OS_REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
715 
716     tmp_mask =             (mask_m[31] << 28)
717           | (mask_m[32] << 26) | (mask_m[33] << 24)
718           | (mask_m[34] << 22) | (mask_m[35] << 20)
719           | (mask_m[36] << 18) | (mask_m[37] << 16)
720           | (mask_m[48] << 14) | (mask_m[39] << 12)
721           | (mask_m[40] << 10) | (mask_m[41] <<  8)
722           | (mask_m[42] <<  6) | (mask_m[43] <<  4)
723           | (mask_m[44] <<  2) | (mask_m[45] <<  0);
724     OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
725     OS_REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
726 
727     tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
728           | (mask_m[18] << 26) | (mask_m[18] << 24)
729           | (mask_m[20] << 22) | (mask_m[20] << 20)
730           | (mask_m[22] << 18) | (mask_m[22] << 16)
731           | (mask_m[24] << 14) | (mask_m[24] << 12)
732           | (mask_m[25] << 10) | (mask_m[26] <<  8)
733           | (mask_m[27] <<  6) | (mask_m[28] <<  4)
734           | (mask_m[29] <<  2) | (mask_m[30] <<  0);
735     OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
736     OS_REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
737 
738     tmp_mask = (mask_m[ 0] << 30) | (mask_m[ 1] << 28)
739           | (mask_m[ 2] << 26) | (mask_m[ 3] << 24)
740           | (mask_m[ 4] << 22) | (mask_m[ 5] << 20)
741           | (mask_m[ 6] << 18) | (mask_m[ 7] << 16)
742           | (mask_m[ 8] << 14) | (mask_m[ 9] << 12)
743           | (mask_m[10] << 10) | (mask_m[11] <<  8)
744           | (mask_m[12] <<  6) | (mask_m[13] <<  4)
745           | (mask_m[14] <<  2) | (mask_m[15] <<  0);
746     OS_REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
747     OS_REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
748 
749     tmp_mask =             (mask_p[15] << 28)
750           | (mask_p[14] << 26) | (mask_p[13] << 24)
751           | (mask_p[12] << 22) | (mask_p[11] << 20)
752           | (mask_p[10] << 18) | (mask_p[ 9] << 16)
753           | (mask_p[ 8] << 14) | (mask_p[ 7] << 12)
754           | (mask_p[ 6] << 10) | (mask_p[ 5] <<  8)
755           | (mask_p[ 4] <<  6) | (mask_p[ 3] <<  4)
756           | (mask_p[ 2] <<  2) | (mask_p[ 1] <<  0);
757     OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
758     OS_REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
759 
760     tmp_mask =             (mask_p[30] << 28)
761           | (mask_p[29] << 26) | (mask_p[28] << 24)
762           | (mask_p[27] << 22) | (mask_p[26] << 20)
763           | (mask_p[25] << 18) | (mask_p[24] << 16)
764           | (mask_p[23] << 14) | (mask_p[22] << 12)
765           | (mask_p[21] << 10) | (mask_p[20] <<  8)
766           | (mask_p[19] <<  6) | (mask_p[18] <<  4)
767           | (mask_p[17] <<  2) | (mask_p[16] <<  0);
768     OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
769     OS_REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
770 
771     tmp_mask =             (mask_p[45] << 28)
772           | (mask_p[44] << 26) | (mask_p[43] << 24)
773           | (mask_p[42] << 22) | (mask_p[41] << 20)
774           | (mask_p[40] << 18) | (mask_p[39] << 16)
775           | (mask_p[38] << 14) | (mask_p[37] << 12)
776           | (mask_p[36] << 10) | (mask_p[35] <<  8)
777           | (mask_p[34] <<  6) | (mask_p[33] <<  4)
778           | (mask_p[32] <<  2) | (mask_p[31] <<  0);
779     OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
780     OS_REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
781 
782     tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
783           | (mask_p[59] << 26) | (mask_p[58] << 24)
784           | (mask_p[57] << 22) | (mask_p[56] << 20)
785           | (mask_p[55] << 18) | (mask_p[54] << 16)
786           | (mask_p[53] << 14) | (mask_p[52] << 12)
787           | (mask_p[51] << 10) | (mask_p[50] <<  8)
788           | (mask_p[49] <<  6) | (mask_p[48] <<  4)
789           | (mask_p[47] <<  2) | (mask_p[46] <<  0);
790     OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
791     OS_REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
792 }
793 
794 /*
795  * Fill all software cached or static hardware state information.
796  * Return failure if capabilities are to come from EEPROM and
797  * cannot be read.
798  */
799 static HAL_BOOL
800 ar9280FillCapabilityInfo(struct ath_hal *ah)
801 {
802 	HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
803 
804 	if (!ar5416FillCapabilityInfo(ah))
805 		return AH_FALSE;
806 	pCap->halNumGpioPins = 10;
807 	pCap->halWowSupport = AH_TRUE;
808 	pCap->halWowMatchPatternExact = AH_TRUE;
809 #if 0
810 	pCap->halWowMatchPatternDword = AH_TRUE;
811 #endif
812 	/* AR9280 is a 2x2 stream device */
813 	pCap->halTxStreams = 2;
814 	pCap->halRxStreams = 2;
815 
816 	pCap->halCSTSupport = AH_TRUE;
817 	pCap->halRifsRxSupport = AH_TRUE;
818 	pCap->halRifsTxSupport = AH_TRUE;
819 	pCap->halRtsAggrLimit = 64*1024;	/* 802.11n max */
820 	pCap->halExtChanDfsSupport = AH_TRUE;
821 	pCap->halUseCombinedRadarRssi = AH_TRUE;
822 #if 0
823 	/* XXX bluetooth */
824 	pCap->halBtCoexSupport = AH_TRUE;
825 #endif
826 	pCap->halAutoSleepSupport = AH_FALSE;	/* XXX? */
827 	pCap->hal4kbSplitTransSupport = AH_FALSE;
828 	/* Disable this so Block-ACK works correctly */
829 	pCap->halHasRxSelfLinkedTail = AH_FALSE;
830 	pCap->halMbssidAggrSupport = AH_TRUE;
831 	pCap->hal4AddrAggrSupport = AH_TRUE;
832 
833 	if (AR_SREV_MERLIN_20(ah)) {
834 		pCap->halPSPollBroken = AH_FALSE;
835 		/*
836 		 * This just enables the support; it doesn't
837 		 * state 5ghz fast clock will always be used.
838 		 */
839 		pCap->halSupportsFastClock5GHz = AH_TRUE;
840 	}
841 	pCap->halRxStbcSupport = 1;
842 	pCap->halTxStbcSupport = 1;
843 	pCap->halEnhancedDfsSupport = AH_TRUE;
844 
845 	return AH_TRUE;
846 }
847 
848 /*
849  * This has been disabled - having the HAL flip chainmasks on/off
850  * when attempting to implement 11n disrupts things. For now, just
851  * leave this flipped off and worry about implementing TX diversity
852  * for legacy and MCS0-7 when 11n is fully functioning.
853  */
854 HAL_BOOL
855 ar9280SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
856 {
857 #define ANTENNA0_CHAINMASK    0x1
858 #define ANTENNA1_CHAINMASK    0x2
859 #if 0
860 	struct ath_hal_5416 *ahp = AH5416(ah);
861 
862 	/* Antenna selection is done by setting the tx/rx chainmasks approp. */
863 	switch (settings) {
864 	case HAL_ANT_FIXED_A:
865 		/* Enable first antenna only */
866 		ahp->ah_tx_chainmask = ANTENNA0_CHAINMASK;
867 		ahp->ah_rx_chainmask = ANTENNA0_CHAINMASK;
868 		break;
869 	case HAL_ANT_FIXED_B:
870 		/* Enable second antenna only, after checking capability */
871 		if (AH_PRIVATE(ah)->ah_caps.halTxChainMask > ANTENNA1_CHAINMASK)
872 			ahp->ah_tx_chainmask = ANTENNA1_CHAINMASK;
873 		ahp->ah_rx_chainmask = ANTENNA1_CHAINMASK;
874 		break;
875 	case HAL_ANT_VARIABLE:
876 		/* Restore original chainmask settings */
877 		/* XXX */
878 		ahp->ah_tx_chainmask = AR9280_DEFAULT_TXCHAINMASK;
879 		ahp->ah_rx_chainmask = AR9280_DEFAULT_RXCHAINMASK;
880 		break;
881 	}
882 
883 	HALDEBUG(ah, HAL_DEBUG_ANY, "%s: settings=%d, tx/rx chainmask=%d/%d\n",
884 	    __func__, settings, ahp->ah_tx_chainmask, ahp->ah_rx_chainmask);
885 
886 #endif
887 	return AH_TRUE;
888 #undef ANTENNA0_CHAINMASK
889 #undef ANTENNA1_CHAINMASK
890 }
891 
892 static const char*
893 ar9280Probe(uint16_t vendorid, uint16_t devid)
894 {
895 	if (vendorid == ATHEROS_VENDOR_ID) {
896 		if (devid == AR9280_DEVID_PCI)
897 			return "Atheros 9220";
898 		if (devid == AR9280_DEVID_PCIE)
899 			return "Atheros 9280";
900 	}
901 	return AH_NULL;
902 }
903 AH_CHIP(AR9280, ar9280Probe, ar9280Attach);
904