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