xref: /freebsd/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c (revision dd41de95a84d979615a2ef11df6850622bf6184e)
1 /*-
2  * SPDX-License-Identifier: ISC
3  *
4  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5  * Copyright (c) 2002-2008 Atheros Communications, Inc.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  *
19  * $FreeBSD$
20  */
21 #include "opt_ah.h"
22 
23 #ifdef AH_SUPPORT_AR5312
24 
25 #include "ah.h"
26 #include "ah_internal.h"
27 #include "ah_devid.h"
28 
29 #include "ar5312/ar5312.h"
30 #include "ar5312/ar5312reg.h"
31 #include "ar5312/ar5312phy.h"
32 
33 #include "ah_eeprom_v3.h"
34 
35 /* Additional Time delay to wait after activiting the Base band */
36 #define BASE_ACTIVATE_DELAY	100	/* 100 usec */
37 #define PLL_SETTLE_DELAY	300	/* 300 usec */
38 
39 extern int16_t ar5212GetNf(struct ath_hal *, const struct ieee80211_channel *);
40 extern void ar5212SetRateDurationTable(struct ath_hal *,
41 		const struct ieee80211_channel *);
42 extern HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah,
43 	         const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
44 extern void ar5212SetDeltaSlope(struct ath_hal *,
45 		 const struct ieee80211_channel *);
46 extern HAL_BOOL ar5212SetBoardValues(struct ath_hal *,
47 		 const struct ieee80211_channel *);
48 extern void ar5212SetIFSTiming(struct ath_hal *,
49 		 const struct ieee80211_channel *);
50 extern HAL_BOOL	ar5212IsSpurChannel(struct ath_hal *,
51 		 const struct ieee80211_channel *);
52 extern HAL_BOOL	ar5212ChannelChange(struct ath_hal *,
53 		 const struct ieee80211_channel *);
54 
55 static HAL_BOOL ar5312SetResetReg(struct ath_hal *, uint32_t resetMask);
56 
57 static int
58 write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
59 	HAL_BOOL bChannelChange, int writes)
60 {
61 #define IS_NO_RESET_TIMER_ADDR(x)                      \
62     ( (((x) >= AR_BEACON) && ((x) <= AR_CFP_DUR)) || \
63       (((x) >= AR_SLEEP1) && ((x) <= AR_SLEEP3)))
64 #define	V(r, c)	(ia)->data[((r)*(ia)->cols) + (c)]
65 	int i;
66 
67 	/* Write Common Array Parameters */
68 	for (i = 0; i < ia->rows; i++) {
69 		uint32_t reg = V(i, 0);
70 		/* XXX timer/beacon setup registers? */
71 		/* On channel change, don't reset the PCU registers */
72 		if (!(bChannelChange && IS_NO_RESET_TIMER_ADDR(reg))) {
73 			OS_REG_WRITE(ah, reg, V(i, 1));
74 			DMA_YIELD(writes);
75 		}
76 	}
77 	return writes;
78 #undef IS_NO_RESET_TIMER_ADDR
79 #undef V
80 }
81 
82 /*
83  * Places the device in and out of reset and then places sane
84  * values in the registers based on EEPROM config, initialization
85  * vectors (as determined by the mode), and station configuration
86  *
87  * bChannelChange is used to preserve DMA/PCU registers across
88  * a HW Reset during channel change.
89  */
90 HAL_BOOL
91 ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
92 	struct ieee80211_channel *chan,
93 	HAL_BOOL bChannelChange,
94 	HAL_RESET_TYPE resetType,
95 	HAL_STATUS *status)
96 {
97 #define	N(a)	(sizeof (a) / sizeof (a[0]))
98 #define	FAIL(_code)	do { ecode = _code; goto bad; } while (0)
99 	struct ath_hal_5212 *ahp = AH5212(ah);
100 	HAL_CHANNEL_INTERNAL *ichan;
101 	const HAL_EEPROM *ee;
102 	uint32_t saveFrameSeqCount, saveDefAntenna;
103 	uint32_t macStaId1, synthDelay, txFrm2TxDStart;
104 	uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
105 	int16_t cckOfdmPwrDelta = 0;
106 	u_int modesIndex, freqIndex;
107 	HAL_STATUS ecode;
108 	int i, regWrites = 0;
109 	uint32_t testReg;
110 	uint32_t saveLedState = 0;
111 
112 	HALASSERT(ah->ah_magic == AR5212_MAGIC);
113 	ee = AH_PRIVATE(ah)->ah_eeprom;
114 
115 	OS_MARK(ah, AH_MARK_RESET, bChannelChange);
116 	/*
117 	 * Map public channel to private.
118 	 */
119 	ichan = ath_hal_checkchannel(ah, chan);
120 	if (ichan == AH_NULL) {
121 		HALDEBUG(ah, HAL_DEBUG_ANY,
122 		    "%s: invalid channel %u/0x%x; no mapping\n",
123 		    __func__, chan->ic_freq, chan->ic_flags);
124 		FAIL(HAL_EINVAL);
125 	}
126 	switch (opmode) {
127 	case HAL_M_STA:
128 	case HAL_M_IBSS:
129 	case HAL_M_HOSTAP:
130 	case HAL_M_MONITOR:
131 		break;
132 	default:
133 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
134 		    __func__, opmode);
135 		FAIL(HAL_EINVAL);
136 		break;
137 	}
138 	HALASSERT(ahp->ah_eeversion >= AR_EEPROM_VER3);
139 
140 	/* Preserve certain DMA hardware registers on a channel change */
141 	if (bChannelChange) {
142 		/*
143 		 * On Venice, the TSF is almost preserved across a reset;
144 		 * it requires the doubling writes to the RESET_TSF
145 		 * bit in the AR_BEACON register; it also has the quirk
146 		 * of the TSF going back in time on the station (station
147 		 * latches onto the last beacon's tsf during a reset 50%
148 		 * of the times); the latter is not a problem for adhoc
149 		 * stations since as long as the TSF is behind, it will
150 		 * get resynchronized on receiving the next beacon; the
151 		 * TSF going backwards in time could be a problem for the
152 		 * sleep operation (supported on infrastructure stations
153 		 * only) - the best and most general fix for this situation
154 		 * is to resynchronize the various sleep/beacon timers on
155 		 * the receipt of the next beacon i.e. when the TSF itself
156 		 * gets resynchronized to the AP's TSF - power save is
157 		 * needed to be temporarily disabled until that time
158 		 *
159 		 * Need to save the sequence number to restore it after
160 		 * the reset!
161 		 */
162 		saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM);
163 	} else
164 		saveFrameSeqCount = 0;		/* NB: silence compiler */
165 
166 	/* If the channel change is across the same mode - perform a fast channel change */
167 	if ((IS_2413(ah) || IS_5413(ah))) {
168 		/*
169 		 * Channel change can only be used when:
170 		 *  -channel change requested - so it's not the initial reset.
171 		 *  -it's not a change to the current channel - often called when switching modes
172 		 *   on a channel
173 		 *  -the modes of the previous and requested channel are the same - some ugly code for XR
174 		 */
175 		if (bChannelChange &&
176 		    AH_PRIVATE(ah)->ah_curchan != AH_NULL &&
177 		    (chan->ic_freq != AH_PRIVATE(ah)->ah_curchan->ic_freq) &&
178 		    ((chan->ic_flags & IEEE80211_CHAN_ALLTURBO) ==
179 		     (AH_PRIVATE(ah)->ah_curchan->ic_flags & IEEE80211_CHAN_ALLTURBO))) {
180 			if (ar5212ChannelChange(ah, chan))
181 				/* If ChannelChange completed - skip the rest of reset */
182 				return AH_TRUE;
183 		}
184 	}
185 
186 	/*
187 	 * Preserve the antenna on a channel change
188 	 */
189 	saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
190 	if (saveDefAntenna == 0)		/* XXX magic constants */
191 		saveDefAntenna = 1;
192 
193 	/* Save hardware flag before chip reset clears the register */
194 	macStaId1 = OS_REG_READ(ah, AR_STA_ID1) &
195 		(AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);
196 
197 	/* Save led state from pci config register */
198 	if (!IS_5315(ah))
199 		saveLedState = OS_REG_READ(ah, AR5312_PCICFG) &
200 			(AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK |
201 			 AR_PCICFG_LEDSLOW);
202 
203 	ar5312RestoreClock(ah, opmode);		/* move to refclk operation */
204 
205 	/*
206 	 * Adjust gain parameters before reset if
207 	 * there's an outstanding gain updated.
208 	 */
209 	(void) ar5212GetRfgain(ah);
210 
211 	if (!ar5312ChipReset(ah, chan)) {
212 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
213 		FAIL(HAL_EIO);
214 	}
215 
216 	/* Setup the indices for the next set of register array writes */
217 	if (IEEE80211_IS_CHAN_2GHZ(chan)) {
218 		freqIndex  = 2;
219 		modesIndex = IEEE80211_IS_CHAN_108G(chan) ? 5 :
220 			     IEEE80211_IS_CHAN_G(chan) ? 4 : 3;
221 	} else {
222 		freqIndex  = 1;
223 		modesIndex = IEEE80211_IS_CHAN_ST(chan) ? 2 : 1;
224 	}
225 
226 	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
227 
228 	/* Set correct Baseband to analog shift setting to access analog chips. */
229 	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
230 
231 	regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
232 	regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
233 		regWrites);
234 	ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
235 
236 	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
237 
238 	if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))
239 		ar5212SetIFSTiming(ah, chan);
240 
241 	/* Overwrite INI values for revised chipsets */
242 	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
243 		/* ADC_CTL */
244 		OS_REG_WRITE(ah, AR_PHY_ADC_CTL,
245 			     SM(2, AR_PHY_ADC_CTL_OFF_INBUFGAIN) |
246 			     SM(2, AR_PHY_ADC_CTL_ON_INBUFGAIN) |
247 			     AR_PHY_ADC_CTL_OFF_PWDDAC |
248 			     AR_PHY_ADC_CTL_OFF_PWDADC);
249 
250 		/* TX_PWR_ADJ */
251 		if (chan->channel == 2484) {
252 			cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta - ee->ee_scaledCh14FilterCckDelta);
253 		} else {
254 			cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta);
255 		}
256 
257 		if (IEEE80211_IS_CHAN_G(chan)) {
258 			OS_REG_WRITE(ah, AR_PHY_TXPWRADJ,
259 				     SM((ee->ee_cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) |
260 				     SM((cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX));
261 		} else {
262 			OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0);
263 		}
264 
265 		/* Add barker RSSI thresh enable as disabled */
266 		OS_REG_CLR_BIT(ah, AR_PHY_DAG_CTRLCCK,
267 			       AR_PHY_DAG_CTRLCCK_EN_RSSI_THR);
268 		OS_REG_RMW_FIELD(ah, AR_PHY_DAG_CTRLCCK,
269 				 AR_PHY_DAG_CTRLCCK_RSSI_THR, 2);
270 
271 		/* Set the mute mask to the correct default */
272 		OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
273 	}
274 
275 	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {
276 		/* Clear reg to alllow RX_CLEAR line debug */
277 		OS_REG_WRITE(ah, AR_PHY_BLUETOOTH,  0);
278 	}
279 	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {
280 #ifdef notyet
281 		/* Enable burst prefetch for the data queues */
282 		OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... );
283 		/* Enable double-buffering */
284 		OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS);
285 #endif
286 	}
287 
288 	if (IS_5312_2_X(ah)) {
289 		/* ADC_CTRL */
290 		OS_REG_WRITE(ah, AR_PHY_SIGMA_DELTA,
291 			     SM(2, AR_PHY_SIGMA_DELTA_ADC_SEL) |
292 			     SM(4, AR_PHY_SIGMA_DELTA_FILT2) |
293 			     SM(0x16, AR_PHY_SIGMA_DELTA_FILT1) |
294 			     SM(0, AR_PHY_SIGMA_DELTA_ADC_CLIP));
295 
296 		if (IEEE80211_IS_CHAN_2GHZ(chan))
297 			OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN, AR_PHY_RXGAIN_TXRX_RF_MAX, 0x0F);
298 
299 		/* CCK Short parameter adjustment in 11B mode */
300 		if (IEEE80211_IS_CHAN_B(chan))
301 			OS_REG_RMW_FIELD(ah, AR_PHY_CCK_RXCTRL4, AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT, 12);
302 
303 		/* Set ADC/DAC select values */
304 		OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04);
305 
306 		/* Increase 11A AGC Settling */
307 		if (IEEE80211_IS_CHAN_A(chan))
308 			OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_AGC, 32);
309 	} else {
310 		/* Set ADC/DAC select values */
311 		OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
312 	}
313 
314 	/* Setup the transmit power values. */
315 	if (!ar5212SetTransmitPower(ah, chan, rfXpdGain)) {
316 		HALDEBUG(ah, HAL_DEBUG_ANY,
317 		    "%s: error init'ing transmit power\n", __func__);
318 		FAIL(HAL_EIO);
319 	}
320 
321 	/* Write the analog registers */
322 	if (!ahp->ah_rfHal->setRfRegs(ah, chan, modesIndex, rfXpdGain)) {
323 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
324 		    __func__);
325 		FAIL(HAL_EIO);
326 	}
327 
328 	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
329 	if (IEEE80211_IS_CHAN_OFDM(chan)) {
330 		if (IS_5413(ah) ||
331 		   AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)
332 			ar5212SetSpurMitigation(ah, chan);
333 		ar5212SetDeltaSlope(ah, chan);
334 	}
335 
336 	/* Setup board specific options for EEPROM version 3 */
337 	if (!ar5212SetBoardValues(ah, chan)) {
338 		HALDEBUG(ah, HAL_DEBUG_ANY,
339 		    "%s: error setting board options\n", __func__);
340 		FAIL(HAL_EIO);
341 	}
342 
343 	/* Restore certain DMA hardware registers on a channel change */
344 	if (bChannelChange)
345 		OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount);
346 
347 	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
348 
349 	OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
350 	OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
351 		| macStaId1
352 		| AR_STA_ID1_RTS_USE_DEF
353 		| ahp->ah_staId1Defaults
354 	);
355 	ar5212SetOperatingMode(ah, opmode);
356 
357 	/* Set Venice BSSID mask according to current state */
358 	OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
359 	OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
360 
361 	/* Restore previous led state */
362 	if (!IS_5315(ah))
363 		OS_REG_WRITE(ah, AR5312_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState);
364 
365 	/* Restore previous antenna */
366 	OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
367 
368 	/* then our BSSID */
369 	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
370 	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
371 
372 	/* Restore bmiss rssi & count thresholds */
373 	OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
374 
375 	OS_REG_WRITE(ah, AR_ISR, ~0);		/* cleared on write */
376 
377 	if (!ar5212SetChannel(ah, chan))
378 		FAIL(HAL_EIO);
379 
380 	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
381 
382 	ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
383 
384 	ar5212SetRateDurationTable(ah, chan);
385 
386 	/* Set Tx frame start to tx data start delay */
387 	if (IS_RAD5112_ANY(ah) &&
388 	    (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
389 		txFrm2TxDStart =
390 			IEEE80211_IS_CHAN_HALF(chan) ?
391 					TX_FRAME_D_START_HALF_RATE:
392 					TX_FRAME_D_START_QUARTER_RATE;
393 		OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL,
394 			AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart);
395 	}
396 
397 	/*
398 	 * Setup fast diversity.
399 	 * Fast diversity can be enabled or disabled via regadd.txt.
400 	 * Default is enabled.
401 	 * For reference,
402 	 *    Disable: reg        val
403 	 *             0x00009860 0x00009d18 (if 11a / 11g, else no change)
404 	 *             0x00009970 0x192bb514
405 	 *             0x0000a208 0xd03e4648
406 	 *
407 	 *    Enable:  0x00009860 0x00009d10 (if 11a / 11g, else no change)
408 	 *             0x00009970 0x192fb514
409 	 *             0x0000a208 0xd03e6788
410 	 */
411 
412 	/* XXX Setup pre PHY ENABLE EAR additions */
413 
414 	/* flush SCAL reg */
415 	if (IS_5312_2_X(ah)) {
416 		(void) OS_REG_READ(ah, AR_PHY_SLEEP_SCAL);
417 	}
418 
419 	/*
420 	 * Wait for the frequency synth to settle (synth goes on
421 	 * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.
422 	 * Value is in 100ns increments.
423 	 */
424 	synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
425 	if (IEEE80211_IS_CHAN_B(chan)) {
426 		synthDelay = (4 * synthDelay) / 22;
427 	} else {
428 		synthDelay /= 10;
429 	}
430 
431 	/* Activate the PHY (includes baseband activate and synthesizer on) */
432 	OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
433 
434 	/*
435 	 * There is an issue if the AP starts the calibration before
436 	 * the base band timeout completes.  This could result in the
437 	 * rx_clear false triggering.  As a workaround we add delay an
438 	 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
439 	 * does not happen.
440 	 */
441 	if (IEEE80211_IS_CHAN_HALF(chan)) {
442 		OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
443 	} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
444 		OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
445 	} else {
446 		OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
447 	}
448 
449 	/*
450 	 * The udelay method is not reliable with notebooks.
451 	 * Need to check to see if the baseband is ready
452 	 */
453 	testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL);
454 	/* Selects the Tx hold */
455 	OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD);
456 	i = 0;
457 	while ((i++ < 20) &&
458 	       (OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */		OS_DELAY(200);
459 	OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg);
460 
461 	/* Calibrate the AGC and start a NF calculation */
462 	OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
463 		  OS_REG_READ(ah, AR_PHY_AGC_CONTROL)
464 		| AR_PHY_AGC_CONTROL_CAL
465 		| AR_PHY_AGC_CONTROL_NF);
466 
467 	if (!IEEE80211_IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
468 		/* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
469 		OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
470 			AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
471 			INIT_IQCAL_LOG_COUNT_MAX);
472 		OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
473 			AR_PHY_TIMING_CTRL4_DO_IQCAL);
474 		ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
475 	} else
476 		ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
477 
478 	/* Setup compression registers */
479 	ar5212SetCompRegs(ah);
480 
481 	/* Set 1:1 QCU to DCU mapping for all queues */
482 	for (i = 0; i < AR_NUM_DCU; i++)
483 		OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
484 
485 	ahp->ah_intrTxqs = 0;
486 	for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
487 		ar5212ResetTxQueue(ah, i);
488 
489 	/*
490 	 * Setup interrupt handling.  Note that ar5212ResetTxQueue
491 	 * manipulates the secondary IMR's as queues are enabled
492 	 * and disabled.  This is done with RMW ops to insure the
493 	 * settings we make here are preserved.
494 	 */
495 	ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN
496 			| AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN
497 			| AR_IMR_HIUERR
498 			;
499 	if (opmode == HAL_M_HOSTAP)
500 		ahp->ah_maskReg |= AR_IMR_MIB;
501 	OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
502 	/* Enable bus errors that are OR'd to set the HIUERR bit */
503 	OS_REG_WRITE(ah, AR_IMR_S2,
504 		OS_REG_READ(ah, AR_IMR_S2)
505 		| AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR);
506 
507 	if (AH_PRIVATE(ah)->ah_rfkillEnabled)
508 		ar5212EnableRfKill(ah);
509 
510 	if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
511 		HALDEBUG(ah, HAL_DEBUG_ANY,
512 		    "%s: offset calibration failed to complete in 1ms;"
513 		    " noisy environment?\n", __func__);
514 	}
515 
516 	/*
517 	 * Set clocks back to 32kHz if they had been using refClk, then
518 	 * use an external 32kHz crystal when sleeping, if one exists.
519 	 */
520 	ar5312SetupClock(ah, opmode);
521 
522 	/*
523 	 * Writing to AR_BEACON will start timers. Hence it should
524 	 * be the last register to be written. Do not reset tsf, do
525 	 * not enable beacons at this point, but preserve other values
526 	 * like beaconInterval.
527 	 */
528 	OS_REG_WRITE(ah, AR_BEACON,
529 		(OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF)));
530 
531 	/* XXX Setup post reset EAR additions */
532 
533 	/*  QoS support */
534 	if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE ||
535 	    (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&
536 	     AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) {
537 		OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa);	/* XXX magic */
538 		OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210);	/* XXX magic */
539 	}
540 
541 	/* Turn on NOACK Support for QoS packets */
542 	OS_REG_WRITE(ah, AR_NOACK,
543 		     SM(2, AR_NOACK_2BIT_VALUE) |
544 		     SM(5, AR_NOACK_BIT_OFFSET) |
545 		     SM(0, AR_NOACK_BYTE_OFFSET));
546 
547 	/* Restore user-specified settings */
548 	if (ahp->ah_miscMode != 0)
549 		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
550 	if (ahp->ah_slottime != (u_int) -1)
551 		ar5212SetSlotTime(ah, ahp->ah_slottime);
552 	if (ahp->ah_acktimeout != (u_int) -1)
553 		ar5212SetAckTimeout(ah, ahp->ah_acktimeout);
554 	if (ahp->ah_ctstimeout != (u_int) -1)
555 		ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);
556 	if (ahp->ah_sifstime != (u_int) -1)
557 		ar5212SetSifsTime(ah, ahp->ah_sifstime);
558 	if (AH_PRIVATE(ah)->ah_diagreg != 0)
559 		OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
560 
561 	AH_PRIVATE(ah)->ah_opmode = opmode;	/* record operating mode */
562 
563 	if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
564 		chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
565 
566 	HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
567 
568 	OS_MARK(ah, AH_MARK_RESET_DONE, 0);
569 
570 	return AH_TRUE;
571 bad:
572 	OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
573 	if (status != AH_NULL)
574 		*status = ecode;
575 	return AH_FALSE;
576 #undef FAIL
577 #undef N
578 }
579 
580 /*
581  * Places the PHY and Radio chips into reset.  A full reset
582  * must be called to leave this state.  The PCI/MAC/PCU are
583  * not placed into reset as we must receive interrupt to
584  * re-enable the hardware.
585  */
586 HAL_BOOL
587 ar5312PhyDisable(struct ath_hal *ah)
588 {
589     return ar5312SetResetReg(ah, AR_RC_BB);
590 }
591 
592 /*
593  * Places all of hardware into reset
594  */
595 HAL_BOOL
596 ar5312Disable(struct ath_hal *ah)
597 {
598 	if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
599 		return AH_FALSE;
600 	/*
601 	 * Reset the HW - PCI must be reset after the rest of the
602 	 * device has been reset.
603 	 */
604 	return ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB);
605 }
606 
607 /*
608  * Places the hardware into reset and then pulls it out of reset
609  *
610  * TODO: Only write the PLL if we're changing to or from CCK mode
611  *
612  * WARNING: The order of the PLL and mode registers must be correct.
613  */
614 HAL_BOOL
615 ar5312ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
616 {
617 
618 	OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
619 
620 	/*
621 	 * Reset the HW
622 	 */
623 	if (!ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB)) {
624 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n",
625 		    __func__);
626 		return AH_FALSE;
627 	}
628 
629 	/* Bring out of sleep mode (AGAIN) */
630 	if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
631 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetPowerMode failed\n",
632 		    __func__);
633 		return AH_FALSE;
634 	}
635 
636 	/* Clear warm reset register */
637 	if (!ar5312SetResetReg(ah, 0)) {
638 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n",
639 		    __func__);
640 		return AH_FALSE;
641 	}
642 
643 	/*
644 	 * Perform warm reset before the mode/PLL/turbo registers
645 	 * are changed in order to deactivate the radio.  Mode changes
646 	 * with an active radio can result in corrupted shifts to the
647 	 * radio device.
648 	 */
649 
650 	/*
651 	 * Set CCK and Turbo modes correctly.
652 	 */
653 	if (chan != AH_NULL) {		/* NB: can be null during attach */
654 		uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
655 
656 		if (IS_RAD5112_ANY(ah)) {
657 			rfMode = AR_PHY_MODE_AR5112;
658 			if (!IS_5315(ah)) {
659 				if (IEEE80211_IS_CHAN_CCK(chan)) {
660 					phyPLL = AR_PHY_PLL_CTL_44_5312;
661 				} else {
662 					if (IEEE80211_IS_CHAN_HALF(chan)) {
663 						phyPLL = AR_PHY_PLL_CTL_40_5312_HALF;
664 					} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
665 						phyPLL = AR_PHY_PLL_CTL_40_5312_QUARTER;
666 					} else {
667 						phyPLL = AR_PHY_PLL_CTL_40_5312;
668 					}
669 				}
670 			} else {
671 				if (IEEE80211_IS_CHAN_CCK(chan))
672 					phyPLL = AR_PHY_PLL_CTL_44_5112;
673 				else
674 					phyPLL = AR_PHY_PLL_CTL_40_5112;
675 				if (IEEE80211_IS_CHAN_HALF(chan))
676 					phyPLL |= AR_PHY_PLL_CTL_HALF;
677 				else if (IEEE80211_IS_CHAN_QUARTER(chan))
678 					phyPLL |= AR_PHY_PLL_CTL_QUARTER;
679 			}
680 		} else {
681 			rfMode = AR_PHY_MODE_AR5111;
682 			if (IEEE80211_IS_CHAN_CCK(chan))
683 				phyPLL = AR_PHY_PLL_CTL_44;
684 			else
685 				phyPLL = AR_PHY_PLL_CTL_40;
686 			if (IEEE80211_IS_CHAN_HALF(chan))
687 				phyPLL = AR_PHY_PLL_CTL_HALF;
688 			else if (IEEE80211_IS_CHAN_QUARTER(chan))
689 				phyPLL = AR_PHY_PLL_CTL_QUARTER;
690 		}
691 		if (IEEE80211_IS_CHAN_G(chan))
692 			rfMode |= AR_PHY_MODE_DYNAMIC;
693 		else if (IEEE80211_IS_CHAN_OFDM(chan))
694 			rfMode |= AR_PHY_MODE_OFDM;
695 		else
696 			rfMode |= AR_PHY_MODE_CCK;
697 		if (IEEE80211_IS_CHAN_5GHZ(chan))
698 			rfMode |= AR_PHY_MODE_RF5GHZ;
699 		else
700 			rfMode |= AR_PHY_MODE_RF2GHZ;
701 		turbo = IEEE80211_IS_CHAN_TURBO(chan) ?
702 			(AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;
703 		curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);
704 		/*
705 		 * PLL, Mode, and Turbo values must be written in the correct
706 		 * order to ensure:
707 		 * - The PLL cannot be set to 44 unless the CCK or DYNAMIC
708 		 *   mode bit is set
709 		 * - Turbo cannot be set at the same time as CCK or DYNAMIC
710 		 */
711 		if (IEEE80211_IS_CHAN_CCK(chan)) {
712 			OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
713 			OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
714 			if (curPhyPLL != phyPLL) {
715 				OS_REG_WRITE(ah,  AR_PHY_PLL_CTL,  phyPLL);
716 				/* Wait for the PLL to settle */
717 				OS_DELAY(PLL_SETTLE_DELAY);
718 			}
719 		} else {
720 			if (curPhyPLL != phyPLL) {
721 				OS_REG_WRITE(ah,  AR_PHY_PLL_CTL,  phyPLL);
722 				/* Wait for the PLL to settle */
723 				OS_DELAY(PLL_SETTLE_DELAY);
724 			}
725 			OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
726 			OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
727 		}
728 	}
729 	return AH_TRUE;
730 }
731 
732 /*
733  * Write the given reset bit mask into the reset register
734  */
735 static HAL_BOOL
736 ar5312SetResetReg(struct ath_hal *ah, uint32_t resetMask)
737 {
738 	uint32_t mask = resetMask ? resetMask : ~0;
739 	HAL_BOOL rt;
740 
741         if ((rt = ar5312MacReset(ah, mask)) == AH_FALSE) {
742 		return rt;
743 	}
744         if ((resetMask & AR_RC_MAC) == 0) {
745 		if (isBigEndian()) {
746 			/*
747 			 * Set CFG, little-endian for descriptor accesses.
748 			 */
749 #ifdef AH_NEED_DESC_SWAP
750 			mask = INIT_CONFIG_STATUS | AR_CFG_SWRD;
751 #else
752 			mask = INIT_CONFIG_STATUS |
753                                 AR_CFG_SWTD | AR_CFG_SWRD;
754 #endif
755 			OS_REG_WRITE(ah, AR_CFG, mask);
756 		} else
757 			OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
758 	}
759 	return rt;
760 }
761 
762 /*
763  * ar5312MacReset resets (and then un-resets) the specified
764  * wireless components.
765  * Note: The RCMask cannot be zero on entering from ar5312SetResetReg.
766  */
767 
768 HAL_BOOL
769 ar5312MacReset(struct ath_hal *ah, unsigned int RCMask)
770 {
771 	int wlanNum = AR5312_UNIT(ah);
772 	uint32_t resetBB, resetBits, regMask;
773 	uint32_t reg;
774 
775 	if (RCMask == 0)
776 		return(AH_FALSE);
777 #if ( AH_SUPPORT_2316 || AH_SUPPORT_2317 )
778 	    if (IS_5315(ah)) {
779 			switch(wlanNum) {
780 			case 0:
781 				resetBB = AR5315_RC_BB0_CRES | AR5315_RC_WBB0_RES;
782 				/* Warm and cold reset bits for wbb */
783 				resetBits = AR5315_RC_WMAC0_RES;
784 				break;
785 			case 1:
786 				resetBB = AR5315_RC_BB1_CRES | AR5315_RC_WBB1_RES;
787 				/* Warm and cold reset bits for wbb */
788 				resetBits = AR5315_RC_WMAC1_RES;
789 				break;
790 			default:
791 				return(AH_FALSE);
792 			}
793 			regMask = ~(resetBB | resetBits);
794 
795 			/* read before */
796 			reg = OS_REG_READ(ah,
797 							  (AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh) + AR5315_RESET));
798 
799 			if (RCMask == AR_RC_BB) {
800 				/* Put baseband in reset */
801 				reg |= resetBB;    /* Cold and warm reset the baseband bits */
802 			} else {
803 				/*
804 				 * Reset the MAC and baseband.  This is a bit different than
805 				 * the PCI version, but holding in reset causes problems.
806 				 */
807 				reg &= regMask;
808 				reg |= (resetBits | resetBB) ;
809 			}
810 			OS_REG_WRITE(ah,
811 						 (AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5315_RESET),
812 						 reg);
813 			/* read after */
814 			OS_REG_READ(ah,
815 						(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh) +AR5315_RESET));
816 			OS_DELAY(100);
817 
818 			/* Bring MAC and baseband out of reset */
819 			reg &= regMask;
820 			/* read before */
821 			OS_REG_READ(ah,
822 						(AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
823 			OS_REG_WRITE(ah,
824 						 (AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5315_RESET),
825 						 reg);
826 			/* read after */
827 			OS_REG_READ(ah,
828 						(AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
829 
830 		}
831         else
832 #endif
833 		{
834 			switch(wlanNum) {
835 			case 0:
836 				resetBB = AR5312_RC_BB0_CRES | AR5312_RC_WBB0_RES;
837 				/* Warm and cold reset bits for wbb */
838 				resetBits = AR5312_RC_WMAC0_RES;
839 				break;
840 			case 1:
841 				resetBB = AR5312_RC_BB1_CRES | AR5312_RC_WBB1_RES;
842 				/* Warm and cold reset bits for wbb */
843 				resetBits = AR5312_RC_WMAC1_RES;
844 				break;
845 			default:
846 				return(AH_FALSE);
847 			}
848 			regMask = ~(resetBB | resetBits);
849 
850 			/* read before */
851 			reg = OS_REG_READ(ah,
852 							  (AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh) + AR5312_RESET));
853 
854 			if (RCMask == AR_RC_BB) {
855 				/* Put baseband in reset */
856 				reg |= resetBB;    /* Cold and warm reset the baseband bits */
857 			} else {
858 				/*
859 				 * Reset the MAC and baseband.  This is a bit different than
860 				 * the PCI version, but holding in reset causes problems.
861 				 */
862 				reg &= regMask;
863 				reg |= (resetBits | resetBB) ;
864 			}
865 			OS_REG_WRITE(ah,
866 						 (AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5312_RESET),
867 						 reg);
868 			/* read after */
869 			OS_REG_READ(ah,
870 						(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh) +AR5312_RESET));
871 			OS_DELAY(100);
872 
873 			/* Bring MAC and baseband out of reset */
874 			reg &= regMask;
875 			/* read before */
876 			OS_REG_READ(ah,
877 						(AR5312_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5312_RESET));
878 			OS_REG_WRITE(ah,
879 						 (AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5312_RESET),
880 						 reg);
881 			/* read after */
882 			OS_REG_READ(ah,
883 						(AR5312_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5312_RESET));
884 		}
885 	return(AH_TRUE);
886 }
887 
888 #endif /* AH_SUPPORT_AR5312 */
889