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 19 static 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 36 static 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 45 static 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 62 static 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 91 static 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 98 static 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 127 static 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, ¢ers); 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 182 static 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, ¢ers); 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 218 static 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 245 static 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, ¢ers); 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 300 static 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 332 static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) 333 { 334 return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF); 335 } 336 337 static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) 338 { 339 return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF); 340 } 341 342 static 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 368 static 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 486 static 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 529 static 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, ¢ers); 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 697 static void 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_EEPROM, 787 "PDADC (%d,%4x): %4.4x %8.8x\n", 788 i, regChainOffset, regOffset, 789 reg32); 790 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 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 810 static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, 811 struct ath9k_channel *chan, 812 int16_t *ratesArray, 813 u16 cfgCtl, 814 u16 AntennaReduction, 815 u16 twiceMaxRegulatoryPower, 816 u16 powerLimit) 817 { 818 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 819 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 820 static const u16 tpScaleReductionTable[5] = 821 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 822 823 int i; 824 int16_t twiceLargestAntenna; 825 struct cal_ctl_data_4k *rep; 826 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 827 0, { 0, 0, 0, 0} 828 }; 829 struct cal_target_power_leg targetPowerOfdmExt = { 830 0, { 0, 0, 0, 0} }, targetPowerCckExt = { 831 0, { 0, 0, 0, 0 } 832 }; 833 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 834 0, {0, 0, 0, 0} 835 }; 836 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 837 u16 ctlModesFor11g[] = 838 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, 839 CTL_2GHT40 840 }; 841 u16 numCtlModes, *pCtlMode, ctlMode, freq; 842 struct chan_centers centers; 843 int tx_chainmask; 844 u16 twiceMinEdgePower; 845 846 tx_chainmask = ah->txchainmask; 847 848 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 849 850 twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0]; 851 852 twiceLargestAntenna = (int16_t)min(AntennaReduction - 853 twiceLargestAntenna, 0); 854 855 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 856 857 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) { 858 maxRegAllowedPower -= 859 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); 860 } 861 862 scaledPower = min(powerLimit, maxRegAllowedPower); 863 scaledPower = max((u16)0, scaledPower); 864 865 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 866 pCtlMode = ctlModesFor11g; 867 868 ath9k_hw_get_legacy_target_powers(ah, chan, 869 pEepData->calTargetPowerCck, 870 AR5416_NUM_2G_CCK_TARGET_POWERS, 871 &targetPowerCck, 4, false); 872 ath9k_hw_get_legacy_target_powers(ah, chan, 873 pEepData->calTargetPower2G, 874 AR5416_NUM_2G_20_TARGET_POWERS, 875 &targetPowerOfdm, 4, false); 876 ath9k_hw_get_target_powers(ah, chan, 877 pEepData->calTargetPower2GHT20, 878 AR5416_NUM_2G_20_TARGET_POWERS, 879 &targetPowerHt20, 8, false); 880 881 if (IS_CHAN_HT40(chan)) { 882 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 883 ath9k_hw_get_target_powers(ah, chan, 884 pEepData->calTargetPower2GHT40, 885 AR5416_NUM_2G_40_TARGET_POWERS, 886 &targetPowerHt40, 8, true); 887 ath9k_hw_get_legacy_target_powers(ah, chan, 888 pEepData->calTargetPowerCck, 889 AR5416_NUM_2G_CCK_TARGET_POWERS, 890 &targetPowerCckExt, 4, true); 891 ath9k_hw_get_legacy_target_powers(ah, chan, 892 pEepData->calTargetPower2G, 893 AR5416_NUM_2G_20_TARGET_POWERS, 894 &targetPowerOfdmExt, 4, true); 895 } 896 897 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 898 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 899 (pCtlMode[ctlMode] == CTL_2GHT40); 900 if (isHt40CtlMode) 901 freq = centers.synth_center; 902 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 903 freq = centers.ext_center; 904 else 905 freq = centers.ctl_center; 906 907 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 908 ah->eep_ops->get_eeprom_rev(ah) <= 2) 909 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 910 911 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 912 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " 913 "EXT_ADDITIVE %d\n", 914 ctlMode, numCtlModes, isHt40CtlMode, 915 (pCtlMode[ctlMode] & EXT_ADDITIVE)); 916 917 for (i = 0; (i < AR5416_NUM_CTLS) && 918 pEepData->ctlIndex[i]; i++) { 919 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 920 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " 921 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " 922 "chan %d\n", 923 i, cfgCtl, pCtlMode[ctlMode], 924 pEepData->ctlIndex[i], chan->channel); 925 926 if ((((cfgCtl & ~CTL_MODE_M) | 927 (pCtlMode[ctlMode] & CTL_MODE_M)) == 928 pEepData->ctlIndex[i]) || 929 (((cfgCtl & ~CTL_MODE_M) | 930 (pCtlMode[ctlMode] & CTL_MODE_M)) == 931 ((pEepData->ctlIndex[i] & CTL_MODE_M) | 932 SD_NO_CTL))) { 933 rep = &(pEepData->ctlData[i]); 934 935 twiceMinEdgePower = 936 ath9k_hw_get_max_edge_power(freq, 937 rep->ctlEdges[ar5416_get_ntxchains 938 (tx_chainmask) - 1], 939 IS_CHAN_2GHZ(chan), 940 AR5416_EEP4K_NUM_BAND_EDGES); 941 942 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 943 " MATCH-EE_IDX %d: ch %d is2 %d " 944 "2xMinEdge %d chainmask %d chains %d\n", 945 i, freq, IS_CHAN_2GHZ(chan), 946 twiceMinEdgePower, tx_chainmask, 947 ar5416_get_ntxchains 948 (tx_chainmask)); 949 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 950 twiceMaxEdgePower = 951 min(twiceMaxEdgePower, 952 twiceMinEdgePower); 953 } else { 954 twiceMaxEdgePower = twiceMinEdgePower; 955 break; 956 } 957 } 958 } 959 960 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 961 962 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 963 " SEL-Min ctlMode %d pCtlMode %d " 964 "2xMaxEdge %d sP %d minCtlPwr %d\n", 965 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, 966 scaledPower, minCtlPower); 967 968 switch (pCtlMode[ctlMode]) { 969 case CTL_11B: 970 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); 971 i++) { 972 targetPowerCck.tPow2x[i] = 973 min((u16)targetPowerCck.tPow2x[i], 974 minCtlPower); 975 } 976 break; 977 case CTL_11G: 978 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); 979 i++) { 980 targetPowerOfdm.tPow2x[i] = 981 min((u16)targetPowerOfdm.tPow2x[i], 982 minCtlPower); 983 } 984 break; 985 case CTL_2GHT20: 986 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); 987 i++) { 988 targetPowerHt20.tPow2x[i] = 989 min((u16)targetPowerHt20.tPow2x[i], 990 minCtlPower); 991 } 992 break; 993 case CTL_11B_EXT: 994 targetPowerCckExt.tPow2x[0] = min((u16) 995 targetPowerCckExt.tPow2x[0], 996 minCtlPower); 997 break; 998 case CTL_11G_EXT: 999 targetPowerOfdmExt.tPow2x[0] = min((u16) 1000 targetPowerOfdmExt.tPow2x[0], 1001 minCtlPower); 1002 break; 1003 case CTL_2GHT40: 1004 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); 1005 i++) { 1006 targetPowerHt40.tPow2x[i] = 1007 min((u16)targetPowerHt40.tPow2x[i], 1008 minCtlPower); 1009 } 1010 break; 1011 default: 1012 break; 1013 } 1014 } 1015 1016 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = 1017 ratesArray[rate18mb] = ratesArray[rate24mb] = 1018 targetPowerOfdm.tPow2x[0]; 1019 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 1020 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 1021 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 1022 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 1023 1024 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 1025 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 1026 1027 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 1028 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 1029 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 1030 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 1031 1032 if (IS_CHAN_HT40(chan)) { 1033 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 1034 ratesArray[rateHt40_0 + i] = 1035 targetPowerHt40.tPow2x[i]; 1036 } 1037 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 1038 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 1039 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 1040 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 1041 } 1042 } 1043 1044 static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, 1045 struct ath9k_channel *chan, 1046 u16 cfgCtl, 1047 u8 twiceAntennaReduction, 1048 u8 twiceMaxRegulatoryPower, 1049 u8 powerLimit) 1050 { 1051 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 1052 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 1053 int16_t ratesArray[Ar5416RateSize]; 1054 int16_t txPowerIndexOffset = 0; 1055 u8 ht40PowerIncForPdadc = 2; 1056 int i; 1057 1058 memset(ratesArray, 0, sizeof(ratesArray)); 1059 1060 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1061 AR5416_EEP_MINOR_VER_2) { 1062 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1063 } 1064 1065 ath9k_hw_set_4k_power_per_rate_table(ah, chan, 1066 &ratesArray[0], cfgCtl, 1067 twiceAntennaReduction, 1068 twiceMaxRegulatoryPower, 1069 powerLimit); 1070 1071 ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset); 1072 1073 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1074 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1075 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 1076 ratesArray[i] = AR5416_MAX_RATE_POWER; 1077 } 1078 1079 if (AR_SREV_9280_10_OR_LATER(ah)) { 1080 for (i = 0; i < Ar5416RateSize; i++) 1081 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; 1082 } 1083 1084 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1085 ATH9K_POW_SM(ratesArray[rate18mb], 24) 1086 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 1087 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 1088 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 1089 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 1090 ATH9K_POW_SM(ratesArray[rate54mb], 24) 1091 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 1092 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 1093 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 1094 1095 if (IS_CHAN_2GHZ(chan)) { 1096 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1097 ATH9K_POW_SM(ratesArray[rate2s], 24) 1098 | ATH9K_POW_SM(ratesArray[rate2l], 16) 1099 | ATH9K_POW_SM(ratesArray[rateXr], 8) 1100 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 1101 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 1102 ATH9K_POW_SM(ratesArray[rate11s], 24) 1103 | ATH9K_POW_SM(ratesArray[rate11l], 16) 1104 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 1105 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 1106 } 1107 1108 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 1109 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 1110 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 1111 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 1112 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 1113 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 1114 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 1115 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 1116 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 1117 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 1118 1119 if (IS_CHAN_HT40(chan)) { 1120 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 1121 ATH9K_POW_SM(ratesArray[rateHt40_3] + 1122 ht40PowerIncForPdadc, 24) 1123 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 1124 ht40PowerIncForPdadc, 16) 1125 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 1126 ht40PowerIncForPdadc, 8) 1127 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 1128 ht40PowerIncForPdadc, 0)); 1129 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 1130 ATH9K_POW_SM(ratesArray[rateHt40_7] + 1131 ht40PowerIncForPdadc, 24) 1132 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 1133 ht40PowerIncForPdadc, 16) 1134 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 1135 ht40PowerIncForPdadc, 8) 1136 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 1137 ht40PowerIncForPdadc, 0)); 1138 1139 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1140 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 1141 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 1142 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 1143 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 1144 } 1145 1146 i = rate6mb; 1147 1148 if (IS_CHAN_HT40(chan)) 1149 i = rateHt40_0; 1150 else if (IS_CHAN_HT20(chan)) 1151 i = rateHt20_0; 1152 1153 if (AR_SREV_9280_10_OR_LATER(ah)) 1154 ah->regulatory.max_power_level = 1155 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; 1156 else 1157 ah->regulatory.max_power_level = ratesArray[i]; 1158 1159 } 1160 1161 static void ath9k_hw_4k_set_addac(struct ath_hw *ah, 1162 struct ath9k_channel *chan) 1163 { 1164 struct modal_eep_4k_header *pModal; 1165 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 1166 u8 biaslevel; 1167 1168 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) 1169 return; 1170 1171 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) 1172 return; 1173 1174 pModal = &eep->modalHeader; 1175 1176 if (pModal->xpaBiasLvl != 0xff) { 1177 biaslevel = pModal->xpaBiasLvl; 1178 INI_RA(&ah->iniAddac, 7, 1) = 1179 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; 1180 } 1181 } 1182 1183 static void ath9k_hw_4k_set_gain(struct ath_hw *ah, 1184 struct modal_eep_4k_header *pModal, 1185 struct ar5416_eeprom_4k *eep, 1186 u8 txRxAttenLocal, int regChainOffset) 1187 { 1188 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, 1189 pModal->antCtrlChain[0]); 1190 1191 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1192 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & 1193 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1194 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1195 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1196 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1197 1198 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1199 AR5416_EEP_MINOR_VER_3) { 1200 txRxAttenLocal = pModal->txRxAttenCh[0]; 1201 1202 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1203 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]); 1204 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1205 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 1206 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1207 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 1208 pModal->xatten2Margin[0]); 1209 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1210 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); 1211 } 1212 1213 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1214 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1215 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1216 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 1217 1218 if (AR_SREV_9285_11(ah)) 1219 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); 1220 } 1221 1222 static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, 1223 struct ath9k_channel *chan) 1224 { 1225 struct modal_eep_4k_header *pModal; 1226 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 1227 u8 txRxAttenLocal; 1228 u8 ob[5], db1[5], db2[5]; 1229 u8 ant_div_control1, ant_div_control2; 1230 u32 regVal; 1231 1232 pModal = &eep->modalHeader; 1233 txRxAttenLocal = 23; 1234 1235 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1236 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); 1237 1238 /* Single chain for 4K EEPROM*/ 1239 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0); 1240 1241 /* Initialize Ant Diversity settings from EEPROM */ 1242 if (pModal->version == 3) { 1243 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf); 1244 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf); 1245 regVal = REG_READ(ah, 0x99ac); 1246 regVal &= (~(0x7f000000)); 1247 regVal |= ((ant_div_control1 & 0x1) << 24); 1248 regVal |= (((ant_div_control1 >> 1) & 0x1) << 29); 1249 regVal |= (((ant_div_control1 >> 2) & 0x1) << 30); 1250 regVal |= ((ant_div_control2 & 0x3) << 25); 1251 regVal |= (((ant_div_control2 >> 2) & 0x3) << 27); 1252 REG_WRITE(ah, 0x99ac, regVal); 1253 regVal = REG_READ(ah, 0x99ac); 1254 regVal = REG_READ(ah, 0xa208); 1255 regVal &= (~(0x1 << 13)); 1256 regVal |= (((ant_div_control1 >> 3) & 0x1) << 13); 1257 REG_WRITE(ah, 0xa208, regVal); 1258 regVal = REG_READ(ah, 0xa208); 1259 } 1260 1261 if (pModal->version >= 2) { 1262 ob[0] = (pModal->ob_01 & 0xf); 1263 ob[1] = (pModal->ob_01 >> 4) & 0xf; 1264 ob[2] = (pModal->ob_234 & 0xf); 1265 ob[3] = ((pModal->ob_234 >> 4) & 0xf); 1266 ob[4] = ((pModal->ob_234 >> 8) & 0xf); 1267 1268 db1[0] = (pModal->db1_01 & 0xf); 1269 db1[1] = ((pModal->db1_01 >> 4) & 0xf); 1270 db1[2] = (pModal->db1_234 & 0xf); 1271 db1[3] = ((pModal->db1_234 >> 4) & 0xf); 1272 db1[4] = ((pModal->db1_234 >> 8) & 0xf); 1273 1274 db2[0] = (pModal->db2_01 & 0xf); 1275 db2[1] = ((pModal->db2_01 >> 4) & 0xf); 1276 db2[2] = (pModal->db2_234 & 0xf); 1277 db2[3] = ((pModal->db2_234 >> 4) & 0xf); 1278 db2[4] = ((pModal->db2_234 >> 8) & 0xf); 1279 1280 } else if (pModal->version == 1) { 1281 ob[0] = (pModal->ob_01 & 0xf); 1282 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf; 1283 db1[0] = (pModal->db1_01 & 0xf); 1284 db1[1] = db1[2] = db1[3] = 1285 db1[4] = ((pModal->db1_01 >> 4) & 0xf); 1286 db2[0] = (pModal->db2_01 & 0xf); 1287 db2[1] = db2[2] = db2[3] = 1288 db2[4] = ((pModal->db2_01 >> 4) & 0xf); 1289 } else { 1290 int i; 1291 for (i = 0; i < 5; i++) { 1292 ob[i] = pModal->ob_01; 1293 db1[i] = pModal->db1_01; 1294 db2[i] = pModal->db1_01; 1295 } 1296 } 1297 1298 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1299 AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]); 1300 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1301 AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]); 1302 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1303 AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]); 1304 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1305 AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]); 1306 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1307 AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]); 1308 1309 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1310 AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]); 1311 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1312 AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]); 1313 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1314 AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]); 1315 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1316 AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]); 1317 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1318 AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]); 1319 1320 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1321 AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]); 1322 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1323 AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]); 1324 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1325 AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]); 1326 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1327 AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]); 1328 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1329 AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]); 1330 1331 1332 if (AR_SREV_9285_11(ah)) 1333 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); 1334 1335 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 1336 pModal->switchSettling); 1337 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 1338 pModal->adcDesiredSize); 1339 1340 REG_WRITE(ah, AR_PHY_RF_CTL4, 1341 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | 1342 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | 1343 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | 1344 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1345 1346 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 1347 pModal->txEndToRxOn); 1348 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1349 pModal->thresh62); 1350 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 1351 pModal->thresh62); 1352 1353 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1354 AR5416_EEP_MINOR_VER_2) { 1355 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, 1356 pModal->txFrameToDataStart); 1357 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, 1358 pModal->txFrameToPaOn); 1359 } 1360 1361 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1362 AR5416_EEP_MINOR_VER_3) { 1363 if (IS_CHAN_HT40(chan)) 1364 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1365 AR_PHY_SETTLING_SWITCH, 1366 pModal->swSettleHt40); 1367 } 1368 } 1369 1370 static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, 1371 struct ath9k_channel *chan) 1372 { 1373 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 1374 struct modal_eep_4k_header *pModal = &eep->modalHeader; 1375 1376 return pModal->antCtrlCommon & 0xFFFF; 1377 } 1378 1379 static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah, 1380 enum ieee80211_band freq_band) 1381 { 1382 return 1; 1383 } 1384 1385 static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1386 { 1387 #define EEP_MAP4K_SPURCHAN \ 1388 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan) 1389 1390 u16 spur_val = AR_NO_SPUR; 1391 1392 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 1393 "Getting spur idx %d is2Ghz. %d val %x\n", 1394 i, is2GHz, ah->config.spurchans[i][is2GHz]); 1395 1396 switch (ah->config.spurmode) { 1397 case SPUR_DISABLE: 1398 break; 1399 case SPUR_ENABLE_IOCTL: 1400 spur_val = ah->config.spurchans[i][is2GHz]; 1401 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 1402 "Getting spur val from new loc. %d\n", spur_val); 1403 break; 1404 case SPUR_ENABLE_EEPROM: 1405 spur_val = EEP_MAP4K_SPURCHAN; 1406 break; 1407 } 1408 1409 return spur_val; 1410 1411 #undef EEP_MAP4K_SPURCHAN 1412 } 1413 1414 static struct eeprom_ops eep_4k_ops = { 1415 .check_eeprom = ath9k_hw_4k_check_eeprom, 1416 .get_eeprom = ath9k_hw_4k_get_eeprom, 1417 .fill_eeprom = ath9k_hw_4k_fill_eeprom, 1418 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, 1419 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, 1420 .get_num_ant_config = ath9k_hw_4k_get_num_ant_config, 1421 .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg, 1422 .set_board_values = ath9k_hw_4k_set_board_values, 1423 .set_addac = ath9k_hw_4k_set_addac, 1424 .set_txpower = ath9k_hw_4k_set_txpower, 1425 .get_spur_channel = ath9k_hw_4k_get_spur_channel 1426 }; 1427 1428 /************************************************/ 1429 /* EEPROM Operations for non-4K (Default) cards */ 1430 /************************************************/ 1431 1432 static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah) 1433 { 1434 return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF); 1435 } 1436 1437 static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah) 1438 { 1439 return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF); 1440 } 1441 1442 static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) 1443 { 1444 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) 1445 u16 *eep_data = (u16 *)&ah->eeprom.def; 1446 int addr, ar5416_eep_start_loc = 0x100; 1447 1448 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { 1449 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, 1450 eep_data)) { 1451 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1452 "Unable to read eeprom region\n"); 1453 return false; 1454 } 1455 eep_data++; 1456 } 1457 return true; 1458 #undef SIZE_EEPROM_DEF 1459 } 1460 1461 static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) 1462 { 1463 struct ar5416_eeprom_def *eep = 1464 (struct ar5416_eeprom_def *) &ah->eeprom.def; 1465 u16 *eepdata, temp, magic, magic2; 1466 u32 sum = 0, el; 1467 bool need_swap = false; 1468 int i, addr, size; 1469 1470 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { 1471 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n"); 1472 return false; 1473 } 1474 1475 if (!ath9k_hw_use_flash(ah)) { 1476 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1477 "Read Magic = 0x%04X\n", magic); 1478 1479 if (magic != AR5416_EEPROM_MAGIC) { 1480 magic2 = swab16(magic); 1481 1482 if (magic2 == AR5416_EEPROM_MAGIC) { 1483 size = sizeof(struct ar5416_eeprom_def); 1484 need_swap = true; 1485 eepdata = (u16 *) (&ah->eeprom); 1486 1487 for (addr = 0; addr < size / sizeof(u16); addr++) { 1488 temp = swab16(*eepdata); 1489 *eepdata = temp; 1490 eepdata++; 1491 } 1492 } else { 1493 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1494 "Invalid EEPROM Magic. " 1495 "Endianness mismatch.\n"); 1496 return -EINVAL; 1497 } 1498 } 1499 } 1500 1501 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", 1502 need_swap ? "True" : "False"); 1503 1504 if (need_swap) 1505 el = swab16(ah->eeprom.def.baseEepHeader.length); 1506 else 1507 el = ah->eeprom.def.baseEepHeader.length; 1508 1509 if (el > sizeof(struct ar5416_eeprom_def)) 1510 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16); 1511 else 1512 el = el / sizeof(u16); 1513 1514 eepdata = (u16 *)(&ah->eeprom); 1515 1516 for (i = 0; i < el; i++) 1517 sum ^= *eepdata++; 1518 1519 if (need_swap) { 1520 u32 integer, j; 1521 u16 word; 1522 1523 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1524 "EEPROM Endianness is not native.. Changing.\n"); 1525 1526 word = swab16(eep->baseEepHeader.length); 1527 eep->baseEepHeader.length = word; 1528 1529 word = swab16(eep->baseEepHeader.checksum); 1530 eep->baseEepHeader.checksum = word; 1531 1532 word = swab16(eep->baseEepHeader.version); 1533 eep->baseEepHeader.version = word; 1534 1535 word = swab16(eep->baseEepHeader.regDmn[0]); 1536 eep->baseEepHeader.regDmn[0] = word; 1537 1538 word = swab16(eep->baseEepHeader.regDmn[1]); 1539 eep->baseEepHeader.regDmn[1] = word; 1540 1541 word = swab16(eep->baseEepHeader.rfSilent); 1542 eep->baseEepHeader.rfSilent = word; 1543 1544 word = swab16(eep->baseEepHeader.blueToothOptions); 1545 eep->baseEepHeader.blueToothOptions = word; 1546 1547 word = swab16(eep->baseEepHeader.deviceCap); 1548 eep->baseEepHeader.deviceCap = word; 1549 1550 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) { 1551 struct modal_eep_header *pModal = 1552 &eep->modalHeader[j]; 1553 integer = swab32(pModal->antCtrlCommon); 1554 pModal->antCtrlCommon = integer; 1555 1556 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1557 integer = swab32(pModal->antCtrlChain[i]); 1558 pModal->antCtrlChain[i] = integer; 1559 } 1560 1561 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 1562 word = swab16(pModal->spurChans[i].spurChan); 1563 pModal->spurChans[i].spurChan = word; 1564 } 1565 } 1566 } 1567 1568 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || 1569 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 1570 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1571 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 1572 sum, ah->eep_ops->get_eeprom_ver(ah)); 1573 return -EINVAL; 1574 } 1575 1576 return 0; 1577 } 1578 1579 static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, 1580 enum eeprom_param param) 1581 { 1582 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1583 struct modal_eep_header *pModal = eep->modalHeader; 1584 struct base_eep_header *pBase = &eep->baseEepHeader; 1585 1586 switch (param) { 1587 case EEP_NFTHRESH_5: 1588 return pModal[0].noiseFloorThreshCh[0]; 1589 case EEP_NFTHRESH_2: 1590 return pModal[1].noiseFloorThreshCh[0]; 1591 case AR_EEPROM_MAC(0): 1592 return pBase->macAddr[0] << 8 | pBase->macAddr[1]; 1593 case AR_EEPROM_MAC(1): 1594 return pBase->macAddr[2] << 8 | pBase->macAddr[3]; 1595 case AR_EEPROM_MAC(2): 1596 return pBase->macAddr[4] << 8 | pBase->macAddr[5]; 1597 case EEP_REG_0: 1598 return pBase->regDmn[0]; 1599 case EEP_REG_1: 1600 return pBase->regDmn[1]; 1601 case EEP_OP_CAP: 1602 return pBase->deviceCap; 1603 case EEP_OP_MODE: 1604 return pBase->opCapFlags; 1605 case EEP_RF_SILENT: 1606 return pBase->rfSilent; 1607 case EEP_OB_5: 1608 return pModal[0].ob; 1609 case EEP_DB_5: 1610 return pModal[0].db; 1611 case EEP_OB_2: 1612 return pModal[1].ob; 1613 case EEP_DB_2: 1614 return pModal[1].db; 1615 case EEP_MINOR_REV: 1616 return AR5416_VER_MASK; 1617 case EEP_TX_MASK: 1618 return pBase->txMask; 1619 case EEP_RX_MASK: 1620 return pBase->rxMask; 1621 case EEP_RXGAIN_TYPE: 1622 return pBase->rxGainType; 1623 case EEP_TXGAIN_TYPE: 1624 return pBase->txGainType; 1625 case EEP_OL_PWRCTRL: 1626 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 1627 return pBase->openLoopPwrCntl ? true : false; 1628 else 1629 return false; 1630 case EEP_RC_CHAIN_MASK: 1631 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 1632 return pBase->rcChainMask; 1633 else 1634 return 0; 1635 case EEP_DAC_HPWR_5G: 1636 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) 1637 return pBase->dacHiPwrMode_5G; 1638 else 1639 return 0; 1640 case EEP_FRAC_N_5G: 1641 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22) 1642 return pBase->frac_n_5g; 1643 else 1644 return 0; 1645 default: 1646 return 0; 1647 } 1648 } 1649 1650 static void ath9k_hw_def_set_gain(struct ath_hw *ah, 1651 struct modal_eep_header *pModal, 1652 struct ar5416_eeprom_def *eep, 1653 u8 txRxAttenLocal, int regChainOffset, int i) 1654 { 1655 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { 1656 txRxAttenLocal = pModal->txRxAttenCh[i]; 1657 1658 if (AR_SREV_9280_10_OR_LATER(ah)) { 1659 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1660 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 1661 pModal->bswMargin[i]); 1662 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1663 AR_PHY_GAIN_2GHZ_XATTEN1_DB, 1664 pModal->bswAtten[i]); 1665 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1666 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 1667 pModal->xatten2Margin[i]); 1668 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1669 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 1670 pModal->xatten2Db[i]); 1671 } else { 1672 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1673 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1674 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) 1675 | SM(pModal-> bswMargin[i], 1676 AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1677 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1678 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1679 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) 1680 | SM(pModal->bswAtten[i], 1681 AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1682 } 1683 } 1684 1685 if (AR_SREV_9280_10_OR_LATER(ah)) { 1686 REG_RMW_FIELD(ah, 1687 AR_PHY_RXGAIN + regChainOffset, 1688 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1689 REG_RMW_FIELD(ah, 1690 AR_PHY_RXGAIN + regChainOffset, 1691 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); 1692 } else { 1693 REG_WRITE(ah, 1694 AR_PHY_RXGAIN + regChainOffset, 1695 (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & 1696 ~AR_PHY_RXGAIN_TXRX_ATTEN) 1697 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN)); 1698 REG_WRITE(ah, 1699 AR_PHY_GAIN_2GHZ + regChainOffset, 1700 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1701 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) | 1702 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN)); 1703 } 1704 } 1705 1706 static void ath9k_hw_def_set_board_values(struct ath_hw *ah, 1707 struct ath9k_channel *chan) 1708 { 1709 struct modal_eep_header *pModal; 1710 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1711 int i, regChainOffset; 1712 u8 txRxAttenLocal; 1713 1714 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1715 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; 1716 1717 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1718 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); 1719 1720 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1721 if (AR_SREV_9280(ah)) { 1722 if (i >= 2) 1723 break; 1724 } 1725 1726 if (AR_SREV_5416_20_OR_LATER(ah) && 1727 (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) 1728 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1729 else 1730 regChainOffset = i * 0x1000; 1731 1732 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, 1733 pModal->antCtrlChain[i]); 1734 1735 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1736 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & 1737 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1738 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1739 SM(pModal->iqCalICh[i], 1740 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1741 SM(pModal->iqCalQCh[i], 1742 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1743 1744 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) 1745 ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal, 1746 regChainOffset, i); 1747 } 1748 1749 if (AR_SREV_9280_10_OR_LATER(ah)) { 1750 if (IS_CHAN_2GHZ(chan)) { 1751 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, 1752 AR_AN_RF2G1_CH0_OB, 1753 AR_AN_RF2G1_CH0_OB_S, 1754 pModal->ob); 1755 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, 1756 AR_AN_RF2G1_CH0_DB, 1757 AR_AN_RF2G1_CH0_DB_S, 1758 pModal->db); 1759 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1, 1760 AR_AN_RF2G1_CH1_OB, 1761 AR_AN_RF2G1_CH1_OB_S, 1762 pModal->ob_ch1); 1763 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1, 1764 AR_AN_RF2G1_CH1_DB, 1765 AR_AN_RF2G1_CH1_DB_S, 1766 pModal->db_ch1); 1767 } else { 1768 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0, 1769 AR_AN_RF5G1_CH0_OB5, 1770 AR_AN_RF5G1_CH0_OB5_S, 1771 pModal->ob); 1772 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0, 1773 AR_AN_RF5G1_CH0_DB5, 1774 AR_AN_RF5G1_CH0_DB5_S, 1775 pModal->db); 1776 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1, 1777 AR_AN_RF5G1_CH1_OB5, 1778 AR_AN_RF5G1_CH1_OB5_S, 1779 pModal->ob_ch1); 1780 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1, 1781 AR_AN_RF5G1_CH1_DB5, 1782 AR_AN_RF5G1_CH1_DB5_S, 1783 pModal->db_ch1); 1784 } 1785 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, 1786 AR_AN_TOP2_XPABIAS_LVL, 1787 AR_AN_TOP2_XPABIAS_LVL_S, 1788 pModal->xpaBiasLvl); 1789 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, 1790 AR_AN_TOP2_LOCALBIAS, 1791 AR_AN_TOP2_LOCALBIAS_S, 1792 pModal->local_bias); 1793 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, 1794 pModal->force_xpaon); 1795 } 1796 1797 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 1798 pModal->switchSettling); 1799 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 1800 pModal->adcDesiredSize); 1801 1802 if (!AR_SREV_9280_10_OR_LATER(ah)) 1803 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 1804 AR_PHY_DESIRED_SZ_PGA, 1805 pModal->pgaDesiredSize); 1806 1807 REG_WRITE(ah, AR_PHY_RF_CTL4, 1808 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 1809 | SM(pModal->txEndToXpaOff, 1810 AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 1811 | SM(pModal->txFrameToXpaOn, 1812 AR_PHY_RF_CTL4_FRAME_XPAA_ON) 1813 | SM(pModal->txFrameToXpaOn, 1814 AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1815 1816 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 1817 pModal->txEndToRxOn); 1818 1819 if (AR_SREV_9280_10_OR_LATER(ah)) { 1820 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1821 pModal->thresh62); 1822 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, 1823 AR_PHY_EXT_CCA0_THRESH62, 1824 pModal->thresh62); 1825 } else { 1826 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, 1827 pModal->thresh62); 1828 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, 1829 AR_PHY_EXT_CCA_THRESH62, 1830 pModal->thresh62); 1831 } 1832 1833 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) { 1834 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, 1835 AR_PHY_TX_END_DATA_START, 1836 pModal->txFrameToDataStart); 1837 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, 1838 pModal->txFrameToPaOn); 1839 } 1840 1841 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { 1842 if (IS_CHAN_HT40(chan)) 1843 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1844 AR_PHY_SETTLING_SWITCH, 1845 pModal->swSettleHt40); 1846 } 1847 1848 if (AR_SREV_9280_20_OR_LATER(ah) && 1849 AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) 1850 REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, 1851 AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, 1852 pModal->miscBits); 1853 1854 1855 if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { 1856 if (IS_CHAN_2GHZ(chan)) 1857 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 1858 eep->baseEepHeader.dacLpMode); 1859 else if (eep->baseEepHeader.dacHiPwrMode_5G) 1860 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); 1861 else 1862 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 1863 eep->baseEepHeader.dacLpMode); 1864 1865 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, 1866 pModal->miscBits >> 2); 1867 1868 REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, 1869 AR_PHY_TX_DESIRED_SCALE_CCK, 1870 eep->baseEepHeader.desiredScaleCCK); 1871 } 1872 } 1873 1874 static void ath9k_hw_def_set_addac(struct ath_hw *ah, 1875 struct ath9k_channel *chan) 1876 { 1877 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) 1878 struct modal_eep_header *pModal; 1879 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 1880 u8 biaslevel; 1881 1882 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) 1883 return; 1884 1885 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) 1886 return; 1887 1888 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1889 1890 if (pModal->xpaBiasLvl != 0xff) { 1891 biaslevel = pModal->xpaBiasLvl; 1892 } else { 1893 u16 resetFreqBin, freqBin, freqCount = 0; 1894 struct chan_centers centers; 1895 1896 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 1897 1898 resetFreqBin = FREQ2FBIN(centers.synth_center, 1899 IS_CHAN_2GHZ(chan)); 1900 freqBin = XPA_LVL_FREQ(0) & 0xff; 1901 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14); 1902 1903 freqCount++; 1904 1905 while (freqCount < 3) { 1906 if (XPA_LVL_FREQ(freqCount) == 0x0) 1907 break; 1908 1909 freqBin = XPA_LVL_FREQ(freqCount) & 0xff; 1910 if (resetFreqBin >= freqBin) 1911 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14); 1912 else 1913 break; 1914 freqCount++; 1915 } 1916 } 1917 1918 if (IS_CHAN_2GHZ(chan)) { 1919 INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac, 1920 7, 1) & (~0x18)) | biaslevel << 3; 1921 } else { 1922 INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac, 1923 6, 1) & (~0xc0)) | biaslevel << 6; 1924 } 1925 #undef XPA_LVL_FREQ 1926 } 1927 1928 static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, 1929 struct ath9k_channel *chan, 1930 struct cal_data_per_freq *pRawDataSet, 1931 u8 *bChans, u16 availPiers, 1932 u16 tPdGainOverlap, int16_t *pMinCalPower, 1933 u16 *pPdGainBoundaries, u8 *pPDADCValues, 1934 u16 numXpdGains) 1935 { 1936 int i, j, k; 1937 int16_t ss; 1938 u16 idxL = 0, idxR = 0, numPiers; 1939 static u8 vpdTableL[AR5416_NUM_PD_GAINS] 1940 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 1941 static u8 vpdTableR[AR5416_NUM_PD_GAINS] 1942 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 1943 static u8 vpdTableI[AR5416_NUM_PD_GAINS] 1944 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 1945 1946 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; 1947 u8 minPwrT4[AR5416_NUM_PD_GAINS]; 1948 u8 maxPwrT4[AR5416_NUM_PD_GAINS]; 1949 int16_t vpdStep; 1950 int16_t tmpVal; 1951 u16 sizeCurrVpdTable, maxIndex, tgtIndex; 1952 bool match; 1953 int16_t minDelta = 0; 1954 struct chan_centers centers; 1955 1956 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 1957 1958 for (numPiers = 0; numPiers < availPiers; numPiers++) { 1959 if (bChans[numPiers] == AR5416_BCHAN_UNUSED) 1960 break; 1961 } 1962 1963 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center, 1964 IS_CHAN_2GHZ(chan)), 1965 bChans, numPiers, &idxL, &idxR); 1966 1967 if (match) { 1968 for (i = 0; i < numXpdGains; i++) { 1969 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 1970 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 1971 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 1972 pRawDataSet[idxL].pwrPdg[i], 1973 pRawDataSet[idxL].vpdPdg[i], 1974 AR5416_PD_GAIN_ICEPTS, 1975 vpdTableI[i]); 1976 } 1977 } else { 1978 for (i = 0; i < numXpdGains; i++) { 1979 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 1980 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 1981 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 1982 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 1983 1984 minPwrT4[i] = max(pPwrL[0], pPwrR[0]); 1985 1986 maxPwrT4[i] = 1987 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], 1988 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); 1989 1990 1991 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 1992 pPwrL, pVpdL, 1993 AR5416_PD_GAIN_ICEPTS, 1994 vpdTableL[i]); 1995 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 1996 pPwrR, pVpdR, 1997 AR5416_PD_GAIN_ICEPTS, 1998 vpdTableR[i]); 1999 2000 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 2001 vpdTableI[i][j] = 2002 (u8)(ath9k_hw_interpolate((u16) 2003 FREQ2FBIN(centers. 2004 synth_center, 2005 IS_CHAN_2GHZ 2006 (chan)), 2007 bChans[idxL], bChans[idxR], 2008 vpdTableL[i][j], vpdTableR[i][j])); 2009 } 2010 } 2011 } 2012 2013 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 2014 2015 k = 0; 2016 2017 for (i = 0; i < numXpdGains; i++) { 2018 if (i == (numXpdGains - 1)) 2019 pPdGainBoundaries[i] = 2020 (u16)(maxPwrT4[i] / 2); 2021 else 2022 pPdGainBoundaries[i] = 2023 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); 2024 2025 pPdGainBoundaries[i] = 2026 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); 2027 2028 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { 2029 minDelta = pPdGainBoundaries[0] - 23; 2030 pPdGainBoundaries[0] = 23; 2031 } else { 2032 minDelta = 0; 2033 } 2034 2035 if (i == 0) { 2036 if (AR_SREV_9280_10_OR_LATER(ah)) 2037 ss = (int16_t)(0 - (minPwrT4[i] / 2)); 2038 else 2039 ss = 0; 2040 } else { 2041 ss = (int16_t)((pPdGainBoundaries[i - 1] - 2042 (minPwrT4[i] / 2)) - 2043 tPdGainOverlap + 1 + minDelta); 2044 } 2045 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 2046 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2047 2048 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2049 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 2050 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); 2051 ss++; 2052 } 2053 2054 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); 2055 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - 2056 (minPwrT4[i] / 2)); 2057 maxIndex = (tgtIndex < sizeCurrVpdTable) ? 2058 tgtIndex : sizeCurrVpdTable; 2059 2060 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2061 pPDADCValues[k++] = vpdTableI[i][ss++]; 2062 } 2063 2064 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - 2065 vpdTableI[i][sizeCurrVpdTable - 2]); 2066 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2067 2068 if (tgtIndex > maxIndex) { 2069 while ((ss <= tgtIndex) && 2070 (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2071 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + 2072 (ss - maxIndex + 1) * vpdStep)); 2073 pPDADCValues[k++] = (u8)((tmpVal > 255) ? 2074 255 : tmpVal); 2075 ss++; 2076 } 2077 } 2078 } 2079 2080 while (i < AR5416_PD_GAINS_IN_MASK) { 2081 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1]; 2082 i++; 2083 } 2084 2085 while (k < AR5416_NUM_PDADC_VALUES) { 2086 pPDADCValues[k] = pPDADCValues[k - 1]; 2087 k++; 2088 } 2089 2090 return; 2091 } 2092 2093 static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, 2094 struct ath9k_channel *chan, 2095 int16_t *pTxPowerIndexOffset) 2096 { 2097 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x) 2098 #define SM_PDGAIN_B(x, y) \ 2099 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y) 2100 2101 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 2102 struct cal_data_per_freq *pRawDataset; 2103 u8 *pCalBChans = NULL; 2104 u16 pdGainOverlap_t2; 2105 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; 2106 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 2107 u16 numPiers, i, j; 2108 int16_t tMinCalPower; 2109 u16 numXpdGain, xpdMask; 2110 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; 2111 u32 reg32, regOffset, regChainOffset; 2112 int16_t modalIdx; 2113 2114 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; 2115 xpdMask = pEepData->modalHeader[modalIdx].xpdGain; 2116 2117 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 2118 AR5416_EEP_MINOR_VER_2) { 2119 pdGainOverlap_t2 = 2120 pEepData->modalHeader[modalIdx].pdGainOverlap; 2121 } else { 2122 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), 2123 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 2124 } 2125 2126 if (IS_CHAN_2GHZ(chan)) { 2127 pCalBChans = pEepData->calFreqPier2G; 2128 numPiers = AR5416_NUM_2G_CAL_PIERS; 2129 } else { 2130 pCalBChans = pEepData->calFreqPier5G; 2131 numPiers = AR5416_NUM_5G_CAL_PIERS; 2132 } 2133 2134 if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) { 2135 pRawDataset = pEepData->calPierData2G[0]; 2136 ah->initPDADC = ((struct calDataPerFreqOpLoop *) 2137 pRawDataset)->vpdPdg[0][0]; 2138 } 2139 2140 numXpdGain = 0; 2141 2142 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 2143 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 2144 if (numXpdGain >= AR5416_NUM_PD_GAINS) 2145 break; 2146 xpdGainValues[numXpdGain] = 2147 (u16)(AR5416_PD_GAINS_IN_MASK - i); 2148 numXpdGain++; 2149 } 2150 } 2151 2152 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 2153 (numXpdGain - 1) & 0x3); 2154 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 2155 xpdGainValues[0]); 2156 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 2157 xpdGainValues[1]); 2158 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 2159 xpdGainValues[2]); 2160 2161 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 2162 if (AR_SREV_5416_20_OR_LATER(ah) && 2163 (ah->rxchainmask == 5 || ah->txchainmask == 5) && 2164 (i != 0)) { 2165 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 2166 } else 2167 regChainOffset = i * 0x1000; 2168 2169 if (pEepData->baseEepHeader.txMask & (1 << i)) { 2170 if (IS_CHAN_2GHZ(chan)) 2171 pRawDataset = pEepData->calPierData2G[i]; 2172 else 2173 pRawDataset = pEepData->calPierData5G[i]; 2174 2175 2176 if (OLC_FOR_AR9280_20_LATER) { 2177 u8 pcdacIdx; 2178 u8 txPower; 2179 2180 ath9k_get_txgain_index(ah, chan, 2181 (struct calDataPerFreqOpLoop *)pRawDataset, 2182 pCalBChans, numPiers, &txPower, &pcdacIdx); 2183 ath9k_olc_get_pdadcs(ah, pcdacIdx, 2184 txPower/2, pdadcValues); 2185 } else { 2186 ath9k_hw_get_def_gain_boundaries_pdadcs(ah, 2187 chan, pRawDataset, 2188 pCalBChans, numPiers, 2189 pdGainOverlap_t2, 2190 &tMinCalPower, 2191 gainBoundaries, 2192 pdadcValues, 2193 numXpdGain); 2194 } 2195 2196 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { 2197 if (OLC_FOR_AR9280_20_LATER) { 2198 REG_WRITE(ah, 2199 AR_PHY_TPCRG5 + regChainOffset, 2200 SM(0x6, 2201 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 2202 SM_PD_GAIN(1) | SM_PD_GAIN(2) | 2203 SM_PD_GAIN(3) | SM_PD_GAIN(4)); 2204 } else { 2205 REG_WRITE(ah, 2206 AR_PHY_TPCRG5 + regChainOffset, 2207 SM(pdGainOverlap_t2, 2208 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| 2209 SM_PDGAIN_B(0, 1) | 2210 SM_PDGAIN_B(1, 2) | 2211 SM_PDGAIN_B(2, 3) | 2212 SM_PDGAIN_B(3, 4)); 2213 } 2214 } 2215 2216 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 2217 for (j = 0; j < 32; j++) { 2218 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | 2219 ((pdadcValues[4 * j + 1] & 0xFF) << 8) | 2220 ((pdadcValues[4 * j + 2] & 0xFF) << 16)| 2221 ((pdadcValues[4 * j + 3] & 0xFF) << 24); 2222 REG_WRITE(ah, regOffset, reg32); 2223 2224 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2225 "PDADC (%d,%4x): %4.4x %8.8x\n", 2226 i, regChainOffset, regOffset, 2227 reg32); 2228 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2229 "PDADC: Chain %d | PDADC %3d " 2230 "Value %3d | PDADC %3d Value %3d | " 2231 "PDADC %3d Value %3d | PDADC %3d " 2232 "Value %3d |\n", 2233 i, 4 * j, pdadcValues[4 * j], 2234 4 * j + 1, pdadcValues[4 * j + 1], 2235 4 * j + 2, pdadcValues[4 * j + 2], 2236 4 * j + 3, 2237 pdadcValues[4 * j + 3]); 2238 2239 regOffset += 4; 2240 } 2241 } 2242 } 2243 2244 *pTxPowerIndexOffset = 0; 2245 #undef SM_PD_GAIN 2246 #undef SM_PDGAIN_B 2247 } 2248 2249 static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, 2250 struct ath9k_channel *chan, 2251 int16_t *ratesArray, 2252 u16 cfgCtl, 2253 u16 AntennaReduction, 2254 u16 twiceMaxRegulatoryPower, 2255 u16 powerLimit) 2256 { 2257 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 2258 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 2259 2260 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 2261 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 2262 static const u16 tpScaleReductionTable[5] = 2263 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 2264 2265 int i; 2266 int16_t twiceLargestAntenna; 2267 struct cal_ctl_data *rep; 2268 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 2269 0, { 0, 0, 0, 0} 2270 }; 2271 struct cal_target_power_leg targetPowerOfdmExt = { 2272 0, { 0, 0, 0, 0} }, targetPowerCckExt = { 2273 0, { 0, 0, 0, 0 } 2274 }; 2275 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 2276 0, {0, 0, 0, 0} 2277 }; 2278 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 2279 u16 ctlModesFor11a[] = 2280 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 }; 2281 u16 ctlModesFor11g[] = 2282 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, 2283 CTL_2GHT40 2284 }; 2285 u16 numCtlModes, *pCtlMode, ctlMode, freq; 2286 struct chan_centers centers; 2287 int tx_chainmask; 2288 u16 twiceMinEdgePower; 2289 2290 tx_chainmask = ah->txchainmask; 2291 2292 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 2293 2294 twiceLargestAntenna = max( 2295 pEepData->modalHeader 2296 [IS_CHAN_2GHZ(chan)].antennaGainCh[0], 2297 pEepData->modalHeader 2298 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]); 2299 2300 twiceLargestAntenna = max((u8)twiceLargestAntenna, 2301 pEepData->modalHeader 2302 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 2303 2304 twiceLargestAntenna = (int16_t)min(AntennaReduction - 2305 twiceLargestAntenna, 0); 2306 2307 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 2308 2309 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) { 2310 maxRegAllowedPower -= 2311 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); 2312 } 2313 2314 scaledPower = min(powerLimit, maxRegAllowedPower); 2315 2316 switch (ar5416_get_ntxchains(tx_chainmask)) { 2317 case 1: 2318 break; 2319 case 2: 2320 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; 2321 break; 2322 case 3: 2323 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; 2324 break; 2325 } 2326 2327 scaledPower = max((u16)0, scaledPower); 2328 2329 if (IS_CHAN_2GHZ(chan)) { 2330 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - 2331 SUB_NUM_CTL_MODES_AT_2G_40; 2332 pCtlMode = ctlModesFor11g; 2333 2334 ath9k_hw_get_legacy_target_powers(ah, chan, 2335 pEepData->calTargetPowerCck, 2336 AR5416_NUM_2G_CCK_TARGET_POWERS, 2337 &targetPowerCck, 4, false); 2338 ath9k_hw_get_legacy_target_powers(ah, chan, 2339 pEepData->calTargetPower2G, 2340 AR5416_NUM_2G_20_TARGET_POWERS, 2341 &targetPowerOfdm, 4, false); 2342 ath9k_hw_get_target_powers(ah, chan, 2343 pEepData->calTargetPower2GHT20, 2344 AR5416_NUM_2G_20_TARGET_POWERS, 2345 &targetPowerHt20, 8, false); 2346 2347 if (IS_CHAN_HT40(chan)) { 2348 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 2349 ath9k_hw_get_target_powers(ah, chan, 2350 pEepData->calTargetPower2GHT40, 2351 AR5416_NUM_2G_40_TARGET_POWERS, 2352 &targetPowerHt40, 8, true); 2353 ath9k_hw_get_legacy_target_powers(ah, chan, 2354 pEepData->calTargetPowerCck, 2355 AR5416_NUM_2G_CCK_TARGET_POWERS, 2356 &targetPowerCckExt, 4, true); 2357 ath9k_hw_get_legacy_target_powers(ah, chan, 2358 pEepData->calTargetPower2G, 2359 AR5416_NUM_2G_20_TARGET_POWERS, 2360 &targetPowerOfdmExt, 4, true); 2361 } 2362 } else { 2363 numCtlModes = ARRAY_SIZE(ctlModesFor11a) - 2364 SUB_NUM_CTL_MODES_AT_5G_40; 2365 pCtlMode = ctlModesFor11a; 2366 2367 ath9k_hw_get_legacy_target_powers(ah, chan, 2368 pEepData->calTargetPower5G, 2369 AR5416_NUM_5G_20_TARGET_POWERS, 2370 &targetPowerOfdm, 4, false); 2371 ath9k_hw_get_target_powers(ah, chan, 2372 pEepData->calTargetPower5GHT20, 2373 AR5416_NUM_5G_20_TARGET_POWERS, 2374 &targetPowerHt20, 8, false); 2375 2376 if (IS_CHAN_HT40(chan)) { 2377 numCtlModes = ARRAY_SIZE(ctlModesFor11a); 2378 ath9k_hw_get_target_powers(ah, chan, 2379 pEepData->calTargetPower5GHT40, 2380 AR5416_NUM_5G_40_TARGET_POWERS, 2381 &targetPowerHt40, 8, true); 2382 ath9k_hw_get_legacy_target_powers(ah, chan, 2383 pEepData->calTargetPower5G, 2384 AR5416_NUM_5G_20_TARGET_POWERS, 2385 &targetPowerOfdmExt, 4, true); 2386 } 2387 } 2388 2389 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 2390 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 2391 (pCtlMode[ctlMode] == CTL_2GHT40); 2392 if (isHt40CtlMode) 2393 freq = centers.synth_center; 2394 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 2395 freq = centers.ext_center; 2396 else 2397 freq = centers.ctl_center; 2398 2399 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 2400 ah->eep_ops->get_eeprom_rev(ah) <= 2) 2401 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 2402 2403 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2404 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " 2405 "EXT_ADDITIVE %d\n", 2406 ctlMode, numCtlModes, isHt40CtlMode, 2407 (pCtlMode[ctlMode] & EXT_ADDITIVE)); 2408 2409 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 2410 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2411 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " 2412 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " 2413 "chan %d\n", 2414 i, cfgCtl, pCtlMode[ctlMode], 2415 pEepData->ctlIndex[i], chan->channel); 2416 2417 if ((((cfgCtl & ~CTL_MODE_M) | 2418 (pCtlMode[ctlMode] & CTL_MODE_M)) == 2419 pEepData->ctlIndex[i]) || 2420 (((cfgCtl & ~CTL_MODE_M) | 2421 (pCtlMode[ctlMode] & CTL_MODE_M)) == 2422 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { 2423 rep = &(pEepData->ctlData[i]); 2424 2425 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq, 2426 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1], 2427 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); 2428 2429 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2430 " MATCH-EE_IDX %d: ch %d is2 %d " 2431 "2xMinEdge %d chainmask %d chains %d\n", 2432 i, freq, IS_CHAN_2GHZ(chan), 2433 twiceMinEdgePower, tx_chainmask, 2434 ar5416_get_ntxchains 2435 (tx_chainmask)); 2436 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 2437 twiceMaxEdgePower = min(twiceMaxEdgePower, 2438 twiceMinEdgePower); 2439 } else { 2440 twiceMaxEdgePower = twiceMinEdgePower; 2441 break; 2442 } 2443 } 2444 } 2445 2446 minCtlPower = min(twiceMaxEdgePower, scaledPower); 2447 2448 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2449 " SEL-Min ctlMode %d pCtlMode %d " 2450 "2xMaxEdge %d sP %d minCtlPwr %d\n", 2451 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, 2452 scaledPower, minCtlPower); 2453 2454 switch (pCtlMode[ctlMode]) { 2455 case CTL_11B: 2456 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { 2457 targetPowerCck.tPow2x[i] = 2458 min((u16)targetPowerCck.tPow2x[i], 2459 minCtlPower); 2460 } 2461 break; 2462 case CTL_11A: 2463 case CTL_11G: 2464 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { 2465 targetPowerOfdm.tPow2x[i] = 2466 min((u16)targetPowerOfdm.tPow2x[i], 2467 minCtlPower); 2468 } 2469 break; 2470 case CTL_5GHT20: 2471 case CTL_2GHT20: 2472 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { 2473 targetPowerHt20.tPow2x[i] = 2474 min((u16)targetPowerHt20.tPow2x[i], 2475 minCtlPower); 2476 } 2477 break; 2478 case CTL_11B_EXT: 2479 targetPowerCckExt.tPow2x[0] = min((u16) 2480 targetPowerCckExt.tPow2x[0], 2481 minCtlPower); 2482 break; 2483 case CTL_11A_EXT: 2484 case CTL_11G_EXT: 2485 targetPowerOfdmExt.tPow2x[0] = min((u16) 2486 targetPowerOfdmExt.tPow2x[0], 2487 minCtlPower); 2488 break; 2489 case CTL_5GHT40: 2490 case CTL_2GHT40: 2491 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 2492 targetPowerHt40.tPow2x[i] = 2493 min((u16)targetPowerHt40.tPow2x[i], 2494 minCtlPower); 2495 } 2496 break; 2497 default: 2498 break; 2499 } 2500 } 2501 2502 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = 2503 ratesArray[rate18mb] = ratesArray[rate24mb] = 2504 targetPowerOfdm.tPow2x[0]; 2505 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 2506 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 2507 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 2508 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 2509 2510 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 2511 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 2512 2513 if (IS_CHAN_2GHZ(chan)) { 2514 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 2515 ratesArray[rate2s] = ratesArray[rate2l] = 2516 targetPowerCck.tPow2x[1]; 2517 ratesArray[rate5_5s] = ratesArray[rate5_5l] = 2518 targetPowerCck.tPow2x[2]; 2519 ; 2520 ratesArray[rate11s] = ratesArray[rate11l] = 2521 targetPowerCck.tPow2x[3]; 2522 ; 2523 } 2524 if (IS_CHAN_HT40(chan)) { 2525 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 2526 ratesArray[rateHt40_0 + i] = 2527 targetPowerHt40.tPow2x[i]; 2528 } 2529 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 2530 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 2531 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 2532 if (IS_CHAN_2GHZ(chan)) { 2533 ratesArray[rateExtCck] = 2534 targetPowerCckExt.tPow2x[0]; 2535 } 2536 } 2537 } 2538 2539 static void ath9k_hw_def_set_txpower(struct ath_hw *ah, 2540 struct ath9k_channel *chan, 2541 u16 cfgCtl, 2542 u8 twiceAntennaReduction, 2543 u8 twiceMaxRegulatoryPower, 2544 u8 powerLimit) 2545 { 2546 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) 2547 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 2548 struct modal_eep_header *pModal = 2549 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); 2550 int16_t ratesArray[Ar5416RateSize]; 2551 int16_t txPowerIndexOffset = 0; 2552 u8 ht40PowerIncForPdadc = 2; 2553 int i, cck_ofdm_delta = 0; 2554 2555 memset(ratesArray, 0, sizeof(ratesArray)); 2556 2557 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 2558 AR5416_EEP_MINOR_VER_2) { 2559 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 2560 } 2561 2562 ath9k_hw_set_def_power_per_rate_table(ah, chan, 2563 &ratesArray[0], cfgCtl, 2564 twiceAntennaReduction, 2565 twiceMaxRegulatoryPower, 2566 powerLimit); 2567 2568 ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset); 2569 2570 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 2571 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 2572 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 2573 ratesArray[i] = AR5416_MAX_RATE_POWER; 2574 } 2575 2576 if (AR_SREV_9280_10_OR_LATER(ah)) { 2577 for (i = 0; i < Ar5416RateSize; i++) 2578 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; 2579 } 2580 2581 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 2582 ATH9K_POW_SM(ratesArray[rate18mb], 24) 2583 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 2584 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 2585 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 2586 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 2587 ATH9K_POW_SM(ratesArray[rate54mb], 24) 2588 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 2589 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 2590 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 2591 2592 if (IS_CHAN_2GHZ(chan)) { 2593 if (OLC_FOR_AR9280_20_LATER) { 2594 cck_ofdm_delta = 2; 2595 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 2596 ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24) 2597 | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16) 2598 | ATH9K_POW_SM(ratesArray[rateXr], 8) 2599 | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0)); 2600 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 2601 ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24) 2602 | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16) 2603 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8) 2604 | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0)); 2605 } else { 2606 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 2607 ATH9K_POW_SM(ratesArray[rate2s], 24) 2608 | ATH9K_POW_SM(ratesArray[rate2l], 16) 2609 | ATH9K_POW_SM(ratesArray[rateXr], 8) 2610 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 2611 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 2612 ATH9K_POW_SM(ratesArray[rate11s], 24) 2613 | ATH9K_POW_SM(ratesArray[rate11l], 16) 2614 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 2615 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 2616 } 2617 } 2618 2619 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 2620 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 2621 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 2622 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 2623 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 2624 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 2625 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 2626 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 2627 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 2628 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 2629 2630 if (IS_CHAN_HT40(chan)) { 2631 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 2632 ATH9K_POW_SM(ratesArray[rateHt40_3] + 2633 ht40PowerIncForPdadc, 24) 2634 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 2635 ht40PowerIncForPdadc, 16) 2636 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 2637 ht40PowerIncForPdadc, 8) 2638 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 2639 ht40PowerIncForPdadc, 0)); 2640 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 2641 ATH9K_POW_SM(ratesArray[rateHt40_7] + 2642 ht40PowerIncForPdadc, 24) 2643 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 2644 ht40PowerIncForPdadc, 16) 2645 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 2646 ht40PowerIncForPdadc, 8) 2647 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 2648 ht40PowerIncForPdadc, 0)); 2649 if (OLC_FOR_AR9280_20_LATER) { 2650 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 2651 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 2652 | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16) 2653 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 2654 | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0)); 2655 } else { 2656 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 2657 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 2658 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 2659 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 2660 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 2661 } 2662 } 2663 2664 REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 2665 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) 2666 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); 2667 2668 i = rate6mb; 2669 2670 if (IS_CHAN_HT40(chan)) 2671 i = rateHt40_0; 2672 else if (IS_CHAN_HT20(chan)) 2673 i = rateHt20_0; 2674 2675 if (AR_SREV_9280_10_OR_LATER(ah)) 2676 ah->regulatory.max_power_level = 2677 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; 2678 else 2679 ah->regulatory.max_power_level = ratesArray[i]; 2680 2681 switch(ar5416_get_ntxchains(ah->txchainmask)) { 2682 case 1: 2683 break; 2684 case 2: 2685 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; 2686 break; 2687 case 3: 2688 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; 2689 break; 2690 default: 2691 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2692 "Invalid chainmask configuration\n"); 2693 break; 2694 } 2695 } 2696 2697 static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, 2698 enum ieee80211_band freq_band) 2699 { 2700 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 2701 struct modal_eep_header *pModal = 2702 &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]); 2703 struct base_eep_header *pBase = &eep->baseEepHeader; 2704 u8 num_ant_config; 2705 2706 num_ant_config = 1; 2707 2708 if (pBase->version >= 0x0E0D) 2709 if (pModal->useAnt1) 2710 num_ant_config += 1; 2711 2712 return num_ant_config; 2713 } 2714 2715 static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah, 2716 struct ath9k_channel *chan) 2717 { 2718 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 2719 struct modal_eep_header *pModal = 2720 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 2721 2722 return pModal->antCtrlCommon & 0xFFFF; 2723 } 2724 2725 static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 2726 { 2727 #define EEP_DEF_SPURCHAN \ 2728 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan) 2729 2730 u16 spur_val = AR_NO_SPUR; 2731 2732 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 2733 "Getting spur idx %d is2Ghz. %d val %x\n", 2734 i, is2GHz, ah->config.spurchans[i][is2GHz]); 2735 2736 switch (ah->config.spurmode) { 2737 case SPUR_DISABLE: 2738 break; 2739 case SPUR_ENABLE_IOCTL: 2740 spur_val = ah->config.spurchans[i][is2GHz]; 2741 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 2742 "Getting spur val from new loc. %d\n", spur_val); 2743 break; 2744 case SPUR_ENABLE_EEPROM: 2745 spur_val = EEP_DEF_SPURCHAN; 2746 break; 2747 } 2748 2749 return spur_val; 2750 2751 #undef EEP_DEF_SPURCHAN 2752 } 2753 2754 static struct eeprom_ops eep_def_ops = { 2755 .check_eeprom = ath9k_hw_def_check_eeprom, 2756 .get_eeprom = ath9k_hw_def_get_eeprom, 2757 .fill_eeprom = ath9k_hw_def_fill_eeprom, 2758 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver, 2759 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev, 2760 .get_num_ant_config = ath9k_hw_def_get_num_ant_config, 2761 .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg, 2762 .set_board_values = ath9k_hw_def_set_board_values, 2763 .set_addac = ath9k_hw_def_set_addac, 2764 .set_txpower = ath9k_hw_def_set_txpower, 2765 .get_spur_channel = ath9k_hw_def_get_spur_channel 2766 }; 2767 2768 int ath9k_hw_eeprom_attach(struct ath_hw *ah) 2769 { 2770 int status; 2771 2772 if (AR_SREV_9285(ah)) { 2773 ah->eep_map = EEP_MAP_4KBITS; 2774 ah->eep_ops = &eep_4k_ops; 2775 } else { 2776 ah->eep_map = EEP_MAP_DEFAULT; 2777 ah->eep_ops = &eep_def_ops; 2778 } 2779 2780 if (!ah->eep_ops->fill_eeprom(ah)) 2781 return -EIO; 2782 2783 status = ah->eep_ops->check_eeprom(ah); 2784 2785 return status; 2786 } 2787