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.
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
*, 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
);
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)]
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));
70 #undef IS_NO_RESET_TIMER_ADDR
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.
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
;
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
;
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
);
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
);
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
);
136 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: invalid operating mode %u\n",
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
165 saveFrameSeqCount
= OS_REG_READ(ah
, AR_D_SEQNUM
);
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
176 * -the modes of the previous and requested channel are the same
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 */
190 * Preserve the antenna on a channel change
192 saveDefAntenna
= OS_REG_READ(ah
, AR_DEF_ANTENNA
);
193 if (saveDefAntenna
== 0) /* XXX magic constants */
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 */
202 saveLedState
= OS_REG_READ(ah
, AR5312_PCICFG
) &
203 (AR_PCICFG_LEDCTL
| AR_PCICFG_LEDMODE
| AR_PCICFG_LEDBLINK
|
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__
);
219 /* Setup the indices for the next set of register array writes */
220 switch (chan
->channelFlags
& CHANNEL_ALL
) {
242 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: invalid channel flags 0x%x\n",
243 __func__
, chan
->channelFlags
);
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
,
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
) {
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
);
273 if (chan
->channel
== 2484) {
274 cckOfdmPwrDelta
= SCALE_OC_DELTA(ee
->ee_cckOfdmPwrDelta
- ee
->ee_scaledCh14FilterCckDelta
);
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
));
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
) {
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
);
310 if (IS_5312_2_X(ah
)) {
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 */
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);
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__
);
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",
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
)) &&
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__
);
365 /* Restore certain DMA hardware registers on a channel change */
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)
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 */
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
);
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
))
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_5112(ah
) && (IS_CHAN_HALF_RATE(AH_PRIVATE(ah
)->ah_curchan
) ||
410 IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah
)->ah_curchan
))) {
412 (IS_CHAN_HALF_RATE(AH_PRIVATE(ah
)->ah_curchan
)) ?
413 TX_FRAME_D_START_HALF_RATE
:
414 TX_FRAME_D_START_QUARTER_RATE
;
415 OS_REG_RMW_FIELD(ah
, AR_PHY_TX_CTL
,
416 AR_PHY_TX_FRAME_TO_TX_DATA_START
, txFrm2TxDStart
);
420 * Setup fast diversity.
421 * Fast diversity can be enabled or disabled via regadd.txt.
422 * Default is enabled.
425 * 0x00009860 0x00009d18 (if 11a / 11g, else no change)
426 * 0x00009970 0x192bb514
427 * 0x0000a208 0xd03e4648
429 * Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change)
430 * 0x00009970 0x192fb514
431 * 0x0000a208 0xd03e6788
434 /* XXX Setup pre PHY ENABLE EAR additions */
437 if (IS_5312_2_X(ah
)) {
438 (void) OS_REG_READ(ah
, AR_PHY_SLEEP_SCAL
);
442 * Wait for the frequency synth to settle (synth goes on
443 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
444 * Value is in 100ns increments.
446 synthDelay
= OS_REG_READ(ah
, AR_PHY_RX_DELAY
) & AR_PHY_RX_DELAY_DELAY
;
447 if (IS_CHAN_CCK(chan
)) {
448 synthDelay
= (4 * synthDelay
) / 22;
453 /* Activate the PHY (includes baseband activate and synthesizer on) */
454 OS_REG_WRITE(ah
, AR_PHY_ACTIVE
, AR_PHY_ACTIVE_EN
);
457 * There is an issue if the AP starts the calibration before
458 * the base band timeout completes. This could result in the
459 * rx_clear false triggering. As a workaround we add delay an
460 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
463 if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah
)->ah_curchan
)) {
464 OS_DELAY((synthDelay
<< 1) + BASE_ACTIVATE_DELAY
);
465 } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah
)->ah_curchan
)) {
466 OS_DELAY((synthDelay
<< 2) + BASE_ACTIVATE_DELAY
);
468 OS_DELAY(synthDelay
+ BASE_ACTIVATE_DELAY
);
472 * The udelay method is not reliable with notebooks.
473 * Need to check to see if the baseband is ready
475 testReg
= OS_REG_READ(ah
, AR_PHY_TESTCTRL
);
476 /* Selects the Tx hold */
477 OS_REG_WRITE(ah
, AR_PHY_TESTCTRL
, AR_PHY_TESTCTRL_TXHOLD
);
480 (OS_REG_READ(ah
, 0x9c24) & 0x10)) /* test if baseband not ready */ OS_DELAY(200);
481 OS_REG_WRITE(ah
, AR_PHY_TESTCTRL
, testReg
);
483 /* Calibrate the AGC and start a NF calculation */
484 OS_REG_WRITE(ah
, AR_PHY_AGC_CONTROL
,
485 OS_REG_READ(ah
, AR_PHY_AGC_CONTROL
)
486 | AR_PHY_AGC_CONTROL_CAL
487 | AR_PHY_AGC_CONTROL_NF
);
489 if (!IS_CHAN_B(chan
) && ahp
->ah_bIQCalibration
!= IQ_CAL_DONE
) {
490 /* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
491 OS_REG_RMW_FIELD(ah
, AR_PHY_TIMING_CTRL4
,
492 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX
,
493 INIT_IQCAL_LOG_COUNT_MAX
);
494 OS_REG_SET_BIT(ah
, AR_PHY_TIMING_CTRL4
,
495 AR_PHY_TIMING_CTRL4_DO_IQCAL
);
496 ahp
->ah_bIQCalibration
= IQ_CAL_RUNNING
;
498 ahp
->ah_bIQCalibration
= IQ_CAL_INACTIVE
;
500 /* Setup compression registers */
501 ar5212SetCompRegs(ah
);
503 /* Set 1:1 QCU to DCU mapping for all queues */
504 for (i
= 0; i
< AR_NUM_DCU
; i
++)
505 OS_REG_WRITE(ah
, AR_DQCUMASK(i
), 1 << i
);
507 ahp
->ah_intrTxqs
= 0;
508 for (i
= 0; i
< AH_PRIVATE(ah
)->ah_caps
.halTotalQueues
; i
++)
509 ar5212ResetTxQueue(ah
, i
);
512 * Setup interrupt handling. Note that ar5212ResetTxQueue
513 * manipulates the secondary IMR's as queues are enabled
514 * and disabled. This is done with RMW ops to insure the
515 * settings we make here are preserved.
517 ahp
->ah_maskReg
= AR_IMR_TXOK
| AR_IMR_TXERR
| AR_IMR_TXURN
518 | AR_IMR_RXOK
| AR_IMR_RXERR
| AR_IMR_RXORN
521 if (opmode
== HAL_M_HOSTAP
)
522 ahp
->ah_maskReg
|= AR_IMR_MIB
;
523 OS_REG_WRITE(ah
, AR_IMR
, ahp
->ah_maskReg
);
524 /* Enable bus errors that are OR'd to set the HIUERR bit */
525 OS_REG_WRITE(ah
, AR_IMR_S2
,
526 OS_REG_READ(ah
, AR_IMR_S2
)
527 | AR_IMR_S2_MCABT
| AR_IMR_S2_SSERR
| AR_IMR_S2_DPERR
);
529 if (AH_PRIVATE(ah
)->ah_rfkillEnabled
)
530 ar5212EnableRfKill(ah
);
532 if (!ath_hal_wait(ah
, AR_PHY_AGC_CONTROL
, AR_PHY_AGC_CONTROL_CAL
, 0)) {
533 HALDEBUG(ah
, HAL_DEBUG_ANY
,
534 "%s: offset calibration failed to complete in 1ms;"
535 " noisy environment?\n", __func__
);
539 * Set clocks back to 32kHz if they had been using refClk, then
540 * use an external 32kHz crystal when sleeping, if one exists.
542 ar5312SetupClock(ah
, opmode
);
545 * Writing to AR_BEACON will start timers. Hence it should
546 * be the last register to be written. Do not reset tsf, do
547 * not enable beacons at this point, but preserve other values
548 * like beaconInterval.
550 OS_REG_WRITE(ah
, AR_BEACON
,
551 (OS_REG_READ(ah
, AR_BEACON
) &~ (AR_BEACON_EN
| AR_BEACON_RESET_TSF
)));
553 /* XXX Setup post reset EAR additions */
556 if (AH_PRIVATE(ah
)->ah_macVersion
> AR_SREV_VERSION_VENICE
||
557 (AH_PRIVATE(ah
)->ah_macVersion
== AR_SREV_VERSION_VENICE
&&
558 AH_PRIVATE(ah
)->ah_macRev
>= AR_SREV_GRIFFIN_LITE
)) {
559 OS_REG_WRITE(ah
, AR_QOS_CONTROL
, 0x100aa); /* XXX magic */
560 OS_REG_WRITE(ah
, AR_QOS_SELECT
, 0x3210); /* XXX magic */
563 /* Turn on NOACK Support for QoS packets */
564 OS_REG_WRITE(ah
, AR_NOACK
,
565 SM(2, AR_NOACK_2BIT_VALUE
) |
566 SM(5, AR_NOACK_BIT_OFFSET
) |
567 SM(0, AR_NOACK_BYTE_OFFSET
));
569 /* Restore user-specified settings */
570 if (ahp
->ah_miscMode
!= 0)
571 OS_REG_WRITE(ah
, AR_MISC_MODE
, ahp
->ah_miscMode
);
572 if (ahp
->ah_slottime
!= (u_int
) -1)
573 ar5212SetSlotTime(ah
, ahp
->ah_slottime
);
574 if (ahp
->ah_acktimeout
!= (u_int
) -1)
575 ar5212SetAckTimeout(ah
, ahp
->ah_acktimeout
);
576 if (ahp
->ah_ctstimeout
!= (u_int
) -1)
577 ar5212SetCTSTimeout(ah
, ahp
->ah_ctstimeout
);
578 if (ahp
->ah_sifstime
!= (u_int
) -1)
579 ar5212SetSifsTime(ah
, ahp
->ah_sifstime
);
580 if (AH_PRIVATE(ah
)->ah_diagreg
!= 0)
581 OS_REG_WRITE(ah
, AR_DIAG_SW
, AH_PRIVATE(ah
)->ah_diagreg
);
583 AH_PRIVATE(ah
)->ah_opmode
= opmode
; /* record operating mode */
585 if (bChannelChange
) {
586 if (!(ichan
->privFlags
& CHANNEL_DFS
))
587 ichan
->privFlags
&= ~CHANNEL_INTERFERENCE
;
588 chan
->channelFlags
= ichan
->channelFlags
;
589 chan
->privFlags
= ichan
->privFlags
;
592 HALDEBUG(ah
, HAL_DEBUG_RESET
, "%s: done\n", __func__
);
594 OS_MARK(ah
, AH_MARK_RESET_DONE
, 0);
598 OS_MARK(ah
, AH_MARK_RESET_DONE
, ecode
);
607 * Places the PHY and Radio chips into reset. A full reset
608 * must be called to leave this state. The PCI/MAC/PCU are
609 * not placed into reset as we must receive interrupt to
610 * re-enable the hardware.
613 ar5312PhyDisable(struct ath_hal
*ah
)
615 return ar5312SetResetReg(ah
, AR_RC_BB
);
619 * Places all of hardware into reset
622 ar5312Disable(struct ath_hal
*ah
)
624 if (!ar5312SetPowerMode(ah
, HAL_PM_AWAKE
, AH_TRUE
))
627 * Reset the HW - PCI must be reset after the rest of the
628 * device has been reset.
630 return ar5312SetResetReg(ah
, AR_RC_MAC
| AR_RC_BB
);
634 * Places the hardware into reset and then pulls it out of reset
636 * TODO: Only write the PLL if we're changing to or from CCK mode
638 * WARNING: The order of the PLL and mode registers must be correct.
641 ar5312ChipReset(struct ath_hal
*ah
, HAL_CHANNEL
*chan
)
644 OS_MARK(ah
, AH_MARK_CHIPRESET
, chan
? chan
->channel
: 0);
649 if (!ar5312SetResetReg(ah
, AR_RC_MAC
| AR_RC_BB
)) {
650 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: ar5312SetResetReg failed\n",
655 /* Bring out of sleep mode (AGAIN) */
656 if (!ar5312SetPowerMode(ah
, HAL_PM_AWAKE
, AH_TRUE
)) {
657 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: ar5312SetPowerMode failed\n",
662 /* Clear warm reset register */
663 if (!ar5312SetResetReg(ah
, 0)) {
664 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: ar5312SetResetReg failed\n",
670 * Perform warm reset before the mode/PLL/turbo registers
671 * are changed in order to deactivate the radio. Mode changes
672 * with an active radio can result in corrupted shifts to the
677 * Set CCK and Turbo modes correctly.
679 if (chan
!= AH_NULL
) { /* NB: can be null during attach */
680 uint32_t rfMode
, phyPLL
= 0, curPhyPLL
, turbo
;
682 if (IS_5112(ah
) || IS_2413(ah
)) {
683 rfMode
= AR_PHY_MODE_AR5112
;
685 if (IS_CHAN_CCK(chan
) || IS_CHAN_G(chan
)) {
686 phyPLL
= AR_PHY_PLL_CTL_44_5312
;
688 if (IS_CHAN_HALF_RATE(chan
)) {
689 phyPLL
= AR_PHY_PLL_CTL_40_5312_HALF
;
690 } else if (IS_CHAN_QUARTER_RATE(chan
)) {
691 phyPLL
= AR_PHY_PLL_CTL_40_5312_QUARTER
;
693 phyPLL
= AR_PHY_PLL_CTL_40_5312
;
697 if (IS_CHAN_CCK(chan
) || IS_CHAN_G(chan
)) {
698 phyPLL
= AR_PHY_PLL_CTL_44_5112
;
700 if (IS_CHAN_HALF_RATE(chan
)) {
701 phyPLL
= AR_PHY_PLL_CTL_40_5112_HALF
;
702 } else if (IS_CHAN_QUARTER_RATE(chan
)) {
703 phyPLL
= AR_PHY_PLL_CTL_40_5112_QUARTER
;
705 phyPLL
= AR_PHY_PLL_CTL_40_5112
;
710 rfMode
= AR_PHY_MODE_AR5111
;
711 if (IS_CHAN_CCK(chan
) || IS_CHAN_G(chan
)) {
712 phyPLL
= AR_PHY_PLL_CTL_44
;
714 if (IS_CHAN_HALF_RATE(chan
)) {
715 phyPLL
= AR_PHY_PLL_CTL_40_HALF
;
716 } else if (IS_CHAN_QUARTER_RATE(chan
)) {
717 phyPLL
= AR_PHY_PLL_CTL_40_QUARTER
;
719 phyPLL
= AR_PHY_PLL_CTL_40
;
723 if (IS_CHAN_OFDM(chan
) && (IS_CHAN_CCK(chan
) ||
725 rfMode
|= AR_PHY_MODE_DYNAMIC
;
726 else if (IS_CHAN_OFDM(chan
))
727 rfMode
|= AR_PHY_MODE_OFDM
;
729 rfMode
|= AR_PHY_MODE_CCK
;
730 if (IS_CHAN_5GHZ(chan
))
731 rfMode
|= AR_PHY_MODE_RF5GHZ
;
733 rfMode
|= AR_PHY_MODE_RF2GHZ
;
734 turbo
= IS_CHAN_TURBO(chan
) ?
735 (AR_PHY_FC_TURBO_MODE
| AR_PHY_FC_TURBO_SHORT
) : 0;
736 curPhyPLL
= OS_REG_READ(ah
, AR_PHY_PLL_CTL
);
738 * PLL, Mode, and Turbo values must be written in the correct
740 * - The PLL cannot be set to 44 unless the CCK or DYNAMIC
742 * - Turbo cannot be set at the same time as CCK or DYNAMIC
744 if (IS_CHAN_CCK(chan
) || IS_CHAN_G(chan
)) {
745 OS_REG_WRITE(ah
, AR_PHY_TURBO
, turbo
);
746 OS_REG_WRITE(ah
, AR_PHY_MODE
, rfMode
);
747 if (curPhyPLL
!= phyPLL
) {
748 OS_REG_WRITE(ah
, AR_PHY_PLL_CTL
, phyPLL
);
749 /* Wait for the PLL to settle */
750 OS_DELAY(PLL_SETTLE_DELAY
);
753 if (curPhyPLL
!= phyPLL
) {
754 OS_REG_WRITE(ah
, AR_PHY_PLL_CTL
, phyPLL
);
755 /* Wait for the PLL to settle */
756 OS_DELAY(PLL_SETTLE_DELAY
);
758 OS_REG_WRITE(ah
, AR_PHY_TURBO
, turbo
);
759 OS_REG_WRITE(ah
, AR_PHY_MODE
, rfMode
);
766 * Write the given reset bit mask into the reset register
769 ar5312SetResetReg(struct ath_hal
*ah
, uint32_t resetMask
)
771 uint32_t mask
= resetMask
? resetMask
: ~0;
774 if ((rt
= ar5312MacReset(ah
, mask
)) == AH_FALSE
) {
777 if ((resetMask
& AR_RC_MAC
) == 0) {
780 * Set CFG, little-endian for register
781 * and descriptor accesses.
783 #ifdef AH_NEED_DESC_SWAP
784 mask
= INIT_CONFIG_STATUS
| AR_CFG_SWRD
;
786 mask
= INIT_CONFIG_STATUS
|
787 AR_CFG_SWTD
| AR_CFG_SWRD
;
789 OS_REG_WRITE(ah
, AR_CFG
, mask
);
791 OS_REG_WRITE(ah
, AR_CFG
, INIT_CONFIG_STATUS
);
797 * ar5312MacReset resets (and then un-resets) the specified
798 * wireless components.
799 * Note: The RCMask cannot be zero on entering from ar5312SetResetReg.
803 ar5312MacReset(struct ath_hal
*ah
, unsigned int RCMask
)
805 int wlanNum
= AR5312_UNIT(ah
);
806 uint32_t resetBB
, resetBits
, regMask
;
811 #if ( AH_SUPPORT_2316 || AH_SUPPORT_2317 )
815 resetBB
= AR5315_RC_BB0_CRES
| AR5315_RC_WBB0_RES
;
816 /* Warm and cold reset bits for wbb */
817 resetBits
= AR5315_RC_WMAC0_RES
;
820 resetBB
= AR5315_RC_BB1_CRES
| AR5315_RC_WBB1_RES
;
821 /* Warm and cold reset bits for wbb */
822 resetBits
= AR5315_RC_WMAC1_RES
;
827 regMask
= ~(resetBB
| resetBits
);
830 reg
= OS_REG_READ(ah
,
831 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) + AR5315_RESET
));
833 if (RCMask
== AR_RC_BB
) {
834 /* Put baseband in reset */
835 reg
|= resetBB
; /* Cold and warm reset the baseband bits */
838 * Reset the MAC and baseband. This is a bit different than
839 * the PCI version, but holding in reset causes problems.
842 reg
|= (resetBits
| resetBB
) ;
845 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
)+AR5315_RESET
),
849 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5315_RESET
));
852 /* Bring MAC and baseband out of reset */
856 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5315_RESET
));
858 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
)+AR5315_RESET
),
862 (AR5315_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5315_RESET
));
872 resetBB
= AR5312_RC_BB0_CRES
| AR5312_RC_WBB0_RES
;
873 /* Warm and cold reset bits for wbb */
874 resetBits
= AR5312_RC_WMAC0_RES
;
877 resetBB
= AR5312_RC_BB1_CRES
| AR5312_RC_WBB1_RES
;
878 /* Warm and cold reset bits for wbb */
879 resetBits
= AR5312_RC_WMAC1_RES
;
884 regMask
= ~(resetBB
| resetBits
);
887 reg
= OS_REG_READ(ah
,
888 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) + AR5312_RESET
));
890 if (RCMask
== AR_RC_BB
) {
891 /* Put baseband in reset */
892 reg
|= resetBB
; /* Cold and warm reset the baseband bits */
895 * Reset the MAC and baseband. This is a bit different than
896 * the PCI version, but holding in reset causes problems.
899 reg
|= (resetBits
| resetBB
) ;
902 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
)+AR5312_RESET
),
906 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5312_RESET
));
909 /* Bring MAC and baseband out of reset */
913 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5312_RESET
));
915 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
)+AR5312_RESET
),
919 (AR5312_RSTIMER_BASE
- ((uint32_t) ah
->ah_sh
) +AR5312_RESET
));
924 #endif /* AH_SUPPORT_AR5312 */