1 1.1 alc /* 2 1.1 alc * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 1.1 alc * Copyright (c) 2002-2004 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.7 jklos * $Id: ar5210_reset.c,v 1.7 2015/11/24 08:48:25 jklos Exp $ 18 1.1 alc */ 19 1.1 alc #include "opt_ah.h" 20 1.1 alc 21 1.1 alc #include "ah.h" 22 1.1 alc #include "ah_internal.h" 23 1.1 alc 24 1.1 alc #include "ar5210/ar5210.h" 25 1.1 alc #include "ar5210/ar5210reg.h" 26 1.1 alc #include "ar5210/ar5210phy.h" 27 1.1 alc 28 1.1 alc #include "ah_eeprom_v1.h" 29 1.1 alc 30 1.1 alc typedef struct { 31 1.1 alc uint32_t Offset; 32 1.1 alc uint32_t Value; 33 1.1 alc } REGISTER_VAL; 34 1.1 alc 35 1.1 alc static const REGISTER_VAL ar5k0007_init[] = { 36 1.1 alc #include "ar5210/ar5k_0007.ini" 37 1.1 alc }; 38 1.1 alc 39 1.1 alc /* Default Power Settings for channels outside of EEPROM range */ 40 1.1 alc static const uint8_t ar5k0007_pwrSettings[17] = { 41 1.1 alc /* gain delta pc dac */ 42 1.1 alc /* 54 48 36 24 18 12 9 54 48 36 24 18 12 9 6 ob db */ 43 1.1 alc 9, 9, 0, 0, 0, 0, 0, 2, 2, 6, 6, 6, 6, 6, 6, 2, 2 44 1.1 alc }; 45 1.1 alc 46 1.1 alc /* 47 1.1 alc * The delay, in usecs, between writing AR_RC with a reset 48 1.1 alc * request and waiting for the chip to settle. If this is 49 1.1 alc * too short then the chip does not come out of sleep state. 50 1.1 alc * Note this value was empirically derived and may be dependent 51 1.1 alc * on the host machine (don't know--the problem was identified 52 1.1 alc * on an IBM 570e laptop; 10us delays worked on other systems). 53 1.1 alc */ 54 1.1 alc #define AR_RC_SETTLE_TIME 20000 55 1.1 alc 56 1.1 alc static HAL_BOOL ar5210SetResetReg(struct ath_hal *, 57 1.2 alc uint32_t resetMask, u_int waitTime); 58 1.1 alc static HAL_BOOL ar5210SetChannel(struct ath_hal *, HAL_CHANNEL_INTERNAL *); 59 1.1 alc static void ar5210SetOperatingMode(struct ath_hal *, int opmode); 60 1.1 alc 61 1.1 alc /* 62 1.1 alc * Places the device in and out of reset and then places sane 63 1.1 alc * values in the registers based on EEPROM config, initialization 64 1.1 alc * vectors (as determined by the mode), and station configuration 65 1.1 alc * 66 1.1 alc * bChannelChange is used to preserve DMA/PCU registers across 67 1.1 alc * a HW Reset during channel change. 68 1.1 alc */ 69 1.1 alc HAL_BOOL 70 1.1 alc ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode, 71 1.1 alc HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status) 72 1.1 alc { 73 1.1 alc #define N(a) (sizeof (a) /sizeof (a[0])) 74 1.1 alc #define FAIL(_code) do { ecode = _code; goto bad; } while (0) 75 1.1 alc struct ath_hal_5210 *ahp = AH5210(ah); 76 1.1 alc const HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom; 77 1.1 alc HAL_CHANNEL_INTERNAL *ichan; 78 1.1 alc HAL_STATUS ecode; 79 1.1 alc uint32_t ledstate; 80 1.1 alc int i, q; 81 1.1 alc 82 1.1 alc HALDEBUG(ah, HAL_DEBUG_RESET, 83 1.1 alc "%s: opmode %u channel %u/0x%x %s channel\n", __func__, 84 1.1 alc opmode, chan->channel, chan->channelFlags, 85 1.1 alc bChannelChange ? "change" : "same"); 86 1.1 alc 87 1.1 alc if ((chan->channelFlags & CHANNEL_5GHZ) == 0) { 88 1.1 alc /* Only 11a mode */ 89 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: channel not 5Ghz\n", __func__); 90 1.1 alc FAIL(HAL_EINVAL); 91 1.1 alc } 92 1.1 alc /* 93 1.1 alc * Map public channel to private. 94 1.1 alc */ 95 1.1 alc ichan = ath_hal_checkchannel(ah, chan); 96 1.1 alc if (ichan == AH_NULL) { 97 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 98 1.1 alc "%s: invalid channel %u/0x%x; no mapping\n", 99 1.1 alc __func__, chan->channel, chan->channelFlags); 100 1.1 alc FAIL(HAL_EINVAL); 101 1.1 alc } 102 1.1 alc switch (opmode) { 103 1.1 alc case HAL_M_STA: 104 1.1 alc case HAL_M_IBSS: 105 1.1 alc case HAL_M_HOSTAP: 106 1.1 alc case HAL_M_MONITOR: 107 1.1 alc break; 108 1.1 alc default: 109 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n", 110 1.1 alc __func__, opmode); 111 1.1 alc FAIL(HAL_EINVAL); 112 1.1 alc break; 113 1.1 alc } 114 1.1 alc 115 1.1 alc ledstate = OS_REG_READ(ah, AR_PCICFG) & 116 1.1 alc (AR_PCICFG_LED_PEND | AR_PCICFG_LED_ACT); 117 1.1 alc 118 1.1 alc if (!ar5210ChipReset(ah, chan)) { 119 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", 120 1.1 alc __func__); 121 1.1 alc FAIL(HAL_EIO); 122 1.1 alc } 123 1.1 alc 124 1.1 alc OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 125 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)); 126 1.1 alc ar5210SetOperatingMode(ah, opmode); 127 1.1 alc 128 1.1 alc switch (opmode) { 129 1.1 alc case HAL_M_HOSTAP: 130 1.1 alc OS_REG_WRITE(ah, AR_BCR, INIT_BCON_CNTRL_REG); 131 1.1 alc OS_REG_WRITE(ah, AR_PCICFG, 132 1.1 alc AR_PCICFG_LED_ACT | AR_PCICFG_LED_BCTL); 133 1.1 alc break; 134 1.1 alc case HAL_M_IBSS: 135 1.1 alc OS_REG_WRITE(ah, AR_BCR, INIT_BCON_CNTRL_REG | AR_BCR_BCMD); 136 1.1 alc OS_REG_WRITE(ah, AR_PCICFG, 137 1.1 alc AR_PCICFG_CLKRUNEN | AR_PCICFG_LED_PEND | AR_PCICFG_LED_BCTL); 138 1.1 alc break; 139 1.1 alc case HAL_M_STA: 140 1.1 alc OS_REG_WRITE(ah, AR_BCR, INIT_BCON_CNTRL_REG); 141 1.1 alc OS_REG_WRITE(ah, AR_PCICFG, 142 1.1 alc AR_PCICFG_CLKRUNEN | AR_PCICFG_LED_PEND | AR_PCICFG_LED_BCTL); 143 1.1 alc break; 144 1.1 alc case HAL_M_MONITOR: 145 1.1 alc OS_REG_WRITE(ah, AR_BCR, INIT_BCON_CNTRL_REG); 146 1.1 alc OS_REG_WRITE(ah, AR_PCICFG, 147 1.1 alc AR_PCICFG_LED_ACT | AR_PCICFG_LED_BCTL); 148 1.1 alc break; 149 1.1 alc } 150 1.1 alc 151 1.1 alc /* Restore previous led state */ 152 1.1 alc OS_REG_WRITE(ah, AR_PCICFG, OS_REG_READ(ah, AR_PCICFG) | ledstate); 153 1.1 alc 154 1.1 alc OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 155 1.1 alc OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4)); 156 1.1 alc 157 1.1 alc OS_REG_WRITE(ah, AR_TXDP0, 0); 158 1.1 alc OS_REG_WRITE(ah, AR_TXDP1, 0); 159 1.1 alc OS_REG_WRITE(ah, AR_RXDP, 0); 160 1.1 alc 161 1.1 alc /* 162 1.1 alc * Initialize interrupt state. 163 1.1 alc */ 164 1.1 alc (void) OS_REG_READ(ah, AR_ISR); /* cleared on read */ 165 1.1 alc OS_REG_WRITE(ah, AR_IMR, 0); 166 1.1 alc OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE); 167 1.1 alc ahp->ah_maskReg = 0; 168 1.1 alc 169 1.1 alc (void) OS_REG_READ(ah, AR_BSR); /* cleared on read */ 170 1.1 alc OS_REG_WRITE(ah, AR_TXCFG, AR_DMASIZE_128B); 171 1.1 alc OS_REG_WRITE(ah, AR_RXCFG, AR_DMASIZE_128B); 172 1.1 alc 173 1.1 alc OS_REG_WRITE(ah, AR_TOPS, 8); /* timeout prescale */ 174 1.1 alc OS_REG_WRITE(ah, AR_RXNOFRM, 8); /* RX no frame timeout */ 175 1.1 alc OS_REG_WRITE(ah, AR_RPGTO, 0); /* RX frame gap timeout */ 176 1.1 alc OS_REG_WRITE(ah, AR_TXNOFRM, 0); /* TX no frame timeout */ 177 1.1 alc 178 1.1 alc OS_REG_WRITE(ah, AR_SFR, 0); 179 1.1 alc OS_REG_WRITE(ah, AR_MIBC, 0); /* unfreeze ctrs + clr state */ 180 1.1 alc OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr); 181 1.1 alc OS_REG_WRITE(ah, AR_CFP_DUR, 0); 182 1.1 alc 183 1.1 alc ar5210SetRxFilter(ah, 0); /* nothing for now */ 184 1.1 alc OS_REG_WRITE(ah, AR_MCAST_FIL0, 0); /* multicast filter */ 185 1.1 alc OS_REG_WRITE(ah, AR_MCAST_FIL1, 0); /* XXX was 2 */ 186 1.1 alc 187 1.1 alc OS_REG_WRITE(ah, AR_TX_MASK0, 0); 188 1.1 alc OS_REG_WRITE(ah, AR_TX_MASK1, 0); 189 1.1 alc OS_REG_WRITE(ah, AR_CLR_TMASK, 1); 190 1.1 alc OS_REG_WRITE(ah, AR_TRIG_LEV, 1); /* minimum */ 191 1.1 alc 192 1.1 alc OS_REG_WRITE(ah, AR_DIAG_SW, 0); 193 1.1 alc 194 1.1 alc OS_REG_WRITE(ah, AR_CFP_PERIOD, 0); 195 1.1 alc OS_REG_WRITE(ah, AR_TIMER0, 0); /* next beacon time */ 196 1.1 alc OS_REG_WRITE(ah, AR_TSF_L32, 0); /* local clock */ 197 1.1 alc OS_REG_WRITE(ah, AR_TIMER1, ~0); /* next DMA beacon alert */ 198 1.1 alc OS_REG_WRITE(ah, AR_TIMER2, ~0); /* next SW beacon alert */ 199 1.1 alc OS_REG_WRITE(ah, AR_TIMER3, 1); /* next ATIM window */ 200 1.1 alc 201 1.1 alc /* Write the INI values for PHYreg initialization */ 202 1.1 alc for (i = 0; i < N(ar5k0007_init); i++) { 203 1.1 alc uint32_t reg = ar5k0007_init[i].Offset; 204 1.1 alc /* On channel change, don't reset the PCU registers */ 205 1.1 alc if (!(bChannelChange && (0x8000 <= reg && reg < 0x9000))) 206 1.1 alc OS_REG_WRITE(ah, reg, ar5k0007_init[i].Value); 207 1.1 alc } 208 1.1 alc 209 1.1 alc /* Setup the transmit power values for cards since 0x0[0-2]05 */ 210 1.1 alc if (!ar5210SetTransmitPower(ah, chan)) { 211 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 212 1.1 alc "%s: error init'ing transmit power\n", __func__); 213 1.1 alc FAIL(HAL_EIO); 214 1.1 alc } 215 1.1 alc 216 1.1 alc OS_REG_WRITE(ah, AR_PHY(10), 217 1.1 alc (OS_REG_READ(ah, AR_PHY(10)) & 0xFFFF00FF) | 218 1.1 alc (ee->ee_xlnaOn << 8)); 219 1.1 alc OS_REG_WRITE(ah, AR_PHY(13), 220 1.1 alc (ee->ee_xpaOff << 24) | (ee->ee_xpaOff << 16) | 221 1.1 alc (ee->ee_xpaOn << 8) | ee->ee_xpaOn); 222 1.1 alc OS_REG_WRITE(ah, AR_PHY(17), 223 1.1 alc (OS_REG_READ(ah, AR_PHY(17)) & 0xFFFFC07F) | 224 1.1 alc ((ee->ee_antenna >> 1) & 0x3F80)); 225 1.1 alc OS_REG_WRITE(ah, AR_PHY(18), 226 1.1 alc (OS_REG_READ(ah, AR_PHY(18)) & 0xFFFC0FFF) | 227 1.1 alc ((ee->ee_antenna << 10) & 0x3F000)); 228 1.1 alc OS_REG_WRITE(ah, AR_PHY(25), 229 1.1 alc (OS_REG_READ(ah, AR_PHY(25)) & 0xFFF80FFF) | 230 1.1 alc ((ee->ee_thresh62 << 12) & 0x7F000)); 231 1.1 alc OS_REG_WRITE(ah, AR_PHY(68), 232 1.1 alc (OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFFFC) | 233 1.1 alc (ee->ee_antenna & 0x3)); 234 1.1 alc 235 1.1 alc if (!ar5210SetChannel(ah, ichan)) { 236 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set channel\n", 237 1.1 alc __func__); 238 1.1 alc FAIL(HAL_EIO); 239 1.1 alc } 240 1.1 alc if (bChannelChange) { 241 1.1 alc if (!(ichan->privFlags & CHANNEL_DFS)) 242 1.1 alc ichan->privFlags &= ~CHANNEL_INTERFERENCE; 243 1.1 alc chan->channelFlags = ichan->channelFlags; 244 1.1 alc chan->privFlags = ichan->privFlags; 245 1.1 alc } 246 1.1 alc 247 1.1 alc /* Activate the PHY */ 248 1.1 alc OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ENABLE); 249 1.1 alc 250 1.1 alc OS_DELAY(1000); /* Wait a bit (1 msec) */ 251 1.1 alc 252 1.1 alc /* calibrate the HW and poll the bit going to 0 for completion */ 253 1.1 alc OS_REG_WRITE(ah, AR_PHY_AGCCTL, 254 1.1 alc OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_CAL); 255 1.1 alc (void) ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_CAL, 0); 256 1.1 alc 257 1.1 alc /* Perform noise floor calibration and set status */ 258 1.1 alc if (!ar5210CalNoiseFloor(ah, ichan)) { 259 1.1 alc chan->channelFlags |= CHANNEL_CW_INT; 260 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 261 1.1 alc "%s: noise floor calibration failed\n", __func__); 262 1.1 alc FAIL(HAL_EIO); 263 1.1 alc } 264 1.1 alc 265 1.1 alc for (q = 0; q < HAL_NUM_TX_QUEUES; q++) 266 1.1 alc ar5210ResetTxQueue(ah, q); 267 1.1 alc 268 1.1 alc if (AH_PRIVATE(ah)->ah_rfkillEnabled) 269 1.1 alc ar5210EnableRfKill(ah); 270 1.1 alc 271 1.1 alc /* 272 1.1 alc * Writing to AR_BEACON will start timers. Hence it should be 273 1.1 alc * the last register to be written. Do not reset tsf, do not 274 1.1 alc * enable beacons at this point, but preserve other values 275 1.1 alc * like beaconInterval. 276 1.1 alc */ 277 1.1 alc OS_REG_WRITE(ah, AR_BEACON, 278 1.1 alc (OS_REG_READ(ah, AR_BEACON) & 279 1.1 alc ~(AR_BEACON_EN | AR_BEACON_RESET_TSF))); 280 1.1 alc 281 1.1 alc /* Restore user-specified slot time and timeouts */ 282 1.1 alc if (ahp->ah_sifstime != (u_int) -1) 283 1.1 alc ar5210SetSifsTime(ah, ahp->ah_sifstime); 284 1.1 alc if (ahp->ah_slottime != (u_int) -1) 285 1.1 alc ar5210SetSlotTime(ah, ahp->ah_slottime); 286 1.1 alc if (ahp->ah_acktimeout != (u_int) -1) 287 1.1 alc ar5210SetAckTimeout(ah, ahp->ah_acktimeout); 288 1.1 alc if (ahp->ah_ctstimeout != (u_int) -1) 289 1.1 alc ar5210SetCTSTimeout(ah, ahp->ah_ctstimeout); 290 1.1 alc if (AH_PRIVATE(ah)->ah_diagreg != 0) 291 1.1 alc OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 292 1.1 alc 293 1.1 alc AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 294 1.1 alc 295 1.1 alc HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__); 296 1.1 alc 297 1.1 alc return AH_TRUE; 298 1.1 alc bad: 299 1.5 cegger if (status != AH_NULL) 300 1.1 alc *status = ecode; 301 1.1 alc return AH_FALSE; 302 1.1 alc #undef FAIL 303 1.1 alc #undef N 304 1.1 alc } 305 1.1 alc 306 1.1 alc static void 307 1.1 alc ar5210SetOperatingMode(struct ath_hal *ah, int opmode) 308 1.1 alc { 309 1.1 alc struct ath_hal_5210 *ahp = AH5210(ah); 310 1.1 alc uint32_t val; 311 1.1 alc 312 1.1 alc val = OS_REG_READ(ah, AR_STA_ID1) & 0xffff; 313 1.1 alc switch (opmode) { 314 1.1 alc case HAL_M_HOSTAP: 315 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, val 316 1.1 alc | AR_STA_ID1_AP 317 1.1 alc | AR_STA_ID1_NO_PSPOLL 318 1.1 alc | AR_STA_ID1_DESC_ANTENNA 319 1.1 alc | ahp->ah_staId1Defaults); 320 1.1 alc break; 321 1.1 alc case HAL_M_IBSS: 322 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, val 323 1.1 alc | AR_STA_ID1_ADHOC 324 1.1 alc | AR_STA_ID1_NO_PSPOLL 325 1.1 alc | AR_STA_ID1_DESC_ANTENNA 326 1.1 alc | ahp->ah_staId1Defaults); 327 1.1 alc break; 328 1.1 alc case HAL_M_STA: 329 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, val 330 1.1 alc | AR_STA_ID1_NO_PSPOLL 331 1.1 alc | AR_STA_ID1_PWR_SV 332 1.1 alc | ahp->ah_staId1Defaults); 333 1.1 alc break; 334 1.1 alc case HAL_M_MONITOR: 335 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, val 336 1.1 alc | AR_STA_ID1_NO_PSPOLL 337 1.1 alc | ahp->ah_staId1Defaults); 338 1.1 alc break; 339 1.1 alc } 340 1.1 alc } 341 1.1 alc 342 1.1 alc void 343 1.1 alc ar5210SetPCUConfig(struct ath_hal *ah) 344 1.1 alc { 345 1.1 alc ar5210SetOperatingMode(ah, AH_PRIVATE(ah)->ah_opmode); 346 1.1 alc } 347 1.1 alc 348 1.1 alc /* 349 1.1 alc * Places the PHY and Radio chips into reset. A full reset 350 1.1 alc * must be called to leave this state. The PCI/MAC/PCU are 351 1.1 alc * not placed into reset as we must receive interrupt to 352 1.1 alc * re-enable the hardware. 353 1.1 alc */ 354 1.1 alc HAL_BOOL 355 1.1 alc ar5210PhyDisable(struct ath_hal *ah) 356 1.1 alc { 357 1.1 alc return ar5210SetResetReg(ah, AR_RC_RPHY, 10); 358 1.1 alc } 359 1.1 alc 360 1.1 alc /* 361 1.1 alc * Places all of hardware into reset 362 1.1 alc */ 363 1.1 alc HAL_BOOL 364 1.1 alc ar5210Disable(struct ath_hal *ah) 365 1.1 alc { 366 1.1 alc #define AR_RC_HW (AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC) 367 1.1 alc if (!ar5210SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 368 1.1 alc return AH_FALSE; 369 1.1 alc 370 1.1 alc /* 371 1.1 alc * Reset the HW - PCI must be reset after the rest of the 372 1.1 alc * device has been reset 373 1.1 alc */ 374 1.1 alc if (!ar5210SetResetReg(ah, AR_RC_HW, AR_RC_SETTLE_TIME)) 375 1.1 alc return AH_FALSE; 376 1.1 alc OS_DELAY(1000); 377 1.1 alc (void) ar5210SetResetReg(ah, AR_RC_HW | AR_RC_RPCI, AR_RC_SETTLE_TIME); 378 1.1 alc OS_DELAY(2100); /* 8245 @ 96Mhz hangs with 2000us. */ 379 1.1 alc 380 1.1 alc return AH_TRUE; 381 1.1 alc #undef AR_RC_HW 382 1.1 alc } 383 1.1 alc 384 1.1 alc /* 385 1.1 alc * Places the hardware into reset and then pulls it out of reset 386 1.1 alc */ 387 1.1 alc HAL_BOOL 388 1.1 alc ar5210ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan) 389 1.1 alc { 390 1.1 alc #define AR_RC_HW (AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC) 391 1.1 alc 392 1.1 alc HALDEBUG(ah, HAL_DEBUG_RESET, "%s turbo %s\n", __func__, 393 1.1 alc chan && IS_CHAN_TURBO(chan) ? "enabled" : "disabled"); 394 1.1 alc 395 1.1 alc if (!ar5210SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 396 1.1 alc return AH_FALSE; 397 1.1 alc 398 1.1 alc /* Place chip in turbo before reset to cleanly reset clocks */ 399 1.1 alc OS_REG_WRITE(ah, AR_PHY_FRCTL, 400 1.1 alc chan && IS_CHAN_TURBO(chan) ? AR_PHY_TURBO_MODE : 0); 401 1.1 alc 402 1.1 alc /* 403 1.1 alc * Reset the HW. 404 1.1 alc * PCI must be reset after the rest of the device has been reset. 405 1.1 alc */ 406 1.1 alc if (!ar5210SetResetReg(ah, AR_RC_HW, AR_RC_SETTLE_TIME)) 407 1.1 alc return AH_FALSE; 408 1.1 alc OS_DELAY(1000); 409 1.1 alc if (!ar5210SetResetReg(ah, AR_RC_HW | AR_RC_RPCI, AR_RC_SETTLE_TIME)) 410 1.1 alc return AH_FALSE; 411 1.1 alc OS_DELAY(2100); /* 8245 @ 96Mhz hangs with 2000us. */ 412 1.1 alc 413 1.1 alc /* 414 1.1 alc * Bring out of sleep mode (AGAIN) 415 1.1 alc * 416 1.1 alc * WARNING WARNING WARNING 417 1.1 alc * 418 1.1 alc * There is a problem with the chip where it doesn't always indicate 419 1.1 alc * that it's awake, so initializePowerUp() will fail. 420 1.1 alc */ 421 1.1 alc if (!ar5210SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 422 1.1 alc return AH_FALSE; 423 1.1 alc 424 1.1 alc /* Clear warm reset reg */ 425 1.1 alc return ar5210SetResetReg(ah, 0, 10); 426 1.1 alc #undef AR_RC_HW 427 1.1 alc } 428 1.1 alc 429 1.1 alc enum { 430 1.1 alc FIRPWR_M = 0x03fc0000, 431 1.1 alc FIRPWR_S = 18, 432 1.1 alc KCOARSEHIGH_M = 0x003f8000, 433 1.1 alc KCOARSEHIGH_S = 15, 434 1.1 alc KCOARSELOW_M = 0x00007f80, 435 1.1 alc KCOARSELOW_S = 7, 436 1.1 alc ADCSAT_ICOUNT_M = 0x0001f800, 437 1.1 alc ADCSAT_ICOUNT_S = 11, 438 1.1 alc ADCSAT_THRESH_M = 0x000007e0, 439 1.1 alc ADCSAT_THRESH_S = 5 440 1.1 alc }; 441 1.1 alc 442 1.1 alc /* 443 1.1 alc * Recalibrate the lower PHY chips to account for temperature/environment 444 1.1 alc * changes. 445 1.1 alc */ 446 1.1 alc HAL_BOOL 447 1.1 alc ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask, 448 1.1 alc HAL_BOOL longCal, HAL_BOOL *isCalDone) 449 1.1 alc { 450 1.1 alc uint32_t regBeacon; 451 1.1 alc uint32_t reg9858, reg985c, reg9868; 452 1.1 alc HAL_CHANNEL_INTERNAL *ichan; 453 1.1 alc 454 1.1 alc ichan = ath_hal_checkchannel(ah, chan); 455 1.1 alc if (ichan == AH_NULL) { 456 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 457 1.1 alc "%s: invalid channel %u/0x%x; no mapping\n", 458 1.1 alc __func__, chan->channel, chan->channelFlags); 459 1.1 alc return AH_FALSE; 460 1.1 alc } 461 1.1 alc /* Disable tx and rx */ 462 1.1 alc OS_REG_WRITE(ah, AR_DIAG_SW, 463 1.1 alc OS_REG_READ(ah, AR_DIAG_SW) | (AR_DIAG_SW_DIS_TX | AR_DIAG_SW_DIS_RX)); 464 1.1 alc 465 1.1 alc /* Disable Beacon Enable */ 466 1.1 alc regBeacon = OS_REG_READ(ah, AR_BEACON); 467 1.1 alc OS_REG_WRITE(ah, AR_BEACON, regBeacon & ~AR_BEACON_EN); 468 1.1 alc 469 1.1 alc /* Delay 4ms to ensure that all tx and rx activity has ceased */ 470 1.1 alc OS_DELAY(4000); 471 1.1 alc 472 1.1 alc /* Disable AGC to radio traffic */ 473 1.1 alc OS_REG_WRITE(ah, 0x9808, OS_REG_READ(ah, 0x9808) | 0x08000000); 474 1.1 alc /* Wait for the AGC traffic to cease. */ 475 1.1 alc OS_DELAY(10); 476 1.1 alc 477 1.1 alc /* Change Channel to relock synth */ 478 1.1 alc if (!ar5210SetChannel(ah, ichan)) 479 1.1 alc return AH_FALSE; 480 1.1 alc 481 1.1 alc /* wait for the synthesizer lock to stabilize */ 482 1.1 alc OS_DELAY(1000); 483 1.1 alc 484 1.1 alc /* Re-enable AGC to radio traffic */ 485 1.1 alc OS_REG_WRITE(ah, 0x9808, OS_REG_READ(ah, 0x9808) & (~0x08000000)); 486 1.1 alc 487 1.1 alc /* 488 1.1 alc * Configure the AGC so that it is highly unlikely (if not 489 1.1 alc * impossible) for it to send any gain changes to the analog 490 1.1 alc * chip. We store off the current values so that they can 491 1.1 alc * be rewritten below. Setting the following values: 492 1.1 alc * firpwr = -1 493 1.1 alc * Kcoursehigh = -1 494 1.1 alc * Kcourselow = -127 495 1.1 alc * ADCsat_icount = 2 496 1.1 alc * ADCsat_thresh = 12 497 1.1 alc */ 498 1.1 alc reg9858 = OS_REG_READ(ah, 0x9858); 499 1.1 alc reg985c = OS_REG_READ(ah, 0x985c); 500 1.1 alc reg9868 = OS_REG_READ(ah, 0x9868); 501 1.1 alc 502 1.1 alc OS_REG_WRITE(ah, 0x9858, (reg9858 & ~FIRPWR_M) | 503 1.6 joerg ((~0U << FIRPWR_S) & FIRPWR_M)); 504 1.1 alc OS_REG_WRITE(ah, 0x985c, 505 1.1 alc (reg985c & ~(KCOARSEHIGH_M | KCOARSELOW_M)) | 506 1.6 joerg ((~0U << KCOARSEHIGH_S) & KCOARSEHIGH_M) | 507 1.7 jklos ((((~0U << 7) + 1) << KCOARSELOW_S) & KCOARSELOW_M)); 508 1.1 alc OS_REG_WRITE(ah, 0x9868, 509 1.1 alc (reg9868 & ~(ADCSAT_ICOUNT_M | ADCSAT_THRESH_M)) | 510 1.1 alc ((2 << ADCSAT_ICOUNT_S) & ADCSAT_ICOUNT_M) | 511 1.1 alc ((12 << ADCSAT_THRESH_S) & ADCSAT_THRESH_M)); 512 1.1 alc 513 1.1 alc /* Wait for AGC changes to be enacted */ 514 1.1 alc OS_DELAY(20); 515 1.1 alc 516 1.1 alc /* 517 1.1 alc * We disable RF mix/gain stages for the PGA to avoid a 518 1.1 alc * race condition that will occur with receiving a frame 519 1.1 alc * and performing the AGC calibration. This will be 520 1.1 alc * re-enabled at the end of offset cal. We turn off AGC 521 1.1 alc * writes during this write as it will go over the analog bus. 522 1.1 alc */ 523 1.1 alc OS_REG_WRITE(ah, 0x9808, OS_REG_READ(ah, 0x9808) | 0x08000000); 524 1.1 alc OS_DELAY(10); /* wait for the AGC traffic to cease */ 525 1.1 alc OS_REG_WRITE(ah, 0x98D4, 0x21); 526 1.1 alc OS_REG_WRITE(ah, 0x9808, OS_REG_READ(ah, 0x9808) & (~0x08000000)); 527 1.1 alc 528 1.1 alc /* wait to make sure that additional AGC traffic has quiesced */ 529 1.1 alc OS_DELAY(1000); 530 1.1 alc 531 1.1 alc /* AGC calibration (this was added to make the NF threshold check work) */ 532 1.1 alc OS_REG_WRITE(ah, AR_PHY_AGCCTL, 533 1.1 alc OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_CAL); 534 1.3 alc if (!ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_CAL, 0)) { 535 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: AGC calibration timeout\n", 536 1.1 alc __func__); 537 1.3 alc } 538 1.1 alc 539 1.1 alc /* Rewrite our AGC values we stored off earlier (return AGC to normal operation) */ 540 1.1 alc OS_REG_WRITE(ah, 0x9858, reg9858); 541 1.1 alc OS_REG_WRITE(ah, 0x985c, reg985c); 542 1.1 alc OS_REG_WRITE(ah, 0x9868, reg9868); 543 1.1 alc 544 1.1 alc /* Perform noise floor and set status */ 545 1.1 alc if (!ar5210CalNoiseFloor(ah, ichan)) { 546 1.1 alc /* 547 1.1 alc * Delay 5ms before retrying the noise floor - 548 1.1 alc * just to make sure. We're in an error 549 1.1 alc * condition here 550 1.1 alc */ 551 1.1 alc HALDEBUG(ah, HAL_DEBUG_NFCAL | HAL_DEBUG_PERCAL, 552 1.1 alc "%s: Performing 2nd Noise Cal\n", __func__); 553 1.1 alc OS_DELAY(5000); 554 1.1 alc if (!ar5210CalNoiseFloor(ah, ichan)) 555 1.1 alc chan->channelFlags |= CHANNEL_CW_INT; 556 1.1 alc } 557 1.1 alc 558 1.1 alc /* Clear tx and rx disable bit */ 559 1.1 alc OS_REG_WRITE(ah, AR_DIAG_SW, 560 1.1 alc OS_REG_READ(ah, AR_DIAG_SW) & ~(AR_DIAG_SW_DIS_TX | AR_DIAG_SW_DIS_RX)); 561 1.1 alc 562 1.1 alc /* Re-enable Beacons */ 563 1.1 alc OS_REG_WRITE(ah, AR_BEACON, regBeacon); 564 1.1 alc 565 1.1 alc *isCalDone = AH_TRUE; 566 1.1 alc 567 1.1 alc return AH_TRUE; 568 1.1 alc } 569 1.1 alc 570 1.1 alc HAL_BOOL 571 1.1 alc ar5210PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone) 572 1.1 alc { 573 1.1 alc return ar5210PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone); 574 1.1 alc } 575 1.1 alc 576 1.1 alc HAL_BOOL 577 1.1 alc ar5210ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan) 578 1.1 alc { 579 1.1 alc return AH_TRUE; 580 1.1 alc } 581 1.1 alc 582 1.1 alc /* 583 1.1 alc * Writes the given reset bit mask into the reset register 584 1.1 alc */ 585 1.1 alc static HAL_BOOL 586 1.2 alc ar5210SetResetReg(struct ath_hal *ah, uint32_t resetMask, u_int waitTime) 587 1.1 alc { 588 1.1 alc uint32_t mask = resetMask ? resetMask : ~0; 589 1.1 alc HAL_BOOL rt; 590 1.1 alc 591 1.1 alc OS_REG_WRITE(ah, AR_RC, resetMask); 592 1.1 alc /* need to wait at least 128 clocks when reseting PCI before read */ 593 1.2 alc OS_DELAY(waitTime); 594 1.1 alc 595 1.1 alc resetMask &= AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC; 596 1.1 alc mask &= AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC; 597 1.1 alc rt = ath_hal_wait(ah, AR_RC, mask, resetMask); 598 1.1 alc if ((resetMask & AR_RC_RMAC) == 0) { 599 1.1 alc if (isBigEndian()) { 600 1.1 alc /* 601 1.1 alc * Set CFG, little-endian for register 602 1.1 alc * and descriptor accesses. 603 1.1 alc */ 604 1.1 alc mask = INIT_CONFIG_STATUS | 605 1.1 alc AR_CFG_SWTD | AR_CFG_SWRD | AR_CFG_SWRG; 606 1.1 alc OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask)); 607 1.1 alc } else 608 1.1 alc OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS); 609 1.1 alc } 610 1.1 alc return rt; 611 1.1 alc } 612 1.1 alc 613 1.1 alc 614 1.1 alc /* 615 1.1 alc * Returns: the pcdac value 616 1.1 alc */ 617 1.1 alc static uint8_t 618 1.1 alc getPcdac(struct ath_hal *ah, const struct tpcMap *pRD, uint8_t dBm) 619 1.1 alc { 620 1.1 alc int32_t i; 621 1.1 alc int useNextEntry = AH_FALSE; 622 1.1 alc uint32_t interp; 623 1.1 alc 624 1.1 alc for (i = AR_TP_SCALING_ENTRIES - 1; i >= 0; i--) { 625 1.1 alc /* Check for exact entry */ 626 1.1 alc if (dBm == AR_I2DBM(i)) { 627 1.1 alc if (pRD->pcdac[i] != 63) 628 1.1 alc return pRD->pcdac[i]; 629 1.1 alc useNextEntry = AH_TRUE; 630 1.1 alc } else if (dBm + 1 == AR_I2DBM(i) && i > 0) { 631 1.1 alc /* Interpolate for between entry with a logish scale */ 632 1.1 alc if (pRD->pcdac[i] != 63 && pRD->pcdac[i-1] != 63) { 633 1.1 alc interp = (350 * (pRD->pcdac[i] - pRD->pcdac[i-1])) + 999; 634 1.1 alc interp = (interp / 1000) + pRD->pcdac[i-1]; 635 1.1 alc return interp; 636 1.1 alc } 637 1.1 alc useNextEntry = AH_TRUE; 638 1.1 alc } else if (useNextEntry == AH_TRUE) { 639 1.1 alc /* Grab the next lowest */ 640 1.1 alc if (pRD->pcdac[i] != 63) 641 1.1 alc return pRD->pcdac[i]; 642 1.1 alc } 643 1.1 alc } 644 1.1 alc 645 1.1 alc /* Return the lowest Entry if we haven't returned */ 646 1.1 alc for (i = 0; i < AR_TP_SCALING_ENTRIES; i++) 647 1.1 alc if (pRD->pcdac[i] != 63) 648 1.1 alc return pRD->pcdac[i]; 649 1.1 alc 650 1.1 alc /* No value to return from table */ 651 1.1 alc #ifdef AH_DEBUG 652 1.1 alc ath_hal_printf(ah, "%s: empty transmit power table?\n", __func__); 653 1.1 alc #endif 654 1.1 alc return 1; 655 1.1 alc } 656 1.1 alc 657 1.1 alc /* 658 1.1 alc * Find or interpolates the gainF value from the table ptr. 659 1.1 alc */ 660 1.1 alc static uint8_t 661 1.1 alc getGainF(struct ath_hal *ah, const struct tpcMap *pRD, 662 1.1 alc uint8_t pcdac, uint8_t *dBm) 663 1.1 alc { 664 1.1 alc uint32_t interp; 665 1.1 alc int low, high, i; 666 1.1 alc 667 1.1 alc low = high = -1; 668 1.1 alc 669 1.1 alc for (i = 0; i < AR_TP_SCALING_ENTRIES; i++) { 670 1.1 alc if(pRD->pcdac[i] == 63) 671 1.1 alc continue; 672 1.1 alc if (pcdac == pRD->pcdac[i]) { 673 1.1 alc *dBm = AR_I2DBM(i); 674 1.1 alc return pRD->gainF[i]; /* Exact Match */ 675 1.1 alc } 676 1.1 alc if (pcdac > pRD->pcdac[i]) 677 1.1 alc low = i; 678 1.1 alc if (pcdac < pRD->pcdac[i]) { 679 1.1 alc high = i; 680 1.1 alc if (low == -1) { 681 1.1 alc *dBm = AR_I2DBM(i); 682 1.1 alc /* PCDAC is lower than lowest setting */ 683 1.1 alc return pRD->gainF[i]; 684 1.1 alc } 685 1.1 alc break; 686 1.1 alc } 687 1.1 alc } 688 1.1 alc if (i >= AR_TP_SCALING_ENTRIES && low == -1) { 689 1.1 alc /* No settings were found */ 690 1.1 alc #ifdef AH_DEBUG 691 1.1 alc ath_hal_printf(ah, 692 1.1 alc "%s: no valid entries in the pcdac table: %d\n", 693 1.1 alc __func__, pcdac); 694 1.1 alc #endif 695 1.1 alc return 63; 696 1.1 alc } 697 1.1 alc if (i >= AR_TP_SCALING_ENTRIES) { 698 1.1 alc /* PCDAC setting was above the max setting in the table */ 699 1.1 alc *dBm = AR_I2DBM(low); 700 1.1 alc return pRD->gainF[low]; 701 1.1 alc } 702 1.1 alc /* Only exact if table has no missing entries */ 703 1.1 alc *dBm = (low + high) + 3; 704 1.1 alc 705 1.1 alc /* 706 1.1 alc * Perform interpolation between low and high values to find gainF 707 1.1 alc * linearly scale the pcdac between low and high 708 1.1 alc */ 709 1.1 alc interp = ((pcdac - pRD->pcdac[low]) * 1000) / 710 1.1 alc (pRD->pcdac[high] - pRD->pcdac[low]); 711 1.1 alc /* 712 1.1 alc * Multiply the scale ratio by the gainF difference 713 1.1 alc * (plus a rnd up factor) 714 1.1 alc */ 715 1.1 alc interp = ((interp * (pRD->gainF[high] - pRD->gainF[low])) + 999) / 1000; 716 1.1 alc 717 1.1 alc /* Add ratioed gain_f to low gain_f value */ 718 1.1 alc return interp + pRD->gainF[low]; 719 1.1 alc } 720 1.1 alc 721 1.1 alc HAL_BOOL 722 1.1 alc ar5210SetTxPowerLimit(struct ath_hal *ah, uint32_t limit) 723 1.1 alc { 724 1.1 alc AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, AR5210_MAX_RATE_POWER); 725 1.1 alc /* XXX flush to h/w */ 726 1.1 alc return AH_TRUE; 727 1.1 alc } 728 1.1 alc 729 1.1 alc /* 730 1.1 alc * Get TXPower values and set them in the radio 731 1.1 alc */ 732 1.1 alc static HAL_BOOL 733 1.1 alc setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17]) 734 1.1 alc { 735 1.1 alc const HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom; 736 1.1 alc uint8_t gainFRD, gainF36, gainF48, gainF54; 737 1.4 mrg uint8_t dBmRD = 0, dBm36 = 0, dBm48 = 0, dBm54 = 0, dontcare; 738 1.1 alc uint32_t rd, group; 739 1.1 alc const struct tpcMap *pRD; 740 1.1 alc 741 1.1 alc /* Set OB/DB Values regardless of channel */ 742 1.1 alc cp[15] = (ee->ee_biasCurrents >> 4) & 0x7; 743 1.1 alc cp[16] = ee->ee_biasCurrents & 0x7; 744 1.1 alc 745 1.1 alc if (chan->channel < 5170 || chan->channel > 5320) { 746 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u\n", 747 1.1 alc __func__, chan->channel); 748 1.1 alc return AH_FALSE; 749 1.1 alc } 750 1.1 alc 751 1.1 alc HALASSERT(ee->ee_version >= AR_EEPROM_VER1 && 752 1.1 alc ee->ee_version < AR_EEPROM_VER3); 753 1.1 alc 754 1.1 alc /* Match regulatory domain */ 755 1.1 alc for (rd = 0; rd < AR_REG_DOMAINS_MAX; rd++) 756 1.1 alc if (AH_PRIVATE(ah)->ah_currentRD == ee->ee_regDomain[rd]) 757 1.1 alc break; 758 1.1 alc if (rd == AR_REG_DOMAINS_MAX) { 759 1.1 alc #ifdef AH_DEBUG 760 1.1 alc ath_hal_printf(ah, 761 1.1 alc "%s: no calibrated regulatory domain matches the " 762 1.1 alc "current regularly domain (0x%0x)\n", __func__, 763 1.1 alc AH_PRIVATE(ah)->ah_currentRD); 764 1.1 alc #endif 765 1.1 alc return AH_FALSE; 766 1.1 alc } 767 1.1 alc group = ((chan->channel - 5170) / 10); 768 1.1 alc 769 1.1 alc if (group > 11) { 770 1.1 alc /* Pull 5.29 into the 5.27 group */ 771 1.1 alc group--; 772 1.1 alc } 773 1.1 alc 774 1.1 alc /* Integer divide will set group from 0 to 4 */ 775 1.1 alc group = group / 3; 776 1.1 alc pRD = &ee->ee_tpc[group]; 777 1.1 alc 778 1.1 alc /* Set PC DAC Values */ 779 1.1 alc cp[14] = pRD->regdmn[rd]; 780 1.1 alc cp[9] = AH_MIN(pRD->regdmn[rd], pRD->rate36); 781 1.1 alc cp[8] = AH_MIN(pRD->regdmn[rd], pRD->rate48); 782 1.1 alc cp[7] = AH_MIN(pRD->regdmn[rd], pRD->rate54); 783 1.1 alc 784 1.1 alc /* Find Corresponding gainF values for RD, 36, 48, 54 */ 785 1.1 alc gainFRD = getGainF(ah, pRD, pRD->regdmn[rd], &dBmRD); 786 1.1 alc gainF36 = getGainF(ah, pRD, cp[9], &dBm36); 787 1.1 alc gainF48 = getGainF(ah, pRD, cp[8], &dBm48); 788 1.1 alc gainF54 = getGainF(ah, pRD, cp[7], &dBm54); 789 1.1 alc 790 1.1 alc /* Power Scale if requested */ 791 1.1 alc if (AH_PRIVATE(ah)->ah_tpScale != HAL_TP_SCALE_MAX) { 792 1.1 alc static const uint16_t tpcScaleReductionTable[5] = 793 1.1 alc { 0, 3, 6, 9, AR5210_MAX_RATE_POWER }; 794 1.1 alc uint16_t tpScale; 795 1.1 alc 796 1.1 alc tpScale = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale]; 797 1.1 alc if (dBmRD < tpScale+3) 798 1.1 alc dBmRD = 3; /* min */ 799 1.1 alc else 800 1.1 alc dBmRD -= tpScale; 801 1.1 alc cp[14] = getPcdac(ah, pRD, dBmRD); 802 1.1 alc gainFRD = getGainF(ah, pRD, cp[14], &dontcare); 803 1.1 alc dBm36 = AH_MIN(dBm36, dBmRD); 804 1.1 alc cp[9] = getPcdac(ah, pRD, dBm36); 805 1.1 alc gainF36 = getGainF(ah, pRD, cp[9], &dontcare); 806 1.1 alc dBm48 = AH_MIN(dBm48, dBmRD); 807 1.1 alc cp[8] = getPcdac(ah, pRD, dBm48); 808 1.1 alc gainF48 = getGainF(ah, pRD, cp[8], &dontcare); 809 1.1 alc dBm54 = AH_MIN(dBm54, dBmRD); 810 1.1 alc cp[7] = getPcdac(ah, pRD, dBm54); 811 1.1 alc gainF54 = getGainF(ah, pRD, cp[7], &dontcare); 812 1.1 alc } 813 1.1 alc /* Record current dBm at rate 6 */ 814 1.1 alc AH_PRIVATE(ah)->ah_maxPowerLevel = 2*dBmRD; 815 1.1 alc 816 1.1 alc cp[13] = cp[12] = cp[11] = cp[10] = cp[14]; 817 1.1 alc 818 1.1 alc /* Set GainF Values */ 819 1.1 alc cp[0] = gainFRD - gainF54; 820 1.1 alc cp[1] = gainFRD - gainF48; 821 1.1 alc cp[2] = gainFRD - gainF36; 822 1.1 alc /* 9, 12, 18, 24 have no gain_delta from 6 */ 823 1.1 alc cp[3] = cp[4] = cp[5] = cp[6] = 0; 824 1.1 alc return AH_TRUE; 825 1.1 alc } 826 1.1 alc 827 1.1 alc /* 828 1.1 alc * Places the device in and out of reset and then places sane 829 1.1 alc * values in the registers based on EEPROM config, initialization 830 1.1 alc * vectors (as determined by the mode), and station configuration 831 1.1 alc */ 832 1.1 alc HAL_BOOL 833 1.1 alc ar5210SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan) 834 1.1 alc { 835 1.1 alc #define N(a) (sizeof (a) / sizeof (a[0])) 836 1.1 alc static const uint32_t pwr_regs_start[17] = { 837 1.1 alc 0x00000000, 0x00000000, 0x00000000, 838 1.1 alc 0x00000000, 0x00000000, 0xf0000000, 839 1.1 alc 0xcc000000, 0x00000000, 0x00000000, 840 1.1 alc 0x00000000, 0x0a000000, 0x000000e2, 841 1.1 alc 0x0a000020, 0x01000002, 0x01000018, 842 1.1 alc 0x40000000, 0x00000418 843 1.1 alc }; 844 1.1 alc uint16_t i; 845 1.1 alc uint8_t cp[sizeof(ar5k0007_pwrSettings)]; 846 1.1 alc uint32_t pwr_regs[17]; 847 1.1 alc 848 1.1 alc OS_MEMCPY(pwr_regs, pwr_regs_start, sizeof(pwr_regs)); 849 1.1 alc OS_MEMCPY(cp, ar5k0007_pwrSettings, sizeof(cp)); 850 1.1 alc 851 1.1 alc /* Check the EEPROM tx power calibration settings */ 852 1.1 alc if (!setupPowerSettings(ah, chan, cp)) { 853 1.1 alc #ifdef AH_DEBUG 854 1.1 alc ath_hal_printf(ah, "%s: unable to setup power settings\n", 855 1.1 alc __func__); 856 1.1 alc #endif 857 1.1 alc return AH_FALSE; 858 1.1 alc } 859 1.1 alc if (cp[15] < 1 || cp[15] > 5) { 860 1.1 alc #ifdef AH_DEBUG 861 1.1 alc ath_hal_printf(ah, "%s: OB out of range (%u)\n", 862 1.1 alc __func__, cp[15]); 863 1.1 alc #endif 864 1.1 alc return AH_FALSE; 865 1.1 alc } 866 1.1 alc if (cp[16] < 1 || cp[16] > 5) { 867 1.1 alc #ifdef AH_DEBUG 868 1.1 alc ath_hal_printf(ah, "%s: DB out of range (%u)\n", 869 1.1 alc __func__, cp[16]); 870 1.1 alc #endif 871 1.1 alc return AH_FALSE; 872 1.1 alc } 873 1.1 alc 874 1.1 alc /* reverse bits of the transmit power array */ 875 1.1 alc for (i = 0; i < 7; i++) 876 1.1 alc cp[i] = ath_hal_reverseBits(cp[i], 5); 877 1.1 alc for (i = 7; i < 15; i++) 878 1.1 alc cp[i] = ath_hal_reverseBits(cp[i], 6); 879 1.1 alc 880 1.1 alc /* merge transmit power values into the register - quite gross */ 881 1.1 alc pwr_regs[0] |= ((cp[1] << 5) & 0xE0) | (cp[0] & 0x1F); 882 1.1 alc pwr_regs[1] |= ((cp[3] << 7) & 0x80) | ((cp[2] << 2) & 0x7C) | 883 1.1 alc ((cp[1] >> 3) & 0x03); 884 1.1 alc pwr_regs[2] |= ((cp[4] << 4) & 0xF0) | ((cp[3] >> 1) & 0x0F); 885 1.1 alc pwr_regs[3] |= ((cp[6] << 6) & 0xC0) | ((cp[5] << 1) & 0x3E) | 886 1.1 alc ((cp[4] >> 4) & 0x01); 887 1.1 alc pwr_regs[4] |= ((cp[7] << 3) & 0xF8) | ((cp[6] >> 2) & 0x07); 888 1.1 alc pwr_regs[5] |= ((cp[9] << 7) & 0x80) | ((cp[8] << 1) & 0x7E) | 889 1.1 alc ((cp[7] >> 5) & 0x01); 890 1.1 alc pwr_regs[6] |= ((cp[10] << 5) & 0xE0) | ((cp[9] >> 1) & 0x1F); 891 1.1 alc pwr_regs[7] |= ((cp[11] << 3) & 0xF8) | ((cp[10] >> 3) & 0x07); 892 1.1 alc pwr_regs[8] |= ((cp[12] << 1) & 0x7E) | ((cp[11] >> 5) & 0x01); 893 1.1 alc pwr_regs[9] |= ((cp[13] << 5) & 0xE0); 894 1.1 alc pwr_regs[10] |= ((cp[14] << 3) & 0xF8) | ((cp[13] >> 3) & 0x07); 895 1.1 alc pwr_regs[11] |= ((cp[14] >> 5) & 0x01); 896 1.1 alc 897 1.1 alc /* Set OB */ 898 1.1 alc pwr_regs[8] |= (ath_hal_reverseBits(cp[15], 3) << 7) & 0x80; 899 1.1 alc pwr_regs[9] |= (ath_hal_reverseBits(cp[15], 3) >> 1) & 0x03; 900 1.1 alc 901 1.1 alc /* Set DB */ 902 1.1 alc pwr_regs[9] |= (ath_hal_reverseBits(cp[16], 3) << 2) & 0x1C; 903 1.1 alc 904 1.1 alc /* Write the registers */ 905 1.1 alc for (i = 0; i < N(pwr_regs)-1; i++) 906 1.1 alc OS_REG_WRITE(ah, 0x0000989c, pwr_regs[i]); 907 1.1 alc /* last write is a flush */ 908 1.1 alc OS_REG_WRITE(ah, 0x000098d4, pwr_regs[i]); 909 1.1 alc 910 1.1 alc return AH_TRUE; 911 1.1 alc #undef N 912 1.1 alc } 913 1.1 alc 914 1.1 alc /* 915 1.1 alc * Takes the MHz channel value and sets the Channel value 916 1.1 alc * 917 1.1 alc * ASSUMES: Writes enabled to analog bus before AGC is active 918 1.1 alc * or by disabling the AGC. 919 1.1 alc */ 920 1.1 alc static HAL_BOOL 921 1.1 alc ar5210SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 922 1.1 alc { 923 1.1 alc uint32_t data; 924 1.1 alc 925 1.1 alc /* Set the Channel */ 926 1.1 alc data = ath_hal_reverseBits((chan->channel - 5120)/10, 5); 927 1.1 alc data = (data << 1) | 0x41; 928 1.1 alc OS_REG_WRITE(ah, AR_PHY(0x27), data); 929 1.1 alc OS_REG_WRITE(ah, AR_PHY(0x30), 0); 930 1.1 alc AH_PRIVATE(ah)->ah_curchan = chan; 931 1.1 alc return AH_TRUE; 932 1.1 alc } 933 1.1 alc 934 1.1 alc int16_t 935 1.1 alc ar5210GetNoiseFloor(struct ath_hal *ah) 936 1.1 alc { 937 1.1 alc int16_t nf; 938 1.1 alc 939 1.1 alc nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff; 940 1.1 alc if (nf & 0x100) 941 1.1 alc nf = 0 - ((nf ^ 0x1ff) + 1); 942 1.1 alc return nf; 943 1.1 alc } 944 1.1 alc 945 1.1 alc #define NORMAL_NF_THRESH (-72) 946 1.1 alc /* 947 1.1 alc * Peform the noisefloor calibration and check for 948 1.1 alc * any constant channel interference 949 1.1 alc * 950 1.1 alc * Returns: TRUE for a successful noise floor calibration; else FALSE 951 1.1 alc */ 952 1.1 alc HAL_BOOL 953 1.1 alc ar5210CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 954 1.1 alc { 955 1.1 alc int32_t nf, nfLoops; 956 1.1 alc 957 1.1 alc /* Calibrate the noise floor */ 958 1.1 alc OS_REG_WRITE(ah, AR_PHY_AGCCTL, 959 1.1 alc OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_NF); 960 1.1 alc 961 1.1 alc /* Do not read noise floor until it has done the first update */ 962 1.1 alc if (!ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_NF, 0)) { 963 1.1 alc #ifdef ATH_HAL_DEBUG 964 1.1 alc ath_hal_printf(ah, " -PHY NF Reg state: 0x%x\n", 965 1.1 alc OS_REG_READ(ah, AR_PHY_AGCCTL)); 966 1.1 alc ath_hal_printf(ah, " -MAC Reset Reg state: 0x%x\n", 967 1.1 alc OS_REG_READ(ah, AR_RC)); 968 1.1 alc ath_hal_printf(ah, " -PHY Active Reg state: 0x%x\n", 969 1.1 alc OS_REG_READ(ah, AR_PHY_ACTIVE)); 970 1.1 alc #endif /* ATH_HAL_DEBUG */ 971 1.1 alc return AH_FALSE; 972 1.1 alc } 973 1.1 alc 974 1.1 alc nf = 0; 975 1.1 alc /* Keep checking until the floor is below the threshold or the nf is done */ 976 1.1 alc for (nfLoops = 0; ((nfLoops < 21) && (nf > NORMAL_NF_THRESH)); nfLoops++) { 977 1.1 alc OS_DELAY(1000); /* Sleep for 1 ms */ 978 1.1 alc nf = ar5210GetNoiseFloor(ah); 979 1.1 alc } 980 1.1 alc 981 1.1 alc if (nf > NORMAL_NF_THRESH) { 982 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: Bad noise cal %d\n", 983 1.1 alc __func__, nf); 984 1.1 alc chan->rawNoiseFloor = 0; 985 1.1 alc return AH_FALSE; 986 1.1 alc } 987 1.1 alc chan->rawNoiseFloor = nf; 988 1.1 alc return AH_TRUE; 989 1.1 alc } 990 1.1 alc 991 1.1 alc /* 992 1.1 alc * Adjust NF based on statistical values for 5GHz frequencies. 993 1.1 alc */ 994 1.1 alc int16_t 995 1.1 alc ar5210GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c) 996 1.1 alc { 997 1.1 alc return 0; 998 1.1 alc } 999 1.1 alc 1000 1.1 alc HAL_RFGAIN 1001 1.1 alc ar5210GetRfgain(struct ath_hal *ah) 1002 1.1 alc { 1003 1.1 alc return HAL_RFGAIN_INACTIVE; 1004 1.1 alc } 1005