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.5 joerg * $Id: ar5212_reset.c,v 1.5 2014/02/27 01:31:09 joerg 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 #include "ah_devid.h" 24 1.1 alc 25 1.1 alc #include "ar5212/ar5212.h" 26 1.1 alc #include "ar5212/ar5212reg.h" 27 1.1 alc #include "ar5212/ar5212phy.h" 28 1.1 alc 29 1.1 alc #include "ah_eeprom_v3.h" 30 1.1 alc 31 1.1 alc /* Additional Time delay to wait after activiting the Base band */ 32 1.1 alc #define BASE_ACTIVATE_DELAY 100 /* 100 usec */ 33 1.1 alc #define PLL_SETTLE_DELAY 300 /* 300 usec */ 34 1.1 alc 35 1.1 alc static HAL_BOOL ar5212SetResetReg(struct ath_hal *, uint32_t resetMask); 36 1.1 alc /* NB: public for 5312 use */ 37 1.1 alc HAL_BOOL ar5212IsSpurChannel(struct ath_hal *, HAL_CHANNEL *); 38 1.1 alc HAL_BOOL ar5212ChannelChange(struct ath_hal *, HAL_CHANNEL *); 39 1.1 alc int16_t ar5212GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *); 40 1.1 alc HAL_BOOL ar5212SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *); 41 1.1 alc void ar5212SetDeltaSlope(struct ath_hal *, HAL_CHANNEL *); 42 1.1 alc HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah, 43 1.1 alc HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain); 44 1.1 alc static HAL_BOOL ar5212SetRateTable(struct ath_hal *, 45 1.1 alc HAL_CHANNEL *, int16_t tpcScaleReduction, int16_t powerLimit, 46 1.1 alc HAL_BOOL commit, int16_t *minPower, int16_t *maxPower); 47 1.1 alc static void ar5212CorrectGainDelta(struct ath_hal *, int twiceOfdmCckDelta); 48 1.1 alc static void ar5212GetTargetPowers(struct ath_hal *, HAL_CHANNEL *, 49 1.1 alc const TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels, 50 1.1 alc TRGT_POWER_INFO *pNewPower); 51 1.1 alc static uint16_t ar5212GetMaxEdgePower(uint16_t channel, 52 1.1 alc const RD_EDGES_POWER *pRdEdgesPower); 53 1.1 alc void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *); 54 1.1 alc void ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *); 55 1.1 alc 56 1.1 alc /* NB: public for RF backend use */ 57 1.1 alc void ar5212GetLowerUpperValues(uint16_t value, 58 1.1 alc uint16_t *pList, uint16_t listSize, 59 1.1 alc uint16_t *pLowerValue, uint16_t *pUpperValue); 60 1.1 alc void ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, 61 1.1 alc uint32_t numBits, uint32_t firstBit, uint32_t column); 62 1.1 alc 63 1.1 alc static int 64 1.1 alc write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 65 1.1 alc HAL_BOOL bChannelChange, int writes) 66 1.1 alc { 67 1.1 alc #define IS_NO_RESET_TIMER_ADDR(x) \ 68 1.1 alc ( (((x) >= AR_BEACON) && ((x) <= AR_CFP_DUR)) || \ 69 1.1 alc (((x) >= AR_SLEEP1) && ((x) <= AR_SLEEP3))) 70 1.1 alc #define V(r, c) (ia)->data[((r)*(ia)->cols) + (c)] 71 1.1 alc int r; 72 1.1 alc 73 1.1 alc /* Write Common Array Parameters */ 74 1.1 alc for (r = 0; r < ia->rows; r++) { 75 1.1 alc uint32_t reg = V(r, 0); 76 1.1 alc /* XXX timer/beacon setup registers? */ 77 1.1 alc /* On channel change, don't reset the PCU registers */ 78 1.1 alc if (!(bChannelChange && IS_NO_RESET_TIMER_ADDR(reg))) { 79 1.1 alc OS_REG_WRITE(ah, reg, V(r, 1)); 80 1.1 alc DMA_YIELD(writes); 81 1.1 alc } 82 1.1 alc } 83 1.1 alc return writes; 84 1.1 alc #undef IS_NO_RESET_TIMER_ADDR 85 1.1 alc #undef V 86 1.1 alc } 87 1.1 alc 88 1.1 alc #define IS_DISABLE_FAST_ADC_CHAN(x) (((x) == 2462) || ((x) == 2467)) 89 1.1 alc 90 1.1 alc /* 91 1.1 alc * Places the device in and out of reset and then places sane 92 1.1 alc * values in the registers based on EEPROM config, initialization 93 1.1 alc * vectors (as determined by the mode), and station configuration 94 1.1 alc * 95 1.1 alc * bChannelChange is used to preserve DMA/PCU registers across 96 1.1 alc * a HW Reset during channel change. 97 1.1 alc */ 98 1.1 alc HAL_BOOL 99 1.1 alc ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode, 100 1.1 alc HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status) 101 1.1 alc { 102 1.1 alc #define N(a) (sizeof (a) / sizeof (a[0])) 103 1.1 alc #define FAIL(_code) do { ecode = _code; goto bad; } while (0) 104 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 105 1.1 alc HAL_CHANNEL_INTERNAL *ichan = AH_NULL; 106 1.1 alc const HAL_EEPROM *ee; 107 1.1 alc uint32_t softLedCfg, softLedState; 108 1.1 alc uint32_t saveFrameSeqCount, saveDefAntenna, saveLedState; 109 1.1 alc uint32_t macStaId1, synthDelay, txFrm2TxDStart; 110 1.1 alc uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL]; 111 1.1 alc int16_t cckOfdmPwrDelta = 0; 112 1.1 alc u_int modesIndex, freqIndex; 113 1.1 alc HAL_STATUS ecode; 114 1.1 alc int i, regWrites; 115 1.1 alc uint32_t testReg, powerVal; 116 1.1 alc int8_t twiceAntennaGain, twiceAntennaReduction; 117 1.1 alc uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow; 118 1.1 alc HAL_BOOL isBmode = AH_FALSE; 119 1.1 alc HAL_BOOL ichan_isBmode = AH_FALSE; 120 1.1 alc 121 1.1 alc HALASSERT(ah->ah_magic == AR5212_MAGIC); 122 1.1 alc ee = AH_PRIVATE(ah)->ah_eeprom; 123 1.1 alc 124 1.1 alc OS_MARK(ah, AH_MARK_RESET, bChannelChange); 125 1.1 alc #define IS(_c,_f) (((_c)->channelFlags & _f) || 0) 126 1.1 alc if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) { 127 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 128 1.1 alc "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n", 129 1.1 alc __func__, chan->channel, chan->channelFlags); 130 1.1 alc FAIL(HAL_EINVAL); 131 1.1 alc } 132 1.1 alc if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) { 133 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 134 1.1 alc "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n", 135 1.1 alc __func__, chan->channel, chan->channelFlags); 136 1.1 alc FAIL(HAL_EINVAL); 137 1.1 alc } 138 1.1 alc #undef IS 139 1.1 alc 140 1.1 alc /* Bring out of sleep mode */ 141 1.1 alc if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 142 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n", 143 1.1 alc __func__); 144 1.1 alc FAIL(HAL_EIO); 145 1.1 alc } 146 1.1 alc 147 1.1 alc /* 148 1.1 alc * Map public channel to private. 149 1.1 alc */ 150 1.1 alc ichan = ath_hal_checkchannel(ah, chan); 151 1.1 alc if (ichan == AH_NULL) { 152 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 153 1.1 alc "%s: invalid channel %u/0x%x; no mapping\n", 154 1.1 alc __func__, chan->channel, chan->channelFlags); 155 1.1 alc FAIL(HAL_EINVAL); 156 1.1 alc } 157 1.1 alc switch (opmode) { 158 1.1 alc case HAL_M_STA: 159 1.1 alc case HAL_M_IBSS: 160 1.1 alc case HAL_M_HOSTAP: 161 1.1 alc case HAL_M_MONITOR: 162 1.1 alc break; 163 1.1 alc default: 164 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n", 165 1.1 alc __func__, opmode); 166 1.1 alc FAIL(HAL_EINVAL); 167 1.1 alc break; 168 1.1 alc } 169 1.1 alc HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3); 170 1.1 alc 171 1.1 alc SAVE_CCK(ah, ichan, ichan_isBmode); 172 1.1 alc SAVE_CCK(ah, chan, isBmode); 173 1.1 alc 174 1.1 alc /* Preserve certain DMA hardware registers on a channel change */ 175 1.1 alc if (bChannelChange) { 176 1.1 alc /* 177 1.1 alc * On Venice, the TSF is almost preserved across a reset; 178 1.1 alc * it requires doubling writes to the RESET_TSF 179 1.1 alc * bit in the AR_BEACON register; it also has the quirk 180 1.1 alc * of the TSF going back in time on the station (station 181 1.1 alc * latches onto the last beacon's tsf during a reset 50% 182 1.1 alc * of the times); the latter is not a problem for adhoc 183 1.1 alc * stations since as long as the TSF is behind, it will 184 1.1 alc * get resynchronized on receiving the next beacon; the 185 1.1 alc * TSF going backwards in time could be a problem for the 186 1.1 alc * sleep operation (supported on infrastructure stations 187 1.1 alc * only) - the best and most general fix for this situation 188 1.1 alc * is to resynchronize the various sleep/beacon timers on 189 1.1 alc * the receipt of the next beacon i.e. when the TSF itself 190 1.1 alc * gets resynchronized to the AP's TSF - power save is 191 1.1 alc * needed to be temporarily disabled until that time 192 1.1 alc * 193 1.1 alc * Need to save the sequence number to restore it after 194 1.1 alc * the reset! 195 1.1 alc */ 196 1.1 alc saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM); 197 1.1 alc } else 198 1.1 alc saveFrameSeqCount = 0; /* NB: silence compiler */ 199 1.1 alc #if 0 200 1.1 alc /* 201 1.1 alc * XXX disable for now; this appears to sometimes cause OFDM 202 1.1 alc * XXX timing error floods when ani is enabled and bg scanning 203 1.1 alc * XXX kicks in 204 1.1 alc */ 205 1.1 alc /* If the channel change is across the same mode - perform a fast channel change */ 206 1.1 alc if (IS_2413(ah) || IS_5413(ah)) { 207 1.1 alc /* 208 1.1 alc * Fast channel change can only be used when: 209 1.1 alc * -channel change requested - so it's not the initial reset. 210 1.1 alc * -it's not a change to the current channel - 211 1.1 alc * often called when switching modes on a channel 212 1.1 alc * -the modes of the previous and requested channel are the 213 1.1 alc * same 214 1.1 alc * XXX opmode shouldn't change either? 215 1.1 alc */ 216 1.1 alc if (bChannelChange && 217 1.1 alc (AH_PRIVATE(ah)->ah_curchan != AH_NULL) && 218 1.1 alc (chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) && 219 1.1 alc ((chan->channelFlags & CHANNEL_ALL) == 220 1.1 alc (AH_PRIVATE(ah)->ah_curchan->channelFlags & CHANNEL_ALL))) { 221 1.1 alc if (ar5212ChannelChange(ah, chan)) { 222 1.1 alc /* If ChannelChange completed - skip the rest of reset */ 223 1.1 alc /* XXX ani? */ 224 1.1 alc return AH_TRUE; 225 1.1 alc } 226 1.1 alc } 227 1.1 alc } 228 1.1 alc #endif 229 1.1 alc /* 230 1.1 alc * Preserve the antenna on a channel change 231 1.1 alc */ 232 1.1 alc saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA); 233 1.1 alc if (saveDefAntenna == 0) /* XXX magic constants */ 234 1.1 alc saveDefAntenna = 1; 235 1.1 alc 236 1.1 alc /* Save hardware flag before chip reset clears the register */ 237 1.1 alc macStaId1 = OS_REG_READ(ah, AR_STA_ID1) & 238 1.1 alc (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT); 239 1.1 alc 240 1.1 alc /* Save led state from pci config register */ 241 1.1 alc saveLedState = OS_REG_READ(ah, AR_PCICFG) & 242 1.1 alc (AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK | 243 1.1 alc AR_PCICFG_LEDSLOW); 244 1.1 alc softLedCfg = OS_REG_READ(ah, AR_GPIOCR); 245 1.1 alc softLedState = OS_REG_READ(ah, AR_GPIODO); 246 1.1 alc 247 1.1 alc ar5212RestoreClock(ah, opmode); /* move to refclk operation */ 248 1.1 alc 249 1.1 alc /* 250 1.1 alc * Adjust gain parameters before reset if 251 1.1 alc * there's an outstanding gain updated. 252 1.1 alc */ 253 1.1 alc (void) ar5212GetRfgain(ah); 254 1.1 alc 255 1.1 alc if (!ar5212ChipReset(ah, chan)) { 256 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); 257 1.1 alc FAIL(HAL_EIO); 258 1.1 alc } 259 1.1 alc 260 1.1 alc /* Setup the indices for the next set of register array writes */ 261 1.1 alc switch (chan->channelFlags & CHANNEL_ALL) { 262 1.1 alc case CHANNEL_A: 263 1.1 alc modesIndex = 1; 264 1.1 alc freqIndex = 1; 265 1.1 alc break; 266 1.1 alc case CHANNEL_T: 267 1.1 alc modesIndex = 2; 268 1.1 alc freqIndex = 1; 269 1.1 alc break; 270 1.1 alc case CHANNEL_B: 271 1.1 alc modesIndex = 3; 272 1.1 alc freqIndex = 2; 273 1.1 alc break; 274 1.1 alc case CHANNEL_PUREG: 275 1.1 alc modesIndex = 4; 276 1.1 alc freqIndex = 2; 277 1.1 alc break; 278 1.1 alc case CHANNEL_108G: 279 1.1 alc modesIndex = 5; 280 1.1 alc freqIndex = 2; 281 1.1 alc break; 282 1.1 alc default: 283 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n", 284 1.1 alc __func__, chan->channelFlags); 285 1.1 alc FAIL(HAL_EINVAL); 286 1.1 alc } 287 1.1 alc 288 1.1 alc OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 289 1.1 alc 290 1.1 alc /* Set correct Baseband to analog shift setting to access analog chips. */ 291 1.1 alc OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 292 1.1 alc 293 1.1 alc regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0); 294 1.1 alc regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange, 295 1.1 alc regWrites); 296 1.1 alc ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites); 297 1.1 alc 298 1.1 alc OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 299 1.1 alc 300 1.1 alc if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) { 301 1.1 alc ar5212SetIFSTiming(ah, chan); 302 1.1 alc if (IS_5413(ah)) { 303 1.1 alc /* 304 1.1 alc * Force window_length for 1/2 and 1/4 rate channels, 305 1.1 alc * the ini file sets this to zero otherwise. 306 1.1 alc */ 307 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, 308 1.1 alc AR_PHY_FRAME_CTL_WINLEN, 3); 309 1.1 alc } 310 1.1 alc } 311 1.1 alc 312 1.1 alc /* Overwrite INI values for revised chipsets */ 313 1.1 alc if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) { 314 1.1 alc /* ADC_CTL */ 315 1.1 alc OS_REG_WRITE(ah, AR_PHY_ADC_CTL, 316 1.1 alc SM(2, AR_PHY_ADC_CTL_OFF_INBUFGAIN) | 317 1.1 alc SM(2, AR_PHY_ADC_CTL_ON_INBUFGAIN) | 318 1.1 alc AR_PHY_ADC_CTL_OFF_PWDDAC | 319 1.1 alc AR_PHY_ADC_CTL_OFF_PWDADC); 320 1.1 alc 321 1.1 alc /* TX_PWR_ADJ */ 322 1.1 alc if (chan->channel == 2484) { 323 1.1 alc cckOfdmPwrDelta = SCALE_OC_DELTA( 324 1.1 alc ee->ee_cckOfdmPwrDelta - 325 1.1 alc ee->ee_scaledCh14FilterCckDelta); 326 1.1 alc } else { 327 1.1 alc cckOfdmPwrDelta = SCALE_OC_DELTA( 328 1.1 alc ee->ee_cckOfdmPwrDelta); 329 1.1 alc } 330 1.1 alc 331 1.1 alc if (IS_CHAN_G(chan)) { 332 1.1 alc OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 333 1.1 alc SM((ee->ee_cckOfdmPwrDelta*-1), 334 1.1 alc AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) | 335 1.1 alc SM((cckOfdmPwrDelta*-1), 336 1.1 alc AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX)); 337 1.1 alc } else { 338 1.1 alc OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0); 339 1.1 alc } 340 1.1 alc 341 1.1 alc /* Add barker RSSI thresh enable as disabled */ 342 1.1 alc OS_REG_CLR_BIT(ah, AR_PHY_DAG_CTRLCCK, 343 1.1 alc AR_PHY_DAG_CTRLCCK_EN_RSSI_THR); 344 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_DAG_CTRLCCK, 345 1.1 alc AR_PHY_DAG_CTRLCCK_RSSI_THR, 2); 346 1.1 alc 347 1.1 alc /* Set the mute mask to the correct default */ 348 1.1 alc OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F); 349 1.1 alc } 350 1.1 alc 351 1.1 alc if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) { 352 1.1 alc /* Clear reg to alllow RX_CLEAR line debug */ 353 1.1 alc OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0); 354 1.1 alc } 355 1.1 alc if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) { 356 1.1 alc #ifdef notyet 357 1.1 alc /* Enable burst prefetch for the data queues */ 358 1.1 alc OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... ); 359 1.1 alc /* Enable double-buffering */ 360 1.1 alc OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS); 361 1.1 alc #endif 362 1.1 alc } 363 1.1 alc 364 1.1 alc /* Set ADC/DAC select values */ 365 1.1 alc OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e); 366 1.1 alc 367 1.1 alc if (IS_5413(ah) || IS_2417(ah)) { 368 1.1 alc uint32_t newReg=1; 369 1.1 alc if (IS_DISABLE_FAST_ADC_CHAN(chan->channel)) 370 1.1 alc newReg = 0; 371 1.1 alc /* As it's a clock changing register, only write when the value needs to be changed */ 372 1.1 alc if (OS_REG_READ(ah, AR_PHY_FAST_ADC) != newReg) 373 1.1 alc OS_REG_WRITE(ah, AR_PHY_FAST_ADC, newReg); 374 1.1 alc } 375 1.1 alc 376 1.1 alc /* Setup the transmit power values. */ 377 1.1 alc if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) { 378 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 379 1.1 alc "%s: error init'ing transmit power\n", __func__); 380 1.1 alc FAIL(HAL_EIO); 381 1.1 alc } 382 1.1 alc 383 1.1 alc /* Write the analog registers */ 384 1.1 alc if (!ahp->ah_rfHal->setRfRegs(ah, ichan, modesIndex, rfXpdGain)) { 385 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n", 386 1.1 alc __func__); 387 1.1 alc FAIL(HAL_EIO); 388 1.1 alc } 389 1.1 alc 390 1.1 alc /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 391 1.1 alc if (IS_CHAN_OFDM(chan)) { 392 1.1 alc if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) && 393 1.1 alc (!IS_CHAN_B(chan))) 394 1.1 alc ar5212SetSpurMitigation(ah, ichan); 395 1.1 alc ar5212SetDeltaSlope(ah, chan); 396 1.1 alc } 397 1.1 alc 398 1.1 alc /* Setup board specific options for EEPROM version 3 */ 399 1.1 alc if (!ar5212SetBoardValues(ah, ichan)) { 400 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 401 1.1 alc "%s: error setting board options\n", __func__); 402 1.1 alc FAIL(HAL_EIO); 403 1.1 alc } 404 1.1 alc 405 1.1 alc /* Restore certain DMA hardware registers on a channel change */ 406 1.1 alc if (bChannelChange) 407 1.1 alc OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount); 408 1.1 alc 409 1.1 alc OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 410 1.1 alc 411 1.1 alc OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 412 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) 413 1.1 alc | macStaId1 414 1.1 alc | AR_STA_ID1_RTS_USE_DEF 415 1.1 alc | ahp->ah_staId1Defaults 416 1.1 alc ); 417 1.1 alc ar5212SetOperatingMode(ah, opmode); 418 1.1 alc 419 1.1 alc /* Set Venice BSSID mask according to current state */ 420 1.1 alc OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask)); 421 1.1 alc OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4)); 422 1.1 alc 423 1.1 alc /* Restore previous led state */ 424 1.1 alc OS_REG_WRITE(ah, AR_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState); 425 1.1 alc 426 1.1 alc /* Restore soft Led state to GPIO */ 427 1.1 alc OS_REG_WRITE(ah, AR_GPIOCR, softLedCfg); 428 1.1 alc OS_REG_WRITE(ah, AR_GPIODO, softLedState); 429 1.1 alc 430 1.1 alc /* Restore previous antenna */ 431 1.1 alc OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 432 1.1 alc 433 1.1 alc /* then our BSSID */ 434 1.1 alc OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 435 1.1 alc OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4)); 436 1.1 alc 437 1.1 alc /* Restore bmiss rssi & count thresholds */ 438 1.1 alc OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr); 439 1.1 alc 440 1.1 alc OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ 441 1.1 alc 442 1.1 alc if (!ar5212SetChannel(ah, ichan)) 443 1.1 alc FAIL(HAL_EIO); 444 1.1 alc 445 1.1 alc OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 446 1.1 alc 447 1.1 alc ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); 448 1.1 alc 449 1.1 alc ar5212SetRateDurationTable(ah, chan); 450 1.1 alc 451 1.1 alc /* Set Tx frame start to tx data start delay */ 452 1.1 alc if (IS_RAD5112_ANY(ah) && 453 1.1 alc (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) || 454 1.1 alc IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) { 455 1.1 alc txFrm2TxDStart = 456 1.1 alc (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ? 457 1.1 alc TX_FRAME_D_START_HALF_RATE: 458 1.1 alc TX_FRAME_D_START_QUARTER_RATE; 459 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL, 460 1.1 alc AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart); 461 1.1 alc } 462 1.1 alc 463 1.1 alc /* 464 1.1 alc * Setup fast diversity. 465 1.1 alc * Fast diversity can be enabled or disabled via regadd.txt. 466 1.1 alc * Default is enabled. 467 1.1 alc * For reference, 468 1.1 alc * Disable: reg val 469 1.1 alc * 0x00009860 0x00009d18 (if 11a / 11g, else no change) 470 1.1 alc * 0x00009970 0x192bb514 471 1.1 alc * 0x0000a208 0xd03e4648 472 1.1 alc * 473 1.1 alc * Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change) 474 1.1 alc * 0x00009970 0x192fb514 475 1.1 alc * 0x0000a208 0xd03e6788 476 1.1 alc */ 477 1.1 alc 478 1.1 alc /* XXX Setup pre PHY ENABLE EAR additions */ 479 1.1 alc /* 480 1.1 alc * Wait for the frequency synth to settle (synth goes on 481 1.1 alc * via AR_PHY_ACTIVE_EN). Read the phy active delay register. 482 1.1 alc * Value is in 100ns increments. 483 1.1 alc */ 484 1.1 alc synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 485 1.1 alc if (IS_CHAN_CCK(chan)) { 486 1.1 alc synthDelay = (4 * synthDelay) / 22; 487 1.1 alc } else { 488 1.1 alc synthDelay /= 10; 489 1.1 alc } 490 1.1 alc 491 1.1 alc /* Activate the PHY (includes baseband activate and synthesizer on) */ 492 1.1 alc OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 493 1.1 alc 494 1.1 alc /* 495 1.1 alc * There is an issue if the AP starts the calibration before 496 1.1 alc * the base band timeout completes. This could result in the 497 1.1 alc * rx_clear false triggering. As a workaround we add delay an 498 1.1 alc * extra BASE_ACTIVATE_DELAY usecs to ensure this condition 499 1.1 alc * does not happen. 500 1.1 alc */ 501 1.1 alc if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) { 502 1.1 alc OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY); 503 1.1 alc } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) { 504 1.1 alc OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY); 505 1.1 alc } else { 506 1.1 alc OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 507 1.1 alc } 508 1.1 alc 509 1.1 alc /* 510 1.1 alc * The udelay method is not reliable with notebooks. 511 1.1 alc * Need to check to see if the baseband is ready 512 1.1 alc */ 513 1.1 alc testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL); 514 1.1 alc /* Selects the Tx hold */ 515 1.1 alc OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD); 516 1.1 alc i = 0; 517 1.1 alc while ((i++ < 20) && 518 1.1 alc (OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */ OS_DELAY(200); 519 1.1 alc OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg); 520 1.1 alc 521 1.1 alc /* Calibrate the AGC and start a NF calculation */ 522 1.1 alc OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL, 523 1.1 alc OS_REG_READ(ah, AR_PHY_AGC_CONTROL) 524 1.1 alc | AR_PHY_AGC_CONTROL_CAL 525 1.1 alc | AR_PHY_AGC_CONTROL_NF); 526 1.1 alc 527 1.1 alc if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) { 528 1.1 alc /* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */ 529 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, 530 1.1 alc AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, 531 1.1 alc INIT_IQCAL_LOG_COUNT_MAX); 532 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, 533 1.1 alc AR_PHY_TIMING_CTRL4_DO_IQCAL); 534 1.1 alc ahp->ah_bIQCalibration = IQ_CAL_RUNNING; 535 1.1 alc } else 536 1.1 alc ahp->ah_bIQCalibration = IQ_CAL_INACTIVE; 537 1.1 alc 538 1.1 alc /* Setup compression registers */ 539 1.1 alc ar5212SetCompRegs(ah); 540 1.1 alc 541 1.1 alc /* Set 1:1 QCU to DCU mapping for all queues */ 542 1.1 alc for (i = 0; i < AR_NUM_DCU; i++) 543 1.1 alc OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 544 1.1 alc 545 1.1 alc ahp->ah_intrTxqs = 0; 546 1.1 alc for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) 547 1.1 alc ar5212ResetTxQueue(ah, i); 548 1.1 alc 549 1.1 alc /* 550 1.1 alc * Setup interrupt handling. Note that ar5212ResetTxQueue 551 1.1 alc * manipulates the secondary IMR's as queues are enabled 552 1.1 alc * and disabled. This is done with RMW ops to insure the 553 1.1 alc * settings we make here are preserved. 554 1.1 alc */ 555 1.1 alc ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN 556 1.1 alc | AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN 557 1.1 alc | AR_IMR_HIUERR 558 1.1 alc ; 559 1.1 alc if (opmode == HAL_M_HOSTAP) 560 1.1 alc ahp->ah_maskReg |= AR_IMR_MIB; 561 1.1 alc OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); 562 1.1 alc /* Enable bus errors that are OR'd to set the HIUERR bit */ 563 1.1 alc OS_REG_WRITE(ah, AR_IMR_S2, 564 1.1 alc OS_REG_READ(ah, AR_IMR_S2) 565 1.1 alc | AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR); 566 1.1 alc 567 1.1 alc if (AH_PRIVATE(ah)->ah_rfkillEnabled) 568 1.1 alc ar5212EnableRfKill(ah); 569 1.1 alc 570 1.1 alc if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { 571 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 572 1.1 alc "%s: offset calibration failed to complete in 1ms;" 573 1.1 alc " noisy environment?\n", __func__); 574 1.1 alc } 575 1.1 alc 576 1.1 alc /* 577 1.1 alc * Set clocks back to 32kHz if they had been using refClk, then 578 1.1 alc * use an external 32kHz crystal when sleeping, if one exists. 579 1.1 alc */ 580 1.1 alc ar5212SetupClock(ah, opmode); 581 1.1 alc 582 1.1 alc /* 583 1.1 alc * Writing to AR_BEACON will start timers. Hence it should 584 1.1 alc * be the last register to be written. Do not reset tsf, do 585 1.1 alc * not enable beacons at this point, but preserve other values 586 1.1 alc * like beaconInterval. 587 1.1 alc */ 588 1.1 alc OS_REG_WRITE(ah, AR_BEACON, 589 1.1 alc (OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF))); 590 1.1 alc 591 1.1 alc /* XXX Setup post reset EAR additions */ 592 1.1 alc 593 1.1 alc /* QoS support */ 594 1.1 alc if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE || 595 1.1 alc (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE && 596 1.1 alc AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) { 597 1.1 alc OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */ 598 1.1 alc OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */ 599 1.1 alc } 600 1.1 alc 601 1.1 alc /* Turn on NOACK Support for QoS packets */ 602 1.1 alc OS_REG_WRITE(ah, AR_NOACK, 603 1.1 alc SM(2, AR_NOACK_2BIT_VALUE) | 604 1.1 alc SM(5, AR_NOACK_BIT_OFFSET) | 605 1.1 alc SM(0, AR_NOACK_BYTE_OFFSET)); 606 1.1 alc 607 1.1 alc /* Get Antenna Gain reduction */ 608 1.1 alc if (IS_CHAN_5GHZ(chan)) { 609 1.1 alc ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain); 610 1.1 alc } else { 611 1.1 alc ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain); 612 1.1 alc } 613 1.1 alc twiceAntennaReduction = 614 1.1 alc ath_hal_getantennareduction(ah, chan, twiceAntennaGain); 615 1.1 alc 616 1.1 alc /* TPC for self-generated frames */ 617 1.1 alc 618 1.1 alc ackTpcPow = MS(ahp->ah_macTPC, AR_TPC_ACK); 619 1.1 alc if ((ackTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower) 620 1.1 alc ackTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset; 621 1.1 alc 622 1.1 alc if (ackTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction)) 623 1.1 alc ackTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction) 624 1.1 alc + ahp->ah_txPowerIndexOffset; 625 1.1 alc 626 1.1 alc ctsTpcPow = MS(ahp->ah_macTPC, AR_TPC_CTS); 627 1.1 alc if ((ctsTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower) 628 1.1 alc ctsTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset; 629 1.1 alc 630 1.1 alc if (ctsTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction)) 631 1.1 alc ctsTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction) 632 1.1 alc + ahp->ah_txPowerIndexOffset; 633 1.1 alc 634 1.1 alc chirpTpcPow = MS(ahp->ah_macTPC, AR_TPC_CHIRP); 635 1.1 alc if ((chirpTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower) 636 1.1 alc chirpTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset; 637 1.1 alc 638 1.1 alc if (chirpTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction)) 639 1.1 alc chirpTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction) 640 1.1 alc + ahp->ah_txPowerIndexOffset; 641 1.1 alc 642 1.1 alc if (ackTpcPow > 63) 643 1.1 alc ackTpcPow = 63; 644 1.1 alc if (ctsTpcPow > 63) 645 1.1 alc ctsTpcPow = 63; 646 1.1 alc if (chirpTpcPow > 63) 647 1.1 alc chirpTpcPow = 63; 648 1.1 alc 649 1.1 alc powerVal = SM(ackTpcPow, AR_TPC_ACK) | 650 1.1 alc SM(ctsTpcPow, AR_TPC_CTS) | 651 1.1 alc SM(chirpTpcPow, AR_TPC_CHIRP); 652 1.1 alc 653 1.1 alc OS_REG_WRITE(ah, AR_TPC, powerVal); 654 1.1 alc 655 1.1 alc /* Restore user-specified settings */ 656 1.1 alc if (ahp->ah_miscMode != 0) 657 1.1 alc OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 658 1.1 alc if (ahp->ah_sifstime != (u_int) -1) 659 1.1 alc ar5212SetSifsTime(ah, ahp->ah_sifstime); 660 1.1 alc if (ahp->ah_slottime != (u_int) -1) 661 1.1 alc ar5212SetSlotTime(ah, ahp->ah_slottime); 662 1.1 alc if (ahp->ah_acktimeout != (u_int) -1) 663 1.1 alc ar5212SetAckTimeout(ah, ahp->ah_acktimeout); 664 1.1 alc if (ahp->ah_ctstimeout != (u_int) -1) 665 1.1 alc ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout); 666 1.1 alc if (AH_PRIVATE(ah)->ah_diagreg != 0) 667 1.1 alc OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 668 1.1 alc 669 1.1 alc AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 670 1.1 alc 671 1.1 alc if (bChannelChange) { 672 1.1 alc if (!(ichan->privFlags & CHANNEL_DFS)) 673 1.1 alc ichan->privFlags &= ~CHANNEL_INTERFERENCE; 674 1.1 alc chan->channelFlags = ichan->channelFlags; 675 1.1 alc chan->privFlags = ichan->privFlags; 676 1.1 alc chan->maxRegTxPower = ichan->maxRegTxPower; 677 1.1 alc chan->maxTxPower = ichan->maxTxPower; 678 1.1 alc chan->minTxPower = ichan->minTxPower; 679 1.1 alc } 680 1.1 alc 681 1.1 alc HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__); 682 1.1 alc 683 1.1 alc RESTORE_CCK(ah, ichan, ichan_isBmode); 684 1.1 alc RESTORE_CCK(ah, chan, isBmode); 685 1.1 alc 686 1.1 alc OS_MARK(ah, AH_MARK_RESET_DONE, 0); 687 1.1 alc 688 1.1 alc return AH_TRUE; 689 1.1 alc bad: 690 1.1 alc if (ichan != AH_NULL) 691 1.1 alc RESTORE_CCK(ah, ichan, ichan_isBmode); 692 1.1 alc RESTORE_CCK(ah, chan, isBmode); 693 1.1 alc 694 1.1 alc OS_MARK(ah, AH_MARK_RESET_DONE, ecode); 695 1.4 cegger if (status != AH_NULL) 696 1.1 alc *status = ecode; 697 1.1 alc return AH_FALSE; 698 1.1 alc #undef FAIL 699 1.1 alc #undef N 700 1.1 alc } 701 1.1 alc 702 1.1 alc /* 703 1.1 alc * Call the rf backend to change the channel. 704 1.1 alc */ 705 1.1 alc HAL_BOOL 706 1.1 alc ar5212SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 707 1.1 alc { 708 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 709 1.1 alc 710 1.1 alc /* Change the synth */ 711 1.1 alc if (!ahp->ah_rfHal->setChannel(ah, chan)) 712 1.1 alc return AH_FALSE; 713 1.1 alc return AH_TRUE; 714 1.1 alc } 715 1.1 alc 716 1.1 alc /* 717 1.1 alc * This channel change evaluates whether the selected hardware can 718 1.1 alc * perform a synthesizer-only channel change (no reset). If the 719 1.1 alc * TX is not stopped, or the RFBus cannot be granted in the given 720 1.1 alc * time, the function returns false as a reset is necessary 721 1.1 alc */ 722 1.1 alc HAL_BOOL 723 1.1 alc ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan) 724 1.1 alc { 725 1.1 alc uint32_t ulCount; 726 1.1 alc uint32_t data, synthDelay, qnum; 727 1.1 alc uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL]; 728 1.1 alc HAL_BOOL txStopped = AH_TRUE; 729 1.1 alc HAL_CHANNEL_INTERNAL *ichan; 730 1.1 alc 731 1.1 alc /* 732 1.1 alc * Map public channel to private. 733 1.1 alc */ 734 1.1 alc ichan = ath_hal_checkchannel(ah, chan); 735 1.1 alc 736 1.1 alc /* TX must be stopped or RF Bus grant will not work */ 737 1.1 alc for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) { 738 1.1 alc if (ar5212NumTxPending(ah, qnum)) { 739 1.1 alc txStopped = AH_FALSE; 740 1.1 alc break; 741 1.1 alc } 742 1.1 alc } 743 1.1 alc if (!txStopped) 744 1.1 alc return AH_FALSE; 745 1.1 alc 746 1.1 alc /* Kill last Baseband Rx Frame */ 747 1.1 alc OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); /* Request analog bus grant */ 748 1.1 alc for (ulCount = 0; ulCount < 100; ulCount++) { 749 1.1 alc if (OS_REG_READ(ah, AR_PHY_RFBUS_GNT)) 750 1.1 alc break; 751 1.1 alc OS_DELAY(5); 752 1.1 alc } 753 1.1 alc if (ulCount >= 100) 754 1.1 alc return AH_FALSE; 755 1.1 alc 756 1.1 alc /* Change the synth */ 757 1.1 alc if (!ar5212SetChannel(ah, ichan)) 758 1.1 alc return AH_FALSE; 759 1.1 alc 760 1.1 alc /* 761 1.1 alc * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN). 762 1.1 alc * Read the phy active delay register. Value is in 100ns increments. 763 1.1 alc */ 764 1.1 alc data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 765 1.1 alc if (IS_CHAN_CCK(ichan)) { 766 1.1 alc synthDelay = (4 * data) / 22; 767 1.1 alc } else { 768 1.1 alc synthDelay = data / 10; 769 1.1 alc } 770 1.1 alc OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 771 1.1 alc 772 1.1 alc /* Setup the transmit power values. */ 773 1.1 alc if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) { 774 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 775 1.1 alc "%s: error init'ing transmit power\n", __func__); 776 1.1 alc return AH_FALSE; 777 1.1 alc } 778 1.1 alc 779 1.1 alc /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 780 1.1 alc if (IS_CHAN_OFDM(ichan)) { 781 1.1 alc if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) && 782 1.1 alc (!IS_CHAN_B(chan))) 783 1.1 alc ar5212SetSpurMitigation(ah, ichan); 784 1.1 alc ar5212SetDeltaSlope(ah, chan); 785 1.1 alc } 786 1.1 alc 787 1.1 alc /* Release the RFBus Grant */ 788 1.1 alc OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 789 1.1 alc 790 1.1 alc /* Start Noise Floor Cal */ 791 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 792 1.1 alc 793 1.1 alc if (!(ichan->privFlags & CHANNEL_DFS)) 794 1.1 alc ichan->privFlags &= ~CHANNEL_INTERFERENCE; 795 1.1 alc chan->channelFlags = ichan->channelFlags; 796 1.1 alc chan->privFlags = ichan->privFlags; 797 1.1 alc chan->maxRegTxPower = ichan->maxRegTxPower; 798 1.1 alc chan->maxTxPower = ichan->maxTxPower; 799 1.1 alc chan->minTxPower = ichan->minTxPower; 800 1.1 alc return AH_TRUE; 801 1.1 alc } 802 1.1 alc 803 1.1 alc void 804 1.1 alc ar5212SetOperatingMode(struct ath_hal *ah, int opmode) 805 1.1 alc { 806 1.1 alc uint32_t val; 807 1.1 alc 808 1.1 alc val = OS_REG_READ(ah, AR_STA_ID1); 809 1.1 alc val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC); 810 1.1 alc switch (opmode) { 811 1.1 alc case HAL_M_HOSTAP: 812 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP 813 1.1 alc | AR_STA_ID1_KSRCH_MODE); 814 1.1 alc OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 815 1.1 alc break; 816 1.1 alc case HAL_M_IBSS: 817 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC 818 1.1 alc | AR_STA_ID1_KSRCH_MODE); 819 1.1 alc OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 820 1.1 alc break; 821 1.1 alc case HAL_M_STA: 822 1.1 alc case HAL_M_MONITOR: 823 1.1 alc OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); 824 1.1 alc break; 825 1.1 alc } 826 1.1 alc } 827 1.1 alc 828 1.1 alc /* 829 1.1 alc * Places the PHY and Radio chips into reset. A full reset 830 1.1 alc * must be called to leave this state. The PCI/MAC/PCU are 831 1.1 alc * not placed into reset as we must receive interrupt to 832 1.1 alc * re-enable the hardware. 833 1.1 alc */ 834 1.1 alc HAL_BOOL 835 1.1 alc ar5212PhyDisable(struct ath_hal *ah) 836 1.1 alc { 837 1.1 alc return ar5212SetResetReg(ah, AR_RC_BB); 838 1.1 alc } 839 1.1 alc 840 1.1 alc /* 841 1.1 alc * Places all of hardware into reset 842 1.1 alc */ 843 1.1 alc HAL_BOOL 844 1.1 alc ar5212Disable(struct ath_hal *ah) 845 1.1 alc { 846 1.1 alc if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 847 1.1 alc return AH_FALSE; 848 1.1 alc /* 849 1.1 alc * Reset the HW - PCI must be reset after the rest of the 850 1.1 alc * device has been reset. 851 1.1 alc */ 852 1.1 alc return ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI); 853 1.1 alc } 854 1.1 alc 855 1.1 alc /* 856 1.1 alc * Places the hardware into reset and then pulls it out of reset 857 1.1 alc * 858 1.1 alc * TODO: Only write the PLL if we're changing to or from CCK mode 859 1.1 alc * 860 1.1 alc * WARNING: The order of the PLL and mode registers must be correct. 861 1.1 alc */ 862 1.1 alc HAL_BOOL 863 1.1 alc ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan) 864 1.1 alc { 865 1.1 alc 866 1.1 alc OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0); 867 1.1 alc 868 1.1 alc /* 869 1.1 alc * Reset the HW - PCI must be reset after the rest of the 870 1.1 alc * device has been reset 871 1.1 alc */ 872 1.1 alc if (!ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI)) 873 1.1 alc return AH_FALSE; 874 1.1 alc 875 1.1 alc /* Bring out of sleep mode (AGAIN) */ 876 1.1 alc if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 877 1.1 alc return AH_FALSE; 878 1.1 alc 879 1.1 alc /* Clear warm reset register */ 880 1.1 alc if (!ar5212SetResetReg(ah, 0)) 881 1.1 alc return AH_FALSE; 882 1.1 alc 883 1.1 alc /* 884 1.1 alc * Perform warm reset before the mode/PLL/turbo registers 885 1.1 alc * are changed in order to deactivate the radio. Mode changes 886 1.1 alc * with an active radio can result in corrupted shifts to the 887 1.1 alc * radio device. 888 1.1 alc */ 889 1.1 alc 890 1.1 alc /* 891 1.1 alc * Set CCK and Turbo modes correctly. 892 1.1 alc */ 893 1.1 alc if (chan != AH_NULL) { /* NB: can be null during attach */ 894 1.1 alc uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo; 895 1.1 alc 896 1.1 alc if (IS_5413(ah)) { /* NB: =>'s 5424 also */ 897 1.1 alc rfMode = AR_PHY_MODE_AR5112; 898 1.1 alc if (IS_CHAN_HALF_RATE(chan)) 899 1.1 alc rfMode |= AR_PHY_MODE_HALF; 900 1.1 alc else if (IS_CHAN_QUARTER_RATE(chan)) 901 1.1 alc rfMode |= AR_PHY_MODE_QUARTER; 902 1.1 alc 903 1.1 alc if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) 904 1.1 alc phyPLL = AR_PHY_PLL_CTL_44_5112; 905 1.1 alc else 906 1.1 alc phyPLL = AR_PHY_PLL_CTL_40_5413; 907 1.1 alc } else if (IS_RAD5111(ah)) { 908 1.1 alc rfMode = AR_PHY_MODE_AR5111; 909 1.1 alc if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) 910 1.1 alc phyPLL = AR_PHY_PLL_CTL_44; 911 1.1 alc else 912 1.1 alc phyPLL = AR_PHY_PLL_CTL_40; 913 1.1 alc if (IS_CHAN_HALF_RATE(chan)) 914 1.1 alc phyPLL = AR_PHY_PLL_CTL_HALF; 915 1.1 alc else if (IS_CHAN_QUARTER_RATE(chan)) 916 1.1 alc phyPLL = AR_PHY_PLL_CTL_QUARTER; 917 1.1 alc } else { /* 5112, 2413, 2316, 2317 */ 918 1.1 alc rfMode = AR_PHY_MODE_AR5112; 919 1.1 alc if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) 920 1.1 alc phyPLL = AR_PHY_PLL_CTL_44_5112; 921 1.1 alc else 922 1.1 alc phyPLL = AR_PHY_PLL_CTL_40_5112; 923 1.1 alc if (IS_CHAN_HALF_RATE(chan)) 924 1.1 alc phyPLL |= AR_PHY_PLL_CTL_HALF; 925 1.1 alc else if (IS_CHAN_QUARTER_RATE(chan)) 926 1.1 alc phyPLL |= AR_PHY_PLL_CTL_QUARTER; 927 1.1 alc } 928 1.1 alc if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) || 929 1.1 alc IS_CHAN_G(chan))) 930 1.1 alc rfMode |= AR_PHY_MODE_DYNAMIC; 931 1.1 alc else if (IS_CHAN_OFDM(chan)) 932 1.1 alc rfMode |= AR_PHY_MODE_OFDM; 933 1.1 alc else 934 1.1 alc rfMode |= AR_PHY_MODE_CCK; 935 1.1 alc if (IS_CHAN_5GHZ(chan)) 936 1.1 alc rfMode |= AR_PHY_MODE_RF5GHZ; 937 1.1 alc else 938 1.1 alc rfMode |= AR_PHY_MODE_RF2GHZ; 939 1.1 alc turbo = IS_CHAN_TURBO(chan) ? 940 1.1 alc (AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0; 941 1.1 alc curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL); 942 1.1 alc /* 943 1.1 alc * PLL, Mode, and Turbo values must be written in the correct 944 1.1 alc * order to ensure: 945 1.1 alc * - The PLL cannot be set to 44 unless the CCK or DYNAMIC 946 1.1 alc * mode bit is set 947 1.1 alc * - Turbo cannot be set at the same time as CCK or DYNAMIC 948 1.1 alc */ 949 1.1 alc if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) { 950 1.1 alc OS_REG_WRITE(ah, AR_PHY_TURBO, turbo); 951 1.1 alc OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); 952 1.1 alc if (curPhyPLL != phyPLL) { 953 1.1 alc OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL); 954 1.1 alc /* Wait for the PLL to settle */ 955 1.1 alc OS_DELAY(PLL_SETTLE_DELAY); 956 1.1 alc } 957 1.1 alc } else { 958 1.1 alc if (curPhyPLL != phyPLL) { 959 1.1 alc OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL); 960 1.1 alc /* Wait for the PLL to settle */ 961 1.1 alc OS_DELAY(PLL_SETTLE_DELAY); 962 1.1 alc } 963 1.1 alc OS_REG_WRITE(ah, AR_PHY_TURBO, turbo); 964 1.1 alc OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); 965 1.1 alc } 966 1.1 alc } 967 1.1 alc return AH_TRUE; 968 1.1 alc } 969 1.1 alc 970 1.1 alc /* 971 1.1 alc * Recalibrate the lower PHY chips to account for temperature/environment 972 1.1 alc * changes. 973 1.1 alc */ 974 1.1 alc HAL_BOOL 975 1.1 alc ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask, 976 1.1 alc HAL_BOOL longCal, HAL_BOOL *isCalDone) 977 1.1 alc { 978 1.1 alc #define IQ_CAL_TRIES 10 979 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 980 1.1 alc HAL_CHANNEL_INTERNAL *ichan; 981 1.1 alc int32_t qCoff, qCoffDenom; 982 1.1 alc int32_t iqCorrMeas, iCoff, iCoffDenom; 983 1.1 alc uint32_t powerMeasQ, powerMeasI; 984 1.1 alc HAL_BOOL ichan_isBmode = AH_FALSE; 985 1.1 alc HAL_BOOL isBmode = AH_FALSE; 986 1.1 alc 987 1.1 alc OS_MARK(ah, AH_MARK_PERCAL, chan->channel); 988 1.1 alc *isCalDone = AH_FALSE; 989 1.1 alc ichan = ath_hal_checkchannel(ah, chan); 990 1.1 alc if (ichan == AH_NULL) { 991 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 992 1.1 alc "%s: invalid channel %u/0x%x; no mapping\n", 993 1.1 alc __func__, chan->channel, chan->channelFlags); 994 1.1 alc return AH_FALSE; 995 1.1 alc } 996 1.1 alc SAVE_CCK(ah, ichan, ichan_isBmode); 997 1.1 alc SAVE_CCK(ah, chan, isBmode); 998 1.1 alc 999 1.1 alc if (ahp->ah_bIQCalibration == IQ_CAL_DONE || 1000 1.1 alc ahp->ah_bIQCalibration == IQ_CAL_INACTIVE) 1001 1.1 alc *isCalDone = AH_TRUE; 1002 1.1 alc 1003 1.1 alc /* IQ calibration in progress. Check to see if it has finished. */ 1004 1.1 alc if (ahp->ah_bIQCalibration == IQ_CAL_RUNNING && 1005 1.1 alc !(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_DO_IQCAL)) { 1006 1.1 alc int i; 1007 1.1 alc 1008 1.1 alc /* IQ Calibration has finished. */ 1009 1.1 alc ahp->ah_bIQCalibration = IQ_CAL_INACTIVE; 1010 1.1 alc *isCalDone = AH_TRUE; 1011 1.1 alc 1012 1.1 alc /* workaround for misgated IQ Cal results */ 1013 1.1 alc i = 0; 1014 1.1 alc do { 1015 1.1 alc /* Read calibration results. */ 1016 1.1 alc powerMeasI = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_I); 1017 1.1 alc powerMeasQ = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_Q); 1018 1.1 alc iqCorrMeas = OS_REG_READ(ah, AR_PHY_IQCAL_RES_IQ_CORR_MEAS); 1019 1.1 alc if (powerMeasI && powerMeasQ) 1020 1.1 alc break; 1021 1.1 alc /* Do we really need this??? */ 1022 1.1 alc OS_REG_WRITE (ah, AR_PHY_TIMING_CTRL4, 1023 1.1 alc OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) | 1024 1.1 alc AR_PHY_TIMING_CTRL4_DO_IQCAL); 1025 1.1 alc } while (++i < IQ_CAL_TRIES); 1026 1.1 alc 1027 1.1 alc /* 1028 1.1 alc * Prescale these values to remove 64-bit operation 1029 1.1 alc * requirement at the loss of a little precision. 1030 1.1 alc */ 1031 1.1 alc iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; 1032 1.1 alc qCoffDenom = powerMeasQ / 128; 1033 1.1 alc 1034 1.1 alc /* Protect against divide-by-0 and loss of sign bits. */ 1035 1.1 alc if (iCoffDenom != 0 && qCoffDenom >= 2) { 1036 1.1 alc iCoff = (int8_t)(-iqCorrMeas) / iCoffDenom; 1037 1.1 alc /* IQCORR_Q_I_COFF is a signed 6 bit number */ 1038 1.1 alc if (iCoff < -32) { 1039 1.1 alc iCoff = -32; 1040 1.1 alc } else if (iCoff > 31) { 1041 1.1 alc iCoff = 31; 1042 1.1 alc } 1043 1.1 alc 1044 1.1 alc /* IQCORR_Q_Q_COFF is a signed 5 bit number */ 1045 1.1 alc qCoff = (powerMeasI / qCoffDenom) - 128; 1046 1.1 alc if (qCoff < -16) { 1047 1.1 alc qCoff = -16; 1048 1.1 alc } else if (qCoff > 15) { 1049 1.1 alc qCoff = 15; 1050 1.1 alc } 1051 1.1 alc 1052 1.1 alc HALDEBUG(ah, HAL_DEBUG_PERCAL, 1053 1.1 alc "****************** MISGATED IQ CAL! *******************\n"); 1054 1.1 alc HALDEBUG(ah, HAL_DEBUG_PERCAL, 1055 1.1 alc "time = %d, i = %d, \n", OS_GETUPTIME(ah), i); 1056 1.1 alc HALDEBUG(ah, HAL_DEBUG_PERCAL, 1057 1.1 alc "powerMeasI = 0x%08x\n", powerMeasI); 1058 1.1 alc HALDEBUG(ah, HAL_DEBUG_PERCAL, 1059 1.1 alc "powerMeasQ = 0x%08x\n", powerMeasQ); 1060 1.1 alc HALDEBUG(ah, HAL_DEBUG_PERCAL, 1061 1.1 alc "iqCorrMeas = 0x%08x\n", iqCorrMeas); 1062 1.1 alc HALDEBUG(ah, HAL_DEBUG_PERCAL, 1063 1.1 alc "iCoff = %d\n", iCoff); 1064 1.1 alc HALDEBUG(ah, HAL_DEBUG_PERCAL, 1065 1.1 alc "qCoff = %d\n", qCoff); 1066 1.1 alc 1067 1.1 alc /* Write values and enable correction */ 1068 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, 1069 1.1 alc AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff); 1070 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, 1071 1.1 alc AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff); 1072 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, 1073 1.1 alc AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); 1074 1.1 alc 1075 1.1 alc ahp->ah_bIQCalibration = IQ_CAL_DONE; 1076 1.1 alc ichan->iqCalValid = AH_TRUE; 1077 1.1 alc ichan->iCoff = iCoff; 1078 1.1 alc ichan->qCoff = qCoff; 1079 1.1 alc } 1080 1.1 alc } else if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration == IQ_CAL_DONE && 1081 1.1 alc !ichan->iqCalValid) { 1082 1.1 alc /* 1083 1.1 alc * Start IQ calibration if configured channel has changed. 1084 1.1 alc * Use a magic number of 15 based on default value. 1085 1.1 alc */ 1086 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, 1087 1.1 alc AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, 1088 1.1 alc INIT_IQCAL_LOG_COUNT_MAX); 1089 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, 1090 1.1 alc AR_PHY_TIMING_CTRL4_DO_IQCAL); 1091 1.1 alc ahp->ah_bIQCalibration = IQ_CAL_RUNNING; 1092 1.1 alc } 1093 1.1 alc /* XXX EAR */ 1094 1.1 alc 1095 1.1 alc if (longCal) { 1096 1.1 alc /* Check noise floor results */ 1097 1.1 alc ar5212GetNf(ah, ichan); 1098 1.1 alc 1099 1.1 alc if ((ichan->channelFlags & CHANNEL_CW_INT) == 0) { 1100 1.1 alc /* Perform cal for 5Ghz channels and any OFDM on 5112 */ 1101 1.1 alc if (IS_CHAN_5GHZ(chan) || 1102 1.1 alc (IS_RAD5112(ah) && IS_CHAN_OFDM(chan))) 1103 1.1 alc ar5212RequestRfgain(ah); 1104 1.1 alc } else { 1105 1.1 alc /* report up and clear internal state */ 1106 1.1 alc chan->channelFlags |= CHANNEL_CW_INT; 1107 1.1 alc ichan->channelFlags &= ~CHANNEL_CW_INT; 1108 1.1 alc } 1109 1.1 alc } 1110 1.1 alc RESTORE_CCK(ah, ichan, ichan_isBmode); 1111 1.1 alc RESTORE_CCK(ah, chan, isBmode); 1112 1.1 alc 1113 1.1 alc return AH_TRUE; 1114 1.1 alc #undef IQ_CAL_TRIES 1115 1.1 alc } 1116 1.1 alc 1117 1.1 alc HAL_BOOL 1118 1.1 alc ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone) 1119 1.1 alc { 1120 1.1 alc return ar5212PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone); 1121 1.1 alc } 1122 1.1 alc 1123 1.1 alc HAL_BOOL 1124 1.1 alc ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan) 1125 1.1 alc { 1126 1.1 alc /* XXX */ 1127 1.1 alc return AH_TRUE; 1128 1.1 alc } 1129 1.1 alc 1130 1.1 alc /* 1131 1.1 alc * Write the given reset bit mask into the reset register 1132 1.1 alc */ 1133 1.1 alc static HAL_BOOL 1134 1.1 alc ar5212SetResetReg(struct ath_hal *ah, uint32_t resetMask) 1135 1.1 alc { 1136 1.1 alc uint32_t mask = resetMask ? resetMask : ~0; 1137 1.1 alc HAL_BOOL rt; 1138 1.1 alc 1139 1.1 alc /* XXX ar5212MacStop & co. */ 1140 1.1 alc 1141 1.3 jmcneill if (AH_PRIVATE(ah)->ah_ispcie) { 1142 1.1 alc resetMask &= ~AR_RC_PCI; 1143 1.1 alc } 1144 1.1 alc 1145 1.1 alc (void) OS_REG_READ(ah, AR_RXDP);/* flush any pending MMR writes */ 1146 1.1 alc OS_REG_WRITE(ah, AR_RC, resetMask); 1147 1.1 alc OS_DELAY(15); /* need to wait at least 128 clocks 1148 1.1 alc when reseting PCI before read */ 1149 1.1 alc mask &= (AR_RC_MAC | AR_RC_BB); 1150 1.1 alc resetMask &= (AR_RC_MAC | AR_RC_BB); 1151 1.1 alc rt = ath_hal_wait(ah, AR_RC, mask, resetMask); 1152 1.1 alc if ((resetMask & AR_RC_MAC) == 0) { 1153 1.1 alc if (isBigEndian()) { 1154 1.1 alc /* 1155 1.1 alc * Set CFG, little-endian for register 1156 1.1 alc * and descriptor accesses. 1157 1.1 alc */ 1158 1.1 alc mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG; 1159 1.1 alc #ifndef AH_NEED_DESC_SWAP 1160 1.1 alc mask |= AR_CFG_SWTD; 1161 1.1 alc #endif 1162 1.1 alc OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask)); 1163 1.1 alc } else 1164 1.1 alc OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS); 1165 1.1 alc if (ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 1166 1.1 alc (void) OS_REG_READ(ah, AR_ISR_RAC); 1167 1.1 alc } 1168 1.1 alc 1169 1.1 alc /* track PHY power state so we don't try to r/w BB registers */ 1170 1.1 alc AH5212(ah)->ah_phyPowerOn = ((resetMask & AR_RC_BB) == 0); 1171 1.1 alc return rt; 1172 1.1 alc } 1173 1.1 alc 1174 1.1 alc int16_t 1175 1.1 alc ar5212GetNoiseFloor(struct ath_hal *ah) 1176 1.1 alc { 1177 1.1 alc int16_t nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff; 1178 1.1 alc if (nf & 0x100) 1179 1.1 alc nf = 0 - ((nf ^ 0x1ff) + 1); 1180 1.1 alc return nf; 1181 1.1 alc } 1182 1.1 alc 1183 1.1 alc static HAL_BOOL 1184 1.1 alc getNoiseFloorThresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan, 1185 1.1 alc int16_t *nft) 1186 1.1 alc { 1187 1.1 alc const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1188 1.1 alc 1189 1.1 alc HALASSERT(ah->ah_magic == AR5212_MAGIC); 1190 1.1 alc 1191 1.1 alc switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) { 1192 1.1 alc case CHANNEL_A: 1193 1.1 alc *nft = ee->ee_noiseFloorThresh[headerInfo11A]; 1194 1.1 alc break; 1195 1.1 alc case CHANNEL_B: 1196 1.1 alc *nft = ee->ee_noiseFloorThresh[headerInfo11B]; 1197 1.1 alc break; 1198 1.1 alc case CHANNEL_PUREG: 1199 1.1 alc *nft = ee->ee_noiseFloorThresh[headerInfo11G]; 1200 1.1 alc break; 1201 1.1 alc default: 1202 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n", 1203 1.1 alc __func__, chan->channelFlags); 1204 1.1 alc return AH_FALSE; 1205 1.1 alc } 1206 1.1 alc return AH_TRUE; 1207 1.1 alc } 1208 1.1 alc 1209 1.1 alc /* 1210 1.1 alc * Setup the noise floor cal history buffer. 1211 1.1 alc */ 1212 1.1 alc void 1213 1.1 alc ar5212InitNfCalHistBuffer(struct ath_hal *ah) 1214 1.1 alc { 1215 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 1216 1.1 alc int i; 1217 1.1 alc 1218 1.1 alc ahp->ah_nfCalHist.first_run = 1; 1219 1.1 alc ahp->ah_nfCalHist.currIndex = 0; 1220 1.1 alc ahp->ah_nfCalHist.privNF = AR5212_CCA_MAX_GOOD_VALUE; 1221 1.1 alc ahp->ah_nfCalHist.invalidNFcount = AR512_NF_CAL_HIST_MAX; 1222 1.1 alc for (i = 0; i < AR512_NF_CAL_HIST_MAX; i ++) 1223 1.1 alc ahp->ah_nfCalHist.nfCalBuffer[i] = AR5212_CCA_MAX_GOOD_VALUE; 1224 1.1 alc } 1225 1.1 alc 1226 1.1 alc /* 1227 1.1 alc * Add a noise floor value to the ring buffer. 1228 1.1 alc */ 1229 1.1 alc static __inline void 1230 1.1 alc updateNFHistBuff(struct ar5212NfCalHist *h, int16_t nf) 1231 1.1 alc { 1232 1.1 alc h->nfCalBuffer[h->currIndex] = nf; 1233 1.1 alc if (++h->currIndex >= AR512_NF_CAL_HIST_MAX) 1234 1.1 alc h->currIndex = 0; 1235 1.1 alc } 1236 1.1 alc 1237 1.1 alc /* 1238 1.1 alc * Return the median noise floor value in the ring buffer. 1239 1.1 alc */ 1240 1.1 alc int16_t 1241 1.1 alc ar5212GetNfHistMid(const int16_t calData[AR512_NF_CAL_HIST_MAX]) 1242 1.1 alc { 1243 1.1 alc int16_t sort[AR512_NF_CAL_HIST_MAX]; 1244 1.1 alc int i, j; 1245 1.1 alc 1246 1.1 alc OS_MEMCPY(sort, calData, AR512_NF_CAL_HIST_MAX*sizeof(int16_t)); 1247 1.1 alc for (i = 0; i < AR512_NF_CAL_HIST_MAX-1; i ++) { 1248 1.1 alc for (j = 1; j < AR512_NF_CAL_HIST_MAX-i; j ++) { 1249 1.1 alc if (sort[j] > sort[j-1]) { 1250 1.1 alc int16_t nf = sort[j]; 1251 1.1 alc sort[j] = sort[j-1]; 1252 1.1 alc sort[j-1] = nf; 1253 1.1 alc } 1254 1.1 alc } 1255 1.1 alc } 1256 1.1 alc return sort[(AR512_NF_CAL_HIST_MAX-1)>>1]; 1257 1.1 alc } 1258 1.1 alc 1259 1.1 alc /* 1260 1.1 alc * Read the NF and check it against the noise floor threshhold 1261 1.1 alc */ 1262 1.1 alc int16_t 1263 1.1 alc ar5212GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 1264 1.1 alc { 1265 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 1266 1.1 alc struct ar5212NfCalHist *h = &ahp->ah_nfCalHist; 1267 1.1 alc int16_t nf, nfThresh; 1268 1.1 alc int32_t val; 1269 1.1 alc 1270 1.1 alc if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { 1271 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1272 1.1 alc "%s: NF did not complete in calibration window\n", __func__); 1273 1.1 alc chan->rawNoiseFloor = h->privNF; /* most recent value */ 1274 1.1 alc return chan->rawNoiseFloor; 1275 1.1 alc } 1276 1.1 alc 1277 1.1 alc /* 1278 1.1 alc * Finished NF cal, check against threshold. 1279 1.1 alc */ 1280 1.1 alc nf = ar5212GetNoiseFloor(ah); 1281 1.1 alc if (getNoiseFloorThresh(ah, chan, &nfThresh)) { 1282 1.1 alc if (nf > nfThresh) { 1283 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1284 1.1 alc "%s: noise floor failed detected; detected %u, " 1285 1.1 alc "threshold %u\n", __func__, nf, nfThresh); 1286 1.1 alc /* 1287 1.1 alc * NB: Don't discriminate 2.4 vs 5Ghz, if this 1288 1.1 alc * happens it indicates a problem regardless 1289 1.1 alc * of the band. 1290 1.1 alc */ 1291 1.1 alc chan->channelFlags |= CHANNEL_CW_INT; 1292 1.1 alc nf = 0; 1293 1.1 alc } 1294 1.1 alc } else 1295 1.1 alc nf = 0; 1296 1.1 alc 1297 1.1 alc /* 1298 1.1 alc * Pass through histogram and write median value as 1299 1.1 alc * calculated from the accrued window. We require a 1300 1.1 alc * full window of in-range values to be seen before we 1301 1.1 alc * start using the history. 1302 1.1 alc */ 1303 1.1 alc updateNFHistBuff(h, nf); 1304 1.1 alc if (h->first_run) { 1305 1.1 alc if (nf < AR5212_CCA_MIN_BAD_VALUE || 1306 1.1 alc nf > AR5212_CCA_MAX_HIGH_VALUE) { 1307 1.1 alc nf = AR5212_CCA_MAX_GOOD_VALUE; 1308 1.1 alc h->invalidNFcount = AR512_NF_CAL_HIST_MAX; 1309 1.1 alc } else if (--(h->invalidNFcount) == 0) { 1310 1.1 alc h->first_run = 0; 1311 1.1 alc h->privNF = nf = ar5212GetNfHistMid(h->nfCalBuffer); 1312 1.1 alc } else { 1313 1.1 alc nf = AR5212_CCA_MAX_GOOD_VALUE; 1314 1.1 alc } 1315 1.1 alc } else { 1316 1.1 alc h->privNF = nf = ar5212GetNfHistMid(h->nfCalBuffer); 1317 1.1 alc } 1318 1.1 alc 1319 1.1 alc val = OS_REG_READ(ah, AR_PHY(25)); 1320 1.1 alc val &= 0xFFFFFE00; 1321 1.1 alc val |= (((uint32_t)nf << 1) & 0x1FF); 1322 1.1 alc OS_REG_WRITE(ah, AR_PHY(25), val); 1323 1.1 alc OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF); 1324 1.1 alc OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF); 1325 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 1326 1.1 alc 1327 1.1 alc if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF, 0)) { 1328 1.1 alc #ifdef AH_DEBUG 1329 1.1 alc ath_hal_printf(ah, "%s: AGC not ready AGC_CONTROL 0x%x\n", 1330 1.1 alc __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL)); 1331 1.1 alc #endif 1332 1.1 alc } 1333 1.1 alc 1334 1.1 alc /* 1335 1.1 alc * Now load a high maxCCAPower value again so that we're 1336 1.1 alc * not capped by the median we just loaded 1337 1.1 alc */ 1338 1.1 alc val &= 0xFFFFFE00; 1339 1.1 alc val |= (((uint32_t)(-50) << 1) & 0x1FF); 1340 1.1 alc OS_REG_WRITE(ah, AR_PHY(25), val); 1341 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF); 1342 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF); 1343 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 1344 1.1 alc 1345 1.1 alc return (chan->rawNoiseFloor = nf); 1346 1.1 alc } 1347 1.1 alc 1348 1.1 alc /* 1349 1.1 alc * Set up compression configuration registers 1350 1.1 alc */ 1351 1.1 alc void 1352 1.1 alc ar5212SetCompRegs(struct ath_hal *ah) 1353 1.1 alc { 1354 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 1355 1.1 alc int i; 1356 1.1 alc 1357 1.1 alc /* Check if h/w supports compression */ 1358 1.1 alc if (!AH_PRIVATE(ah)->ah_caps.halCompressSupport) 1359 1.1 alc return; 1360 1.1 alc 1361 1.1 alc OS_REG_WRITE(ah, AR_DCCFG, 1); 1362 1.1 alc 1363 1.1 alc OS_REG_WRITE(ah, AR_CCFG, 1364 1.1 alc (AR_COMPRESSION_WINDOW_SIZE >> 8) & AR_CCFG_WIN_M); 1365 1.1 alc 1366 1.1 alc OS_REG_WRITE(ah, AR_CCFG, 1367 1.1 alc OS_REG_READ(ah, AR_CCFG) | AR_CCFG_MIB_INT_EN); 1368 1.1 alc OS_REG_WRITE(ah, AR_CCUCFG, 1369 1.1 alc AR_CCUCFG_RESET_VAL | AR_CCUCFG_CATCHUP_EN); 1370 1.1 alc 1371 1.1 alc OS_REG_WRITE(ah, AR_CPCOVF, 0); 1372 1.1 alc 1373 1.1 alc /* reset decompression mask */ 1374 1.1 alc for (i = 0; i < HAL_DECOMP_MASK_SIZE; i++) { 1375 1.1 alc OS_REG_WRITE(ah, AR_DCM_A, i); 1376 1.1 alc OS_REG_WRITE(ah, AR_DCM_D, ahp->ah_decompMask[i]); 1377 1.1 alc } 1378 1.1 alc } 1379 1.1 alc 1380 1.1 alc HAL_BOOL 1381 1.1 alc ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings, 1382 1.1 alc const HAL_CHANNEL_INTERNAL *chan) 1383 1.1 alc { 1384 1.1 alc #define ANT_SWITCH_TABLE1 AR_PHY(88) 1385 1.1 alc #define ANT_SWITCH_TABLE2 AR_PHY(89) 1386 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 1387 1.1 alc const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1388 1.1 alc uint32_t antSwitchA, antSwitchB; 1389 1.1 alc int ix; 1390 1.1 alc HAL_BOOL isBmode = AH_FALSE; 1391 1.1 alc /* NB: need local copy for SAVE/RESTORE 'cuz chan is const */ 1392 1.1 alc HAL_CHANNEL_INTERNAL ichan = *chan; 1393 1.1 alc 1394 1.1 alc HALASSERT(ah->ah_magic == AR5212_MAGIC); 1395 1.1 alc HALASSERT(ahp->ah_phyPowerOn); 1396 1.1 alc 1397 1.1 alc SAVE_CCK(ah, &ichan, isBmode); 1398 1.1 alc switch (ichan.channelFlags & CHANNEL_ALL_NOTURBO) { 1399 1.1 alc case CHANNEL_A: ix = 0; break; 1400 1.1 alc case CHANNEL_B: ix = 1; break; 1401 1.1 alc case CHANNEL_PUREG: ix = 2; break; 1402 1.1 alc default: 1403 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n", 1404 1.1 alc __func__, ichan.channelFlags); 1405 1.1 alc RESTORE_CCK(ah, &ichan, isBmode); 1406 1.1 alc return AH_FALSE; 1407 1.1 alc } 1408 1.1 alc RESTORE_CCK(ah, &ichan, isBmode); 1409 1.1 alc 1410 1.1 alc antSwitchA = ee->ee_antennaControl[1][ix] 1411 1.1 alc | (ee->ee_antennaControl[2][ix] << 6) 1412 1.1 alc | (ee->ee_antennaControl[3][ix] << 12) 1413 1.1 alc | (ee->ee_antennaControl[4][ix] << 18) 1414 1.1 alc | (ee->ee_antennaControl[5][ix] << 24) 1415 1.1 alc ; 1416 1.1 alc antSwitchB = ee->ee_antennaControl[6][ix] 1417 1.1 alc | (ee->ee_antennaControl[7][ix] << 6) 1418 1.1 alc | (ee->ee_antennaControl[8][ix] << 12) 1419 1.1 alc | (ee->ee_antennaControl[9][ix] << 18) 1420 1.1 alc | (ee->ee_antennaControl[10][ix] << 24) 1421 1.1 alc ; 1422 1.1 alc /* 1423 1.1 alc * For fixed antenna, give the same setting for both switch banks 1424 1.1 alc */ 1425 1.1 alc switch (settings) { 1426 1.1 alc case HAL_ANT_FIXED_A: 1427 1.1 alc antSwitchB = antSwitchA; 1428 1.1 alc break; 1429 1.1 alc case HAL_ANT_FIXED_B: 1430 1.1 alc antSwitchA = antSwitchB; 1431 1.1 alc break; 1432 1.1 alc case HAL_ANT_VARIABLE: 1433 1.1 alc break; 1434 1.1 alc default: 1435 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad antenna setting %u\n", 1436 1.1 alc __func__, settings); 1437 1.1 alc return AH_FALSE; 1438 1.1 alc } 1439 1.1 alc if (antSwitchB == antSwitchA) { 1440 1.1 alc HALDEBUG(ah, HAL_DEBUG_RFPARAM, 1441 1.1 alc "%s: Setting fast diversity off.\n", __func__); 1442 1.1 alc OS_REG_CLR_BIT(ah,AR_PHY_CCK_DETECT, 1443 1.1 alc AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 1444 1.1 alc ahp->ah_diversity = AH_FALSE; 1445 1.1 alc } else { 1446 1.1 alc HALDEBUG(ah, HAL_DEBUG_RFPARAM, 1447 1.1 alc "%s: Setting fast diversity on.\n", __func__); 1448 1.1 alc OS_REG_SET_BIT(ah,AR_PHY_CCK_DETECT, 1449 1.1 alc AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 1450 1.1 alc ahp->ah_diversity = AH_TRUE; 1451 1.1 alc } 1452 1.1 alc ahp->ah_antControl = settings; 1453 1.1 alc 1454 1.1 alc OS_REG_WRITE(ah, ANT_SWITCH_TABLE1, antSwitchA); 1455 1.1 alc OS_REG_WRITE(ah, ANT_SWITCH_TABLE2, antSwitchB); 1456 1.1 alc 1457 1.1 alc return AH_TRUE; 1458 1.1 alc #undef ANT_SWITCH_TABLE2 1459 1.1 alc #undef ANT_SWITCH_TABLE1 1460 1.1 alc } 1461 1.1 alc 1462 1.1 alc HAL_BOOL 1463 1.1 alc ar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan) 1464 1.1 alc { 1465 1.1 alc uint32_t clockFreq = 1466 1.1 alc ((IS_5413(ah) || IS_RAD5112_ANY(ah) || IS_2417(ah)) ? 40 : 32); 1467 1.1 alc return ( ((chan->channel % clockFreq) != 0) 1468 1.1 alc && (((chan->channel % clockFreq) < 10) 1469 1.1 alc || (((chan->channel) % clockFreq) > 22)) ); 1470 1.1 alc } 1471 1.1 alc 1472 1.1 alc /* 1473 1.1 alc * Read EEPROM header info and program the device for correct operation 1474 1.1 alc * given the channel value. 1475 1.1 alc */ 1476 1.1 alc HAL_BOOL 1477 1.1 alc ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 1478 1.1 alc { 1479 1.1 alc #define NO_FALSE_DETECT_BACKOFF 2 1480 1.1 alc #define CB22_FALSE_DETECT_BACKOFF 6 1481 1.1 alc #define AR_PHY_BIS(_ah, _reg, _mask, _val) \ 1482 1.1 alc OS_REG_WRITE(_ah, AR_PHY(_reg), \ 1483 1.1 alc (OS_REG_READ(_ah, AR_PHY(_reg)) & _mask) | (_val)); 1484 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 1485 1.1 alc const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1486 1.1 alc int arrayMode, falseDectectBackoff; 1487 1.1 alc int is2GHz = IS_CHAN_2GHZ(chan); 1488 1.1 alc int8_t adcDesiredSize, pgaDesiredSize; 1489 1.1 alc uint16_t switchSettling, txrxAtten, rxtxMargin; 1490 1.1 alc int iCoff, qCoff; 1491 1.1 alc 1492 1.1 alc HALASSERT(ah->ah_magic == AR5212_MAGIC); 1493 1.1 alc 1494 1.1 alc switch (chan->channelFlags & CHANNEL_ALL) { 1495 1.1 alc case CHANNEL_A: 1496 1.1 alc case CHANNEL_T: 1497 1.1 alc arrayMode = headerInfo11A; 1498 1.1 alc if (!IS_RAD5112_ANY(ah) && !IS_2413(ah) && !IS_5413(ah)) 1499 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, 1500 1.1 alc AR_PHY_FRAME_CTL_TX_CLIP, 1501 1.1 alc ahp->ah_gainValues.currStep->paramVal[GP_TXCLIP]); 1502 1.1 alc break; 1503 1.1 alc case CHANNEL_B: 1504 1.1 alc arrayMode = headerInfo11B; 1505 1.1 alc break; 1506 1.1 alc case CHANNEL_G: 1507 1.1 alc case CHANNEL_108G: 1508 1.1 alc arrayMode = headerInfo11G; 1509 1.1 alc break; 1510 1.1 alc default: 1511 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n", 1512 1.1 alc __func__, chan->channelFlags); 1513 1.1 alc return AH_FALSE; 1514 1.1 alc } 1515 1.1 alc 1516 1.1 alc /* Set the antenna register(s) correctly for the chip revision */ 1517 1.1 alc AR_PHY_BIS(ah, 68, 0xFFFFFC06, 1518 1.1 alc (ee->ee_antennaControl[0][arrayMode] << 4) | 0x1); 1519 1.1 alc 1520 1.1 alc ar5212SetAntennaSwitchInternal(ah, ahp->ah_antControl, chan); 1521 1.1 alc 1522 1.1 alc /* Set the Noise Floor Thresh on ar5211 devices */ 1523 1.1 alc OS_REG_WRITE(ah, AR_PHY(90), 1524 1.1 alc (ee->ee_noiseFloorThresh[arrayMode] & 0x1FF) 1525 1.1 alc | (1 << 9)); 1526 1.1 alc 1527 1.1 alc if (ee->ee_version >= AR_EEPROM_VER5_0 && IS_CHAN_TURBO(chan)) { 1528 1.1 alc switchSettling = ee->ee_switchSettlingTurbo[is2GHz]; 1529 1.1 alc adcDesiredSize = ee->ee_adcDesiredSizeTurbo[is2GHz]; 1530 1.1 alc pgaDesiredSize = ee->ee_pgaDesiredSizeTurbo[is2GHz]; 1531 1.1 alc txrxAtten = ee->ee_txrxAttenTurbo[is2GHz]; 1532 1.1 alc rxtxMargin = ee->ee_rxtxMarginTurbo[is2GHz]; 1533 1.1 alc } else { 1534 1.1 alc switchSettling = ee->ee_switchSettling[arrayMode]; 1535 1.1 alc adcDesiredSize = ee->ee_adcDesiredSize[arrayMode]; 1536 1.1 alc pgaDesiredSize = ee->ee_pgaDesiredSize[is2GHz]; 1537 1.1 alc txrxAtten = ee->ee_txrxAtten[is2GHz]; 1538 1.1 alc rxtxMargin = ee->ee_rxtxMargin[is2GHz]; 1539 1.1 alc } 1540 1.1 alc 1541 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1542 1.1 alc AR_PHY_SETTLING_SWITCH, switchSettling); 1543 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 1544 1.1 alc AR_PHY_DESIRED_SZ_ADC, adcDesiredSize); 1545 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 1546 1.1 alc AR_PHY_DESIRED_SZ_PGA, pgaDesiredSize); 1547 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN, 1548 1.1 alc AR_PHY_RXGAIN_TXRX_ATTEN, txrxAtten); 1549 1.1 alc OS_REG_WRITE(ah, AR_PHY(13), 1550 1.1 alc (ee->ee_txEndToXPAOff[arrayMode] << 24) 1551 1.1 alc | (ee->ee_txEndToXPAOff[arrayMode] << 16) 1552 1.1 alc | (ee->ee_txFrameToXPAOn[arrayMode] << 8) 1553 1.1 alc | ee->ee_txFrameToXPAOn[arrayMode]); 1554 1.1 alc AR_PHY_BIS(ah, 10, 0xFFFF00FF, 1555 1.1 alc ee->ee_txEndToXLNAOn[arrayMode] << 8); 1556 1.1 alc AR_PHY_BIS(ah, 25, 0xFFF80FFF, 1557 1.1 alc (ee->ee_thresh62[arrayMode] << 12) & 0x7F000); 1558 1.1 alc 1559 1.1 alc /* 1560 1.1 alc * False detect backoff - suspected 32 MHz spur causes false 1561 1.1 alc * detects in OFDM, causing Tx Hangs. Decrease weak signal 1562 1.1 alc * sensitivity for this card. 1563 1.1 alc */ 1564 1.1 alc falseDectectBackoff = NO_FALSE_DETECT_BACKOFF; 1565 1.1 alc if (ee->ee_version < AR_EEPROM_VER3_3) { 1566 1.1 alc /* XXX magic number */ 1567 1.1 alc if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 && 1568 1.1 alc IS_CHAN_OFDM(chan)) 1569 1.1 alc falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF; 1570 1.1 alc } else { 1571 1.1 alc if (ar5212IsSpurChannel(ah, (HAL_CHANNEL *)chan)) { 1572 1.1 alc falseDectectBackoff += ee->ee_falseDetectBackoff[arrayMode]; 1573 1.1 alc } 1574 1.1 alc } 1575 1.1 alc AR_PHY_BIS(ah, 73, 0xFFFFFF01, (falseDectectBackoff << 1) & 0xFE); 1576 1.1 alc 1577 1.1 alc if (chan->iqCalValid) { 1578 1.1 alc iCoff = chan->iCoff; 1579 1.1 alc qCoff = chan->qCoff; 1580 1.1 alc } else { 1581 1.1 alc iCoff = ee->ee_iqCalI[is2GHz]; 1582 1.1 alc qCoff = ee->ee_iqCalQ[is2GHz]; 1583 1.1 alc } 1584 1.1 alc 1585 1.1 alc /* write previous IQ results */ 1586 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, 1587 1.1 alc AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff); 1588 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, 1589 1.1 alc AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff); 1590 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, 1591 1.1 alc AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); 1592 1.1 alc 1593 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_1) { 1594 1.1 alc if (!IS_CHAN_108G(chan) || ee->ee_version >= AR_EEPROM_VER5_0) 1595 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 1596 1.1 alc AR_PHY_GAIN_2GHZ_RXTX_MARGIN, rxtxMargin); 1597 1.1 alc } 1598 1.1 alc if (ee->ee_version >= AR_EEPROM_VER5_1) { 1599 1.1 alc /* for now always disabled */ 1600 1.1 alc OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_ENABLE, 0); 1601 1.1 alc } 1602 1.1 alc 1603 1.1 alc return AH_TRUE; 1604 1.1 alc #undef AR_PHY_BIS 1605 1.1 alc #undef NO_FALSE_DETECT_BACKOFF 1606 1.1 alc #undef CB22_FALSE_DETECT_BACKOFF 1607 1.1 alc } 1608 1.1 alc 1609 1.1 alc /* 1610 1.1 alc * Apply Spur Immunity to Boards that require it. 1611 1.1 alc * Applies only to OFDM RX operation. 1612 1.1 alc */ 1613 1.1 alc 1614 1.1 alc void 1615 1.1 alc ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan) 1616 1.1 alc { 1617 1.1 alc uint32_t pilotMask[2] = {0, 0}, binMagMask[4] = {0, 0, 0 , 0}; 1618 1.1 alc uint16_t i, finalSpur, curChanAsSpur, binWidth = 0, spurDetectWidth, spurChan; 1619 1.1 alc int32_t spurDeltaPhase = 0, spurFreqSd = 0, spurOffset, binOffsetNumT16, curBinOffset; 1620 1.1 alc int16_t numBinOffsets; 1621 1.1 alc static const uint16_t magMapFor4[4] = {1, 2, 2, 1}; 1622 1.1 alc static const uint16_t magMapFor3[3] = {1, 2, 1}; 1623 1.1 alc const uint16_t *pMagMap; 1624 1.1 alc HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan); 1625 1.1 alc uint32_t val; 1626 1.1 alc 1627 1.1 alc #define CHAN_TO_SPUR(_f, _freq) ( ((_freq) - ((_f) ? 2300 : 4900)) * 10 ) 1628 1.1 alc if (IS_2417(ah)) { 1629 1.1 alc HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: no spur mitigation\n", 1630 1.1 alc __func__); 1631 1.1 alc return; 1632 1.1 alc } 1633 1.1 alc 1634 1.1 alc curChanAsSpur = CHAN_TO_SPUR(is2GHz, ichan->channel); 1635 1.1 alc 1636 1.1 alc if (ichan->mainSpur) { 1637 1.1 alc /* Pull out the saved spur value */ 1638 1.1 alc finalSpur = ichan->mainSpur; 1639 1.1 alc } else { 1640 1.1 alc /* 1641 1.1 alc * Check if spur immunity should be performed for this channel 1642 1.1 alc * Should only be performed once per channel and then saved 1643 1.1 alc */ 1644 1.1 alc finalSpur = AR_NO_SPUR; 1645 1.1 alc spurDetectWidth = HAL_SPUR_CHAN_WIDTH; 1646 1.1 alc if (IS_CHAN_TURBO(ichan)) 1647 1.1 alc spurDetectWidth *= 2; 1648 1.1 alc 1649 1.1 alc /* Decide if any spur affects the current channel */ 1650 1.1 alc for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 1651 1.1 alc spurChan = ath_hal_getSpurChan(ah, i, is2GHz); 1652 1.1 alc if (spurChan == AR_NO_SPUR) { 1653 1.1 alc break; 1654 1.1 alc } 1655 1.1 alc if ((curChanAsSpur - spurDetectWidth <= (spurChan & HAL_SPUR_VAL_MASK)) && 1656 1.1 alc (curChanAsSpur + spurDetectWidth >= (spurChan & HAL_SPUR_VAL_MASK))) { 1657 1.1 alc finalSpur = spurChan & HAL_SPUR_VAL_MASK; 1658 1.1 alc break; 1659 1.1 alc } 1660 1.1 alc } 1661 1.1 alc /* Save detected spur (or no spur) for this channel */ 1662 1.1 alc ichan->mainSpur = finalSpur; 1663 1.1 alc } 1664 1.1 alc 1665 1.1 alc /* Write spur immunity data */ 1666 1.1 alc if (finalSpur == AR_NO_SPUR) { 1667 1.1 alc /* Disable Spur Immunity Regs if they appear set */ 1668 1.1 alc if (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER) { 1669 1.1 alc /* Clear Spur Delta Phase, Spur Freq, and enable bits */ 1670 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0); 1671 1.1 alc val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4); 1672 1.1 alc val &= ~(AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 1673 1.1 alc AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 1674 1.1 alc AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 1675 1.1 alc OS_REG_WRITE(ah, AR_PHY_MASK_CTL, val); 1676 1.1 alc OS_REG_WRITE(ah, AR_PHY_TIMING11, 0); 1677 1.1 alc 1678 1.1 alc /* Clear pilot masks */ 1679 1.1 alc OS_REG_WRITE(ah, AR_PHY_TIMING7, 0); 1680 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, 0); 1681 1.1 alc OS_REG_WRITE(ah, AR_PHY_TIMING9, 0); 1682 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, 0); 1683 1.1 alc 1684 1.1 alc /* Clear magnitude masks */ 1685 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, 0); 1686 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, 0); 1687 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, 0); 1688 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, 0); 1689 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, 0); 1690 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, 0); 1691 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, 0); 1692 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, 0); 1693 1.1 alc } 1694 1.1 alc } else { 1695 1.1 alc spurOffset = finalSpur - curChanAsSpur; 1696 1.1 alc /* 1697 1.1 alc * Spur calculations: 1698 1.1 alc * spurDeltaPhase is (spurOffsetIn100KHz / chipFrequencyIn100KHz) << 21 1699 1.1 alc * spurFreqSd is (spurOffsetIn100KHz / sampleFrequencyIn100KHz) << 11 1700 1.1 alc */ 1701 1.1 alc switch (ichan->channelFlags & CHANNEL_ALL) { 1702 1.1 alc case CHANNEL_A: /* Chip Frequency & sampleFrequency are 40 MHz */ 1703 1.1 alc spurDeltaPhase = (spurOffset << 17) / 25; 1704 1.1 alc spurFreqSd = spurDeltaPhase >> 10; 1705 1.1 alc binWidth = HAL_BIN_WIDTH_BASE_100HZ; 1706 1.1 alc break; 1707 1.1 alc case CHANNEL_G: /* Chip Frequency is 44MHz, sampleFrequency is 40 MHz */ 1708 1.1 alc spurFreqSd = (spurOffset << 8) / 55; 1709 1.1 alc spurDeltaPhase = (spurOffset << 17) / 25; 1710 1.1 alc binWidth = HAL_BIN_WIDTH_BASE_100HZ; 1711 1.1 alc break; 1712 1.1 alc case CHANNEL_T: /* Chip Frequency & sampleFrequency are 80 MHz */ 1713 1.1 alc case CHANNEL_108G: 1714 1.1 alc spurDeltaPhase = (spurOffset << 16) / 25; 1715 1.1 alc spurFreqSd = spurDeltaPhase >> 10; 1716 1.1 alc binWidth = HAL_BIN_WIDTH_TURBO_100HZ; 1717 1.1 alc break; 1718 1.1 alc } 1719 1.1 alc 1720 1.1 alc /* Compute Pilot Mask */ 1721 1.1 alc binOffsetNumT16 = ((spurOffset * 1000) << 4) / binWidth; 1722 1.1 alc /* The spur is on a bin if it's remainder at times 16 is 0 */ 1723 1.1 alc if (binOffsetNumT16 & 0xF) { 1724 1.1 alc numBinOffsets = 4; 1725 1.1 alc pMagMap = magMapFor4; 1726 1.1 alc } else { 1727 1.1 alc numBinOffsets = 3; 1728 1.1 alc pMagMap = magMapFor3; 1729 1.1 alc } 1730 1.1 alc for (i = 0; i < numBinOffsets; i++) { 1731 1.1 alc if ((binOffsetNumT16 >> 4) > HAL_MAX_BINS_ALLOWED) { 1732 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1733 1.1 alc "Too man bins in spur mitigation\n"); 1734 1.1 alc return; 1735 1.1 alc } 1736 1.1 alc 1737 1.1 alc /* Get Pilot Mask values */ 1738 1.1 alc curBinOffset = (binOffsetNumT16 >> 4) + i + 25; 1739 1.1 alc if ((curBinOffset >= 0) && (curBinOffset <= 32)) { 1740 1.1 alc if (curBinOffset <= 25) 1741 1.1 alc pilotMask[0] |= 1 << curBinOffset; 1742 1.1 alc else if (curBinOffset >= 27) 1743 1.1 alc pilotMask[0] |= 1 << (curBinOffset - 1); 1744 1.1 alc } else if ((curBinOffset >= 33) && (curBinOffset <= 52)) 1745 1.1 alc pilotMask[1] |= 1 << (curBinOffset - 33); 1746 1.1 alc 1747 1.1 alc /* Get viterbi values */ 1748 1.1 alc if ((curBinOffset >= -1) && (curBinOffset <= 14)) 1749 1.1 alc binMagMask[0] |= pMagMap[i] << (curBinOffset + 1) * 2; 1750 1.1 alc else if ((curBinOffset >= 15) && (curBinOffset <= 30)) 1751 1.1 alc binMagMask[1] |= pMagMap[i] << (curBinOffset - 15) * 2; 1752 1.1 alc else if ((curBinOffset >= 31) && (curBinOffset <= 46)) 1753 1.1 alc binMagMask[2] |= pMagMap[i] << (curBinOffset -31) * 2; 1754 1.1 alc else if((curBinOffset >= 47) && (curBinOffset <= 53)) 1755 1.1 alc binMagMask[3] |= pMagMap[i] << (curBinOffset -47) * 2; 1756 1.1 alc } 1757 1.1 alc 1758 1.1 alc /* Write Spur Delta Phase, Spur Freq, and enable bits */ 1759 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0xFF); 1760 1.1 alc val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4); 1761 1.1 alc val |= (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 1762 1.1 alc AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 1763 1.1 alc AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 1764 1.1 alc OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4, val); 1765 1.1 alc OS_REG_WRITE(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_IN_AGC | 1766 1.1 alc SM(spurFreqSd, AR_PHY_TIMING11_SPUR_FREQ_SD) | 1767 1.1 alc SM(spurDeltaPhase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); 1768 1.1 alc 1769 1.1 alc /* Write pilot masks */ 1770 1.1 alc OS_REG_WRITE(ah, AR_PHY_TIMING7, pilotMask[0]); 1771 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, pilotMask[1]); 1772 1.1 alc OS_REG_WRITE(ah, AR_PHY_TIMING9, pilotMask[0]); 1773 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, pilotMask[1]); 1774 1.1 alc 1775 1.1 alc /* Write magnitude masks */ 1776 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, binMagMask[0]); 1777 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, binMagMask[1]); 1778 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, binMagMask[2]); 1779 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, binMagMask[3]); 1780 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, binMagMask[0]); 1781 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, binMagMask[1]); 1782 1.1 alc OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, binMagMask[2]); 1783 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, binMagMask[3]); 1784 1.1 alc } 1785 1.1 alc #undef CHAN_TO_SPUR 1786 1.1 alc } 1787 1.1 alc 1788 1.1 alc 1789 1.1 alc /* 1790 1.1 alc * Delta slope coefficient computation. 1791 1.1 alc * Required for OFDM operation. 1792 1.1 alc */ 1793 1.1 alc void 1794 1.1 alc ar5212SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL *chan) 1795 1.1 alc { 1796 1.1 alc #define COEF_SCALE_S 24 1797 1.1 alc #define INIT_CLOCKMHZSCALED 0x64000000 1798 1.1 alc unsigned long coef_scaled, coef_exp, coef_man, ds_coef_exp, ds_coef_man; 1799 1.1 alc unsigned long clockMhzScaled = INIT_CLOCKMHZSCALED; 1800 1.1 alc 1801 1.1 alc if (IS_CHAN_TURBO(chan)) 1802 1.1 alc clockMhzScaled *= 2; 1803 1.1 alc /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */ 1804 1.1 alc /* scale for selected channel bandwidth */ 1805 1.1 alc if (IS_CHAN_HALF_RATE(chan)) { 1806 1.1 alc clockMhzScaled = clockMhzScaled >> 1; 1807 1.1 alc } else if (IS_CHAN_QUARTER_RATE(chan)) { 1808 1.1 alc clockMhzScaled = clockMhzScaled >> 2; 1809 1.1 alc } 1810 1.1 alc 1811 1.1 alc /* 1812 1.1 alc * ALGO -> coef = 1e8/fcarrier*fclock/40; 1813 1.1 alc * scaled coef to provide precision for this floating calculation 1814 1.1 alc */ 1815 1.1 alc coef_scaled = clockMhzScaled / chan->channel; 1816 1.1 alc 1817 1.1 alc /* 1818 1.1 alc * ALGO -> coef_exp = 14-floor(log2(coef)); 1819 1.1 alc * floor(log2(x)) is the highest set bit position 1820 1.1 alc */ 1821 1.1 alc for (coef_exp = 31; coef_exp > 0; coef_exp--) 1822 1.1 alc if ((coef_scaled >> coef_exp) & 0x1) 1823 1.1 alc break; 1824 1.1 alc /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */ 1825 1.1 alc HALASSERT(coef_exp); 1826 1.1 alc coef_exp = 14 - (coef_exp - COEF_SCALE_S); 1827 1.1 alc 1828 1.1 alc /* 1829 1.1 alc * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5); 1830 1.1 alc * The coefficient is already shifted up for scaling 1831 1.1 alc */ 1832 1.1 alc coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); 1833 1.1 alc ds_coef_man = coef_man >> (COEF_SCALE_S - coef_exp); 1834 1.1 alc ds_coef_exp = coef_exp - 16; 1835 1.1 alc 1836 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 1837 1.1 alc AR_PHY_TIMING3_DSC_MAN, ds_coef_man); 1838 1.1 alc OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 1839 1.1 alc AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); 1840 1.1 alc #undef INIT_CLOCKMHZSCALED 1841 1.1 alc #undef COEF_SCALE_S 1842 1.1 alc } 1843 1.1 alc 1844 1.1 alc /* 1845 1.1 alc * Set a limit on the overall output power. Used for dynamic 1846 1.1 alc * transmit power control and the like. 1847 1.1 alc * 1848 1.1 alc * NB: limit is in units of 0.5 dbM. 1849 1.1 alc */ 1850 1.1 alc HAL_BOOL 1851 1.1 alc ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit) 1852 1.1 alc { 1853 1.1 alc uint16_t dummyXpdGains[2]; 1854 1.1 alc HAL_BOOL ret, isBmode = AH_FALSE; 1855 1.1 alc 1856 1.1 alc SAVE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode); 1857 1.1 alc AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); 1858 1.1 alc ret = ar5212SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan, 1859 1.1 alc dummyXpdGains); 1860 1.1 alc RESTORE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode); 1861 1.1 alc return ret; 1862 1.1 alc } 1863 1.1 alc 1864 1.1 alc /* 1865 1.1 alc * Set the transmit power in the baseband for the given 1866 1.1 alc * operating channel and mode. 1867 1.1 alc */ 1868 1.1 alc HAL_BOOL 1869 1.1 alc ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, 1870 1.1 alc uint16_t *rfXpdGain) 1871 1.1 alc { 1872 1.1 alc #define POW_OFDM(_r, _s) (((0 & 1)<< ((_s)+6)) | (((_r) & 0x3f) << (_s))) 1873 1.1 alc #define POW_CCK(_r, _s) (((_r) & 0x3f) << (_s)) 1874 1.1 alc #define N(a) (sizeof (a) / sizeof (a[0])) 1875 1.1 alc static const uint16_t tpcScaleReductionTable[5] = 1876 1.1 alc { 0, 3, 6, 9, MAX_RATE_POWER }; 1877 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 1878 1.1 alc const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1879 1.1 alc int16_t minPower, maxPower, tpcInDb, powerLimit; 1880 1.1 alc int i; 1881 1.1 alc 1882 1.1 alc HALASSERT(ah->ah_magic == AR5212_MAGIC); 1883 1.1 alc 1884 1.1 alc OS_MEMZERO(ahp->ah_pcdacTable, ahp->ah_pcdacTableSize); 1885 1.1 alc OS_MEMZERO(ahp->ah_ratesArray, sizeof(ahp->ah_ratesArray)); 1886 1.1 alc 1887 1.1 alc powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 1888 1.1 alc if (powerLimit >= MAX_RATE_POWER || powerLimit == 0) 1889 1.1 alc tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale]; 1890 1.1 alc else 1891 1.1 alc tpcInDb = 0; 1892 1.1 alc if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit, 1893 1.1 alc AH_TRUE, &minPower, &maxPower)) { 1894 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set rate table\n", 1895 1.1 alc __func__); 1896 1.1 alc return AH_FALSE; 1897 1.1 alc } 1898 1.1 alc if (!ahp->ah_rfHal->setPowerTable(ah, 1899 1.1 alc &minPower, &maxPower, chan, rfXpdGain)) { 1900 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n", 1901 1.1 alc __func__); 1902 1.1 alc return AH_FALSE; 1903 1.1 alc } 1904 1.1 alc 1905 1.1 alc /* 1906 1.1 alc * Adjust XR power/rate up by 2 dB to account for greater peak 1907 1.1 alc * to avg ratio - except in newer avg power designs 1908 1.1 alc */ 1909 1.1 alc if (!IS_2413(ah) && !IS_5413(ah)) 1910 1.1 alc ahp->ah_ratesArray[15] += 4; 1911 1.1 alc /* 1912 1.1 alc * txPowerIndexOffset is set by the SetPowerTable() call - 1913 1.1 alc * adjust the rate table 1914 1.1 alc */ 1915 1.1 alc for (i = 0; i < N(ahp->ah_ratesArray); i++) { 1916 1.1 alc ahp->ah_ratesArray[i] += ahp->ah_txPowerIndexOffset; 1917 1.1 alc if (ahp->ah_ratesArray[i] > 63) 1918 1.1 alc ahp->ah_ratesArray[i] = 63; 1919 1.1 alc } 1920 1.1 alc 1921 1.1 alc if (ee->ee_eepMap < 2) { 1922 1.1 alc /* 1923 1.1 alc * Correct gain deltas for 5212 G operation - 1924 1.1 alc * Removed with revised chipset 1925 1.1 alc */ 1926 1.1 alc if (AH_PRIVATE(ah)->ah_phyRev < AR_PHY_CHIP_ID_REV_2 && 1927 1.1 alc IS_CHAN_G(chan)) { 1928 1.1 alc uint16_t cckOfdmPwrDelta; 1929 1.1 alc 1930 1.1 alc if (chan->channel == 2484) 1931 1.1 alc cckOfdmPwrDelta = SCALE_OC_DELTA( 1932 1.1 alc ee->ee_cckOfdmPwrDelta - 1933 1.1 alc ee->ee_scaledCh14FilterCckDelta); 1934 1.1 alc else 1935 1.1 alc cckOfdmPwrDelta = SCALE_OC_DELTA( 1936 1.1 alc ee->ee_cckOfdmPwrDelta); 1937 1.1 alc ar5212CorrectGainDelta(ah, cckOfdmPwrDelta); 1938 1.1 alc } 1939 1.1 alc /* 1940 1.1 alc * Finally, write the power values into the 1941 1.1 alc * baseband power table 1942 1.1 alc */ 1943 1.1 alc for (i = 0; i < (PWR_TABLE_SIZE/2); i++) { 1944 1.1 alc OS_REG_WRITE(ah, AR_PHY_PCDAC_TX_POWER(i), 1945 1.1 alc ((((ahp->ah_pcdacTable[2*i + 1] << 8) | 0xff) & 0xffff) << 16) 1946 1.1 alc | (((ahp->ah_pcdacTable[2*i] << 8) | 0xff) & 0xffff) 1947 1.1 alc ); 1948 1.1 alc } 1949 1.1 alc } 1950 1.1 alc 1951 1.1 alc /* Write the OFDM power per rate set */ 1952 1.1 alc OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1953 1.1 alc POW_OFDM(ahp->ah_ratesArray[3], 24) 1954 1.1 alc | POW_OFDM(ahp->ah_ratesArray[2], 16) 1955 1.1 alc | POW_OFDM(ahp->ah_ratesArray[1], 8) 1956 1.1 alc | POW_OFDM(ahp->ah_ratesArray[0], 0) 1957 1.1 alc ); 1958 1.1 alc OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 1959 1.1 alc POW_OFDM(ahp->ah_ratesArray[7], 24) 1960 1.1 alc | POW_OFDM(ahp->ah_ratesArray[6], 16) 1961 1.1 alc | POW_OFDM(ahp->ah_ratesArray[5], 8) 1962 1.1 alc | POW_OFDM(ahp->ah_ratesArray[4], 0) 1963 1.1 alc ); 1964 1.1 alc 1965 1.1 alc /* Write the CCK power per rate set */ 1966 1.1 alc OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1967 1.1 alc POW_CCK(ahp->ah_ratesArray[10], 24) 1968 1.1 alc | POW_CCK(ahp->ah_ratesArray[9], 16) 1969 1.1 alc | POW_CCK(ahp->ah_ratesArray[15], 8) /* XR target power */ 1970 1.1 alc | POW_CCK(ahp->ah_ratesArray[8], 0) 1971 1.1 alc ); 1972 1.1 alc OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 1973 1.1 alc POW_CCK(ahp->ah_ratesArray[14], 24) 1974 1.1 alc | POW_CCK(ahp->ah_ratesArray[13], 16) 1975 1.1 alc | POW_CCK(ahp->ah_ratesArray[12], 8) 1976 1.1 alc | POW_CCK(ahp->ah_ratesArray[11], 0) 1977 1.1 alc ); 1978 1.1 alc 1979 1.1 alc /* 1980 1.1 alc * Set max power to 30 dBm and, optionally, 1981 1.1 alc * enable TPC in tx descriptors. 1982 1.1 alc */ 1983 1.1 alc OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER | 1984 1.1 alc (ahp->ah_tpcEnabled ? AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE : 0)); 1985 1.1 alc 1986 1.1 alc return AH_TRUE; 1987 1.1 alc #undef N 1988 1.1 alc #undef POW_CCK 1989 1.1 alc #undef POW_OFDM 1990 1.1 alc } 1991 1.1 alc 1992 1.1 alc /* 1993 1.1 alc * Sets the transmit power in the baseband for the given 1994 1.1 alc * operating channel and mode. 1995 1.1 alc */ 1996 1.1 alc static HAL_BOOL 1997 1.1 alc ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan, 1998 1.1 alc int16_t tpcScaleReduction, int16_t powerLimit, HAL_BOOL commit, 1999 1.1 alc int16_t *pMinPower, int16_t *pMaxPower) 2000 1.1 alc { 2001 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 2002 1.1 alc const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 2003 1.1 alc uint16_t *rpow = ahp->ah_ratesArray; 2004 1.1 alc uint16_t twiceMaxEdgePower = MAX_RATE_POWER; 2005 1.1 alc uint16_t twiceMaxEdgePowerCck = MAX_RATE_POWER; 2006 1.1 alc uint16_t twiceMaxRDPower = MAX_RATE_POWER; 2007 1.1 alc int i; 2008 1.1 alc uint8_t cfgCtl; 2009 1.1 alc int8_t twiceAntennaGain, twiceAntennaReduction; 2010 1.1 alc const RD_EDGES_POWER *rep; 2011 1.1 alc TRGT_POWER_INFO targetPowerOfdm, targetPowerCck; 2012 1.1 alc int16_t scaledPower, maxAvailPower = 0; 2013 1.1 alc int16_t r13, r9, r7, r0; 2014 1.1 alc 2015 1.1 alc HALASSERT(ah->ah_magic == AR5212_MAGIC); 2016 1.1 alc 2017 1.1 alc twiceMaxRDPower = chan->maxRegTxPower * 2; 2018 1.1 alc *pMaxPower = -MAX_RATE_POWER; 2019 1.1 alc *pMinPower = MAX_RATE_POWER; 2020 1.1 alc 2021 1.1 alc /* Get conformance test limit maximum for this channel */ 2022 1.1 alc cfgCtl = ath_hal_getctl(ah, chan); 2023 1.1 alc for (i = 0; i < ee->ee_numCtls; i++) { 2024 1.1 alc uint16_t twiceMinEdgePower; 2025 1.1 alc 2026 1.1 alc if (ee->ee_ctl[i] == 0) 2027 1.1 alc continue; 2028 1.1 alc if (ee->ee_ctl[i] == cfgCtl || 2029 1.1 alc cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) { 2030 1.1 alc rep = &ee->ee_rdEdgesPower[i * NUM_EDGES]; 2031 1.1 alc twiceMinEdgePower = ar5212GetMaxEdgePower(chan->channel, rep); 2032 1.1 alc if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 2033 1.1 alc /* Find the minimum of all CTL edge powers that apply to this channel */ 2034 1.1 alc twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower); 2035 1.1 alc } else { 2036 1.1 alc twiceMaxEdgePower = twiceMinEdgePower; 2037 1.1 alc break; 2038 1.1 alc } 2039 1.1 alc } 2040 1.1 alc } 2041 1.1 alc 2042 1.1 alc if (IS_CHAN_G(chan)) { 2043 1.1 alc /* Check for a CCK CTL for 11G CCK powers */ 2044 1.1 alc cfgCtl = (cfgCtl & ~CTL_MODE_M) | CTL_11B; 2045 1.1 alc for (i = 0; i < ee->ee_numCtls; i++) { 2046 1.1 alc uint16_t twiceMinEdgePowerCck; 2047 1.1 alc 2048 1.1 alc if (ee->ee_ctl[i] == 0) 2049 1.1 alc continue; 2050 1.1 alc if (ee->ee_ctl[i] == cfgCtl || 2051 1.1 alc cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) { 2052 1.1 alc rep = &ee->ee_rdEdgesPower[i * NUM_EDGES]; 2053 1.1 alc twiceMinEdgePowerCck = ar5212GetMaxEdgePower(chan->channel, rep); 2054 1.1 alc if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 2055 1.1 alc /* Find the minimum of all CTL edge powers that apply to this channel */ 2056 1.1 alc twiceMaxEdgePowerCck = AH_MIN(twiceMaxEdgePowerCck, twiceMinEdgePowerCck); 2057 1.1 alc } else { 2058 1.1 alc twiceMaxEdgePowerCck = twiceMinEdgePowerCck; 2059 1.1 alc break; 2060 1.1 alc } 2061 1.1 alc } 2062 1.1 alc } 2063 1.1 alc } else { 2064 1.1 alc /* Set the 11B cck edge power to the one found before */ 2065 1.1 alc twiceMaxEdgePowerCck = twiceMaxEdgePower; 2066 1.1 alc } 2067 1.1 alc 2068 1.1 alc /* Get Antenna Gain reduction */ 2069 1.1 alc if (IS_CHAN_5GHZ(chan)) { 2070 1.1 alc ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain); 2071 1.1 alc } else { 2072 1.1 alc ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain); 2073 1.1 alc } 2074 1.1 alc twiceAntennaReduction = 2075 1.1 alc ath_hal_getantennareduction(ah, chan, twiceAntennaGain); 2076 1.1 alc 2077 1.1 alc if (IS_CHAN_OFDM(chan)) { 2078 1.1 alc /* Get final OFDM target powers */ 2079 1.1 alc if (IS_CHAN_2GHZ(chan)) { 2080 1.1 alc ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11g, 2081 1.1 alc ee->ee_numTargetPwr_11g, &targetPowerOfdm); 2082 1.1 alc } else { 2083 1.1 alc ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11a, 2084 1.1 alc ee->ee_numTargetPwr_11a, &targetPowerOfdm); 2085 1.1 alc } 2086 1.1 alc 2087 1.1 alc /* Get Maximum OFDM power */ 2088 1.1 alc /* Minimum of target and edge powers */ 2089 1.1 alc scaledPower = AH_MIN(twiceMaxEdgePower, 2090 1.1 alc twiceMaxRDPower - twiceAntennaReduction); 2091 1.1 alc 2092 1.1 alc /* 2093 1.1 alc * If turbo is set, reduce power to keep power 2094 1.1 alc * consumption under 2 Watts. Note that we always do 2095 1.1 alc * this unless specially configured. Then we limit 2096 1.1 alc * power only for non-AP operation. 2097 1.1 alc */ 2098 1.1 alc if (IS_CHAN_TURBO(chan) 2099 1.1 alc #ifdef AH_ENABLE_AP_SUPPORT 2100 1.1 alc && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP 2101 1.1 alc #endif 2102 1.1 alc ) { 2103 1.1 alc /* 2104 1.1 alc * If turbo is set, reduce power to keep power 2105 1.1 alc * consumption under 2 Watts 2106 1.1 alc */ 2107 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_1) 2108 1.1 alc scaledPower = AH_MIN(scaledPower, 2109 1.1 alc ee->ee_turbo2WMaxPower5); 2110 1.1 alc /* 2111 1.1 alc * EEPROM version 4.0 added an additional 2112 1.1 alc * constraint on 2.4GHz channels. 2113 1.1 alc */ 2114 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0 && 2115 1.1 alc IS_CHAN_2GHZ(chan)) 2116 1.1 alc scaledPower = AH_MIN(scaledPower, 2117 1.1 alc ee->ee_turbo2WMaxPower2); 2118 1.1 alc } 2119 1.1 alc 2120 1.1 alc maxAvailPower = AH_MIN(scaledPower, 2121 1.1 alc targetPowerOfdm.twicePwr6_24); 2122 1.1 alc 2123 1.1 alc /* Reduce power by max regulatory domain allowed restrictions */ 2124 1.1 alc scaledPower = maxAvailPower - (tpcScaleReduction * 2); 2125 1.1 alc scaledPower = (scaledPower < 0) ? 0 : scaledPower; 2126 1.1 alc scaledPower = AH_MIN(scaledPower, powerLimit); 2127 1.1 alc 2128 1.1 alc if (commit) { 2129 1.1 alc /* Set OFDM rates 9, 12, 18, 24 */ 2130 1.1 alc r0 = rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower; 2131 1.1 alc 2132 1.1 alc /* Set OFDM rates 36, 48, 54, XR */ 2133 1.1 alc rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36); 2134 1.1 alc rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48); 2135 1.1 alc r7 = rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54); 2136 1.1 alc 2137 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0) { 2138 1.1 alc /* Setup XR target power from EEPROM */ 2139 1.1 alc rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ? 2140 1.1 alc ee->ee_xrTargetPower2 : ee->ee_xrTargetPower5); 2141 1.1 alc } else { 2142 1.1 alc /* XR uses 6mb power */ 2143 1.1 alc rpow[15] = rpow[0]; 2144 1.1 alc } 2145 1.1 alc ahp->ah_ofdmTxPower = *pMaxPower; 2146 1.1 alc 2147 1.1 alc } else { 2148 1.1 alc r0 = scaledPower; 2149 1.1 alc r7 = AH_MIN(r0, targetPowerOfdm.twicePwr54); 2150 1.1 alc } 2151 1.1 alc *pMinPower = r7; 2152 1.1 alc *pMaxPower = r0; 2153 1.1 alc 2154 1.1 alc HALDEBUG(ah, HAL_DEBUG_RFPARAM, 2155 1.1 alc "%s: MaxRD: %d TurboMax: %d MaxCTL: %d " 2156 1.1 alc "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n", 2157 1.1 alc __func__, twiceMaxRDPower, ee->ee_turbo2WMaxPower5, 2158 1.1 alc twiceMaxEdgePower, tpcScaleReduction * 2, 2159 1.1 alc chan->channel, chan->channelFlags, 2160 1.1 alc maxAvailPower, targetPowerOfdm.twicePwr6_24, *pMaxPower); 2161 1.1 alc } 2162 1.1 alc 2163 1.1 alc if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) { 2164 1.1 alc /* Get final CCK target powers */ 2165 1.1 alc ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11b, 2166 1.1 alc ee->ee_numTargetPwr_11b, &targetPowerCck); 2167 1.1 alc 2168 1.1 alc /* Reduce power by max regulatory domain allowed restrictions */ 2169 1.1 alc scaledPower = AH_MIN(twiceMaxEdgePowerCck, 2170 1.1 alc twiceMaxRDPower - twiceAntennaReduction); 2171 1.1 alc if (maxAvailPower < AH_MIN(scaledPower, targetPowerCck.twicePwr6_24)) 2172 1.1 alc maxAvailPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24); 2173 1.1 alc 2174 1.1 alc /* Reduce power by user selection */ 2175 1.1 alc scaledPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24) - (tpcScaleReduction * 2); 2176 1.1 alc scaledPower = (scaledPower < 0) ? 0 : scaledPower; 2177 1.1 alc scaledPower = AH_MIN(scaledPower, powerLimit); 2178 1.1 alc 2179 1.1 alc if (commit) { 2180 1.1 alc /* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */ 2181 1.1 alc rpow[8] = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24); 2182 1.1 alc r9 = rpow[9] = AH_MIN(scaledPower, targetPowerCck.twicePwr36); 2183 1.1 alc rpow[10] = rpow[9]; 2184 1.1 alc rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48); 2185 1.1 alc rpow[12] = rpow[11]; 2186 1.1 alc r13 = rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54); 2187 1.1 alc rpow[14] = rpow[13]; 2188 1.1 alc } else { 2189 1.1 alc r9 = AH_MIN(scaledPower, targetPowerCck.twicePwr36); 2190 1.1 alc r13 = AH_MIN(scaledPower, targetPowerCck.twicePwr54); 2191 1.1 alc } 2192 1.1 alc 2193 1.1 alc /* Set min/max power based off OFDM values or initialization */ 2194 1.1 alc if (r13 < *pMinPower) 2195 1.1 alc *pMinPower = r13; 2196 1.1 alc if (r9 > *pMaxPower) 2197 1.1 alc *pMaxPower = r9; 2198 1.1 alc 2199 1.1 alc HALDEBUG(ah, HAL_DEBUG_RFPARAM, 2200 1.1 alc "%s: cck: MaxRD: %d MaxCTL: %d " 2201 1.1 alc "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n", 2202 1.1 alc __func__, twiceMaxRDPower, twiceMaxEdgePowerCck, 2203 1.1 alc tpcScaleReduction * 2, chan->channel, chan->channelFlags, 2204 1.1 alc maxAvailPower, targetPowerCck.twicePwr6_24, *pMaxPower); 2205 1.1 alc } 2206 1.1 alc if (commit) { 2207 1.1 alc ahp->ah_tx6PowerInHalfDbm = *pMaxPower; 2208 1.1 alc AH_PRIVATE(ah)->ah_maxPowerLevel = ahp->ah_tx6PowerInHalfDbm; 2209 1.1 alc } 2210 1.1 alc return AH_TRUE; 2211 1.1 alc } 2212 1.1 alc 2213 1.1 alc HAL_BOOL 2214 1.1 alc ar5212GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans) 2215 1.1 alc { 2216 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 2217 1.1 alc static const uint16_t tpcScaleReductionTable[5] = 2218 1.1 alc { 0, 3, 6, 9, MAX_RATE_POWER }; 2219 1.1 alc int16_t minPower, maxPower, tpcInDb, powerLimit; 2220 1.1 alc HAL_CHANNEL *chan; 2221 1.1 alc int i; 2222 1.1 alc 2223 1.1 alc /* 2224 1.1 alc * Get Pier table max and min powers. 2225 1.1 alc */ 2226 1.1 alc for (i = 0; i < nchans; i++) { 2227 1.1 alc chan = &chans[i]; 2228 1.1 alc if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) { 2229 1.1 alc /* NB: rf code returns 1/4 dBm units, convert */ 2230 1.1 alc chan->maxTxPower = maxPower / 2; 2231 1.1 alc chan->minTxPower = minPower / 2; 2232 1.1 alc } else { 2233 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 2234 1.1 alc "%s: no min/max power for %u/0x%x\n", 2235 1.1 alc __func__, chan->channel, chan->channelFlags); 2236 1.1 alc chan->maxTxPower = MAX_RATE_POWER; 2237 1.1 alc chan->minTxPower = 0; 2238 1.1 alc } 2239 1.1 alc } 2240 1.1 alc /* 2241 1.1 alc * Now adjust to reflect any global scale and/or CTL's. 2242 1.1 alc * (XXX is that correct?) 2243 1.1 alc */ 2244 1.1 alc powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 2245 1.1 alc if (powerLimit >= MAX_RATE_POWER || powerLimit == 0) 2246 1.1 alc tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale]; 2247 1.1 alc else 2248 1.1 alc tpcInDb = 0; 2249 1.1 alc for (i=0; i<nchans; i++) { 2250 1.1 alc chan = &chans[i]; 2251 1.1 alc if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit, 2252 1.1 alc AH_FALSE, &minPower, &maxPower)) { 2253 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 2254 1.1 alc "%s: unable to find max/min power\n",__func__); 2255 1.1 alc return AH_FALSE; 2256 1.1 alc } 2257 1.1 alc if (maxPower < chan->maxTxPower) 2258 1.1 alc chan->maxTxPower = maxPower; 2259 1.1 alc if (minPower < chan->minTxPower) 2260 1.1 alc chan->minTxPower = minPower; 2261 1.1 alc } 2262 1.1 alc #ifdef AH_DEBUG 2263 1.1 alc for (i=0; i<nchans; i++) { 2264 1.1 alc HALDEBUG(ah, HAL_DEBUG_RESET, 2265 1.1 alc "Chan %d: MaxPow = %d MinPow = %d\n", 2266 1.1 alc chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower); 2267 1.1 alc } 2268 1.1 alc #endif 2269 1.1 alc return AH_TRUE; 2270 1.1 alc } 2271 1.1 alc 2272 1.1 alc /* 2273 1.1 alc * Correct for the gain-delta between ofdm and cck mode target 2274 1.1 alc * powers. Write the results to the rate table and the power table. 2275 1.1 alc * 2276 1.1 alc * Conventions : 2277 1.1 alc * 1. rpow[ii] is the integer value of 2*(desired power 2278 1.1 alc * for the rate ii in dBm) to provide 0.5dB resolution. rate 2279 1.1 alc * mapping is as following : 2280 1.1 alc * [0..7] --> ofdm 6, 9, .. 48, 54 2281 1.1 alc * [8..14] --> cck 1L, 2L, 2S, .. 11L, 11S 2282 1.1 alc * [15] --> XR (all rates get the same power) 2283 1.1 alc * 2. powv[ii] is the pcdac corresponding to ii/2 dBm. 2284 1.1 alc */ 2285 1.1 alc static void 2286 1.1 alc ar5212CorrectGainDelta(struct ath_hal *ah, int twiceOfdmCckDelta) 2287 1.1 alc { 2288 1.1 alc #define N(_a) (sizeof(_a) / sizeof(_a[0])) 2289 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 2290 1.1 alc const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 2291 1.1 alc int16_t ratesIndex[N(ahp->ah_ratesArray)]; 2292 1.1 alc uint16_t ii, jj, iter; 2293 1.1 alc int32_t cckIndex; 2294 1.1 alc int16_t gainDeltaAdjust; 2295 1.1 alc 2296 1.1 alc HALASSERT(ah->ah_magic == AR5212_MAGIC); 2297 1.1 alc 2298 1.1 alc gainDeltaAdjust = ee->ee_cckOfdmGainDelta; 2299 1.1 alc 2300 1.1 alc /* make a local copy of desired powers as initial indices */ 2301 1.1 alc OS_MEMCPY(ratesIndex, ahp->ah_ratesArray, sizeof(ratesIndex)); 2302 1.1 alc 2303 1.1 alc /* fix only the CCK indices */ 2304 1.1 alc for (ii = 8; ii < 15; ii++) { 2305 1.1 alc /* apply a gain_delta correction of -15 for CCK */ 2306 1.1 alc ratesIndex[ii] -= gainDeltaAdjust; 2307 1.1 alc 2308 1.1 alc /* Now check for contention with all ofdm target powers */ 2309 1.1 alc jj = 0; 2310 1.1 alc iter = 0; 2311 1.1 alc /* indicates not all ofdm rates checked forcontention yet */ 2312 1.1 alc while (jj < 16) { 2313 1.1 alc if (ratesIndex[ii] < 0) 2314 1.1 alc ratesIndex[ii] = 0; 2315 1.1 alc if (jj == 8) { /* skip CCK rates */ 2316 1.1 alc jj = 15; 2317 1.1 alc continue; 2318 1.1 alc } 2319 1.1 alc if (ratesIndex[ii] == ahp->ah_ratesArray[jj]) { 2320 1.1 alc if (ahp->ah_ratesArray[jj] == 0) 2321 1.1 alc ratesIndex[ii]++; 2322 1.1 alc else if (iter > 50) { 2323 1.1 alc /* 2324 1.1 alc * To avoid pathological case of of 2325 1.1 alc * dm target powers 0 and 0.5dBm 2326 1.1 alc */ 2327 1.1 alc ratesIndex[ii]++; 2328 1.1 alc } else 2329 1.1 alc ratesIndex[ii]--; 2330 1.1 alc /* check with all rates again */ 2331 1.1 alc jj = 0; 2332 1.1 alc iter++; 2333 1.1 alc } else 2334 1.1 alc jj++; 2335 1.1 alc } 2336 1.1 alc if (ratesIndex[ii] >= PWR_TABLE_SIZE) 2337 1.1 alc ratesIndex[ii] = PWR_TABLE_SIZE -1; 2338 1.1 alc cckIndex = ahp->ah_ratesArray[ii] - twiceOfdmCckDelta; 2339 1.1 alc if (cckIndex < 0) 2340 1.1 alc cckIndex = 0; 2341 1.1 alc 2342 1.1 alc /* 2343 1.1 alc * Validate that the indexes for the powv are not 2344 1.1 alc * out of bounds. 2345 1.1 alc */ 2346 1.1 alc HALASSERT(cckIndex < PWR_TABLE_SIZE); 2347 1.1 alc HALASSERT(ratesIndex[ii] < PWR_TABLE_SIZE); 2348 1.1 alc ahp->ah_pcdacTable[ratesIndex[ii]] = 2349 1.1 alc ahp->ah_pcdacTable[cckIndex]; 2350 1.1 alc } 2351 1.1 alc /* Override rate per power table with new values */ 2352 1.1 alc for (ii = 8; ii < 15; ii++) 2353 1.1 alc ahp->ah_ratesArray[ii] = ratesIndex[ii]; 2354 1.1 alc #undef N 2355 1.1 alc } 2356 1.1 alc 2357 1.1 alc /* 2358 1.1 alc * Find the maximum conformance test limit for the given channel and CTL info 2359 1.1 alc */ 2360 1.1 alc static uint16_t 2361 1.1 alc ar5212GetMaxEdgePower(uint16_t channel, const RD_EDGES_POWER *pRdEdgesPower) 2362 1.1 alc { 2363 1.1 alc /* temp array for holding edge channels */ 2364 1.1 alc uint16_t tempChannelList[NUM_EDGES]; 2365 1.2 mrg uint16_t clo = 0, chi = 0, twiceMaxEdgePower; 2366 1.1 alc int i, numEdges; 2367 1.1 alc 2368 1.1 alc /* Get the edge power */ 2369 1.1 alc for (i = 0; i < NUM_EDGES; i++) { 2370 1.1 alc if (pRdEdgesPower[i].rdEdge == 0) 2371 1.1 alc break; 2372 1.1 alc tempChannelList[i] = pRdEdgesPower[i].rdEdge; 2373 1.1 alc } 2374 1.1 alc numEdges = i; 2375 1.1 alc 2376 1.1 alc ar5212GetLowerUpperValues(channel, tempChannelList, 2377 1.1 alc numEdges, &clo, &chi); 2378 1.1 alc /* Get the index for the lower channel */ 2379 1.1 alc for (i = 0; i < numEdges && clo != tempChannelList[i]; i++) 2380 1.1 alc ; 2381 1.1 alc /* Is lower channel ever outside the rdEdge? */ 2382 1.1 alc HALASSERT(i != numEdges); 2383 1.1 alc 2384 1.1 alc if ((clo == chi && clo == channel) || (pRdEdgesPower[i].flag)) { 2385 1.1 alc /* 2386 1.1 alc * If there's an exact channel match or an inband flag set 2387 1.1 alc * on the lower channel use the given rdEdgePower 2388 1.1 alc */ 2389 1.1 alc twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower; 2390 1.1 alc HALASSERT(twiceMaxEdgePower > 0); 2391 1.1 alc } else 2392 1.1 alc twiceMaxEdgePower = MAX_RATE_POWER; 2393 1.1 alc return twiceMaxEdgePower; 2394 1.1 alc } 2395 1.1 alc 2396 1.1 alc /* 2397 1.1 alc * Returns interpolated or the scaled up interpolated value 2398 1.1 alc */ 2399 1.1 alc static uint16_t 2400 1.1 alc interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 2401 1.1 alc uint16_t targetLeft, uint16_t targetRight) 2402 1.1 alc { 2403 1.1 alc uint16_t rv; 2404 1.1 alc int16_t lRatio; 2405 1.1 alc 2406 1.1 alc /* to get an accurate ratio, always scale, if want to scale, then don't scale back down */ 2407 1.1 alc if ((targetLeft * targetRight) == 0) 2408 1.1 alc return 0; 2409 1.1 alc 2410 1.1 alc if (srcRight != srcLeft) { 2411 1.1 alc /* 2412 1.1 alc * Note the ratio always need to be scaled, 2413 1.1 alc * since it will be a fraction. 2414 1.1 alc */ 2415 1.1 alc lRatio = (target - srcLeft) * EEP_SCALE / (srcRight - srcLeft); 2416 1.1 alc if (lRatio < 0) { 2417 1.1 alc /* Return as Left target if value would be negative */ 2418 1.1 alc rv = targetLeft; 2419 1.1 alc } else if (lRatio > EEP_SCALE) { 2420 1.1 alc /* Return as Right target if Ratio is greater than 100% (SCALE) */ 2421 1.1 alc rv = targetRight; 2422 1.1 alc } else { 2423 1.1 alc rv = (lRatio * targetRight + (EEP_SCALE - lRatio) * 2424 1.1 alc targetLeft) / EEP_SCALE; 2425 1.1 alc } 2426 1.1 alc } else { 2427 1.1 alc rv = targetLeft; 2428 1.1 alc } 2429 1.1 alc return rv; 2430 1.1 alc } 2431 1.1 alc 2432 1.1 alc /* 2433 1.1 alc * Return the four rates of target power for the given target power table 2434 1.1 alc * channel, and number of channels 2435 1.1 alc */ 2436 1.1 alc static void 2437 1.1 alc ar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan, 2438 1.1 alc const TRGT_POWER_INFO *powInfo, 2439 1.1 alc uint16_t numChannels, TRGT_POWER_INFO *pNewPower) 2440 1.1 alc { 2441 1.1 alc /* temp array for holding target power channels */ 2442 1.1 alc uint16_t tempChannelList[NUM_TEST_FREQUENCIES]; 2443 1.2 mrg uint16_t clo = 0, chi = 0, ixlo, ixhi; 2444 1.1 alc int i; 2445 1.1 alc 2446 1.1 alc /* Copy the target powers into the temp channel list */ 2447 1.1 alc for (i = 0; i < numChannels; i++) 2448 1.1 alc tempChannelList[i] = powInfo[i].testChannel; 2449 1.1 alc 2450 1.1 alc ar5212GetLowerUpperValues(chan->channel, tempChannelList, 2451 1.1 alc numChannels, &clo, &chi); 2452 1.1 alc 2453 1.1 alc /* Get the indices for the channel */ 2454 1.1 alc ixlo = ixhi = 0; 2455 1.1 alc for (i = 0; i < numChannels; i++) { 2456 1.1 alc if (clo == tempChannelList[i]) { 2457 1.1 alc ixlo = i; 2458 1.1 alc } 2459 1.1 alc if (chi == tempChannelList[i]) { 2460 1.1 alc ixhi = i; 2461 1.1 alc break; 2462 1.1 alc } 2463 1.1 alc } 2464 1.1 alc 2465 1.1 alc /* 2466 1.1 alc * Get the lower and upper channels, target powers, 2467 1.1 alc * and interpolate between them. 2468 1.1 alc */ 2469 1.1 alc pNewPower->twicePwr6_24 = interpolate(chan->channel, clo, chi, 2470 1.1 alc powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24); 2471 1.1 alc pNewPower->twicePwr36 = interpolate(chan->channel, clo, chi, 2472 1.1 alc powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36); 2473 1.1 alc pNewPower->twicePwr48 = interpolate(chan->channel, clo, chi, 2474 1.1 alc powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48); 2475 1.1 alc pNewPower->twicePwr54 = interpolate(chan->channel, clo, chi, 2476 1.1 alc powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54); 2477 1.1 alc } 2478 1.1 alc 2479 1.1 alc /* 2480 1.1 alc * Search a list for a specified value v that is within 2481 1.1 alc * EEP_DELTA of the search values. Return the closest 2482 1.1 alc * values in the list above and below the desired value. 2483 1.1 alc * EEP_DELTA is a factional value; everything is scaled 2484 1.1 alc * so only integer arithmetic is used. 2485 1.1 alc * 2486 1.1 alc * NB: the input list is assumed to be sorted in ascending order 2487 1.1 alc */ 2488 1.1 alc void 2489 1.1 alc ar5212GetLowerUpperValues(uint16_t v, uint16_t *lp, uint16_t listSize, 2490 1.1 alc uint16_t *vlo, uint16_t *vhi) 2491 1.1 alc { 2492 1.1 alc uint32_t target = v * EEP_SCALE; 2493 1.1 alc uint16_t *ep = lp+listSize; 2494 1.1 alc 2495 1.1 alc /* 2496 1.1 alc * Check first and last elements for out-of-bounds conditions. 2497 1.1 alc */ 2498 1.1 alc if (target < (uint32_t)(lp[0] * EEP_SCALE - EEP_DELTA)) { 2499 1.1 alc *vlo = *vhi = lp[0]; 2500 1.1 alc return; 2501 1.1 alc } 2502 1.1 alc if (target > (uint32_t)(ep[-1] * EEP_SCALE + EEP_DELTA)) { 2503 1.1 alc *vlo = *vhi = ep[-1]; 2504 1.1 alc return; 2505 1.1 alc } 2506 1.1 alc 2507 1.1 alc /* look for value being near or between 2 values in list */ 2508 1.1 alc for (; lp < ep; lp++) { 2509 1.1 alc /* 2510 1.1 alc * If value is close to the current value of the list 2511 1.1 alc * then target is not between values, it is one of the values 2512 1.1 alc */ 2513 1.5 joerg if (lp[0] * EEP_SCALE - target < EEP_DELTA) { 2514 1.1 alc *vlo = *vhi = lp[0]; 2515 1.1 alc return; 2516 1.1 alc } 2517 1.1 alc /* 2518 1.1 alc * Look for value being between current value and next value 2519 1.1 alc * if so return these 2 values 2520 1.1 alc */ 2521 1.1 alc if (target < (uint32_t)(lp[1] * EEP_SCALE - EEP_DELTA)) { 2522 1.1 alc *vlo = lp[0]; 2523 1.1 alc *vhi = lp[1]; 2524 1.1 alc return; 2525 1.1 alc } 2526 1.1 alc } 2527 1.1 alc HALASSERT(AH_FALSE); /* should not reach here */ 2528 1.1 alc } 2529 1.1 alc 2530 1.1 alc /* 2531 1.1 alc * Perform analog "swizzling" of parameters into their location 2532 1.1 alc * 2533 1.1 alc * NB: used by RF backends 2534 1.1 alc */ 2535 1.1 alc void 2536 1.1 alc ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, uint32_t numBits, 2537 1.1 alc uint32_t firstBit, uint32_t column) 2538 1.1 alc { 2539 1.1 alc #define MAX_ANALOG_START 319 /* XXX */ 2540 1.1 alc uint32_t tmp32, mask, arrayEntry, lastBit; 2541 1.1 alc int32_t bitPosition, bitsLeft; 2542 1.1 alc 2543 1.1 alc HALASSERT(column <= 3); 2544 1.1 alc HALASSERT(numBits <= 32); 2545 1.1 alc HALASSERT(firstBit + numBits <= MAX_ANALOG_START); 2546 1.1 alc 2547 1.1 alc tmp32 = ath_hal_reverseBits(reg32, numBits); 2548 1.1 alc arrayEntry = (firstBit - 1) / 8; 2549 1.1 alc bitPosition = (firstBit - 1) % 8; 2550 1.1 alc bitsLeft = numBits; 2551 1.1 alc while (bitsLeft > 0) { 2552 1.1 alc lastBit = (bitPosition + bitsLeft > 8) ? 2553 1.1 alc 8 : bitPosition + bitsLeft; 2554 1.1 alc mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << 2555 1.1 alc (column * 8); 2556 1.1 alc rfBuf[arrayEntry] &= ~mask; 2557 1.1 alc rfBuf[arrayEntry] |= ((tmp32 << bitPosition) << 2558 1.1 alc (column * 8)) & mask; 2559 1.1 alc bitsLeft -= 8 - bitPosition; 2560 1.1 alc tmp32 = tmp32 >> (8 - bitPosition); 2561 1.1 alc bitPosition = 0; 2562 1.1 alc arrayEntry++; 2563 1.1 alc } 2564 1.1 alc #undef MAX_ANALOG_START 2565 1.1 alc } 2566 1.1 alc 2567 1.1 alc /* 2568 1.1 alc * Sets the rate to duration values in MAC - used for multi- 2569 1.1 alc * rate retry. 2570 1.1 alc * The rate duration table needs to cover all valid rate codes; 2571 1.1 alc * the 11g table covers all ofdm rates, while the 11b table 2572 1.1 alc * covers all cck rates => all valid rates get covered between 2573 1.1 alc * these two mode's ratetables! 2574 1.1 alc * But if we're turbo, the ofdm phy is replaced by the turbo phy 2575 1.1 alc * and cck is not valid with turbo => all rates get covered 2576 1.1 alc * by the turbo ratetable only 2577 1.1 alc */ 2578 1.1 alc void 2579 1.1 alc ar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan) 2580 1.1 alc { 2581 1.1 alc const HAL_RATE_TABLE *rt; 2582 1.1 alc int i; 2583 1.1 alc 2584 1.1 alc /* NB: band doesn't matter for 1/2 and 1/4 rate */ 2585 1.1 alc if (IS_CHAN_HALF_RATE(chan)) { 2586 1.1 alc rt = ar5212GetRateTable(ah, HAL_MODE_11A_HALF_RATE); 2587 1.1 alc } else if (IS_CHAN_QUARTER_RATE(chan)) { 2588 1.1 alc rt = ar5212GetRateTable(ah, HAL_MODE_11A_QUARTER_RATE); 2589 1.1 alc } else { 2590 1.1 alc rt = ar5212GetRateTable(ah, 2591 1.1 alc IS_CHAN_TURBO(chan) ? HAL_MODE_TURBO : HAL_MODE_11G); 2592 1.1 alc } 2593 1.1 alc 2594 1.1 alc for (i = 0; i < rt->rateCount; ++i) 2595 1.1 alc OS_REG_WRITE(ah, 2596 1.1 alc AR_RATE_DURATION(rt->info[i].rateCode), 2597 1.1 alc ath_hal_computetxtime(ah, rt, 2598 1.1 alc WLAN_CTRL_FRAME_SIZE, 2599 1.1 alc rt->info[i].controlRate, AH_FALSE)); 2600 1.1 alc if (!IS_CHAN_TURBO(chan)) { 2601 1.1 alc /* 11g Table is used to cover the CCK rates. */ 2602 1.1 alc rt = ar5212GetRateTable(ah, HAL_MODE_11G); 2603 1.1 alc for (i = 0; i < rt->rateCount; ++i) { 2604 1.1 alc uint32_t reg = AR_RATE_DURATION(rt->info[i].rateCode); 2605 1.1 alc 2606 1.1 alc if (rt->info[i].phy != IEEE80211_T_CCK) 2607 1.1 alc continue; 2608 1.1 alc 2609 1.1 alc OS_REG_WRITE(ah, reg, 2610 1.1 alc ath_hal_computetxtime(ah, rt, 2611 1.1 alc WLAN_CTRL_FRAME_SIZE, 2612 1.1 alc rt->info[i].controlRate, AH_FALSE)); 2613 1.1 alc /* cck rates have short preamble option also */ 2614 1.1 alc if (rt->info[i].shortPreamble) { 2615 1.1 alc reg += rt->info[i].shortPreamble << 2; 2616 1.1 alc OS_REG_WRITE(ah, reg, 2617 1.1 alc ath_hal_computetxtime(ah, rt, 2618 1.1 alc WLAN_CTRL_FRAME_SIZE, 2619 1.1 alc rt->info[i].controlRate, 2620 1.1 alc AH_TRUE)); 2621 1.1 alc } 2622 1.1 alc } 2623 1.1 alc } 2624 1.1 alc } 2625 1.1 alc 2626 1.1 alc /* Adjust various register settings based on half/quarter rate clock setting. 2627 1.1 alc * This includes: +USEC, TX/RX latency, 2628 1.1 alc * + IFS params: slot, eifs, misc etc. 2629 1.1 alc */ 2630 1.1 alc void 2631 1.1 alc ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan) 2632 1.1 alc { 2633 1.1 alc uint32_t txLat, rxLat, usec, slot, refClock, eifs, init_usec; 2634 1.1 alc 2635 1.1 alc HALASSERT(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)); 2636 1.1 alc 2637 1.1 alc refClock = OS_REG_READ(ah, AR_USEC) & AR_USEC_USEC32; 2638 1.1 alc if (IS_CHAN_HALF_RATE(chan)) { 2639 1.1 alc slot = IFS_SLOT_HALF_RATE; 2640 1.1 alc rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S; 2641 1.1 alc txLat = TX_HALF_RATE_LATENCY << AR5212_USEC_TX_LAT_S; 2642 1.1 alc usec = HALF_RATE_USEC; 2643 1.1 alc eifs = IFS_EIFS_HALF_RATE; 2644 1.1 alc init_usec = INIT_USEC >> 1; 2645 1.1 alc } else { /* quarter rate */ 2646 1.1 alc slot = IFS_SLOT_QUARTER_RATE; 2647 1.1 alc rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S; 2648 1.1 alc txLat = TX_QUARTER_RATE_LATENCY << AR5212_USEC_TX_LAT_S; 2649 1.1 alc usec = QUARTER_RATE_USEC; 2650 1.1 alc eifs = IFS_EIFS_QUARTER_RATE; 2651 1.1 alc init_usec = INIT_USEC >> 2; 2652 1.1 alc } 2653 1.1 alc 2654 1.1 alc OS_REG_WRITE(ah, AR_USEC, (usec | refClock | txLat | rxLat)); 2655 1.1 alc OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot); 2656 1.1 alc OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs); 2657 1.1 alc OS_REG_RMW_FIELD(ah, AR_D_GBL_IFS_MISC, 2658 1.1 alc AR_D_GBL_IFS_MISC_USEC_DURATION, init_usec); 2659 1.1 alc } 2660