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