1/* 2 * Copyright (c) 2008-2011 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 <asm/unaligned.h> 18#include "hw.h" 19#include "ar9002_phy.h" 20 21static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) 22{ 23 return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF); 24} 25 26static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) 27{ 28 return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF); 29} 30 31#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 32 33static bool __ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) 34{ 35 struct ath_common *common = ath9k_hw_common(ah); 36 u16 *eep_data = (u16 *)&ah->eeprom.map4k; 37 int addr, eep_start_loc = 64; 38 39 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { 40 if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { 41 ath_dbg(common, EEPROM, 42 "Unable to read eeprom region\n"); 43 return false; 44 } 45 eep_data++; 46 } 47 48 return true; 49} 50 51static bool __ath9k_hw_usb_4k_fill_eeprom(struct ath_hw *ah) 52{ 53 u16 *eep_data = (u16 *)&ah->eeprom.map4k; 54 55 ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, 64, SIZE_EEPROM_4K); 56 57 return true; 58} 59 60static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) 61{ 62 struct ath_common *common = ath9k_hw_common(ah); 63 64 if (!ath9k_hw_use_flash(ah)) { 65 ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n"); 66 } 67 68 if (common->bus_ops->ath_bus_type == ATH_USB) 69 return __ath9k_hw_usb_4k_fill_eeprom(ah); 70 else 71 return __ath9k_hw_4k_fill_eeprom(ah); 72} 73 74#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS) 75static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size, 76 struct modal_eep_4k_header *modal_hdr) 77{ 78 PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]); 79 PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon); 80 PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]); 81 PR_EEP("Switch Settle", modal_hdr->switchSettling); 82 PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]); 83 PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]); 84 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize); 85 PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize); 86 PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]); 87 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff); 88 PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn); 89 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn); 90 PR_EEP("CCA Threshold)", modal_hdr->thresh62); 91 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]); 92 PR_EEP("xpdGain", modal_hdr->xpdGain); 93 PR_EEP("External PD", modal_hdr->xpd); 94 PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]); 95 PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]); 96 PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap); 97 PR_EEP("O/D Bias Version", modal_hdr->version); 98 PR_EEP("CCK OutputBias", modal_hdr->ob_0); 99 PR_EEP("BPSK OutputBias", modal_hdr->ob_1); 100 PR_EEP("QPSK OutputBias", modal_hdr->ob_2); 101 PR_EEP("16QAM OutputBias", modal_hdr->ob_3); 102 PR_EEP("64QAM OutputBias", modal_hdr->ob_4); 103 PR_EEP("CCK Driver1_Bias", modal_hdr->db1_0); 104 PR_EEP("BPSK Driver1_Bias", modal_hdr->db1_1); 105 PR_EEP("QPSK Driver1_Bias", modal_hdr->db1_2); 106 PR_EEP("16QAM Driver1_Bias", modal_hdr->db1_3); 107 PR_EEP("64QAM Driver1_Bias", modal_hdr->db1_4); 108 PR_EEP("CCK Driver2_Bias", modal_hdr->db2_0); 109 PR_EEP("BPSK Driver2_Bias", modal_hdr->db2_1); 110 PR_EEP("QPSK Driver2_Bias", modal_hdr->db2_2); 111 PR_EEP("16QAM Driver2_Bias", modal_hdr->db2_3); 112 PR_EEP("64QAM Driver2_Bias", modal_hdr->db2_4); 113 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl); 114 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart); 115 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn); 116 PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc); 117 PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]); 118 PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]); 119 PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40); 120 PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]); 121 PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]); 122 PR_EEP("Ant. Diversity ctl1", modal_hdr->antdiv_ctl1); 123 PR_EEP("Ant. Diversity ctl2", modal_hdr->antdiv_ctl2); 124 PR_EEP("TX Diversity", modal_hdr->tx_diversity); 125 126 return len; 127} 128 129static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, 130 u8 *buf, u32 len, u32 size) 131{ 132 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 133 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 134 135 if (!dump_base_hdr) { 136 len += snprintf(buf + len, size - len, 137 "%20s :\n", "2GHz modal Header"); 138 len += ath9k_dump_4k_modal_eeprom(buf, len, size, 139 &eep->modalHeader); 140 goto out; 141 } 142 143 PR_EEP("Major Version", pBase->version >> 12); 144 PR_EEP("Minor Version", pBase->version & 0xFFF); 145 PR_EEP("Checksum", pBase->checksum); 146 PR_EEP("Length", pBase->length); 147 PR_EEP("RegDomain1", pBase->regDmn[0]); 148 PR_EEP("RegDomain2", pBase->regDmn[1]); 149 PR_EEP("TX Mask", pBase->txMask); 150 PR_EEP("RX Mask", pBase->rxMask); 151 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); 152 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); 153 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags & 154 AR5416_OPFLAGS_N_2G_HT20)); 155 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags & 156 AR5416_OPFLAGS_N_2G_HT40)); 157 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags & 158 AR5416_OPFLAGS_N_5G_HT20)); 159 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags & 160 AR5416_OPFLAGS_N_5G_HT40)); 161 PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01)); 162 PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF); 163 PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF); 164 PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); 165 PR_EEP("TX Gain type", pBase->txGainType); 166 167 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", 168 pBase->macAddr); 169 170out: 171 if (len > size) 172 len = size; 173 174 return len; 175} 176#else 177static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, 178 u8 *buf, u32 len, u32 size) 179{ 180 return 0; 181} 182#endif 183 184 185#undef SIZE_EEPROM_4K 186 187static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) 188{ 189#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 190 struct ath_common *common = ath9k_hw_common(ah); 191 struct ar5416_eeprom_4k *eep = 192 (struct ar5416_eeprom_4k *) &ah->eeprom.map4k; 193 u16 *eepdata, temp, magic, magic2; 194 u32 sum = 0, el; 195 bool need_swap = false; 196 int i, addr; 197 198 199 if (!ath9k_hw_use_flash(ah)) { 200 if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, 201 &magic)) { 202 ath_err(common, "Reading Magic # failed\n"); 203 return false; 204 } 205 206 ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); 207 208 if (magic != AR5416_EEPROM_MAGIC) { 209 magic2 = swab16(magic); 210 211 if (magic2 == AR5416_EEPROM_MAGIC) { 212 need_swap = true; 213 eepdata = (u16 *) (&ah->eeprom); 214 215 for (addr = 0; addr < EEPROM_4K_SIZE; addr++) { 216 temp = swab16(*eepdata); 217 *eepdata = temp; 218 eepdata++; 219 } 220 } else { 221 ath_err(common, 222 "Invalid EEPROM Magic. Endianness mismatch.\n"); 223 return -EINVAL; 224 } 225 } 226 } 227 228 ath_dbg(common, EEPROM, "need_swap = %s\n", 229 need_swap ? "True" : "False"); 230 231 if (need_swap) 232 el = swab16(ah->eeprom.map4k.baseEepHeader.length); 233 else 234 el = ah->eeprom.map4k.baseEepHeader.length; 235 236 if (el > sizeof(struct ar5416_eeprom_4k)) 237 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16); 238 else 239 el = el / sizeof(u16); 240 241 eepdata = (u16 *)(&ah->eeprom); 242 243 for (i = 0; i < el; i++) 244 sum ^= *eepdata++; 245 246 if (need_swap) { 247 u32 integer; 248 u16 word; 249 250 ath_dbg(common, EEPROM, 251 "EEPROM Endianness is not native.. Changing\n"); 252 253 word = swab16(eep->baseEepHeader.length); 254 eep->baseEepHeader.length = word; 255 256 word = swab16(eep->baseEepHeader.checksum); 257 eep->baseEepHeader.checksum = word; 258 259 word = swab16(eep->baseEepHeader.version); 260 eep->baseEepHeader.version = word; 261 262 word = swab16(eep->baseEepHeader.regDmn[0]); 263 eep->baseEepHeader.regDmn[0] = word; 264 265 word = swab16(eep->baseEepHeader.regDmn[1]); 266 eep->baseEepHeader.regDmn[1] = word; 267 268 word = swab16(eep->baseEepHeader.rfSilent); 269 eep->baseEepHeader.rfSilent = word; 270 271 word = swab16(eep->baseEepHeader.blueToothOptions); 272 eep->baseEepHeader.blueToothOptions = word; 273 274 word = swab16(eep->baseEepHeader.deviceCap); 275 eep->baseEepHeader.deviceCap = word; 276 277 integer = swab32(eep->modalHeader.antCtrlCommon); 278 eep->modalHeader.antCtrlCommon = integer; 279 280 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { 281 integer = swab32(eep->modalHeader.antCtrlChain[i]); 282 eep->modalHeader.antCtrlChain[i] = integer; 283 } 284 285 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 286 word = swab16(eep->modalHeader.spurChans[i].spurChan); 287 eep->modalHeader.spurChans[i].spurChan = word; 288 } 289 } 290 291 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || 292 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { 293 ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 294 sum, ah->eep_ops->get_eeprom_ver(ah)); 295 return -EINVAL; 296 } 297 298 return 0; 299#undef EEPROM_4K_SIZE 300} 301 302static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, 303 enum eeprom_param param) 304{ 305 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 306 struct modal_eep_4k_header *pModal = &eep->modalHeader; 307 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 308 u16 ver_minor; 309 310 ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK; 311 312 switch (param) { 313 case EEP_NFTHRESH_2: 314 return pModal->noiseFloorThreshCh[0]; 315 case EEP_MAC_LSW: 316 return get_unaligned_be16(pBase->macAddr); 317 case EEP_MAC_MID: 318 return get_unaligned_be16(pBase->macAddr + 2); 319 case EEP_MAC_MSW: 320 return get_unaligned_be16(pBase->macAddr + 4); 321 case EEP_REG_0: 322 return pBase->regDmn[0]; 323 case EEP_OP_CAP: 324 return pBase->deviceCap; 325 case EEP_OP_MODE: 326 return pBase->opCapFlags; 327 case EEP_RF_SILENT: 328 return pBase->rfSilent; 329 case EEP_OB_2: 330 return pModal->ob_0; 331 case EEP_DB_2: 332 return pModal->db1_1; 333 case EEP_MINOR_REV: 334 return ver_minor; 335 case EEP_TX_MASK: 336 return pBase->txMask; 337 case EEP_RX_MASK: 338 return pBase->rxMask; 339 case EEP_FRAC_N_5G: 340 return 0; 341 case EEP_PWR_TABLE_OFFSET: 342 return AR5416_PWR_TABLE_OFFSET_DB; 343 case EEP_MODAL_VER: 344 return pModal->version; 345 case EEP_ANT_DIV_CTL1: 346 return pModal->antdiv_ctl1; 347 case EEP_TXGAIN_TYPE: 348 return pBase->txGainType; 349 case EEP_ANTENNA_GAIN_2G: 350 return pModal->antennaGainCh[0]; 351 default: 352 return 0; 353 } 354} 355 356static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, 357 struct ath9k_channel *chan) 358{ 359 struct ath_common *common = ath9k_hw_common(ah); 360 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 361 struct cal_data_per_freq_4k *pRawDataset; 362 u8 *pCalBChans = NULL; 363 u16 pdGainOverlap_t2; 364 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; 365 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; 366 u16 numPiers, i, j; 367 u16 numXpdGain, xpdMask; 368 u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 }; 369 u32 reg32, regOffset, regChainOffset; 370 371 xpdMask = pEepData->modalHeader.xpdGain; 372 373 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 374 AR5416_EEP_MINOR_VER_2) { 375 pdGainOverlap_t2 = 376 pEepData->modalHeader.pdGainOverlap; 377 } else { 378 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), 379 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 380 } 381 382 pCalBChans = pEepData->calFreqPier2G; 383 numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS; 384 385 numXpdGain = 0; 386 387 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 388 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 389 if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS) 390 break; 391 xpdGainValues[numXpdGain] = 392 (u16)(AR5416_PD_GAINS_IN_MASK - i); 393 numXpdGain++; 394 } 395 } 396 397 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 398 (numXpdGain - 1) & 0x3); 399 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 400 xpdGainValues[0]); 401 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 402 xpdGainValues[1]); 403 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0); 404 405 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { 406 regChainOffset = i * 0x1000; 407 408 if (pEepData->baseEepHeader.txMask & (1 << i)) { 409 pRawDataset = pEepData->calPierData2G[i]; 410 411 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan, 412 pRawDataset, pCalBChans, 413 numPiers, pdGainOverlap_t2, 414 gainBoundaries, 415 pdadcValues, numXpdGain); 416 417 ENABLE_REGWRITE_BUFFER(ah); 418 419 REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 420 SM(pdGainOverlap_t2, 421 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) 422 | SM(gainBoundaries[0], 423 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) 424 | SM(gainBoundaries[1], 425 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) 426 | SM(gainBoundaries[2], 427 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) 428 | SM(gainBoundaries[3], 429 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 430 431 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 432 for (j = 0; j < 32; j++) { 433 reg32 = get_unaligned_le32(&pdadcValues[4 * j]); 434 REG_WRITE(ah, regOffset, reg32); 435 436 ath_dbg(common, EEPROM, 437 "PDADC (%d,%4x): %4.4x %8.8x\n", 438 i, regChainOffset, regOffset, 439 reg32); 440 ath_dbg(common, EEPROM, 441 "PDADC: Chain %d | " 442 "PDADC %3d Value %3d | " 443 "PDADC %3d Value %3d | " 444 "PDADC %3d Value %3d | " 445 "PDADC %3d Value %3d |\n", 446 i, 4 * j, pdadcValues[4 * j], 447 4 * j + 1, pdadcValues[4 * j + 1], 448 4 * j + 2, pdadcValues[4 * j + 2], 449 4 * j + 3, pdadcValues[4 * j + 3]); 450 451 regOffset += 4; 452 } 453 454 REGWRITE_BUFFER_FLUSH(ah); 455 } 456 } 457} 458 459static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, 460 struct ath9k_channel *chan, 461 int16_t *ratesArray, 462 u16 cfgCtl, 463 u16 antenna_reduction, 464 u16 powerLimit) 465{ 466#define CMP_TEST_GRP \ 467 (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) == \ 468 pEepData->ctlIndex[i]) \ 469 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ 470 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) 471 472 int i; 473 u16 twiceMinEdgePower; 474 u16 twiceMaxEdgePower; 475 u16 scaledPower = 0, minCtlPower; 476 u16 numCtlModes; 477 const u16 *pCtlMode; 478 u16 ctlMode, freq; 479 struct chan_centers centers; 480 struct cal_ctl_data_4k *rep; 481 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 482 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 483 0, { 0, 0, 0, 0} 484 }; 485 struct cal_target_power_leg targetPowerOfdmExt = { 486 0, { 0, 0, 0, 0} }, targetPowerCckExt = { 487 0, { 0, 0, 0, 0 } 488 }; 489 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 490 0, {0, 0, 0, 0} 491 }; 492 static const u16 ctlModesFor11g[] = { 493 CTL_11B, CTL_11G, CTL_2GHT20, 494 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 495 }; 496 497 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 498 499 scaledPower = powerLimit - antenna_reduction; 500 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 501 pCtlMode = ctlModesFor11g; 502 503 ath9k_hw_get_legacy_target_powers(ah, chan, 504 pEepData->calTargetPowerCck, 505 AR5416_NUM_2G_CCK_TARGET_POWERS, 506 &targetPowerCck, 4, false); 507 ath9k_hw_get_legacy_target_powers(ah, chan, 508 pEepData->calTargetPower2G, 509 AR5416_NUM_2G_20_TARGET_POWERS, 510 &targetPowerOfdm, 4, false); 511 ath9k_hw_get_target_powers(ah, chan, 512 pEepData->calTargetPower2GHT20, 513 AR5416_NUM_2G_20_TARGET_POWERS, 514 &targetPowerHt20, 8, false); 515 516 if (IS_CHAN_HT40(chan)) { 517 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 518 ath9k_hw_get_target_powers(ah, chan, 519 pEepData->calTargetPower2GHT40, 520 AR5416_NUM_2G_40_TARGET_POWERS, 521 &targetPowerHt40, 8, true); 522 ath9k_hw_get_legacy_target_powers(ah, chan, 523 pEepData->calTargetPowerCck, 524 AR5416_NUM_2G_CCK_TARGET_POWERS, 525 &targetPowerCckExt, 4, true); 526 ath9k_hw_get_legacy_target_powers(ah, chan, 527 pEepData->calTargetPower2G, 528 AR5416_NUM_2G_20_TARGET_POWERS, 529 &targetPowerOfdmExt, 4, true); 530 } 531 532 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 533 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 534 (pCtlMode[ctlMode] == CTL_2GHT40); 535 536 if (isHt40CtlMode) 537 freq = centers.synth_center; 538 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 539 freq = centers.ext_center; 540 else 541 freq = centers.ctl_center; 542 543 twiceMaxEdgePower = MAX_RATE_POWER; 544 545 for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) && 546 pEepData->ctlIndex[i]; i++) { 547 548 if (CMP_TEST_GRP) { 549 rep = &(pEepData->ctlData[i]); 550 551 twiceMinEdgePower = ath9k_hw_get_max_edge_power( 552 freq, 553 rep->ctlEdges[ 554 ar5416_get_ntxchains(ah->txchainmask) - 1], 555 IS_CHAN_2GHZ(chan), 556 AR5416_EEP4K_NUM_BAND_EDGES); 557 558 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 559 twiceMaxEdgePower = 560 min(twiceMaxEdgePower, 561 twiceMinEdgePower); 562 } else { 563 twiceMaxEdgePower = twiceMinEdgePower; 564 break; 565 } 566 } 567 } 568 569 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 570 571 switch (pCtlMode[ctlMode]) { 572 case CTL_11B: 573 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { 574 targetPowerCck.tPow2x[i] = 575 min((u16)targetPowerCck.tPow2x[i], 576 minCtlPower); 577 } 578 break; 579 case CTL_11G: 580 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { 581 targetPowerOfdm.tPow2x[i] = 582 min((u16)targetPowerOfdm.tPow2x[i], 583 minCtlPower); 584 } 585 break; 586 case CTL_2GHT20: 587 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { 588 targetPowerHt20.tPow2x[i] = 589 min((u16)targetPowerHt20.tPow2x[i], 590 minCtlPower); 591 } 592 break; 593 case CTL_11B_EXT: 594 targetPowerCckExt.tPow2x[0] = 595 min((u16)targetPowerCckExt.tPow2x[0], 596 minCtlPower); 597 break; 598 case CTL_11G_EXT: 599 targetPowerOfdmExt.tPow2x[0] = 600 min((u16)targetPowerOfdmExt.tPow2x[0], 601 minCtlPower); 602 break; 603 case CTL_2GHT40: 604 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 605 targetPowerHt40.tPow2x[i] = 606 min((u16)targetPowerHt40.tPow2x[i], 607 minCtlPower); 608 } 609 break; 610 default: 611 break; 612 } 613 } 614 615 ratesArray[rate6mb] = 616 ratesArray[rate9mb] = 617 ratesArray[rate12mb] = 618 ratesArray[rate18mb] = 619 ratesArray[rate24mb] = 620 targetPowerOfdm.tPow2x[0]; 621 622 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 623 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 624 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 625 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 626 627 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) 628 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 629 630 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 631 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 632 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 633 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 634 635 if (IS_CHAN_HT40(chan)) { 636 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { 637 ratesArray[rateHt40_0 + i] = 638 targetPowerHt40.tPow2x[i]; 639 } 640 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 641 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 642 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 643 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 644 } 645 646#undef CMP_TEST_GRP 647} 648 649static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, 650 struct ath9k_channel *chan, 651 u16 cfgCtl, 652 u8 twiceAntennaReduction, 653 u8 powerLimit, bool test) 654{ 655 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 656 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 657 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 658 int16_t ratesArray[Ar5416RateSize]; 659 u8 ht40PowerIncForPdadc = 2; 660 int i; 661 662 memset(ratesArray, 0, sizeof(ratesArray)); 663 664 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 665 AR5416_EEP_MINOR_VER_2) { 666 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 667 } 668 669 ath9k_hw_set_4k_power_per_rate_table(ah, chan, 670 &ratesArray[0], cfgCtl, 671 twiceAntennaReduction, 672 powerLimit); 673 674 ath9k_hw_set_4k_power_cal_table(ah, chan); 675 676 regulatory->max_power_level = 0; 677 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 678 if (ratesArray[i] > MAX_RATE_POWER) 679 ratesArray[i] = MAX_RATE_POWER; 680 681 if (ratesArray[i] > regulatory->max_power_level) 682 regulatory->max_power_level = ratesArray[i]; 683 } 684 685 if (test) 686 return; 687 688 for (i = 0; i < Ar5416RateSize; i++) 689 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; 690 691 ENABLE_REGWRITE_BUFFER(ah); 692 693 /* OFDM power per rate */ 694 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 695 ATH9K_POW_SM(ratesArray[rate18mb], 24) 696 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 697 | ATH9K_POW_SM(ratesArray[rate9mb], 8) 698 | ATH9K_POW_SM(ratesArray[rate6mb], 0)); 699 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 700 ATH9K_POW_SM(ratesArray[rate54mb], 24) 701 | ATH9K_POW_SM(ratesArray[rate48mb], 16) 702 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 703 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 704 705 /* CCK power per rate */ 706 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 707 ATH9K_POW_SM(ratesArray[rate2s], 24) 708 | ATH9K_POW_SM(ratesArray[rate2l], 16) 709 | ATH9K_POW_SM(ratesArray[rateXr], 8) 710 | ATH9K_POW_SM(ratesArray[rate1l], 0)); 711 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 712 ATH9K_POW_SM(ratesArray[rate11s], 24) 713 | ATH9K_POW_SM(ratesArray[rate11l], 16) 714 | ATH9K_POW_SM(ratesArray[rate5_5s], 8) 715 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 716 717 /* HT20 power per rate */ 718 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 719 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 720 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 721 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) 722 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); 723 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 724 ATH9K_POW_SM(ratesArray[rateHt20_7], 24) 725 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) 726 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 727 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 728 729 /* HT40 power per rate */ 730 if (IS_CHAN_HT40(chan)) { 731 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 732 ATH9K_POW_SM(ratesArray[rateHt40_3] + 733 ht40PowerIncForPdadc, 24) 734 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 735 ht40PowerIncForPdadc, 16) 736 | ATH9K_POW_SM(ratesArray[rateHt40_1] + 737 ht40PowerIncForPdadc, 8) 738 | ATH9K_POW_SM(ratesArray[rateHt40_0] + 739 ht40PowerIncForPdadc, 0)); 740 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 741 ATH9K_POW_SM(ratesArray[rateHt40_7] + 742 ht40PowerIncForPdadc, 24) 743 | ATH9K_POW_SM(ratesArray[rateHt40_6] + 744 ht40PowerIncForPdadc, 16) 745 | ATH9K_POW_SM(ratesArray[rateHt40_5] + 746 ht40PowerIncForPdadc, 8) 747 | ATH9K_POW_SM(ratesArray[rateHt40_4] + 748 ht40PowerIncForPdadc, 0)); 749 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 750 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 751 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 752 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 753 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 754 } 755 756 REGWRITE_BUFFER_FLUSH(ah); 757} 758 759static void ath9k_hw_4k_set_gain(struct ath_hw *ah, 760 struct modal_eep_4k_header *pModal, 761 struct ar5416_eeprom_4k *eep, 762 u8 txRxAttenLocal) 763{ 764 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0, 765 pModal->antCtrlChain[0]); 766 767 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), 768 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & 769 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 770 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 771 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 772 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 773 774 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 775 AR5416_EEP_MINOR_VER_3) { 776 txRxAttenLocal = pModal->txRxAttenCh[0]; 777 778 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 779 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]); 780 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 781 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 782 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 783 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 784 pModal->xatten2Margin[0]); 785 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, 786 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); 787 788 /* Set the block 1 value to block 0 value */ 789 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 790 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 791 pModal->bswMargin[0]); 792 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 793 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); 794 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 795 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 796 pModal->xatten2Margin[0]); 797 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000, 798 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 799 pModal->xatten2Db[0]); 800 } 801 802 REG_RMW_FIELD(ah, AR_PHY_RXGAIN, 803 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 804 REG_RMW_FIELD(ah, AR_PHY_RXGAIN, 805 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 806 807 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, 808 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 809 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, 810 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 811} 812 813/* 814 * Read EEPROM header info and program the device for correct operation 815 * given the channel value. 816 */ 817static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, 818 struct ath9k_channel *chan) 819{ 820 struct modal_eep_4k_header *pModal; 821 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 822 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 823 u8 txRxAttenLocal; 824 u8 ob[5], db1[5], db2[5]; 825 u8 ant_div_control1, ant_div_control2; 826 u8 bb_desired_scale; 827 u32 regVal; 828 829 pModal = &eep->modalHeader; 830 txRxAttenLocal = 23; 831 832 REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 833 834 /* Single chain for 4K EEPROM*/ 835 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal); 836 837 /* Initialize Ant Diversity settings from EEPROM */ 838 if (pModal->version >= 3) { 839 ant_div_control1 = pModal->antdiv_ctl1; 840 ant_div_control2 = pModal->antdiv_ctl2; 841 842 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 843 regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL)); 844 845 regVal |= SM(ant_div_control1, 846 AR_PHY_9285_ANT_DIV_CTL); 847 regVal |= SM(ant_div_control2, 848 AR_PHY_9285_ANT_DIV_ALT_LNACONF); 849 regVal |= SM((ant_div_control2 >> 2), 850 AR_PHY_9285_ANT_DIV_MAIN_LNACONF); 851 regVal |= SM((ant_div_control1 >> 1), 852 AR_PHY_9285_ANT_DIV_ALT_GAINTB); 853 regVal |= SM((ant_div_control1 >> 2), 854 AR_PHY_9285_ANT_DIV_MAIN_GAINTB); 855 856 857 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal); 858 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 859 regVal = REG_READ(ah, AR_PHY_CCK_DETECT); 860 regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 861 regVal |= SM((ant_div_control1 >> 3), 862 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 863 864 REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal); 865 regVal = REG_READ(ah, AR_PHY_CCK_DETECT); 866 } 867 868 if (pModal->version >= 2) { 869 ob[0] = pModal->ob_0; 870 ob[1] = pModal->ob_1; 871 ob[2] = pModal->ob_2; 872 ob[3] = pModal->ob_3; 873 ob[4] = pModal->ob_4; 874 875 db1[0] = pModal->db1_0; 876 db1[1] = pModal->db1_1; 877 db1[2] = pModal->db1_2; 878 db1[3] = pModal->db1_3; 879 db1[4] = pModal->db1_4; 880 881 db2[0] = pModal->db2_0; 882 db2[1] = pModal->db2_1; 883 db2[2] = pModal->db2_2; 884 db2[3] = pModal->db2_3; 885 db2[4] = pModal->db2_4; 886 } else if (pModal->version == 1) { 887 ob[0] = pModal->ob_0; 888 ob[1] = ob[2] = ob[3] = ob[4] = pModal->ob_1; 889 db1[0] = pModal->db1_0; 890 db1[1] = db1[2] = db1[3] = db1[4] = pModal->db1_1; 891 db2[0] = pModal->db2_0; 892 db2[1] = db2[2] = db2[3] = db2[4] = pModal->db2_1; 893 } else { 894 int i; 895 896 for (i = 0; i < 5; i++) { 897 ob[i] = pModal->ob_0; 898 db1[i] = pModal->db1_0; 899 db2[i] = pModal->db1_0; 900 } 901 } 902 903 if (AR_SREV_9271(ah)) { 904 ath9k_hw_analog_shift_rmw(ah, 905 AR9285_AN_RF2G3, 906 AR9271_AN_RF2G3_OB_cck, 907 AR9271_AN_RF2G3_OB_cck_S, 908 ob[0]); 909 ath9k_hw_analog_shift_rmw(ah, 910 AR9285_AN_RF2G3, 911 AR9271_AN_RF2G3_OB_psk, 912 AR9271_AN_RF2G3_OB_psk_S, 913 ob[1]); 914 ath9k_hw_analog_shift_rmw(ah, 915 AR9285_AN_RF2G3, 916 AR9271_AN_RF2G3_OB_qam, 917 AR9271_AN_RF2G3_OB_qam_S, 918 ob[2]); 919 ath9k_hw_analog_shift_rmw(ah, 920 AR9285_AN_RF2G3, 921 AR9271_AN_RF2G3_DB_1, 922 AR9271_AN_RF2G3_DB_1_S, 923 db1[0]); 924 ath9k_hw_analog_shift_rmw(ah, 925 AR9285_AN_RF2G4, 926 AR9271_AN_RF2G4_DB_2, 927 AR9271_AN_RF2G4_DB_2_S, 928 db2[0]); 929 } else { 930 ath9k_hw_analog_shift_rmw(ah, 931 AR9285_AN_RF2G3, 932 AR9285_AN_RF2G3_OB_0, 933 AR9285_AN_RF2G3_OB_0_S, 934 ob[0]); 935 ath9k_hw_analog_shift_rmw(ah, 936 AR9285_AN_RF2G3, 937 AR9285_AN_RF2G3_OB_1, 938 AR9285_AN_RF2G3_OB_1_S, 939 ob[1]); 940 ath9k_hw_analog_shift_rmw(ah, 941 AR9285_AN_RF2G3, 942 AR9285_AN_RF2G3_OB_2, 943 AR9285_AN_RF2G3_OB_2_S, 944 ob[2]); 945 ath9k_hw_analog_shift_rmw(ah, 946 AR9285_AN_RF2G3, 947 AR9285_AN_RF2G3_OB_3, 948 AR9285_AN_RF2G3_OB_3_S, 949 ob[3]); 950 ath9k_hw_analog_shift_rmw(ah, 951 AR9285_AN_RF2G3, 952 AR9285_AN_RF2G3_OB_4, 953 AR9285_AN_RF2G3_OB_4_S, 954 ob[4]); 955 956 ath9k_hw_analog_shift_rmw(ah, 957 AR9285_AN_RF2G3, 958 AR9285_AN_RF2G3_DB1_0, 959 AR9285_AN_RF2G3_DB1_0_S, 960 db1[0]); 961 ath9k_hw_analog_shift_rmw(ah, 962 AR9285_AN_RF2G3, 963 AR9285_AN_RF2G3_DB1_1, 964 AR9285_AN_RF2G3_DB1_1_S, 965 db1[1]); 966 ath9k_hw_analog_shift_rmw(ah, 967 AR9285_AN_RF2G3, 968 AR9285_AN_RF2G3_DB1_2, 969 AR9285_AN_RF2G3_DB1_2_S, 970 db1[2]); 971 ath9k_hw_analog_shift_rmw(ah, 972 AR9285_AN_RF2G4, 973 AR9285_AN_RF2G4_DB1_3, 974 AR9285_AN_RF2G4_DB1_3_S, 975 db1[3]); 976 ath9k_hw_analog_shift_rmw(ah, 977 AR9285_AN_RF2G4, 978 AR9285_AN_RF2G4_DB1_4, 979 AR9285_AN_RF2G4_DB1_4_S, db1[4]); 980 981 ath9k_hw_analog_shift_rmw(ah, 982 AR9285_AN_RF2G4, 983 AR9285_AN_RF2G4_DB2_0, 984 AR9285_AN_RF2G4_DB2_0_S, 985 db2[0]); 986 ath9k_hw_analog_shift_rmw(ah, 987 AR9285_AN_RF2G4, 988 AR9285_AN_RF2G4_DB2_1, 989 AR9285_AN_RF2G4_DB2_1_S, 990 db2[1]); 991 ath9k_hw_analog_shift_rmw(ah, 992 AR9285_AN_RF2G4, 993 AR9285_AN_RF2G4_DB2_2, 994 AR9285_AN_RF2G4_DB2_2_S, 995 db2[2]); 996 ath9k_hw_analog_shift_rmw(ah, 997 AR9285_AN_RF2G4, 998 AR9285_AN_RF2G4_DB2_3, 999 AR9285_AN_RF2G4_DB2_3_S, 1000 db2[3]); 1001 ath9k_hw_analog_shift_rmw(ah, 1002 AR9285_AN_RF2G4, 1003 AR9285_AN_RF2G4_DB2_4, 1004 AR9285_AN_RF2G4_DB2_4_S, 1005 db2[4]); 1006 } 1007 1008 1009 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 1010 pModal->switchSettling); 1011 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 1012 pModal->adcDesiredSize); 1013 1014 REG_WRITE(ah, AR_PHY_RF_CTL4, 1015 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | 1016 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | 1017 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | 1018 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1019 1020 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 1021 pModal->txEndToRxOn); 1022 1023 if (AR_SREV_9271_10(ah)) 1024 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 1025 pModal->txEndToRxOn); 1026 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1027 pModal->thresh62); 1028 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 1029 pModal->thresh62); 1030 1031 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1032 AR5416_EEP_MINOR_VER_2) { 1033 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, 1034 pModal->txFrameToDataStart); 1035 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, 1036 pModal->txFrameToPaOn); 1037 } 1038 1039 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1040 AR5416_EEP_MINOR_VER_3) { 1041 if (IS_CHAN_HT40(chan)) 1042 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 1043 AR_PHY_SETTLING_SWITCH, 1044 pModal->swSettleHt40); 1045 } 1046 1047 bb_desired_scale = (pModal->bb_scale_smrt_antenna & 1048 EEP_4K_BB_DESIRED_SCALE_MASK); 1049 if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { 1050 u32 pwrctrl, mask, clr; 1051 1052 mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); 1053 pwrctrl = mask * bb_desired_scale; 1054 clr = mask * 0x1f; 1055 REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); 1056 REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); 1057 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); 1058 1059 mask = BIT(0)|BIT(5)|BIT(15); 1060 pwrctrl = mask * bb_desired_scale; 1061 clr = mask * 0x1f; 1062 REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); 1063 1064 mask = BIT(0)|BIT(5); 1065 pwrctrl = mask * bb_desired_scale; 1066 clr = mask * 0x1f; 1067 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); 1068 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); 1069 } 1070} 1071 1072static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1073{ 1074#define EEP_MAP4K_SPURCHAN \ 1075 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan) 1076 struct ath_common *common = ath9k_hw_common(ah); 1077 1078 u16 spur_val = AR_NO_SPUR; 1079 1080 ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n", 1081 i, is2GHz, ah->config.spurchans[i][is2GHz]); 1082 1083 switch (ah->config.spurmode) { 1084 case SPUR_DISABLE: 1085 break; 1086 case SPUR_ENABLE_IOCTL: 1087 spur_val = ah->config.spurchans[i][is2GHz]; 1088 ath_dbg(common, ANI, "Getting spur val from new loc. %d\n", 1089 spur_val); 1090 break; 1091 case SPUR_ENABLE_EEPROM: 1092 spur_val = EEP_MAP4K_SPURCHAN; 1093 break; 1094 } 1095 1096 return spur_val; 1097 1098#undef EEP_MAP4K_SPURCHAN 1099} 1100 1101const struct eeprom_ops eep_4k_ops = { 1102 .check_eeprom = ath9k_hw_4k_check_eeprom, 1103 .get_eeprom = ath9k_hw_4k_get_eeprom, 1104 .fill_eeprom = ath9k_hw_4k_fill_eeprom, 1105 .dump_eeprom = ath9k_hw_4k_dump_eeprom, 1106 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, 1107 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, 1108 .set_board_values = ath9k_hw_4k_set_board_values, 1109 .set_txpower = ath9k_hw_4k_set_txpower, 1110 .get_spur_channel = ath9k_hw_4k_get_spur_channel 1111}; 1112