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