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