ar5416_reset.c (185380) | ar5416_reset.c (185406) |
---|---|
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: ar5416_reset.c,v 1.27 2008/11/27 22:30:08 sam Exp $ 18 */ 19#include "opt_ah.h" 20 | 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: ar5416_reset.c,v 1.27 2008/11/27 22:30:08 sam Exp $ 18 */ 19#include "opt_ah.h" 20 |
21#ifdef AH_SUPPORT_AR5416 22 | |
23#include "ah.h" 24#include "ah_internal.h" 25#include "ah_devid.h" 26 27#include "ah_eeprom_v14.h" 28 29#include "ar5416/ar5416.h" 30#include "ar5416/ar5416reg.h" 31#include "ar5416/ar5416phy.h" 32#ifdef AH_SUPPORT_AR9280 33#include "ar5416/ar9280.h" 34#endif 35 36/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ 37#define EEP_MINOR(_ah) \ 38 (AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK) 39#define IS_EEP_MINOR_V2(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2) 40#define IS_EEP_MINOR_V3(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3) 41 42/* Additional Time delay to wait after activiting the Base band */ 43#define BASE_ACTIVATE_DELAY 100 /* 100 usec */ 44#define PLL_SETTLE_DELAY 300 /* 300 usec */ 45#define RTC_PLL_SETTLE_DELAY 1000 /* 1 ms */ 46 47static void ar5416InitDMA(struct ath_hal *ah); 48static void ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan); 49static void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode); 50static void ar5416InitQoS(struct ath_hal *ah); 51static void ar5416InitUserSettings(struct ath_hal *ah); 52 53static HAL_BOOL ar5416SetTransmitPower(struct ath_hal *ah, 54 HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain); 55 56#if 0 57static HAL_BOOL ar5416ChannelChange(struct ath_hal *, HAL_CHANNEL *); 58#endif 59static void ar5416SetDeltaSlope(struct ath_hal *, HAL_CHANNEL_INTERNAL *); 60static void ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan); 61#ifdef AH_SUPPORT_AR9280 62static void ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan); 63#endif 64 65static HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah); 66static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type); 67static void ar5416InitPLL(struct ath_hal *ah, HAL_CHANNEL *chan); 68static HAL_BOOL ar5416SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *); 69static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah, 70 struct ar5416eeprom *pEepData, 71 HAL_CHANNEL_INTERNAL *chan, int16_t *ratesArray, 72 uint16_t cfgCtl, uint16_t AntennaReduction, 73 uint16_t twiceMaxRegulatoryPower, 74 uint16_t powerLimit); 75static HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah, 76 struct ar5416eeprom *pEepData, 77 HAL_CHANNEL_INTERNAL *chan, 78 int16_t *pTxPowerIndexOffset); 79static uint16_t ar5416GetMaxEdgePower(uint16_t freq, 80 CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz); 81static void ar5416GetTargetPowers(struct ath_hal *ah, 82 HAL_CHANNEL_INTERNAL *chan, CAL_TARGET_POWER_HT *powInfo, 83 uint16_t numChannels, CAL_TARGET_POWER_HT *pNewPower, 84 uint16_t numRates, HAL_BOOL isHt40Target); 85static void ar5416GetTargetPowersLeg(struct ath_hal *ah, 86 HAL_CHANNEL_INTERNAL *chan, CAL_TARGET_POWER_LEG *powInfo, 87 uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower, 88 uint16_t numRates, HAL_BOOL isExtTarget); 89 90static int16_t interpolate(uint16_t target, uint16_t srcLeft, 91 uint16_t srcRight, int16_t targetLeft, int16_t targetRight); 92static void ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan); 93static void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 94 HAL_CHANNEL_INTERNAL *chan, CAL_DATA_PER_FREQ *pRawDataSet, 95 uint8_t * bChans, uint16_t availPiers, 96 uint16_t tPdGainOverlap, int16_t *pMinCalPower, 97 uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues, 98 uint16_t numXpdGains); 99static HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList, 100 uint16_t listSize, uint16_t *indexL, uint16_t *indexR); 101static HAL_BOOL ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, 102 uint8_t *pPwrList, uint8_t *pVpdList, 103 uint16_t numIntercepts, uint8_t *pRetVpdList); 104 105/* 106 * Places the device in and out of reset and then places sane 107 * values in the registers based on EEPROM config, initialization 108 * vectors (as determined by the mode), and station configuration 109 * 110 * bChannelChange is used to preserve DMA/PCU registers across 111 * a HW Reset during channel change. 112 */ 113HAL_BOOL 114ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, 115 HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status) 116{ 117#define N(a) (sizeof (a) / sizeof (a[0])) 118#define FAIL(_code) do { ecode = _code; goto bad; } while (0) 119 struct ath_hal_5212 *ahp = AH5212(ah); 120 HAL_CHANNEL_INTERNAL *ichan; 121 uint32_t softLedCfg; 122 uint32_t saveDefAntenna, saveLedState; 123 uint32_t macStaId1; 124 uint16_t rfXpdGain[2]; 125 u_int modesIndex, freqIndex; 126 HAL_STATUS ecode; 127 int i, regWrites = 0; 128 uint32_t powerVal, rssiThrReg; 129 uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow; 130 131 OS_MARK(ah, AH_MARK_RESET, bChannelChange); 132#define IS(_c,_f) (((_c)->channelFlags & _f) || 0) 133 if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) { 134 HALDEBUG(ah, HAL_DEBUG_ANY, 135 "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n", 136 __func__, chan->channel, chan->channelFlags); 137 FAIL(HAL_EINVAL); 138 } 139 if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) { 140 HALDEBUG(ah, HAL_DEBUG_ANY, 141 "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n", 142 __func__, chan->channel, chan->channelFlags); 143 FAIL(HAL_EINVAL); 144 } 145#undef IS 146 147 /* Bring out of sleep mode */ 148 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 149 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n", 150 __func__); 151 FAIL(HAL_EIO); 152 } 153 154 /* 155 * Map public channel to private. 156 */ 157 ichan = ath_hal_checkchannel(ah, chan); 158 if (ichan == AH_NULL) { 159 HALDEBUG(ah, HAL_DEBUG_ANY, 160 "%s: invalid channel %u/0x%x; no mapping\n", 161 __func__, chan->channel, chan->channelFlags); 162 FAIL(HAL_EINVAL); 163 } else { 164 HALDEBUG(ah, HAL_DEBUG_RESET, 165 "%s: Ch=%u Max=%d Min=%d\n",__func__, 166 ichan->channel, ichan->maxTxPower, ichan->minTxPower); 167 } 168 switch (opmode) { 169 case HAL_M_STA: 170 case HAL_M_IBSS: 171 case HAL_M_HOSTAP: 172 case HAL_M_MONITOR: 173 break; 174 default: 175 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n", 176 __func__, opmode); 177 FAIL(HAL_EINVAL); 178 break; 179 } 180 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 181 182 /* XXX Turn on fast channel change for 5416 */ 183 /* 184 * Preserve the bmiss rssi threshold and count threshold 185 * across resets 186 */ 187 rssiThrReg = OS_REG_READ(ah, AR_RSSI_THR); 188 /* If reg is zero, first time thru set to default val */ 189 if (rssiThrReg == 0) 190 rssiThrReg = INIT_RSSI_THR; 191 192 /* 193 * Preserve the antenna on a channel change 194 */ 195 saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA); 196 if (saveDefAntenna == 0) /* XXX magic constants */ 197 saveDefAntenna = 1; 198 199 /* Save hardware flag before chip reset clears the register */ 200 macStaId1 = OS_REG_READ(ah, AR_STA_ID1) & 201 (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT); 202 203 /* Save led state from pci config register */ 204 saveLedState = OS_REG_READ(ah, AR_MAC_LED) & 205 (AR_MAC_LED_ASSOC | AR_MAC_LED_MODE | 206 AR_MAC_LED_BLINK_THRESH_SEL | AR_MAC_LED_BLINK_SLOW); 207 softLedCfg = OS_REG_READ(ah, AR_GPIO_INTR_OUT); 208 209 /* 210 * Adjust gain parameters before reset if 211 * there's an outstanding gain updated. 212 */ 213 (void) ar5416GetRfgain(ah); 214 215 if (!ar5416ChipReset(ah, chan)) { 216 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); 217 FAIL(HAL_EIO); 218 } 219 220 /* Restore bmiss rssi & count thresholds */ 221 OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg); 222 223 /* Setup the indices for the next set of register array writes */ 224 /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */ 225 switch (chan->channelFlags & CHANNEL_ALL) { 226 case CHANNEL_A: 227 case CHANNEL_A_HT20: 228 modesIndex = 1; 229 freqIndex = 1; 230 break; 231 case CHANNEL_T: 232 case CHANNEL_A_HT40PLUS: 233 case CHANNEL_A_HT40MINUS: 234 modesIndex = 2; 235 freqIndex = 1; 236 break; 237 case CHANNEL_PUREG: 238 case CHANNEL_G_HT20: 239 case CHANNEL_B: /* treat as channel G , no B mode suport in owl */ 240 modesIndex = 4; 241 freqIndex = 2; 242 break; 243 case CHANNEL_G_HT40PLUS: 244 case CHANNEL_G_HT40MINUS: 245 modesIndex = 3; 246 freqIndex = 2; 247 break; 248 case CHANNEL_108G: 249 modesIndex = 5; 250 freqIndex = 2; 251 break; 252 default: 253 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n", 254 __func__, chan->channelFlags); 255 FAIL(HAL_EINVAL); 256 } 257 258 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 259 260 /* Set correct Baseband to analog shift setting to access analog chips. */ 261 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 262 263 /* 264 * Write addac shifts 265 */ 266 OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); 267#if 0 268 /* NB: only required for Sowl */ 269 ar5416EepromSetAddac(ah, ichan); 270#endif 271 regWrites = ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_addac, 1, 272 regWrites); 273 OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); 274 275 /* XXX Merlin ini fixups */ 276 /* XXX Merlin 100us delay for shift registers */ 277 regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 278 regWrites); 279#ifdef AH_SUPPORT_AR9280 280 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 281 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain, 282 modesIndex, regWrites); 283 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain, 284 modesIndex, regWrites); 285 } 286#endif 287 /* XXX Merlin 100us delay for shift registers */ 288 regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_common, 1, regWrites); 289 /* Setup 11n MAC/Phy mode registers */ 290 ar5416Set11nRegs(ah,chan); 291 /* XXX updated regWrites? */ 292 ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites); 293#ifdef AH_SUPPORT_AR9280 294 if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 295 /* 5GHz channels w/ Fast Clock use different modal values */ 296 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes, 297 modesIndex, regWrites); 298 } 299#endif 300 301 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 302 303 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_DAG_CTRLCCK=0x%x\n", 304 __func__, OS_REG_READ(ah,AR_PHY_DAG_CTRLCCK)); 305 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_ADC_CTL=0x%x\n", 306 __func__, OS_REG_READ(ah,AR_PHY_ADC_CTL)); 307 308 /* Set the mute mask to the correct default */ 309 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) 310 OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F); 311 312 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) { 313 /* Clear reg to alllow RX_CLEAR line debug */ 314 OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0); 315 } 316 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) { 317#ifdef notyet 318 /* Enable burst prefetch for the data queues */ 319 OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... ); 320 /* Enable double-buffering */ 321 OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS); 322#endif 323 } 324 325 /* Set ADC/DAC select values */ 326 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e); 327 328 if (AH5416(ah)->ah_rx_chainmask == 0x5 || 329 AH5416(ah)->ah_tx_chainmask == 0x5) 330 OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); 331 /* Setup Chain Masks */ 332 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 333 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 334 OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask); 335 336 /* Setup the transmit power values. */ 337 if (!ar5416SetTransmitPower(ah, ichan, rfXpdGain)) { 338 HALDEBUG(ah, HAL_DEBUG_ANY, 339 "%s: error init'ing transmit power\n", __func__); 340 FAIL(HAL_EIO); 341 } 342 343 /* Write the analog registers */ 344 if (!ahp->ah_rfHal->setRfRegs(ah, ichan, freqIndex, rfXpdGain)) { 345 HALDEBUG(ah, HAL_DEBUG_ANY, 346 "%s: ar5212SetRfRegs failed\n", __func__); 347 FAIL(HAL_EIO); 348 } 349 350 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 351 if (IS_CHAN_OFDM(chan)|| IS_CHAN_HT(chan)) 352 ar5416SetDeltaSlope(ah, ichan); 353 354#ifdef AH_SUPPORT_AR9280 355 if (AR_SREV_MERLIN_10_OR_LATER(ah)) 356 ar9280SpurMitigate(ah, ichan); 357 else 358#endif 359 ar5416SpurMitigate(ah, ichan); 360 361 /* Setup board specific options for EEPROM version 3 */ 362 if (!ar5416SetBoardValues(ah, ichan)) { 363 HALDEBUG(ah, HAL_DEBUG_ANY, 364 "%s: error setting board options\n", __func__); 365 FAIL(HAL_EIO); 366 } 367 368 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 369 370 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 371 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) 372 | macStaId1 373 | AR_STA_ID1_RTS_USE_DEF 374 | ahp->ah_staId1Defaults 375 ); 376 ar5212SetOperatingMode(ah, opmode); 377 378 /* Set Venice BSSID mask according to current state */ 379 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask)); 380 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4)); 381 382 /* Restore previous led state */ 383 OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) | saveLedState); 384 /* Restore soft Led state to GPIO */ 385 OS_REG_WRITE(ah, AR_GPIO_INTR_OUT, softLedCfg); 386 387 /* Restore previous antenna */ 388 OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 389 390 /* then our BSSID */ 391 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 392 OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4)); 393 394 /* Restore bmiss rssi & count thresholds */ 395 OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr); 396 397 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ 398 399 if (!ar5212SetChannel(ah, ichan)) 400 FAIL(HAL_EIO); 401 402 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 403 404 /* Set 1:1 QCU to DCU mapping for all queues */ 405 for (i = 0; i < AR_NUM_DCU; i++) 406 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 407 408 ahp->ah_intrTxqs = 0; 409 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) 410 ar5212ResetTxQueue(ah, i); 411 412 ar5416InitIMR(ah, opmode); 413 ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); 414 ar5416InitQoS(ah); 415 ar5416InitUserSettings(ah); 416 417 /* 418 * disable seq number generation in hw 419 */ 420 OS_REG_WRITE(ah, AR_STA_ID1, 421 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 422 423 ar5416InitDMA(ah); 424 425 /* 426 * program OBS bus to see MAC interrupts 427 */ 428 OS_REG_WRITE(ah, AR_OBS, 8); 429 430#ifdef AR5416_INT_MITIGATION 431 OS_REG_WRITE(ah, AR_MIRT, 0); 432 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 433 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 434#endif 435 436 ar5416InitBB(ah, chan); 437 438 /* Setup compression registers */ 439 ar5212SetCompRegs(ah); /* XXX not needed? */ 440 441 /* 442 * 5416 baseband will check the per rate power table 443 * and select the lower of the two 444 */ 445 ackTpcPow = 63; 446 ctsTpcPow = 63; 447 chirpTpcPow = 63; 448 powerVal = SM(ackTpcPow, AR_TPC_ACK) | 449 SM(ctsTpcPow, AR_TPC_CTS) | 450 SM(chirpTpcPow, AR_TPC_CHIRP); 451 OS_REG_WRITE(ah, AR_TPC, powerVal); 452 453 if (!ar5416InitCal(ah, chan)) 454 FAIL(HAL_ESELFTEST); 455 456 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 457 458 if (bChannelChange) { 459 if (!(ichan->privFlags & CHANNEL_DFS)) 460 ichan->privFlags &= ~CHANNEL_INTERFERENCE; 461 chan->channelFlags = ichan->channelFlags; 462 chan->privFlags = ichan->privFlags; 463 chan->maxRegTxPower = ichan->maxRegTxPower; 464 chan->maxTxPower = ichan->maxTxPower; 465 chan->minTxPower = ichan->minTxPower; 466 } 467 468 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__); 469 470 OS_MARK(ah, AH_MARK_RESET_DONE, 0); 471 472 return AH_TRUE; 473bad: 474 OS_MARK(ah, AH_MARK_RESET_DONE, ecode); 475 if (*status) 476 *status = ecode; 477 return AH_FALSE; 478#undef FAIL 479#undef N 480} 481 482#if 0 483/* 484 * This channel change evaluates whether the selected hardware can 485 * perform a synthesizer-only channel change (no reset). If the 486 * TX is not stopped, or the RFBus cannot be granted in the given 487 * time, the function returns false as a reset is necessary 488 */ 489HAL_BOOL 490ar5416ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan) 491{ 492 uint32_t ulCount; 493 uint32_t data, synthDelay, qnum; 494 uint16_t rfXpdGain[4]; 495 struct ath_hal_5212 *ahp = AH5212(ah); 496 HAL_CHANNEL_INTERNAL *ichan; 497 498 /* 499 * Map public channel to private. 500 */ 501 ichan = ath_hal_checkchannel(ah, chan); 502 503 /* TX must be stopped or RF Bus grant will not work */ 504 for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) { 505 if (ar5212NumTxPending(ah, qnum)) { 506 HALDEBUG(ah, HAL_DEBUG_ANY, 507 "%s: frames pending on queue %d\n", __func__, qnum); 508 return AH_FALSE; 509 } 510 } 511 512 /* 513 * Kill last Baseband Rx Frame - Request analog bus grant 514 */ 515 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); 516 if (!ath_hal_wait(ah, AR_PHY_RFBUS_GNT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) { 517 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: could not kill baseband rx\n", 518 __func__); 519 return AH_FALSE; 520 } 521 522 ar5416Set11nRegs(ah, chan); /* NB: setup 5416-specific regs */ 523 524 /* Change the synth */ 525 if (!ar5212SetChannel(ah, ichan)) 526 return AH_FALSE; 527 528 /* Setup the transmit power values. */ 529 if (!ar5416SetTransmitPower(ah, ichan, rfXpdGain)) { 530 HALDEBUG(ah, HAL_DEBUG_ANY, 531 "%s: error init'ing transmit power\n", __func__); 532 return AH_FALSE; 533 } 534 535 /* 536 * Wait for the frequency synth to settle (synth goes on 537 * via PHY_ACTIVE_EN). Read the phy active delay register. 538 * Value is in 100ns increments. 539 */ 540 data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 541 if (IS_CHAN_CCK(ichan)) { 542 synthDelay = (4 * data) / 22; 543 } else { 544 synthDelay = data / 10; 545 } 546 547 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 548 549 /* Release the RFBus Grant */ 550 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 551 552 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 553 if (IS_CHAN_OFDM(ichan)|| IS_CHAN_HT(chan)) { 554 if (ahp->ah_eeprom.ee_version >= AR_EEPROM_VER5_3 && 555 !IS_CHAN_B(chan)) 556 ar5212SetSpurMitigation(ah, ichan); 557 ar5416SetDeltaSlope(ah, ichan); 558 } 559 560 /* XXX spur mitigation for Melin */ 561 562 /* Copy over internal channel flags to public hal channel */ 563 564 if (!(ichan->privFlags & CHANNEL_DFS)) 565 ichan->privFlags &= ~CHANNEL_INTERFERENCE; 566 chan->channelFlags = ichan->channelFlags; 567 chan->privFlags = ichan->privFlags; 568 chan->maxRegTxPower = ichan->maxRegTxPower; 569 chan->maxTxPower = ichan->maxTxPower; 570 chan->minTxPower = ichan->minTxPower; 571 AH_PRIVATE(ah)->ah_curchan->ah_channel_time=0; 572 AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar5212GetTsf64(ah); 573 ar5212TxEnable(ah,AH_TRUE); 574 return AH_TRUE; 575} 576#endif 577 578static void 579ar5416InitDMA(struct ath_hal *ah) 580{ 581 582 /* 583 * set AHB_MODE not to do cacheline prefetches 584 */ 585 OS_REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); 586 587 /* 588 * let mac dma reads be in 128 byte chunks 589 */ 590 OS_REG_WRITE(ah, AR_TXCFG, 591 (OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK) | AR_TXCFG_DMASZ_128B); 592 593 /* 594 * let mac dma writes be in 128 byte chunks 595 */ 596 OS_REG_WRITE(ah, AR_RXCFG, 597 (OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B); 598 599 /* XXX restore TX trigger level */ 600 601 /* 602 * Setup receive FIFO threshold to hold off TX activities 603 */ 604 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 605 606 /* 607 * reduce the number of usable entries in PCU TXBUF to avoid 608 * wrap around. 609 */ 610 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE); 611} 612 613static void 614ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan) 615{ 616 uint32_t synthDelay; 617 618 /* 619 * Wait for the frequency synth to settle (synth goes on 620 * via AR_PHY_ACTIVE_EN). Read the phy active delay register. 621 * Value is in 100ns increments. 622 */ 623 synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 624 if (IS_CHAN_CCK(chan)) { 625 synthDelay = (4 * synthDelay) / 22; 626 } else { 627 synthDelay /= 10; 628 } 629 630 /* Turn on PLL on 5416 */ 631 HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n", 632 __func__, IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz"); 633 ar5416InitPLL(ah, chan); 634 635 /* Activate the PHY (includes baseband activate and synthesizer on) */ 636 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 637 638 /* 639 * If the AP starts the calibration before the base band timeout 640 * completes we could get rx_clear false triggering. Add an 641 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition 642 * does not happen. 643 */ 644 if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) { 645 OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY); 646 } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) { 647 OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY); 648 } else { 649 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 650 } 651} 652 653static void 654ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode) 655{ 656 struct ath_hal_5212 *ahp = AH5212(ah); 657 658 /* 659 * Setup interrupt handling. Note that ar5212ResetTxQueue 660 * manipulates the secondary IMR's as queues are enabled 661 * and disabled. This is done with RMW ops to insure the 662 * settings we make here are preserved. 663 */ 664 ahp->ah_maskReg = AR_IMR_TXERR | AR_IMR_TXURN 665 | AR_IMR_RXERR | AR_IMR_RXORN 666 | AR_IMR_BCNMISC; 667 668#ifdef AR5416_INT_MITIGATION 669 ahp->ah_maskReg |= AR_IMR_TXINTM | AR_IMR_RXINTM 670 | AR_IMR_TXMINTR | AR_IMR_RXMINTR; 671#else 672 ahp->ah_maskReg |= AR_IMR_TXOK | AR_IMR_RXOK; 673#endif 674 if (opmode == HAL_M_HOSTAP) 675 ahp->ah_maskReg |= AR_IMR_MIB; 676 OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); 677 /* Enable bus errors that are OR'd to set the HIUERR bit */ 678 679#if 0 680 OS_REG_WRITE(ah, AR_IMR_S2, 681 OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST); 682#endif 683} 684 685static void 686ar5416InitQoS(struct ath_hal *ah) 687{ 688 /* QoS support */ 689 OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */ 690 OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */ 691 692 /* Turn on NOACK Support for QoS packets */ 693 OS_REG_WRITE(ah, AR_NOACK, 694 SM(2, AR_NOACK_2BIT_VALUE) | 695 SM(5, AR_NOACK_BIT_OFFSET) | 696 SM(0, AR_NOACK_BYTE_OFFSET)); 697 698 /* 699 * initialize TXOP for all TIDs 700 */ 701 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); 702 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); 703 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); 704 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); 705 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 706} 707 708static void 709ar5416InitUserSettings(struct ath_hal *ah) 710{ 711 struct ath_hal_5212 *ahp = AH5212(ah); 712 713 /* Restore user-specified settings */ 714 if (ahp->ah_miscMode != 0) 715 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 716 if (ahp->ah_sifstime != (u_int) -1) 717 ar5212SetSifsTime(ah, ahp->ah_sifstime); 718 if (ahp->ah_slottime != (u_int) -1) 719 ar5212SetSlotTime(ah, ahp->ah_slottime); 720 if (ahp->ah_acktimeout != (u_int) -1) 721 ar5212SetAckTimeout(ah, ahp->ah_acktimeout); 722 if (ahp->ah_ctstimeout != (u_int) -1) 723 ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout); 724 if (AH_PRIVATE(ah)->ah_diagreg != 0) 725 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 726#if 0 /* XXX Todo */ 727 if (ahp->ah_globaltxtimeout != (u_int) -1) 728 ar5416SetGlobalTxTimeout(ah, ahp->ah_globaltxtimeout); 729#endif 730} 731 732/* 733 * Places the hardware into reset and then pulls it out of reset 734 */ 735HAL_BOOL 736ar5416ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan) 737{ 738 uint32_t rfMode = 0; 739 740 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0); 741 /* 742 * Warm reset is optimistic. 743 */ 744 if (AR_SREV_MERLIN_20_OR_LATER(ah) && 745 ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 746 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) 747 return AH_FALSE; 748 } else { 749 if (!ar5416SetResetReg(ah, HAL_RESET_WARM)) 750 return AH_FALSE; 751 } 752 753 /* Bring out of sleep mode (AGAIN) */ 754 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 755 return AH_FALSE; 756 757 ar5416InitPLL(ah, chan); 758 759 /* 760 * Perform warm reset before the mode/PLL/turbo registers 761 * are changed in order to deactivate the radio. Mode changes 762 * with an active radio can result in corrupted shifts to the 763 * radio device. 764 */ 765 if (chan != AH_NULL) { 766 /* treat channel B as channel G , no B mode suport in owl */ 767 rfMode |= (IS_CHAN_G(chan) || IS_CHAN_B(chan)) ? 768 AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; 769 if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 770 /* phy mode bits for 5GHz channels require Fast Clock */ 771 rfMode |= AR_PHY_MODE_DYNAMIC 772 | AR_PHY_MODE_DYN_CCK_DISABLE; 773 } else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) { 774 rfMode |= (IS_CHAN_5GHZ(chan)) ? 775 AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; 776 } 777 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); 778 } 779 return AH_TRUE; 780} 781 782/* 783 * Delta slope coefficient computation. 784 * Required for OFDM operation. 785 */ 786static void 787ar5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled, 788 uint32_t *coef_mantissa, uint32_t *coef_exponent) 789{ 790#define COEF_SCALE_S 24 791 uint32_t coef_exp, coef_man; 792 /* 793 * ALGO -> coef_exp = 14-floor(log2(coef)); 794 * floor(log2(x)) is the highest set bit position 795 */ 796 for (coef_exp = 31; coef_exp > 0; coef_exp--) 797 if ((coef_scaled >> coef_exp) & 0x1) 798 break; 799 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */ 800 HALASSERT(coef_exp); 801 coef_exp = 14 - (coef_exp - COEF_SCALE_S); 802 803 /* 804 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5); 805 * The coefficient is already shifted up for scaling 806 */ 807 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); 808 809 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp); 810 *coef_exponent = coef_exp - 16; 811 812#undef COEF_SCALE_S 813} 814 815void 816ar5416SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 817{ 818#define INIT_CLOCKMHZSCALED 0x64000000 819 uint32_t coef_scaled, ds_coef_exp, ds_coef_man; 820 uint32_t clockMhzScaled = INIT_CLOCKMHZSCALED; 821 822 CHAN_CENTERS centers; 823 824 if (IS_CHAN_TURBO(chan)) 825 clockMhzScaled *= 2; 826 /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */ 827 /* scale for selected channel bandwidth */ 828 if (IS_CHAN_HALF_RATE(chan)) { 829 clockMhzScaled = clockMhzScaled >> 1; 830 } else if (IS_CHAN_QUARTER_RATE(chan)) { 831 clockMhzScaled = clockMhzScaled >> 2; 832 } 833 834 /* 835 * ALGO -> coef = 1e8/fcarrier*fclock/40; 836 * scaled coef to provide precision for this floating calculation 837 */ 838 ar5416GetChannelCenters(ah, chan, ¢ers); 839 coef_scaled = clockMhzScaled / centers.synth_center; 840 841 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 842 843 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 844 AR_PHY_TIMING3_DSC_MAN, ds_coef_man); 845 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 846 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); 847 848 /* 849 * For Short GI, 850 * scaled coeff is 9/10 that of normal coeff 851 */ 852 coef_scaled = (9 * coef_scaled)/10; 853 854 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 855 856 /* for short gi */ 857 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 858 AR_PHY_HALFGI_DSC_MAN, ds_coef_man); 859 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 860 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); 861#undef INIT_CLOCKMHZSCALED 862} 863 864/* 865 * Convert to baseband spur frequency given input channel frequency 866 * and compute register settings below. 867 */ 868#define SPUR_RSSI_THRESH 40 869 870static void 871ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 872{ 873 static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, 874 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 }; 875 static const int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, 876 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 }; 877 static const int inc[4] = { 0, 100, 0, 0 }; 878 879 int bb_spur = AR_NO_SPUR; 880 int bin, cur_bin; 881 int spur_freq_sd; 882 int spur_delta_phase; 883 int denominator; 884 int upper, lower, cur_vit_mask; 885 int tmp, new; 886 int i; 887 888 int8_t mask_m[123]; 889 int8_t mask_p[123]; 890 int8_t mask_amt; 891 int tmp_mask; 892 int cur_bb_spur; 893 HAL_BOOL is2GHz = IS_CHAN_2GHZ(chan); 894 895 OS_MEMZERO(mask_m, sizeof(mask_m)); 896 OS_MEMZERO(mask_p, sizeof(mask_p)); 897 898 /* 899 * Need to verify range +/- 9.5 for static ht20, otherwise spur 900 * is out-of-band and can be ignored. 901 */ 902 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 903 cur_bb_spur = ath_hal_getSpurChan(ah, i, is2GHz); 904 if (AR_NO_SPUR == cur_bb_spur) 905 break; 906 cur_bb_spur = cur_bb_spur - (chan->channel * 10); 907 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) { 908 bb_spur = cur_bb_spur; 909 break; 910 } 911 } 912 if (AR_NO_SPUR == bb_spur) 913 return; 914 915 bin = bb_spur * 32; 916 917 tmp = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0)); 918 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | 919 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 920 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 921 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 922 923 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0), new); 924 925 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | 926 AR_PHY_SPUR_REG_ENABLE_MASK_PPM | 927 AR_PHY_SPUR_REG_MASK_RATE_SELECT | 928 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | 929 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); 930 OS_REG_WRITE(ah, AR_PHY_SPUR_REG, new); 931 /* 932 * Should offset bb_spur by +/- 10 MHz for dynamic 2040 MHz 933 * config, no offset for HT20. 934 * spur_delta_phase = bb_spur/40 * 2**21 for static ht20, 935 * /80 for dyn2040. 936 */ 937 spur_delta_phase = ((bb_spur * 524288) / 100) & 938 AR_PHY_TIMING11_SPUR_DELTA_PHASE; 939 /* 940 * in 11A mode the denominator of spur_freq_sd should be 40 and 941 * it should be 44 in 11G 942 */ 943 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400; 944 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff; 945 946 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | 947 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | 948 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); 949 OS_REG_WRITE(ah, AR_PHY_TIMING11, new); 950 951 952 /* 953 * ============================================ 954 * pilot mask 1 [31:0] = +6..-26, no 0 bin 955 * pilot mask 2 [19:0] = +26..+7 956 * 957 * channel mask 1 [31:0] = +6..-26, no 0 bin 958 * channel mask 2 [19:0] = +26..+7 959 */ 960 //cur_bin = -26; 961 cur_bin = -6000; 962 upper = bin + 100; 963 lower = bin - 100; 964 965 for (i = 0; i < 4; i++) { 966 int pilot_mask = 0; 967 int chan_mask = 0; 968 int bp = 0; 969 for (bp = 0; bp < 30; bp++) { 970 if ((cur_bin > lower) && (cur_bin < upper)) { 971 pilot_mask = pilot_mask | 0x1 << bp; 972 chan_mask = chan_mask | 0x1 << bp; 973 } 974 cur_bin += 100; 975 } 976 cur_bin += inc[i]; 977 OS_REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); 978 OS_REG_WRITE(ah, chan_mask_reg[i], chan_mask); 979 } 980 981 /* ================================================= 982 * viterbi mask 1 based on channel magnitude 983 * four levels 0-3 984 * - mask (-27 to 27) (reg 64,0x9900 to 67,0x990c) 985 * [1 2 2 1] for -9.6 or [1 2 1] for +16 986 * - enable_mask_ppm, all bins move with freq 987 * 988 * - mask_select, 8 bits for rates (reg 67,0x990c) 989 * - mask_rate_cntl, 8 bits for rates (reg 67,0x990c) 990 * choose which mask to use mask or mask2 991 */ 992 993 /* 994 * viterbi mask 2 2nd set for per data rate puncturing 995 * four levels 0-3 996 * - mask_select, 8 bits for rates (reg 67) 997 * - mask (-27 to 27) (reg 98,0x9988 to 101,0x9994) 998 * [1 2 2 1] for -9.6 or [1 2 1] for +16 999 */ 1000 cur_vit_mask = 6100; 1001 upper = bin + 120; 1002 lower = bin - 120; 1003 1004 for (i = 0; i < 123; i++) { 1005 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { 1006 if ((abs(cur_vit_mask - bin)) < 75) { 1007 mask_amt = 1; 1008 } else { 1009 mask_amt = 0; 1010 } 1011 if (cur_vit_mask < 0) { 1012 mask_m[abs(cur_vit_mask / 100)] = mask_amt; 1013 } else { 1014 mask_p[cur_vit_mask / 100] = mask_amt; 1015 } 1016 } 1017 cur_vit_mask -= 100; 1018 } 1019 1020 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) 1021 | (mask_m[48] << 26) | (mask_m[49] << 24) 1022 | (mask_m[50] << 22) | (mask_m[51] << 20) 1023 | (mask_m[52] << 18) | (mask_m[53] << 16) 1024 | (mask_m[54] << 14) | (mask_m[55] << 12) 1025 | (mask_m[56] << 10) | (mask_m[57] << 8) 1026 | (mask_m[58] << 6) | (mask_m[59] << 4) 1027 | (mask_m[60] << 2) | (mask_m[61] << 0); 1028 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); 1029 OS_REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); 1030 1031 tmp_mask = (mask_m[31] << 28) 1032 | (mask_m[32] << 26) | (mask_m[33] << 24) 1033 | (mask_m[34] << 22) | (mask_m[35] << 20) 1034 | (mask_m[36] << 18) | (mask_m[37] << 16) 1035 | (mask_m[48] << 14) | (mask_m[39] << 12) 1036 | (mask_m[40] << 10) | (mask_m[41] << 8) 1037 | (mask_m[42] << 6) | (mask_m[43] << 4) 1038 | (mask_m[44] << 2) | (mask_m[45] << 0); 1039 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); 1040 OS_REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); 1041 1042 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) 1043 | (mask_m[18] << 26) | (mask_m[18] << 24) 1044 | (mask_m[20] << 22) | (mask_m[20] << 20) 1045 | (mask_m[22] << 18) | (mask_m[22] << 16) 1046 | (mask_m[24] << 14) | (mask_m[24] << 12) 1047 | (mask_m[25] << 10) | (mask_m[26] << 8) 1048 | (mask_m[27] << 6) | (mask_m[28] << 4) 1049 | (mask_m[29] << 2) | (mask_m[30] << 0); 1050 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); 1051 OS_REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); 1052 1053 tmp_mask = (mask_m[ 0] << 30) | (mask_m[ 1] << 28) 1054 | (mask_m[ 2] << 26) | (mask_m[ 3] << 24) 1055 | (mask_m[ 4] << 22) | (mask_m[ 5] << 20) 1056 | (mask_m[ 6] << 18) | (mask_m[ 7] << 16) 1057 | (mask_m[ 8] << 14) | (mask_m[ 9] << 12) 1058 | (mask_m[10] << 10) | (mask_m[11] << 8) 1059 | (mask_m[12] << 6) | (mask_m[13] << 4) 1060 | (mask_m[14] << 2) | (mask_m[15] << 0); 1061 OS_REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); 1062 OS_REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); 1063 1064 tmp_mask = (mask_p[15] << 28) 1065 | (mask_p[14] << 26) | (mask_p[13] << 24) 1066 | (mask_p[12] << 22) | (mask_p[11] << 20) 1067 | (mask_p[10] << 18) | (mask_p[ 9] << 16) 1068 | (mask_p[ 8] << 14) | (mask_p[ 7] << 12) 1069 | (mask_p[ 6] << 10) | (mask_p[ 5] << 8) 1070 | (mask_p[ 4] << 6) | (mask_p[ 3] << 4) 1071 | (mask_p[ 2] << 2) | (mask_p[ 1] << 0); 1072 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); 1073 OS_REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); 1074 1075 tmp_mask = (mask_p[30] << 28) 1076 | (mask_p[29] << 26) | (mask_p[28] << 24) 1077 | (mask_p[27] << 22) | (mask_p[26] << 20) 1078 | (mask_p[25] << 18) | (mask_p[24] << 16) 1079 | (mask_p[23] << 14) | (mask_p[22] << 12) 1080 | (mask_p[21] << 10) | (mask_p[20] << 8) 1081 | (mask_p[19] << 6) | (mask_p[18] << 4) 1082 | (mask_p[17] << 2) | (mask_p[16] << 0); 1083 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); 1084 OS_REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); 1085 1086 tmp_mask = (mask_p[45] << 28) 1087 | (mask_p[44] << 26) | (mask_p[43] << 24) 1088 | (mask_p[42] << 22) | (mask_p[41] << 20) 1089 | (mask_p[40] << 18) | (mask_p[39] << 16) 1090 | (mask_p[38] << 14) | (mask_p[37] << 12) 1091 | (mask_p[36] << 10) | (mask_p[35] << 8) 1092 | (mask_p[34] << 6) | (mask_p[33] << 4) 1093 | (mask_p[32] << 2) | (mask_p[31] << 0); 1094 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); 1095 OS_REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); 1096 1097 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) 1098 | (mask_p[59] << 26) | (mask_p[58] << 24) 1099 | (mask_p[57] << 22) | (mask_p[56] << 20) 1100 | (mask_p[55] << 18) | (mask_p[54] << 16) 1101 | (mask_p[53] << 14) | (mask_p[52] << 12) 1102 | (mask_p[51] << 10) | (mask_p[50] << 8) 1103 | (mask_p[49] << 6) | (mask_p[48] << 4) 1104 | (mask_p[47] << 2) | (mask_p[46] << 0); 1105 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); 1106 OS_REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 1107} 1108 1109#ifdef AH_SUPPORT_AR9280 1110#define AR_BASE_FREQ_2GHZ 2300 1111#define AR_BASE_FREQ_5GHZ 4900 1112#define AR_SPUR_FEEQ_BOUND_HT40 19 1113#define AR_SPUR_FEEQ_BOUND_HT20 10 1114 1115static void 1116ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan) 1117{ 1118 static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, 1119 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 }; 1120 static const int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, 1121 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 }; 1122 static int inc[4] = { 0, 100, 0, 0 }; 1123 1124 int bb_spur = AR_NO_SPUR; 1125 int freq; 1126 int bin, cur_bin; 1127 int bb_spur_off, spur_subchannel_sd; 1128 int spur_freq_sd; 1129 int spur_delta_phase; 1130 int denominator; 1131 int upper, lower, cur_vit_mask; 1132 int tmp, newVal; 1133 int i; 1134 CHAN_CENTERS centers; 1135 1136 int8_t mask_m[123]; 1137 int8_t mask_p[123]; 1138 int8_t mask_amt; 1139 int tmp_mask; 1140 int cur_bb_spur; 1141 HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan); 1142 1143 OS_MEMZERO(&mask_m, sizeof(int8_t) * 123); 1144 OS_MEMZERO(&mask_p, sizeof(int8_t) * 123); 1145 1146 ar5416GetChannelCenters(ah, ichan, ¢ers); 1147 freq = centers.synth_center; 1148 1149 /* 1150 * Need to verify range +/- 9.38 for static ht20 and +/- 18.75 for ht40, 1151 * otherwise spur is out-of-band and can be ignored. 1152 */ 1153 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 1154 cur_bb_spur = ath_hal_getSpurChan(ah, i, is2GHz); 1155 /* Get actual spur freq in MHz from EEPROM read value */ 1156 if (is2GHz) { 1157 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; 1158 } else { 1159 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; 1160 } 1161 1162 if (AR_NO_SPUR == cur_bb_spur) 1163 break; 1164 cur_bb_spur = cur_bb_spur - freq; 1165 1166 if (IS_CHAN_HT40(ichan)) { 1167 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && 1168 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { 1169 bb_spur = cur_bb_spur; 1170 break; 1171 } 1172 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && 1173 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { 1174 bb_spur = cur_bb_spur; 1175 break; 1176 } 1177 } 1178 1179 if (AR_NO_SPUR == bb_spur) { 1180#if 1 1181 /* 1182 * MRC CCK can interfere with beacon detection and cause deaf/mute. 1183 * Disable MRC CCK for now. 1184 */ 1185 OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 1186#else 1187 /* Enable MRC CCK if no spur is found in this channel. */ 1188 OS_REG_SET_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 1189#endif 1190 return; 1191 } else { 1192 /* 1193 * For Merlin, spur can break CCK MRC algorithm. Disable CCK MRC if spur 1194 * is found in this channel. 1195 */ 1196 OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 1197 } 1198 1199 bin = bb_spur * 320; 1200 1201 tmp = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0)); 1202 1203 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | 1204 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 1205 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 1206 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 1207 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0), newVal); 1208 1209 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | 1210 AR_PHY_SPUR_REG_ENABLE_MASK_PPM | 1211 AR_PHY_SPUR_REG_MASK_RATE_SELECT | 1212 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | 1213 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); 1214 OS_REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); 1215 1216 /* Pick control or extn channel to cancel the spur */ 1217 if (IS_CHAN_HT40(ichan)) { 1218 if (bb_spur < 0) { 1219 spur_subchannel_sd = 1; 1220 bb_spur_off = bb_spur + 10; 1221 } else { 1222 spur_subchannel_sd = 0; 1223 bb_spur_off = bb_spur - 10; 1224 } 1225 } else { 1226 spur_subchannel_sd = 0; 1227 bb_spur_off = bb_spur; 1228 } 1229 1230 /* 1231 * spur_delta_phase = bb_spur/40 * 2**21 for static ht20, 1232 * /80 for dyn2040. 1233 */ 1234 if (IS_CHAN_HT40(ichan)) 1235 spur_delta_phase = ((bb_spur * 262144) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; 1236 else 1237 spur_delta_phase = ((bb_spur * 524288) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; 1238 1239 /* 1240 * in 11A mode the denominator of spur_freq_sd should be 40 and 1241 * it should be 44 in 11G 1242 */ 1243 denominator = IS_CHAN_2GHZ(ichan) ? 44 : 40; 1244 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; 1245 1246 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | 1247 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | 1248 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); 1249 OS_REG_WRITE(ah, AR_PHY_TIMING11, newVal); 1250 1251 /* Choose to cancel between control and extension channels */ 1252 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; 1253 OS_REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); 1254 1255 /* 1256 * ============================================ 1257 * Set Pilot and Channel Masks 1258 * 1259 * pilot mask 1 [31:0] = +6..-26, no 0 bin 1260 * pilot mask 2 [19:0] = +26..+7 1261 * 1262 * channel mask 1 [31:0] = +6..-26, no 0 bin 1263 * channel mask 2 [19:0] = +26..+7 1264 */ 1265 cur_bin = -6000; 1266 upper = bin + 100; 1267 lower = bin - 100; 1268 1269 for (i = 0; i < 4; i++) { 1270 int pilot_mask = 0; 1271 int chan_mask = 0; 1272 int bp = 0; 1273 for (bp = 0; bp < 30; bp++) { 1274 if ((cur_bin > lower) && (cur_bin < upper)) { 1275 pilot_mask = pilot_mask | 0x1 << bp; 1276 chan_mask = chan_mask | 0x1 << bp; 1277 } 1278 cur_bin += 100; 1279 } 1280 cur_bin += inc[i]; 1281 OS_REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); 1282 OS_REG_WRITE(ah, chan_mask_reg[i], chan_mask); 1283 } 1284 1285 /* ================================================= 1286 * viterbi mask 1 based on channel magnitude 1287 * four levels 0-3 1288 * - mask (-27 to 27) (reg 64,0x9900 to 67,0x990c) 1289 * [1 2 2 1] for -9.6 or [1 2 1] for +16 1290 * - enable_mask_ppm, all bins move with freq 1291 * 1292 * - mask_select, 8 bits for rates (reg 67,0x990c) 1293 * - mask_rate_cntl, 8 bits for rates (reg 67,0x990c) 1294 * choose which mask to use mask or mask2 1295 */ 1296 1297 /* 1298 * viterbi mask 2 2nd set for per data rate puncturing 1299 * four levels 0-3 1300 * - mask_select, 8 bits for rates (reg 67) 1301 * - mask (-27 to 27) (reg 98,0x9988 to 101,0x9994) 1302 * [1 2 2 1] for -9.6 or [1 2 1] for +16 1303 */ 1304 cur_vit_mask = 6100; 1305 upper = bin + 120; 1306 lower = bin - 120; 1307 1308 for (i = 0; i < 123; i++) { 1309 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { 1310 if ((abs(cur_vit_mask - bin)) < 75) { 1311 mask_amt = 1; 1312 } else { 1313 mask_amt = 0; 1314 } 1315 if (cur_vit_mask < 0) { 1316 mask_m[abs(cur_vit_mask / 100)] = mask_amt; 1317 } else { 1318 mask_p[cur_vit_mask / 100] = mask_amt; 1319 } 1320 } 1321 cur_vit_mask -= 100; 1322 } 1323 1324 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) 1325 | (mask_m[48] << 26) | (mask_m[49] << 24) 1326 | (mask_m[50] << 22) | (mask_m[51] << 20) 1327 | (mask_m[52] << 18) | (mask_m[53] << 16) 1328 | (mask_m[54] << 14) | (mask_m[55] << 12) 1329 | (mask_m[56] << 10) | (mask_m[57] << 8) 1330 | (mask_m[58] << 6) | (mask_m[59] << 4) 1331 | (mask_m[60] << 2) | (mask_m[61] << 0); 1332 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); 1333 OS_REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); 1334 1335 tmp_mask = (mask_m[31] << 28) 1336 | (mask_m[32] << 26) | (mask_m[33] << 24) 1337 | (mask_m[34] << 22) | (mask_m[35] << 20) 1338 | (mask_m[36] << 18) | (mask_m[37] << 16) 1339 | (mask_m[48] << 14) | (mask_m[39] << 12) 1340 | (mask_m[40] << 10) | (mask_m[41] << 8) 1341 | (mask_m[42] << 6) | (mask_m[43] << 4) 1342 | (mask_m[44] << 2) | (mask_m[45] << 0); 1343 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); 1344 OS_REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); 1345 1346 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) 1347 | (mask_m[18] << 26) | (mask_m[18] << 24) 1348 | (mask_m[20] << 22) | (mask_m[20] << 20) 1349 | (mask_m[22] << 18) | (mask_m[22] << 16) 1350 | (mask_m[24] << 14) | (mask_m[24] << 12) 1351 | (mask_m[25] << 10) | (mask_m[26] << 8) 1352 | (mask_m[27] << 6) | (mask_m[28] << 4) 1353 | (mask_m[29] << 2) | (mask_m[30] << 0); 1354 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); 1355 OS_REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); 1356 1357 tmp_mask = (mask_m[ 0] << 30) | (mask_m[ 1] << 28) 1358 | (mask_m[ 2] << 26) | (mask_m[ 3] << 24) 1359 | (mask_m[ 4] << 22) | (mask_m[ 5] << 20) 1360 | (mask_m[ 6] << 18) | (mask_m[ 7] << 16) 1361 | (mask_m[ 8] << 14) | (mask_m[ 9] << 12) 1362 | (mask_m[10] << 10) | (mask_m[11] << 8) 1363 | (mask_m[12] << 6) | (mask_m[13] << 4) 1364 | (mask_m[14] << 2) | (mask_m[15] << 0); 1365 OS_REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); 1366 OS_REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); 1367 1368 tmp_mask = (mask_p[15] << 28) 1369 | (mask_p[14] << 26) | (mask_p[13] << 24) 1370 | (mask_p[12] << 22) | (mask_p[11] << 20) 1371 | (mask_p[10] << 18) | (mask_p[ 9] << 16) 1372 | (mask_p[ 8] << 14) | (mask_p[ 7] << 12) 1373 | (mask_p[ 6] << 10) | (mask_p[ 5] << 8) 1374 | (mask_p[ 4] << 6) | (mask_p[ 3] << 4) 1375 | (mask_p[ 2] << 2) | (mask_p[ 1] << 0); 1376 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); 1377 OS_REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); 1378 1379 tmp_mask = (mask_p[30] << 28) 1380 | (mask_p[29] << 26) | (mask_p[28] << 24) 1381 | (mask_p[27] << 22) | (mask_p[26] << 20) 1382 | (mask_p[25] << 18) | (mask_p[24] << 16) 1383 | (mask_p[23] << 14) | (mask_p[22] << 12) 1384 | (mask_p[21] << 10) | (mask_p[20] << 8) 1385 | (mask_p[19] << 6) | (mask_p[18] << 4) 1386 | (mask_p[17] << 2) | (mask_p[16] << 0); 1387 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); 1388 OS_REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); 1389 1390 tmp_mask = (mask_p[45] << 28) 1391 | (mask_p[44] << 26) | (mask_p[43] << 24) 1392 | (mask_p[42] << 22) | (mask_p[41] << 20) 1393 | (mask_p[40] << 18) | (mask_p[39] << 16) 1394 | (mask_p[38] << 14) | (mask_p[37] << 12) 1395 | (mask_p[36] << 10) | (mask_p[35] << 8) 1396 | (mask_p[34] << 6) | (mask_p[33] << 4) 1397 | (mask_p[32] << 2) | (mask_p[31] << 0); 1398 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); 1399 OS_REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); 1400 1401 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) 1402 | (mask_p[59] << 26) | (mask_p[58] << 24) 1403 | (mask_p[57] << 22) | (mask_p[56] << 20) 1404 | (mask_p[55] << 18) | (mask_p[54] << 16) 1405 | (mask_p[53] << 14) | (mask_p[52] << 12) 1406 | (mask_p[51] << 10) | (mask_p[50] << 8) 1407 | (mask_p[49] << 6) | (mask_p[48] << 4) 1408 | (mask_p[47] << 2) | (mask_p[46] << 0); 1409 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); 1410 OS_REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 1411} 1412#endif /* AH_SUPPORT_AR9280 */ 1413 1414/* 1415 * Set a limit on the overall output power. Used for dynamic 1416 * transmit power control and the like. 1417 * 1418 * NB: limit is in units of 0.5 dbM. 1419 */ 1420HAL_BOOL 1421ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit) 1422{ 1423 uint16_t dummyXpdGains[2]; 1424 1425 AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); 1426 return ar5416SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan, 1427 dummyXpdGains); 1428} 1429 1430HAL_BOOL 1431ar5416GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans) 1432{ 1433 struct ath_hal_5212 *ahp = AH5212(ah); 1434 int16_t minPower, maxPower; 1435 HAL_CHANNEL *chan; 1436 int i; 1437 1438 /* 1439 * Get Pier table max and min powers. 1440 */ 1441 for (i = 0; i < nchans; i++) { 1442 chan = &chans[i]; 1443 if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) { 1444 /* NB: rf code returns 1/4 dBm units, convert */ 1445 chan->maxTxPower = maxPower / 2; 1446 chan->minTxPower = minPower / 2; 1447 } else { 1448 HALDEBUG(ah, HAL_DEBUG_ANY, 1449 "%s: no min/max power for %u/0x%x\n", 1450 __func__, chan->channel, chan->channelFlags); 1451 chan->maxTxPower = AR5416_MAX_RATE_POWER; 1452 chan->minTxPower = 0; 1453 } 1454 } 1455#ifdef AH_DEBUG 1456 for (i=0; i<nchans; i++) { 1457 HALDEBUG(ah, HAL_DEBUG_RESET, 1458 "Chan %d: MaxPow = %d MinPow = %d\n", 1459 chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower); 1460 } 1461#endif 1462 return AH_TRUE; 1463} 1464 1465/* XXX gag, this is sick */ 1466typedef enum Ar5416_Rates { 1467 rate6mb, rate9mb, rate12mb, rate18mb, 1468 rate24mb, rate36mb, rate48mb, rate54mb, 1469 rate1l, rate2l, rate2s, rate5_5l, 1470 rate5_5s, rate11l, rate11s, rateXr, 1471 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, 1472 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, 1473 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, 1474 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, 1475 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, 1476 Ar5416RateSize 1477} AR5416_RATES; 1478 1479/************************************************************** 1480 * ar5416SetTransmitPower 1481 * 1482 * Set the transmit power in the baseband for the given 1483 * operating channel and mode. 1484 */ 1485static HAL_BOOL 1486ar5416SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain) 1487{ 1488#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 1489#define N(a) (sizeof (a) / sizeof (a[0])) 1490 1491 MODAL_EEP_HEADER *pModal; 1492 struct ath_hal_5212 *ahp = AH5212(ah); 1493 int16_t ratesArray[Ar5416RateSize]; 1494 int16_t txPowerIndexOffset = 0; 1495 uint8_t ht40PowerIncForPdadc = 2; 1496 int i; 1497 1498 uint16_t cfgCtl; 1499 uint16_t powerLimit; 1500 uint16_t twiceAntennaReduction; 1501 uint16_t twiceMaxRegulatoryPower; 1502 int16_t maxPower; 1503 HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 1504 struct ar5416eeprom *pEepData = &ee->ee_base; 1505 1506 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 1507 1508 /* Setup info for the actual eeprom */ 1509 ath_hal_memzero(ratesArray, sizeof(ratesArray)); 1510 cfgCtl = ath_hal_getctl(ah, (HAL_CHANNEL *)chan); 1511 powerLimit = chan->maxRegTxPower * 2; 1512 twiceAntennaReduction = chan->antennaMax; 1513 twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 1514 pModal = &pEepData->modalHeader[IS_CHAN_2GHZ(chan)]; 1515 HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n", 1516 __func__,chan->channel, cfgCtl ); 1517 1518 if (IS_EEP_MINOR_V2(ah)) { 1519 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1520 } 1521 1522 if (!ar5416SetPowerPerRateTable(ah, pEepData, chan, 1523 &ratesArray[0],cfgCtl, 1524 twiceAntennaReduction, 1525 twiceMaxRegulatoryPower, powerLimit)) { 1526 HALDEBUG(ah, HAL_DEBUG_ANY, 1527 "%s: unable to set tx power per rate table\n", __func__); 1528 return AH_FALSE; 1529 } 1530 1531 if (!ar5416SetPowerCalTable(ah, pEepData, chan, &txPowerIndexOffset)) { 1532 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n", 1533 __func__); 1534 return AH_FALSE; 1535 } 1536 1537 maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); 1538 1539 if (IS_CHAN_2GHZ(chan)) { 1540 maxPower = AH_MAX(maxPower, ratesArray[rate1l]); 1541 } 1542 1543 if (IS_CHAN_HT40(chan)) { 1544 maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); 1545 } 1546 1547 ahp->ah_tx6PowerInHalfDbm = maxPower; 1548 AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower; 1549 ahp->ah_txPowerIndexOffset = txPowerIndexOffset; 1550 1551 /* 1552 * txPowerIndexOffset is set by the SetPowerTable() call - 1553 * adjust the rate table (0 offset if rates EEPROM not loaded) 1554 */ 1555 for (i = 0; i < N(ratesArray); i++) { 1556 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1557 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 1558 ratesArray[i] = AR5416_MAX_RATE_POWER; 1559 } 1560 1561#ifdef AH_EEPROM_DUMP 1562 ar5416PrintPowerPerRate(ah, ratesArray); 1563#endif 1564 1565 /* Write the OFDM power per rate set */ 1566 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1567 POW_SM(ratesArray[rate18mb], 24) 1568 | POW_SM(ratesArray[rate12mb], 16) 1569 | POW_SM(ratesArray[rate9mb], 8) 1570 | POW_SM(ratesArray[rate6mb], 0) 1571 ); 1572 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 1573 POW_SM(ratesArray[rate54mb], 24) 1574 | POW_SM(ratesArray[rate48mb], 16) 1575 | POW_SM(ratesArray[rate36mb], 8) 1576 | POW_SM(ratesArray[rate24mb], 0) 1577 ); 1578 1579 if (IS_CHAN_2GHZ(chan)) { 1580 /* Write the CCK power per rate set */ 1581 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1582 POW_SM(ratesArray[rate2s], 24) 1583 | POW_SM(ratesArray[rate2l], 16) 1584 | POW_SM(ratesArray[rateXr], 8) /* XR target power */ 1585 | POW_SM(ratesArray[rate1l], 0) 1586 ); 1587 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 1588 POW_SM(ratesArray[rate11s], 24) 1589 | POW_SM(ratesArray[rate11l], 16) 1590 | POW_SM(ratesArray[rate5_5s], 8) 1591 | POW_SM(ratesArray[rate5_5l], 0) 1592 ); 1593 HALDEBUG(ah, HAL_DEBUG_RESET, 1594 "%s AR_PHY_POWER_TX_RATE3=0x%x AR_PHY_POWER_TX_RATE4=0x%x\n", 1595 __func__, OS_REG_READ(ah,AR_PHY_POWER_TX_RATE3), 1596 OS_REG_READ(ah,AR_PHY_POWER_TX_RATE4)); 1597 } 1598 1599 /* Write the HT20 power per rate set */ 1600 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 1601 POW_SM(ratesArray[rateHt20_3], 24) 1602 | POW_SM(ratesArray[rateHt20_2], 16) 1603 | POW_SM(ratesArray[rateHt20_1], 8) 1604 | POW_SM(ratesArray[rateHt20_0], 0) 1605 ); 1606 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 1607 POW_SM(ratesArray[rateHt20_7], 24) 1608 | POW_SM(ratesArray[rateHt20_6], 16) 1609 | POW_SM(ratesArray[rateHt20_5], 8) 1610 | POW_SM(ratesArray[rateHt20_4], 0) 1611 ); 1612 1613 if (IS_CHAN_HT40(chan)) { 1614 /* Write the HT40 power per rate set */ 1615 /* Correct PAR difference between HT40 and HT20/LEGACY */ 1616 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 1617 POW_SM(ratesArray[rateHt40_3] + ht40PowerIncForPdadc, 24) 1618 | POW_SM(ratesArray[rateHt40_2] + ht40PowerIncForPdadc, 16) 1619 | POW_SM(ratesArray[rateHt40_1] + ht40PowerIncForPdadc, 8) 1620 | POW_SM(ratesArray[rateHt40_0] + ht40PowerIncForPdadc, 0) 1621 ); 1622 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 1623 POW_SM(ratesArray[rateHt40_7] + ht40PowerIncForPdadc, 24) 1624 | POW_SM(ratesArray[rateHt40_6] + ht40PowerIncForPdadc, 16) 1625 | POW_SM(ratesArray[rateHt40_5] + ht40PowerIncForPdadc, 8) 1626 | POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0) 1627 ); 1628 /* Write the Dup/Ext 40 power per rate set */ 1629 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1630 POW_SM(ratesArray[rateExtOfdm], 24) 1631 | POW_SM(ratesArray[rateExtCck], 16) 1632 | POW_SM(ratesArray[rateDupOfdm], 8) 1633 | POW_SM(ratesArray[rateDupCck], 0) 1634 ); 1635 } 1636 1637 /* Write the Power subtraction for dynamic chain changing, for per-packet powertx */ 1638 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 1639 POW_SM(pModal->pwrDecreaseFor3Chain, 6) 1640 | POW_SM(pModal->pwrDecreaseFor2Chain, 0) 1641 ); 1642 return AH_TRUE; 1643#undef POW_SM 1644#undef N 1645} 1646 1647/* 1648 * Exported call to check for a recent gain reading and return 1649 * the current state of the thermal calibration gain engine. 1650 */ 1651HAL_RFGAIN 1652ar5416GetRfgain(struct ath_hal *ah) 1653{ 1654 return HAL_RFGAIN_INACTIVE; 1655} 1656 1657/* 1658 * Places all of hardware into reset 1659 */ 1660HAL_BOOL 1661ar5416Disable(struct ath_hal *ah) 1662{ 1663 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 1664 return AH_FALSE; 1665 return ar5416SetResetReg(ah, HAL_RESET_COLD); 1666} 1667 1668/* 1669 * Places the PHY and Radio chips into reset. A full reset 1670 * must be called to leave this state. The PCI/MAC/PCU are 1671 * not placed into reset as we must receive interrupt to 1672 * re-enable the hardware. 1673 */ 1674HAL_BOOL 1675ar5416PhyDisable(struct ath_hal *ah) 1676{ 1677 return ar5416SetResetReg(ah, HAL_RESET_WARM); 1678} 1679 1680/* 1681 * Write the given reset bit mask into the reset register 1682 */ 1683HAL_BOOL 1684ar5416SetResetReg(struct ath_hal *ah, uint32_t type) 1685{ 1686 /* 1687 * Set force wake 1688 */ 1689 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1690 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1691 1692 switch (type) { 1693 case HAL_RESET_POWER_ON: 1694 return ar5416SetResetPowerOn(ah); 1695 break; 1696 case HAL_RESET_WARM: 1697 case HAL_RESET_COLD: 1698 return ar5416SetReset(ah, type); 1699 break; 1700 default: 1701 return AH_FALSE; 1702 } 1703} 1704 1705static HAL_BOOL 1706ar5416SetResetPowerOn(struct ath_hal *ah) 1707{ 1708 /* Power On Reset (Hard Reset) */ 1709 1710 /* 1711 * Set force wake 1712 * 1713 * If the MAC was running, previously calling 1714 * reset will wake up the MAC but it may go back to sleep 1715 * before we can start polling. 1716 * Set force wake stops that 1717 * This must be called before initiating a hard reset. 1718 */ 1719 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1720 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1721 1722 /* 1723 * RTC reset and clear 1724 */ 1725 OS_REG_WRITE(ah, AR_RTC_RESET, 0); 1726 OS_DELAY(20); 1727 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 1728 1729 /* 1730 * Poll till RTC is ON 1731 */ 1732 if (!ath_hal_wait(ah, AR_RTC_STATUS, AR_RTC_PM_STATUS_M, AR_RTC_STATUS_ON)) { 1733 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC not waking up\n", __func__); 1734 return AH_FALSE; 1735 } 1736 1737 return ar5416SetReset(ah, HAL_RESET_COLD); 1738} 1739 1740static HAL_BOOL 1741ar5416SetReset(struct ath_hal *ah, int type) 1742{ 1743 uint32_t tmpReg; 1744 1745 /* 1746 * Force wake 1747 */ 1748 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1749 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1750 1751 /* 1752 * Reset AHB 1753 */ 1754 tmpReg = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE); 1755 if (tmpReg & (AR_INTR_SYNC_LOCAL_TIMEOUT|AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { 1756 OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 1757 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF); 1758 } else { 1759 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB); 1760 } 1761 1762 /* 1763 * Set Mac(BB,Phy) Warm Reset 1764 */ 1765 switch (type) { 1766 case HAL_RESET_WARM: 1767 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM); 1768 break; 1769 case HAL_RESET_COLD: 1770 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM|AR_RTC_RC_MAC_COLD); 1771 break; 1772 default: 1773 HALASSERT(0); 1774 break; 1775 } 1776 1777 /* 1778 * Clear resets and force wakeup 1779 */ 1780 OS_REG_WRITE(ah, AR_RTC_RC, 0); 1781 if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) { 1782 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC stuck in MAC reset\n", __func__); 1783 return AH_FALSE; 1784 } 1785 1786 /* Clear AHB reset */ 1787 OS_REG_WRITE(ah, AR_RC, 0); 1788 1789 /* Set register and descriptor swapping on 1790 * Bigendian platforms on cold reset 1791 */ 1792#ifdef __BIG_ENDIAN__ 1793 if (type == HAL_RESET_COLD) { 1794 uint32_t mask; 1795 1796 HALDEBUG(ah, HAL_DEBUG_RESET, 1797 "%s Applying descriptor swap\n", __func__); 1798 1799 mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG; 1800#ifndef AH_NEED_DESC_SWAP 1801 mask |= AR_CFG_SWTD; 1802#endif 1803 OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask)); 1804 } 1805#endif 1806 1807 ar5416InitPLL(ah, AH_NULL); 1808 1809 return AH_TRUE; 1810} 1811 1812#ifndef IS_5GHZ_FAST_CLOCK_EN 1813#define IS_5GHZ_FAST_CLOCK_EN(ah, chan) AH_FALSE 1814#endif 1815 1816static void 1817ar5416InitPLL(struct ath_hal *ah, HAL_CHANNEL *chan) 1818{ 1819 uint32_t pll; 1820 1821 if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1822 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1823 1824 if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) { 1825 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1826 } else if (chan && IS_CHAN_QUARTER_RATE(chan)) { 1827 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1828 } 1829 if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) { 1830 pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV); 1831 1832 /* 1833 * PLL WAR for Merlin 2.0/2.1 1834 * When doing fast clock, set PLL to 0x142c 1835 * Else, set PLL to 0x2850 to prevent reset-to-reset variation 1836 */ 1837 if (AR_SREV_MERLIN_20(ah)) { 1838 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 1839 pll = 0x142c; 1840 } else { 1841 pll = 0x2850; 1842 } 1843 } 1844 } else { 1845 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); 1846 } 1847 } else if (AR_SREV_SOWL_10_OR_LATER(ah)) { 1848 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1849 1850 if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) { 1851 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1852 } else if (chan && IS_CHAN_QUARTER_RATE(chan)) { 1853 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1854 } 1855 if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) { 1856 pll |= SM(0x50, AR_RTC_SOWL_PLL_DIV); 1857 } else { 1858 pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV); 1859 } 1860 } else { 1861 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; 1862 1863 if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) { 1864 pll |= SM(0x1, AR_RTC_PLL_CLKSEL); 1865 } else if (chan != AH_NULL && IS_CHAN_QUARTER_RATE(chan)) { 1866 pll |= SM(0x2, AR_RTC_PLL_CLKSEL); 1867 } 1868 if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) { 1869 pll |= SM(0xa, AR_RTC_PLL_DIV); 1870 } else { 1871 pll |= SM(0xb, AR_RTC_PLL_DIV); 1872 } 1873 } 1874 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 1875 1876 /* TODO: 1877 * For multi-band owl, switch between bands by reiniting the PLL. 1878 */ 1879 1880 OS_DELAY(RTC_PLL_SETTLE_DELAY); 1881 1882 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK); 1883} 1884 1885/* 1886 * Read EEPROM header info and program the device for correct operation 1887 * given the channel value. 1888 */ 1889static HAL_BOOL 1890ar5416SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 1891{ 1892 const HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 1893 const struct ar5416eeprom *eep = &ee->ee_base; 1894 const MODAL_EEP_HEADER *pModal; 1895 int i, regChainOffset; 1896 uint8_t txRxAttenLocal; /* workaround for eeprom versions <= 14.2 */ 1897 1898 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 1899 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1900 1901 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; /* workaround for eeprom versions <= 14.2 */ 1902 1903 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 1904 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1905 if (AR_SREV_MERLIN(ah)) { 1906 if (i >= 2) break; 1907 } 1908 if (AR_SREV_OWL_20_OR_LATER(ah) && 1909 (AH5416(ah)->ah_rx_chainmask == 0x5 || 1910 AH5416(ah)->ah_tx_chainmask == 0x5) && i != 0) { 1911 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 1912 * only chains 0 and 2 populated 1913 */ 1914 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1915 } else { 1916 regChainOffset = i * 0x1000; 1917 } 1918 1919 OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, pModal->antCtrlChain[i]); 1920 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset, 1921 (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) & 1922 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1923 SM(pModal->iqCalICh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1924 SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1925 1926 /* 1927 * Large signal upgrade. 1928 * XXX update 1929 */ 1930 1931 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { 1932 OS_REG_WRITE(ah, AR_PHY_RXGAIN + regChainOffset, 1933 (OS_REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & ~AR_PHY_RXGAIN_TXRX_ATTEN) | 1934 SM(IS_EEP_MINOR_V3(ah) ? pModal->txRxAttenCh[i] : txRxAttenLocal, 1935 AR_PHY_RXGAIN_TXRX_ATTEN)); 1936 1937 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1938 (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) | 1939 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN)); 1940 } 1941 } 1942 1943 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling); 1944 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); 1945 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize); 1946 OS_REG_WRITE(ah, AR_PHY_RF_CTL4, 1947 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 1948 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 1949 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) 1950 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1951 1952 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); 1953 1954 if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1955 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1956 pModal->thresh62); 1957 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 1958 pModal->thresh62); 1959 } else { 1960 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, 1961 pModal->thresh62); 1962 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA_THRESH62, 1963 pModal->thresh62); 1964 } 1965 1966 /* Minor Version Specific application */ 1967 if (IS_EEP_MINOR_V2(ah)) { 1968 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart); 1969 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn); 1970 } 1971 1972 if (IS_EEP_MINOR_V3(ah)) { 1973 if (IS_CHAN_HT40(chan)) { 1974 /* Overwrite switch settling with HT40 value */ 1975 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); 1976 } 1977 1978 if ((AR_SREV_OWL_20_OR_LATER(ah)) && 1979 ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5)){ 1980 /* Reg Offsets are swapped for logical mapping */ 1981 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | 1982 SM(pModal->bswMargin[2], AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1983 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | 1984 SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1985 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | 1986 SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1987 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | 1988 SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1989 } else { 1990 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | 1991 SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1992 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | 1993 SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1994 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | 1995 SM(pModal->bswMargin[2],AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1996 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | 1997 SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1998 } 1999 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_MARGIN, pModal->bswMargin[0]); 2000 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_ATTEN, pModal->bswAtten[0]); 2001 } 2002 return AH_TRUE; 2003} 2004 2005/* 2006 * Helper functions common for AP/CB/XB 2007 */ 2008 2009/* 2010 * ar5416SetPowerPerRateTable 2011 * 2012 * Sets the transmit power in the baseband for the given 2013 * operating channel and mode. 2014 */ 2015static HAL_BOOL 2016ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 2017 HAL_CHANNEL_INTERNAL *chan, 2018 int16_t *ratesArray, uint16_t cfgCtl, 2019 uint16_t AntennaReduction, 2020 uint16_t twiceMaxRegulatoryPower, 2021 uint16_t powerLimit) 2022{ 2023#define N(a) (sizeof(a)/sizeof(a[0])) 2024/* Local defines to distinguish between extension and control CTL's */ 2025#define EXT_ADDITIVE (0x8000) 2026#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 2027#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 2028#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 2029 2030 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 2031 int i; 2032 int16_t twiceLargestAntenna; 2033 CAL_CTL_DATA *rep; 2034 CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}}; 2035 CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}}; 2036 CAL_TARGET_POWER_HT targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}}; 2037 int16_t scaledPower, minCtlPower; 2038 2039#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 2040#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 2041 static const uint16_t ctlModesFor11a[] = { 2042 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 2043 }; 2044 static const uint16_t ctlModesFor11g[] = { 2045 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 2046 }; 2047 const uint16_t *pCtlMode; 2048 uint16_t numCtlModes, ctlMode, freq; 2049 CHAN_CENTERS centers; 2050 2051 ar5416GetChannelCenters(ah, chan, ¢ers); 2052 2053 /* Compute TxPower reduction due to Antenna Gain */ 2054 2055 twiceLargestAntenna = AH_MAX(AH_MAX(pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[0], 2056 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[1]), 2057 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 2058#if 0 2059 /* Turn it back on if we need to calculate per chain antenna gain reduction */ 2060 /* Use only if the expected gain > 6dbi */ 2061 /* Chain 0 is always used */ 2062 twiceLargestAntenna = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[0]; 2063 2064 /* Look at antenna gains of Chains 1 and 2 if the TX mask is set */ 2065 if (ahp->ah_tx_chainmask & 0x2) 2066 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 2067 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[1]); 2068 2069 if (ahp->ah_tx_chainmask & 0x4) 2070 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 2071 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 2072#endif 2073 twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0); 2074 2075 /* XXX setup for 5212 use (really used?) */ 2076 ath_hal_eepromSet(ah, 2077 IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5, 2078 twiceLargestAntenna); 2079 2080 /* 2081 * scaledPower is the minimum of the user input power level and 2082 * the regulatory allowed power level 2083 */ 2084 scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna); 2085 2086 /* Reduce scaled Power by number of chains active to get to per chain tx power level */ 2087 /* TODO: better value than these? */ 2088 switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) { 2089 case 1: 2090 break; 2091 case 2: 2092 scaledPower -= pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain; 2093 break; 2094 case 3: 2095 scaledPower -= pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain; 2096 break; 2097 default: 2098 return AH_FALSE; /* Unsupported number of chains */ 2099 } 2100 2101 scaledPower = AH_MAX(0, scaledPower); 2102 2103 /* Get target powers from EEPROM - our baseline for TX Power */ 2104 if (IS_CHAN_2GHZ(chan)) { 2105 /* Setup for CTL modes */ 2106 numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */ 2107 pCtlMode = ctlModesFor11g; 2108 2109 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 2110 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE); 2111 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 2112 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 2113 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT20, 2114 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 2115 2116 if (IS_CHAN_HT40(chan)) { 2117 numCtlModes = N(ctlModesFor11g); /* All 2G CTL's */ 2118 2119 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT40, 2120 AR5416_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 2121 /* Get target powers for extension channels */ 2122 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 2123 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE); 2124 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 2125 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 2126 } 2127 } else { 2128 /* Setup for CTL modes */ 2129 numCtlModes = N(ctlModesFor11a) - SUB_NUM_CTL_MODES_AT_5G_40; /* CTL_11A, CTL_5GHT20 */ 2130 pCtlMode = ctlModesFor11a; 2131 2132 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 2133 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 2134 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT20, 2135 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 2136 2137 if (IS_CHAN_HT40(chan)) { 2138 numCtlModes = N(ctlModesFor11a); /* All 5G CTL's */ 2139 2140 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT40, 2141 AR5416_NUM_5G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 2142 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 2143 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 2144 } 2145 } 2146 2147 /* 2148 * For MIMO, need to apply regulatory caps individually across dynamically 2149 * running modes: CCK, OFDM, HT20, HT40 2150 * 2151 * The outer loop walks through each possible applicable runtime mode. 2152 * The inner loop walks through each ctlIndex entry in EEPROM. 2153 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. 2154 * 2155 */ 2156 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 2157 2158 HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 2159 (pCtlMode[ctlMode] == CTL_2GHT40); 2160 if (isHt40CtlMode) { 2161 freq = centers.ctl_center; 2162 } else if (pCtlMode[ctlMode] & EXT_ADDITIVE) { 2163 freq = centers.ext_center; 2164 } else { 2165 freq = centers.ctl_center; 2166 } 2167 2168 /* walk through each CTL index stored in EEPROM */ 2169 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 2170 uint16_t twiceMinEdgePower; 2171 2172 /* compare test group from regulatory channel list with test mode from pCtlMode list */ 2173 if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) || 2174 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == 2175 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { 2176 rep = &(pEepData->ctlData[i]); 2177 twiceMinEdgePower = ar5416GetMaxEdgePower(freq, 2178 rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1], 2179 IS_CHAN_2GHZ(chan)); 2180 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 2181 /* Find the minimum of all CTL edge powers that apply to this channel */ 2182 twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower); 2183 } else { 2184 /* specific */ 2185 twiceMaxEdgePower = twiceMinEdgePower; 2186 break; 2187 } 2188 } 2189 } 2190 minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower); 2191 /* Apply ctl mode to correct target power set */ 2192 switch(pCtlMode[ctlMode]) { 2193 case CTL_11B: 2194 for (i = 0; i < N(targetPowerCck.tPow2x); i++) { 2195 targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower); 2196 } 2197 break; 2198 case CTL_11A: 2199 case CTL_11G: 2200 for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) { 2201 targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower); 2202 } 2203 break; 2204 case CTL_5GHT20: 2205 case CTL_2GHT20: 2206 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 2207 targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower); 2208 } 2209 break; 2210 case CTL_11B_EXT: 2211 targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower); 2212 break; 2213 case CTL_11A_EXT: 2214 case CTL_11G_EXT: 2215 targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower); 2216 break; 2217 case CTL_5GHT40: 2218 case CTL_2GHT40: 2219 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 2220 targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower); 2221 } 2222 break; 2223 default: 2224 return AH_FALSE; 2225 break; 2226 } 2227 } /* end ctl mode checking */ 2228 2229 /* Set rates Array from collected data */ 2230 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0]; 2231 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 2232 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 2233 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 2234 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 2235 2236 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 2237 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 2238 } 2239 2240 if (IS_CHAN_2GHZ(chan)) { 2241 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 2242 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 2243 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 2244 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 2245 } 2246 if (IS_CHAN_HT40(chan)) { 2247 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 2248 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i]; 2249 } 2250 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 2251 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 2252 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 2253 if (IS_CHAN_2GHZ(chan)) { 2254 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 2255 } 2256 } 2257 return AH_TRUE; 2258#undef EXT_ADDITIVE 2259#undef CTL_11A_EXT 2260#undef CTL_11G_EXT 2261#undef CTL_11B_EXT 2262#undef SUB_NUM_CTL_MODES_AT_5G_40 2263#undef SUB_NUM_CTL_MODES_AT_2G_40 2264#undef N 2265} 2266 2267/************************************************************************** 2268 * fbin2freq 2269 * 2270 * Get channel value from binary representation held in eeprom 2271 * RETURNS: the frequency in MHz 2272 */ 2273static uint16_t 2274fbin2freq(uint8_t fbin, HAL_BOOL is2GHz) 2275{ 2276 /* 2277 * Reserved value 0xFF provides an empty definition both as 2278 * an fbin and as a frequency - do not convert 2279 */ 2280 if (fbin == AR5416_BCHAN_UNUSED) { 2281 return fbin; 2282 } 2283 2284 return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 2285} 2286 2287/* 2288 * ar5416GetMaxEdgePower 2289 * 2290 * Find the maximum conformance test limit for the given channel and CTL info 2291 */ 2292static uint16_t 2293ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz) 2294{ 2295 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 2296 int i; 2297 2298 /* Get the edge power */ 2299 for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) { 2300 /* 2301 * If there's an exact channel match or an inband flag set 2302 * on the lower channel use the given rdEdgePower 2303 */ 2304 if (freq == fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { 2305 twiceMaxEdgePower = MS(pRdEdgesPower[i].tPowerFlag, CAL_CTL_EDGES_POWER); 2306 break; 2307 } else if ((i > 0) && (freq < fbin2freq(pRdEdgesPower[i].bChannel, is2GHz))) { 2308 if (fbin2freq(pRdEdgesPower[i - 1].bChannel, is2GHz) < freq && (pRdEdgesPower[i - 1].tPowerFlag & CAL_CTL_EDGES_FLAG) != 0) { 2309 twiceMaxEdgePower = MS(pRdEdgesPower[i - 1].tPowerFlag, CAL_CTL_EDGES_POWER); 2310 } 2311 /* Leave loop - no more affecting edges possible in this monotonic increasing list */ 2312 break; 2313 } 2314 } 2315 HALASSERT(twiceMaxEdgePower > 0); 2316 return twiceMaxEdgePower; 2317} 2318 2319/************************************************************** 2320 * ar5416GetTargetPowers 2321 * 2322 * Return the rates of target power for the given target power table 2323 * channel, and number of channels 2324 */ 2325static void 2326ar5416GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, 2327 CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels, 2328 CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates, 2329 HAL_BOOL isHt40Target) 2330{ 2331 uint16_t clo, chi; 2332 int i; 2333 int matchIndex = -1, lowIndex = -1; 2334 uint16_t freq; 2335 CHAN_CENTERS centers; 2336 2337 ar5416GetChannelCenters(ah, chan, ¢ers); 2338 freq = isHt40Target ? centers.synth_center : centers.ctl_center; 2339 2340 /* Copy the target powers into the temp channel list */ 2341 if (freq <= fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) { 2342 matchIndex = 0; 2343 } else { 2344 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 2345 if (freq == fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) { 2346 matchIndex = i; 2347 break; 2348 } else if ((freq < fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) && 2349 (freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan)))) 2350 { 2351 lowIndex = i - 1; 2352 break; 2353 } 2354 } 2355 if ((matchIndex == -1) && (lowIndex == -1)) { 2356 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan))); 2357 matchIndex = i - 1; 2358 } 2359 } 2360 2361 if (matchIndex != -1) { 2362 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 2363 } else { 2364 HALASSERT(lowIndex != -1); 2365 /* 2366 * Get the lower and upper channels, target powers, 2367 * and interpolate between them. 2368 */ 2369 clo = fbin2freq(powInfo[lowIndex].bChannel, IS_CHAN_2GHZ(chan)); 2370 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IS_CHAN_2GHZ(chan)); 2371 2372 for (i = 0; i < numRates; i++) { 2373 pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi, 2374 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 2375 } 2376 } 2377} 2378/************************************************************** 2379 * ar5416GetTargetPowersLeg 2380 * 2381 * Return the four rates of target power for the given target power table 2382 * channel, and number of channels 2383 */ 2384static void 2385ar5416GetTargetPowersLeg(struct ath_hal *ah, 2386 HAL_CHANNEL_INTERNAL *chan, 2387 CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels, 2388 CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates, 2389 HAL_BOOL isExtTarget) 2390{ 2391 uint16_t clo, chi; 2392 int i; 2393 int matchIndex = -1, lowIndex = -1; 2394 uint16_t freq; 2395 CHAN_CENTERS centers; 2396 2397 ar5416GetChannelCenters(ah, chan, ¢ers); 2398 freq = (isExtTarget) ? centers.ext_center :centers.ctl_center; 2399 2400 /* Copy the target powers into the temp channel list */ 2401 if (freq <= fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) { 2402 matchIndex = 0; 2403 } else { 2404 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 2405 if (freq == fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) { 2406 matchIndex = i; 2407 break; 2408 } else if ((freq < fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) && 2409 (freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan)))) 2410 { 2411 lowIndex = i - 1; 2412 break; 2413 } 2414 } 2415 if ((matchIndex == -1) && (lowIndex == -1)) { 2416 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan))); 2417 matchIndex = i - 1; 2418 } 2419 } 2420 2421 if (matchIndex != -1) { 2422 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 2423 } else { 2424 HALASSERT(lowIndex != -1); 2425 /* 2426 * Get the lower and upper channels, target powers, 2427 * and interpolate between them. 2428 */ 2429 clo = fbin2freq(powInfo[lowIndex].bChannel, IS_CHAN_2GHZ(chan)); 2430 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IS_CHAN_2GHZ(chan)); 2431 2432 for (i = 0; i < numRates; i++) { 2433 pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi, 2434 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 2435 } 2436 } 2437} 2438 2439/************************************************************** 2440 * ar5416SetPowerCalTable 2441 * 2442 * Pull the PDADC piers from cal data and interpolate them across the given 2443 * points as well as from the nearest pier(s) to get a power detector 2444 * linear voltage to power level table. 2445 */ 2446static HAL_BOOL 2447ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, HAL_CHANNEL_INTERNAL *chan, int16_t *pTxPowerIndexOffset) 2448{ 2449 CAL_DATA_PER_FREQ *pRawDataset; 2450 uint8_t *pCalBChans = AH_NULL; 2451 uint16_t pdGainOverlap_t2; 2452 static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES]; 2453 uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 2454 uint16_t numPiers, i, j; 2455 int16_t tMinCalPower; 2456 uint16_t numXpdGain, xpdMask; 2457 uint16_t xpdGainValues[AR5416_NUM_PD_GAINS]; 2458 uint32_t reg32, regOffset, regChainOffset; 2459 2460 ath_hal_memzero(xpdGainValues, sizeof(xpdGainValues)); 2461 2462 xpdMask = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].xpdGain; 2463 2464 if (IS_EEP_MINOR_V2(ah)) { 2465 pdGainOverlap_t2 = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pdGainOverlap; 2466 } else { 2467 pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 2468 } 2469 2470 if (IS_CHAN_2GHZ(chan)) { 2471 pCalBChans = pEepData->calFreqPier2G; 2472 numPiers = AR5416_NUM_2G_CAL_PIERS; 2473 } else { 2474 pCalBChans = pEepData->calFreqPier5G; 2475 numPiers = AR5416_NUM_5G_CAL_PIERS; 2476 } 2477 2478 numXpdGain = 0; 2479 /* Calculate the value of xpdgains from the xpdGain Mask */ 2480 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 2481 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 2482 if (numXpdGain >= AR5416_NUM_PD_GAINS) { 2483 HALASSERT(0); 2484 break; 2485 } 2486 xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i); 2487 numXpdGain++; 2488 } 2489 } 2490 2491 /* Write the detector gain biases and their number */ 2492 OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 2493 ~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 2494 SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) | 2495 SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(xpdGainValues[2], AR_PHY_TPCRG1_PD_GAIN_3)); 2496 2497 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 2498 2499 if (AR_SREV_OWL_20_OR_LATER(ah) && 2500 ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) { 2501 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 2502 * only chains 0 and 2 populated 2503 */ 2504 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 2505 } else { 2506 regChainOffset = i * 0x1000; 2507 } 2508 2509 if (pEepData->baseEepHeader.txMask & (1 << i)) { 2510 if (IS_CHAN_2GHZ(chan)) { 2511 pRawDataset = pEepData->calPierData2G[i]; 2512 } else { 2513 pRawDataset = pEepData->calPierData5G[i]; 2514 } 2515 2516 ar5416GetGainBoundariesAndPdadcs(ah, chan, pRawDataset, 2517 pCalBChans, numPiers, 2518 pdGainOverlap_t2, 2519 &tMinCalPower, gainBoundaries, 2520 pdadcValues, numXpdGain); 2521 2522 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { 2523 /* 2524 * Note the pdadc table may not start at 0 dBm power, could be 2525 * negative or greater than 0. Need to offset the power 2526 * values by the amount of minPower for griffin 2527 */ 2528 2529 OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 2530 SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 2531 SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | 2532 SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | 2533 SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | 2534 SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 2535 } 2536 2537 /* Write the power values into the baseband power table */ 2538 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 2539 2540 for (j = 0; j < 32; j++) { 2541 reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0) | 2542 ((pdadcValues[4*j + 1] & 0xFF) << 8) | 2543 ((pdadcValues[4*j + 2] & 0xFF) << 16) | 2544 ((pdadcValues[4*j + 3] & 0xFF) << 24) ; 2545 OS_REG_WRITE(ah, regOffset, reg32); 2546 2547#ifdef PDADC_DUMP 2548 ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n", 2549 i, 2550 4*j, pdadcValues[4*j], 2551 4*j+1, pdadcValues[4*j + 1], 2552 4*j+2, pdadcValues[4*j + 2], 2553 4*j+3, pdadcValues[4*j + 3]); 2554#endif 2555 regOffset += 4; 2556 } 2557 } 2558 } 2559 *pTxPowerIndexOffset = 0; 2560 2561 return AH_TRUE; 2562} 2563 2564/************************************************************** 2565 * ar5416GetGainBoundariesAndPdadcs 2566 * 2567 * Uses the data points read from EEPROM to reconstruct the pdadc power table 2568 * Called by ar5416SetPowerCalTable only. 2569 */ 2570static void 2571ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 2572 HAL_CHANNEL_INTERNAL *chan, CAL_DATA_PER_FREQ *pRawDataSet, 2573 uint8_t * bChans, uint16_t availPiers, 2574 uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries, 2575 uint8_t * pPDADCValues, uint16_t numXpdGains) 2576{ 2577 2578 int i, j, k; 2579 int16_t ss; /* potentially -ve index for taking care of pdGainOverlap */ 2580 uint16_t idxL, idxR, numPiers; /* Pier indexes */ 2581 2582 /* filled out Vpd table for all pdGains (chanL) */ 2583 static uint8_t vpdTableL[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2584 2585 /* filled out Vpd table for all pdGains (chanR) */ 2586 static uint8_t vpdTableR[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2587 2588 /* filled out Vpd table for all pdGains (interpolated) */ 2589 static uint8_t vpdTableI[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2590 2591 uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR; 2592 uint8_t minPwrT4[AR5416_NUM_PD_GAINS]; 2593 uint8_t maxPwrT4[AR5416_NUM_PD_GAINS]; 2594 int16_t vpdStep; 2595 int16_t tmpVal; 2596 uint16_t sizeCurrVpdTable, maxIndex, tgtIndex; 2597 HAL_BOOL match; 2598 int16_t minDelta = 0; 2599 CHAN_CENTERS centers; 2600 2601 ar5416GetChannelCenters(ah, chan, ¢ers); 2602 2603 /* Trim numPiers for the number of populated channel Piers */ 2604 for (numPiers = 0; numPiers < availPiers; numPiers++) { 2605 if (bChans[numPiers] == AR5416_BCHAN_UNUSED) { 2606 break; 2607 } 2608 } 2609 2610 /* Find pier indexes around the current channel */ 2611 match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), 2612 bChans, numPiers, &idxL, &idxR); 2613 2614 if (match) { 2615 /* Directly fill both vpd tables from the matching index */ 2616 for (i = 0; i < numXpdGains; i++) { 2617 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 2618 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 2619 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i], 2620 pRawDataSet[idxL].vpdPdg[i], AR5416_PD_GAIN_ICEPTS, vpdTableI[i]); 2621 } 2622 } else { 2623 for (i = 0; i < numXpdGains; i++) { 2624 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 2625 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 2626 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 2627 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 2628 2629 /* Start Vpd interpolation from the max of the minimum powers */ 2630 minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]); 2631 2632 /* End Vpd interpolation from the min of the max powers */ 2633 maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); 2634 HALASSERT(maxPwrT4[i] > minPwrT4[i]); 2635 2636 /* Fill pier Vpds */ 2637 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]); 2638 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]); 2639 2640 /* Interpolate the final vpd */ 2641 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 2642 vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), 2643 bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j])); 2644 } 2645 } 2646 } 2647 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 2648 2649 k = 0; /* index for the final table */ 2650 for (i = 0; i < numXpdGains; i++) { 2651 if (i == (numXpdGains - 1)) { 2652 pPdGainBoundaries[i] = (uint16_t)(maxPwrT4[i] / 2); 2653 } else { 2654 pPdGainBoundaries[i] = (uint16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4); 2655 } 2656 2657 pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); 2658 2659 /* NB: only applies to owl 1.0 */ 2660 if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { 2661 /* 2662 * fix the gain delta, but get a delta that can be applied to min to 2663 * keep the upper power values accurate, don't think max needs to 2664 * be adjusted because should not be at that area of the table? 2665 */ 2666 minDelta = pPdGainBoundaries[0] - 23; 2667 pPdGainBoundaries[0] = 23; 2668 } 2669 else { 2670 minDelta = 0; 2671 } 2672 2673 /* Find starting index for this pdGain */ 2674 if (i == 0) { 2675 ss = 0; /* for the first pdGain, start from index 0 */ 2676 } else { 2677 /* need overlap entries extrapolated below. */ 2678 ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta); 2679 } 2680 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 2681 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2682 /* 2683 *-ve ss indicates need to extrapolate data below for this pdGain 2684 */ 2685 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2686 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 2687 pPDADCValues[k++] = (uint8_t)((tmpVal < 0) ? 0 : tmpVal); 2688 ss++; 2689 } 2690 2691 sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1); 2692 tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2)); 2693 maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable; 2694 2695 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2696 pPDADCValues[k++] = vpdTableI[i][ss++]; 2697 } 2698 2699 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]); 2700 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2701 /* 2702 * for last gain, pdGainBoundary == Pmax_t2, so will 2703 * have to extrapolate 2704 */ 2705 if (tgtIndex > maxIndex) { /* need to extrapolate above */ 2706 while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2707 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + 2708 (ss - maxIndex +1) * vpdStep)); 2709 pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ? 255 : tmpVal); 2710 ss++; 2711 } 2712 } /* extrapolated above */ 2713 } /* for all pdGainUsed */ 2714 2715 /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */ 2716 while (i < AR5416_PD_GAINS_IN_MASK) { 2717 pPdGainBoundaries[i] = pPdGainBoundaries[i-1]; 2718 i++; 2719 } 2720 2721 while (k < AR5416_NUM_PDADC_VALUES) { 2722 pPDADCValues[k] = pPDADCValues[k-1]; 2723 k++; 2724 } 2725 return; 2726} 2727 2728/************************************************************** 2729 * getLowerUppderIndex 2730 * 2731 * Return indices surrounding the value in sorted integer lists. 2732 * Requirement: the input list must be monotonically increasing 2733 * and populated up to the list size 2734 * Returns: match is set if an index in the array matches exactly 2735 * or a the target is before or after the range of the array. 2736 */ 2737HAL_BOOL 2738getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize, 2739 uint16_t *indexL, uint16_t *indexR) 2740{ 2741 uint16_t i; 2742 2743 /* 2744 * Check first and last elements for beyond ordered array cases. 2745 */ 2746 if (target <= pList[0]) { 2747 *indexL = *indexR = 0; 2748 return AH_TRUE; 2749 } 2750 if (target >= pList[listSize-1]) { 2751 *indexL = *indexR = (uint16_t)(listSize - 1); 2752 return AH_TRUE; 2753 } 2754 2755 /* look for value being near or between 2 values in list */ 2756 for (i = 0; i < listSize - 1; i++) { 2757 /* 2758 * If value is close to the current value of the list 2759 * then target is not between values, it is one of the values 2760 */ 2761 if (pList[i] == target) { 2762 *indexL = *indexR = i; 2763 return AH_TRUE; 2764 } 2765 /* 2766 * Look for value being between current value and next value 2767 * if so return these 2 values 2768 */ 2769 if (target < pList[i + 1]) { 2770 *indexL = i; 2771 *indexR = (uint16_t)(i + 1); 2772 return AH_FALSE; 2773 } 2774 } 2775 HALASSERT(0); 2776 return AH_FALSE; 2777} 2778 2779/************************************************************** 2780 * ar5416FillVpdTable 2781 * 2782 * Fill the Vpdlist for indices Pmax-Pmin 2783 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 2784 */ 2785static HAL_BOOL 2786ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList, 2787 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList) 2788{ 2789 uint16_t i, k; 2790 uint8_t currPwr = pwrMin; 2791 uint16_t idxL, idxR; 2792 2793 HALASSERT(pwrMax > pwrMin); 2794 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 2795 getLowerUpperIndex(currPwr, pPwrList, numIntercepts, 2796 &(idxL), &(idxR)); 2797 if (idxR < 1) 2798 idxR = 1; /* extrapolate below */ 2799 if (idxL == numIntercepts - 1) 2800 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */ 2801 if (pPwrList[idxL] == pPwrList[idxR]) 2802 k = pVpdList[idxL]; 2803 else 2804 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 2805 (pPwrList[idxR] - pPwrList[idxL]) ); 2806 HALASSERT(k < 256); 2807 pRetVpdList[i] = (uint8_t)k; 2808 currPwr += 2; /* half dB steps */ 2809 } 2810 2811 return AH_TRUE; 2812} 2813 2814/************************************************************************** 2815 * interpolate 2816 * 2817 * Returns signed interpolated or the scaled up interpolated value 2818 */ 2819static int16_t 2820interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 2821 int16_t targetLeft, int16_t targetRight) 2822{ 2823 int16_t rv; 2824 2825 if (srcRight == srcLeft) { 2826 rv = targetLeft; 2827 } else { 2828 rv = (int16_t)( ((target - srcLeft) * targetRight + 2829 (srcRight - target) * targetLeft) / (srcRight - srcLeft) ); 2830 } 2831 return rv; 2832} 2833 2834static void 2835ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan) 2836{ 2837 uint32_t phymode; 2838 HAL_HT_MACMODE macmode; /* MAC - 20/40 mode */ 2839 2840 if (!IS_CHAN_HT(chan)) 2841 return; 2842 2843 /* Enable 11n HT, 20 MHz */ 2844 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 2845 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH; 2846 2847 /* Configure baseband for dynamic 20/40 operation */ 2848 if (IS_CHAN_HT40(chan)) { 2849 phymode |= AR_PHY_FC_DYN2040_EN | AR_PHY_FC_SHORT_GI_40; 2850 2851 /* Configure control (primary) channel at +-10MHz */ 2852 if ((chan->channelFlags & CHANNEL_HT40PLUS)) 2853 phymode |= AR_PHY_FC_DYN2040_PRI_CH; 2854#if 0 2855 /* Configure 20/25 spacing */ 2856 if (ht->ht_extprotspacing == HAL_HT_EXTPROTSPACING_25) 2857 phymode |= AR_PHY_FC_DYN2040_EXT_CH; 2858#endif 2859 macmode = HAL_HT_MACMODE_2040; 2860 } else 2861 macmode = HAL_HT_MACMODE_20; 2862 OS_REG_WRITE(ah, AR_PHY_TURBO, phymode); 2863 2864 /* Configure MAC for 20/40 operation */ 2865 ar5416Set11nMac2040(ah, macmode); 2866 2867 /* global transmit timeout (25 TUs default)*/ 2868 /* XXX - put this elsewhere??? */ 2869 OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S) ; 2870 2871 /* carrier sense timeout */ 2872 OS_REG_SET_BIT(ah, AR_GTTM, AR_GTTM_CST_USEC); 2873 OS_REG_WRITE(ah, AR_CST, 1 << AR_CST_TIMEOUT_LIMIT_S); 2874} 2875 2876void 2877ar5416GetChannelCenters(struct ath_hal *ah, 2878 HAL_CHANNEL_INTERNAL *chan, CHAN_CENTERS *centers) 2879{ 2880 centers->ctl_center = chan->channel; 2881 centers->synth_center = chan->channel; 2882 /* 2883 * In 20/40 phy mode, the center frequency is 2884 * "between" the control and extension channels. 2885 */ 2886 if (chan->channelFlags & CHANNEL_HT40PLUS) { 2887 centers->synth_center += HT40_CHANNEL_CENTER_SHIFT; 2888 centers->ext_center = 2889 centers->synth_center + HT40_CHANNEL_CENTER_SHIFT; 2890 } else if (chan->channelFlags & CHANNEL_HT40MINUS) { 2891 centers->synth_center -= HT40_CHANNEL_CENTER_SHIFT; 2892 centers->ext_center = 2893 centers->synth_center - HT40_CHANNEL_CENTER_SHIFT; 2894 } else { 2895 centers->ext_center = chan->channel; 2896 } 2897} | 21#include "ah.h" 22#include "ah_internal.h" 23#include "ah_devid.h" 24 25#include "ah_eeprom_v14.h" 26 27#include "ar5416/ar5416.h" 28#include "ar5416/ar5416reg.h" 29#include "ar5416/ar5416phy.h" 30#ifdef AH_SUPPORT_AR9280 31#include "ar5416/ar9280.h" 32#endif 33 34/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ 35#define EEP_MINOR(_ah) \ 36 (AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK) 37#define IS_EEP_MINOR_V2(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2) 38#define IS_EEP_MINOR_V3(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3) 39 40/* Additional Time delay to wait after activiting the Base band */ 41#define BASE_ACTIVATE_DELAY 100 /* 100 usec */ 42#define PLL_SETTLE_DELAY 300 /* 300 usec */ 43#define RTC_PLL_SETTLE_DELAY 1000 /* 1 ms */ 44 45static void ar5416InitDMA(struct ath_hal *ah); 46static void ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan); 47static void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode); 48static void ar5416InitQoS(struct ath_hal *ah); 49static void ar5416InitUserSettings(struct ath_hal *ah); 50 51static HAL_BOOL ar5416SetTransmitPower(struct ath_hal *ah, 52 HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain); 53 54#if 0 55static HAL_BOOL ar5416ChannelChange(struct ath_hal *, HAL_CHANNEL *); 56#endif 57static void ar5416SetDeltaSlope(struct ath_hal *, HAL_CHANNEL_INTERNAL *); 58static void ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan); 59#ifdef AH_SUPPORT_AR9280 60static void ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan); 61#endif 62 63static HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah); 64static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type); 65static void ar5416InitPLL(struct ath_hal *ah, HAL_CHANNEL *chan); 66static HAL_BOOL ar5416SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *); 67static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah, 68 struct ar5416eeprom *pEepData, 69 HAL_CHANNEL_INTERNAL *chan, int16_t *ratesArray, 70 uint16_t cfgCtl, uint16_t AntennaReduction, 71 uint16_t twiceMaxRegulatoryPower, 72 uint16_t powerLimit); 73static HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah, 74 struct ar5416eeprom *pEepData, 75 HAL_CHANNEL_INTERNAL *chan, 76 int16_t *pTxPowerIndexOffset); 77static uint16_t ar5416GetMaxEdgePower(uint16_t freq, 78 CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz); 79static void ar5416GetTargetPowers(struct ath_hal *ah, 80 HAL_CHANNEL_INTERNAL *chan, CAL_TARGET_POWER_HT *powInfo, 81 uint16_t numChannels, CAL_TARGET_POWER_HT *pNewPower, 82 uint16_t numRates, HAL_BOOL isHt40Target); 83static void ar5416GetTargetPowersLeg(struct ath_hal *ah, 84 HAL_CHANNEL_INTERNAL *chan, CAL_TARGET_POWER_LEG *powInfo, 85 uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower, 86 uint16_t numRates, HAL_BOOL isExtTarget); 87 88static int16_t interpolate(uint16_t target, uint16_t srcLeft, 89 uint16_t srcRight, int16_t targetLeft, int16_t targetRight); 90static void ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan); 91static void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 92 HAL_CHANNEL_INTERNAL *chan, CAL_DATA_PER_FREQ *pRawDataSet, 93 uint8_t * bChans, uint16_t availPiers, 94 uint16_t tPdGainOverlap, int16_t *pMinCalPower, 95 uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues, 96 uint16_t numXpdGains); 97static HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList, 98 uint16_t listSize, uint16_t *indexL, uint16_t *indexR); 99static HAL_BOOL ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, 100 uint8_t *pPwrList, uint8_t *pVpdList, 101 uint16_t numIntercepts, uint8_t *pRetVpdList); 102 103/* 104 * Places the device in and out of reset and then places sane 105 * values in the registers based on EEPROM config, initialization 106 * vectors (as determined by the mode), and station configuration 107 * 108 * bChannelChange is used to preserve DMA/PCU registers across 109 * a HW Reset during channel change. 110 */ 111HAL_BOOL 112ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, 113 HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status) 114{ 115#define N(a) (sizeof (a) / sizeof (a[0])) 116#define FAIL(_code) do { ecode = _code; goto bad; } while (0) 117 struct ath_hal_5212 *ahp = AH5212(ah); 118 HAL_CHANNEL_INTERNAL *ichan; 119 uint32_t softLedCfg; 120 uint32_t saveDefAntenna, saveLedState; 121 uint32_t macStaId1; 122 uint16_t rfXpdGain[2]; 123 u_int modesIndex, freqIndex; 124 HAL_STATUS ecode; 125 int i, regWrites = 0; 126 uint32_t powerVal, rssiThrReg; 127 uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow; 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 (!ar5416SetPowerMode(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 } else { 162 HALDEBUG(ah, HAL_DEBUG_RESET, 163 "%s: Ch=%u Max=%d Min=%d\n",__func__, 164 ichan->channel, ichan->maxTxPower, ichan->minTxPower); 165 } 166 switch (opmode) { 167 case HAL_M_STA: 168 case HAL_M_IBSS: 169 case HAL_M_HOSTAP: 170 case HAL_M_MONITOR: 171 break; 172 default: 173 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n", 174 __func__, opmode); 175 FAIL(HAL_EINVAL); 176 break; 177 } 178 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 179 180 /* XXX Turn on fast channel change for 5416 */ 181 /* 182 * Preserve the bmiss rssi threshold and count threshold 183 * across resets 184 */ 185 rssiThrReg = OS_REG_READ(ah, AR_RSSI_THR); 186 /* If reg is zero, first time thru set to default val */ 187 if (rssiThrReg == 0) 188 rssiThrReg = INIT_RSSI_THR; 189 190 /* 191 * Preserve the antenna on a channel change 192 */ 193 saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA); 194 if (saveDefAntenna == 0) /* XXX magic constants */ 195 saveDefAntenna = 1; 196 197 /* Save hardware flag before chip reset clears the register */ 198 macStaId1 = OS_REG_READ(ah, AR_STA_ID1) & 199 (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT); 200 201 /* Save led state from pci config register */ 202 saveLedState = OS_REG_READ(ah, AR_MAC_LED) & 203 (AR_MAC_LED_ASSOC | AR_MAC_LED_MODE | 204 AR_MAC_LED_BLINK_THRESH_SEL | AR_MAC_LED_BLINK_SLOW); 205 softLedCfg = OS_REG_READ(ah, AR_GPIO_INTR_OUT); 206 207 /* 208 * Adjust gain parameters before reset if 209 * there's an outstanding gain updated. 210 */ 211 (void) ar5416GetRfgain(ah); 212 213 if (!ar5416ChipReset(ah, chan)) { 214 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); 215 FAIL(HAL_EIO); 216 } 217 218 /* Restore bmiss rssi & count thresholds */ 219 OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg); 220 221 /* Setup the indices for the next set of register array writes */ 222 /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */ 223 switch (chan->channelFlags & CHANNEL_ALL) { 224 case CHANNEL_A: 225 case CHANNEL_A_HT20: 226 modesIndex = 1; 227 freqIndex = 1; 228 break; 229 case CHANNEL_T: 230 case CHANNEL_A_HT40PLUS: 231 case CHANNEL_A_HT40MINUS: 232 modesIndex = 2; 233 freqIndex = 1; 234 break; 235 case CHANNEL_PUREG: 236 case CHANNEL_G_HT20: 237 case CHANNEL_B: /* treat as channel G , no B mode suport in owl */ 238 modesIndex = 4; 239 freqIndex = 2; 240 break; 241 case CHANNEL_G_HT40PLUS: 242 case CHANNEL_G_HT40MINUS: 243 modesIndex = 3; 244 freqIndex = 2; 245 break; 246 case CHANNEL_108G: 247 modesIndex = 5; 248 freqIndex = 2; 249 break; 250 default: 251 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n", 252 __func__, chan->channelFlags); 253 FAIL(HAL_EINVAL); 254 } 255 256 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 257 258 /* Set correct Baseband to analog shift setting to access analog chips. */ 259 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 260 261 /* 262 * Write addac shifts 263 */ 264 OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); 265#if 0 266 /* NB: only required for Sowl */ 267 ar5416EepromSetAddac(ah, ichan); 268#endif 269 regWrites = ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_addac, 1, 270 regWrites); 271 OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); 272 273 /* XXX Merlin ini fixups */ 274 /* XXX Merlin 100us delay for shift registers */ 275 regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 276 regWrites); 277#ifdef AH_SUPPORT_AR9280 278 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 279 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain, 280 modesIndex, regWrites); 281 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain, 282 modesIndex, regWrites); 283 } 284#endif 285 /* XXX Merlin 100us delay for shift registers */ 286 regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_common, 1, regWrites); 287 /* Setup 11n MAC/Phy mode registers */ 288 ar5416Set11nRegs(ah,chan); 289 /* XXX updated regWrites? */ 290 ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites); 291#ifdef AH_SUPPORT_AR9280 292 if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 293 /* 5GHz channels w/ Fast Clock use different modal values */ 294 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes, 295 modesIndex, regWrites); 296 } 297#endif 298 299 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 300 301 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_DAG_CTRLCCK=0x%x\n", 302 __func__, OS_REG_READ(ah,AR_PHY_DAG_CTRLCCK)); 303 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_ADC_CTL=0x%x\n", 304 __func__, OS_REG_READ(ah,AR_PHY_ADC_CTL)); 305 306 /* Set the mute mask to the correct default */ 307 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) 308 OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F); 309 310 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) { 311 /* Clear reg to alllow RX_CLEAR line debug */ 312 OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0); 313 } 314 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) { 315#ifdef notyet 316 /* Enable burst prefetch for the data queues */ 317 OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... ); 318 /* Enable double-buffering */ 319 OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS); 320#endif 321 } 322 323 /* Set ADC/DAC select values */ 324 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e); 325 326 if (AH5416(ah)->ah_rx_chainmask == 0x5 || 327 AH5416(ah)->ah_tx_chainmask == 0x5) 328 OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); 329 /* Setup Chain Masks */ 330 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 331 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 332 OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask); 333 334 /* Setup the transmit power values. */ 335 if (!ar5416SetTransmitPower(ah, ichan, rfXpdGain)) { 336 HALDEBUG(ah, HAL_DEBUG_ANY, 337 "%s: error init'ing transmit power\n", __func__); 338 FAIL(HAL_EIO); 339 } 340 341 /* Write the analog registers */ 342 if (!ahp->ah_rfHal->setRfRegs(ah, ichan, freqIndex, rfXpdGain)) { 343 HALDEBUG(ah, HAL_DEBUG_ANY, 344 "%s: ar5212SetRfRegs failed\n", __func__); 345 FAIL(HAL_EIO); 346 } 347 348 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 349 if (IS_CHAN_OFDM(chan)|| IS_CHAN_HT(chan)) 350 ar5416SetDeltaSlope(ah, ichan); 351 352#ifdef AH_SUPPORT_AR9280 353 if (AR_SREV_MERLIN_10_OR_LATER(ah)) 354 ar9280SpurMitigate(ah, ichan); 355 else 356#endif 357 ar5416SpurMitigate(ah, ichan); 358 359 /* Setup board specific options for EEPROM version 3 */ 360 if (!ar5416SetBoardValues(ah, ichan)) { 361 HALDEBUG(ah, HAL_DEBUG_ANY, 362 "%s: error setting board options\n", __func__); 363 FAIL(HAL_EIO); 364 } 365 366 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 367 368 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 369 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) 370 | macStaId1 371 | AR_STA_ID1_RTS_USE_DEF 372 | ahp->ah_staId1Defaults 373 ); 374 ar5212SetOperatingMode(ah, opmode); 375 376 /* Set Venice BSSID mask according to current state */ 377 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask)); 378 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4)); 379 380 /* Restore previous led state */ 381 OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) | saveLedState); 382 /* Restore soft Led state to GPIO */ 383 OS_REG_WRITE(ah, AR_GPIO_INTR_OUT, softLedCfg); 384 385 /* Restore previous antenna */ 386 OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 387 388 /* then our BSSID */ 389 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 390 OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4)); 391 392 /* Restore bmiss rssi & count thresholds */ 393 OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr); 394 395 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ 396 397 if (!ar5212SetChannel(ah, ichan)) 398 FAIL(HAL_EIO); 399 400 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 401 402 /* Set 1:1 QCU to DCU mapping for all queues */ 403 for (i = 0; i < AR_NUM_DCU; i++) 404 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 405 406 ahp->ah_intrTxqs = 0; 407 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) 408 ar5212ResetTxQueue(ah, i); 409 410 ar5416InitIMR(ah, opmode); 411 ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); 412 ar5416InitQoS(ah); 413 ar5416InitUserSettings(ah); 414 415 /* 416 * disable seq number generation in hw 417 */ 418 OS_REG_WRITE(ah, AR_STA_ID1, 419 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 420 421 ar5416InitDMA(ah); 422 423 /* 424 * program OBS bus to see MAC interrupts 425 */ 426 OS_REG_WRITE(ah, AR_OBS, 8); 427 428#ifdef AR5416_INT_MITIGATION 429 OS_REG_WRITE(ah, AR_MIRT, 0); 430 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 431 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 432#endif 433 434 ar5416InitBB(ah, chan); 435 436 /* Setup compression registers */ 437 ar5212SetCompRegs(ah); /* XXX not needed? */ 438 439 /* 440 * 5416 baseband will check the per rate power table 441 * and select the lower of the two 442 */ 443 ackTpcPow = 63; 444 ctsTpcPow = 63; 445 chirpTpcPow = 63; 446 powerVal = SM(ackTpcPow, AR_TPC_ACK) | 447 SM(ctsTpcPow, AR_TPC_CTS) | 448 SM(chirpTpcPow, AR_TPC_CHIRP); 449 OS_REG_WRITE(ah, AR_TPC, powerVal); 450 451 if (!ar5416InitCal(ah, chan)) 452 FAIL(HAL_ESELFTEST); 453 454 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 455 456 if (bChannelChange) { 457 if (!(ichan->privFlags & CHANNEL_DFS)) 458 ichan->privFlags &= ~CHANNEL_INTERFERENCE; 459 chan->channelFlags = ichan->channelFlags; 460 chan->privFlags = ichan->privFlags; 461 chan->maxRegTxPower = ichan->maxRegTxPower; 462 chan->maxTxPower = ichan->maxTxPower; 463 chan->minTxPower = ichan->minTxPower; 464 } 465 466 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__); 467 468 OS_MARK(ah, AH_MARK_RESET_DONE, 0); 469 470 return AH_TRUE; 471bad: 472 OS_MARK(ah, AH_MARK_RESET_DONE, ecode); 473 if (*status) 474 *status = ecode; 475 return AH_FALSE; 476#undef FAIL 477#undef N 478} 479 480#if 0 481/* 482 * This channel change evaluates whether the selected hardware can 483 * perform a synthesizer-only channel change (no reset). If the 484 * TX is not stopped, or the RFBus cannot be granted in the given 485 * time, the function returns false as a reset is necessary 486 */ 487HAL_BOOL 488ar5416ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan) 489{ 490 uint32_t ulCount; 491 uint32_t data, synthDelay, qnum; 492 uint16_t rfXpdGain[4]; 493 struct ath_hal_5212 *ahp = AH5212(ah); 494 HAL_CHANNEL_INTERNAL *ichan; 495 496 /* 497 * Map public channel to private. 498 */ 499 ichan = ath_hal_checkchannel(ah, chan); 500 501 /* TX must be stopped or RF Bus grant will not work */ 502 for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) { 503 if (ar5212NumTxPending(ah, qnum)) { 504 HALDEBUG(ah, HAL_DEBUG_ANY, 505 "%s: frames pending on queue %d\n", __func__, qnum); 506 return AH_FALSE; 507 } 508 } 509 510 /* 511 * Kill last Baseband Rx Frame - Request analog bus grant 512 */ 513 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); 514 if (!ath_hal_wait(ah, AR_PHY_RFBUS_GNT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) { 515 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: could not kill baseband rx\n", 516 __func__); 517 return AH_FALSE; 518 } 519 520 ar5416Set11nRegs(ah, chan); /* NB: setup 5416-specific regs */ 521 522 /* Change the synth */ 523 if (!ar5212SetChannel(ah, ichan)) 524 return AH_FALSE; 525 526 /* Setup the transmit power values. */ 527 if (!ar5416SetTransmitPower(ah, ichan, rfXpdGain)) { 528 HALDEBUG(ah, HAL_DEBUG_ANY, 529 "%s: error init'ing transmit power\n", __func__); 530 return AH_FALSE; 531 } 532 533 /* 534 * Wait for the frequency synth to settle (synth goes on 535 * via PHY_ACTIVE_EN). Read the phy active delay register. 536 * Value is in 100ns increments. 537 */ 538 data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 539 if (IS_CHAN_CCK(ichan)) { 540 synthDelay = (4 * data) / 22; 541 } else { 542 synthDelay = data / 10; 543 } 544 545 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 546 547 /* Release the RFBus Grant */ 548 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 549 550 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 551 if (IS_CHAN_OFDM(ichan)|| IS_CHAN_HT(chan)) { 552 if (ahp->ah_eeprom.ee_version >= AR_EEPROM_VER5_3 && 553 !IS_CHAN_B(chan)) 554 ar5212SetSpurMitigation(ah, ichan); 555 ar5416SetDeltaSlope(ah, ichan); 556 } 557 558 /* XXX spur mitigation for Melin */ 559 560 /* Copy over internal channel flags to public hal channel */ 561 562 if (!(ichan->privFlags & CHANNEL_DFS)) 563 ichan->privFlags &= ~CHANNEL_INTERFERENCE; 564 chan->channelFlags = ichan->channelFlags; 565 chan->privFlags = ichan->privFlags; 566 chan->maxRegTxPower = ichan->maxRegTxPower; 567 chan->maxTxPower = ichan->maxTxPower; 568 chan->minTxPower = ichan->minTxPower; 569 AH_PRIVATE(ah)->ah_curchan->ah_channel_time=0; 570 AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar5212GetTsf64(ah); 571 ar5212TxEnable(ah,AH_TRUE); 572 return AH_TRUE; 573} 574#endif 575 576static void 577ar5416InitDMA(struct ath_hal *ah) 578{ 579 580 /* 581 * set AHB_MODE not to do cacheline prefetches 582 */ 583 OS_REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); 584 585 /* 586 * let mac dma reads be in 128 byte chunks 587 */ 588 OS_REG_WRITE(ah, AR_TXCFG, 589 (OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK) | AR_TXCFG_DMASZ_128B); 590 591 /* 592 * let mac dma writes be in 128 byte chunks 593 */ 594 OS_REG_WRITE(ah, AR_RXCFG, 595 (OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B); 596 597 /* XXX restore TX trigger level */ 598 599 /* 600 * Setup receive FIFO threshold to hold off TX activities 601 */ 602 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 603 604 /* 605 * reduce the number of usable entries in PCU TXBUF to avoid 606 * wrap around. 607 */ 608 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE); 609} 610 611static void 612ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan) 613{ 614 uint32_t synthDelay; 615 616 /* 617 * Wait for the frequency synth to settle (synth goes on 618 * via AR_PHY_ACTIVE_EN). Read the phy active delay register. 619 * Value is in 100ns increments. 620 */ 621 synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 622 if (IS_CHAN_CCK(chan)) { 623 synthDelay = (4 * synthDelay) / 22; 624 } else { 625 synthDelay /= 10; 626 } 627 628 /* Turn on PLL on 5416 */ 629 HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n", 630 __func__, IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz"); 631 ar5416InitPLL(ah, chan); 632 633 /* Activate the PHY (includes baseband activate and synthesizer on) */ 634 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 635 636 /* 637 * If the AP starts the calibration before the base band timeout 638 * completes we could get rx_clear false triggering. Add an 639 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition 640 * does not happen. 641 */ 642 if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) { 643 OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY); 644 } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) { 645 OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY); 646 } else { 647 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 648 } 649} 650 651static void 652ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode) 653{ 654 struct ath_hal_5212 *ahp = AH5212(ah); 655 656 /* 657 * Setup interrupt handling. Note that ar5212ResetTxQueue 658 * manipulates the secondary IMR's as queues are enabled 659 * and disabled. This is done with RMW ops to insure the 660 * settings we make here are preserved. 661 */ 662 ahp->ah_maskReg = AR_IMR_TXERR | AR_IMR_TXURN 663 | AR_IMR_RXERR | AR_IMR_RXORN 664 | AR_IMR_BCNMISC; 665 666#ifdef AR5416_INT_MITIGATION 667 ahp->ah_maskReg |= AR_IMR_TXINTM | AR_IMR_RXINTM 668 | AR_IMR_TXMINTR | AR_IMR_RXMINTR; 669#else 670 ahp->ah_maskReg |= AR_IMR_TXOK | AR_IMR_RXOK; 671#endif 672 if (opmode == HAL_M_HOSTAP) 673 ahp->ah_maskReg |= AR_IMR_MIB; 674 OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); 675 /* Enable bus errors that are OR'd to set the HIUERR bit */ 676 677#if 0 678 OS_REG_WRITE(ah, AR_IMR_S2, 679 OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST); 680#endif 681} 682 683static void 684ar5416InitQoS(struct ath_hal *ah) 685{ 686 /* QoS support */ 687 OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */ 688 OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */ 689 690 /* Turn on NOACK Support for QoS packets */ 691 OS_REG_WRITE(ah, AR_NOACK, 692 SM(2, AR_NOACK_2BIT_VALUE) | 693 SM(5, AR_NOACK_BIT_OFFSET) | 694 SM(0, AR_NOACK_BYTE_OFFSET)); 695 696 /* 697 * initialize TXOP for all TIDs 698 */ 699 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); 700 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); 701 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); 702 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); 703 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 704} 705 706static void 707ar5416InitUserSettings(struct ath_hal *ah) 708{ 709 struct ath_hal_5212 *ahp = AH5212(ah); 710 711 /* Restore user-specified settings */ 712 if (ahp->ah_miscMode != 0) 713 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 714 if (ahp->ah_sifstime != (u_int) -1) 715 ar5212SetSifsTime(ah, ahp->ah_sifstime); 716 if (ahp->ah_slottime != (u_int) -1) 717 ar5212SetSlotTime(ah, ahp->ah_slottime); 718 if (ahp->ah_acktimeout != (u_int) -1) 719 ar5212SetAckTimeout(ah, ahp->ah_acktimeout); 720 if (ahp->ah_ctstimeout != (u_int) -1) 721 ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout); 722 if (AH_PRIVATE(ah)->ah_diagreg != 0) 723 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 724#if 0 /* XXX Todo */ 725 if (ahp->ah_globaltxtimeout != (u_int) -1) 726 ar5416SetGlobalTxTimeout(ah, ahp->ah_globaltxtimeout); 727#endif 728} 729 730/* 731 * Places the hardware into reset and then pulls it out of reset 732 */ 733HAL_BOOL 734ar5416ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan) 735{ 736 uint32_t rfMode = 0; 737 738 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0); 739 /* 740 * Warm reset is optimistic. 741 */ 742 if (AR_SREV_MERLIN_20_OR_LATER(ah) && 743 ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 744 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) 745 return AH_FALSE; 746 } else { 747 if (!ar5416SetResetReg(ah, HAL_RESET_WARM)) 748 return AH_FALSE; 749 } 750 751 /* Bring out of sleep mode (AGAIN) */ 752 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 753 return AH_FALSE; 754 755 ar5416InitPLL(ah, chan); 756 757 /* 758 * Perform warm reset before the mode/PLL/turbo registers 759 * are changed in order to deactivate the radio. Mode changes 760 * with an active radio can result in corrupted shifts to the 761 * radio device. 762 */ 763 if (chan != AH_NULL) { 764 /* treat channel B as channel G , no B mode suport in owl */ 765 rfMode |= (IS_CHAN_G(chan) || IS_CHAN_B(chan)) ? 766 AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; 767 if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 768 /* phy mode bits for 5GHz channels require Fast Clock */ 769 rfMode |= AR_PHY_MODE_DYNAMIC 770 | AR_PHY_MODE_DYN_CCK_DISABLE; 771 } else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) { 772 rfMode |= (IS_CHAN_5GHZ(chan)) ? 773 AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; 774 } 775 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); 776 } 777 return AH_TRUE; 778} 779 780/* 781 * Delta slope coefficient computation. 782 * Required for OFDM operation. 783 */ 784static void 785ar5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled, 786 uint32_t *coef_mantissa, uint32_t *coef_exponent) 787{ 788#define COEF_SCALE_S 24 789 uint32_t coef_exp, coef_man; 790 /* 791 * ALGO -> coef_exp = 14-floor(log2(coef)); 792 * floor(log2(x)) is the highest set bit position 793 */ 794 for (coef_exp = 31; coef_exp > 0; coef_exp--) 795 if ((coef_scaled >> coef_exp) & 0x1) 796 break; 797 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */ 798 HALASSERT(coef_exp); 799 coef_exp = 14 - (coef_exp - COEF_SCALE_S); 800 801 /* 802 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5); 803 * The coefficient is already shifted up for scaling 804 */ 805 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); 806 807 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp); 808 *coef_exponent = coef_exp - 16; 809 810#undef COEF_SCALE_S 811} 812 813void 814ar5416SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 815{ 816#define INIT_CLOCKMHZSCALED 0x64000000 817 uint32_t coef_scaled, ds_coef_exp, ds_coef_man; 818 uint32_t clockMhzScaled = INIT_CLOCKMHZSCALED; 819 820 CHAN_CENTERS centers; 821 822 if (IS_CHAN_TURBO(chan)) 823 clockMhzScaled *= 2; 824 /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */ 825 /* scale for selected channel bandwidth */ 826 if (IS_CHAN_HALF_RATE(chan)) { 827 clockMhzScaled = clockMhzScaled >> 1; 828 } else if (IS_CHAN_QUARTER_RATE(chan)) { 829 clockMhzScaled = clockMhzScaled >> 2; 830 } 831 832 /* 833 * ALGO -> coef = 1e8/fcarrier*fclock/40; 834 * scaled coef to provide precision for this floating calculation 835 */ 836 ar5416GetChannelCenters(ah, chan, ¢ers); 837 coef_scaled = clockMhzScaled / centers.synth_center; 838 839 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 840 841 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 842 AR_PHY_TIMING3_DSC_MAN, ds_coef_man); 843 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 844 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); 845 846 /* 847 * For Short GI, 848 * scaled coeff is 9/10 that of normal coeff 849 */ 850 coef_scaled = (9 * coef_scaled)/10; 851 852 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 853 854 /* for short gi */ 855 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 856 AR_PHY_HALFGI_DSC_MAN, ds_coef_man); 857 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 858 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); 859#undef INIT_CLOCKMHZSCALED 860} 861 862/* 863 * Convert to baseband spur frequency given input channel frequency 864 * and compute register settings below. 865 */ 866#define SPUR_RSSI_THRESH 40 867 868static void 869ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 870{ 871 static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, 872 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 }; 873 static const int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, 874 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 }; 875 static const int inc[4] = { 0, 100, 0, 0 }; 876 877 int bb_spur = AR_NO_SPUR; 878 int bin, cur_bin; 879 int spur_freq_sd; 880 int spur_delta_phase; 881 int denominator; 882 int upper, lower, cur_vit_mask; 883 int tmp, new; 884 int i; 885 886 int8_t mask_m[123]; 887 int8_t mask_p[123]; 888 int8_t mask_amt; 889 int tmp_mask; 890 int cur_bb_spur; 891 HAL_BOOL is2GHz = IS_CHAN_2GHZ(chan); 892 893 OS_MEMZERO(mask_m, sizeof(mask_m)); 894 OS_MEMZERO(mask_p, sizeof(mask_p)); 895 896 /* 897 * Need to verify range +/- 9.5 for static ht20, otherwise spur 898 * is out-of-band and can be ignored. 899 */ 900 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 901 cur_bb_spur = ath_hal_getSpurChan(ah, i, is2GHz); 902 if (AR_NO_SPUR == cur_bb_spur) 903 break; 904 cur_bb_spur = cur_bb_spur - (chan->channel * 10); 905 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) { 906 bb_spur = cur_bb_spur; 907 break; 908 } 909 } 910 if (AR_NO_SPUR == bb_spur) 911 return; 912 913 bin = bb_spur * 32; 914 915 tmp = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0)); 916 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | 917 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 918 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 919 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 920 921 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0), new); 922 923 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | 924 AR_PHY_SPUR_REG_ENABLE_MASK_PPM | 925 AR_PHY_SPUR_REG_MASK_RATE_SELECT | 926 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | 927 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); 928 OS_REG_WRITE(ah, AR_PHY_SPUR_REG, new); 929 /* 930 * Should offset bb_spur by +/- 10 MHz for dynamic 2040 MHz 931 * config, no offset for HT20. 932 * spur_delta_phase = bb_spur/40 * 2**21 for static ht20, 933 * /80 for dyn2040. 934 */ 935 spur_delta_phase = ((bb_spur * 524288) / 100) & 936 AR_PHY_TIMING11_SPUR_DELTA_PHASE; 937 /* 938 * in 11A mode the denominator of spur_freq_sd should be 40 and 939 * it should be 44 in 11G 940 */ 941 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400; 942 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff; 943 944 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | 945 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | 946 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); 947 OS_REG_WRITE(ah, AR_PHY_TIMING11, new); 948 949 950 /* 951 * ============================================ 952 * pilot mask 1 [31:0] = +6..-26, no 0 bin 953 * pilot mask 2 [19:0] = +26..+7 954 * 955 * channel mask 1 [31:0] = +6..-26, no 0 bin 956 * channel mask 2 [19:0] = +26..+7 957 */ 958 //cur_bin = -26; 959 cur_bin = -6000; 960 upper = bin + 100; 961 lower = bin - 100; 962 963 for (i = 0; i < 4; i++) { 964 int pilot_mask = 0; 965 int chan_mask = 0; 966 int bp = 0; 967 for (bp = 0; bp < 30; bp++) { 968 if ((cur_bin > lower) && (cur_bin < upper)) { 969 pilot_mask = pilot_mask | 0x1 << bp; 970 chan_mask = chan_mask | 0x1 << bp; 971 } 972 cur_bin += 100; 973 } 974 cur_bin += inc[i]; 975 OS_REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); 976 OS_REG_WRITE(ah, chan_mask_reg[i], chan_mask); 977 } 978 979 /* ================================================= 980 * viterbi mask 1 based on channel magnitude 981 * four levels 0-3 982 * - mask (-27 to 27) (reg 64,0x9900 to 67,0x990c) 983 * [1 2 2 1] for -9.6 or [1 2 1] for +16 984 * - enable_mask_ppm, all bins move with freq 985 * 986 * - mask_select, 8 bits for rates (reg 67,0x990c) 987 * - mask_rate_cntl, 8 bits for rates (reg 67,0x990c) 988 * choose which mask to use mask or mask2 989 */ 990 991 /* 992 * viterbi mask 2 2nd set for per data rate puncturing 993 * four levels 0-3 994 * - mask_select, 8 bits for rates (reg 67) 995 * - mask (-27 to 27) (reg 98,0x9988 to 101,0x9994) 996 * [1 2 2 1] for -9.6 or [1 2 1] for +16 997 */ 998 cur_vit_mask = 6100; 999 upper = bin + 120; 1000 lower = bin - 120; 1001 1002 for (i = 0; i < 123; i++) { 1003 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { 1004 if ((abs(cur_vit_mask - bin)) < 75) { 1005 mask_amt = 1; 1006 } else { 1007 mask_amt = 0; 1008 } 1009 if (cur_vit_mask < 0) { 1010 mask_m[abs(cur_vit_mask / 100)] = mask_amt; 1011 } else { 1012 mask_p[cur_vit_mask / 100] = mask_amt; 1013 } 1014 } 1015 cur_vit_mask -= 100; 1016 } 1017 1018 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) 1019 | (mask_m[48] << 26) | (mask_m[49] << 24) 1020 | (mask_m[50] << 22) | (mask_m[51] << 20) 1021 | (mask_m[52] << 18) | (mask_m[53] << 16) 1022 | (mask_m[54] << 14) | (mask_m[55] << 12) 1023 | (mask_m[56] << 10) | (mask_m[57] << 8) 1024 | (mask_m[58] << 6) | (mask_m[59] << 4) 1025 | (mask_m[60] << 2) | (mask_m[61] << 0); 1026 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); 1027 OS_REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); 1028 1029 tmp_mask = (mask_m[31] << 28) 1030 | (mask_m[32] << 26) | (mask_m[33] << 24) 1031 | (mask_m[34] << 22) | (mask_m[35] << 20) 1032 | (mask_m[36] << 18) | (mask_m[37] << 16) 1033 | (mask_m[48] << 14) | (mask_m[39] << 12) 1034 | (mask_m[40] << 10) | (mask_m[41] << 8) 1035 | (mask_m[42] << 6) | (mask_m[43] << 4) 1036 | (mask_m[44] << 2) | (mask_m[45] << 0); 1037 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); 1038 OS_REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); 1039 1040 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) 1041 | (mask_m[18] << 26) | (mask_m[18] << 24) 1042 | (mask_m[20] << 22) | (mask_m[20] << 20) 1043 | (mask_m[22] << 18) | (mask_m[22] << 16) 1044 | (mask_m[24] << 14) | (mask_m[24] << 12) 1045 | (mask_m[25] << 10) | (mask_m[26] << 8) 1046 | (mask_m[27] << 6) | (mask_m[28] << 4) 1047 | (mask_m[29] << 2) | (mask_m[30] << 0); 1048 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); 1049 OS_REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); 1050 1051 tmp_mask = (mask_m[ 0] << 30) | (mask_m[ 1] << 28) 1052 | (mask_m[ 2] << 26) | (mask_m[ 3] << 24) 1053 | (mask_m[ 4] << 22) | (mask_m[ 5] << 20) 1054 | (mask_m[ 6] << 18) | (mask_m[ 7] << 16) 1055 | (mask_m[ 8] << 14) | (mask_m[ 9] << 12) 1056 | (mask_m[10] << 10) | (mask_m[11] << 8) 1057 | (mask_m[12] << 6) | (mask_m[13] << 4) 1058 | (mask_m[14] << 2) | (mask_m[15] << 0); 1059 OS_REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); 1060 OS_REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); 1061 1062 tmp_mask = (mask_p[15] << 28) 1063 | (mask_p[14] << 26) | (mask_p[13] << 24) 1064 | (mask_p[12] << 22) | (mask_p[11] << 20) 1065 | (mask_p[10] << 18) | (mask_p[ 9] << 16) 1066 | (mask_p[ 8] << 14) | (mask_p[ 7] << 12) 1067 | (mask_p[ 6] << 10) | (mask_p[ 5] << 8) 1068 | (mask_p[ 4] << 6) | (mask_p[ 3] << 4) 1069 | (mask_p[ 2] << 2) | (mask_p[ 1] << 0); 1070 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); 1071 OS_REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); 1072 1073 tmp_mask = (mask_p[30] << 28) 1074 | (mask_p[29] << 26) | (mask_p[28] << 24) 1075 | (mask_p[27] << 22) | (mask_p[26] << 20) 1076 | (mask_p[25] << 18) | (mask_p[24] << 16) 1077 | (mask_p[23] << 14) | (mask_p[22] << 12) 1078 | (mask_p[21] << 10) | (mask_p[20] << 8) 1079 | (mask_p[19] << 6) | (mask_p[18] << 4) 1080 | (mask_p[17] << 2) | (mask_p[16] << 0); 1081 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); 1082 OS_REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); 1083 1084 tmp_mask = (mask_p[45] << 28) 1085 | (mask_p[44] << 26) | (mask_p[43] << 24) 1086 | (mask_p[42] << 22) | (mask_p[41] << 20) 1087 | (mask_p[40] << 18) | (mask_p[39] << 16) 1088 | (mask_p[38] << 14) | (mask_p[37] << 12) 1089 | (mask_p[36] << 10) | (mask_p[35] << 8) 1090 | (mask_p[34] << 6) | (mask_p[33] << 4) 1091 | (mask_p[32] << 2) | (mask_p[31] << 0); 1092 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); 1093 OS_REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); 1094 1095 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) 1096 | (mask_p[59] << 26) | (mask_p[58] << 24) 1097 | (mask_p[57] << 22) | (mask_p[56] << 20) 1098 | (mask_p[55] << 18) | (mask_p[54] << 16) 1099 | (mask_p[53] << 14) | (mask_p[52] << 12) 1100 | (mask_p[51] << 10) | (mask_p[50] << 8) 1101 | (mask_p[49] << 6) | (mask_p[48] << 4) 1102 | (mask_p[47] << 2) | (mask_p[46] << 0); 1103 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); 1104 OS_REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 1105} 1106 1107#ifdef AH_SUPPORT_AR9280 1108#define AR_BASE_FREQ_2GHZ 2300 1109#define AR_BASE_FREQ_5GHZ 4900 1110#define AR_SPUR_FEEQ_BOUND_HT40 19 1111#define AR_SPUR_FEEQ_BOUND_HT20 10 1112 1113static void 1114ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan) 1115{ 1116 static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, 1117 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 }; 1118 static const int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, 1119 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 }; 1120 static int inc[4] = { 0, 100, 0, 0 }; 1121 1122 int bb_spur = AR_NO_SPUR; 1123 int freq; 1124 int bin, cur_bin; 1125 int bb_spur_off, spur_subchannel_sd; 1126 int spur_freq_sd; 1127 int spur_delta_phase; 1128 int denominator; 1129 int upper, lower, cur_vit_mask; 1130 int tmp, newVal; 1131 int i; 1132 CHAN_CENTERS centers; 1133 1134 int8_t mask_m[123]; 1135 int8_t mask_p[123]; 1136 int8_t mask_amt; 1137 int tmp_mask; 1138 int cur_bb_spur; 1139 HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan); 1140 1141 OS_MEMZERO(&mask_m, sizeof(int8_t) * 123); 1142 OS_MEMZERO(&mask_p, sizeof(int8_t) * 123); 1143 1144 ar5416GetChannelCenters(ah, ichan, ¢ers); 1145 freq = centers.synth_center; 1146 1147 /* 1148 * Need to verify range +/- 9.38 for static ht20 and +/- 18.75 for ht40, 1149 * otherwise spur is out-of-band and can be ignored. 1150 */ 1151 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 1152 cur_bb_spur = ath_hal_getSpurChan(ah, i, is2GHz); 1153 /* Get actual spur freq in MHz from EEPROM read value */ 1154 if (is2GHz) { 1155 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; 1156 } else { 1157 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; 1158 } 1159 1160 if (AR_NO_SPUR == cur_bb_spur) 1161 break; 1162 cur_bb_spur = cur_bb_spur - freq; 1163 1164 if (IS_CHAN_HT40(ichan)) { 1165 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && 1166 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { 1167 bb_spur = cur_bb_spur; 1168 break; 1169 } 1170 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && 1171 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { 1172 bb_spur = cur_bb_spur; 1173 break; 1174 } 1175 } 1176 1177 if (AR_NO_SPUR == bb_spur) { 1178#if 1 1179 /* 1180 * MRC CCK can interfere with beacon detection and cause deaf/mute. 1181 * Disable MRC CCK for now. 1182 */ 1183 OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 1184#else 1185 /* Enable MRC CCK if no spur is found in this channel. */ 1186 OS_REG_SET_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 1187#endif 1188 return; 1189 } else { 1190 /* 1191 * For Merlin, spur can break CCK MRC algorithm. Disable CCK MRC if spur 1192 * is found in this channel. 1193 */ 1194 OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 1195 } 1196 1197 bin = bb_spur * 320; 1198 1199 tmp = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0)); 1200 1201 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | 1202 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 1203 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 1204 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 1205 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0), newVal); 1206 1207 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | 1208 AR_PHY_SPUR_REG_ENABLE_MASK_PPM | 1209 AR_PHY_SPUR_REG_MASK_RATE_SELECT | 1210 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | 1211 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); 1212 OS_REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); 1213 1214 /* Pick control or extn channel to cancel the spur */ 1215 if (IS_CHAN_HT40(ichan)) { 1216 if (bb_spur < 0) { 1217 spur_subchannel_sd = 1; 1218 bb_spur_off = bb_spur + 10; 1219 } else { 1220 spur_subchannel_sd = 0; 1221 bb_spur_off = bb_spur - 10; 1222 } 1223 } else { 1224 spur_subchannel_sd = 0; 1225 bb_spur_off = bb_spur; 1226 } 1227 1228 /* 1229 * spur_delta_phase = bb_spur/40 * 2**21 for static ht20, 1230 * /80 for dyn2040. 1231 */ 1232 if (IS_CHAN_HT40(ichan)) 1233 spur_delta_phase = ((bb_spur * 262144) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; 1234 else 1235 spur_delta_phase = ((bb_spur * 524288) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; 1236 1237 /* 1238 * in 11A mode the denominator of spur_freq_sd should be 40 and 1239 * it should be 44 in 11G 1240 */ 1241 denominator = IS_CHAN_2GHZ(ichan) ? 44 : 40; 1242 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; 1243 1244 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | 1245 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | 1246 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); 1247 OS_REG_WRITE(ah, AR_PHY_TIMING11, newVal); 1248 1249 /* Choose to cancel between control and extension channels */ 1250 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; 1251 OS_REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); 1252 1253 /* 1254 * ============================================ 1255 * Set Pilot and Channel Masks 1256 * 1257 * pilot mask 1 [31:0] = +6..-26, no 0 bin 1258 * pilot mask 2 [19:0] = +26..+7 1259 * 1260 * channel mask 1 [31:0] = +6..-26, no 0 bin 1261 * channel mask 2 [19:0] = +26..+7 1262 */ 1263 cur_bin = -6000; 1264 upper = bin + 100; 1265 lower = bin - 100; 1266 1267 for (i = 0; i < 4; i++) { 1268 int pilot_mask = 0; 1269 int chan_mask = 0; 1270 int bp = 0; 1271 for (bp = 0; bp < 30; bp++) { 1272 if ((cur_bin > lower) && (cur_bin < upper)) { 1273 pilot_mask = pilot_mask | 0x1 << bp; 1274 chan_mask = chan_mask | 0x1 << bp; 1275 } 1276 cur_bin += 100; 1277 } 1278 cur_bin += inc[i]; 1279 OS_REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); 1280 OS_REG_WRITE(ah, chan_mask_reg[i], chan_mask); 1281 } 1282 1283 /* ================================================= 1284 * viterbi mask 1 based on channel magnitude 1285 * four levels 0-3 1286 * - mask (-27 to 27) (reg 64,0x9900 to 67,0x990c) 1287 * [1 2 2 1] for -9.6 or [1 2 1] for +16 1288 * - enable_mask_ppm, all bins move with freq 1289 * 1290 * - mask_select, 8 bits for rates (reg 67,0x990c) 1291 * - mask_rate_cntl, 8 bits for rates (reg 67,0x990c) 1292 * choose which mask to use mask or mask2 1293 */ 1294 1295 /* 1296 * viterbi mask 2 2nd set for per data rate puncturing 1297 * four levels 0-3 1298 * - mask_select, 8 bits for rates (reg 67) 1299 * - mask (-27 to 27) (reg 98,0x9988 to 101,0x9994) 1300 * [1 2 2 1] for -9.6 or [1 2 1] for +16 1301 */ 1302 cur_vit_mask = 6100; 1303 upper = bin + 120; 1304 lower = bin - 120; 1305 1306 for (i = 0; i < 123; i++) { 1307 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { 1308 if ((abs(cur_vit_mask - bin)) < 75) { 1309 mask_amt = 1; 1310 } else { 1311 mask_amt = 0; 1312 } 1313 if (cur_vit_mask < 0) { 1314 mask_m[abs(cur_vit_mask / 100)] = mask_amt; 1315 } else { 1316 mask_p[cur_vit_mask / 100] = mask_amt; 1317 } 1318 } 1319 cur_vit_mask -= 100; 1320 } 1321 1322 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) 1323 | (mask_m[48] << 26) | (mask_m[49] << 24) 1324 | (mask_m[50] << 22) | (mask_m[51] << 20) 1325 | (mask_m[52] << 18) | (mask_m[53] << 16) 1326 | (mask_m[54] << 14) | (mask_m[55] << 12) 1327 | (mask_m[56] << 10) | (mask_m[57] << 8) 1328 | (mask_m[58] << 6) | (mask_m[59] << 4) 1329 | (mask_m[60] << 2) | (mask_m[61] << 0); 1330 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); 1331 OS_REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); 1332 1333 tmp_mask = (mask_m[31] << 28) 1334 | (mask_m[32] << 26) | (mask_m[33] << 24) 1335 | (mask_m[34] << 22) | (mask_m[35] << 20) 1336 | (mask_m[36] << 18) | (mask_m[37] << 16) 1337 | (mask_m[48] << 14) | (mask_m[39] << 12) 1338 | (mask_m[40] << 10) | (mask_m[41] << 8) 1339 | (mask_m[42] << 6) | (mask_m[43] << 4) 1340 | (mask_m[44] << 2) | (mask_m[45] << 0); 1341 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); 1342 OS_REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); 1343 1344 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) 1345 | (mask_m[18] << 26) | (mask_m[18] << 24) 1346 | (mask_m[20] << 22) | (mask_m[20] << 20) 1347 | (mask_m[22] << 18) | (mask_m[22] << 16) 1348 | (mask_m[24] << 14) | (mask_m[24] << 12) 1349 | (mask_m[25] << 10) | (mask_m[26] << 8) 1350 | (mask_m[27] << 6) | (mask_m[28] << 4) 1351 | (mask_m[29] << 2) | (mask_m[30] << 0); 1352 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); 1353 OS_REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); 1354 1355 tmp_mask = (mask_m[ 0] << 30) | (mask_m[ 1] << 28) 1356 | (mask_m[ 2] << 26) | (mask_m[ 3] << 24) 1357 | (mask_m[ 4] << 22) | (mask_m[ 5] << 20) 1358 | (mask_m[ 6] << 18) | (mask_m[ 7] << 16) 1359 | (mask_m[ 8] << 14) | (mask_m[ 9] << 12) 1360 | (mask_m[10] << 10) | (mask_m[11] << 8) 1361 | (mask_m[12] << 6) | (mask_m[13] << 4) 1362 | (mask_m[14] << 2) | (mask_m[15] << 0); 1363 OS_REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); 1364 OS_REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); 1365 1366 tmp_mask = (mask_p[15] << 28) 1367 | (mask_p[14] << 26) | (mask_p[13] << 24) 1368 | (mask_p[12] << 22) | (mask_p[11] << 20) 1369 | (mask_p[10] << 18) | (mask_p[ 9] << 16) 1370 | (mask_p[ 8] << 14) | (mask_p[ 7] << 12) 1371 | (mask_p[ 6] << 10) | (mask_p[ 5] << 8) 1372 | (mask_p[ 4] << 6) | (mask_p[ 3] << 4) 1373 | (mask_p[ 2] << 2) | (mask_p[ 1] << 0); 1374 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); 1375 OS_REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); 1376 1377 tmp_mask = (mask_p[30] << 28) 1378 | (mask_p[29] << 26) | (mask_p[28] << 24) 1379 | (mask_p[27] << 22) | (mask_p[26] << 20) 1380 | (mask_p[25] << 18) | (mask_p[24] << 16) 1381 | (mask_p[23] << 14) | (mask_p[22] << 12) 1382 | (mask_p[21] << 10) | (mask_p[20] << 8) 1383 | (mask_p[19] << 6) | (mask_p[18] << 4) 1384 | (mask_p[17] << 2) | (mask_p[16] << 0); 1385 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); 1386 OS_REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); 1387 1388 tmp_mask = (mask_p[45] << 28) 1389 | (mask_p[44] << 26) | (mask_p[43] << 24) 1390 | (mask_p[42] << 22) | (mask_p[41] << 20) 1391 | (mask_p[40] << 18) | (mask_p[39] << 16) 1392 | (mask_p[38] << 14) | (mask_p[37] << 12) 1393 | (mask_p[36] << 10) | (mask_p[35] << 8) 1394 | (mask_p[34] << 6) | (mask_p[33] << 4) 1395 | (mask_p[32] << 2) | (mask_p[31] << 0); 1396 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); 1397 OS_REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); 1398 1399 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) 1400 | (mask_p[59] << 26) | (mask_p[58] << 24) 1401 | (mask_p[57] << 22) | (mask_p[56] << 20) 1402 | (mask_p[55] << 18) | (mask_p[54] << 16) 1403 | (mask_p[53] << 14) | (mask_p[52] << 12) 1404 | (mask_p[51] << 10) | (mask_p[50] << 8) 1405 | (mask_p[49] << 6) | (mask_p[48] << 4) 1406 | (mask_p[47] << 2) | (mask_p[46] << 0); 1407 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); 1408 OS_REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 1409} 1410#endif /* AH_SUPPORT_AR9280 */ 1411 1412/* 1413 * Set a limit on the overall output power. Used for dynamic 1414 * transmit power control and the like. 1415 * 1416 * NB: limit is in units of 0.5 dbM. 1417 */ 1418HAL_BOOL 1419ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit) 1420{ 1421 uint16_t dummyXpdGains[2]; 1422 1423 AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); 1424 return ar5416SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan, 1425 dummyXpdGains); 1426} 1427 1428HAL_BOOL 1429ar5416GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans) 1430{ 1431 struct ath_hal_5212 *ahp = AH5212(ah); 1432 int16_t minPower, maxPower; 1433 HAL_CHANNEL *chan; 1434 int i; 1435 1436 /* 1437 * Get Pier table max and min powers. 1438 */ 1439 for (i = 0; i < nchans; i++) { 1440 chan = &chans[i]; 1441 if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) { 1442 /* NB: rf code returns 1/4 dBm units, convert */ 1443 chan->maxTxPower = maxPower / 2; 1444 chan->minTxPower = minPower / 2; 1445 } else { 1446 HALDEBUG(ah, HAL_DEBUG_ANY, 1447 "%s: no min/max power for %u/0x%x\n", 1448 __func__, chan->channel, chan->channelFlags); 1449 chan->maxTxPower = AR5416_MAX_RATE_POWER; 1450 chan->minTxPower = 0; 1451 } 1452 } 1453#ifdef AH_DEBUG 1454 for (i=0; i<nchans; i++) { 1455 HALDEBUG(ah, HAL_DEBUG_RESET, 1456 "Chan %d: MaxPow = %d MinPow = %d\n", 1457 chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower); 1458 } 1459#endif 1460 return AH_TRUE; 1461} 1462 1463/* XXX gag, this is sick */ 1464typedef enum Ar5416_Rates { 1465 rate6mb, rate9mb, rate12mb, rate18mb, 1466 rate24mb, rate36mb, rate48mb, rate54mb, 1467 rate1l, rate2l, rate2s, rate5_5l, 1468 rate5_5s, rate11l, rate11s, rateXr, 1469 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, 1470 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, 1471 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, 1472 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, 1473 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, 1474 Ar5416RateSize 1475} AR5416_RATES; 1476 1477/************************************************************** 1478 * ar5416SetTransmitPower 1479 * 1480 * Set the transmit power in the baseband for the given 1481 * operating channel and mode. 1482 */ 1483static HAL_BOOL 1484ar5416SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain) 1485{ 1486#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 1487#define N(a) (sizeof (a) / sizeof (a[0])) 1488 1489 MODAL_EEP_HEADER *pModal; 1490 struct ath_hal_5212 *ahp = AH5212(ah); 1491 int16_t ratesArray[Ar5416RateSize]; 1492 int16_t txPowerIndexOffset = 0; 1493 uint8_t ht40PowerIncForPdadc = 2; 1494 int i; 1495 1496 uint16_t cfgCtl; 1497 uint16_t powerLimit; 1498 uint16_t twiceAntennaReduction; 1499 uint16_t twiceMaxRegulatoryPower; 1500 int16_t maxPower; 1501 HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 1502 struct ar5416eeprom *pEepData = &ee->ee_base; 1503 1504 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 1505 1506 /* Setup info for the actual eeprom */ 1507 ath_hal_memzero(ratesArray, sizeof(ratesArray)); 1508 cfgCtl = ath_hal_getctl(ah, (HAL_CHANNEL *)chan); 1509 powerLimit = chan->maxRegTxPower * 2; 1510 twiceAntennaReduction = chan->antennaMax; 1511 twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 1512 pModal = &pEepData->modalHeader[IS_CHAN_2GHZ(chan)]; 1513 HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n", 1514 __func__,chan->channel, cfgCtl ); 1515 1516 if (IS_EEP_MINOR_V2(ah)) { 1517 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1518 } 1519 1520 if (!ar5416SetPowerPerRateTable(ah, pEepData, chan, 1521 &ratesArray[0],cfgCtl, 1522 twiceAntennaReduction, 1523 twiceMaxRegulatoryPower, powerLimit)) { 1524 HALDEBUG(ah, HAL_DEBUG_ANY, 1525 "%s: unable to set tx power per rate table\n", __func__); 1526 return AH_FALSE; 1527 } 1528 1529 if (!ar5416SetPowerCalTable(ah, pEepData, chan, &txPowerIndexOffset)) { 1530 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n", 1531 __func__); 1532 return AH_FALSE; 1533 } 1534 1535 maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); 1536 1537 if (IS_CHAN_2GHZ(chan)) { 1538 maxPower = AH_MAX(maxPower, ratesArray[rate1l]); 1539 } 1540 1541 if (IS_CHAN_HT40(chan)) { 1542 maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); 1543 } 1544 1545 ahp->ah_tx6PowerInHalfDbm = maxPower; 1546 AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower; 1547 ahp->ah_txPowerIndexOffset = txPowerIndexOffset; 1548 1549 /* 1550 * txPowerIndexOffset is set by the SetPowerTable() call - 1551 * adjust the rate table (0 offset if rates EEPROM not loaded) 1552 */ 1553 for (i = 0; i < N(ratesArray); i++) { 1554 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1555 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 1556 ratesArray[i] = AR5416_MAX_RATE_POWER; 1557 } 1558 1559#ifdef AH_EEPROM_DUMP 1560 ar5416PrintPowerPerRate(ah, ratesArray); 1561#endif 1562 1563 /* Write the OFDM power per rate set */ 1564 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1565 POW_SM(ratesArray[rate18mb], 24) 1566 | POW_SM(ratesArray[rate12mb], 16) 1567 | POW_SM(ratesArray[rate9mb], 8) 1568 | POW_SM(ratesArray[rate6mb], 0) 1569 ); 1570 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 1571 POW_SM(ratesArray[rate54mb], 24) 1572 | POW_SM(ratesArray[rate48mb], 16) 1573 | POW_SM(ratesArray[rate36mb], 8) 1574 | POW_SM(ratesArray[rate24mb], 0) 1575 ); 1576 1577 if (IS_CHAN_2GHZ(chan)) { 1578 /* Write the CCK power per rate set */ 1579 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1580 POW_SM(ratesArray[rate2s], 24) 1581 | POW_SM(ratesArray[rate2l], 16) 1582 | POW_SM(ratesArray[rateXr], 8) /* XR target power */ 1583 | POW_SM(ratesArray[rate1l], 0) 1584 ); 1585 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 1586 POW_SM(ratesArray[rate11s], 24) 1587 | POW_SM(ratesArray[rate11l], 16) 1588 | POW_SM(ratesArray[rate5_5s], 8) 1589 | POW_SM(ratesArray[rate5_5l], 0) 1590 ); 1591 HALDEBUG(ah, HAL_DEBUG_RESET, 1592 "%s AR_PHY_POWER_TX_RATE3=0x%x AR_PHY_POWER_TX_RATE4=0x%x\n", 1593 __func__, OS_REG_READ(ah,AR_PHY_POWER_TX_RATE3), 1594 OS_REG_READ(ah,AR_PHY_POWER_TX_RATE4)); 1595 } 1596 1597 /* Write the HT20 power per rate set */ 1598 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 1599 POW_SM(ratesArray[rateHt20_3], 24) 1600 | POW_SM(ratesArray[rateHt20_2], 16) 1601 | POW_SM(ratesArray[rateHt20_1], 8) 1602 | POW_SM(ratesArray[rateHt20_0], 0) 1603 ); 1604 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 1605 POW_SM(ratesArray[rateHt20_7], 24) 1606 | POW_SM(ratesArray[rateHt20_6], 16) 1607 | POW_SM(ratesArray[rateHt20_5], 8) 1608 | POW_SM(ratesArray[rateHt20_4], 0) 1609 ); 1610 1611 if (IS_CHAN_HT40(chan)) { 1612 /* Write the HT40 power per rate set */ 1613 /* Correct PAR difference between HT40 and HT20/LEGACY */ 1614 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 1615 POW_SM(ratesArray[rateHt40_3] + ht40PowerIncForPdadc, 24) 1616 | POW_SM(ratesArray[rateHt40_2] + ht40PowerIncForPdadc, 16) 1617 | POW_SM(ratesArray[rateHt40_1] + ht40PowerIncForPdadc, 8) 1618 | POW_SM(ratesArray[rateHt40_0] + ht40PowerIncForPdadc, 0) 1619 ); 1620 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 1621 POW_SM(ratesArray[rateHt40_7] + ht40PowerIncForPdadc, 24) 1622 | POW_SM(ratesArray[rateHt40_6] + ht40PowerIncForPdadc, 16) 1623 | POW_SM(ratesArray[rateHt40_5] + ht40PowerIncForPdadc, 8) 1624 | POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0) 1625 ); 1626 /* Write the Dup/Ext 40 power per rate set */ 1627 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1628 POW_SM(ratesArray[rateExtOfdm], 24) 1629 | POW_SM(ratesArray[rateExtCck], 16) 1630 | POW_SM(ratesArray[rateDupOfdm], 8) 1631 | POW_SM(ratesArray[rateDupCck], 0) 1632 ); 1633 } 1634 1635 /* Write the Power subtraction for dynamic chain changing, for per-packet powertx */ 1636 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 1637 POW_SM(pModal->pwrDecreaseFor3Chain, 6) 1638 | POW_SM(pModal->pwrDecreaseFor2Chain, 0) 1639 ); 1640 return AH_TRUE; 1641#undef POW_SM 1642#undef N 1643} 1644 1645/* 1646 * Exported call to check for a recent gain reading and return 1647 * the current state of the thermal calibration gain engine. 1648 */ 1649HAL_RFGAIN 1650ar5416GetRfgain(struct ath_hal *ah) 1651{ 1652 return HAL_RFGAIN_INACTIVE; 1653} 1654 1655/* 1656 * Places all of hardware into reset 1657 */ 1658HAL_BOOL 1659ar5416Disable(struct ath_hal *ah) 1660{ 1661 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 1662 return AH_FALSE; 1663 return ar5416SetResetReg(ah, HAL_RESET_COLD); 1664} 1665 1666/* 1667 * Places the PHY and Radio chips into reset. A full reset 1668 * must be called to leave this state. The PCI/MAC/PCU are 1669 * not placed into reset as we must receive interrupt to 1670 * re-enable the hardware. 1671 */ 1672HAL_BOOL 1673ar5416PhyDisable(struct ath_hal *ah) 1674{ 1675 return ar5416SetResetReg(ah, HAL_RESET_WARM); 1676} 1677 1678/* 1679 * Write the given reset bit mask into the reset register 1680 */ 1681HAL_BOOL 1682ar5416SetResetReg(struct ath_hal *ah, uint32_t type) 1683{ 1684 /* 1685 * Set force wake 1686 */ 1687 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1688 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1689 1690 switch (type) { 1691 case HAL_RESET_POWER_ON: 1692 return ar5416SetResetPowerOn(ah); 1693 break; 1694 case HAL_RESET_WARM: 1695 case HAL_RESET_COLD: 1696 return ar5416SetReset(ah, type); 1697 break; 1698 default: 1699 return AH_FALSE; 1700 } 1701} 1702 1703static HAL_BOOL 1704ar5416SetResetPowerOn(struct ath_hal *ah) 1705{ 1706 /* Power On Reset (Hard Reset) */ 1707 1708 /* 1709 * Set force wake 1710 * 1711 * If the MAC was running, previously calling 1712 * reset will wake up the MAC but it may go back to sleep 1713 * before we can start polling. 1714 * Set force wake stops that 1715 * This must be called before initiating a hard reset. 1716 */ 1717 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1718 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1719 1720 /* 1721 * RTC reset and clear 1722 */ 1723 OS_REG_WRITE(ah, AR_RTC_RESET, 0); 1724 OS_DELAY(20); 1725 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 1726 1727 /* 1728 * Poll till RTC is ON 1729 */ 1730 if (!ath_hal_wait(ah, AR_RTC_STATUS, AR_RTC_PM_STATUS_M, AR_RTC_STATUS_ON)) { 1731 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC not waking up\n", __func__); 1732 return AH_FALSE; 1733 } 1734 1735 return ar5416SetReset(ah, HAL_RESET_COLD); 1736} 1737 1738static HAL_BOOL 1739ar5416SetReset(struct ath_hal *ah, int type) 1740{ 1741 uint32_t tmpReg; 1742 1743 /* 1744 * Force wake 1745 */ 1746 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1747 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1748 1749 /* 1750 * Reset AHB 1751 */ 1752 tmpReg = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE); 1753 if (tmpReg & (AR_INTR_SYNC_LOCAL_TIMEOUT|AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { 1754 OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 1755 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF); 1756 } else { 1757 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB); 1758 } 1759 1760 /* 1761 * Set Mac(BB,Phy) Warm Reset 1762 */ 1763 switch (type) { 1764 case HAL_RESET_WARM: 1765 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM); 1766 break; 1767 case HAL_RESET_COLD: 1768 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM|AR_RTC_RC_MAC_COLD); 1769 break; 1770 default: 1771 HALASSERT(0); 1772 break; 1773 } 1774 1775 /* 1776 * Clear resets and force wakeup 1777 */ 1778 OS_REG_WRITE(ah, AR_RTC_RC, 0); 1779 if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) { 1780 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC stuck in MAC reset\n", __func__); 1781 return AH_FALSE; 1782 } 1783 1784 /* Clear AHB reset */ 1785 OS_REG_WRITE(ah, AR_RC, 0); 1786 1787 /* Set register and descriptor swapping on 1788 * Bigendian platforms on cold reset 1789 */ 1790#ifdef __BIG_ENDIAN__ 1791 if (type == HAL_RESET_COLD) { 1792 uint32_t mask; 1793 1794 HALDEBUG(ah, HAL_DEBUG_RESET, 1795 "%s Applying descriptor swap\n", __func__); 1796 1797 mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG; 1798#ifndef AH_NEED_DESC_SWAP 1799 mask |= AR_CFG_SWTD; 1800#endif 1801 OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask)); 1802 } 1803#endif 1804 1805 ar5416InitPLL(ah, AH_NULL); 1806 1807 return AH_TRUE; 1808} 1809 1810#ifndef IS_5GHZ_FAST_CLOCK_EN 1811#define IS_5GHZ_FAST_CLOCK_EN(ah, chan) AH_FALSE 1812#endif 1813 1814static void 1815ar5416InitPLL(struct ath_hal *ah, HAL_CHANNEL *chan) 1816{ 1817 uint32_t pll; 1818 1819 if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1820 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1821 1822 if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) { 1823 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1824 } else if (chan && IS_CHAN_QUARTER_RATE(chan)) { 1825 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1826 } 1827 if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) { 1828 pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV); 1829 1830 /* 1831 * PLL WAR for Merlin 2.0/2.1 1832 * When doing fast clock, set PLL to 0x142c 1833 * Else, set PLL to 0x2850 to prevent reset-to-reset variation 1834 */ 1835 if (AR_SREV_MERLIN_20(ah)) { 1836 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 1837 pll = 0x142c; 1838 } else { 1839 pll = 0x2850; 1840 } 1841 } 1842 } else { 1843 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); 1844 } 1845 } else if (AR_SREV_SOWL_10_OR_LATER(ah)) { 1846 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1847 1848 if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) { 1849 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1850 } else if (chan && IS_CHAN_QUARTER_RATE(chan)) { 1851 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1852 } 1853 if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) { 1854 pll |= SM(0x50, AR_RTC_SOWL_PLL_DIV); 1855 } else { 1856 pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV); 1857 } 1858 } else { 1859 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; 1860 1861 if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) { 1862 pll |= SM(0x1, AR_RTC_PLL_CLKSEL); 1863 } else if (chan != AH_NULL && IS_CHAN_QUARTER_RATE(chan)) { 1864 pll |= SM(0x2, AR_RTC_PLL_CLKSEL); 1865 } 1866 if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) { 1867 pll |= SM(0xa, AR_RTC_PLL_DIV); 1868 } else { 1869 pll |= SM(0xb, AR_RTC_PLL_DIV); 1870 } 1871 } 1872 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 1873 1874 /* TODO: 1875 * For multi-band owl, switch between bands by reiniting the PLL. 1876 */ 1877 1878 OS_DELAY(RTC_PLL_SETTLE_DELAY); 1879 1880 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK); 1881} 1882 1883/* 1884 * Read EEPROM header info and program the device for correct operation 1885 * given the channel value. 1886 */ 1887static HAL_BOOL 1888ar5416SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) 1889{ 1890 const HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 1891 const struct ar5416eeprom *eep = &ee->ee_base; 1892 const MODAL_EEP_HEADER *pModal; 1893 int i, regChainOffset; 1894 uint8_t txRxAttenLocal; /* workaround for eeprom versions <= 14.2 */ 1895 1896 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 1897 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1898 1899 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; /* workaround for eeprom versions <= 14.2 */ 1900 1901 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 1902 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1903 if (AR_SREV_MERLIN(ah)) { 1904 if (i >= 2) break; 1905 } 1906 if (AR_SREV_OWL_20_OR_LATER(ah) && 1907 (AH5416(ah)->ah_rx_chainmask == 0x5 || 1908 AH5416(ah)->ah_tx_chainmask == 0x5) && i != 0) { 1909 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 1910 * only chains 0 and 2 populated 1911 */ 1912 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1913 } else { 1914 regChainOffset = i * 0x1000; 1915 } 1916 1917 OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, pModal->antCtrlChain[i]); 1918 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset, 1919 (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) & 1920 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1921 SM(pModal->iqCalICh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1922 SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1923 1924 /* 1925 * Large signal upgrade. 1926 * XXX update 1927 */ 1928 1929 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { 1930 OS_REG_WRITE(ah, AR_PHY_RXGAIN + regChainOffset, 1931 (OS_REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & ~AR_PHY_RXGAIN_TXRX_ATTEN) | 1932 SM(IS_EEP_MINOR_V3(ah) ? pModal->txRxAttenCh[i] : txRxAttenLocal, 1933 AR_PHY_RXGAIN_TXRX_ATTEN)); 1934 1935 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1936 (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) | 1937 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN)); 1938 } 1939 } 1940 1941 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling); 1942 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); 1943 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize); 1944 OS_REG_WRITE(ah, AR_PHY_RF_CTL4, 1945 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 1946 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 1947 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) 1948 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1949 1950 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); 1951 1952 if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1953 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1954 pModal->thresh62); 1955 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 1956 pModal->thresh62); 1957 } else { 1958 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, 1959 pModal->thresh62); 1960 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA_THRESH62, 1961 pModal->thresh62); 1962 } 1963 1964 /* Minor Version Specific application */ 1965 if (IS_EEP_MINOR_V2(ah)) { 1966 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart); 1967 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn); 1968 } 1969 1970 if (IS_EEP_MINOR_V3(ah)) { 1971 if (IS_CHAN_HT40(chan)) { 1972 /* Overwrite switch settling with HT40 value */ 1973 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); 1974 } 1975 1976 if ((AR_SREV_OWL_20_OR_LATER(ah)) && 1977 ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5)){ 1978 /* Reg Offsets are swapped for logical mapping */ 1979 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | 1980 SM(pModal->bswMargin[2], AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1981 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | 1982 SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1983 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | 1984 SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1985 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | 1986 SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1987 } else { 1988 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | 1989 SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1990 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | 1991 SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1992 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | 1993 SM(pModal->bswMargin[2],AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1994 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | 1995 SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1996 } 1997 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_MARGIN, pModal->bswMargin[0]); 1998 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_ATTEN, pModal->bswAtten[0]); 1999 } 2000 return AH_TRUE; 2001} 2002 2003/* 2004 * Helper functions common for AP/CB/XB 2005 */ 2006 2007/* 2008 * ar5416SetPowerPerRateTable 2009 * 2010 * Sets the transmit power in the baseband for the given 2011 * operating channel and mode. 2012 */ 2013static HAL_BOOL 2014ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 2015 HAL_CHANNEL_INTERNAL *chan, 2016 int16_t *ratesArray, uint16_t cfgCtl, 2017 uint16_t AntennaReduction, 2018 uint16_t twiceMaxRegulatoryPower, 2019 uint16_t powerLimit) 2020{ 2021#define N(a) (sizeof(a)/sizeof(a[0])) 2022/* Local defines to distinguish between extension and control CTL's */ 2023#define EXT_ADDITIVE (0x8000) 2024#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 2025#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 2026#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 2027 2028 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 2029 int i; 2030 int16_t twiceLargestAntenna; 2031 CAL_CTL_DATA *rep; 2032 CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}}; 2033 CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}}; 2034 CAL_TARGET_POWER_HT targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}}; 2035 int16_t scaledPower, minCtlPower; 2036 2037#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 2038#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 2039 static const uint16_t ctlModesFor11a[] = { 2040 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 2041 }; 2042 static const uint16_t ctlModesFor11g[] = { 2043 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 2044 }; 2045 const uint16_t *pCtlMode; 2046 uint16_t numCtlModes, ctlMode, freq; 2047 CHAN_CENTERS centers; 2048 2049 ar5416GetChannelCenters(ah, chan, ¢ers); 2050 2051 /* Compute TxPower reduction due to Antenna Gain */ 2052 2053 twiceLargestAntenna = AH_MAX(AH_MAX(pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[0], 2054 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[1]), 2055 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 2056#if 0 2057 /* Turn it back on if we need to calculate per chain antenna gain reduction */ 2058 /* Use only if the expected gain > 6dbi */ 2059 /* Chain 0 is always used */ 2060 twiceLargestAntenna = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[0]; 2061 2062 /* Look at antenna gains of Chains 1 and 2 if the TX mask is set */ 2063 if (ahp->ah_tx_chainmask & 0x2) 2064 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 2065 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[1]); 2066 2067 if (ahp->ah_tx_chainmask & 0x4) 2068 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 2069 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 2070#endif 2071 twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0); 2072 2073 /* XXX setup for 5212 use (really used?) */ 2074 ath_hal_eepromSet(ah, 2075 IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5, 2076 twiceLargestAntenna); 2077 2078 /* 2079 * scaledPower is the minimum of the user input power level and 2080 * the regulatory allowed power level 2081 */ 2082 scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna); 2083 2084 /* Reduce scaled Power by number of chains active to get to per chain tx power level */ 2085 /* TODO: better value than these? */ 2086 switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) { 2087 case 1: 2088 break; 2089 case 2: 2090 scaledPower -= pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain; 2091 break; 2092 case 3: 2093 scaledPower -= pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain; 2094 break; 2095 default: 2096 return AH_FALSE; /* Unsupported number of chains */ 2097 } 2098 2099 scaledPower = AH_MAX(0, scaledPower); 2100 2101 /* Get target powers from EEPROM - our baseline for TX Power */ 2102 if (IS_CHAN_2GHZ(chan)) { 2103 /* Setup for CTL modes */ 2104 numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */ 2105 pCtlMode = ctlModesFor11g; 2106 2107 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 2108 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE); 2109 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 2110 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 2111 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT20, 2112 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 2113 2114 if (IS_CHAN_HT40(chan)) { 2115 numCtlModes = N(ctlModesFor11g); /* All 2G CTL's */ 2116 2117 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT40, 2118 AR5416_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 2119 /* Get target powers for extension channels */ 2120 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 2121 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE); 2122 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 2123 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 2124 } 2125 } else { 2126 /* Setup for CTL modes */ 2127 numCtlModes = N(ctlModesFor11a) - SUB_NUM_CTL_MODES_AT_5G_40; /* CTL_11A, CTL_5GHT20 */ 2128 pCtlMode = ctlModesFor11a; 2129 2130 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 2131 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 2132 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT20, 2133 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 2134 2135 if (IS_CHAN_HT40(chan)) { 2136 numCtlModes = N(ctlModesFor11a); /* All 5G CTL's */ 2137 2138 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT40, 2139 AR5416_NUM_5G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 2140 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 2141 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 2142 } 2143 } 2144 2145 /* 2146 * For MIMO, need to apply regulatory caps individually across dynamically 2147 * running modes: CCK, OFDM, HT20, HT40 2148 * 2149 * The outer loop walks through each possible applicable runtime mode. 2150 * The inner loop walks through each ctlIndex entry in EEPROM. 2151 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. 2152 * 2153 */ 2154 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 2155 2156 HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 2157 (pCtlMode[ctlMode] == CTL_2GHT40); 2158 if (isHt40CtlMode) { 2159 freq = centers.ctl_center; 2160 } else if (pCtlMode[ctlMode] & EXT_ADDITIVE) { 2161 freq = centers.ext_center; 2162 } else { 2163 freq = centers.ctl_center; 2164 } 2165 2166 /* walk through each CTL index stored in EEPROM */ 2167 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 2168 uint16_t twiceMinEdgePower; 2169 2170 /* compare test group from regulatory channel list with test mode from pCtlMode list */ 2171 if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) || 2172 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == 2173 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { 2174 rep = &(pEepData->ctlData[i]); 2175 twiceMinEdgePower = ar5416GetMaxEdgePower(freq, 2176 rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1], 2177 IS_CHAN_2GHZ(chan)); 2178 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 2179 /* Find the minimum of all CTL edge powers that apply to this channel */ 2180 twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower); 2181 } else { 2182 /* specific */ 2183 twiceMaxEdgePower = twiceMinEdgePower; 2184 break; 2185 } 2186 } 2187 } 2188 minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower); 2189 /* Apply ctl mode to correct target power set */ 2190 switch(pCtlMode[ctlMode]) { 2191 case CTL_11B: 2192 for (i = 0; i < N(targetPowerCck.tPow2x); i++) { 2193 targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower); 2194 } 2195 break; 2196 case CTL_11A: 2197 case CTL_11G: 2198 for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) { 2199 targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower); 2200 } 2201 break; 2202 case CTL_5GHT20: 2203 case CTL_2GHT20: 2204 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 2205 targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower); 2206 } 2207 break; 2208 case CTL_11B_EXT: 2209 targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower); 2210 break; 2211 case CTL_11A_EXT: 2212 case CTL_11G_EXT: 2213 targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower); 2214 break; 2215 case CTL_5GHT40: 2216 case CTL_2GHT40: 2217 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 2218 targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower); 2219 } 2220 break; 2221 default: 2222 return AH_FALSE; 2223 break; 2224 } 2225 } /* end ctl mode checking */ 2226 2227 /* Set rates Array from collected data */ 2228 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0]; 2229 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 2230 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 2231 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 2232 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 2233 2234 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 2235 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 2236 } 2237 2238 if (IS_CHAN_2GHZ(chan)) { 2239 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 2240 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 2241 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 2242 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 2243 } 2244 if (IS_CHAN_HT40(chan)) { 2245 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 2246 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i]; 2247 } 2248 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 2249 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 2250 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 2251 if (IS_CHAN_2GHZ(chan)) { 2252 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 2253 } 2254 } 2255 return AH_TRUE; 2256#undef EXT_ADDITIVE 2257#undef CTL_11A_EXT 2258#undef CTL_11G_EXT 2259#undef CTL_11B_EXT 2260#undef SUB_NUM_CTL_MODES_AT_5G_40 2261#undef SUB_NUM_CTL_MODES_AT_2G_40 2262#undef N 2263} 2264 2265/************************************************************************** 2266 * fbin2freq 2267 * 2268 * Get channel value from binary representation held in eeprom 2269 * RETURNS: the frequency in MHz 2270 */ 2271static uint16_t 2272fbin2freq(uint8_t fbin, HAL_BOOL is2GHz) 2273{ 2274 /* 2275 * Reserved value 0xFF provides an empty definition both as 2276 * an fbin and as a frequency - do not convert 2277 */ 2278 if (fbin == AR5416_BCHAN_UNUSED) { 2279 return fbin; 2280 } 2281 2282 return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 2283} 2284 2285/* 2286 * ar5416GetMaxEdgePower 2287 * 2288 * Find the maximum conformance test limit for the given channel and CTL info 2289 */ 2290static uint16_t 2291ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz) 2292{ 2293 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 2294 int i; 2295 2296 /* Get the edge power */ 2297 for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) { 2298 /* 2299 * If there's an exact channel match or an inband flag set 2300 * on the lower channel use the given rdEdgePower 2301 */ 2302 if (freq == fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { 2303 twiceMaxEdgePower = MS(pRdEdgesPower[i].tPowerFlag, CAL_CTL_EDGES_POWER); 2304 break; 2305 } else if ((i > 0) && (freq < fbin2freq(pRdEdgesPower[i].bChannel, is2GHz))) { 2306 if (fbin2freq(pRdEdgesPower[i - 1].bChannel, is2GHz) < freq && (pRdEdgesPower[i - 1].tPowerFlag & CAL_CTL_EDGES_FLAG) != 0) { 2307 twiceMaxEdgePower = MS(pRdEdgesPower[i - 1].tPowerFlag, CAL_CTL_EDGES_POWER); 2308 } 2309 /* Leave loop - no more affecting edges possible in this monotonic increasing list */ 2310 break; 2311 } 2312 } 2313 HALASSERT(twiceMaxEdgePower > 0); 2314 return twiceMaxEdgePower; 2315} 2316 2317/************************************************************** 2318 * ar5416GetTargetPowers 2319 * 2320 * Return the rates of target power for the given target power table 2321 * channel, and number of channels 2322 */ 2323static void 2324ar5416GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, 2325 CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels, 2326 CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates, 2327 HAL_BOOL isHt40Target) 2328{ 2329 uint16_t clo, chi; 2330 int i; 2331 int matchIndex = -1, lowIndex = -1; 2332 uint16_t freq; 2333 CHAN_CENTERS centers; 2334 2335 ar5416GetChannelCenters(ah, chan, ¢ers); 2336 freq = isHt40Target ? centers.synth_center : centers.ctl_center; 2337 2338 /* Copy the target powers into the temp channel list */ 2339 if (freq <= fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) { 2340 matchIndex = 0; 2341 } else { 2342 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 2343 if (freq == fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) { 2344 matchIndex = i; 2345 break; 2346 } else if ((freq < fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) && 2347 (freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan)))) 2348 { 2349 lowIndex = i - 1; 2350 break; 2351 } 2352 } 2353 if ((matchIndex == -1) && (lowIndex == -1)) { 2354 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan))); 2355 matchIndex = i - 1; 2356 } 2357 } 2358 2359 if (matchIndex != -1) { 2360 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 2361 } else { 2362 HALASSERT(lowIndex != -1); 2363 /* 2364 * Get the lower and upper channels, target powers, 2365 * and interpolate between them. 2366 */ 2367 clo = fbin2freq(powInfo[lowIndex].bChannel, IS_CHAN_2GHZ(chan)); 2368 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IS_CHAN_2GHZ(chan)); 2369 2370 for (i = 0; i < numRates; i++) { 2371 pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi, 2372 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 2373 } 2374 } 2375} 2376/************************************************************** 2377 * ar5416GetTargetPowersLeg 2378 * 2379 * Return the four rates of target power for the given target power table 2380 * channel, and number of channels 2381 */ 2382static void 2383ar5416GetTargetPowersLeg(struct ath_hal *ah, 2384 HAL_CHANNEL_INTERNAL *chan, 2385 CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels, 2386 CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates, 2387 HAL_BOOL isExtTarget) 2388{ 2389 uint16_t clo, chi; 2390 int i; 2391 int matchIndex = -1, lowIndex = -1; 2392 uint16_t freq; 2393 CHAN_CENTERS centers; 2394 2395 ar5416GetChannelCenters(ah, chan, ¢ers); 2396 freq = (isExtTarget) ? centers.ext_center :centers.ctl_center; 2397 2398 /* Copy the target powers into the temp channel list */ 2399 if (freq <= fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) { 2400 matchIndex = 0; 2401 } else { 2402 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 2403 if (freq == fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) { 2404 matchIndex = i; 2405 break; 2406 } else if ((freq < fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) && 2407 (freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan)))) 2408 { 2409 lowIndex = i - 1; 2410 break; 2411 } 2412 } 2413 if ((matchIndex == -1) && (lowIndex == -1)) { 2414 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan))); 2415 matchIndex = i - 1; 2416 } 2417 } 2418 2419 if (matchIndex != -1) { 2420 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 2421 } else { 2422 HALASSERT(lowIndex != -1); 2423 /* 2424 * Get the lower and upper channels, target powers, 2425 * and interpolate between them. 2426 */ 2427 clo = fbin2freq(powInfo[lowIndex].bChannel, IS_CHAN_2GHZ(chan)); 2428 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IS_CHAN_2GHZ(chan)); 2429 2430 for (i = 0; i < numRates; i++) { 2431 pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi, 2432 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 2433 } 2434 } 2435} 2436 2437/************************************************************** 2438 * ar5416SetPowerCalTable 2439 * 2440 * Pull the PDADC piers from cal data and interpolate them across the given 2441 * points as well as from the nearest pier(s) to get a power detector 2442 * linear voltage to power level table. 2443 */ 2444static HAL_BOOL 2445ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, HAL_CHANNEL_INTERNAL *chan, int16_t *pTxPowerIndexOffset) 2446{ 2447 CAL_DATA_PER_FREQ *pRawDataset; 2448 uint8_t *pCalBChans = AH_NULL; 2449 uint16_t pdGainOverlap_t2; 2450 static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES]; 2451 uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 2452 uint16_t numPiers, i, j; 2453 int16_t tMinCalPower; 2454 uint16_t numXpdGain, xpdMask; 2455 uint16_t xpdGainValues[AR5416_NUM_PD_GAINS]; 2456 uint32_t reg32, regOffset, regChainOffset; 2457 2458 ath_hal_memzero(xpdGainValues, sizeof(xpdGainValues)); 2459 2460 xpdMask = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].xpdGain; 2461 2462 if (IS_EEP_MINOR_V2(ah)) { 2463 pdGainOverlap_t2 = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pdGainOverlap; 2464 } else { 2465 pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 2466 } 2467 2468 if (IS_CHAN_2GHZ(chan)) { 2469 pCalBChans = pEepData->calFreqPier2G; 2470 numPiers = AR5416_NUM_2G_CAL_PIERS; 2471 } else { 2472 pCalBChans = pEepData->calFreqPier5G; 2473 numPiers = AR5416_NUM_5G_CAL_PIERS; 2474 } 2475 2476 numXpdGain = 0; 2477 /* Calculate the value of xpdgains from the xpdGain Mask */ 2478 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 2479 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 2480 if (numXpdGain >= AR5416_NUM_PD_GAINS) { 2481 HALASSERT(0); 2482 break; 2483 } 2484 xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i); 2485 numXpdGain++; 2486 } 2487 } 2488 2489 /* Write the detector gain biases and their number */ 2490 OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 2491 ~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 2492 SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) | 2493 SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(xpdGainValues[2], AR_PHY_TPCRG1_PD_GAIN_3)); 2494 2495 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 2496 2497 if (AR_SREV_OWL_20_OR_LATER(ah) && 2498 ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) { 2499 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 2500 * only chains 0 and 2 populated 2501 */ 2502 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 2503 } else { 2504 regChainOffset = i * 0x1000; 2505 } 2506 2507 if (pEepData->baseEepHeader.txMask & (1 << i)) { 2508 if (IS_CHAN_2GHZ(chan)) { 2509 pRawDataset = pEepData->calPierData2G[i]; 2510 } else { 2511 pRawDataset = pEepData->calPierData5G[i]; 2512 } 2513 2514 ar5416GetGainBoundariesAndPdadcs(ah, chan, pRawDataset, 2515 pCalBChans, numPiers, 2516 pdGainOverlap_t2, 2517 &tMinCalPower, gainBoundaries, 2518 pdadcValues, numXpdGain); 2519 2520 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { 2521 /* 2522 * Note the pdadc table may not start at 0 dBm power, could be 2523 * negative or greater than 0. Need to offset the power 2524 * values by the amount of minPower for griffin 2525 */ 2526 2527 OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 2528 SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 2529 SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | 2530 SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | 2531 SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | 2532 SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 2533 } 2534 2535 /* Write the power values into the baseband power table */ 2536 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 2537 2538 for (j = 0; j < 32; j++) { 2539 reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0) | 2540 ((pdadcValues[4*j + 1] & 0xFF) << 8) | 2541 ((pdadcValues[4*j + 2] & 0xFF) << 16) | 2542 ((pdadcValues[4*j + 3] & 0xFF) << 24) ; 2543 OS_REG_WRITE(ah, regOffset, reg32); 2544 2545#ifdef PDADC_DUMP 2546 ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n", 2547 i, 2548 4*j, pdadcValues[4*j], 2549 4*j+1, pdadcValues[4*j + 1], 2550 4*j+2, pdadcValues[4*j + 2], 2551 4*j+3, pdadcValues[4*j + 3]); 2552#endif 2553 regOffset += 4; 2554 } 2555 } 2556 } 2557 *pTxPowerIndexOffset = 0; 2558 2559 return AH_TRUE; 2560} 2561 2562/************************************************************** 2563 * ar5416GetGainBoundariesAndPdadcs 2564 * 2565 * Uses the data points read from EEPROM to reconstruct the pdadc power table 2566 * Called by ar5416SetPowerCalTable only. 2567 */ 2568static void 2569ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 2570 HAL_CHANNEL_INTERNAL *chan, CAL_DATA_PER_FREQ *pRawDataSet, 2571 uint8_t * bChans, uint16_t availPiers, 2572 uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries, 2573 uint8_t * pPDADCValues, uint16_t numXpdGains) 2574{ 2575 2576 int i, j, k; 2577 int16_t ss; /* potentially -ve index for taking care of pdGainOverlap */ 2578 uint16_t idxL, idxR, numPiers; /* Pier indexes */ 2579 2580 /* filled out Vpd table for all pdGains (chanL) */ 2581 static uint8_t vpdTableL[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2582 2583 /* filled out Vpd table for all pdGains (chanR) */ 2584 static uint8_t vpdTableR[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2585 2586 /* filled out Vpd table for all pdGains (interpolated) */ 2587 static uint8_t vpdTableI[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2588 2589 uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR; 2590 uint8_t minPwrT4[AR5416_NUM_PD_GAINS]; 2591 uint8_t maxPwrT4[AR5416_NUM_PD_GAINS]; 2592 int16_t vpdStep; 2593 int16_t tmpVal; 2594 uint16_t sizeCurrVpdTable, maxIndex, tgtIndex; 2595 HAL_BOOL match; 2596 int16_t minDelta = 0; 2597 CHAN_CENTERS centers; 2598 2599 ar5416GetChannelCenters(ah, chan, ¢ers); 2600 2601 /* Trim numPiers for the number of populated channel Piers */ 2602 for (numPiers = 0; numPiers < availPiers; numPiers++) { 2603 if (bChans[numPiers] == AR5416_BCHAN_UNUSED) { 2604 break; 2605 } 2606 } 2607 2608 /* Find pier indexes around the current channel */ 2609 match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), 2610 bChans, numPiers, &idxL, &idxR); 2611 2612 if (match) { 2613 /* Directly fill both vpd tables from the matching index */ 2614 for (i = 0; i < numXpdGains; i++) { 2615 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 2616 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 2617 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i], 2618 pRawDataSet[idxL].vpdPdg[i], AR5416_PD_GAIN_ICEPTS, vpdTableI[i]); 2619 } 2620 } else { 2621 for (i = 0; i < numXpdGains; i++) { 2622 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 2623 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 2624 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 2625 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 2626 2627 /* Start Vpd interpolation from the max of the minimum powers */ 2628 minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]); 2629 2630 /* End Vpd interpolation from the min of the max powers */ 2631 maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); 2632 HALASSERT(maxPwrT4[i] > minPwrT4[i]); 2633 2634 /* Fill pier Vpds */ 2635 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]); 2636 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]); 2637 2638 /* Interpolate the final vpd */ 2639 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 2640 vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), 2641 bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j])); 2642 } 2643 } 2644 } 2645 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 2646 2647 k = 0; /* index for the final table */ 2648 for (i = 0; i < numXpdGains; i++) { 2649 if (i == (numXpdGains - 1)) { 2650 pPdGainBoundaries[i] = (uint16_t)(maxPwrT4[i] / 2); 2651 } else { 2652 pPdGainBoundaries[i] = (uint16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4); 2653 } 2654 2655 pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); 2656 2657 /* NB: only applies to owl 1.0 */ 2658 if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { 2659 /* 2660 * fix the gain delta, but get a delta that can be applied to min to 2661 * keep the upper power values accurate, don't think max needs to 2662 * be adjusted because should not be at that area of the table? 2663 */ 2664 minDelta = pPdGainBoundaries[0] - 23; 2665 pPdGainBoundaries[0] = 23; 2666 } 2667 else { 2668 minDelta = 0; 2669 } 2670 2671 /* Find starting index for this pdGain */ 2672 if (i == 0) { 2673 ss = 0; /* for the first pdGain, start from index 0 */ 2674 } else { 2675 /* need overlap entries extrapolated below. */ 2676 ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta); 2677 } 2678 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 2679 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2680 /* 2681 *-ve ss indicates need to extrapolate data below for this pdGain 2682 */ 2683 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2684 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 2685 pPDADCValues[k++] = (uint8_t)((tmpVal < 0) ? 0 : tmpVal); 2686 ss++; 2687 } 2688 2689 sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1); 2690 tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2)); 2691 maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable; 2692 2693 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2694 pPDADCValues[k++] = vpdTableI[i][ss++]; 2695 } 2696 2697 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]); 2698 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2699 /* 2700 * for last gain, pdGainBoundary == Pmax_t2, so will 2701 * have to extrapolate 2702 */ 2703 if (tgtIndex > maxIndex) { /* need to extrapolate above */ 2704 while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2705 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + 2706 (ss - maxIndex +1) * vpdStep)); 2707 pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ? 255 : tmpVal); 2708 ss++; 2709 } 2710 } /* extrapolated above */ 2711 } /* for all pdGainUsed */ 2712 2713 /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */ 2714 while (i < AR5416_PD_GAINS_IN_MASK) { 2715 pPdGainBoundaries[i] = pPdGainBoundaries[i-1]; 2716 i++; 2717 } 2718 2719 while (k < AR5416_NUM_PDADC_VALUES) { 2720 pPDADCValues[k] = pPDADCValues[k-1]; 2721 k++; 2722 } 2723 return; 2724} 2725 2726/************************************************************** 2727 * getLowerUppderIndex 2728 * 2729 * Return indices surrounding the value in sorted integer lists. 2730 * Requirement: the input list must be monotonically increasing 2731 * and populated up to the list size 2732 * Returns: match is set if an index in the array matches exactly 2733 * or a the target is before or after the range of the array. 2734 */ 2735HAL_BOOL 2736getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize, 2737 uint16_t *indexL, uint16_t *indexR) 2738{ 2739 uint16_t i; 2740 2741 /* 2742 * Check first and last elements for beyond ordered array cases. 2743 */ 2744 if (target <= pList[0]) { 2745 *indexL = *indexR = 0; 2746 return AH_TRUE; 2747 } 2748 if (target >= pList[listSize-1]) { 2749 *indexL = *indexR = (uint16_t)(listSize - 1); 2750 return AH_TRUE; 2751 } 2752 2753 /* look for value being near or between 2 values in list */ 2754 for (i = 0; i < listSize - 1; i++) { 2755 /* 2756 * If value is close to the current value of the list 2757 * then target is not between values, it is one of the values 2758 */ 2759 if (pList[i] == target) { 2760 *indexL = *indexR = i; 2761 return AH_TRUE; 2762 } 2763 /* 2764 * Look for value being between current value and next value 2765 * if so return these 2 values 2766 */ 2767 if (target < pList[i + 1]) { 2768 *indexL = i; 2769 *indexR = (uint16_t)(i + 1); 2770 return AH_FALSE; 2771 } 2772 } 2773 HALASSERT(0); 2774 return AH_FALSE; 2775} 2776 2777/************************************************************** 2778 * ar5416FillVpdTable 2779 * 2780 * Fill the Vpdlist for indices Pmax-Pmin 2781 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 2782 */ 2783static HAL_BOOL 2784ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList, 2785 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList) 2786{ 2787 uint16_t i, k; 2788 uint8_t currPwr = pwrMin; 2789 uint16_t idxL, idxR; 2790 2791 HALASSERT(pwrMax > pwrMin); 2792 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 2793 getLowerUpperIndex(currPwr, pPwrList, numIntercepts, 2794 &(idxL), &(idxR)); 2795 if (idxR < 1) 2796 idxR = 1; /* extrapolate below */ 2797 if (idxL == numIntercepts - 1) 2798 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */ 2799 if (pPwrList[idxL] == pPwrList[idxR]) 2800 k = pVpdList[idxL]; 2801 else 2802 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 2803 (pPwrList[idxR] - pPwrList[idxL]) ); 2804 HALASSERT(k < 256); 2805 pRetVpdList[i] = (uint8_t)k; 2806 currPwr += 2; /* half dB steps */ 2807 } 2808 2809 return AH_TRUE; 2810} 2811 2812/************************************************************************** 2813 * interpolate 2814 * 2815 * Returns signed interpolated or the scaled up interpolated value 2816 */ 2817static int16_t 2818interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 2819 int16_t targetLeft, int16_t targetRight) 2820{ 2821 int16_t rv; 2822 2823 if (srcRight == srcLeft) { 2824 rv = targetLeft; 2825 } else { 2826 rv = (int16_t)( ((target - srcLeft) * targetRight + 2827 (srcRight - target) * targetLeft) / (srcRight - srcLeft) ); 2828 } 2829 return rv; 2830} 2831 2832static void 2833ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan) 2834{ 2835 uint32_t phymode; 2836 HAL_HT_MACMODE macmode; /* MAC - 20/40 mode */ 2837 2838 if (!IS_CHAN_HT(chan)) 2839 return; 2840 2841 /* Enable 11n HT, 20 MHz */ 2842 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 2843 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH; 2844 2845 /* Configure baseband for dynamic 20/40 operation */ 2846 if (IS_CHAN_HT40(chan)) { 2847 phymode |= AR_PHY_FC_DYN2040_EN | AR_PHY_FC_SHORT_GI_40; 2848 2849 /* Configure control (primary) channel at +-10MHz */ 2850 if ((chan->channelFlags & CHANNEL_HT40PLUS)) 2851 phymode |= AR_PHY_FC_DYN2040_PRI_CH; 2852#if 0 2853 /* Configure 20/25 spacing */ 2854 if (ht->ht_extprotspacing == HAL_HT_EXTPROTSPACING_25) 2855 phymode |= AR_PHY_FC_DYN2040_EXT_CH; 2856#endif 2857 macmode = HAL_HT_MACMODE_2040; 2858 } else 2859 macmode = HAL_HT_MACMODE_20; 2860 OS_REG_WRITE(ah, AR_PHY_TURBO, phymode); 2861 2862 /* Configure MAC for 20/40 operation */ 2863 ar5416Set11nMac2040(ah, macmode); 2864 2865 /* global transmit timeout (25 TUs default)*/ 2866 /* XXX - put this elsewhere??? */ 2867 OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S) ; 2868 2869 /* carrier sense timeout */ 2870 OS_REG_SET_BIT(ah, AR_GTTM, AR_GTTM_CST_USEC); 2871 OS_REG_WRITE(ah, AR_CST, 1 << AR_CST_TIMEOUT_LIMIT_S); 2872} 2873 2874void 2875ar5416GetChannelCenters(struct ath_hal *ah, 2876 HAL_CHANNEL_INTERNAL *chan, CHAN_CENTERS *centers) 2877{ 2878 centers->ctl_center = chan->channel; 2879 centers->synth_center = chan->channel; 2880 /* 2881 * In 20/40 phy mode, the center frequency is 2882 * "between" the control and extension channels. 2883 */ 2884 if (chan->channelFlags & CHANNEL_HT40PLUS) { 2885 centers->synth_center += HT40_CHANNEL_CENTER_SHIFT; 2886 centers->ext_center = 2887 centers->synth_center + HT40_CHANNEL_CENTER_SHIFT; 2888 } else if (chan->channelFlags & CHANNEL_HT40MINUS) { 2889 centers->synth_center -= HT40_CHANNEL_CENTER_SHIFT; 2890 centers->ext_center = 2891 centers->synth_center - HT40_CHANNEL_CENTER_SHIFT; 2892 } else { 2893 centers->ext_center = chan->channel; 2894 } 2895} |
2898#endif /* AH_SUPPORT_AR5416 */ | |