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 "hw.h" 18 19 static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah) 20 { 21 return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF; 22 } 23 24 static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah) 25 { 26 return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; 27 } 28 29 static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) 30 { 31 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 32 struct ath_common *common = ath9k_hw_common(ah); 33 u16 *eep_data; 34 int addr, eep_start_loc = AR9287_EEP_START_LOC; 35 eep_data = (u16 *)eep; 36 37 if (!ath9k_hw_use_flash(ah)) { 38 ath_print(common, ATH_DBG_EEPROM, 39 "Reading from EEPROM, not flash\n"); 40 } 41 42 for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16); 43 addr++) { 44 if (!ath9k_hw_nvram_read(common, 45 addr + eep_start_loc, eep_data)) { 46 ath_print(common, ATH_DBG_EEPROM, 47 "Unable to read eeprom region \n"); 48 return false; 49 } 50 eep_data++; 51 } 52 return true; 53 } 54 55 static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) 56 { 57 u32 sum = 0, el, integer; 58 u16 temp, word, magic, magic2, *eepdata; 59 int i, addr; 60 bool need_swap = false; 61 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 62 struct ath_common *common = ath9k_hw_common(ah); 63 64 if (!ath9k_hw_use_flash(ah)) { 65 if (!ath9k_hw_nvram_read(common, 66 AR5416_EEPROM_MAGIC_OFFSET, &magic)) { 67 ath_print(common, ATH_DBG_FATAL, 68 "Reading Magic # failed\n"); 69 return false; 70 } 71 72 ath_print(common, ATH_DBG_EEPROM, 73 "Read Magic = 0x%04X\n", magic); 74 if (magic != AR5416_EEPROM_MAGIC) { 75 magic2 = swab16(magic); 76 77 if (magic2 == AR5416_EEPROM_MAGIC) { 78 need_swap = true; 79 eepdata = (u16 *)(&ah->eeprom); 80 81 for (addr = 0; 82 addr < sizeof(struct ar9287_eeprom) / sizeof(u16); 83 addr++) { 84 temp = swab16(*eepdata); 85 *eepdata = temp; 86 eepdata++; 87 } 88 } else { 89 ath_print(common, ATH_DBG_FATAL, 90 "Invalid EEPROM Magic. " 91 "endianness mismatch.\n"); 92 return -EINVAL; 93 } 94 } 95 } 96 ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ? 97 "True" : "False"); 98 99 if (need_swap) 100 el = swab16(ah->eeprom.map9287.baseEepHeader.length); 101 else 102 el = ah->eeprom.map9287.baseEepHeader.length; 103 104 if (el > sizeof(struct ar9287_eeprom)) 105 el = sizeof(struct ar9287_eeprom) / sizeof(u16); 106 else 107 el = el / sizeof(u16); 108 109 eepdata = (u16 *)(&ah->eeprom); 110 for (i = 0; i < el; i++) 111 sum ^= *eepdata++; 112 113 if (need_swap) { 114 word = swab16(eep->baseEepHeader.length); 115 eep->baseEepHeader.length = word; 116 117 word = swab16(eep->baseEepHeader.checksum); 118 eep->baseEepHeader.checksum = word; 119 120 word = swab16(eep->baseEepHeader.version); 121 eep->baseEepHeader.version = word; 122 123 word = swab16(eep->baseEepHeader.regDmn[0]); 124 eep->baseEepHeader.regDmn[0] = word; 125 126 word = swab16(eep->baseEepHeader.regDmn[1]); 127 eep->baseEepHeader.regDmn[1] = word; 128 129 word = swab16(eep->baseEepHeader.rfSilent); 130 eep->baseEepHeader.rfSilent = word; 131 132 word = swab16(eep->baseEepHeader.blueToothOptions); 133 eep->baseEepHeader.blueToothOptions = word; 134 135 word = swab16(eep->baseEepHeader.deviceCap); 136 eep->baseEepHeader.deviceCap = word; 137 138 integer = swab32(eep->modalHeader.antCtrlCommon); 139 eep->modalHeader.antCtrlCommon = integer; 140 141 for (i = 0; i < AR9287_MAX_CHAINS; i++) { 142 integer = swab32(eep->modalHeader.antCtrlChain[i]); 143 eep->modalHeader.antCtrlChain[i] = integer; 144 } 145 146 for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) { 147 word = swab16(eep->modalHeader.spurChans[i].spurChan); 148 eep->modalHeader.spurChans[i].spurChan = word; 149 } 150 } 151 152 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER 153 || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 154 ath_print(common, ATH_DBG_FATAL, 155 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 156 sum, ah->eep_ops->get_eeprom_ver(ah)); 157 return -EINVAL; 158 } 159 160 return 0; 161 } 162 163 static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, 164 enum eeprom_param param) 165 { 166 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 167 struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 168 struct base_eep_ar9287_header *pBase = &eep->baseEepHeader; 169 u16 ver_minor; 170 171 ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK; 172 switch (param) { 173 case EEP_NFTHRESH_2: 174 return pModal->noiseFloorThreshCh[0]; 175 case AR_EEPROM_MAC(0): 176 return pBase->macAddr[0] << 8 | pBase->macAddr[1]; 177 case AR_EEPROM_MAC(1): 178 return pBase->macAddr[2] << 8 | pBase->macAddr[3]; 179 case AR_EEPROM_MAC(2): 180 return pBase->macAddr[4] << 8 | pBase->macAddr[5]; 181 case EEP_REG_0: 182 return pBase->regDmn[0]; 183 case EEP_REG_1: 184 return pBase->regDmn[1]; 185 case EEP_OP_CAP: 186 return pBase->deviceCap; 187 case EEP_OP_MODE: 188 return pBase->opCapFlags; 189 case EEP_RF_SILENT: 190 return pBase->rfSilent; 191 case EEP_MINOR_REV: 192 return ver_minor; 193 case EEP_TX_MASK: 194 return pBase->txMask; 195 case EEP_RX_MASK: 196 return pBase->rxMask; 197 case EEP_DEV_TYPE: 198 return pBase->deviceType; 199 case EEP_OL_PWRCTRL: 200 return pBase->openLoopPwrCntl; 201 case EEP_TEMPSENSE_SLOPE: 202 if (ver_minor >= AR9287_EEP_MINOR_VER_2) 203 return pBase->tempSensSlope; 204 else 205 return 0; 206 case EEP_TEMPSENSE_SLOPE_PAL_ON: 207 if (ver_minor >= AR9287_EEP_MINOR_VER_3) 208 return pBase->tempSensSlopePalOn; 209 else 210 return 0; 211 default: 212 return 0; 213 } 214 } 215 216 217 static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, 218 struct ath9k_channel *chan, 219 struct cal_data_per_freq_ar9287 *pRawDataSet, 220 u8 *bChans, u16 availPiers, 221 u16 tPdGainOverlap, int16_t *pMinCalPower, 222 u16 *pPdGainBoundaries, u8 *pPDADCValues, 223 u16 numXpdGains) 224 { 225 #define TMP_VAL_VPD_TABLE \ 226 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); 227 228 int i, j, k; 229 int16_t ss; 230 u16 idxL = 0, idxR = 0, numPiers; 231 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; 232 u8 minPwrT4[AR9287_NUM_PD_GAINS]; 233 u8 maxPwrT4[AR9287_NUM_PD_GAINS]; 234 int16_t vpdStep; 235 int16_t tmpVal; 236 u16 sizeCurrVpdTable, maxIndex, tgtIndex; 237 bool match; 238 int16_t minDelta = 0; 239 struct chan_centers centers; 240 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] 241 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 242 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS] 243 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 244 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] 245 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 246 247 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 248 249 for (numPiers = 0; numPiers < availPiers; numPiers++) { 250 if (bChans[numPiers] == AR9287_BCHAN_UNUSED) 251 break; 252 } 253 254 match = ath9k_hw_get_lower_upper_index( 255 (u8)FREQ2FBIN(centers.synth_center, 256 IS_CHAN_2GHZ(chan)), bChans, numPiers, 257 &idxL, &idxR); 258 259 if (match) { 260 for (i = 0; i < numXpdGains; i++) { 261 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 262 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 263 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 264 pRawDataSet[idxL].pwrPdg[i], 265 pRawDataSet[idxL].vpdPdg[i], 266 AR9287_PD_GAIN_ICEPTS, vpdTableI[i]); 267 } 268 } else { 269 for (i = 0; i < numXpdGains; i++) { 270 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 271 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 272 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 273 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 274 275 minPwrT4[i] = max(pPwrL[0], pPwrR[0]); 276 277 maxPwrT4[i] = 278 min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1], 279 pPwrR[AR9287_PD_GAIN_ICEPTS - 1]); 280 281 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 282 pPwrL, pVpdL, 283 AR9287_PD_GAIN_ICEPTS, 284 vpdTableL[i]); 285 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 286 pPwrR, pVpdR, 287 AR9287_PD_GAIN_ICEPTS, 288 vpdTableR[i]); 289 290 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 291 vpdTableI[i][j] = 292 (u8)(ath9k_hw_interpolate((u16) 293 FREQ2FBIN(centers. synth_center, 294 IS_CHAN_2GHZ(chan)), 295 bChans[idxL], bChans[idxR], 296 vpdTableL[i][j], vpdTableR[i][j])); 297 } 298 } 299 } 300 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 301 302 k = 0; 303 for (i = 0; i < numXpdGains; i++) { 304 if (i == (numXpdGains - 1)) 305 pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2); 306 else 307 pPdGainBoundaries[i] = (u16)((maxPwrT4[i] + 308 minPwrT4[i+1]) / 4); 309 310 pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER, 311 pPdGainBoundaries[i]); 312 313 314 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { 315 minDelta = pPdGainBoundaries[0] - 23; 316 pPdGainBoundaries[0] = 23; 317 } else 318 minDelta = 0; 319 320 if (i == 0) { 321 if (AR_SREV_9280_10_OR_LATER(ah)) 322 ss = (int16_t)(0 - (minPwrT4[i] / 2)); 323 else 324 ss = 0; 325 } else 326 ss = (int16_t)((pPdGainBoundaries[i-1] - 327 (minPwrT4[i] / 2)) - 328 tPdGainOverlap + 1 + minDelta); 329 330 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 331 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 332 while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) { 333 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 334 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); 335 ss++; 336 } 337 338 sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); 339 tgtIndex = (u8)(pPdGainBoundaries[i] + 340 tPdGainOverlap - (minPwrT4[i] / 2)); 341 maxIndex = (tgtIndex < sizeCurrVpdTable) ? 342 tgtIndex : sizeCurrVpdTable; 343 344 while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1))) 345 pPDADCValues[k++] = vpdTableI[i][ss++]; 346 347 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - 348 vpdTableI[i][sizeCurrVpdTable - 2]); 349 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 350 if (tgtIndex > maxIndex) { 351 while ((ss <= tgtIndex) && 352 (k < (AR9287_NUM_PDADC_VALUES - 1))) { 353 tmpVal = (int16_t) TMP_VAL_VPD_TABLE; 354 pPDADCValues[k++] = (u8)((tmpVal > 255) ? 355 255 : tmpVal); 356 ss++; 357 } 358 } 359 } 360 361 while (i < AR9287_PD_GAINS_IN_MASK) { 362 pPdGainBoundaries[i] = pPdGainBoundaries[i-1]; 363 i++; 364 } 365 366 while (k < AR9287_NUM_PDADC_VALUES) { 367 pPDADCValues[k] = pPDADCValues[k-1]; 368 k++; 369 } 370 371 #undef TMP_VAL_VPD_TABLE 372 } 373 374 static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, 375 struct ath9k_channel *chan, 376 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, 377 u8 *pCalChans, u16 availPiers, 378 int8_t *pPwr) 379 { 380 u16 idxL = 0, idxR = 0, numPiers; 381 bool match; 382 struct chan_centers centers; 383 384 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 385 386 for (numPiers = 0; numPiers < availPiers; numPiers++) { 387 if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED) 388 break; 389 } 390 391 match = ath9k_hw_get_lower_upper_index( 392 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), 393 pCalChans, numPiers, 394 &idxL, &idxR); 395 396 if (match) { 397 *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0]; 398 } else { 399 *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] + 400 (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2; 401 } 402 403 } 404 405 static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah, 406 int32_t txPower, u16 chain) 407 { 408 u32 tmpVal; 409 u32 a; 410 411 tmpVal = REG_READ(ah, 0xa270); 412 tmpVal = tmpVal & 0xFCFFFFFF; 413 tmpVal = tmpVal | (0x3 << 24); 414 REG_WRITE(ah, 0xa270, tmpVal); 415 416 tmpVal = REG_READ(ah, 0xb270); 417 tmpVal = tmpVal & 0xFCFFFFFF; 418 tmpVal = tmpVal | (0x3 << 24); 419 REG_WRITE(ah, 0xb270, tmpVal); 420 421 if (chain == 0) { 422 tmpVal = REG_READ(ah, 0xa398); 423 tmpVal = tmpVal & 0xff00ffff; 424 a = (txPower)&0xff; 425 tmpVal = tmpVal | (a << 16); 426 REG_WRITE(ah, 0xa398, tmpVal); 427 } 428 429 if (chain == 1) { 430 tmpVal = REG_READ(ah, 0xb398); 431 tmpVal = tmpVal & 0xff00ffff; 432 a = (txPower)&0xff; 433 tmpVal = tmpVal | (a << 16); 434 REG_WRITE(ah, 0xb398, tmpVal); 435 } 436 } 437 438 static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, 439 struct ath9k_channel *chan, 440 int16_t *pTxPowerIndexOffset) 441 { 442 struct ath_common *common = ath9k_hw_common(ah); 443 struct cal_data_per_freq_ar9287 *pRawDataset; 444 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; 445 u8 *pCalBChans = NULL; 446 u16 pdGainOverlap_t2; 447 u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; 448 u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK]; 449 u16 numPiers = 0, i, j; 450 int16_t tMinCalPower; 451 u16 numXpdGain, xpdMask; 452 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; 453 u32 reg32, regOffset, regChainOffset; 454 int16_t modalIdx, diff = 0; 455 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 456 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; 457 xpdMask = pEepData->modalHeader.xpdGain; 458 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= 459 AR9287_EEP_MINOR_VER_2) 460 pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap; 461 else 462 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), 463 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 464 465 if (IS_CHAN_2GHZ(chan)) { 466 pCalBChans = pEepData->calFreqPier2G; 467 numPiers = AR9287_NUM_2G_CAL_PIERS; 468 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 469 pRawDatasetOpenLoop = 470 (struct cal_data_op_loop_ar9287 *) 471 pEepData->calPierData2G[0]; 472 ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0]; 473 } 474 } 475 476 numXpdGain = 0; 477 for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) { 478 if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) { 479 if (numXpdGain >= AR9287_NUM_PD_GAINS) 480 break; 481 xpdGainValues[numXpdGain] = 482 (u16)(AR9287_PD_GAINS_IN_MASK-i); 483 numXpdGain++; 484 } 485 } 486 487 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 488 (numXpdGain - 1) & 0x3); 489 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 490 xpdGainValues[0]); 491 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 492 xpdGainValues[1]); 493 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 494 xpdGainValues[2]); 495 496 for (i = 0; i < AR9287_MAX_CHAINS; i++) { 497 regChainOffset = i * 0x1000; 498 if (pEepData->baseEepHeader.txMask & (1 << i)) { 499 pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *) 500 pEepData->calPierData2G[i]; 501 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 502 int8_t txPower; 503 ar9287_eeprom_get_tx_gain_index(ah, chan, 504 pRawDatasetOpenLoop, 505 pCalBChans, numPiers, 506 &txPower); 507 ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i); 508 } else { 509 pRawDataset = 510 (struct cal_data_per_freq_ar9287 *) 511 pEepData->calPierData2G[i]; 512 ath9k_hw_get_AR9287_gain_boundaries_pdadcs( 513 ah, chan, pRawDataset, 514 pCalBChans, numPiers, 515 pdGainOverlap_t2, 516 &tMinCalPower, gainBoundaries, 517 pdadcValues, numXpdGain); 518 } 519 520 if (i == 0) { 521 if (!ath9k_hw_AR9287_get_eeprom( 522 ah, EEP_OL_PWRCTRL)) { 523 REG_WRITE(ah, AR_PHY_TPCRG5 + 524 regChainOffset, 525 SM(pdGainOverlap_t2, 526 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 527 SM(gainBoundaries[0], 528 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) 529 | SM(gainBoundaries[1], 530 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) 531 | SM(gainBoundaries[2], 532 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) 533 | SM(gainBoundaries[3], 534 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 535 } 536 } 537 538 if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB != 539 pEepData->baseEepHeader.pwrTableOffset) { 540 diff = (u16) 541 (pEepData->baseEepHeader.pwrTableOffset 542 - (int32_t)AR9287_PWR_TABLE_OFFSET_DB); 543 diff *= 2; 544 545 for (j = 0; 546 j < ((u16)AR9287_NUM_PDADC_VALUES-diff); 547 j++) 548 pdadcValues[j] = pdadcValues[j+diff]; 549 550 for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff); 551 j < AR9287_NUM_PDADC_VALUES; j++) 552 pdadcValues[j] = 553 pdadcValues[ 554 AR9287_NUM_PDADC_VALUES-diff]; 555 } 556 557 if (!ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 558 regOffset = AR_PHY_BASE + (672 << 2) + 559 regChainOffset; 560 for (j = 0; j < 32; j++) { 561 reg32 = ((pdadcValues[4*j + 0] 562 & 0xFF) << 0) | 563 ((pdadcValues[4*j + 1] 564 & 0xFF) << 8) | 565 ((pdadcValues[4*j + 2] 566 & 0xFF) << 16) | 567 ((pdadcValues[4*j + 3] 568 & 0xFF) << 24) ; 569 REG_WRITE(ah, regOffset, reg32); 570 571 ath_print(common, ATH_DBG_EEPROM, 572 "PDADC (%d,%4x): %4.4x " 573 "%8.8x\n", 574 i, regChainOffset, regOffset, 575 reg32); 576 577 ath_print(common, ATH_DBG_EEPROM, 578 "PDADC: Chain %d | " 579 "PDADC %3d Value %3d | " 580 "PDADC %3d Value %3d | " 581 "PDADC %3d Value %3d | " 582 "PDADC %3d Value %3d |\n", 583 i, 4 * j, pdadcValues[4 * j], 584 4 * j + 1, 585 pdadcValues[4 * j + 1], 586 4 * j + 2, 587 pdadcValues[4 * j + 2], 588 4 * j + 3, 589 pdadcValues[4 * j + 3]); 590 591 regOffset += 4; 592 } 593 } 594 } 595 } 596 597 *pTxPowerIndexOffset = 0; 598 } 599 600 static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, 601 struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl, 602 u16 AntennaReduction, u16 twiceMaxRegulatoryPower, 603 u16 powerLimit) 604 { 605 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 606 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 607 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 608 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 609 static const u16 tpScaleReductionTable[5] = 610 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 611 int i; 612 int16_t twiceLargestAntenna; 613 struct cal_ctl_data_ar9287 *rep; 614 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} }, 615 targetPowerCck = {0, {0, 0, 0, 0} }; 616 struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} }, 617 targetPowerCckExt = {0, {0, 0, 0, 0} }; 618 struct cal_target_power_ht targetPowerHt20, 619 targetPowerHt40 = {0, {0, 0, 0, 0} }; 620 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 621 u16 ctlModesFor11g[] = 622 {CTL_11B, CTL_11G, CTL_2GHT20, 623 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40}; 624 u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq; 625 struct chan_centers centers; 626 int tx_chainmask; 627 u16 twiceMinEdgePower; 628 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 629 tx_chainmask = ah->txchainmask; 630 631 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 632 633 twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0], 634 pEepData->modalHeader.antennaGainCh[1]); 635 636 twiceLargestAntenna = (int16_t)min((AntennaReduction) - 637 twiceLargestAntenna, 0); 638 639 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 640 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) 641 maxRegAllowedPower -= 642 (tpScaleReductionTable[(regulatory->tp_scale)] * 2); 643 644 scaledPower = min(powerLimit, maxRegAllowedPower); 645 646 switch (ar5416_get_ntxchains(tx_chainmask)) { 647 case 1: 648 break; 649 case 2: 650 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; 651 break; 652 case 3: 653 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; 654 break; 655 } 656 scaledPower = max((u16)0, scaledPower); 657 658 if (IS_CHAN_2GHZ(chan)) { 659 numCtlModes = 660 ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 661 pCtlMode = ctlModesFor11g; 662 663 ath9k_hw_get_legacy_target_powers(ah, chan, 664 pEepData->calTargetPowerCck, 665 AR9287_NUM_2G_CCK_TARGET_POWERS, 666 &targetPowerCck, 4, false); 667 ath9k_hw_get_legacy_target_powers(ah, chan, 668 pEepData->calTargetPower2G, 669 AR9287_NUM_2G_20_TARGET_POWERS, 670 &targetPowerOfdm, 4, false); 671 ath9k_hw_get_target_powers(ah, chan, 672 pEepData->calTargetPower2GHT20, 673 AR9287_NUM_2G_20_TARGET_POWERS, 674 &targetPowerHt20, 8, false); 675 676 if (IS_CHAN_HT40(chan)) { 677 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 678 ath9k_hw_get_target_powers(ah, chan, 679 pEepData->calTargetPower2GHT40, 680 AR9287_NUM_2G_40_TARGET_POWERS, 681 &targetPowerHt40, 8, true); 682 ath9k_hw_get_legacy_target_powers(ah, chan, 683 pEepData->calTargetPowerCck, 684 AR9287_NUM_2G_CCK_TARGET_POWERS, 685 &targetPowerCckExt, 4, true); 686 ath9k_hw_get_legacy_target_powers(ah, chan, 687 pEepData->calTargetPower2G, 688 AR9287_NUM_2G_20_TARGET_POWERS, 689 &targetPowerOfdmExt, 4, true); 690 } 691 } 692 693 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 694 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 695 (pCtlMode[ctlMode] == CTL_2GHT40); 696 if (isHt40CtlMode) 697 freq = centers.synth_center; 698 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 699 freq = centers.ext_center; 700 else 701 freq = centers.ctl_center; 702 703 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 704 ah->eep_ops->get_eeprom_rev(ah) <= 2) 705 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 706 707 for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 708 if ((((cfgCtl & ~CTL_MODE_M) | 709 (pCtlMode[ctlMode] & CTL_MODE_M)) == 710 pEepData->ctlIndex[i]) || 711 (((cfgCtl & ~CTL_MODE_M) | 712 (pCtlMode[ctlMode] & CTL_MODE_M)) == 713 ((pEepData->ctlIndex[i] & 714 CTL_MODE_M) | SD_NO_CTL))) { 715 716 rep = &(pEepData->ctlData[i]); 717 twiceMinEdgePower = ath9k_hw_get_max_edge_power( 718 freq, 719 rep->ctlEdges[ar5416_get_ntxchains( 720 tx_chainmask) - 1], 721 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); 722 723 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) 724 twiceMaxEdgePower = min( 725 twiceMaxEdgePower, 726 twiceMinEdgePower); 727 else { 728 twiceMaxEdgePower = twiceMinEdgePower; 729 break; 730 } 731 } 732 } 733 734 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 735 736 switch (pCtlMode[ctlMode]) { 737 case CTL_11B: 738 for (i = 0; 739 i < ARRAY_SIZE(targetPowerCck.tPow2x); 740 i++) { 741 targetPowerCck.tPow2x[i] = (u8)min( 742 (u16)targetPowerCck.tPow2x[i], 743 minCtlPower); 744 } 745 break; 746 case CTL_11A: 747 case CTL_11G: 748 for (i = 0; 749 i < ARRAY_SIZE(targetPowerOfdm.tPow2x); 750 i++) { 751 targetPowerOfdm.tPow2x[i] = (u8)min( 752 (u16)targetPowerOfdm.tPow2x[i], 753 minCtlPower); 754 } 755 break; 756 case CTL_5GHT20: 757 case CTL_2GHT20: 758 for (i = 0; 759 i < ARRAY_SIZE(targetPowerHt20.tPow2x); 760 i++) { 761 targetPowerHt20.tPow2x[i] = (u8)min( 762 (u16)targetPowerHt20.tPow2x[i], 763 minCtlPower); 764 } 765 break; 766 case CTL_11B_EXT: 767 targetPowerCckExt.tPow2x[0] = (u8)min( 768 (u16)targetPowerCckExt.tPow2x[0], 769 minCtlPower); 770 break; 771 case CTL_11A_EXT: 772 case CTL_11G_EXT: 773 targetPowerOfdmExt.tPow2x[0] = (u8)min( 774 (u16)targetPowerOfdmExt.tPow2x[0], 775 minCtlPower); 776 break; 777 case CTL_5GHT40: 778 case CTL_2GHT40: 779 for (i = 0; 780 i < ARRAY_SIZE(targetPowerHt40.tPow2x); 781 i++) { 782 targetPowerHt40.tPow2x[i] = (u8)min( 783 (u16)targetPowerHt40.tPow2x[i], 784 minCtlPower); 785 } 786 break; 787 default: 788 break; 789 } 790 } 791 792 ratesArray[rate6mb] = 793 ratesArray[rate9mb] = 794 ratesArray[rate12mb] = 795 ratesArray[rate18mb] = 796 ratesArray[rate24mb] = 797 targetPowerOfdm.tPow2x[0]; 798 799 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 800 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 801 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 802 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 803 804 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 805 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 806 807 if (IS_CHAN_2GHZ(chan)) { 808 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 809 ratesArray[rate2s] = ratesArray[rate2l] = 810 targetPowerCck.tPow2x[1]; 811 ratesArray[rate5_5s] = ratesArray[rate5_5l] = 812 targetPowerCck.tPow2x[2]; 813 ratesArray[rate11s] = ratesArray[rate11l] = 814 targetPowerCck.tPow2x[3]; 815 } 816 if (IS_CHAN_HT40(chan)) { 817 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) 818 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i]; 819 820 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 821 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 822 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 823 if (IS_CHAN_2GHZ(chan)) 824 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 825 } 826 827 #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN 828 #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN 829 } 830 831 static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, 832 struct ath9k_channel *chan, u16 cfgCtl, 833 u8 twiceAntennaReduction, 834 u8 twiceMaxRegulatoryPower, 835 u8 powerLimit) 836 { 837 #define INCREASE_MAXPOW_BY_TWO_CHAIN 6 838 #define INCREASE_MAXPOW_BY_THREE_CHAIN 10 839 struct ath_common *common = ath9k_hw_common(ah); 840 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 841 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 842 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader; 843 int16_t ratesArray[Ar5416RateSize]; 844 int16_t txPowerIndexOffset = 0; 845 u8 ht40PowerIncForPdadc = 2; 846 int i; 847 848 memset(ratesArray, 0, sizeof(ratesArray)); 849 850 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= 851 AR9287_EEP_MINOR_VER_2) 852 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 853 854 ath9k_hw_set_AR9287_power_per_rate_table(ah, chan, 855 &ratesArray[0], cfgCtl, 856 twiceAntennaReduction, 857 twiceMaxRegulatoryPower, 858 powerLimit); 859 860 ath9k_hw_set_AR9287_power_cal_table(ah, chan, &txPowerIndexOffset); 861 862 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 863 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 864 if (ratesArray[i] > AR9287_MAX_RATE_POWER) 865 ratesArray[i] = AR9287_MAX_RATE_POWER; 866 } 867 868 if (AR_SREV_9280_10_OR_LATER(ah)) { 869 for (i = 0; i < Ar5416RateSize; i++) 870 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; 871 } 872 873 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 874 ATH9K_POW_SM(ratesArray[rate18mb], 24) 875 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 876 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 877 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 878 879 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 880 ATH9K_POW_SM(ratesArray[rate54mb], 24) 881 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 882 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 883 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 884 885 if (IS_CHAN_2GHZ(chan)) { 886 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 887 ATH9K_POW_SM(ratesArray[rate2s], 24) 888 | ATH9K_POW_SM(ratesArray[rate2l], 16) 889 | ATH9K_POW_SM(ratesArray[rateXr], 8) 890 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 891 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 892 ATH9K_POW_SM(ratesArray[rate11s], 24) 893 | ATH9K_POW_SM(ratesArray[rate11l], 16) 894 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 895 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 896 } 897 898 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 899 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 900 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 901 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 902 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 903 904 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 905 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 906 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 907 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 908 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 909 910 if (IS_CHAN_HT40(chan)) { 911 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 912 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 913 ATH9K_POW_SM(ratesArray[rateHt40_3], 24) 914 | ATH9K_POW_SM(ratesArray[rateHt40_2], 16) 915 | ATH9K_POW_SM(ratesArray[rateHt40_1], 8) 916 | ATH9K_POW_SM(ratesArray[rateHt40_0], 0)); 917 918 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 919 ATH9K_POW_SM(ratesArray[rateHt40_7], 24) 920 | ATH9K_POW_SM(ratesArray[rateHt40_6], 16) 921 | ATH9K_POW_SM(ratesArray[rateHt40_5], 8) 922 | ATH9K_POW_SM(ratesArray[rateHt40_4], 0)); 923 } else { 924 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 925 ATH9K_POW_SM(ratesArray[rateHt40_3] + 926 ht40PowerIncForPdadc, 24) 927 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 928 ht40PowerIncForPdadc, 16) 929 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 930 ht40PowerIncForPdadc, 8) 931 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 932 ht40PowerIncForPdadc, 0)); 933 934 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 935 ATH9K_POW_SM(ratesArray[rateHt40_7] + 936 ht40PowerIncForPdadc, 24) 937 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 938 ht40PowerIncForPdadc, 16) 939 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 940 ht40PowerIncForPdadc, 8) 941 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 942 ht40PowerIncForPdadc, 0)); 943 } 944 945 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 946 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 947 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 948 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 949 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 950 } 951 952 if (IS_CHAN_2GHZ(chan)) 953 i = rate1l; 954 else 955 i = rate6mb; 956 957 if (AR_SREV_9280_10_OR_LATER(ah)) 958 regulatory->max_power_level = 959 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; 960 else 961 regulatory->max_power_level = ratesArray[i]; 962 963 switch (ar5416_get_ntxchains(ah->txchainmask)) { 964 case 1: 965 break; 966 case 2: 967 regulatory->max_power_level += 968 INCREASE_MAXPOW_BY_TWO_CHAIN; 969 break; 970 case 3: 971 regulatory->max_power_level += 972 INCREASE_MAXPOW_BY_THREE_CHAIN; 973 break; 974 default: 975 ath_print(common, ATH_DBG_EEPROM, 976 "Invalid chainmask configuration\n"); 977 break; 978 } 979 } 980 981 static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah, 982 struct ath9k_channel *chan) 983 { 984 } 985 986 static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, 987 struct ath9k_channel *chan) 988 { 989 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 990 struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 991 u16 antWrites[AR9287_ANT_16S]; 992 u32 regChainOffset; 993 u8 txRxAttenLocal; 994 int i, j, offset_num; 995 996 pModal = &eep->modalHeader; 997 998 antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF); 999 antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF); 1000 antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF); 1001 antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF); 1002 antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF); 1003 antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF); 1004 antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF); 1005 antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF); 1006 1007 offset_num = 8; 1008 1009 for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) { 1010 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf); 1011 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3); 1012 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3); 1013 antWrites[j++] = 0; 1014 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3); 1015 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3); 1016 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3); 1017 antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3); 1018 } 1019 1020 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1021 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); 1022 1023 for (i = 0; i < AR9287_MAX_CHAINS; i++) { 1024 regChainOffset = i * 0x1000; 1025 1026 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, 1027 pModal->antCtrlChain[i]); 1028 1029 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1030 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) 1031 & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1032 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1033 SM(pModal->iqCalICh[i], 1034 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1035 SM(pModal->iqCalQCh[i], 1036 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1037 1038 txRxAttenLocal = pModal->txRxAttenCh[i]; 1039 1040 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1041 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 1042 pModal->bswMargin[i]); 1043 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1044 AR_PHY_GAIN_2GHZ_XATTEN1_DB, 1045 pModal->bswAtten[i]); 1046 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1047 AR9280_PHY_RXGAIN_TXRX_ATTEN, 1048 txRxAttenLocal); 1049 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1050 AR9280_PHY_RXGAIN_TXRX_MARGIN, 1051 pModal->rxTxMarginCh[i]); 1052 } 1053 1054 1055 if (IS_CHAN_HT40(chan)) 1056 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1057 AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); 1058 else 1059 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1060 AR_PHY_SETTLING_SWITCH, pModal->switchSettling); 1061 1062 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 1063 AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); 1064 1065 REG_WRITE(ah, AR_PHY_RF_CTL4, 1066 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 1067 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 1068 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) 1069 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1070 1071 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, 1072 AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); 1073 1074 REG_RMW_FIELD(ah, AR_PHY_CCA, 1075 AR9280_PHY_CCA_THRESH62, pModal->thresh62); 1076 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, 1077 AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62); 1078 1079 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB1, 1080 AR9287_AN_RF2G3_DB1_S, pModal->db1); 1081 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB2, 1082 AR9287_AN_RF2G3_DB2_S, pModal->db2); 1083 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, 1084 AR9287_AN_RF2G3_OB_CCK, 1085 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck); 1086 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, 1087 AR9287_AN_RF2G3_OB_PSK, 1088 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk); 1089 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, 1090 AR9287_AN_RF2G3_OB_QAM, 1091 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam); 1092 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, 1093 AR9287_AN_RF2G3_OB_PAL_OFF, 1094 AR9287_AN_RF2G3_OB_PAL_OFF_S, 1095 pModal->ob_pal_off); 1096 1097 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1098 AR9287_AN_RF2G3_DB1, AR9287_AN_RF2G3_DB1_S, 1099 pModal->db1); 1100 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, AR9287_AN_RF2G3_DB2, 1101 AR9287_AN_RF2G3_DB2_S, pModal->db2); 1102 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1103 AR9287_AN_RF2G3_OB_CCK, 1104 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck); 1105 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1106 AR9287_AN_RF2G3_OB_PSK, 1107 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk); 1108 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1109 AR9287_AN_RF2G3_OB_QAM, 1110 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam); 1111 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1112 AR9287_AN_RF2G3_OB_PAL_OFF, 1113 AR9287_AN_RF2G3_OB_PAL_OFF_S, 1114 pModal->ob_pal_off); 1115 1116 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, 1117 AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart); 1118 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, 1119 AR_PHY_TX_END_PA_ON, pModal->txFrameToPaOn); 1120 1121 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TOP2, 1122 AR9287_AN_TOP2_XPABIAS_LVL, 1123 AR9287_AN_TOP2_XPABIAS_LVL_S, 1124 pModal->xpaBiasLvl); 1125 } 1126 1127 static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah, 1128 enum ieee80211_band freq_band) 1129 { 1130 return 1; 1131 } 1132 1133 static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah, 1134 struct ath9k_channel *chan) 1135 { 1136 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 1137 struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 1138 1139 return pModal->antCtrlCommon & 0xFFFF; 1140 } 1141 1142 static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah, 1143 u16 i, bool is2GHz) 1144 { 1145 #define EEP_MAP9287_SPURCHAN \ 1146 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan) 1147 struct ath_common *common = ath9k_hw_common(ah); 1148 u16 spur_val = AR_NO_SPUR; 1149 1150 ath_print(common, ATH_DBG_ANI, 1151 "Getting spur idx %d is2Ghz. %d val %x\n", 1152 i, is2GHz, ah->config.spurchans[i][is2GHz]); 1153 1154 switch (ah->config.spurmode) { 1155 case SPUR_DISABLE: 1156 break; 1157 case SPUR_ENABLE_IOCTL: 1158 spur_val = ah->config.spurchans[i][is2GHz]; 1159 ath_print(common, ATH_DBG_ANI, 1160 "Getting spur val from new loc. %d\n", spur_val); 1161 break; 1162 case SPUR_ENABLE_EEPROM: 1163 spur_val = EEP_MAP9287_SPURCHAN; 1164 break; 1165 } 1166 1167 return spur_val; 1168 1169 #undef EEP_MAP9287_SPURCHAN 1170 } 1171 1172 const struct eeprom_ops eep_AR9287_ops = { 1173 .check_eeprom = ath9k_hw_AR9287_check_eeprom, 1174 .get_eeprom = ath9k_hw_AR9287_get_eeprom, 1175 .fill_eeprom = ath9k_hw_AR9287_fill_eeprom, 1176 .get_eeprom_ver = ath9k_hw_AR9287_get_eeprom_ver, 1177 .get_eeprom_rev = ath9k_hw_AR9287_get_eeprom_rev, 1178 .get_num_ant_config = ath9k_hw_AR9287_get_num_ant_config, 1179 .get_eeprom_antenna_cfg = ath9k_hw_AR9287_get_eeprom_antenna_cfg, 1180 .set_board_values = ath9k_hw_AR9287_set_board_values, 1181 .set_addac = ath9k_hw_AR9287_set_addac, 1182 .set_txpower = ath9k_hw_AR9287_set_txpower, 1183 .get_spur_channel = ath9k_hw_AR9287_get_spur_channel 1184 }; 1185