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