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