2 * Copyright (c) 2002-2009 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 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c 187831 2009-01-28 18:00:22Z sam $
21 #ifdef AH_SUPPORT_AR5312
24 #include "ah_internal.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
*, const struct ieee80211_channel
*);
38 extern void ar5212SetRateDurationTable(struct ath_hal
*,
39 const struct ieee80211_channel
*);
40 extern HAL_BOOL
ar5212SetTransmitPower(struct ath_hal
*ah
,
41 const struct ieee80211_channel
*chan
, uint16_t *rfXpdGain
);
42 extern void ar5212SetDeltaSlope(struct ath_hal
*,
43 const struct ieee80211_channel
*);
44 extern HAL_BOOL
ar5212SetBoardValues(struct ath_hal
*,
45 const struct ieee80211_channel
*);
46 extern void ar5212SetIFSTiming(struct ath_hal
*,
47 const struct ieee80211_channel
*);
48 extern HAL_BOOL
ar5212IsSpurChannel(struct ath_hal
*,
49 const struct ieee80211_channel
*);
50 extern HAL_BOOL
ar5212ChannelChange(struct ath_hal
*,
51 const struct ieee80211_channel
*);
53 static HAL_BOOL
ar5312SetResetReg(struct ath_hal
*, uint32_t resetMask
);
56 write_common(struct ath_hal
*ah
, const HAL_INI_ARRAY
*ia
,
57 HAL_BOOL bChannelChange
, int writes
)
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)]
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));
76 #undef IS_NO_RESET_TIMER_ADDR
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
85 * bChannelChange is used to preserve DMA/PCU registers across
86 * a HW Reset during channel change.
89 ar5312Reset(struct ath_hal
*ah
, HAL_OPMODE opmode
,
90 struct ieee80211_channel
*chan
,
91 HAL_BOOL bChannelChange
, HAL_STATUS
*status
)
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
;
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
;
104 int i
, regWrites
= 0;
106 uint32_t saveLedState
= 0;
108 HALASSERT(ah
->ah_magic
== AR5212_MAGIC
);
109 ee
= AH_PRIVATE(ah
)->ah_eeprom
;
111 OS_MARK(ah
, AH_MARK_RESET
, bChannelChange
);
113 * Map public channel to private.
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
);
129 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: invalid operating mode %u\n",
134 HALASSERT(ahp
->ah_eeversion
>= AR_EEPROM_VER3
);
136 /* Preserve certain DMA hardware registers on a channel change */
137 if (bChannelChange
) {
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
155 * Need to save the sequence number to restore it after
158 saveFrameSeqCount
= OS_REG_READ(ah
, AR_D_SEQNUM
);
160 saveFrameSeqCount
= 0; /* NB: silence compiler */
162 /* If the channel change is across the same mode - perform a fast channel change */
163 if ((IS_2413(ah
) || IS_5413(ah
))) {
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
169 * -the modes of the previous and requested channel are the same - some ugly code for XR
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 */
183 * Preserve the antenna on a channel change
185 saveDefAntenna
= OS_REG_READ(ah
, AR_DEF_ANTENNA
);
186 if (saveDefAntenna
== 0) /* XXX magic constants */
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
);
193 /* Save led state from pci config register */
195 saveLedState
= OS_REG_READ(ah
, AR5312_PCICFG
) &
196 (AR_PCICFG_LEDCTL
| AR_PCICFG_LEDMODE
| AR_PCICFG_LEDBLINK
|
199 ar5312RestoreClock(ah
, opmode
); /* move to refclk operation */
202 * Adjust gain parameters before reset if
203 * there's an outstanding gain updated.
205 (void) ar5212GetRfgain(ah
);
207 if (!ar5312ChipReset(ah
, chan
)) {
208 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: chip reset failed\n", __func__
);
212 /* Setup the indices for the next set of register array writes */
213 if (IEEE80211_IS_CHAN_2GHZ(chan
)) {
215 modesIndex
= IEEE80211_IS_CHAN_108G(chan
) ? 5 :
216 IEEE80211_IS_CHAN_G(chan
) ? 4 : 3;
219 modesIndex
= IEEE80211_IS_CHAN_ST(chan
) ? 2 : 1;
222 OS_MARK(ah
, AH_MARK_RESET_LINE
, __LINE__
);
224 /* Set correct Baseband to analog shift setting to access analog chips. */
225 OS_REG_WRITE(ah
, AR_PHY(0), 0x00000007);
227 regWrites
= ath_hal_ini_write(ah
, &ahp
->ah_ini_modes
, modesIndex
, 0);
228 regWrites
= write_common(ah
, &ahp
->ah_ini_common
, bChannelChange
,
230 ahp
->ah_rfHal
->writeRegs(ah
, modesIndex
, freqIndex
, regWrites
);
232 OS_MARK(ah
, AH_MARK_RESET_LINE
, __LINE__
);
234 if (IEEE80211_IS_CHAN_HALF(chan
) || IEEE80211_IS_CHAN_QUARTER(chan
))
235 ar5212SetIFSTiming(ah
, chan
);
237 /* Overwrite INI values for revised chipsets */
238 if (AH_PRIVATE(ah
)->ah_phyRev
>= AR_PHY_CHIP_ID_REV_2
) {
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
);
247 if (chan
->channel
== 2484) {
248 cckOfdmPwrDelta
= SCALE_OC_DELTA(ee
->ee_cckOfdmPwrDelta
- ee
->ee_scaledCh14FilterCckDelta
);
250 cckOfdmPwrDelta
= SCALE_OC_DELTA(ee
->ee_cckOfdmPwrDelta
);
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
));
258 OS_REG_WRITE(ah
, AR_PHY_TXPWRADJ
, 0);
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);
267 /* Set the mute mask to the correct default */
268 OS_REG_WRITE(ah
, AR_SEQ_MASK
, 0x0000000F);
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);
275 if (AH_PRIVATE(ah
)->ah_phyRev
>= AR_PHY_CHIP_ID_REV_4
) {
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
);
284 if (IS_5312_2_X(ah
)) {
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
));
292 if (IEEE80211_IS_CHAN_2GHZ(chan
))
293 OS_REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
, AR_PHY_RXGAIN_TXRX_RF_MAX
, 0x0F);
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);
299 /* Set ADC/DAC select values */
300 OS_REG_WRITE(ah
, AR_PHY_SLEEP_SCAL
, 0x04);
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);
306 /* Set ADC/DAC select values */
307 OS_REG_WRITE(ah
, AR_PHY_SLEEP_SCAL
, 0x0e);
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__
);
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",
324 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
325 if (IEEE80211_IS_CHAN_OFDM(chan
)) {
327 AH_PRIVATE(ah
)->ah_eeversion
>= AR_EEPROM_VER5_3
)
328 ar5212SetSpurMitigation(ah
, chan
);
329 ar5212SetDeltaSlope(ah
, chan
);
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__
);
339 /* Restore certain DMA hardware registers on a channel change */
341 OS_REG_WRITE(ah
, AR_D_SEQNUM
, saveFrameSeqCount
);
343 OS_MARK(ah
, AH_MARK_RESET_LINE
, __LINE__
);
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)
348 | AR_STA_ID1_RTS_USE_DEF
349 | ahp
->ah_staId1Defaults
351 ar5212SetOperatingMode(ah
, opmode
);
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));
357 /* Restore previous led state */
359 OS_REG_WRITE(ah
, AR5312_PCICFG
, OS_REG_READ(ah
, AR_PCICFG
) | saveLedState
);
361 /* Restore previous antenna */
362 OS_REG_WRITE(ah
, AR_DEF_ANTENNA
, saveDefAntenna
);
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));
368 /* Restore bmiss rssi & count thresholds */
369 OS_REG_WRITE(ah
, AR_RSSI_THR
, ahp
->ah_rssiThr
);
371 OS_REG_WRITE(ah
, AR_ISR
, ~0); /* cleared on write */
373 if (!ar5212SetChannel(ah
, chan
))
376 OS_MARK(ah
, AH_MARK_RESET_LINE
, __LINE__
);
378 ar5212SetCoverageClass(ah
, AH_PRIVATE(ah
)->ah_coverageClass
, 1);
380 ar5212SetRateDurationTable(ah
, chan
);
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
))) {
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
);
394 * Setup fast diversity.
395 * Fast diversity can be enabled or disabled via regadd.txt.
396 * Default is enabled.
399 * 0x00009860 0x00009d18 (if 11a / 11g, else no change)
400 * 0x00009970 0x192bb514
401 * 0x0000a208 0xd03e4648
403 * Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change)
404 * 0x00009970 0x192fb514
405 * 0x0000a208 0xd03e6788
408 /* XXX Setup pre PHY ENABLE EAR additions */
411 if (IS_5312_2_X(ah
)) {
412 (void) OS_REG_READ(ah
, AR_PHY_SLEEP_SCAL
);
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.
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;
427 /* Activate the PHY (includes baseband activate and synthesizer on) */
428 OS_REG_WRITE(ah
, AR_PHY_ACTIVE
, AR_PHY_ACTIVE_EN
);
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
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
);
442 OS_DELAY(synthDelay
+ BASE_ACTIVATE_DELAY
);
446 * The udelay method is not reliable with notebooks.
447 * Need to check to see if the baseband is ready
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
);
454 (OS_REG_READ(ah
, 0x9c24) & 0x10)) /* test if baseband not ready */ OS_DELAY(200);
455 OS_REG_WRITE(ah
, AR_PHY_TESTCTRL
, testReg
);
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
);
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
;
472 ahp
->ah_bIQCalibration
= IQ_CAL_INACTIVE
;
474 /* Setup compression registers */
475 ar5212SetCompRegs(ah
);
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
);
481 ahp
->ah_intrTxqs
= 0;
482 for (i
= 0; i
< AH_PRIVATE(ah
)->ah_caps
.halTotalQueues
; i
++)
483 ar5212ResetTxQueue(ah
, i
);
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.
491 ahp
->ah_maskReg
= AR_IMR_TXOK
| AR_IMR_TXERR
| AR_IMR_TXURN
492 | AR_IMR_RXOK
| AR_IMR_RXERR
| AR_IMR_RXORN
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
);
503 if (AH_PRIVATE(ah
)->ah_rfkillEnabled
)
504 ar5212EnableRfKill(ah
);
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__
);
513 * Set clocks back to 32kHz if they had been using refClk, then
514 * use an external 32kHz crystal when sleeping, if one exists.
516 ar5312SetupClock(ah
, opmode
);
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.
524 OS_REG_WRITE(ah
, AR_BEACON
,
525 (OS_REG_READ(ah
, AR_BEACON
) &~ (AR_BEACON_EN
| AR_BEACON_RESET_TSF
)));
527 /* XXX Setup post reset EAR additions */
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 */
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
));
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
);
557 AH_PRIVATE(ah
)->ah_opmode
= opmode
; /* record operating mode */
559 if (bChannelChange
&& !IEEE80211_IS_CHAN_DFS(chan
))
560 chan
->ic_state
&= ~IEEE80211_CHANSTATE_CWINT
;
562 HALDEBUG(ah
, HAL_DEBUG_RESET
, "%s: done\n", __func__
);
564 OS_MARK(ah
, AH_MARK_RESET_DONE
, 0);
568 OS_MARK(ah
, AH_MARK_RESET_DONE
, ecode
);
569 if (status
!= AH_NULL
)
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.
583 ar5312PhyDisable(struct ath_hal
*ah
)
585 return ar5312SetResetReg(ah
, AR_RC_BB
);
589 * Places all of hardware into reset
592 ar5312Disable(struct ath_hal
*ah
)
594 if (!ar5312SetPowerMode(ah
, HAL_PM_AWAKE
, AH_TRUE
))
597 * Reset the HW - PCI must be reset after the rest of the
598 * device has been reset.
600 return ar5312SetResetReg(ah
, AR_RC_MAC
| AR_RC_BB
);
604 * Places the hardware into reset and then pulls it out of reset
606 * TODO: Only write the PLL if we're changing to or from CCK mode
608 * WARNING: The order of the PLL and mode registers must be correct.
611 ar5312ChipReset(struct ath_hal
*ah
, const struct ieee80211_channel
*chan
)
614 OS_MARK(ah
, AH_MARK_CHIPRESET
, chan
? chan
->ic_freq
: 0);
619 if (!ar5312SetResetReg(ah
, AR_RC_MAC
| AR_RC_BB
)) {
620 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: ar5312SetResetReg failed\n",
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",
632 /* Clear warm reset register */
633 if (!ar5312SetResetReg(ah
, 0)) {
634 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: ar5312SetResetReg failed\n",
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
647 * Set CCK and Turbo modes correctly.
649 if (chan
!= AH_NULL
) { /* NB: can be null during attach */
650 uint32_t rfMode
, phyPLL
= 0, curPhyPLL
, turbo
;
652 if (IS_RAD5112_ANY(ah
)) {
653 rfMode
= AR_PHY_MODE_AR5112
;
655 if (IEEE80211_IS_CHAN_CCK(chan
)) {
656 phyPLL
= AR_PHY_PLL_CTL_44_5312
;
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
;
663 phyPLL
= AR_PHY_PLL_CTL_40_5312
;
667 if (IEEE80211_IS_CHAN_CCK(chan
))
668 phyPLL
= AR_PHY_PLL_CTL_44_5112
;
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
;
677 rfMode
= AR_PHY_MODE_AR5111
;
678 if (IEEE80211_IS_CHAN_CCK(chan
))
679 phyPLL
= AR_PHY_PLL_CTL_44
;
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
;
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
;
692 rfMode
|= AR_PHY_MODE_CCK
;
693 if (IEEE80211_IS_CHAN_5GHZ(chan
))
694 rfMode
|= AR_PHY_MODE_RF5GHZ
;
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
);
701 * PLL, Mode, and Turbo values must be written in the correct
703 * - The PLL cannot be set to 44 unless the CCK or DYNAMIC
705 * - Turbo cannot be set at the same time as CCK or DYNAMIC
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
);
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
);
721 OS_REG_WRITE(ah
, AR_PHY_TURBO
, turbo
);
722 OS_REG_WRITE(ah
, AR_PHY_MODE
, rfMode
);
729 * Write the given reset bit mask into the reset register
732 ar5312SetResetReg(struct ath_hal
*ah
, uint32_t resetMask
)
734 uint32_t mask
= resetMask
? resetMask
: ~0;
737 if ((rt
= ar5312MacReset(ah
, mask
)) == AH_FALSE
) {
740 if ((resetMask
& AR_RC_MAC
) == 0) {
743 * Set CFG, little-endian for register
744 * and descriptor accesses.
746 #ifdef AH_NEED_DESC_SWAP
747 mask
= INIT_CONFIG_STATUS
| AR_CFG_SWRD
;
749 mask
= INIT_CONFIG_STATUS
|
750 AR_CFG_SWTD
| AR_CFG_SWRD
;
752 OS_REG_WRITE(ah
, AR_CFG
, mask
);
754 OS_REG_WRITE(ah
, AR_CFG
, INIT_CONFIG_STATUS
);
760 * ar5312MacReset resets (and then un-resets) the specified
761 * wireless components.
762 * Note: The RCMask cannot be zero on entering from ar5312SetResetReg.
766 ar5312MacReset(struct ath_hal
*ah
, unsigned int RCMask
)
768 int wlanNum
= AR5312_UNIT(ah
);
769 uint32_t resetBB
, resetBits
, regMask
;
774 #if ( AH_SUPPORT_2316 || AH_SUPPORT_2317 )
778 resetBB
= AR5315_RC_BB0_CRES
| AR5315_RC_WBB0_RES
;
779 /* Warm and cold reset bits for wbb */
780 resetBits
= AR5315_RC_WMAC0_RES
;
783 resetBB
= AR5315_RC_BB1_CRES
| AR5315_RC_WBB1_RES
;
784 /* Warm and cold reset bits for wbb */
785 resetBits
= AR5315_RC_WMAC1_RES
;
790 regMask
= ~(resetBB
| resetBits
);
793 reg
= OS_REG_READ(ah
,
794 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) + AR5315_RESET
));
796 if (RCMask
== AR_RC_BB
) {
797 /* Put baseband in reset */
798 reg
|= resetBB
; /* Cold and warm reset the baseband bits */
801 * Reset the MAC and baseband. This is a bit different than
802 * the PCI version, but holding in reset causes problems.
805 reg
|= (resetBits
| resetBB
) ;
808 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
)+AR5315_RESET
),
812 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5315_RESET
));
815 /* Bring MAC and baseband out of reset */
819 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5315_RESET
));
821 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
)+AR5315_RESET
),
825 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5315_RESET
));
835 resetBB
= AR5312_RC_BB0_CRES
| AR5312_RC_WBB0_RES
;
836 /* Warm and cold reset bits for wbb */
837 resetBits
= AR5312_RC_WMAC0_RES
;
840 resetBB
= AR5312_RC_BB1_CRES
| AR5312_RC_WBB1_RES
;
841 /* Warm and cold reset bits for wbb */
842 resetBits
= AR5312_RC_WMAC1_RES
;
847 regMask
= ~(resetBB
| resetBits
);
850 reg
= OS_REG_READ(ah
,
851 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) + AR5312_RESET
));
853 if (RCMask
== AR_RC_BB
) {
854 /* Put baseband in reset */
855 reg
|= resetBB
; /* Cold and warm reset the baseband bits */
858 * Reset the MAC and baseband. This is a bit different than
859 * the PCI version, but holding in reset causes problems.
862 reg
|= (resetBits
| resetBB
) ;
865 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
)+AR5312_RESET
),
869 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5312_RESET
));
872 /* Bring MAC and baseband out of reset */
876 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5312_RESET
));
878 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
)+AR5312_RESET
),
882 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5312_RESET
));
887 #endif /* AH_SUPPORT_AR5312 */