7154 arn(7D) walks out of bounds when byteswapping the 4K eeprom
7152 weird condition in arn(7D) needs clarification
7153 delete unused code in arn(7D)
7155 arn(7D) should include the mac fields in the eeprom enumeration

   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 }
--- EOF ---