Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30 2813 lines 81 kB view raw
1/* 2 * Copyright (c) 2008-2009 Atheros Communications Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include "ath9k.h" 18 19static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, 20 u32 reg, u32 mask, 21 u32 shift, u32 val) 22{ 23 u32 regVal; 24 25 regVal = REG_READ(ah, reg) & ~mask; 26 regVal |= (val << shift) & mask; 27 28 REG_WRITE(ah, reg, regVal); 29 30 if (ah->config.analog_shiftreg) 31 udelay(100); 32 33 return; 34} 35 36static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) 37{ 38 39 if (fbin == AR5416_BCHAN_UNUSED) 40 return fbin; 41 42 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 43} 44 45static inline int16_t ath9k_hw_interpolate(u16 target, 46 u16 srcLeft, u16 srcRight, 47 int16_t targetLeft, 48 int16_t targetRight) 49{ 50 int16_t rv; 51 52 if (srcRight == srcLeft) { 53 rv = targetLeft; 54 } else { 55 rv = (int16_t) (((target - srcLeft) * targetRight + 56 (srcRight - target) * targetLeft) / 57 (srcRight - srcLeft)); 58 } 59 return rv; 60} 61 62static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, 63 u16 listSize, u16 *indexL, 64 u16 *indexR) 65{ 66 u16 i; 67 68 if (target <= pList[0]) { 69 *indexL = *indexR = 0; 70 return true; 71 } 72 if (target >= pList[listSize - 1]) { 73 *indexL = *indexR = (u16) (listSize - 1); 74 return true; 75 } 76 77 for (i = 0; i < listSize - 1; i++) { 78 if (pList[i] == target) { 79 *indexL = *indexR = i; 80 return true; 81 } 82 if (target < pList[i + 1]) { 83 *indexL = i; 84 *indexR = (u16) (i + 1); 85 return false; 86 } 87 } 88 return false; 89} 90 91static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) 92{ 93 struct ath_softc *sc = ah->ah_sc; 94 95 return sc->bus_ops->eeprom_read(ah, off, data); 96} 97 98static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, 99 u8 *pVpdList, u16 numIntercepts, 100 u8 *pRetVpdList) 101{ 102 u16 i, k; 103 u8 currPwr = pwrMin; 104 u16 idxL = 0, idxR = 0; 105 106 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 107 ath9k_hw_get_lower_upper_index(currPwr, pPwrList, 108 numIntercepts, &(idxL), 109 &(idxR)); 110 if (idxR < 1) 111 idxR = 1; 112 if (idxL == numIntercepts - 1) 113 idxL = (u16) (numIntercepts - 2); 114 if (pPwrList[idxL] == pPwrList[idxR]) 115 k = pVpdList[idxL]; 116 else 117 k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] + 118 (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 119 (pPwrList[idxR] - pPwrList[idxL])); 120 pRetVpdList[i] = (u8) k; 121 currPwr += 2; 122 } 123 124 return true; 125} 126 127static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah, 128 struct ath9k_channel *chan, 129 struct cal_target_power_leg *powInfo, 130 u16 numChannels, 131 struct cal_target_power_leg *pNewPower, 132 u16 numRates, bool isExtTarget) 133{ 134 struct chan_centers centers; 135 u16 clo, chi; 136 int i; 137 int matchIndex = -1, lowIndex = -1; 138 u16 freq; 139 140 ath9k_hw_get_channel_centers(ah, chan, &centers); 141 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center; 142 143 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, 144 IS_CHAN_2GHZ(chan))) { 145 matchIndex = 0; 146 } else { 147 for (i = 0; (i < numChannels) && 148 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 149 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel, 150 IS_CHAN_2GHZ(chan))) { 151 matchIndex = i; 152 break; 153 } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel, 154 IS_CHAN_2GHZ(chan))) && 155 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel, 156 IS_CHAN_2GHZ(chan)))) { 157 lowIndex = i - 1; 158 break; 159 } 160 } 161 if ((matchIndex == -1) && (lowIndex == -1)) 162 matchIndex = i - 1; 163 } 164 165 if (matchIndex != -1) { 166 *pNewPower = powInfo[matchIndex]; 167 } else { 168 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel, 169 IS_CHAN_2GHZ(chan)); 170 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel, 171 IS_CHAN_2GHZ(chan)); 172 173 for (i = 0; i < numRates; i++) { 174 pNewPower->tPow2x[i] = 175 (u8)ath9k_hw_interpolate(freq, clo, chi, 176 powInfo[lowIndex].tPow2x[i], 177 powInfo[lowIndex + 1].tPow2x[i]); 178 } 179 } 180} 181 182static void ath9k_get_txgain_index(struct ath_hw *ah, 183 struct ath9k_channel *chan, 184 struct calDataPerFreqOpLoop *rawDatasetOpLoop, 185 u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx) 186{ 187 u8 pcdac, i = 0; 188 u16 idxL = 0, idxR = 0, numPiers; 189 bool match; 190 struct chan_centers centers; 191 192 ath9k_hw_get_channel_centers(ah, chan, &centers); 193 194 for (numPiers = 0; numPiers < availPiers; numPiers++) 195 if (calChans[numPiers] == AR5416_BCHAN_UNUSED) 196 break; 197 198 match = ath9k_hw_get_lower_upper_index( 199 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), 200 calChans, numPiers, &idxL, &idxR); 201 if (match) { 202 pcdac = rawDatasetOpLoop[idxL].pcdac[0][0]; 203 *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0]; 204 } else { 205 pcdac = rawDatasetOpLoop[idxR].pcdac[0][0]; 206 *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] + 207 rawDatasetOpLoop[idxR].pwrPdg[0][0])/2; 208 } 209 210 while (pcdac > ah->originalGain[i] && 211 i < (AR9280_TX_GAIN_TABLE_SIZE - 1)) 212 i++; 213 214 *pcdacIdx = i; 215 return; 216} 217 218static void ath9k_olc_get_pdadcs(struct ath_hw *ah, 219 u32 initTxGain, 220 int txPower, 221 u8 *pPDADCValues) 222{ 223 u32 i; 224 u32 offset; 225 226 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0, 227 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); 228 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1, 229 AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); 230 231 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7, 232 AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain); 233 234 offset = txPower; 235 for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++) 236 if (i < offset) 237 pPDADCValues[i] = 0x0; 238 else 239 pPDADCValues[i] = 0xFF; 240} 241 242 243 244 245static void ath9k_hw_get_target_powers(struct ath_hw *ah, 246 struct ath9k_channel *chan, 247 struct cal_target_power_ht *powInfo, 248 u16 numChannels, 249 struct cal_target_power_ht *pNewPower, 250 u16 numRates, bool isHt40Target) 251{ 252 struct chan_centers centers; 253 u16 clo, chi; 254 int i; 255 int matchIndex = -1, lowIndex = -1; 256 u16 freq; 257 258 ath9k_hw_get_channel_centers(ah, chan, &centers); 259 freq = isHt40Target ? centers.synth_center : centers.ctl_center; 260 261 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) { 262 matchIndex = 0; 263 } else { 264 for (i = 0; (i < numChannels) && 265 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 266 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel, 267 IS_CHAN_2GHZ(chan))) { 268 matchIndex = i; 269 break; 270 } else 271 if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel, 272 IS_CHAN_2GHZ(chan))) && 273 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel, 274 IS_CHAN_2GHZ(chan)))) { 275 lowIndex = i - 1; 276 break; 277 } 278 } 279 if ((matchIndex == -1) && (lowIndex == -1)) 280 matchIndex = i - 1; 281 } 282 283 if (matchIndex != -1) { 284 *pNewPower = powInfo[matchIndex]; 285 } else { 286 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel, 287 IS_CHAN_2GHZ(chan)); 288 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel, 289 IS_CHAN_2GHZ(chan)); 290 291 for (i = 0; i < numRates; i++) { 292 pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq, 293 clo, chi, 294 powInfo[lowIndex].tPow2x[i], 295 powInfo[lowIndex + 1].tPow2x[i]); 296 } 297 } 298} 299 300static u16 ath9k_hw_get_max_edge_power(u16 freq, 301 struct cal_ctl_edges *pRdEdgesPower, 302 bool is2GHz, int num_band_edges) 303{ 304 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 305 int i; 306 307 for (i = 0; (i < num_band_edges) && 308 (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 309 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { 310 twiceMaxEdgePower = pRdEdgesPower[i].tPower; 311 break; 312 } else if ((i > 0) && 313 (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, 314 is2GHz))) { 315 if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, 316 is2GHz) < freq && 317 pRdEdgesPower[i - 1].flag) { 318 twiceMaxEdgePower = 319 pRdEdgesPower[i - 1].tPower; 320 } 321 break; 322 } 323 } 324 325 return twiceMaxEdgePower; 326} 327 328/****************************************/ 329/* EEPROM Operations for 4K sized cards */ 330/****************************************/ 331 332static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) 333{ 334 return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF); 335} 336 337static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) 338{ 339 return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF); 340} 341 342static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) 343{ 344#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 345 u16 *eep_data = (u16 *)&ah->eeprom.map4k; 346 int addr, eep_start_loc = 0; 347 348 eep_start_loc = 64; 349 350 if (!ath9k_hw_use_flash(ah)) { 351 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 352 "Reading from EEPROM, not flash\n"); 353 } 354 355 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { 356 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) { 357 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 358 "Unable to read eeprom region \n"); 359 return false; 360 } 361 eep_data++; 362 } 363 364 return true; 365#undef SIZE_EEPROM_4K 366} 367 368static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) 369{ 370#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 371 struct ar5416_eeprom_4k *eep = 372 (struct ar5416_eeprom_4k *) &ah->eeprom.map4k; 373 u16 *eepdata, temp, magic, magic2; 374 u32 sum = 0, el; 375 bool need_swap = false; 376 int i, addr; 377 378 379 if (!ath9k_hw_use_flash(ah)) { 380 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, 381 &magic)) { 382 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 383 "Reading Magic # failed\n"); 384 return false; 385 } 386 387 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 388 "Read Magic = 0x%04X\n", magic); 389 390 if (magic != AR5416_EEPROM_MAGIC) { 391 magic2 = swab16(magic); 392 393 if (magic2 == AR5416_EEPROM_MAGIC) { 394 need_swap = true; 395 eepdata = (u16 *) (&ah->eeprom); 396 397 for (addr = 0; addr < EEPROM_4K_SIZE; addr++) { 398 temp = swab16(*eepdata); 399 *eepdata = temp; 400 eepdata++; 401 } 402 } else { 403 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 404 "Invalid EEPROM Magic. " 405 "endianness mismatch.\n"); 406 return -EINVAL; 407 } 408 } 409 } 410 411 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", 412 need_swap ? "True" : "False"); 413 414 if (need_swap) 415 el = swab16(ah->eeprom.map4k.baseEepHeader.length); 416 else 417 el = ah->eeprom.map4k.baseEepHeader.length; 418 419 if (el > sizeof(struct ar5416_eeprom_4k)) 420 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16); 421 else 422 el = el / sizeof(u16); 423 424 eepdata = (u16 *)(&ah->eeprom); 425 426 for (i = 0; i < el; i++) 427 sum ^= *eepdata++; 428 429 if (need_swap) { 430 u32 integer; 431 u16 word; 432 433 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 434 "EEPROM Endianness is not native.. Changing\n"); 435 436 word = swab16(eep->baseEepHeader.length); 437 eep->baseEepHeader.length = word; 438 439 word = swab16(eep->baseEepHeader.checksum); 440 eep->baseEepHeader.checksum = word; 441 442 word = swab16(eep->baseEepHeader.version); 443 eep->baseEepHeader.version = word; 444 445 word = swab16(eep->baseEepHeader.regDmn[0]); 446 eep->baseEepHeader.regDmn[0] = word; 447 448 word = swab16(eep->baseEepHeader.regDmn[1]); 449 eep->baseEepHeader.regDmn[1] = word; 450 451 word = swab16(eep->baseEepHeader.rfSilent); 452 eep->baseEepHeader.rfSilent = word; 453 454 word = swab16(eep->baseEepHeader.blueToothOptions); 455 eep->baseEepHeader.blueToothOptions = word; 456 457 word = swab16(eep->baseEepHeader.deviceCap); 458 eep->baseEepHeader.deviceCap = word; 459 460 integer = swab32(eep->modalHeader.antCtrlCommon); 461 eep->modalHeader.antCtrlCommon = integer; 462 463 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 464 integer = swab32(eep->modalHeader.antCtrlChain[i]); 465 eep->modalHeader.antCtrlChain[i] = integer; 466 } 467 468 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 469 word = swab16(eep->modalHeader.spurChans[i].spurChan); 470 eep->modalHeader.spurChans[i].spurChan = word; 471 } 472 } 473 474 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || 475 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 476 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 477 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 478 sum, ah->eep_ops->get_eeprom_ver(ah)); 479 return -EINVAL; 480 } 481 482 return 0; 483#undef EEPROM_4K_SIZE 484} 485 486static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, 487 enum eeprom_param param) 488{ 489 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 490 struct modal_eep_4k_header *pModal = &eep->modalHeader; 491 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 492 493 switch (param) { 494 case EEP_NFTHRESH_2: 495 return pModal->noiseFloorThreshCh[0]; 496 case AR_EEPROM_MAC(0): 497 return pBase->macAddr[0] << 8 | pBase->macAddr[1]; 498 case AR_EEPROM_MAC(1): 499 return pBase->macAddr[2] << 8 | pBase->macAddr[3]; 500 case AR_EEPROM_MAC(2): 501 return pBase->macAddr[4] << 8 | pBase->macAddr[5]; 502 case EEP_REG_0: 503 return pBase->regDmn[0]; 504 case EEP_REG_1: 505 return pBase->regDmn[1]; 506 case EEP_OP_CAP: 507 return pBase->deviceCap; 508 case EEP_OP_MODE: 509 return pBase->opCapFlags; 510 case EEP_RF_SILENT: 511 return pBase->rfSilent; 512 case EEP_OB_2: 513 return pModal->ob_01; 514 case EEP_DB_2: 515 return pModal->db1_01; 516 case EEP_MINOR_REV: 517 return pBase->version & AR5416_EEP_VER_MINOR_MASK; 518 case EEP_TX_MASK: 519 return pBase->txMask; 520 case EEP_RX_MASK: 521 return pBase->rxMask; 522 case EEP_FRAC_N_5G: 523 return 0; 524 default: 525 return 0; 526 } 527} 528 529static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, 530 struct ath9k_channel *chan, 531 struct cal_data_per_freq_4k *pRawDataSet, 532 u8 *bChans, u16 availPiers, 533 u16 tPdGainOverlap, int16_t *pMinCalPower, 534 u16 *pPdGainBoundaries, u8 *pPDADCValues, 535 u16 numXpdGains) 536{ 537#define TMP_VAL_VPD_TABLE \ 538 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); 539 int i, j, k; 540 int16_t ss; 541 u16 idxL = 0, idxR = 0, numPiers; 542 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] 543 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 544 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS] 545 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 546 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] 547 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 548 549 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; 550 u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS]; 551 u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS]; 552 int16_t vpdStep; 553 int16_t tmpVal; 554 u16 sizeCurrVpdTable, maxIndex, tgtIndex; 555 bool match; 556 int16_t minDelta = 0; 557 struct chan_centers centers; 558#define PD_GAIN_BOUNDARY_DEFAULT 58; 559 560 ath9k_hw_get_channel_centers(ah, chan, &centers); 561 562 for (numPiers = 0; numPiers < availPiers; numPiers++) { 563 if (bChans[numPiers] == AR5416_BCHAN_UNUSED) 564 break; 565 } 566 567 match = ath9k_hw_get_lower_upper_index( 568 (u8)FREQ2FBIN(centers.synth_center, 569 IS_CHAN_2GHZ(chan)), bChans, numPiers, 570 &idxL, &idxR); 571 572 if (match) { 573 for (i = 0; i < numXpdGains; i++) { 574 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 575 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 576 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 577 pRawDataSet[idxL].pwrPdg[i], 578 pRawDataSet[idxL].vpdPdg[i], 579 AR5416_EEP4K_PD_GAIN_ICEPTS, 580 vpdTableI[i]); 581 } 582 } else { 583 for (i = 0; i < numXpdGains; i++) { 584 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 585 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 586 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 587 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 588 589 minPwrT4[i] = max(pPwrL[0], pPwrR[0]); 590 591 maxPwrT4[i] = 592 min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1], 593 pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]); 594 595 596 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 597 pPwrL, pVpdL, 598 AR5416_EEP4K_PD_GAIN_ICEPTS, 599 vpdTableL[i]); 600 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 601 pPwrR, pVpdR, 602 AR5416_EEP4K_PD_GAIN_ICEPTS, 603 vpdTableR[i]); 604 605 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 606 vpdTableI[i][j] = 607 (u8)(ath9k_hw_interpolate((u16) 608 FREQ2FBIN(centers. 609 synth_center, 610 IS_CHAN_2GHZ 611 (chan)), 612 bChans[idxL], bChans[idxR], 613 vpdTableL[i][j], vpdTableR[i][j])); 614 } 615 } 616 } 617 618 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 619 620 k = 0; 621 622 for (i = 0; i < numXpdGains; i++) { 623 if (i == (numXpdGains - 1)) 624 pPdGainBoundaries[i] = 625 (u16)(maxPwrT4[i] / 2); 626 else 627 pPdGainBoundaries[i] = 628 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); 629 630 pPdGainBoundaries[i] = 631 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); 632 633 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { 634 minDelta = pPdGainBoundaries[0] - 23; 635 pPdGainBoundaries[0] = 23; 636 } else { 637 minDelta = 0; 638 } 639 640 if (i == 0) { 641 if (AR_SREV_9280_10_OR_LATER(ah)) 642 ss = (int16_t)(0 - (minPwrT4[i] / 2)); 643 else 644 ss = 0; 645 } else { 646 ss = (int16_t)((pPdGainBoundaries[i - 1] - 647 (minPwrT4[i] / 2)) - 648 tPdGainOverlap + 1 + minDelta); 649 } 650 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 651 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 652 653 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 654 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 655 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); 656 ss++; 657 } 658 659 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); 660 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - 661 (minPwrT4[i] / 2)); 662 maxIndex = (tgtIndex < sizeCurrVpdTable) ? 663 tgtIndex : sizeCurrVpdTable; 664 665 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) 666 pPDADCValues[k++] = vpdTableI[i][ss++]; 667 668 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - 669 vpdTableI[i][sizeCurrVpdTable - 2]); 670 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 671 672 if (tgtIndex >= maxIndex) { 673 while ((ss <= tgtIndex) && 674 (k < (AR5416_NUM_PDADC_VALUES - 1))) { 675 tmpVal = (int16_t) TMP_VAL_VPD_TABLE; 676 pPDADCValues[k++] = (u8)((tmpVal > 255) ? 677 255 : tmpVal); 678 ss++; 679 } 680 } 681 } 682 683 while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) { 684 pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT; 685 i++; 686 } 687 688 while (k < AR5416_NUM_PDADC_VALUES) { 689 pPDADCValues[k] = pPDADCValues[k - 1]; 690 k++; 691 } 692 693 return; 694#undef TMP_VAL_VPD_TABLE 695} 696 697static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, 698 struct ath9k_channel *chan, 699 int16_t *pTxPowerIndexOffset) 700{ 701 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 702 struct cal_data_per_freq_4k *pRawDataset; 703 u8 *pCalBChans = NULL; 704 u16 pdGainOverlap_t2; 705 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; 706 u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK]; 707 u16 numPiers, i, j; 708 int16_t tMinCalPower; 709 u16 numXpdGain, xpdMask; 710 u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 }; 711 u32 reg32, regOffset, regChainOffset; 712 713 xpdMask = pEepData->modalHeader.xpdGain; 714 715 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 716 AR5416_EEP_MINOR_VER_2) { 717 pdGainOverlap_t2 = 718 pEepData->modalHeader.pdGainOverlap; 719 } else { 720 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), 721 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 722 } 723 724 pCalBChans = pEepData->calFreqPier2G; 725 numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS; 726 727 numXpdGain = 0; 728 729 for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) { 730 if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) { 731 if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS) 732 break; 733 xpdGainValues[numXpdGain] = 734 (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i); 735 numXpdGain++; 736 } 737 } 738 739 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 740 (numXpdGain - 1) & 0x3); 741 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 742 xpdGainValues[0]); 743 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 744 xpdGainValues[1]); 745 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0); 746 747 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { 748 if (AR_SREV_5416_20_OR_LATER(ah) && 749 (ah->rxchainmask == 5 || ah->txchainmask == 5) && 750 (i != 0)) { 751 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 752 } else 753 regChainOffset = i * 0x1000; 754 755 if (pEepData->baseEepHeader.txMask & (1 << i)) { 756 pRawDataset = pEepData->calPierData2G[i]; 757 758 ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan, 759 pRawDataset, pCalBChans, 760 numPiers, pdGainOverlap_t2, 761 &tMinCalPower, gainBoundaries, 762 pdadcValues, numXpdGain); 763 764 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { 765 REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 766 SM(pdGainOverlap_t2, 767 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) 768 | SM(gainBoundaries[0], 769 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) 770 | SM(gainBoundaries[1], 771 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) 772 | SM(gainBoundaries[2], 773 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) 774 | SM(gainBoundaries[3], 775 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 776 } 777 778 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 779 for (j = 0; j < 32; j++) { 780 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | 781 ((pdadcValues[4 * j + 1] & 0xFF) << 8) | 782 ((pdadcValues[4 * j + 2] & 0xFF) << 16)| 783 ((pdadcValues[4 * j + 3] & 0xFF) << 24); 784 REG_WRITE(ah, regOffset, reg32); 785 786 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, 787 "PDADC (%d,%4x): %4.4x %8.8x\n", 788 i, regChainOffset, regOffset, 789 reg32); 790 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, 791 "PDADC: Chain %d | " 792 "PDADC %3d Value %3d | " 793 "PDADC %3d Value %3d | " 794 "PDADC %3d Value %3d | " 795 "PDADC %3d Value %3d |\n", 796 i, 4 * j, pdadcValues[4 * j], 797 4 * j + 1, pdadcValues[4 * j + 1], 798 4 * j + 2, pdadcValues[4 * j + 2], 799 4 * j + 3, 800 pdadcValues[4 * j + 3]); 801 802 regOffset += 4; 803 } 804 } 805 } 806 807 *pTxPowerIndexOffset = 0; 808 809 return true; 810} 811 812static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, 813 struct ath9k_channel *chan, 814 int16_t *ratesArray, 815 u16 cfgCtl, 816 u16 AntennaReduction, 817 u16 twiceMaxRegulatoryPower, 818 u16 powerLimit) 819{ 820 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 821 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 822 static const u16 tpScaleReductionTable[5] = 823 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 824 825 int i; 826 int16_t twiceLargestAntenna; 827 struct cal_ctl_data_4k *rep; 828 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 829 0, { 0, 0, 0, 0} 830 }; 831 struct cal_target_power_leg targetPowerOfdmExt = { 832 0, { 0, 0, 0, 0} }, targetPowerCckExt = { 833 0, { 0, 0, 0, 0 } 834 }; 835 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 836 0, {0, 0, 0, 0} 837 }; 838 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 839 u16 ctlModesFor11g[] = 840 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, 841 CTL_2GHT40 842 }; 843 u16 numCtlModes, *pCtlMode, ctlMode, freq; 844 struct chan_centers centers; 845 int tx_chainmask; 846 u16 twiceMinEdgePower; 847 848 tx_chainmask = ah->txchainmask; 849 850 ath9k_hw_get_channel_centers(ah, chan, &centers); 851 852 twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0]; 853 854 twiceLargestAntenna = (int16_t)min(AntennaReduction - 855 twiceLargestAntenna, 0); 856 857 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 858 859 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) { 860 maxRegAllowedPower -= 861 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); 862 } 863 864 scaledPower = min(powerLimit, maxRegAllowedPower); 865 scaledPower = max((u16)0, scaledPower); 866 867 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 868 pCtlMode = ctlModesFor11g; 869 870 ath9k_hw_get_legacy_target_powers(ah, chan, 871 pEepData->calTargetPowerCck, 872 AR5416_NUM_2G_CCK_TARGET_POWERS, 873 &targetPowerCck, 4, false); 874 ath9k_hw_get_legacy_target_powers(ah, chan, 875 pEepData->calTargetPower2G, 876 AR5416_NUM_2G_20_TARGET_POWERS, 877 &targetPowerOfdm, 4, false); 878 ath9k_hw_get_target_powers(ah, chan, 879 pEepData->calTargetPower2GHT20, 880 AR5416_NUM_2G_20_TARGET_POWERS, 881 &targetPowerHt20, 8, false); 882 883 if (IS_CHAN_HT40(chan)) { 884 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 885 ath9k_hw_get_target_powers(ah, chan, 886 pEepData->calTargetPower2GHT40, 887 AR5416_NUM_2G_40_TARGET_POWERS, 888 &targetPowerHt40, 8, true); 889 ath9k_hw_get_legacy_target_powers(ah, chan, 890 pEepData->calTargetPowerCck, 891 AR5416_NUM_2G_CCK_TARGET_POWERS, 892 &targetPowerCckExt, 4, true); 893 ath9k_hw_get_legacy_target_powers(ah, chan, 894 pEepData->calTargetPower2G, 895 AR5416_NUM_2G_20_TARGET_POWERS, 896 &targetPowerOfdmExt, 4, true); 897 } 898 899 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 900 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 901 (pCtlMode[ctlMode] == CTL_2GHT40); 902 if (isHt40CtlMode) 903 freq = centers.synth_center; 904 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 905 freq = centers.ext_center; 906 else 907 freq = centers.ctl_center; 908 909 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 910 ah->eep_ops->get_eeprom_rev(ah) <= 2) 911 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 912 913 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 914 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " 915 "EXT_ADDITIVE %d\n", 916 ctlMode, numCtlModes, isHt40CtlMode, 917 (pCtlMode[ctlMode] & EXT_ADDITIVE)); 918 919 for (i = 0; (i < AR5416_NUM_CTLS) && 920 pEepData->ctlIndex[i]; i++) { 921 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 922 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " 923 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " 924 "chan %d\n", 925 i, cfgCtl, pCtlMode[ctlMode], 926 pEepData->ctlIndex[i], chan->channel); 927 928 if ((((cfgCtl & ~CTL_MODE_M) | 929 (pCtlMode[ctlMode] & CTL_MODE_M)) == 930 pEepData->ctlIndex[i]) || 931 (((cfgCtl & ~CTL_MODE_M) | 932 (pCtlMode[ctlMode] & CTL_MODE_M)) == 933 ((pEepData->ctlIndex[i] & CTL_MODE_M) | 934 SD_NO_CTL))) { 935 rep = &(pEepData->ctlData[i]); 936 937 twiceMinEdgePower = 938 ath9k_hw_get_max_edge_power(freq, 939 rep->ctlEdges[ar5416_get_ntxchains 940 (tx_chainmask) - 1], 941 IS_CHAN_2GHZ(chan), 942 AR5416_EEP4K_NUM_BAND_EDGES); 943 944 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 945 " MATCH-EE_IDX %d: ch %d is2 %d " 946 "2xMinEdge %d chainmask %d chains %d\n", 947 i, freq, IS_CHAN_2GHZ(chan), 948 twiceMinEdgePower, tx_chainmask, 949 ar5416_get_ntxchains 950 (tx_chainmask)); 951 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 952 twiceMaxEdgePower = 953 min(twiceMaxEdgePower, 954 twiceMinEdgePower); 955 } else { 956 twiceMaxEdgePower = twiceMinEdgePower; 957 break; 958 } 959 } 960 } 961 962 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 963 964 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 965 " SEL-Min ctlMode %d pCtlMode %d " 966 "2xMaxEdge %d sP %d minCtlPwr %d\n", 967 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, 968 scaledPower, minCtlPower); 969 970 switch (pCtlMode[ctlMode]) { 971 case CTL_11B: 972 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); 973 i++) { 974 targetPowerCck.tPow2x[i] = 975 min((u16)targetPowerCck.tPow2x[i], 976 minCtlPower); 977 } 978 break; 979 case CTL_11G: 980 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); 981 i++) { 982 targetPowerOfdm.tPow2x[i] = 983 min((u16)targetPowerOfdm.tPow2x[i], 984 minCtlPower); 985 } 986 break; 987 case CTL_2GHT20: 988 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); 989 i++) { 990 targetPowerHt20.tPow2x[i] = 991 min((u16)targetPowerHt20.tPow2x[i], 992 minCtlPower); 993 } 994 break; 995 case CTL_11B_EXT: 996 targetPowerCckExt.tPow2x[0] = min((u16) 997 targetPowerCckExt.tPow2x[0], 998 minCtlPower); 999 break; 1000 case CTL_11G_EXT: 1001 targetPowerOfdmExt.tPow2x[0] = min((u16) 1002 targetPowerOfdmExt.tPow2x[0], 1003 minCtlPower); 1004 break; 1005 case CTL_2GHT40: 1006 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); 1007 i++) { 1008 targetPowerHt40.tPow2x[i] = 1009 min((u16)targetPowerHt40.tPow2x[i], 1010 minCtlPower); 1011 } 1012 break; 1013 default: 1014 break; 1015 } 1016 } 1017 1018 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = 1019 ratesArray[rate18mb] = ratesArray[rate24mb] = 1020 targetPowerOfdm.tPow2x[0]; 1021 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 1022 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 1023 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 1024 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 1025 1026 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 1027 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 1028 1029 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 1030 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 1031 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 1032 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 1033 1034 if (IS_CHAN_HT40(chan)) { 1035 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 1036 ratesArray[rateHt40_0 + i] = 1037 targetPowerHt40.tPow2x[i]; 1038 } 1039 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 1040 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 1041 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 1042 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 1043 } 1044 return true; 1045} 1046 1047static int ath9k_hw_4k_set_txpower(struct ath_hw *ah, 1048 struct ath9k_channel *chan, 1049 u16 cfgCtl, 1050 u8 twiceAntennaReduction, 1051 u8 twiceMaxRegulatoryPower, 1052 u8 powerLimit) 1053{ 1054 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 1055 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 1056 int16_t ratesArray[Ar5416RateSize]; 1057 int16_t txPowerIndexOffset = 0; 1058 u8 ht40PowerIncForPdadc = 2; 1059 int i; 1060 1061 memset(ratesArray, 0, sizeof(ratesArray)); 1062 1063 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1064 AR5416_EEP_MINOR_VER_2) { 1065 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1066 } 1067 1068 if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan, 1069 &ratesArray[0], cfgCtl, 1070 twiceAntennaReduction, 1071 twiceMaxRegulatoryPower, 1072 powerLimit)) { 1073 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1074 "ath9k_hw_set_txpower: unable to set " 1075 "tx power per rate table\n"); 1076 return -EIO; 1077 } 1078 1079 if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) { 1080 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1081 "ath9k_hw_set_txpower: unable to set power table\n"); 1082 return -EIO; 1083 } 1084 1085 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1086 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1087 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 1088 ratesArray[i] = AR5416_MAX_RATE_POWER; 1089 } 1090 1091 if (AR_SREV_9280_10_OR_LATER(ah)) { 1092 for (i = 0; i < Ar5416RateSize; i++) 1093 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; 1094 } 1095 1096 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1097 ATH9K_POW_SM(ratesArray[rate18mb], 24) 1098 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 1099 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 1100 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 1101 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 1102 ATH9K_POW_SM(ratesArray[rate54mb], 24) 1103 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 1104 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 1105 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 1106 1107 if (IS_CHAN_2GHZ(chan)) { 1108 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1109 ATH9K_POW_SM(ratesArray[rate2s], 24) 1110 | ATH9K_POW_SM(ratesArray[rate2l], 16) 1111 | ATH9K_POW_SM(ratesArray[rateXr], 8) 1112 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 1113 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 1114 ATH9K_POW_SM(ratesArray[rate11s], 24) 1115 | ATH9K_POW_SM(ratesArray[rate11l], 16) 1116 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 1117 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 1118 } 1119 1120 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 1121 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 1122 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 1123 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 1124 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 1125 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 1126 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 1127 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 1128 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 1129 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 1130 1131 if (IS_CHAN_HT40(chan)) { 1132 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 1133 ATH9K_POW_SM(ratesArray[rateHt40_3] + 1134 ht40PowerIncForPdadc, 24) 1135 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 1136 ht40PowerIncForPdadc, 16) 1137 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 1138 ht40PowerIncForPdadc, 8) 1139 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 1140 ht40PowerIncForPdadc, 0)); 1141 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 1142 ATH9K_POW_SM(ratesArray[rateHt40_7] + 1143 ht40PowerIncForPdadc, 24) 1144 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 1145 ht40PowerIncForPdadc, 16) 1146 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 1147 ht40PowerIncForPdadc, 8) 1148 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 1149 ht40PowerIncForPdadc, 0)); 1150 1151 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1152 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 1153 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 1154 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 1155 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 1156 } 1157 1158 i = rate6mb; 1159 1160 if (IS_CHAN_HT40(chan)) 1161 i = rateHt40_0; 1162 else if (IS_CHAN_HT20(chan)) 1163 i = rateHt20_0; 1164 1165 if (AR_SREV_9280_10_OR_LATER(ah)) 1166 ah->regulatory.max_power_level = 1167 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; 1168 else 1169 ah->regulatory.max_power_level = ratesArray[i]; 1170 1171 return 0; 1172} 1173 1174static void ath9k_hw_4k_set_addac(struct ath_hw *ah, 1175 struct ath9k_channel *chan) 1176{ 1177 struct modal_eep_4k_header *pModal; 1178 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 1179 u8 biaslevel; 1180 1181 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) 1182 return; 1183 1184 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) 1185 return; 1186 1187 pModal = &eep->modalHeader; 1188 1189 if (pModal->xpaBiasLvl != 0xff) { 1190 biaslevel = pModal->xpaBiasLvl; 1191 INI_RA(&ah->iniAddac, 7, 1) = 1192 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; 1193 } 1194} 1195 1196static void ath9k_hw_4k_set_gain(struct ath_hw *ah, 1197 struct modal_eep_4k_header *pModal, 1198 struct ar5416_eeprom_4k *eep, 1199 u8 txRxAttenLocal, int regChainOffset) 1200{ 1201 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, 1202 pModal->antCtrlChain[0]); 1203 1204 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1205 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & 1206 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1207 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1208 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1209 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1210 1211 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1212 AR5416_EEP_MINOR_VER_3) { 1213 txRxAttenLocal = pModal->txRxAttenCh[0]; 1214 1215 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1216 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]); 1217 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1218 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 1219 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1220 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 1221 pModal->xatten2Margin[0]); 1222 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1223 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); 1224 } 1225 1226 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1227 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1228 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1229 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 1230 1231 if (AR_SREV_9285_11(ah)) 1232 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); 1233} 1234 1235static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, 1236 struct ath9k_channel *chan) 1237{ 1238 struct modal_eep_4k_header *pModal; 1239 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 1240 u8 txRxAttenLocal; 1241 u8 ob[5], db1[5], db2[5]; 1242 u8 ant_div_control1, ant_div_control2; 1243 u32 regVal; 1244 1245 pModal = &eep->modalHeader; 1246 txRxAttenLocal = 23; 1247 1248 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1249 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); 1250 1251 /* Single chain for 4K EEPROM*/ 1252 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0); 1253 1254 /* Initialize Ant Diversity settings from EEPROM */ 1255 if (pModal->version == 3) { 1256 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf); 1257 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf); 1258 regVal = REG_READ(ah, 0x99ac); 1259 regVal &= (~(0x7f000000)); 1260 regVal |= ((ant_div_control1 & 0x1) << 24); 1261 regVal |= (((ant_div_control1 >> 1) & 0x1) << 29); 1262 regVal |= (((ant_div_control1 >> 2) & 0x1) << 30); 1263 regVal |= ((ant_div_control2 & 0x3) << 25); 1264 regVal |= (((ant_div_control2 >> 2) & 0x3) << 27); 1265 REG_WRITE(ah, 0x99ac, regVal); 1266 regVal = REG_READ(ah, 0x99ac); 1267 regVal = REG_READ(ah, 0xa208); 1268 regVal &= (~(0x1 << 13)); 1269 regVal |= (((ant_div_control1 >> 3) & 0x1) << 13); 1270 REG_WRITE(ah, 0xa208, regVal); 1271 regVal = REG_READ(ah, 0xa208); 1272 } 1273 1274 if (pModal->version >= 2) { 1275 ob[0] = (pModal->ob_01 & 0xf); 1276 ob[1] = (pModal->ob_01 >> 4) & 0xf; 1277 ob[2] = (pModal->ob_234 & 0xf); 1278 ob[3] = ((pModal->ob_234 >> 4) & 0xf); 1279 ob[4] = ((pModal->ob_234 >> 8) & 0xf); 1280 1281 db1[0] = (pModal->db1_01 & 0xf); 1282 db1[1] = ((pModal->db1_01 >> 4) & 0xf); 1283 db1[2] = (pModal->db1_234 & 0xf); 1284 db1[3] = ((pModal->db1_234 >> 4) & 0xf); 1285 db1[4] = ((pModal->db1_234 >> 8) & 0xf); 1286 1287 db2[0] = (pModal->db2_01 & 0xf); 1288 db2[1] = ((pModal->db2_01 >> 4) & 0xf); 1289 db2[2] = (pModal->db2_234 & 0xf); 1290 db2[3] = ((pModal->db2_234 >> 4) & 0xf); 1291 db2[4] = ((pModal->db2_234 >> 8) & 0xf); 1292 1293 } else if (pModal->version == 1) { 1294 ob[0] = (pModal->ob_01 & 0xf); 1295 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf; 1296 db1[0] = (pModal->db1_01 & 0xf); 1297 db1[1] = db1[2] = db1[3] = 1298 db1[4] = ((pModal->db1_01 >> 4) & 0xf); 1299 db2[0] = (pModal->db2_01 & 0xf); 1300 db2[1] = db2[2] = db2[3] = 1301 db2[4] = ((pModal->db2_01 >> 4) & 0xf); 1302 } else { 1303 int i; 1304 for (i = 0; i < 5; i++) { 1305 ob[i] = pModal->ob_01; 1306 db1[i] = pModal->db1_01; 1307 db2[i] = pModal->db1_01; 1308 } 1309 } 1310 1311 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1312 AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]); 1313 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1314 AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]); 1315 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1316 AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]); 1317 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1318 AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]); 1319 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1320 AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]); 1321 1322 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1323 AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]); 1324 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1325 AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]); 1326 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1327 AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]); 1328 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1329 AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]); 1330 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1331 AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]); 1332 1333 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1334 AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]); 1335 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1336 AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]); 1337 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1338 AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]); 1339 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1340 AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]); 1341 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1342 AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]); 1343 1344 1345 if (AR_SREV_9285_11(ah)) 1346 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); 1347 1348 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 1349 pModal->switchSettling); 1350 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 1351 pModal->adcDesiredSize); 1352 1353 REG_WRITE(ah, AR_PHY_RF_CTL4, 1354 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | 1355 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | 1356 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | 1357 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1358 1359 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 1360 pModal->txEndToRxOn); 1361 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1362 pModal->thresh62); 1363 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 1364 pModal->thresh62); 1365 1366 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1367 AR5416_EEP_MINOR_VER_2) { 1368 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, 1369 pModal->txFrameToDataStart); 1370 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, 1371 pModal->txFrameToPaOn); 1372 } 1373 1374 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1375 AR5416_EEP_MINOR_VER_3) { 1376 if (IS_CHAN_HT40(chan)) 1377 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1378 AR_PHY_SETTLING_SWITCH, 1379 pModal->swSettleHt40); 1380 } 1381} 1382 1383static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, 1384 struct ath9k_channel *chan) 1385{ 1386 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 1387 struct modal_eep_4k_header *pModal = &eep->modalHeader; 1388 1389 return pModal->antCtrlCommon & 0xFFFF; 1390} 1391 1392static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah, 1393 enum ieee80211_band freq_band) 1394{ 1395 return 1; 1396} 1397 1398static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1399{ 1400#define EEP_MAP4K_SPURCHAN \ 1401 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan) 1402 1403 u16 spur_val = AR_NO_SPUR; 1404 1405 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 1406 "Getting spur idx %d is2Ghz. %d val %x\n", 1407 i, is2GHz, ah->config.spurchans[i][is2GHz]); 1408 1409 switch (ah->config.spurmode) { 1410 case SPUR_DISABLE: 1411 break; 1412 case SPUR_ENABLE_IOCTL: 1413 spur_val = ah->config.spurchans[i][is2GHz]; 1414 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 1415 "Getting spur val from new loc. %d\n", spur_val); 1416 break; 1417 case SPUR_ENABLE_EEPROM: 1418 spur_val = EEP_MAP4K_SPURCHAN; 1419 break; 1420 } 1421 1422 return spur_val; 1423 1424#undef EEP_MAP4K_SPURCHAN 1425} 1426 1427static struct eeprom_ops eep_4k_ops = { 1428 .check_eeprom = ath9k_hw_4k_check_eeprom, 1429 .get_eeprom = ath9k_hw_4k_get_eeprom, 1430 .fill_eeprom = ath9k_hw_4k_fill_eeprom, 1431 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, 1432 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, 1433 .get_num_ant_config = ath9k_hw_4k_get_num_ant_config, 1434 .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg, 1435 .set_board_values = ath9k_hw_4k_set_board_values, 1436 .set_addac = ath9k_hw_4k_set_addac, 1437 .set_txpower = ath9k_hw_4k_set_txpower, 1438 .get_spur_channel = ath9k_hw_4k_get_spur_channel 1439}; 1440 1441/************************************************/ 1442/* EEPROM Operations for non-4K (Default) cards */ 1443/************************************************/ 1444 1445static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah) 1446{ 1447 return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF); 1448} 1449 1450static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah) 1451{ 1452 return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF); 1453} 1454 1455static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) 1456{ 1457#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) 1458 u16 *eep_data = (u16 *)&ah->eeprom.def; 1459 int addr, ar5416_eep_start_loc = 0x100; 1460 1461 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { 1462 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, 1463 eep_data)) { 1464 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1465 "Unable to read eeprom region\n"); 1466 return false; 1467 } 1468 eep_data++; 1469 } 1470 return true; 1471#undef SIZE_EEPROM_DEF 1472} 1473 1474static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) 1475{ 1476 struct ar5416_eeprom_def *eep = 1477 (struct ar5416_eeprom_def *) &ah->eeprom.def; 1478 u16 *eepdata, temp, magic, magic2; 1479 u32 sum = 0, el; 1480 bool need_swap = false; 1481 int i, addr, size; 1482 1483 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { 1484 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n"); 1485 return false; 1486 } 1487 1488 if (!ath9k_hw_use_flash(ah)) { 1489 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1490 "Read Magic = 0x%04X\n", magic); 1491 1492 if (magic != AR5416_EEPROM_MAGIC) { 1493 magic2 = swab16(magic); 1494 1495 if (magic2 == AR5416_EEPROM_MAGIC) { 1496 size = sizeof(struct ar5416_eeprom_def); 1497 need_swap = true; 1498 eepdata = (u16 *) (&ah->eeprom); 1499 1500 for (addr = 0; addr < size / sizeof(u16); addr++) { 1501 temp = swab16(*eepdata); 1502 *eepdata = temp; 1503 eepdata++; 1504 } 1505 } else { 1506 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1507 "Invalid EEPROM Magic. " 1508 "Endianness mismatch.\n"); 1509 return -EINVAL; 1510 } 1511 } 1512 } 1513 1514 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", 1515 need_swap ? "True" : "False"); 1516 1517 if (need_swap) 1518 el = swab16(ah->eeprom.def.baseEepHeader.length); 1519 else 1520 el = ah->eeprom.def.baseEepHeader.length; 1521 1522 if (el > sizeof(struct ar5416_eeprom_def)) 1523 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16); 1524 else 1525 el = el / sizeof(u16); 1526 1527 eepdata = (u16 *)(&ah->eeprom); 1528 1529 for (i = 0; i < el; i++) 1530 sum ^= *eepdata++; 1531 1532 if (need_swap) { 1533 u32 integer, j; 1534 u16 word; 1535 1536 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1537 "EEPROM Endianness is not native.. Changing.\n"); 1538 1539 word = swab16(eep->baseEepHeader.length); 1540 eep->baseEepHeader.length = word; 1541 1542 word = swab16(eep->baseEepHeader.checksum); 1543 eep->baseEepHeader.checksum = word; 1544 1545 word = swab16(eep->baseEepHeader.version); 1546 eep->baseEepHeader.version = word; 1547 1548 word = swab16(eep->baseEepHeader.regDmn[0]); 1549 eep->baseEepHeader.regDmn[0] = word; 1550 1551 word = swab16(eep->baseEepHeader.regDmn[1]); 1552 eep->baseEepHeader.regDmn[1] = word; 1553 1554 word = swab16(eep->baseEepHeader.rfSilent); 1555 eep->baseEepHeader.rfSilent = word; 1556 1557 word = swab16(eep->baseEepHeader.blueToothOptions); 1558 eep->baseEepHeader.blueToothOptions = word; 1559 1560 word = swab16(eep->baseEepHeader.deviceCap); 1561 eep->baseEepHeader.deviceCap = word; 1562 1563 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) { 1564 struct modal_eep_header *pModal = 1565 &eep->modalHeader[j]; 1566 integer = swab32(pModal->antCtrlCommon); 1567 pModal->antCtrlCommon = integer; 1568 1569 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1570 integer = swab32(pModal->antCtrlChain[i]); 1571 pModal->antCtrlChain[i] = integer; 1572 } 1573 1574 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 1575 word = swab16(pModal->spurChans[i].spurChan); 1576 pModal->spurChans[i].spurChan = word; 1577 } 1578 } 1579 } 1580 1581 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || 1582 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 1583 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1584 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 1585 sum, ah->eep_ops->get_eeprom_ver(ah)); 1586 return -EINVAL; 1587 } 1588 1589 return 0; 1590} 1591 1592static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, 1593 enum eeprom_param param) 1594{ 1595 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1596 struct modal_eep_header *pModal = eep->modalHeader; 1597 struct base_eep_header *pBase = &eep->baseEepHeader; 1598 1599 switch (param) { 1600 case EEP_NFTHRESH_5: 1601 return pModal[0].noiseFloorThreshCh[0]; 1602 case EEP_NFTHRESH_2: 1603 return pModal[1].noiseFloorThreshCh[0]; 1604 case AR_EEPROM_MAC(0): 1605 return pBase->macAddr[0] << 8 | pBase->macAddr[1]; 1606 case AR_EEPROM_MAC(1): 1607 return pBase->macAddr[2] << 8 | pBase->macAddr[3]; 1608 case AR_EEPROM_MAC(2): 1609 return pBase->macAddr[4] << 8 | pBase->macAddr[5]; 1610 case EEP_REG_0: 1611 return pBase->regDmn[0]; 1612 case EEP_REG_1: 1613 return pBase->regDmn[1]; 1614 case EEP_OP_CAP: 1615 return pBase->deviceCap; 1616 case EEP_OP_MODE: 1617 return pBase->opCapFlags; 1618 case EEP_RF_SILENT: 1619 return pBase->rfSilent; 1620 case EEP_OB_5: 1621 return pModal[0].ob; 1622 case EEP_DB_5: 1623 return pModal[0].db; 1624 case EEP_OB_2: 1625 return pModal[1].ob; 1626 case EEP_DB_2: 1627 return pModal[1].db; 1628 case EEP_MINOR_REV: 1629 return AR5416_VER_MASK; 1630 case EEP_TX_MASK: 1631 return pBase->txMask; 1632 case EEP_RX_MASK: 1633 return pBase->rxMask; 1634 case EEP_RXGAIN_TYPE: 1635 return pBase->rxGainType; 1636 case EEP_TXGAIN_TYPE: 1637 return pBase->txGainType; 1638 case EEP_OL_PWRCTRL: 1639 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 1640 return pBase->openLoopPwrCntl ? true : false; 1641 else 1642 return false; 1643 case EEP_RC_CHAIN_MASK: 1644 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 1645 return pBase->rcChainMask; 1646 else 1647 return 0; 1648 case EEP_DAC_HPWR_5G: 1649 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) 1650 return pBase->dacHiPwrMode_5G; 1651 else 1652 return 0; 1653 case EEP_FRAC_N_5G: 1654 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22) 1655 return pBase->frac_n_5g; 1656 else 1657 return 0; 1658 default: 1659 return 0; 1660 } 1661} 1662 1663static void ath9k_hw_def_set_gain(struct ath_hw *ah, 1664 struct modal_eep_header *pModal, 1665 struct ar5416_eeprom_def *eep, 1666 u8 txRxAttenLocal, int regChainOffset, int i) 1667{ 1668 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { 1669 txRxAttenLocal = pModal->txRxAttenCh[i]; 1670 1671 if (AR_SREV_9280_10_OR_LATER(ah)) { 1672 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1673 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 1674 pModal->bswMargin[i]); 1675 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1676 AR_PHY_GAIN_2GHZ_XATTEN1_DB, 1677 pModal->bswAtten[i]); 1678 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1679 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 1680 pModal->xatten2Margin[i]); 1681 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1682 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 1683 pModal->xatten2Db[i]); 1684 } else { 1685 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1686 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1687 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) 1688 | SM(pModal-> bswMargin[i], 1689 AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1690 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1691 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1692 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) 1693 | SM(pModal->bswAtten[i], 1694 AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1695 } 1696 } 1697 1698 if (AR_SREV_9280_10_OR_LATER(ah)) { 1699 REG_RMW_FIELD(ah, 1700 AR_PHY_RXGAIN + regChainOffset, 1701 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1702 REG_RMW_FIELD(ah, 1703 AR_PHY_RXGAIN + regChainOffset, 1704 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); 1705 } else { 1706 REG_WRITE(ah, 1707 AR_PHY_RXGAIN + regChainOffset, 1708 (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & 1709 ~AR_PHY_RXGAIN_TXRX_ATTEN) 1710 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN)); 1711 REG_WRITE(ah, 1712 AR_PHY_GAIN_2GHZ + regChainOffset, 1713 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1714 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) | 1715 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN)); 1716 } 1717} 1718 1719static void ath9k_hw_def_set_board_values(struct ath_hw *ah, 1720 struct ath9k_channel *chan) 1721{ 1722 struct modal_eep_header *pModal; 1723 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1724 int i, regChainOffset; 1725 u8 txRxAttenLocal; 1726 1727 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1728 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; 1729 1730 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1731 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); 1732 1733 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1734 if (AR_SREV_9280(ah)) { 1735 if (i >= 2) 1736 break; 1737 } 1738 1739 if (AR_SREV_5416_20_OR_LATER(ah) && 1740 (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) 1741 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1742 else 1743 regChainOffset = i * 0x1000; 1744 1745 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, 1746 pModal->antCtrlChain[i]); 1747 1748 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1749 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & 1750 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1751 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1752 SM(pModal->iqCalICh[i], 1753 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1754 SM(pModal->iqCalQCh[i], 1755 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1756 1757 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) 1758 ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal, 1759 regChainOffset, i); 1760 } 1761 1762 if (AR_SREV_9280_10_OR_LATER(ah)) { 1763 if (IS_CHAN_2GHZ(chan)) { 1764 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, 1765 AR_AN_RF2G1_CH0_OB, 1766 AR_AN_RF2G1_CH0_OB_S, 1767 pModal->ob); 1768 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, 1769 AR_AN_RF2G1_CH0_DB, 1770 AR_AN_RF2G1_CH0_DB_S, 1771 pModal->db); 1772 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1, 1773 AR_AN_RF2G1_CH1_OB, 1774 AR_AN_RF2G1_CH1_OB_S, 1775 pModal->ob_ch1); 1776 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1, 1777 AR_AN_RF2G1_CH1_DB, 1778 AR_AN_RF2G1_CH1_DB_S, 1779 pModal->db_ch1); 1780 } else { 1781 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0, 1782 AR_AN_RF5G1_CH0_OB5, 1783 AR_AN_RF5G1_CH0_OB5_S, 1784 pModal->ob); 1785 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0, 1786 AR_AN_RF5G1_CH0_DB5, 1787 AR_AN_RF5G1_CH0_DB5_S, 1788 pModal->db); 1789 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1, 1790 AR_AN_RF5G1_CH1_OB5, 1791 AR_AN_RF5G1_CH1_OB5_S, 1792 pModal->ob_ch1); 1793 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1, 1794 AR_AN_RF5G1_CH1_DB5, 1795 AR_AN_RF5G1_CH1_DB5_S, 1796 pModal->db_ch1); 1797 } 1798 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, 1799 AR_AN_TOP2_XPABIAS_LVL, 1800 AR_AN_TOP2_XPABIAS_LVL_S, 1801 pModal->xpaBiasLvl); 1802 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, 1803 AR_AN_TOP2_LOCALBIAS, 1804 AR_AN_TOP2_LOCALBIAS_S, 1805 pModal->local_bias); 1806 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, 1807 pModal->force_xpaon); 1808 } 1809 1810 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 1811 pModal->switchSettling); 1812 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 1813 pModal->adcDesiredSize); 1814 1815 if (!AR_SREV_9280_10_OR_LATER(ah)) 1816 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 1817 AR_PHY_DESIRED_SZ_PGA, 1818 pModal->pgaDesiredSize); 1819 1820 REG_WRITE(ah, AR_PHY_RF_CTL4, 1821 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 1822 | SM(pModal->txEndToXpaOff, 1823 AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 1824 | SM(pModal->txFrameToXpaOn, 1825 AR_PHY_RF_CTL4_FRAME_XPAA_ON) 1826 | SM(pModal->txFrameToXpaOn, 1827 AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1828 1829 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 1830 pModal->txEndToRxOn); 1831 1832 if (AR_SREV_9280_10_OR_LATER(ah)) { 1833 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1834 pModal->thresh62); 1835 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, 1836 AR_PHY_EXT_CCA0_THRESH62, 1837 pModal->thresh62); 1838 } else { 1839 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, 1840 pModal->thresh62); 1841 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, 1842 AR_PHY_EXT_CCA_THRESH62, 1843 pModal->thresh62); 1844 } 1845 1846 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) { 1847 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, 1848 AR_PHY_TX_END_DATA_START, 1849 pModal->txFrameToDataStart); 1850 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, 1851 pModal->txFrameToPaOn); 1852 } 1853 1854 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { 1855 if (IS_CHAN_HT40(chan)) 1856 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1857 AR_PHY_SETTLING_SWITCH, 1858 pModal->swSettleHt40); 1859 } 1860 1861 if (AR_SREV_9280_20_OR_LATER(ah) && 1862 AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 1863 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, 1864 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, 1865 pModal->miscBits); 1866 1867 1868 if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { 1869 if (IS_CHAN_2GHZ(chan)) 1870 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 1871 eep->baseEepHeader.dacLpMode); 1872 else if (eep->baseEepHeader.dacHiPwrMode_5G) 1873 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); 1874 else 1875 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 1876 eep->baseEepHeader.dacLpMode); 1877 1878 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, 1879 pModal->miscBits >> 2); 1880 1881 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, 1882 AR_PHY_TX_DESIRED_SCALE_CCK, 1883 eep->baseEepHeader.desiredScaleCCK); 1884 } 1885} 1886 1887static void ath9k_hw_def_set_addac(struct ath_hw *ah, 1888 struct ath9k_channel *chan) 1889{ 1890#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) 1891 struct modal_eep_header *pModal; 1892 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1893 u8 biaslevel; 1894 1895 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) 1896 return; 1897 1898 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) 1899 return; 1900 1901 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1902 1903 if (pModal->xpaBiasLvl != 0xff) { 1904 biaslevel = pModal->xpaBiasLvl; 1905 } else { 1906 u16 resetFreqBin, freqBin, freqCount = 0; 1907 struct chan_centers centers; 1908 1909 ath9k_hw_get_channel_centers(ah, chan, &centers); 1910 1911 resetFreqBin = FREQ2FBIN(centers.synth_center, 1912 IS_CHAN_2GHZ(chan)); 1913 freqBin = XPA_LVL_FREQ(0) & 0xff; 1914 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14); 1915 1916 freqCount++; 1917 1918 while (freqCount < 3) { 1919 if (XPA_LVL_FREQ(freqCount) == 0x0) 1920 break; 1921 1922 freqBin = XPA_LVL_FREQ(freqCount) & 0xff; 1923 if (resetFreqBin >= freqBin) 1924 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14); 1925 else 1926 break; 1927 freqCount++; 1928 } 1929 } 1930 1931 if (IS_CHAN_2GHZ(chan)) { 1932 INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac, 1933 7, 1) & (~0x18)) | biaslevel << 3; 1934 } else { 1935 INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac, 1936 6, 1) & (~0xc0)) | biaslevel << 6; 1937 } 1938#undef XPA_LVL_FREQ 1939} 1940 1941static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, 1942 struct ath9k_channel *chan, 1943 struct cal_data_per_freq *pRawDataSet, 1944 u8 *bChans, u16 availPiers, 1945 u16 tPdGainOverlap, int16_t *pMinCalPower, 1946 u16 *pPdGainBoundaries, u8 *pPDADCValues, 1947 u16 numXpdGains) 1948{ 1949 int i, j, k; 1950 int16_t ss; 1951 u16 idxL = 0, idxR = 0, numPiers; 1952 static u8 vpdTableL[AR5416_NUM_PD_GAINS] 1953 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 1954 static u8 vpdTableR[AR5416_NUM_PD_GAINS] 1955 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 1956 static u8 vpdTableI[AR5416_NUM_PD_GAINS] 1957 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 1958 1959 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; 1960 u8 minPwrT4[AR5416_NUM_PD_GAINS]; 1961 u8 maxPwrT4[AR5416_NUM_PD_GAINS]; 1962 int16_t vpdStep; 1963 int16_t tmpVal; 1964 u16 sizeCurrVpdTable, maxIndex, tgtIndex; 1965 bool match; 1966 int16_t minDelta = 0; 1967 struct chan_centers centers; 1968 1969 ath9k_hw_get_channel_centers(ah, chan, &centers); 1970 1971 for (numPiers = 0; numPiers < availPiers; numPiers++) { 1972 if (bChans[numPiers] == AR5416_BCHAN_UNUSED) 1973 break; 1974 } 1975 1976 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center, 1977 IS_CHAN_2GHZ(chan)), 1978 bChans, numPiers, &idxL, &idxR); 1979 1980 if (match) { 1981 for (i = 0; i < numXpdGains; i++) { 1982 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 1983 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 1984 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 1985 pRawDataSet[idxL].pwrPdg[i], 1986 pRawDataSet[idxL].vpdPdg[i], 1987 AR5416_PD_GAIN_ICEPTS, 1988 vpdTableI[i]); 1989 } 1990 } else { 1991 for (i = 0; i < numXpdGains; i++) { 1992 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 1993 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 1994 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 1995 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 1996 1997 minPwrT4[i] = max(pPwrL[0], pPwrR[0]); 1998 1999 maxPwrT4[i] = 2000 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], 2001 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); 2002 2003 2004 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 2005 pPwrL, pVpdL, 2006 AR5416_PD_GAIN_ICEPTS, 2007 vpdTableL[i]); 2008 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 2009 pPwrR, pVpdR, 2010 AR5416_PD_GAIN_ICEPTS, 2011 vpdTableR[i]); 2012 2013 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 2014 vpdTableI[i][j] = 2015 (u8)(ath9k_hw_interpolate((u16) 2016 FREQ2FBIN(centers. 2017 synth_center, 2018 IS_CHAN_2GHZ 2019 (chan)), 2020 bChans[idxL], bChans[idxR], 2021 vpdTableL[i][j], vpdTableR[i][j])); 2022 } 2023 } 2024 } 2025 2026 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 2027 2028 k = 0; 2029 2030 for (i = 0; i < numXpdGains; i++) { 2031 if (i == (numXpdGains - 1)) 2032 pPdGainBoundaries[i] = 2033 (u16)(maxPwrT4[i] / 2); 2034 else 2035 pPdGainBoundaries[i] = 2036 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); 2037 2038 pPdGainBoundaries[i] = 2039 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); 2040 2041 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { 2042 minDelta = pPdGainBoundaries[0] - 23; 2043 pPdGainBoundaries[0] = 23; 2044 } else { 2045 minDelta = 0; 2046 } 2047 2048 if (i == 0) { 2049 if (AR_SREV_9280_10_OR_LATER(ah)) 2050 ss = (int16_t)(0 - (minPwrT4[i] / 2)); 2051 else 2052 ss = 0; 2053 } else { 2054 ss = (int16_t)((pPdGainBoundaries[i - 1] - 2055 (minPwrT4[i] / 2)) - 2056 tPdGainOverlap + 1 + minDelta); 2057 } 2058 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 2059 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2060 2061 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2062 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 2063 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); 2064 ss++; 2065 } 2066 2067 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); 2068 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - 2069 (minPwrT4[i] / 2)); 2070 maxIndex = (tgtIndex < sizeCurrVpdTable) ? 2071 tgtIndex : sizeCurrVpdTable; 2072 2073 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2074 pPDADCValues[k++] = vpdTableI[i][ss++]; 2075 } 2076 2077 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - 2078 vpdTableI[i][sizeCurrVpdTable - 2]); 2079 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2080 2081 if (tgtIndex > maxIndex) { 2082 while ((ss <= tgtIndex) && 2083 (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2084 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + 2085 (ss - maxIndex + 1) * vpdStep)); 2086 pPDADCValues[k++] = (u8)((tmpVal > 255) ? 2087 255 : tmpVal); 2088 ss++; 2089 } 2090 } 2091 } 2092 2093 while (i < AR5416_PD_GAINS_IN_MASK) { 2094 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1]; 2095 i++; 2096 } 2097 2098 while (k < AR5416_NUM_PDADC_VALUES) { 2099 pPDADCValues[k] = pPDADCValues[k - 1]; 2100 k++; 2101 } 2102 2103 return; 2104} 2105 2106static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, 2107 struct ath9k_channel *chan, 2108 int16_t *pTxPowerIndexOffset) 2109{ 2110#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x) 2111#define SM_PDGAIN_B(x, y) \ 2112 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y) 2113 2114 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 2115 struct cal_data_per_freq *pRawDataset; 2116 u8 *pCalBChans = NULL; 2117 u16 pdGainOverlap_t2; 2118 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; 2119 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 2120 u16 numPiers, i, j; 2121 int16_t tMinCalPower; 2122 u16 numXpdGain, xpdMask; 2123 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; 2124 u32 reg32, regOffset, regChainOffset; 2125 int16_t modalIdx; 2126 2127 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; 2128 xpdMask = pEepData->modalHeader[modalIdx].xpdGain; 2129 2130 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 2131 AR5416_EEP_MINOR_VER_2) { 2132 pdGainOverlap_t2 = 2133 pEepData->modalHeader[modalIdx].pdGainOverlap; 2134 } else { 2135 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), 2136 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 2137 } 2138 2139 if (IS_CHAN_2GHZ(chan)) { 2140 pCalBChans = pEepData->calFreqPier2G; 2141 numPiers = AR5416_NUM_2G_CAL_PIERS; 2142 } else { 2143 pCalBChans = pEepData->calFreqPier5G; 2144 numPiers = AR5416_NUM_5G_CAL_PIERS; 2145 } 2146 2147 if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) { 2148 pRawDataset = pEepData->calPierData2G[0]; 2149 ah->initPDADC = ((struct calDataPerFreqOpLoop *) 2150 pRawDataset)->vpdPdg[0][0]; 2151 } 2152 2153 numXpdGain = 0; 2154 2155 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 2156 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 2157 if (numXpdGain >= AR5416_NUM_PD_GAINS) 2158 break; 2159 xpdGainValues[numXpdGain] = 2160 (u16)(AR5416_PD_GAINS_IN_MASK - i); 2161 numXpdGain++; 2162 } 2163 } 2164 2165 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 2166 (numXpdGain - 1) & 0x3); 2167 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 2168 xpdGainValues[0]); 2169 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 2170 xpdGainValues[1]); 2171 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 2172 xpdGainValues[2]); 2173 2174 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 2175 if (AR_SREV_5416_20_OR_LATER(ah) && 2176 (ah->rxchainmask == 5 || ah->txchainmask == 5) && 2177 (i != 0)) { 2178 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 2179 } else 2180 regChainOffset = i * 0x1000; 2181 2182 if (pEepData->baseEepHeader.txMask & (1 << i)) { 2183 if (IS_CHAN_2GHZ(chan)) 2184 pRawDataset = pEepData->calPierData2G[i]; 2185 else 2186 pRawDataset = pEepData->calPierData5G[i]; 2187 2188 2189 if (OLC_FOR_AR9280_20_LATER) { 2190 u8 pcdacIdx; 2191 u8 txPower; 2192 2193 ath9k_get_txgain_index(ah, chan, 2194 (struct calDataPerFreqOpLoop *)pRawDataset, 2195 pCalBChans, numPiers, &txPower, &pcdacIdx); 2196 ath9k_olc_get_pdadcs(ah, pcdacIdx, 2197 txPower/2, pdadcValues); 2198 } else { 2199 ath9k_hw_get_def_gain_boundaries_pdadcs(ah, 2200 chan, pRawDataset, 2201 pCalBChans, numPiers, 2202 pdGainOverlap_t2, 2203 &tMinCalPower, 2204 gainBoundaries, 2205 pdadcValues, 2206 numXpdGain); 2207 } 2208 2209 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { 2210 if (OLC_FOR_AR9280_20_LATER) { 2211 REG_WRITE(ah, 2212 AR_PHY_TPCRG5 + regChainOffset, 2213 SM(0x6, 2214 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 2215 SM_PD_GAIN(1) | SM_PD_GAIN(2) | 2216 SM_PD_GAIN(3) | SM_PD_GAIN(4)); 2217 } else { 2218 REG_WRITE(ah, 2219 AR_PHY_TPCRG5 + regChainOffset, 2220 SM(pdGainOverlap_t2, 2221 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| 2222 SM_PDGAIN_B(0, 1) | 2223 SM_PDGAIN_B(1, 2) | 2224 SM_PDGAIN_B(2, 3) | 2225 SM_PDGAIN_B(3, 4)); 2226 } 2227 } 2228 2229 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 2230 for (j = 0; j < 32; j++) { 2231 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | 2232 ((pdadcValues[4 * j + 1] & 0xFF) << 8) | 2233 ((pdadcValues[4 * j + 2] & 0xFF) << 16)| 2234 ((pdadcValues[4 * j + 3] & 0xFF) << 24); 2235 REG_WRITE(ah, regOffset, reg32); 2236 2237 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, 2238 "PDADC (%d,%4x): %4.4x %8.8x\n", 2239 i, regChainOffset, regOffset, 2240 reg32); 2241 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, 2242 "PDADC: Chain %d | PDADC %3d " 2243 "Value %3d | PDADC %3d Value %3d | " 2244 "PDADC %3d Value %3d | PDADC %3d " 2245 "Value %3d |\n", 2246 i, 4 * j, pdadcValues[4 * j], 2247 4 * j + 1, pdadcValues[4 * j + 1], 2248 4 * j + 2, pdadcValues[4 * j + 2], 2249 4 * j + 3, 2250 pdadcValues[4 * j + 3]); 2251 2252 regOffset += 4; 2253 } 2254 } 2255 } 2256 2257 *pTxPowerIndexOffset = 0; 2258 2259 return true; 2260#undef SM_PD_GAIN 2261#undef SM_PDGAIN_B 2262} 2263 2264static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, 2265 struct ath9k_channel *chan, 2266 int16_t *ratesArray, 2267 u16 cfgCtl, 2268 u16 AntennaReduction, 2269 u16 twiceMaxRegulatoryPower, 2270 u16 powerLimit) 2271{ 2272#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 2273#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 2274 2275 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 2276 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 2277 static const u16 tpScaleReductionTable[5] = 2278 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 2279 2280 int i; 2281 int16_t twiceLargestAntenna; 2282 struct cal_ctl_data *rep; 2283 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 2284 0, { 0, 0, 0, 0} 2285 }; 2286 struct cal_target_power_leg targetPowerOfdmExt = { 2287 0, { 0, 0, 0, 0} }, targetPowerCckExt = { 2288 0, { 0, 0, 0, 0 } 2289 }; 2290 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 2291 0, {0, 0, 0, 0} 2292 }; 2293 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 2294 u16 ctlModesFor11a[] = 2295 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 }; 2296 u16 ctlModesFor11g[] = 2297 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, 2298 CTL_2GHT40 2299 }; 2300 u16 numCtlModes, *pCtlMode, ctlMode, freq; 2301 struct chan_centers centers; 2302 int tx_chainmask; 2303 u16 twiceMinEdgePower; 2304 2305 tx_chainmask = ah->txchainmask; 2306 2307 ath9k_hw_get_channel_centers(ah, chan, &centers); 2308 2309 twiceLargestAntenna = max( 2310 pEepData->modalHeader 2311 [IS_CHAN_2GHZ(chan)].antennaGainCh[0], 2312 pEepData->modalHeader 2313 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]); 2314 2315 twiceLargestAntenna = max((u8)twiceLargestAntenna, 2316 pEepData->modalHeader 2317 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 2318 2319 twiceLargestAntenna = (int16_t)min(AntennaReduction - 2320 twiceLargestAntenna, 0); 2321 2322 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 2323 2324 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) { 2325 maxRegAllowedPower -= 2326 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); 2327 } 2328 2329 scaledPower = min(powerLimit, maxRegAllowedPower); 2330 2331 switch (ar5416_get_ntxchains(tx_chainmask)) { 2332 case 1: 2333 break; 2334 case 2: 2335 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; 2336 break; 2337 case 3: 2338 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; 2339 break; 2340 } 2341 2342 scaledPower = max((u16)0, scaledPower); 2343 2344 if (IS_CHAN_2GHZ(chan)) { 2345 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - 2346 SUB_NUM_CTL_MODES_AT_2G_40; 2347 pCtlMode = ctlModesFor11g; 2348 2349 ath9k_hw_get_legacy_target_powers(ah, chan, 2350 pEepData->calTargetPowerCck, 2351 AR5416_NUM_2G_CCK_TARGET_POWERS, 2352 &targetPowerCck, 4, false); 2353 ath9k_hw_get_legacy_target_powers(ah, chan, 2354 pEepData->calTargetPower2G, 2355 AR5416_NUM_2G_20_TARGET_POWERS, 2356 &targetPowerOfdm, 4, false); 2357 ath9k_hw_get_target_powers(ah, chan, 2358 pEepData->calTargetPower2GHT20, 2359 AR5416_NUM_2G_20_TARGET_POWERS, 2360 &targetPowerHt20, 8, false); 2361 2362 if (IS_CHAN_HT40(chan)) { 2363 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 2364 ath9k_hw_get_target_powers(ah, chan, 2365 pEepData->calTargetPower2GHT40, 2366 AR5416_NUM_2G_40_TARGET_POWERS, 2367 &targetPowerHt40, 8, true); 2368 ath9k_hw_get_legacy_target_powers(ah, chan, 2369 pEepData->calTargetPowerCck, 2370 AR5416_NUM_2G_CCK_TARGET_POWERS, 2371 &targetPowerCckExt, 4, true); 2372 ath9k_hw_get_legacy_target_powers(ah, chan, 2373 pEepData->calTargetPower2G, 2374 AR5416_NUM_2G_20_TARGET_POWERS, 2375 &targetPowerOfdmExt, 4, true); 2376 } 2377 } else { 2378 numCtlModes = ARRAY_SIZE(ctlModesFor11a) - 2379 SUB_NUM_CTL_MODES_AT_5G_40; 2380 pCtlMode = ctlModesFor11a; 2381 2382 ath9k_hw_get_legacy_target_powers(ah, chan, 2383 pEepData->calTargetPower5G, 2384 AR5416_NUM_5G_20_TARGET_POWERS, 2385 &targetPowerOfdm, 4, false); 2386 ath9k_hw_get_target_powers(ah, chan, 2387 pEepData->calTargetPower5GHT20, 2388 AR5416_NUM_5G_20_TARGET_POWERS, 2389 &targetPowerHt20, 8, false); 2390 2391 if (IS_CHAN_HT40(chan)) { 2392 numCtlModes = ARRAY_SIZE(ctlModesFor11a); 2393 ath9k_hw_get_target_powers(ah, chan, 2394 pEepData->calTargetPower5GHT40, 2395 AR5416_NUM_5G_40_TARGET_POWERS, 2396 &targetPowerHt40, 8, true); 2397 ath9k_hw_get_legacy_target_powers(ah, chan, 2398 pEepData->calTargetPower5G, 2399 AR5416_NUM_5G_20_TARGET_POWERS, 2400 &targetPowerOfdmExt, 4, true); 2401 } 2402 } 2403 2404 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 2405 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 2406 (pCtlMode[ctlMode] == CTL_2GHT40); 2407 if (isHt40CtlMode) 2408 freq = centers.synth_center; 2409 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 2410 freq = centers.ext_center; 2411 else 2412 freq = centers.ctl_center; 2413 2414 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 2415 ah->eep_ops->get_eeprom_rev(ah) <= 2) 2416 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 2417 2418 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 2419 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " 2420 "EXT_ADDITIVE %d\n", 2421 ctlMode, numCtlModes, isHt40CtlMode, 2422 (pCtlMode[ctlMode] & EXT_ADDITIVE)); 2423 2424 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 2425 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 2426 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " 2427 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " 2428 "chan %d\n", 2429 i, cfgCtl, pCtlMode[ctlMode], 2430 pEepData->ctlIndex[i], chan->channel); 2431 2432 if ((((cfgCtl & ~CTL_MODE_M) | 2433 (pCtlMode[ctlMode] & CTL_MODE_M)) == 2434 pEepData->ctlIndex[i]) || 2435 (((cfgCtl & ~CTL_MODE_M) | 2436 (pCtlMode[ctlMode] & CTL_MODE_M)) == 2437 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { 2438 rep = &(pEepData->ctlData[i]); 2439 2440 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq, 2441 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1], 2442 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); 2443 2444 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 2445 " MATCH-EE_IDX %d: ch %d is2 %d " 2446 "2xMinEdge %d chainmask %d chains %d\n", 2447 i, freq, IS_CHAN_2GHZ(chan), 2448 twiceMinEdgePower, tx_chainmask, 2449 ar5416_get_ntxchains 2450 (tx_chainmask)); 2451 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 2452 twiceMaxEdgePower = min(twiceMaxEdgePower, 2453 twiceMinEdgePower); 2454 } else { 2455 twiceMaxEdgePower = twiceMinEdgePower; 2456 break; 2457 } 2458 } 2459 } 2460 2461 minCtlPower = min(twiceMaxEdgePower, scaledPower); 2462 2463 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 2464 " SEL-Min ctlMode %d pCtlMode %d " 2465 "2xMaxEdge %d sP %d minCtlPwr %d\n", 2466 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, 2467 scaledPower, minCtlPower); 2468 2469 switch (pCtlMode[ctlMode]) { 2470 case CTL_11B: 2471 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { 2472 targetPowerCck.tPow2x[i] = 2473 min((u16)targetPowerCck.tPow2x[i], 2474 minCtlPower); 2475 } 2476 break; 2477 case CTL_11A: 2478 case CTL_11G: 2479 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { 2480 targetPowerOfdm.tPow2x[i] = 2481 min((u16)targetPowerOfdm.tPow2x[i], 2482 minCtlPower); 2483 } 2484 break; 2485 case CTL_5GHT20: 2486 case CTL_2GHT20: 2487 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { 2488 targetPowerHt20.tPow2x[i] = 2489 min((u16)targetPowerHt20.tPow2x[i], 2490 minCtlPower); 2491 } 2492 break; 2493 case CTL_11B_EXT: 2494 targetPowerCckExt.tPow2x[0] = min((u16) 2495 targetPowerCckExt.tPow2x[0], 2496 minCtlPower); 2497 break; 2498 case CTL_11A_EXT: 2499 case CTL_11G_EXT: 2500 targetPowerOfdmExt.tPow2x[0] = min((u16) 2501 targetPowerOfdmExt.tPow2x[0], 2502 minCtlPower); 2503 break; 2504 case CTL_5GHT40: 2505 case CTL_2GHT40: 2506 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 2507 targetPowerHt40.tPow2x[i] = 2508 min((u16)targetPowerHt40.tPow2x[i], 2509 minCtlPower); 2510 } 2511 break; 2512 default: 2513 break; 2514 } 2515 } 2516 2517 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = 2518 ratesArray[rate18mb] = ratesArray[rate24mb] = 2519 targetPowerOfdm.tPow2x[0]; 2520 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 2521 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 2522 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 2523 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 2524 2525 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 2526 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 2527 2528 if (IS_CHAN_2GHZ(chan)) { 2529 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 2530 ratesArray[rate2s] = ratesArray[rate2l] = 2531 targetPowerCck.tPow2x[1]; 2532 ratesArray[rate5_5s] = ratesArray[rate5_5l] = 2533 targetPowerCck.tPow2x[2]; 2534 ; 2535 ratesArray[rate11s] = ratesArray[rate11l] = 2536 targetPowerCck.tPow2x[3]; 2537 ; 2538 } 2539 if (IS_CHAN_HT40(chan)) { 2540 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 2541 ratesArray[rateHt40_0 + i] = 2542 targetPowerHt40.tPow2x[i]; 2543 } 2544 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 2545 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 2546 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 2547 if (IS_CHAN_2GHZ(chan)) { 2548 ratesArray[rateExtCck] = 2549 targetPowerCckExt.tPow2x[0]; 2550 } 2551 } 2552 return true; 2553} 2554 2555static int ath9k_hw_def_set_txpower(struct ath_hw *ah, 2556 struct ath9k_channel *chan, 2557 u16 cfgCtl, 2558 u8 twiceAntennaReduction, 2559 u8 twiceMaxRegulatoryPower, 2560 u8 powerLimit) 2561{ 2562#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) 2563 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 2564 struct modal_eep_header *pModal = 2565 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); 2566 int16_t ratesArray[Ar5416RateSize]; 2567 int16_t txPowerIndexOffset = 0; 2568 u8 ht40PowerIncForPdadc = 2; 2569 int i, cck_ofdm_delta = 0; 2570 2571 memset(ratesArray, 0, sizeof(ratesArray)); 2572 2573 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 2574 AR5416_EEP_MINOR_VER_2) { 2575 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 2576 } 2577 2578 if (!ath9k_hw_set_def_power_per_rate_table(ah, chan, 2579 &ratesArray[0], cfgCtl, 2580 twiceAntennaReduction, 2581 twiceMaxRegulatoryPower, 2582 powerLimit)) { 2583 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2584 "ath9k_hw_set_txpower: unable to set " 2585 "tx power per rate table\n"); 2586 return -EIO; 2587 } 2588 2589 if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) { 2590 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2591 "ath9k_hw_set_txpower: unable to set power table\n"); 2592 return -EIO; 2593 } 2594 2595 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 2596 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 2597 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 2598 ratesArray[i] = AR5416_MAX_RATE_POWER; 2599 } 2600 2601 if (AR_SREV_9280_10_OR_LATER(ah)) { 2602 for (i = 0; i < Ar5416RateSize; i++) 2603 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; 2604 } 2605 2606 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 2607 ATH9K_POW_SM(ratesArray[rate18mb], 24) 2608 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 2609 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 2610 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 2611 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 2612 ATH9K_POW_SM(ratesArray[rate54mb], 24) 2613 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 2614 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 2615 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 2616 2617 if (IS_CHAN_2GHZ(chan)) { 2618 if (OLC_FOR_AR9280_20_LATER) { 2619 cck_ofdm_delta = 2; 2620 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 2621 ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24) 2622 | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16) 2623 | ATH9K_POW_SM(ratesArray[rateXr], 8) 2624 | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0)); 2625 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 2626 ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24) 2627 | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16) 2628 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8) 2629 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0)); 2630 } else { 2631 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 2632 ATH9K_POW_SM(ratesArray[rate2s], 24) 2633 | ATH9K_POW_SM(ratesArray[rate2l], 16) 2634 | ATH9K_POW_SM(ratesArray[rateXr], 8) 2635 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 2636 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 2637 ATH9K_POW_SM(ratesArray[rate11s], 24) 2638 | ATH9K_POW_SM(ratesArray[rate11l], 16) 2639 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 2640 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 2641 } 2642 } 2643 2644 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 2645 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 2646 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 2647 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 2648 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 2649 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 2650 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 2651 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 2652 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 2653 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 2654 2655 if (IS_CHAN_HT40(chan)) { 2656 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 2657 ATH9K_POW_SM(ratesArray[rateHt40_3] + 2658 ht40PowerIncForPdadc, 24) 2659 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 2660 ht40PowerIncForPdadc, 16) 2661 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 2662 ht40PowerIncForPdadc, 8) 2663 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 2664 ht40PowerIncForPdadc, 0)); 2665 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 2666 ATH9K_POW_SM(ratesArray[rateHt40_7] + 2667 ht40PowerIncForPdadc, 24) 2668 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 2669 ht40PowerIncForPdadc, 16) 2670 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 2671 ht40PowerIncForPdadc, 8) 2672 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 2673 ht40PowerIncForPdadc, 0)); 2674 if (OLC_FOR_AR9280_20_LATER) { 2675 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 2676 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 2677 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16) 2678 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 2679 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0)); 2680 } else { 2681 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 2682 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 2683 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 2684 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 2685 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 2686 } 2687 } 2688 2689 REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 2690 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) 2691 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); 2692 2693 i = rate6mb; 2694 2695 if (IS_CHAN_HT40(chan)) 2696 i = rateHt40_0; 2697 else if (IS_CHAN_HT20(chan)) 2698 i = rateHt20_0; 2699 2700 if (AR_SREV_9280_10_OR_LATER(ah)) 2701 ah->regulatory.max_power_level = 2702 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; 2703 else 2704 ah->regulatory.max_power_level = ratesArray[i]; 2705 2706 switch(ar5416_get_ntxchains(ah->txchainmask)) { 2707 case 1: 2708 break; 2709 case 2: 2710 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; 2711 break; 2712 case 3: 2713 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; 2714 break; 2715 default: 2716 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2717 "Invalid chainmask configuration\n"); 2718 break; 2719 } 2720 2721 return 0; 2722} 2723 2724static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, 2725 enum ieee80211_band freq_band) 2726{ 2727 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 2728 struct modal_eep_header *pModal = 2729 &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]); 2730 struct base_eep_header *pBase = &eep->baseEepHeader; 2731 u8 num_ant_config; 2732 2733 num_ant_config = 1; 2734 2735 if (pBase->version >= 0x0E0D) 2736 if (pModal->useAnt1) 2737 num_ant_config += 1; 2738 2739 return num_ant_config; 2740} 2741 2742static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah, 2743 struct ath9k_channel *chan) 2744{ 2745 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 2746 struct modal_eep_header *pModal = 2747 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 2748 2749 return pModal->antCtrlCommon & 0xFFFF; 2750} 2751 2752static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 2753{ 2754#define EEP_DEF_SPURCHAN \ 2755 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan) 2756 2757 u16 spur_val = AR_NO_SPUR; 2758 2759 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 2760 "Getting spur idx %d is2Ghz. %d val %x\n", 2761 i, is2GHz, ah->config.spurchans[i][is2GHz]); 2762 2763 switch (ah->config.spurmode) { 2764 case SPUR_DISABLE: 2765 break; 2766 case SPUR_ENABLE_IOCTL: 2767 spur_val = ah->config.spurchans[i][is2GHz]; 2768 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 2769 "Getting spur val from new loc. %d\n", spur_val); 2770 break; 2771 case SPUR_ENABLE_EEPROM: 2772 spur_val = EEP_DEF_SPURCHAN; 2773 break; 2774 } 2775 2776 return spur_val; 2777 2778#undef EEP_DEF_SPURCHAN 2779} 2780 2781static struct eeprom_ops eep_def_ops = { 2782 .check_eeprom = ath9k_hw_def_check_eeprom, 2783 .get_eeprom = ath9k_hw_def_get_eeprom, 2784 .fill_eeprom = ath9k_hw_def_fill_eeprom, 2785 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver, 2786 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev, 2787 .get_num_ant_config = ath9k_hw_def_get_num_ant_config, 2788 .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg, 2789 .set_board_values = ath9k_hw_def_set_board_values, 2790 .set_addac = ath9k_hw_def_set_addac, 2791 .set_txpower = ath9k_hw_def_set_txpower, 2792 .get_spur_channel = ath9k_hw_def_get_spur_channel 2793}; 2794 2795int ath9k_hw_eeprom_attach(struct ath_hw *ah) 2796{ 2797 int status; 2798 2799 if (AR_SREV_9285(ah)) { 2800 ah->eep_map = EEP_MAP_4KBITS; 2801 ah->eep_ops = &eep_4k_ops; 2802 } else { 2803 ah->eep_map = EEP_MAP_DEFAULT; 2804 ah->eep_ops = &eep_def_ops; 2805 } 2806 2807 if (!ah->eep_ops->fill_eeprom(ah)) 2808 return -EIO; 2809 2810 status = ah->eep_ops->check_eeprom(ah); 2811 2812 return status; 2813}