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_EEP4K_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, &centers);
 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, &centers);
 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, &centers);
 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, &centers);
 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, &centers);
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, &centers);
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, &centers);
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 }