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