ar5416_reset.c revision 219975
1263320Sdim/* 2263320Sdim * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3263320Sdim * Copyright (c) 2002-2008 Atheros Communications, Inc. 4263320Sdim * 5263320Sdim * Permission to use, copy, modify, and/or distribute this software for any 6263320Sdim * purpose with or without fee is hereby granted, provided that the above 7269012Semaste * copyright notice and this permission notice appear in all copies. 8263320Sdim * 9263320Sdim * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10263320Sdim * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11263320Sdim * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12263320Sdim * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13263320Sdim * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14263320Sdim * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15263320Sdim * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16263320Sdim * 17263320Sdim * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c 219975 2011-03-25 00:03:21Z adrian $ 18263320Sdim */ 19263320Sdim#include "opt_ah.h" 20263320Sdim 21263320Sdim#include "ah.h" 22263320Sdim#include "ah_internal.h" 23263320Sdim#include "ah_devid.h" 24263320Sdim 25263320Sdim#include "ah_eeprom_v14.h" 26263320Sdim 27263320Sdim#include "ar5416/ar5416.h" 28263320Sdim#include "ar5416/ar5416reg.h" 29263320Sdim#include "ar5416/ar5416phy.h" 30263320Sdim 31263320Sdim/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ 32263320Sdim#define EEP_MINOR(_ah) \ 33263320Sdim (AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK) 34263320Sdim#define IS_EEP_MINOR_V2(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2) 35263320Sdim#define IS_EEP_MINOR_V3(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3) 36263320Sdim 37263320Sdim/* Additional Time delay to wait after activiting the Base band */ 38263320Sdim#define BASE_ACTIVATE_DELAY 100 /* 100 usec */ 39263320Sdim#define PLL_SETTLE_DELAY 300 /* 300 usec */ 40263320Sdim#define RTC_PLL_SETTLE_DELAY 1000 /* 1 ms */ 41263320Sdim 42263320Sdimstatic void ar5416InitDMA(struct ath_hal *ah); 43263320Sdimstatic void ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *); 44263320Sdimstatic void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode); 45263320Sdimstatic void ar5416InitQoS(struct ath_hal *ah); 46static void ar5416InitUserSettings(struct ath_hal *ah); 47static void ar5416UpdateChainMasks(struct ath_hal *ah, HAL_BOOL is_ht); 48static void ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *); 49 50#if 0 51static HAL_BOOL ar5416ChannelChange(struct ath_hal *, const struct ieee80211_channel *); 52#endif 53static void ar5416SetDeltaSlope(struct ath_hal *, const struct ieee80211_channel *); 54 55static HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah); 56static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type); 57static void ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan); 58static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah, 59 struct ar5416eeprom *pEepData, 60 const struct ieee80211_channel *chan, int16_t *ratesArray, 61 uint16_t cfgCtl, uint16_t AntennaReduction, 62 uint16_t twiceMaxRegulatoryPower, 63 uint16_t powerLimit); 64static uint16_t ar5416GetMaxEdgePower(uint16_t freq, 65 CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz); 66static void ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan); 67 68/* 69 * Places the device in and out of reset and then places sane 70 * values in the registers based on EEPROM config, initialization 71 * vectors (as determined by the mode), and station configuration 72 * 73 * bChannelChange is used to preserve DMA/PCU registers across 74 * a HW Reset during channel change. 75 */ 76HAL_BOOL 77ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, 78 struct ieee80211_channel *chan, 79 HAL_BOOL bChannelChange, HAL_STATUS *status) 80{ 81#define N(a) (sizeof (a) / sizeof (a[0])) 82#define FAIL(_code) do { ecode = _code; goto bad; } while (0) 83 struct ath_hal_5212 *ahp = AH5212(ah); 84 HAL_CHANNEL_INTERNAL *ichan; 85 uint32_t saveDefAntenna, saveLedState; 86 uint32_t macStaId1; 87 uint16_t rfXpdGain[2]; 88 HAL_STATUS ecode; 89 uint32_t powerVal, rssiThrReg; 90 uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow; 91 int i; 92 uint64_t tsf = 0; 93 94 OS_MARK(ah, AH_MARK_RESET, bChannelChange); 95 96 /* Bring out of sleep mode */ 97 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 98 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n", 99 __func__); 100 FAIL(HAL_EIO); 101 } 102 103 /* 104 * Map public channel to private. 105 */ 106 ichan = ath_hal_checkchannel(ah, chan); 107 if (ichan == AH_NULL) 108 FAIL(HAL_EINVAL); 109 switch (opmode) { 110 case HAL_M_STA: 111 case HAL_M_IBSS: 112 case HAL_M_HOSTAP: 113 case HAL_M_MONITOR: 114 break; 115 default: 116 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n", 117 __func__, opmode); 118 FAIL(HAL_EINVAL); 119 break; 120 } 121 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 122 123 /* XXX Turn on fast channel change for 5416 */ 124 /* 125 * Preserve the bmiss rssi threshold and count threshold 126 * across resets 127 */ 128 rssiThrReg = OS_REG_READ(ah, AR_RSSI_THR); 129 /* If reg is zero, first time thru set to default val */ 130 if (rssiThrReg == 0) 131 rssiThrReg = INIT_RSSI_THR; 132 133 /* 134 * Preserve the antenna on a channel change 135 */ 136 saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA); 137 if (saveDefAntenna == 0) /* XXX magic constants */ 138 saveDefAntenna = 1; 139 140 /* Save hardware flag before chip reset clears the register */ 141 macStaId1 = OS_REG_READ(ah, AR_STA_ID1) & 142 (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT); 143 144 /* Save led state from pci config register */ 145 saveLedState = OS_REG_READ(ah, AR_MAC_LED) & 146 (AR_MAC_LED_ASSOC | AR_MAC_LED_MODE | 147 AR_MAC_LED_BLINK_THRESH_SEL | AR_MAC_LED_BLINK_SLOW); 148 149 /* For chips on which the RTC reset is done, save TSF before it gets cleared */ 150 if (AR_SREV_MERLIN_20_OR_LATER(ah) && ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) 151 tsf = ar5212GetTsf64(ah); 152 153 if (!ar5416ChipReset(ah, chan)) { 154 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); 155 FAIL(HAL_EIO); 156 } 157 158 /* Restore bmiss rssi & count thresholds */ 159 OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg); 160 161 /* Restore TSF */ 162 if (tsf) 163 ar5212SetTsf64(ah, tsf); 164 165 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 166 if (AR_SREV_MERLIN_10_OR_LATER(ah)) 167 OS_REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 168 169 if (AR_SREV_KITE(ah)) { 170 uint32_t val; 171 val = OS_REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); 172 val &= ~AR_PHY_RIFS_INIT_DELAY; 173 OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); 174 } 175 176 AH5416(ah)->ah_writeIni(ah, chan); 177 178 /* Override ini values (that can be overriden in this fashion) */ 179 ar5416OverrideIni(ah, chan); 180 181 /* Setup 11n MAC/Phy mode registers */ 182 ar5416Set11nRegs(ah, chan); 183 184 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 185 186 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_DAG_CTRLCCK=0x%x\n", 187 __func__, OS_REG_READ(ah,AR_PHY_DAG_CTRLCCK)); 188 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_ADC_CTL=0x%x\n", 189 __func__, OS_REG_READ(ah,AR_PHY_ADC_CTL)); 190 191 /* Set the mute mask to the correct default */ 192 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) 193 OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F); 194 195 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) { 196 /* Clear reg to alllow RX_CLEAR line debug */ 197 OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0); 198 } 199 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) { 200#ifdef notyet 201 /* Enable burst prefetch for the data queues */ 202 OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... ); 203 /* Enable double-buffering */ 204 OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS); 205#endif 206 } 207 208 /* 209 * Setup ah_tx_chainmask / ah_rx_chainmask before we fiddle 210 * with enabling the TX/RX radio chains. 211 */ 212 ar5416UpdateChainMasks(ah, IEEE80211_IS_CHAN_HT(chan)); 213 /* 214 * This routine swaps the analog chains - it should be done 215 * before any radio register twiddling is done. 216 */ 217 ar5416InitChainMasks(ah); 218 AH5416(ah)->ah_olcInit(ah); 219 220 /* Setup the transmit power values. */ 221 if (!ah->ah_setTxPower(ah, chan, rfXpdGain)) { 222 HALDEBUG(ah, HAL_DEBUG_ANY, 223 "%s: error init'ing transmit power\n", __func__); 224 FAIL(HAL_EIO); 225 } 226 227 /* Write the analog registers */ 228 if (!ahp->ah_rfHal->setRfRegs(ah, chan, 229 IEEE80211_IS_CHAN_2GHZ(chan) ? 2: 1, rfXpdGain)) { 230 HALDEBUG(ah, HAL_DEBUG_ANY, 231 "%s: ar5212SetRfRegs failed\n", __func__); 232 FAIL(HAL_EIO); 233 } 234 235 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 236 if (IEEE80211_IS_CHAN_OFDM(chan)|| IEEE80211_IS_CHAN_HT(chan)) 237 ar5416SetDeltaSlope(ah, chan); 238 239 AH5416(ah)->ah_spurMitigate(ah, chan); 240 241 /* Setup board specific options for EEPROM version 3 */ 242 if (!ah->ah_setBoardValues(ah, chan)) { 243 HALDEBUG(ah, HAL_DEBUG_ANY, 244 "%s: error setting board options\n", __func__); 245 FAIL(HAL_EIO); 246 } 247 248 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 249 250 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 251 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) 252 | macStaId1 253 | AR_STA_ID1_RTS_USE_DEF 254 | ahp->ah_staId1Defaults 255 ); 256 ar5212SetOperatingMode(ah, opmode); 257 258 /* Set Venice BSSID mask according to current state */ 259 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask)); 260 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4)); 261 262 /* Restore previous led state */ 263 OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) | saveLedState); 264 265 /* Restore previous antenna */ 266 OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 267 268 /* then our BSSID */ 269 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 270 OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4)); 271 272 /* Restore bmiss rssi & count thresholds */ 273 OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr); 274 275 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ 276 277 if (!ar5212SetChannel(ah, chan)) 278 FAIL(HAL_EIO); 279 280 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 281 282 /* Set 1:1 QCU to DCU mapping for all queues */ 283 for (i = 0; i < AR_NUM_DCU; i++) 284 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 285 286 ahp->ah_intrTxqs = 0; 287 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) 288 ah->ah_resetTxQueue(ah, i); 289 290 ar5416InitIMR(ah, opmode); 291 ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); 292 ar5416InitQoS(ah); 293 ar5416InitUserSettings(ah); 294 295 /* 296 * disable seq number generation in hw 297 */ 298 OS_REG_WRITE(ah, AR_STA_ID1, 299 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 300 301 ar5416InitDMA(ah); 302 303 /* 304 * program OBS bus to see MAC interrupts 305 */ 306 OS_REG_WRITE(ah, AR_OBS, 8); 307 308#ifdef AR5416_INT_MITIGATION 309 OS_REG_WRITE(ah, AR_MIRT, 0); 310 311 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 312 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 313 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300); 314 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750); 315#endif 316 317 ar5416InitBB(ah, chan); 318 319 /* Setup compression registers */ 320 ar5212SetCompRegs(ah); /* XXX not needed? */ 321 322 /* 323 * 5416 baseband will check the per rate power table 324 * and select the lower of the two 325 */ 326 ackTpcPow = 63; 327 ctsTpcPow = 63; 328 chirpTpcPow = 63; 329 powerVal = SM(ackTpcPow, AR_TPC_ACK) | 330 SM(ctsTpcPow, AR_TPC_CTS) | 331 SM(chirpTpcPow, AR_TPC_CHIRP); 332 OS_REG_WRITE(ah, AR_TPC, powerVal); 333 334 if (!ar5416InitCal(ah, chan)) 335 FAIL(HAL_ESELFTEST); 336 337 ar5416RestoreChainMask(ah); 338 339 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 340 341 if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan)) 342 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT; 343 344 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__); 345 346 OS_MARK(ah, AH_MARK_RESET_DONE, 0); 347 348 return AH_TRUE; 349bad: 350 OS_MARK(ah, AH_MARK_RESET_DONE, ecode); 351 if (status != AH_NULL) 352 *status = ecode; 353 return AH_FALSE; 354#undef FAIL 355#undef N 356} 357 358#if 0 359/* 360 * This channel change evaluates whether the selected hardware can 361 * perform a synthesizer-only channel change (no reset). If the 362 * TX is not stopped, or the RFBus cannot be granted in the given 363 * time, the function returns false as a reset is necessary 364 */ 365HAL_BOOL 366ar5416ChannelChange(struct ath_hal *ah, const structu ieee80211_channel *chan) 367{ 368 uint32_t ulCount; 369 uint32_t data, synthDelay, qnum; 370 uint16_t rfXpdGain[4]; 371 struct ath_hal_5212 *ahp = AH5212(ah); 372 HAL_CHANNEL_INTERNAL *ichan; 373 374 /* 375 * Map public channel to private. 376 */ 377 ichan = ath_hal_checkchannel(ah, chan); 378 379 /* TX must be stopped or RF Bus grant will not work */ 380 for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) { 381 if (ar5212NumTxPending(ah, qnum)) { 382 HALDEBUG(ah, HAL_DEBUG_ANY, 383 "%s: frames pending on queue %d\n", __func__, qnum); 384 return AH_FALSE; 385 } 386 } 387 388 /* 389 * Kill last Baseband Rx Frame - Request analog bus grant 390 */ 391 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); 392 if (!ath_hal_wait(ah, AR_PHY_RFBUS_GNT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) { 393 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: could not kill baseband rx\n", 394 __func__); 395 return AH_FALSE; 396 } 397 398 ar5416Set11nRegs(ah, chan); /* NB: setup 5416-specific regs */ 399 400 /* Change the synth */ 401 if (!ar5212SetChannel(ah, chan)) 402 return AH_FALSE; 403 404 /* Setup the transmit power values. */ 405 if (!ah->ah_setTxPower(ah, chan, rfXpdGain)) { 406 HALDEBUG(ah, HAL_DEBUG_ANY, 407 "%s: error init'ing transmit power\n", __func__); 408 return AH_FALSE; 409 } 410 411 /* 412 * Wait for the frequency synth to settle (synth goes on 413 * via PHY_ACTIVE_EN). Read the phy active delay register. 414 * Value is in 100ns increments. 415 */ 416 data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 417 if (IS_CHAN_CCK(ichan)) { 418 synthDelay = (4 * data) / 22; 419 } else { 420 synthDelay = data / 10; 421 } 422 423 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 424 425 /* Release the RFBus Grant */ 426 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 427 428 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 429 if (IEEE80211_IS_CHAN_OFDM(ichan)|| IEEE80211_IS_CHAN_HT(chan)) { 430 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3); 431 ar5212SetSpurMitigation(ah, chan); 432 ar5416SetDeltaSlope(ah, chan); 433 } 434 435 /* XXX spur mitigation for Melin */ 436 437 if (!IEEE80211_IS_CHAN_DFS(chan)) 438 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT; 439 440 ichan->channel_time = 0; 441 ichan->tsf_last = ar5212GetTsf64(ah); 442 ar5212TxEnable(ah, AH_TRUE); 443 return AH_TRUE; 444} 445#endif 446 447static void 448ar5416InitDMA(struct ath_hal *ah) 449{ 450 struct ath_hal_5212 *ahp = AH5212(ah); 451 452 /* 453 * set AHB_MODE not to do cacheline prefetches 454 */ 455 OS_REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); 456 457 /* 458 * let mac dma reads be in 128 byte chunks 459 */ 460 OS_REG_WRITE(ah, AR_TXCFG, 461 (OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK) | AR_TXCFG_DMASZ_128B); 462 463 /* 464 * let mac dma writes be in 128 byte chunks 465 */ 466 OS_REG_WRITE(ah, AR_RXCFG, 467 (OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B); 468 469 /* restore TX trigger level */ 470 OS_REG_WRITE(ah, AR_TXCFG, 471 (OS_REG_READ(ah, AR_TXCFG) &~ AR_FTRIG) | 472 SM(ahp->ah_txTrigLev, AR_FTRIG)); 473 474 /* 475 * Setup receive FIFO threshold to hold off TX activities 476 */ 477 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 478 479 /* 480 * reduce the number of usable entries in PCU TXBUF to avoid 481 * wrap around. 482 */ 483 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE); 484} 485 486static void 487ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *chan) 488{ 489 uint32_t synthDelay; 490 491 /* 492 * Wait for the frequency synth to settle (synth goes on 493 * via AR_PHY_ACTIVE_EN). Read the phy active delay register. 494 * Value is in 100ns increments. 495 */ 496 synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 497 if (IEEE80211_IS_CHAN_CCK(chan)) { 498 synthDelay = (4 * synthDelay) / 22; 499 } else { 500 synthDelay /= 10; 501 } 502 503 /* Turn on PLL on 5416 */ 504 HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n", 505 __func__, IEEE80211_IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz"); 506 ar5416InitPLL(ah, chan); 507 508 /* Activate the PHY (includes baseband activate and synthesizer on) */ 509 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 510 511 /* 512 * If the AP starts the calibration before the base band timeout 513 * completes we could get rx_clear false triggering. Add an 514 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition 515 * does not happen. 516 */ 517 if (IEEE80211_IS_CHAN_HALF(chan)) { 518 OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY); 519 } else if (IEEE80211_IS_CHAN_QUARTER(chan)) { 520 OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY); 521 } else { 522 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 523 } 524} 525 526static void 527ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode) 528{ 529 struct ath_hal_5212 *ahp = AH5212(ah); 530 531 /* 532 * Setup interrupt handling. Note that ar5212ResetTxQueue 533 * manipulates the secondary IMR's as queues are enabled 534 * and disabled. This is done with RMW ops to insure the 535 * settings we make here are preserved. 536 */ 537 ahp->ah_maskReg = AR_IMR_TXERR | AR_IMR_TXURN 538 | AR_IMR_RXERR | AR_IMR_RXORN 539 | AR_IMR_BCNMISC; 540 541#ifdef AR5416_INT_MITIGATION 542 ahp->ah_maskReg |= AR_IMR_TXINTM | AR_IMR_RXINTM 543 | AR_IMR_TXMINTR | AR_IMR_RXMINTR; 544#else 545 ahp->ah_maskReg |= AR_IMR_TXOK | AR_IMR_RXOK; 546#endif 547 if (opmode == HAL_M_HOSTAP) 548 ahp->ah_maskReg |= AR_IMR_MIB; 549 OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); 550 /* Enable bus errors that are OR'd to set the HIUERR bit */ 551#if 0 552 OS_REG_WRITE(ah, AR_IMR_S2, 553 OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST); 554#endif 555} 556 557static void 558ar5416InitQoS(struct ath_hal *ah) 559{ 560 /* QoS support */ 561 OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */ 562 OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */ 563 564 /* Turn on NOACK Support for QoS packets */ 565 OS_REG_WRITE(ah, AR_NOACK, 566 SM(2, AR_NOACK_2BIT_VALUE) | 567 SM(5, AR_NOACK_BIT_OFFSET) | 568 SM(0, AR_NOACK_BYTE_OFFSET)); 569 570 /* 571 * initialize TXOP for all TIDs 572 */ 573 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); 574 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); 575 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); 576 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); 577 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 578} 579 580static void 581ar5416InitUserSettings(struct ath_hal *ah) 582{ 583 struct ath_hal_5212 *ahp = AH5212(ah); 584 585 /* Restore user-specified settings */ 586 if (ahp->ah_miscMode != 0) 587 OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode); 588 if (ahp->ah_sifstime != (u_int) -1) 589 ar5212SetSifsTime(ah, ahp->ah_sifstime); 590 if (ahp->ah_slottime != (u_int) -1) 591 ar5212SetSlotTime(ah, ahp->ah_slottime); 592 if (ahp->ah_acktimeout != (u_int) -1) 593 ar5212SetAckTimeout(ah, ahp->ah_acktimeout); 594 if (ahp->ah_ctstimeout != (u_int) -1) 595 ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout); 596 if (AH_PRIVATE(ah)->ah_diagreg != 0) 597 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 598#if 0 /* XXX Todo */ 599 if (ahp->ah_globaltxtimeout != (u_int) -1) 600 ar5416SetGlobalTxTimeout(ah, ahp->ah_globaltxtimeout); 601#endif 602} 603 604static void 605ar5416SetRfMode(struct ath_hal *ah, const struct ieee80211_channel *chan) 606{ 607 uint32_t rfMode; 608 609 if (chan == AH_NULL) 610 return; 611 612 /* treat channel B as channel G , no B mode suport in owl */ 613 rfMode = IEEE80211_IS_CHAN_CCK(chan) ? 614 AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; 615 616 if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 617 /* phy mode bits for 5GHz channels require Fast Clock */ 618 rfMode |= AR_PHY_MODE_DYNAMIC 619 | AR_PHY_MODE_DYN_CCK_DISABLE; 620 } else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) { 621 rfMode |= IEEE80211_IS_CHAN_5GHZ(chan) ? 622 AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; 623 } 624 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); 625} 626 627/* 628 * Places the hardware into reset and then pulls it out of reset 629 */ 630HAL_BOOL 631ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan) 632{ 633 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0); 634 /* 635 * Warm reset is optimistic. 636 */ 637 if (AR_SREV_MERLIN_20_OR_LATER(ah) && 638 ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 639 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) 640 return AH_FALSE; 641 } else { 642 if (!ar5416SetResetReg(ah, HAL_RESET_WARM)) 643 return AH_FALSE; 644 } 645 646 /* Bring out of sleep mode (AGAIN) */ 647 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 648 return AH_FALSE; 649 650 ar5416InitPLL(ah, chan); 651 652 /* 653 * Perform warm reset before the mode/PLL/turbo registers 654 * are changed in order to deactivate the radio. Mode changes 655 * with an active radio can result in corrupted shifts to the 656 * radio device. 657 */ 658 if (chan != AH_NULL) 659 ar5416SetRfMode(ah, chan); 660 661 return AH_TRUE; 662} 663 664/* 665 * Delta slope coefficient computation. 666 * Required for OFDM operation. 667 */ 668static void 669ar5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled, 670 uint32_t *coef_mantissa, uint32_t *coef_exponent) 671{ 672#define COEF_SCALE_S 24 673 uint32_t coef_exp, coef_man; 674 /* 675 * ALGO -> coef_exp = 14-floor(log2(coef)); 676 * floor(log2(x)) is the highest set bit position 677 */ 678 for (coef_exp = 31; coef_exp > 0; coef_exp--) 679 if ((coef_scaled >> coef_exp) & 0x1) 680 break; 681 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */ 682 HALASSERT(coef_exp); 683 coef_exp = 14 - (coef_exp - COEF_SCALE_S); 684 685 /* 686 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5); 687 * The coefficient is already shifted up for scaling 688 */ 689 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); 690 691 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp); 692 *coef_exponent = coef_exp - 16; 693 694#undef COEF_SCALE_S 695} 696 697void 698ar5416SetDeltaSlope(struct ath_hal *ah, const struct ieee80211_channel *chan) 699{ 700#define INIT_CLOCKMHZSCALED 0x64000000 701 uint32_t coef_scaled, ds_coef_exp, ds_coef_man; 702 uint32_t clockMhzScaled; 703 704 CHAN_CENTERS centers; 705 706 /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */ 707 /* scale for selected channel bandwidth */ 708 clockMhzScaled = INIT_CLOCKMHZSCALED; 709 if (IEEE80211_IS_CHAN_TURBO(chan)) 710 clockMhzScaled <<= 1; 711 else if (IEEE80211_IS_CHAN_HALF(chan)) 712 clockMhzScaled >>= 1; 713 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 714 clockMhzScaled >>= 2; 715 716 /* 717 * ALGO -> coef = 1e8/fcarrier*fclock/40; 718 * scaled coef to provide precision for this floating calculation 719 */ 720 ar5416GetChannelCenters(ah, chan, ¢ers); 721 coef_scaled = clockMhzScaled / centers.synth_center; 722 723 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 724 725 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 726 AR_PHY_TIMING3_DSC_MAN, ds_coef_man); 727 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 728 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); 729 730 /* 731 * For Short GI, 732 * scaled coeff is 9/10 that of normal coeff 733 */ 734 coef_scaled = (9 * coef_scaled)/10; 735 736 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 737 738 /* for short gi */ 739 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 740 AR_PHY_HALFGI_DSC_MAN, ds_coef_man); 741 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 742 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); 743#undef INIT_CLOCKMHZSCALED 744} 745 746/* 747 * Set a limit on the overall output power. Used for dynamic 748 * transmit power control and the like. 749 * 750 * NB: limit is in units of 0.5 dbM. 751 */ 752HAL_BOOL 753ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit) 754{ 755 uint16_t dummyXpdGains[2]; 756 757 AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); 758 return ah->ah_setTxPower(ah, AH_PRIVATE(ah)->ah_curchan, 759 dummyXpdGains); 760} 761 762HAL_BOOL 763ar5416GetChipPowerLimits(struct ath_hal *ah, 764 struct ieee80211_channel *chan) 765{ 766 struct ath_hal_5212 *ahp = AH5212(ah); 767 int16_t minPower, maxPower; 768 769 /* 770 * Get Pier table max and min powers. 771 */ 772 if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) { 773 /* NB: rf code returns 1/4 dBm units, convert */ 774 chan->ic_maxpower = maxPower / 2; 775 chan->ic_minpower = minPower / 2; 776 } else { 777 HALDEBUG(ah, HAL_DEBUG_ANY, 778 "%s: no min/max power for %u/0x%x\n", 779 __func__, chan->ic_freq, chan->ic_flags); 780 chan->ic_maxpower = AR5416_MAX_RATE_POWER; 781 chan->ic_minpower = 0; 782 } 783 HALDEBUG(ah, HAL_DEBUG_RESET, 784 "Chan %d: MaxPow = %d MinPow = %d\n", 785 chan->ic_freq, chan->ic_maxpower, chan->ic_minpower); 786 return AH_TRUE; 787} 788 789/* XXX gag, this is sick */ 790typedef enum Ar5416_Rates { 791 rate6mb, rate9mb, rate12mb, rate18mb, 792 rate24mb, rate36mb, rate48mb, rate54mb, 793 rate1l, rate2l, rate2s, rate5_5l, 794 rate5_5s, rate11l, rate11s, rateXr, 795 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, 796 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, 797 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, 798 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, 799 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, 800 Ar5416RateSize 801} AR5416_RATES; 802 803/************************************************************** 804 * ar5416SetTransmitPower 805 * 806 * Set the transmit power in the baseband for the given 807 * operating channel and mode. 808 */ 809HAL_BOOL 810ar5416SetTransmitPower(struct ath_hal *ah, 811 const struct ieee80211_channel *chan, uint16_t *rfXpdGain) 812{ 813#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 814#define N(a) (sizeof (a) / sizeof (a[0])) 815 816 MODAL_EEP_HEADER *pModal; 817 struct ath_hal_5212 *ahp = AH5212(ah); 818 int16_t ratesArray[Ar5416RateSize]; 819 int16_t txPowerIndexOffset = 0; 820 uint8_t ht40PowerIncForPdadc = 2; 821 int i; 822 823 uint16_t cfgCtl; 824 uint16_t powerLimit; 825 uint16_t twiceAntennaReduction; 826 uint16_t twiceMaxRegulatoryPower; 827 int16_t maxPower; 828 HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 829 struct ar5416eeprom *pEepData = &ee->ee_base; 830 831 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 832 833 /* Setup info for the actual eeprom */ 834 OS_MEMZERO(ratesArray, sizeof(ratesArray)); 835 cfgCtl = ath_hal_getctl(ah, chan); 836 powerLimit = chan->ic_maxregpower * 2; 837 twiceAntennaReduction = chan->ic_maxantgain; 838 twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 839 pModal = &pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]; 840 HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n", 841 __func__,chan->ic_freq, cfgCtl ); 842 843 if (IS_EEP_MINOR_V2(ah)) { 844 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 845 } 846 847 if (!ar5416SetPowerPerRateTable(ah, pEepData, chan, 848 &ratesArray[0],cfgCtl, 849 twiceAntennaReduction, 850 twiceMaxRegulatoryPower, powerLimit)) { 851 HALDEBUG(ah, HAL_DEBUG_ANY, 852 "%s: unable to set tx power per rate table\n", __func__); 853 return AH_FALSE; 854 } 855 856 if (!AH5416(ah)->ah_setPowerCalTable(ah, pEepData, chan, &txPowerIndexOffset)) { 857 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n", 858 __func__); 859 return AH_FALSE; 860 } 861 862 maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); 863 864 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 865 maxPower = AH_MAX(maxPower, ratesArray[rate1l]); 866 } 867 868 if (IEEE80211_IS_CHAN_HT40(chan)) { 869 maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); 870 } 871 872 ahp->ah_tx6PowerInHalfDbm = maxPower; 873 AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower; 874 ahp->ah_txPowerIndexOffset = txPowerIndexOffset; 875 876 /* 877 * txPowerIndexOffset is set by the SetPowerTable() call - 878 * adjust the rate table (0 offset if rates EEPROM not loaded) 879 */ 880 for (i = 0; i < N(ratesArray); i++) { 881 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 882 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 883 ratesArray[i] = AR5416_MAX_RATE_POWER; 884 } 885 886#ifdef AH_EEPROM_DUMP 887 /* 888 * Dump the rate array whilst it represents the intended dBm*2 889 * values versus what's being adjusted before being programmed 890 * in. Keep this in mind if you code up this function and enable 891 * this debugging; the values won't necessarily be what's being 892 * programmed into the hardware. 893 */ 894 ar5416PrintPowerPerRate(ah, ratesArray); 895#endif 896 897 /* 898 * Merlin and later have a power offset, so subtract 899 * pwr_table_offset * 2 from each value. The default 900 * power offset is -5 dBm - ie, a register value of 0 901 * equates to a TX power of -5 dBm. 902 */ 903 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 904 int8_t pwr_table_offset; 905 906 (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, 907 &pwr_table_offset); 908 /* Underflow power gets clamped at raw value 0 */ 909 /* Overflow power gets camped at AR5416_MAX_RATE_POWER */ 910 for (i = 0; i < N(ratesArray); i++) { 911 /* 912 * + pwr_table_offset is in dBm 913 * + ratesArray is in 1/2 dBm 914 */ 915 ratesArray[i] -= (pwr_table_offset * 2); 916 if (ratesArray[i] < 0) 917 ratesArray[i] = 0; 918 else if (ratesArray[i] > AR5416_MAX_RATE_POWER) 919 ratesArray[i] = AR5416_MAX_RATE_POWER; 920 } 921 } 922 923 /* 924 * Adjust rates for OLC where needed 925 * 926 * The following CCK rates need adjusting when doing 2.4ghz 927 * CCK transmission. 928 * 929 * + rate2s, rate2l, rate1l, rate11s, rate11l, rate5_5s, rate5_5l 930 * + rateExtCck, rateDupCck 931 * 932 * They're adjusted here regardless. The hardware then gets 933 * programmed as needed. 5GHz operation doesn't program in CCK 934 * rates for legacy mode but they seem to be initialised for 935 * HT40 regardless of channel type. 936 */ 937 if (AR_SREV_MERLIN_20_OR_LATER(ah) && 938 ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 939 int adj[] = { 940 rate2s, rate2l, rate1l, rate11s, rate11l, 941 rate5_5s, rate5_5l, rateExtCck, rateDupCck 942 }; 943 int cck_ofdm_delta = 2; 944 int i; 945 for (i = 0; i < N(adj); i++) { 946 ratesArray[i] -= cck_ofdm_delta; 947 if (ratesArray[i] < 0) 948 ratesArray[i] = 0; 949 } 950 } 951 952 /* Write the OFDM power per rate set */ 953 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 954 POW_SM(ratesArray[rate18mb], 24) 955 | POW_SM(ratesArray[rate12mb], 16) 956 | POW_SM(ratesArray[rate9mb], 8) 957 | POW_SM(ratesArray[rate6mb], 0) 958 ); 959 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 960 POW_SM(ratesArray[rate54mb], 24) 961 | POW_SM(ratesArray[rate48mb], 16) 962 | POW_SM(ratesArray[rate36mb], 8) 963 | POW_SM(ratesArray[rate24mb], 0) 964 ); 965 966 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 967 /* Write the CCK power per rate set */ 968 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 969 POW_SM(ratesArray[rate2s], 24) 970 | POW_SM(ratesArray[rate2l], 16) 971 | POW_SM(ratesArray[rateXr], 8) /* XR target power */ 972 | POW_SM(ratesArray[rate1l], 0) 973 ); 974 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 975 POW_SM(ratesArray[rate11s], 24) 976 | POW_SM(ratesArray[rate11l], 16) 977 | POW_SM(ratesArray[rate5_5s], 8) 978 | POW_SM(ratesArray[rate5_5l], 0) 979 ); 980 HALDEBUG(ah, HAL_DEBUG_RESET, 981 "%s AR_PHY_POWER_TX_RATE3=0x%x AR_PHY_POWER_TX_RATE4=0x%x\n", 982 __func__, OS_REG_READ(ah,AR_PHY_POWER_TX_RATE3), 983 OS_REG_READ(ah,AR_PHY_POWER_TX_RATE4)); 984 } 985 986 /* Write the HT20 power per rate set */ 987 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 988 POW_SM(ratesArray[rateHt20_3], 24) 989 | POW_SM(ratesArray[rateHt20_2], 16) 990 | POW_SM(ratesArray[rateHt20_1], 8) 991 | POW_SM(ratesArray[rateHt20_0], 0) 992 ); 993 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 994 POW_SM(ratesArray[rateHt20_7], 24) 995 | POW_SM(ratesArray[rateHt20_6], 16) 996 | POW_SM(ratesArray[rateHt20_5], 8) 997 | POW_SM(ratesArray[rateHt20_4], 0) 998 ); 999 1000 if (IEEE80211_IS_CHAN_HT40(chan)) { 1001 /* Write the HT40 power per rate set */ 1002 /* Correct PAR difference between HT40 and HT20/LEGACY */ 1003 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 1004 POW_SM(ratesArray[rateHt40_3] + ht40PowerIncForPdadc, 24) 1005 | POW_SM(ratesArray[rateHt40_2] + ht40PowerIncForPdadc, 16) 1006 | POW_SM(ratesArray[rateHt40_1] + ht40PowerIncForPdadc, 8) 1007 | POW_SM(ratesArray[rateHt40_0] + ht40PowerIncForPdadc, 0) 1008 ); 1009 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 1010 POW_SM(ratesArray[rateHt40_7] + ht40PowerIncForPdadc, 24) 1011 | POW_SM(ratesArray[rateHt40_6] + ht40PowerIncForPdadc, 16) 1012 | POW_SM(ratesArray[rateHt40_5] + ht40PowerIncForPdadc, 8) 1013 | POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0) 1014 ); 1015 /* Write the Dup/Ext 40 power per rate set */ 1016 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1017 POW_SM(ratesArray[rateExtOfdm], 24) 1018 | POW_SM(ratesArray[rateExtCck], 16) 1019 | POW_SM(ratesArray[rateDupOfdm], 8) 1020 | POW_SM(ratesArray[rateDupCck], 0) 1021 ); 1022 } 1023 1024 /* Write the Power subtraction for dynamic chain changing, for per-packet powertx */ 1025 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 1026 POW_SM(pModal->pwrDecreaseFor3Chain, 6) 1027 | POW_SM(pModal->pwrDecreaseFor2Chain, 0) 1028 ); 1029 return AH_TRUE; 1030#undef POW_SM 1031#undef N 1032} 1033 1034/* 1035 * Exported call to check for a recent gain reading and return 1036 * the current state of the thermal calibration gain engine. 1037 */ 1038HAL_RFGAIN 1039ar5416GetRfgain(struct ath_hal *ah) 1040{ 1041 return HAL_RFGAIN_INACTIVE; 1042} 1043 1044/* 1045 * Places all of hardware into reset 1046 */ 1047HAL_BOOL 1048ar5416Disable(struct ath_hal *ah) 1049{ 1050 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 1051 return AH_FALSE; 1052 return ar5416SetResetReg(ah, HAL_RESET_COLD); 1053} 1054 1055/* 1056 * Places the PHY and Radio chips into reset. A full reset 1057 * must be called to leave this state. The PCI/MAC/PCU are 1058 * not placed into reset as we must receive interrupt to 1059 * re-enable the hardware. 1060 */ 1061HAL_BOOL 1062ar5416PhyDisable(struct ath_hal *ah) 1063{ 1064 return ar5416SetResetReg(ah, HAL_RESET_WARM); 1065} 1066 1067/* 1068 * Write the given reset bit mask into the reset register 1069 */ 1070HAL_BOOL 1071ar5416SetResetReg(struct ath_hal *ah, uint32_t type) 1072{ 1073 switch (type) { 1074 case HAL_RESET_POWER_ON: 1075 return ar5416SetResetPowerOn(ah); 1076 case HAL_RESET_WARM: 1077 case HAL_RESET_COLD: 1078 return ar5416SetReset(ah, type); 1079 default: 1080 HALASSERT(AH_FALSE); 1081 return AH_FALSE; 1082 } 1083} 1084 1085static HAL_BOOL 1086ar5416SetResetPowerOn(struct ath_hal *ah) 1087{ 1088 /* Power On Reset (Hard Reset) */ 1089 1090 /* 1091 * Set force wake 1092 * 1093 * If the MAC was running, previously calling 1094 * reset will wake up the MAC but it may go back to sleep 1095 * before we can start polling. 1096 * Set force wake stops that 1097 * This must be called before initiating a hard reset. 1098 */ 1099 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1100 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1101 1102 /* 1103 * RTC reset and clear 1104 */ 1105 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB); 1106 OS_REG_WRITE(ah, AR_RTC_RESET, 0); 1107 OS_DELAY(20); 1108 OS_REG_WRITE(ah, AR_RC, 0); 1109 1110 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 1111 1112 /* 1113 * Poll till RTC is ON 1114 */ 1115 if (!ath_hal_wait(ah, AR_RTC_STATUS, AR_RTC_PM_STATUS_M, AR_RTC_STATUS_ON)) { 1116 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC not waking up\n", __func__); 1117 return AH_FALSE; 1118 } 1119 1120 return ar5416SetReset(ah, HAL_RESET_COLD); 1121} 1122 1123static HAL_BOOL 1124ar5416SetReset(struct ath_hal *ah, int type) 1125{ 1126 uint32_t tmpReg, mask; 1127 1128 /* 1129 * Force wake 1130 */ 1131 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1132 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1133 1134 /* 1135 * Reset AHB 1136 */ 1137 tmpReg = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE); 1138 if (tmpReg & (AR_INTR_SYNC_LOCAL_TIMEOUT|AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { 1139 OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 1140 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF); 1141 } else { 1142 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB); 1143 } 1144 1145 /* 1146 * Set Mac(BB,Phy) Warm Reset 1147 */ 1148 switch (type) { 1149 case HAL_RESET_WARM: 1150 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM); 1151 break; 1152 case HAL_RESET_COLD: 1153 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM|AR_RTC_RC_MAC_COLD); 1154 break; 1155 default: 1156 HALASSERT(AH_FALSE); 1157 break; 1158 } 1159 1160 /* 1161 * Clear resets and force wakeup 1162 */ 1163 OS_REG_WRITE(ah, AR_RTC_RC, 0); 1164 if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) { 1165 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC stuck in MAC reset\n", __func__); 1166 return AH_FALSE; 1167 } 1168 1169 /* Clear AHB reset */ 1170 OS_REG_WRITE(ah, AR_RC, 0); 1171 1172 if (type == HAL_RESET_COLD) { 1173 if (isBigEndian()) { 1174 /* 1175 * Set CFG, little-endian for register 1176 * and descriptor accesses. 1177 */ 1178 mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG; 1179#ifndef AH_NEED_DESC_SWAP 1180 mask |= AR_CFG_SWTD; 1181#endif 1182 HALDEBUG(ah, HAL_DEBUG_RESET, 1183 "%s Applying descriptor swap\n", __func__); 1184 OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask)); 1185 } else 1186 OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS); 1187 } 1188 1189 ar5416InitPLL(ah, AH_NULL); 1190 1191 return AH_TRUE; 1192} 1193 1194void 1195ar5416InitChainMasks(struct ath_hal *ah) 1196{ 1197 if (AH5416(ah)->ah_rx_chainmask == 0x5 || 1198 AH5416(ah)->ah_tx_chainmask == 0x5) 1199 OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); 1200 /* Setup Chain Masks */ 1201 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 1202 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 1203 OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask); 1204} 1205 1206void 1207ar5416RestoreChainMask(struct ath_hal *ah) 1208{ 1209 int rx_chainmask = AH5416(ah)->ah_rx_chainmask; 1210 1211 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { 1212 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 1213 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 1214 } 1215} 1216 1217/* 1218 * Update the chainmask based on the current channel configuration. 1219 * 1220 * XXX ath9k checks bluetooth co-existence here 1221 * XXX ath9k checks whether the current state is "off-channel". 1222 * XXX ath9k sticks the hardware into 1x1 mode for legacy; 1223 * we're going to leave multi-RX on for multi-path cancellation. 1224 */ 1225static void 1226ar5416UpdateChainMasks(struct ath_hal *ah, HAL_BOOL is_ht) 1227{ 1228 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 1229 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; 1230 1231 if (is_ht) { 1232 AH5416(ah)->ah_tx_chainmask = pCap->halTxChainMask; 1233 } else { 1234 AH5416(ah)->ah_tx_chainmask = 1; 1235 } 1236 AH5416(ah)->ah_rx_chainmask = pCap->halRxChainMask; 1237 HALDEBUG(ah, HAL_DEBUG_ANY, "TX chainmask: 0x%x; RX chainmask: 0x%x\n", 1238 AH5416(ah)->ah_tx_chainmask, 1239 AH5416(ah)->ah_rx_chainmask); 1240} 1241 1242#ifndef IS_5GHZ_FAST_CLOCK_EN 1243#define IS_5GHZ_FAST_CLOCK_EN(ah, chan) AH_FALSE 1244#endif 1245 1246static void 1247ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan) 1248{ 1249 uint32_t pll; 1250 1251 if (AR_SREV_MERLIN_20(ah) && 1252 chan != AH_NULL && IEEE80211_IS_CHAN_5GHZ(chan)) { 1253 /* 1254 * PLL WAR for Merlin 2.0/2.1 1255 * When doing fast clock, set PLL to 0x142c 1256 * Else, set PLL to 0x2850 to prevent reset-to-reset variation 1257 */ 1258 pll = IS_5GHZ_FAST_CLOCK_EN(ah, chan) ? 0x142c : 0x2850; 1259 } else if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1260 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1261 if (chan != AH_NULL) { 1262 if (IEEE80211_IS_CHAN_HALF(chan)) 1263 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1264 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1265 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1266 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1267 pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV); 1268 else 1269 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); 1270 } else 1271 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); 1272 } else if (AR_SREV_SOWL_10_OR_LATER(ah)) { 1273 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1274 if (chan != AH_NULL) { 1275 if (IEEE80211_IS_CHAN_HALF(chan)) 1276 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1277 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1278 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1279 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1280 pll |= SM(0x50, AR_RTC_SOWL_PLL_DIV); 1281 else 1282 pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV); 1283 } else 1284 pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV); 1285 } else { 1286 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; 1287 if (chan != AH_NULL) { 1288 if (IEEE80211_IS_CHAN_HALF(chan)) 1289 pll |= SM(0x1, AR_RTC_PLL_CLKSEL); 1290 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1291 pll |= SM(0x2, AR_RTC_PLL_CLKSEL); 1292 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1293 pll |= SM(0xa, AR_RTC_PLL_DIV); 1294 else 1295 pll |= SM(0xb, AR_RTC_PLL_DIV); 1296 } else 1297 pll |= SM(0xb, AR_RTC_PLL_DIV); 1298 } 1299 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 1300 1301 /* TODO: 1302 * For multi-band owl, switch between bands by reiniting the PLL. 1303 */ 1304 1305 OS_DELAY(RTC_PLL_SETTLE_DELAY); 1306 1307 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK); 1308} 1309 1310static void 1311ar5416SetDefGainValues(struct ath_hal *ah, 1312 const MODAL_EEP_HEADER *pModal, 1313 const struct ar5416eeprom *eep, 1314 uint8_t txRxAttenLocal, int regChainOffset, int i) 1315{ 1316 if (IS_EEP_MINOR_V3(ah)) { 1317 txRxAttenLocal = pModal->txRxAttenCh[i]; 1318 1319 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1320 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1321 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 1322 pModal->bswMargin[i]); 1323 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1324 AR_PHY_GAIN_2GHZ_XATTEN1_DB, 1325 pModal->bswAtten[i]); 1326 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1327 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 1328 pModal->xatten2Margin[i]); 1329 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1330 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 1331 pModal->xatten2Db[i]); 1332 } else { 1333 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1334 AR_PHY_GAIN_2GHZ_BSW_MARGIN, 1335 pModal->bswMargin[i]); 1336 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1337 AR_PHY_GAIN_2GHZ_BSW_ATTEN, 1338 pModal->bswAtten[i]); 1339 } 1340 } 1341 1342 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1343 OS_REG_RMW_FIELD(ah, 1344 AR_PHY_RXGAIN + regChainOffset, 1345 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1346 OS_REG_RMW_FIELD(ah, 1347 AR_PHY_RXGAIN + regChainOffset, 1348 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); 1349 } else { 1350 OS_REG_RMW_FIELD(ah, 1351 AR_PHY_RXGAIN + regChainOffset, 1352 AR_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1353 OS_REG_RMW_FIELD(ah, 1354 AR_PHY_GAIN_2GHZ + regChainOffset, 1355 AR_PHY_GAIN_2GHZ_RXTX_MARGIN, pModal->rxTxMarginCh[i]); 1356 } 1357} 1358 1359/* 1360 * Get the register chain offset for the given chain. 1361 * 1362 * Take into account the register chain swapping with AR5416 v2.0. 1363 * 1364 * XXX make sure that the reg chain swapping is only done for 1365 * XXX AR5416 v2.0 or greater, and not later chips? 1366 */ 1367int 1368ar5416GetRegChainOffset(struct ath_hal *ah, int i) 1369{ 1370 int regChainOffset; 1371 1372 if (AR_SREV_OWL_20_OR_LATER(ah) && 1373 (AH5416(ah)->ah_rx_chainmask == 0x5 || 1374 AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) { 1375 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 1376 * only chains 0 and 2 populated 1377 */ 1378 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1379 } else { 1380 regChainOffset = i * 0x1000; 1381 } 1382 1383 return regChainOffset; 1384} 1385 1386/* 1387 * Read EEPROM header info and program the device for correct operation 1388 * given the channel value. 1389 */ 1390HAL_BOOL 1391ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan) 1392{ 1393 const HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 1394 const struct ar5416eeprom *eep = &ee->ee_base; 1395 const MODAL_EEP_HEADER *pModal; 1396 int i, regChainOffset; 1397 uint8_t txRxAttenLocal; /* workaround for eeprom versions <= 14.2 */ 1398 1399 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 1400 pModal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]; 1401 1402 /* NB: workaround for eeprom versions <= 14.2 */ 1403 txRxAttenLocal = IEEE80211_IS_CHAN_2GHZ(chan) ? 23 : 44; 1404 1405 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 1406 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1407 if (AR_SREV_MERLIN(ah)) { 1408 if (i >= 2) break; 1409 } 1410 regChainOffset = ar5416GetRegChainOffset(ah, i); 1411 1412 OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, pModal->antCtrlChain[i]); 1413 1414 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset, 1415 (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) & 1416 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1417 SM(pModal->iqCalICh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1418 SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1419 1420 /* 1421 * Large signal upgrade. 1422 * XXX update 1423 */ 1424 1425 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) 1426 ar5416SetDefGainValues(ah, pModal, eep, txRxAttenLocal, regChainOffset, i); 1427 1428 } 1429 1430 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1431 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1432 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_OB, pModal->ob); 1433 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_DB, pModal->db); 1434 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH1, AR_AN_RF2G1_CH1_OB, pModal->ob_ch1); 1435 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH1, AR_AN_RF2G1_CH1_DB, pModal->db_ch1); 1436 } else { 1437 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH0, AR_AN_RF5G1_CH0_OB5, pModal->ob); 1438 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH0, AR_AN_RF5G1_CH0_DB5, pModal->db); 1439 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH1, AR_AN_RF5G1_CH1_OB5, pModal->ob_ch1); 1440 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH1, AR_AN_RF5G1_CH1_DB5, pModal->db_ch1); 1441 } 1442 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP2, AR_AN_TOP2_XPABIAS_LVL, pModal->xpaBiasLvl); 1443 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP2, AR_AN_TOP2_LOCALBIAS, pModal->flagBits & AR5416_EEP_FLAG_LOCALBIAS); 1444 OS_A_REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, pModal->flagBits & AR5416_EEP_FLAG_FORCEXPAON); 1445 } 1446 1447 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling); 1448 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); 1449 1450 if (! AR_SREV_MERLIN_20_OR_LATER(ah)) 1451 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize); 1452 1453 OS_REG_WRITE(ah, AR_PHY_RF_CTL4, 1454 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 1455 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 1456 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) 1457 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1458 1459 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); 1460 1461 if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1462 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1463 pModal->thresh62); 1464 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 1465 pModal->thresh62); 1466 } else { 1467 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, 1468 pModal->thresh62); 1469 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CCA_THRESH62, 1470 pModal->thresh62); 1471 } 1472 1473 /* Minor Version Specific application */ 1474 if (IS_EEP_MINOR_V2(ah)) { 1475 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart); 1476 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn); 1477 } 1478 1479 if (IS_EEP_MINOR_V3(ah) && IEEE80211_IS_CHAN_HT40(chan)) 1480 /* Overwrite switch settling with HT40 value */ 1481 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); 1482 1483 if (AR_SREV_MERLIN_20_OR_LATER(ah) && EEP_MINOR(ah) >= AR5416_EEP_MINOR_VER_19) 1484 OS_REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, pModal->miscBits); 1485 1486 if (AR_SREV_MERLIN_20(ah) && EEP_MINOR(ah) >= AR5416_EEP_MINOR_VER_20) { 1487 if (IEEE80211_IS_CHAN_2GHZ(chan)) 1488 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, eep->baseEepHeader.dacLpMode); 1489 else if (eep->baseEepHeader.dacHiPwrMode_5G) 1490 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); 1491 else 1492 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, eep->baseEepHeader.dacLpMode); 1493 1494 OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, pModal->miscBits >> 2); 1495 OS_REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, AR_PHY_TX_DESIRED_SCALE_CCK, eep->baseEepHeader.desiredScaleCCK); 1496 } 1497 1498 return AH_TRUE; 1499} 1500 1501/* 1502 * Helper functions common for AP/CB/XB 1503 */ 1504 1505/* 1506 * ar5416SetPowerPerRateTable 1507 * 1508 * Sets the transmit power in the baseband for the given 1509 * operating channel and mode. 1510 */ 1511static HAL_BOOL 1512ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 1513 const struct ieee80211_channel *chan, 1514 int16_t *ratesArray, uint16_t cfgCtl, 1515 uint16_t AntennaReduction, 1516 uint16_t twiceMaxRegulatoryPower, 1517 uint16_t powerLimit) 1518{ 1519#define N(a) (sizeof(a)/sizeof(a[0])) 1520/* Local defines to distinguish between extension and control CTL's */ 1521#define EXT_ADDITIVE (0x8000) 1522#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 1523#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 1524#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 1525 1526 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 1527 int i; 1528 int16_t twiceLargestAntenna; 1529 CAL_CTL_DATA *rep; 1530 CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}}; 1531 CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}}; 1532 CAL_TARGET_POWER_HT targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}}; 1533 int16_t scaledPower, minCtlPower; 1534 1535#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 1536#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 1537 static const uint16_t ctlModesFor11a[] = { 1538 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 1539 }; 1540 static const uint16_t ctlModesFor11g[] = { 1541 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 1542 }; 1543 const uint16_t *pCtlMode; 1544 uint16_t numCtlModes, ctlMode, freq; 1545 CHAN_CENTERS centers; 1546 1547 ar5416GetChannelCenters(ah, chan, ¢ers); 1548 1549 /* Compute TxPower reduction due to Antenna Gain */ 1550 1551 twiceLargestAntenna = AH_MAX(AH_MAX( 1552 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0], 1553 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]), 1554 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 1555#if 0 1556 /* Turn it back on if we need to calculate per chain antenna gain reduction */ 1557 /* Use only if the expected gain > 6dbi */ 1558 /* Chain 0 is always used */ 1559 twiceLargestAntenna = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0]; 1560 1561 /* Look at antenna gains of Chains 1 and 2 if the TX mask is set */ 1562 if (ahp->ah_tx_chainmask & 0x2) 1563 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 1564 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]); 1565 1566 if (ahp->ah_tx_chainmask & 0x4) 1567 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 1568 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 1569#endif 1570 twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0); 1571 1572 /* XXX setup for 5212 use (really used?) */ 1573 ath_hal_eepromSet(ah, 1574 IEEE80211_IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5, 1575 twiceLargestAntenna); 1576 1577 /* 1578 * scaledPower is the minimum of the user input power level and 1579 * the regulatory allowed power level 1580 */ 1581 scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna); 1582 1583 /* Reduce scaled Power by number of chains active to get to per chain tx power level */ 1584 /* TODO: better value than these? */ 1585 switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) { 1586 case 1: 1587 break; 1588 case 2: 1589 scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain; 1590 break; 1591 case 3: 1592 scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain; 1593 break; 1594 default: 1595 return AH_FALSE; /* Unsupported number of chains */ 1596 } 1597 1598 scaledPower = AH_MAX(0, scaledPower); 1599 1600 /* Get target powers from EEPROM - our baseline for TX Power */ 1601 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1602 /* Setup for CTL modes */ 1603 numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */ 1604 pCtlMode = ctlModesFor11g; 1605 1606 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 1607 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE); 1608 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 1609 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 1610 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT20, 1611 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 1612 1613 if (IEEE80211_IS_CHAN_HT40(chan)) { 1614 numCtlModes = N(ctlModesFor11g); /* All 2G CTL's */ 1615 1616 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT40, 1617 AR5416_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 1618 /* Get target powers for extension channels */ 1619 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 1620 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE); 1621 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 1622 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 1623 } 1624 } else { 1625 /* Setup for CTL modes */ 1626 numCtlModes = N(ctlModesFor11a) - SUB_NUM_CTL_MODES_AT_5G_40; /* CTL_11A, CTL_5GHT20 */ 1627 pCtlMode = ctlModesFor11a; 1628 1629 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 1630 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 1631 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT20, 1632 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 1633 1634 if (IEEE80211_IS_CHAN_HT40(chan)) { 1635 numCtlModes = N(ctlModesFor11a); /* All 5G CTL's */ 1636 1637 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT40, 1638 AR5416_NUM_5G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 1639 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 1640 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 1641 } 1642 } 1643 1644 /* 1645 * For MIMO, need to apply regulatory caps individually across dynamically 1646 * running modes: CCK, OFDM, HT20, HT40 1647 * 1648 * The outer loop walks through each possible applicable runtime mode. 1649 * The inner loop walks through each ctlIndex entry in EEPROM. 1650 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. 1651 * 1652 */ 1653 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 1654 HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 1655 (pCtlMode[ctlMode] == CTL_2GHT40); 1656 if (isHt40CtlMode) { 1657 freq = centers.ctl_center; 1658 } else if (pCtlMode[ctlMode] & EXT_ADDITIVE) { 1659 freq = centers.ext_center; 1660 } else { 1661 freq = centers.ctl_center; 1662 } 1663 1664 /* walk through each CTL index stored in EEPROM */ 1665 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 1666 uint16_t twiceMinEdgePower; 1667 1668 /* compare test group from regulatory channel list with test mode from pCtlMode list */ 1669 if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) || 1670 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == 1671 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { 1672 rep = &(pEepData->ctlData[i]); 1673 twiceMinEdgePower = ar5416GetMaxEdgePower(freq, 1674 rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1], 1675 IEEE80211_IS_CHAN_2GHZ(chan)); 1676 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 1677 /* Find the minimum of all CTL edge powers that apply to this channel */ 1678 twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower); 1679 } else { 1680 /* specific */ 1681 twiceMaxEdgePower = twiceMinEdgePower; 1682 break; 1683 } 1684 } 1685 } 1686 minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower); 1687 /* Apply ctl mode to correct target power set */ 1688 switch(pCtlMode[ctlMode]) { 1689 case CTL_11B: 1690 for (i = 0; i < N(targetPowerCck.tPow2x); i++) { 1691 targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower); 1692 } 1693 break; 1694 case CTL_11A: 1695 case CTL_11G: 1696 for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) { 1697 targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower); 1698 } 1699 break; 1700 case CTL_5GHT20: 1701 case CTL_2GHT20: 1702 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 1703 targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower); 1704 } 1705 break; 1706 case CTL_11B_EXT: 1707 targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower); 1708 break; 1709 case CTL_11A_EXT: 1710 case CTL_11G_EXT: 1711 targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower); 1712 break; 1713 case CTL_5GHT40: 1714 case CTL_2GHT40: 1715 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 1716 targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower); 1717 } 1718 break; 1719 default: 1720 return AH_FALSE; 1721 break; 1722 } 1723 } /* end ctl mode checking */ 1724 1725 /* Set rates Array from collected data */ 1726 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0]; 1727 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 1728 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 1729 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 1730 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 1731 1732 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 1733 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 1734 } 1735 1736 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1737 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 1738 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 1739 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 1740 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 1741 } 1742 if (IEEE80211_IS_CHAN_HT40(chan)) { 1743 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 1744 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i]; 1745 } 1746 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 1747 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 1748 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 1749 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1750 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 1751 } 1752 } 1753 return AH_TRUE; 1754#undef EXT_ADDITIVE 1755#undef CTL_11A_EXT 1756#undef CTL_11G_EXT 1757#undef CTL_11B_EXT 1758#undef SUB_NUM_CTL_MODES_AT_5G_40 1759#undef SUB_NUM_CTL_MODES_AT_2G_40 1760#undef N 1761} 1762 1763/************************************************************************** 1764 * fbin2freq 1765 * 1766 * Get channel value from binary representation held in eeprom 1767 * RETURNS: the frequency in MHz 1768 */ 1769static uint16_t 1770fbin2freq(uint8_t fbin, HAL_BOOL is2GHz) 1771{ 1772 /* 1773 * Reserved value 0xFF provides an empty definition both as 1774 * an fbin and as a frequency - do not convert 1775 */ 1776 if (fbin == AR5416_BCHAN_UNUSED) { 1777 return fbin; 1778 } 1779 1780 return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 1781} 1782 1783/* 1784 * ar5416GetMaxEdgePower 1785 * 1786 * Find the maximum conformance test limit for the given channel and CTL info 1787 */ 1788static uint16_t 1789ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz) 1790{ 1791 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 1792 int i; 1793 1794 /* Get the edge power */ 1795 for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) { 1796 /* 1797 * If there's an exact channel match or an inband flag set 1798 * on the lower channel use the given rdEdgePower 1799 */ 1800 if (freq == fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { 1801 twiceMaxEdgePower = MS(pRdEdgesPower[i].tPowerFlag, CAL_CTL_EDGES_POWER); 1802 break; 1803 } else if ((i > 0) && (freq < fbin2freq(pRdEdgesPower[i].bChannel, is2GHz))) { 1804 if (fbin2freq(pRdEdgesPower[i - 1].bChannel, is2GHz) < freq && (pRdEdgesPower[i - 1].tPowerFlag & CAL_CTL_EDGES_FLAG) != 0) { 1805 twiceMaxEdgePower = MS(pRdEdgesPower[i - 1].tPowerFlag, CAL_CTL_EDGES_POWER); 1806 } 1807 /* Leave loop - no more affecting edges possible in this monotonic increasing list */ 1808 break; 1809 } 1810 } 1811 HALASSERT(twiceMaxEdgePower > 0); 1812 return twiceMaxEdgePower; 1813} 1814 1815/************************************************************** 1816 * ar5416GetTargetPowers 1817 * 1818 * Return the rates of target power for the given target power table 1819 * channel, and number of channels 1820 */ 1821void 1822ar5416GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan, 1823 CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels, 1824 CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates, 1825 HAL_BOOL isHt40Target) 1826{ 1827 uint16_t clo, chi; 1828 int i; 1829 int matchIndex = -1, lowIndex = -1; 1830 uint16_t freq; 1831 CHAN_CENTERS centers; 1832 1833 ar5416GetChannelCenters(ah, chan, ¢ers); 1834 freq = isHt40Target ? centers.synth_center : centers.ctl_center; 1835 1836 /* Copy the target powers into the temp channel list */ 1837 if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1838 matchIndex = 0; 1839 } else { 1840 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 1841 if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1842 matchIndex = i; 1843 break; 1844 } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) && 1845 (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)))) 1846 { 1847 lowIndex = i - 1; 1848 break; 1849 } 1850 } 1851 if ((matchIndex == -1) && (lowIndex == -1)) { 1852 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))); 1853 matchIndex = i - 1; 1854 } 1855 } 1856 1857 if (matchIndex != -1) { 1858 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 1859 } else { 1860 HALASSERT(lowIndex != -1); 1861 /* 1862 * Get the lower and upper channels, target powers, 1863 * and interpolate between them. 1864 */ 1865 clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1866 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1867 1868 for (i = 0; i < numRates; i++) { 1869 pNewPower->tPow2x[i] = (uint8_t)ath_ee_interpolate(freq, clo, chi, 1870 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 1871 } 1872 } 1873} 1874/************************************************************** 1875 * ar5416GetTargetPowersLeg 1876 * 1877 * Return the four rates of target power for the given target power table 1878 * channel, and number of channels 1879 */ 1880void 1881ar5416GetTargetPowersLeg(struct ath_hal *ah, 1882 const struct ieee80211_channel *chan, 1883 CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels, 1884 CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates, 1885 HAL_BOOL isExtTarget) 1886{ 1887 uint16_t clo, chi; 1888 int i; 1889 int matchIndex = -1, lowIndex = -1; 1890 uint16_t freq; 1891 CHAN_CENTERS centers; 1892 1893 ar5416GetChannelCenters(ah, chan, ¢ers); 1894 freq = (isExtTarget) ? centers.ext_center :centers.ctl_center; 1895 1896 /* Copy the target powers into the temp channel list */ 1897 if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1898 matchIndex = 0; 1899 } else { 1900 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 1901 if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1902 matchIndex = i; 1903 break; 1904 } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) && 1905 (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)))) 1906 { 1907 lowIndex = i - 1; 1908 break; 1909 } 1910 } 1911 if ((matchIndex == -1) && (lowIndex == -1)) { 1912 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))); 1913 matchIndex = i - 1; 1914 } 1915 } 1916 1917 if (matchIndex != -1) { 1918 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 1919 } else { 1920 HALASSERT(lowIndex != -1); 1921 /* 1922 * Get the lower and upper channels, target powers, 1923 * and interpolate between them. 1924 */ 1925 clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1926 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1927 1928 for (i = 0; i < numRates; i++) { 1929 pNewPower->tPow2x[i] = (uint8_t)ath_ee_interpolate(freq, clo, chi, 1930 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 1931 } 1932 } 1933} 1934 1935/* 1936 * Set the gain boundaries for the given radio chain. 1937 * 1938 * The gain boundaries tell the hardware at what point in the 1939 * PDADC array to "switch over" from one PD gain setting 1940 * to another. There's also a gain overlap between two 1941 * PDADC array gain curves where there's valid PD values 1942 * for 2 gain settings. 1943 * 1944 * The hardware uses the gain overlap and gain boundaries 1945 * to determine which gain curve to use for the given 1946 * target TX power. 1947 */ 1948void 1949ar5416SetGainBoundariesClosedLoop(struct ath_hal *ah, int i, 1950 uint16_t pdGainOverlap_t2, uint16_t gainBoundaries[]) 1951{ 1952 int regChainOffset; 1953 1954 regChainOffset = ar5416GetRegChainOffset(ah, i); 1955 1956 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: chain %d: gainOverlap_t2: %d," 1957 " gainBoundaries: %d, %d, %d, %d\n", __func__, i, pdGainOverlap_t2, 1958 gainBoundaries[0], gainBoundaries[1], gainBoundaries[2], 1959 gainBoundaries[3]); 1960 OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 1961 SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 1962 SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | 1963 SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | 1964 SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | 1965 SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 1966} 1967 1968/* 1969 * Get the gain values and the number of gain levels given 1970 * in xpdMask. 1971 * 1972 * The EEPROM xpdMask determines which power detector gain 1973 * levels were used during calibration. Each of these mask 1974 * bits maps to a fixed gain level in hardware. 1975 */ 1976uint16_t 1977ar5416GetXpdGainValues(struct ath_hal *ah, uint16_t xpdMask, 1978 uint16_t xpdGainValues[]) 1979{ 1980 int i; 1981 uint16_t numXpdGain = 0; 1982 1983 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 1984 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 1985 if (numXpdGain >= AR5416_NUM_PD_GAINS) { 1986 HALASSERT(0); 1987 break; 1988 } 1989 xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i); 1990 numXpdGain++; 1991 } 1992 } 1993 return numXpdGain; 1994} 1995 1996/* 1997 * Write the detector gain and biases. 1998 * 1999 * There are four power detector gain levels. The xpdMask in the EEPROM 2000 * determines which power detector gain levels have TX power calibration 2001 * data associated with them. This function writes the number of 2002 * PD gain levels and their values into the hardware. 2003 * 2004 * This is valid for all TX chains - the calibration data itself however 2005 * will likely differ per-chain. 2006 */ 2007void 2008ar5416WriteDetectorGainBiases(struct ath_hal *ah, uint16_t numXpdGain, 2009 uint16_t xpdGainValues[]) 2010{ 2011 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: numXpdGain: %d," 2012 " xpdGainValues: %d, %d, %d\n", __func__, numXpdGain, 2013 xpdGainValues[0], xpdGainValues[1], xpdGainValues[2]); 2014 2015 OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 2016 ~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | 2017 AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 2018 SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | 2019 SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) | 2020 SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | 2021 SM(xpdGainValues[2], AR_PHY_TPCRG1_PD_GAIN_3)); 2022} 2023 2024/* 2025 * Write the PDADC array to the given radio chain i. 2026 * 2027 * The 32 PDADC registers are written without any care about 2028 * their contents - so if various chips treat values as "special", 2029 * this routine will not care. 2030 */ 2031void 2032ar5416WritePdadcValues(struct ath_hal *ah, int i, uint8_t pdadcValues[]) 2033{ 2034 int regOffset, regChainOffset; 2035 int j; 2036 int reg32; 2037 2038 regChainOffset = ar5416GetRegChainOffset(ah, i); 2039 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 2040 2041 for (j = 0; j < 32; j++) { 2042 reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0) | 2043 ((pdadcValues[4*j + 1] & 0xFF) << 8) | 2044 ((pdadcValues[4*j + 2] & 0xFF) << 16) | 2045 ((pdadcValues[4*j + 3] & 0xFF) << 24) ; 2046 OS_REG_WRITE(ah, regOffset, reg32); 2047 HALDEBUG(ah, HAL_DEBUG_EEPROM, "PDADC: Chain %d |" 2048 " PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d" 2049 " Value %3d | PDADC %3d Value %3d |\n", 2050 i, 2051 4*j, pdadcValues[4*j], 2052 4*j+1, pdadcValues[4*j + 1], 2053 4*j+2, pdadcValues[4*j + 2], 2054 4*j+3, pdadcValues[4*j + 3]); 2055 regOffset += 4; 2056 } 2057} 2058 2059/************************************************************** 2060 * ar5416SetPowerCalTable 2061 * 2062 * Pull the PDADC piers from cal data and interpolate them across the given 2063 * points as well as from the nearest pier(s) to get a power detector 2064 * linear voltage to power level table. 2065 */ 2066HAL_BOOL 2067ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 2068 const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset) 2069{ 2070 CAL_DATA_PER_FREQ *pRawDataset; 2071 uint8_t *pCalBChans = AH_NULL; 2072 uint16_t pdGainOverlap_t2; 2073 static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES]; 2074 uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 2075 uint16_t numPiers, i; 2076 int16_t tMinCalPower; 2077 uint16_t numXpdGain, xpdMask; 2078 uint16_t xpdGainValues[AR5416_NUM_PD_GAINS]; 2079 uint32_t regChainOffset; 2080 2081 OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues)); 2082 2083 xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain; 2084 2085 if (IS_EEP_MINOR_V2(ah)) { 2086 pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap; 2087 } else { 2088 pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 2089 } 2090 2091 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2092 pCalBChans = pEepData->calFreqPier2G; 2093 numPiers = AR5416_NUM_2G_CAL_PIERS; 2094 } else { 2095 pCalBChans = pEepData->calFreqPier5G; 2096 numPiers = AR5416_NUM_5G_CAL_PIERS; 2097 } 2098 2099 /* Calculate the value of xpdgains from the xpdGain Mask */ 2100 numXpdGain = ar5416GetXpdGainValues(ah, xpdMask, xpdGainValues); 2101 2102 /* Write the detector gain biases and their number */ 2103 ar5416WriteDetectorGainBiases(ah, numXpdGain, xpdGainValues); 2104 2105 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 2106 regChainOffset = ar5416GetRegChainOffset(ah, i); 2107 2108 if (pEepData->baseEepHeader.txMask & (1 << i)) { 2109 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2110 pRawDataset = pEepData->calPierData2G[i]; 2111 } else { 2112 pRawDataset = pEepData->calPierData5G[i]; 2113 } 2114 2115 /* Fetch the gain boundaries and the PDADC values */ 2116 ar5416GetGainBoundariesAndPdadcs(ah, chan, pRawDataset, 2117 pCalBChans, numPiers, 2118 pdGainOverlap_t2, 2119 &tMinCalPower, gainBoundaries, 2120 pdadcValues, numXpdGain); 2121 2122 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { 2123 ar5416SetGainBoundariesClosedLoop(ah, i, pdGainOverlap_t2, 2124 gainBoundaries); 2125 } 2126 2127 /* Write the power values into the baseband power table */ 2128 ar5416WritePdadcValues(ah, i, pdadcValues); 2129 } 2130 } 2131 *pTxPowerIndexOffset = 0; 2132 2133 return AH_TRUE; 2134} 2135 2136/************************************************************** 2137 * ar5416GetGainBoundariesAndPdadcs 2138 * 2139 * Uses the data points read from EEPROM to reconstruct the pdadc power table 2140 * Called by ar5416SetPowerCalTable only. 2141 */ 2142void 2143ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 2144 const struct ieee80211_channel *chan, 2145 CAL_DATA_PER_FREQ *pRawDataSet, 2146 uint8_t * bChans, uint16_t availPiers, 2147 uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries, 2148 uint8_t * pPDADCValues, uint16_t numXpdGains) 2149{ 2150 2151 int i, j, k; 2152 int16_t ss; /* potentially -ve index for taking care of pdGainOverlap */ 2153 uint16_t idxL, idxR, numPiers; /* Pier indexes */ 2154 2155 /* filled out Vpd table for all pdGains (chanL) */ 2156 static uint8_t vpdTableL[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2157 2158 /* filled out Vpd table for all pdGains (chanR) */ 2159 static uint8_t vpdTableR[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2160 2161 /* filled out Vpd table for all pdGains (interpolated) */ 2162 static uint8_t vpdTableI[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2163 2164 uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR; 2165 uint8_t minPwrT4[AR5416_NUM_PD_GAINS]; 2166 uint8_t maxPwrT4[AR5416_NUM_PD_GAINS]; 2167 int16_t vpdStep; 2168 int16_t tmpVal; 2169 uint16_t sizeCurrVpdTable, maxIndex, tgtIndex; 2170 HAL_BOOL match; 2171 int16_t minDelta = 0; 2172 CHAN_CENTERS centers; 2173 2174 ar5416GetChannelCenters(ah, chan, ¢ers); 2175 2176 /* Trim numPiers for the number of populated channel Piers */ 2177 for (numPiers = 0; numPiers < availPiers; numPiers++) { 2178 if (bChans[numPiers] == AR5416_BCHAN_UNUSED) { 2179 break; 2180 } 2181 } 2182 2183 /* Find pier indexes around the current channel */ 2184 match = ath_ee_getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, 2185 IEEE80211_IS_CHAN_2GHZ(chan)), bChans, numPiers, &idxL, &idxR); 2186 2187 if (match) { 2188 /* Directly fill both vpd tables from the matching index */ 2189 for (i = 0; i < numXpdGains; i++) { 2190 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 2191 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 2192 ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i], 2193 pRawDataSet[idxL].vpdPdg[i], AR5416_PD_GAIN_ICEPTS, vpdTableI[i]); 2194 } 2195 } else { 2196 for (i = 0; i < numXpdGains; i++) { 2197 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 2198 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 2199 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 2200 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 2201 2202 /* Start Vpd interpolation from the max of the minimum powers */ 2203 minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]); 2204 2205 /* End Vpd interpolation from the min of the max powers */ 2206 maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); 2207 HALASSERT(maxPwrT4[i] > minPwrT4[i]); 2208 2209 /* Fill pier Vpds */ 2210 ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]); 2211 ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]); 2212 2213 /* Interpolate the final vpd */ 2214 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 2215 vpdTableI[i][j] = (uint8_t)(ath_ee_interpolate((uint16_t)FREQ2FBIN(centers.synth_center, 2216 IEEE80211_IS_CHAN_2GHZ(chan)), 2217 bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j])); 2218 } 2219 } 2220 } 2221 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 2222 2223 k = 0; /* index for the final table */ 2224 for (i = 0; i < numXpdGains; i++) { 2225 if (i == (numXpdGains - 1)) { 2226 pPdGainBoundaries[i] = (uint16_t)(maxPwrT4[i] / 2); 2227 } else { 2228 pPdGainBoundaries[i] = (uint16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4); 2229 } 2230 2231 pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); 2232 2233 /* NB: only applies to owl 1.0 */ 2234 if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { 2235 /* 2236 * fix the gain delta, but get a delta that can be applied to min to 2237 * keep the upper power values accurate, don't think max needs to 2238 * be adjusted because should not be at that area of the table? 2239 */ 2240 minDelta = pPdGainBoundaries[0] - 23; 2241 pPdGainBoundaries[0] = 23; 2242 } 2243 else { 2244 minDelta = 0; 2245 } 2246 2247 /* Find starting index for this pdGain */ 2248 if (i == 0) { 2249 if (AR_SREV_MERLIN_20_OR_LATER(ah)) 2250 ss = (int16_t)(0 - (minPwrT4[i] / 2)); 2251 else 2252 ss = 0; /* for the first pdGain, start from index 0 */ 2253 } else { 2254 /* need overlap entries extrapolated below. */ 2255 ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta); 2256 } 2257 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 2258 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2259 /* 2260 *-ve ss indicates need to extrapolate data below for this pdGain 2261 */ 2262 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2263 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 2264 pPDADCValues[k++] = (uint8_t)((tmpVal < 0) ? 0 : tmpVal); 2265 ss++; 2266 } 2267 2268 sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1); 2269 tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2)); 2270 maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable; 2271 2272 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2273 pPDADCValues[k++] = vpdTableI[i][ss++]; 2274 } 2275 2276 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]); 2277 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2278 /* 2279 * for last gain, pdGainBoundary == Pmax_t2, so will 2280 * have to extrapolate 2281 */ 2282 if (tgtIndex >= maxIndex) { /* need to extrapolate above */ 2283 while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2284 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + 2285 (ss - maxIndex +1) * vpdStep)); 2286 pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ? 255 : tmpVal); 2287 ss++; 2288 } 2289 } /* extrapolated above */ 2290 } /* for all pdGainUsed */ 2291 2292 /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */ 2293 while (i < AR5416_PD_GAINS_IN_MASK) { 2294 pPdGainBoundaries[i] = pPdGainBoundaries[i-1]; 2295 i++; 2296 } 2297 2298 while (k < AR5416_NUM_PDADC_VALUES) { 2299 pPDADCValues[k] = pPDADCValues[k-1]; 2300 k++; 2301 } 2302 return; 2303} 2304 2305/* 2306 * The linux ath9k driver and (from what I've been told) the reference 2307 * Atheros driver enables the 11n PHY by default whether or not it's 2308 * configured. 2309 */ 2310static void 2311ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan) 2312{ 2313 uint32_t phymode; 2314 uint32_t enableDacFifo = 0; 2315 HAL_HT_MACMODE macmode; /* MAC - 20/40 mode */ 2316 2317 if (AR_SREV_KITE_10_OR_LATER(ah)) 2318 enableDacFifo = (OS_REG_READ(ah, AR_PHY_TURBO) & AR_PHY_FC_ENABLE_DAC_FIFO); 2319 2320 /* Enable 11n HT, 20 MHz */ 2321 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 2322 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; 2323 2324 /* Configure baseband for dynamic 20/40 operation */ 2325 if (IEEE80211_IS_CHAN_HT40(chan)) { 2326 phymode |= AR_PHY_FC_DYN2040_EN; 2327 2328 /* Configure control (primary) channel at +-10MHz */ 2329 if (IEEE80211_IS_CHAN_HT40U(chan)) 2330 phymode |= AR_PHY_FC_DYN2040_PRI_CH; 2331#if 0 2332 /* Configure 20/25 spacing */ 2333 if (ht->ht_extprotspacing == HAL_HT_EXTPROTSPACING_25) 2334 phymode |= AR_PHY_FC_DYN2040_EXT_CH; 2335#endif 2336 macmode = HAL_HT_MACMODE_2040; 2337 } else 2338 macmode = HAL_HT_MACMODE_20; 2339 OS_REG_WRITE(ah, AR_PHY_TURBO, phymode); 2340 2341 /* Configure MAC for 20/40 operation */ 2342 ar5416Set11nMac2040(ah, macmode); 2343 2344 /* global transmit timeout (25 TUs default)*/ 2345 /* XXX - put this elsewhere??? */ 2346 OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S) ; 2347 2348 /* carrier sense timeout */ 2349 OS_REG_SET_BIT(ah, AR_GTTM, AR_GTTM_CST_USEC); 2350 OS_REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); 2351} 2352 2353void 2354ar5416GetChannelCenters(struct ath_hal *ah, 2355 const struct ieee80211_channel *chan, CHAN_CENTERS *centers) 2356{ 2357 uint16_t freq = ath_hal_gethwchannel(ah, chan); 2358 2359 centers->ctl_center = freq; 2360 centers->synth_center = freq; 2361 /* 2362 * In 20/40 phy mode, the center frequency is 2363 * "between" the control and extension channels. 2364 */ 2365 if (IEEE80211_IS_CHAN_HT40U(chan)) { 2366 centers->synth_center += HT40_CHANNEL_CENTER_SHIFT; 2367 centers->ext_center = 2368 centers->synth_center + HT40_CHANNEL_CENTER_SHIFT; 2369 } else if (IEEE80211_IS_CHAN_HT40D(chan)) { 2370 centers->synth_center -= HT40_CHANNEL_CENTER_SHIFT; 2371 centers->ext_center = 2372 centers->synth_center - HT40_CHANNEL_CENTER_SHIFT; 2373 } else { 2374 centers->ext_center = freq; 2375 } 2376} 2377 2378/* 2379 * Override the INI vals being programmed. 2380 */ 2381static void 2382ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan) 2383{ 2384 uint32_t val; 2385 2386 /* 2387 * Set the RX_ABORT and RX_DIS and clear if off only after 2388 * RXE is set for MAC. This prevents frames with corrupted 2389 * descriptor status. 2390 */ 2391 OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 2392 2393 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 2394 val = OS_REG_READ(ah, AR_PCU_MISC_MODE2); 2395 2396 if (!AR_SREV_9271(ah)) 2397 val &= ~AR_PCU_MISC_MODE2_HWWAR1; 2398 2399 if (AR_SREV_9287_11_OR_LATER(ah)) 2400 val = val & (~AR_PCU_MISC_MODE2_HWWAR2); 2401 2402 OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val); 2403 } 2404 2405 /* 2406 * The AR5416 initvals have this already set to 0x11; AR9160 has 2407 * the register set to 0x0. Figure out whether AR9100/AR9160 needs 2408 * this before moving forward with it. 2409 */ 2410#if 0 2411 /* Disable BB clock gating for AR5416v2, AR9100, AR9160 */ 2412 if (AR_SREV_OWL_20_OR_LATER(ah) || AR_SREV_9100(ah) || AR_SREV_SOWL(ah)) { 2413 /* 2414 * Disable BB clock gating 2415 * Necessary to avoid issues on AR5416 2.0 2416 */ 2417 OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); 2418 } 2419#endif 2420 2421 /* 2422 * Disable RIFS search on some chips to avoid baseband 2423 * hang issues. 2424 */ 2425 if (AR_SREV_9100(ah) || AR_SREV_SOWL(ah)) { 2426 val = OS_REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); 2427 val &= ~AR_PHY_RIFS_INIT_DELAY; 2428 OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); 2429 } 2430} 2431 2432struct ini { 2433 uint32_t *data; /* NB: !const */ 2434 int rows, cols; 2435}; 2436 2437/* 2438 * Override XPA bias level based on operating frequency. 2439 * This is a v14 EEPROM specific thing for the AR9160. 2440 */ 2441void 2442ar5416EepromSetAddac(struct ath_hal *ah, const struct ieee80211_channel *chan) 2443{ 2444#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) 2445 MODAL_EEP_HEADER *pModal; 2446 HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 2447 struct ar5416eeprom *eep = &ee->ee_base; 2448 uint8_t biaslevel; 2449 2450 if (! AR_SREV_SOWL(ah)) 2451 return; 2452 2453 if (EEP_MINOR(ah) < AR5416_EEP_MINOR_VER_7) 2454 return; 2455 2456 pModal = &(eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]); 2457 2458 if (pModal->xpaBiasLvl != 0xff) 2459 biaslevel = pModal->xpaBiasLvl; 2460 else { 2461 uint16_t resetFreqBin, freqBin, freqCount = 0; 2462 CHAN_CENTERS centers; 2463 2464 ar5416GetChannelCenters(ah, chan, ¢ers); 2465 2466 resetFreqBin = FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)); 2467 freqBin = XPA_LVL_FREQ(0) & 0xff; 2468 biaslevel = (uint8_t) (XPA_LVL_FREQ(0) >> 14); 2469 2470 freqCount++; 2471 2472 while (freqCount < 3) { 2473 if (XPA_LVL_FREQ(freqCount) == 0x0) 2474 break; 2475 2476 freqBin = XPA_LVL_FREQ(freqCount) & 0xff; 2477 if (resetFreqBin >= freqBin) 2478 biaslevel = (uint8_t)(XPA_LVL_FREQ(freqCount) >> 14); 2479 else 2480 break; 2481 freqCount++; 2482 } 2483 } 2484 2485 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: overriding XPA bias level = %d\n", 2486 __func__, biaslevel); 2487 2488 /* 2489 * This is a dirty workaround for the const initval data, 2490 * which will upset multiple AR9160's on the same board. 2491 * 2492 * The HAL should likely just have a private copy of the addac 2493 * data per instance. 2494 */ 2495 if (IEEE80211_IS_CHAN_2GHZ(chan)) 2496 HAL_INI_VAL((struct ini *) &AH5416(ah)->ah_ini_addac, 7, 1) = 2497 (HAL_INI_VAL(&AH5416(ah)->ah_ini_addac, 7, 1) & (~0x18)) | biaslevel << 3; 2498 else 2499 HAL_INI_VAL((struct ini *) &AH5416(ah)->ah_ini_addac, 6, 1) = 2500 (HAL_INI_VAL(&AH5416(ah)->ah_ini_addac, 6, 1) & (~0xc0)) | biaslevel << 6; 2501#undef XPA_LVL_FREQ 2502} 2503 2504