2 * SPDX-License-Identifier: ISC
4 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5 * Copyright (c) 2002-2008 Atheros Communications, Inc.
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.
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.
23 #ifdef AH_SUPPORT_AR5312
26 #include "ah_internal.h"
29 #include "ar5312/ar5312.h"
30 #include "ar5312/ar5312reg.h"
31 #include "ar5312/ar5312phy.h"
33 #include "ah_eeprom_v3.h"
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 */
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 *);
55 static HAL_BOOL ar5312SetResetReg(struct ath_hal *, uint32_t resetMask);
58 write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
59 HAL_BOOL bChannelChange, int writes)
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)]
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));
78 #undef IS_NO_RESET_TIMER_ADDR
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
87 * bChannelChange is used to preserve DMA/PCU registers across
88 * a HW Reset during channel change.
91 ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
92 struct ieee80211_channel *chan,
93 HAL_BOOL bChannelChange,
94 HAL_RESET_TYPE resetType,
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;
108 int i, regWrites = 0;
110 uint32_t saveLedState = 0;
112 HALASSERT(ah->ah_magic == AR5212_MAGIC);
113 ee = AH_PRIVATE(ah)->ah_eeprom;
115 OS_MARK(ah, AH_MARK_RESET, bChannelChange);
117 * Map public channel to private.
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);
133 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
138 HALASSERT(ahp->ah_eeversion >= AR_EEPROM_VER3);
140 /* Preserve certain DMA hardware registers on a channel change */
141 if (bChannelChange) {
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
159 * Need to save the sequence number to restore it after
162 saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM);
164 saveFrameSeqCount = 0; /* NB: silence compiler */
166 /* If the channel change is across the same mode - perform a fast channel change */
167 if ((IS_2413(ah) || IS_5413(ah))) {
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
173 * -the modes of the previous and requested channel are the same - some ugly code for XR
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 */
187 * Preserve the antenna on a channel change
189 saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
190 if (saveDefAntenna == 0) /* XXX magic constants */
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);
197 /* Save led state from pci config register */
199 saveLedState = OS_REG_READ(ah, AR5312_PCICFG) &
200 (AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK |
203 ar5312RestoreClock(ah, opmode); /* move to refclk operation */
206 * Adjust gain parameters before reset if
207 * there's an outstanding gain updated.
209 (void) ar5212GetRfgain(ah);
211 if (!ar5312ChipReset(ah, chan)) {
212 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
216 /* Setup the indices for the next set of register array writes */
217 if (IEEE80211_IS_CHAN_2GHZ(chan)) {
219 modesIndex = IEEE80211_IS_CHAN_108G(chan) ? 5 :
220 IEEE80211_IS_CHAN_G(chan) ? 4 : 3;
223 modesIndex = IEEE80211_IS_CHAN_ST(chan) ? 2 : 1;
226 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
228 /* Set correct Baseband to analog shift setting to access analog chips. */
229 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
231 regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
232 regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
234 ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
236 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
238 if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))
239 ar5212SetIFSTiming(ah, chan);
241 /* Overwrite INI values for revised chipsets */
242 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
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);
251 if (chan->channel == 2484) {
252 cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta - ee->ee_scaledCh14FilterCckDelta);
254 cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta);
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));
262 OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0);
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);
271 /* Set the mute mask to the correct default */
272 OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
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);
279 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {
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);
288 if (IS_5312_2_X(ah)) {
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));
296 if (IEEE80211_IS_CHAN_2GHZ(chan))
297 OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN, AR_PHY_RXGAIN_TXRX_RF_MAX, 0x0F);
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);
303 /* Set ADC/DAC select values */
304 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04);
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);
310 /* Set ADC/DAC select values */
311 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
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__);
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",
328 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
329 if (IEEE80211_IS_CHAN_OFDM(chan)) {
331 AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)
332 ar5212SetSpurMitigation(ah, chan);
333 ar5212SetDeltaSlope(ah, chan);
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__);
343 /* Restore certain DMA hardware registers on a channel change */
345 OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount);
347 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
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)
352 | AR_STA_ID1_RTS_USE_DEF
353 | ahp->ah_staId1Defaults
355 ar5212SetOperatingMode(ah, opmode);
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));
361 /* Restore previous led state */
363 OS_REG_WRITE(ah, AR5312_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState);
365 /* Restore previous antenna */
366 OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
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));
372 /* Restore bmiss rssi & count thresholds */
373 OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
375 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
377 if (!ar5212SetChannel(ah, chan))
380 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
382 ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
384 ar5212SetRateDurationTable(ah, chan);
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))) {
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);
398 * Setup fast diversity.
399 * Fast diversity can be enabled or disabled via regadd.txt.
400 * Default is enabled.
403 * 0x00009860 0x00009d18 (if 11a / 11g, else no change)
404 * 0x00009970 0x192bb514
405 * 0x0000a208 0xd03e4648
407 * Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change)
408 * 0x00009970 0x192fb514
409 * 0x0000a208 0xd03e6788
412 /* XXX Setup pre PHY ENABLE EAR additions */
415 if (IS_5312_2_X(ah)) {
416 (void) OS_REG_READ(ah, AR_PHY_SLEEP_SCAL);
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.
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;
431 /* Activate the PHY (includes baseband activate and synthesizer on) */
432 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
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
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);
446 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
450 * The udelay method is not reliable with notebooks.
451 * Need to check to see if the baseband is ready
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);
458 (OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */ OS_DELAY(200);
459 OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg);
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);
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;
476 ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
478 /* Setup compression registers */
479 ar5212SetCompRegs(ah);
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);
485 ahp->ah_intrTxqs = 0;
486 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
487 ar5212ResetTxQueue(ah, i);
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.
495 ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN
496 | AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN
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);
507 if (AH_PRIVATE(ah)->ah_rfkillEnabled)
508 ar5212EnableRfKill(ah);
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__);
517 * Set clocks back to 32kHz if they had been using refClk, then
518 * use an external 32kHz crystal when sleeping, if one exists.
520 ar5312SetupClock(ah, opmode);
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.
528 OS_REG_WRITE(ah, AR_BEACON,
529 (OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF)));
531 /* XXX Setup post reset EAR additions */
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 */
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));
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);
561 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
563 if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
564 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
566 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
568 OS_MARK(ah, AH_MARK_RESET_DONE, 0);
572 OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
573 if (status != AH_NULL)
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.
587 ar5312PhyDisable(struct ath_hal *ah)
589 return ar5312SetResetReg(ah, AR_RC_BB);
593 * Places all of hardware into reset
596 ar5312Disable(struct ath_hal *ah)
598 if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
601 * Reset the HW - PCI must be reset after the rest of the
602 * device has been reset.
604 return ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB);
608 * Places the hardware into reset and then pulls it out of reset
610 * TODO: Only write the PLL if we're changing to or from CCK mode
612 * WARNING: The order of the PLL and mode registers must be correct.
615 ar5312ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
618 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
623 if (!ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB)) {
624 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n",
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",
636 /* Clear warm reset register */
637 if (!ar5312SetResetReg(ah, 0)) {
638 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n",
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
651 * Set CCK and Turbo modes correctly.
653 if (chan != AH_NULL) { /* NB: can be null during attach */
654 uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
656 if (IS_RAD5112_ANY(ah)) {
657 rfMode = AR_PHY_MODE_AR5112;
659 if (IEEE80211_IS_CHAN_CCK(chan)) {
660 phyPLL = AR_PHY_PLL_CTL_44_5312;
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;
667 phyPLL = AR_PHY_PLL_CTL_40_5312;
671 if (IEEE80211_IS_CHAN_CCK(chan))
672 phyPLL = AR_PHY_PLL_CTL_44_5112;
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;
681 rfMode = AR_PHY_MODE_AR5111;
682 if (IEEE80211_IS_CHAN_CCK(chan))
683 phyPLL = AR_PHY_PLL_CTL_44;
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;
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;
696 rfMode |= AR_PHY_MODE_CCK;
697 if (IEEE80211_IS_CHAN_5GHZ(chan))
698 rfMode |= AR_PHY_MODE_RF5GHZ;
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);
705 * PLL, Mode, and Turbo values must be written in the correct
707 * - The PLL cannot be set to 44 unless the CCK or DYNAMIC
709 * - Turbo cannot be set at the same time as CCK or DYNAMIC
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);
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);
725 OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
726 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
733 * Write the given reset bit mask into the reset register
736 ar5312SetResetReg(struct ath_hal *ah, uint32_t resetMask)
738 uint32_t mask = resetMask ? resetMask : ~0;
741 if ((rt = ar5312MacReset(ah, mask)) == AH_FALSE) {
744 if ((resetMask & AR_RC_MAC) == 0) {
747 * Set CFG, little-endian for descriptor accesses.
749 #ifdef AH_NEED_DESC_SWAP
750 mask = INIT_CONFIG_STATUS | AR_CFG_SWRD;
752 mask = INIT_CONFIG_STATUS |
753 AR_CFG_SWTD | AR_CFG_SWRD;
755 OS_REG_WRITE(ah, AR_CFG, mask);
757 OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
763 * ar5312MacReset resets (and then un-resets) the specified
764 * wireless components.
765 * Note: The RCMask cannot be zero on entering from ar5312SetResetReg.
769 ar5312MacReset(struct ath_hal *ah, unsigned int RCMask)
771 int wlanNum = AR5312_UNIT(ah);
772 uint32_t resetBB, resetBits, regMask;
777 #if ( AH_SUPPORT_2316 || AH_SUPPORT_2317 )
781 resetBB = AR5315_RC_BB0_CRES | AR5315_RC_WBB0_RES;
782 /* Warm and cold reset bits for wbb */
783 resetBits = AR5315_RC_WMAC0_RES;
786 resetBB = AR5315_RC_BB1_CRES | AR5315_RC_WBB1_RES;
787 /* Warm and cold reset bits for wbb */
788 resetBits = AR5315_RC_WMAC1_RES;
793 regMask = ~(resetBB | resetBits);
796 reg = OS_REG_READ(ah,
797 (AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh) + AR5315_RESET));
799 if (RCMask == AR_RC_BB) {
800 /* Put baseband in reset */
801 reg |= resetBB; /* Cold and warm reset the baseband bits */
804 * Reset the MAC and baseband. This is a bit different than
805 * the PCI version, but holding in reset causes problems.
808 reg |= (resetBits | resetBB) ;
811 (AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5315_RESET),
815 (AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh) +AR5315_RESET));
818 /* Bring MAC and baseband out of reset */
822 (AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
824 (AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5315_RESET),
828 (AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
836 resetBB = AR5312_RC_BB0_CRES | AR5312_RC_WBB0_RES;
837 /* Warm and cold reset bits for wbb */
838 resetBits = AR5312_RC_WMAC0_RES;
841 resetBB = AR5312_RC_BB1_CRES | AR5312_RC_WBB1_RES;
842 /* Warm and cold reset bits for wbb */
843 resetBits = AR5312_RC_WMAC1_RES;
848 regMask = ~(resetBB | resetBits);
851 reg = OS_REG_READ(ah,
852 (AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh) + AR5312_RESET));
854 if (RCMask == AR_RC_BB) {
855 /* Put baseband in reset */
856 reg |= resetBB; /* Cold and warm reset the baseband bits */
859 * Reset the MAC and baseband. This is a bit different than
860 * the PCI version, but holding in reset causes problems.
863 reg |= (resetBits | resetBB) ;
866 (AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5312_RESET),
870 (AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh) +AR5312_RESET));
873 /* Bring MAC and baseband out of reset */
877 (AR5312_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5312_RESET));
879 (AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5312_RESET),
883 (AR5312_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5312_RESET));
888 #endif /* AH_SUPPORT_AR5312 */