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