linux/drivers/net/wireless/ath/ath9k/eeprom_def.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2008-2011 Atheros Communications Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include <asm/unaligned.h>
  18#include "hw.h"
  19#include "ar9002_phy.h"
  20
  21static void ath9k_get_txgain_index(struct ath_hw *ah,
  22                struct ath9k_channel *chan,
  23                struct calDataPerFreqOpLoop *rawDatasetOpLoop,
  24                u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
  25{
  26        u8 pcdac, i = 0;
  27        u16 idxL = 0, idxR = 0, numPiers;
  28        bool match;
  29        struct chan_centers centers;
  30
  31        ath9k_hw_get_channel_centers(ah, chan, &centers);
  32
  33        for (numPiers = 0; numPiers < availPiers; numPiers++)
  34                if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
  35                        break;
  36
  37        match = ath9k_hw_get_lower_upper_index(
  38                        (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
  39                        calChans, numPiers, &idxL, &idxR);
  40        if (match) {
  41                pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
  42                *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
  43        } else {
  44                pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
  45                *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
  46                                rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
  47        }
  48
  49        while (pcdac > ah->originalGain[i] &&
  50                        i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
  51                i++;
  52
  53        *pcdacIdx = i;
  54}
  55
  56static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
  57                                u32 initTxGain,
  58                                int txPower,
  59                                u8 *pPDADCValues)
  60{
  61        u32 i;
  62        u32 offset;
  63
  64        REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
  65                        AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
  66        REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
  67                        AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
  68
  69        REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
  70                        AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
  71
  72        offset = txPower;
  73        for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
  74                if (i < offset)
  75                        pPDADCValues[i] = 0x0;
  76                else
  77                        pPDADCValues[i] = 0xFF;
  78}
  79
  80static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
  81{
  82        return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
  83}
  84
  85static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
  86{
  87        return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
  88}
  89
  90#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
  91
  92static bool __ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
  93{
  94        u16 *eep_data = (u16 *)&ah->eeprom.def;
  95        int addr, ar5416_eep_start_loc = 0x100;
  96
  97        for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
  98                if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
  99                                         eep_data))
 100                        return false;
 101                eep_data++;
 102        }
 103        return true;
 104}
 105
 106static bool __ath9k_hw_usb_def_fill_eeprom(struct ath_hw *ah)
 107{
 108        u16 *eep_data = (u16 *)&ah->eeprom.def;
 109
 110        ath9k_hw_usb_gen_fill_eeprom(ah, eep_data,
 111                                     0x100, SIZE_EEPROM_DEF);
 112        return true;
 113}
 114
 115static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
 116{
 117        struct ath_common *common = ath9k_hw_common(ah);
 118
 119        if (!ath9k_hw_use_flash(ah)) {
 120                ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
 121        }
 122
 123        if (common->bus_ops->ath_bus_type == ATH_USB)
 124                return __ath9k_hw_usb_def_fill_eeprom(ah);
 125        else
 126                return __ath9k_hw_def_fill_eeprom(ah);
 127}
 128
 129#undef SIZE_EEPROM_DEF
 130
 131#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
 132static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
 133                                       struct modal_eep_header *modal_hdr)
 134{
 135        PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
 136        PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]);
 137        PR_EEP("Chain2 Ant. Control", modal_hdr->antCtrlChain[2]);
 138        PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
 139        PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
 140        PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
 141        PR_EEP("Chain2 Ant. Gain", modal_hdr->antennaGainCh[2]);
 142        PR_EEP("Switch Settle", modal_hdr->switchSettling);
 143        PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
 144        PR_EEP("Chain1 TxRxAtten", modal_hdr->txRxAttenCh[1]);
 145        PR_EEP("Chain2 TxRxAtten", modal_hdr->txRxAttenCh[2]);
 146        PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
 147        PR_EEP("Chain1 RxTxMargin", modal_hdr->rxTxMarginCh[1]);
 148        PR_EEP("Chain2 RxTxMargin", modal_hdr->rxTxMarginCh[2]);
 149        PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
 150        PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize);
 151        PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]);
 152        PR_EEP("Chain1 xlna Gain", modal_hdr->xlnaGainCh[1]);
 153        PR_EEP("Chain2 xlna Gain", modal_hdr->xlnaGainCh[2]);
 154        PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
 155        PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
 156        PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
 157        PR_EEP("CCA Threshold)", modal_hdr->thresh62);
 158        PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
 159        PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
 160        PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
 161        PR_EEP("xpdGain", modal_hdr->xpdGain);
 162        PR_EEP("External PD", modal_hdr->xpd);
 163        PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
 164        PR_EEP("Chain1 I Coefficient", modal_hdr->iqCalICh[1]);
 165        PR_EEP("Chain2 I Coefficient", modal_hdr->iqCalICh[2]);
 166        PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
 167        PR_EEP("Chain1 Q Coefficient", modal_hdr->iqCalQCh[1]);
 168        PR_EEP("Chain2 Q Coefficient", modal_hdr->iqCalQCh[2]);
 169        PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
 170        PR_EEP("Chain0 OutputBias", modal_hdr->ob);
 171        PR_EEP("Chain0 DriverBias", modal_hdr->db);
 172        PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
 173        PR_EEP("2chain pwr decrease", modal_hdr->pwrDecreaseFor2Chain);
 174        PR_EEP("3chain pwr decrease", modal_hdr->pwrDecreaseFor3Chain);
 175        PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
 176        PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
 177        PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
 178        PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
 179        PR_EEP("Chain1 bswAtten", modal_hdr->bswAtten[1]);
 180        PR_EEP("Chain2 bswAtten", modal_hdr->bswAtten[2]);
 181        PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
 182        PR_EEP("Chain1 bswMargin", modal_hdr->bswMargin[1]);
 183        PR_EEP("Chain2 bswMargin", modal_hdr->bswMargin[2]);
 184        PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
 185        PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]);
 186        PR_EEP("Chain1 xatten2Db", modal_hdr->xatten2Db[1]);
 187        PR_EEP("Chain2 xatten2Db", modal_hdr->xatten2Db[2]);
 188        PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]);
 189        PR_EEP("Chain1 xatten2Margin", modal_hdr->xatten2Margin[1]);
 190        PR_EEP("Chain2 xatten2Margin", modal_hdr->xatten2Margin[2]);
 191        PR_EEP("Chain1 OutputBias", modal_hdr->ob_ch1);
 192        PR_EEP("Chain1 DriverBias", modal_hdr->db_ch1);
 193        PR_EEP("LNA Control", modal_hdr->lna_ctl);
 194        PR_EEP("XPA Bias Freq0", modal_hdr->xpaBiasLvlFreq[0]);
 195        PR_EEP("XPA Bias Freq1", modal_hdr->xpaBiasLvlFreq[1]);
 196        PR_EEP("XPA Bias Freq2", modal_hdr->xpaBiasLvlFreq[2]);
 197
 198        return len;
 199}
 200
 201static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
 202                                    u8 *buf, u32 len, u32 size)
 203{
 204        struct ar5416_eeprom_def *eep = &ah->eeprom.def;
 205        struct base_eep_header *pBase = &eep->baseEepHeader;
 206
 207        if (!dump_base_hdr) {
 208                len += snprintf(buf + len, size - len,
 209                                "%20s :\n", "2GHz modal Header");
 210                len = ath9k_def_dump_modal_eeprom(buf, len, size,
 211                                                   &eep->modalHeader[0]);
 212                len += snprintf(buf + len, size - len,
 213                                "%20s :\n", "5GHz modal Header");
 214                len = ath9k_def_dump_modal_eeprom(buf, len, size,
 215                                                   &eep->modalHeader[1]);
 216                goto out;
 217        }
 218
 219        PR_EEP("Major Version", pBase->version >> 12);
 220        PR_EEP("Minor Version", pBase->version & 0xFFF);
 221        PR_EEP("Checksum", pBase->checksum);
 222        PR_EEP("Length", pBase->length);
 223        PR_EEP("RegDomain1", pBase->regDmn[0]);
 224        PR_EEP("RegDomain2", pBase->regDmn[1]);
 225        PR_EEP("TX Mask", pBase->txMask);
 226        PR_EEP("RX Mask", pBase->rxMask);
 227        PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
 228        PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
 229        PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
 230                                        AR5416_OPFLAGS_N_2G_HT20));
 231        PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
 232                                        AR5416_OPFLAGS_N_2G_HT40));
 233        PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
 234                                        AR5416_OPFLAGS_N_5G_HT20));
 235        PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
 236                                        AR5416_OPFLAGS_N_5G_HT40));
 237        PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
 238        PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
 239        PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
 240        PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
 241        PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);
 242
 243        len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
 244                        pBase->macAddr);
 245
 246out:
 247        if (len > size)
 248                len = size;
 249
 250        return len;
 251}
 252#else
 253static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
 254                                    u8 *buf, u32 len, u32 size)
 255{
 256        return 0;
 257}
 258#endif
 259
 260
 261static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
 262{
 263        struct ar5416_eeprom_def *eep = &ah->eeprom.def;
 264        struct ath_common *common = ath9k_hw_common(ah);
 265        u16 *eepdata, temp, magic, magic2;
 266        u32 sum = 0, el;
 267        bool need_swap = false;
 268        int i, addr, size;
 269
 270        if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
 271                ath_err(common, "Reading Magic # failed\n");
 272                return false;
 273        }
 274
 275        if (!ath9k_hw_use_flash(ah)) {
 276                ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic);
 277
 278                if (magic != AR5416_EEPROM_MAGIC) {
 279                        magic2 = swab16(magic);
 280
 281                        if (magic2 == AR5416_EEPROM_MAGIC) {
 282                                size = sizeof(struct ar5416_eeprom_def);
 283                                need_swap = true;
 284                                eepdata = (u16 *) (&ah->eeprom);
 285
 286                                for (addr = 0; addr < size / sizeof(u16); addr++) {
 287                                        temp = swab16(*eepdata);
 288                                        *eepdata = temp;
 289                                        eepdata++;
 290                                }
 291                        } else {
 292                                ath_err(common,
 293                                        "Invalid EEPROM Magic. Endianness mismatch.\n");
 294                                return -EINVAL;
 295                        }
 296                }
 297        }
 298
 299        ath_dbg(common, EEPROM, "need_swap = %s\n",
 300                need_swap ? "True" : "False");
 301
 302        if (need_swap)
 303                el = swab16(ah->eeprom.def.baseEepHeader.length);
 304        else
 305                el = ah->eeprom.def.baseEepHeader.length;
 306
 307        if (el > sizeof(struct ar5416_eeprom_def))
 308                el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
 309        else
 310                el = el / sizeof(u16);
 311
 312        eepdata = (u16 *)(&ah->eeprom);
 313
 314        for (i = 0; i < el; i++)
 315                sum ^= *eepdata++;
 316
 317        if (need_swap) {
 318                u32 integer, j;
 319                u16 word;
 320
 321                ath_dbg(common, EEPROM,
 322                        "EEPROM Endianness is not native.. Changing.\n");
 323
 324                word = swab16(eep->baseEepHeader.length);
 325                eep->baseEepHeader.length = word;
 326
 327                word = swab16(eep->baseEepHeader.checksum);
 328                eep->baseEepHeader.checksum = word;
 329
 330                word = swab16(eep->baseEepHeader.version);
 331                eep->baseEepHeader.version = word;
 332
 333                word = swab16(eep->baseEepHeader.regDmn[0]);
 334                eep->baseEepHeader.regDmn[0] = word;
 335
 336                word = swab16(eep->baseEepHeader.regDmn[1]);
 337                eep->baseEepHeader.regDmn[1] = word;
 338
 339                word = swab16(eep->baseEepHeader.rfSilent);
 340                eep->baseEepHeader.rfSilent = word;
 341
 342                word = swab16(eep->baseEepHeader.blueToothOptions);
 343                eep->baseEepHeader.blueToothOptions = word;
 344
 345                word = swab16(eep->baseEepHeader.deviceCap);
 346                eep->baseEepHeader.deviceCap = word;
 347
 348                for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
 349                        struct modal_eep_header *pModal =
 350                                &eep->modalHeader[j];
 351                        integer = swab32(pModal->antCtrlCommon);
 352                        pModal->antCtrlCommon = integer;
 353
 354                        for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 355                                integer = swab32(pModal->antCtrlChain[i]);
 356                                pModal->antCtrlChain[i] = integer;
 357                        }
 358                        for (i = 0; i < 3; i++) {
 359                                word = swab16(pModal->xpaBiasLvlFreq[i]);
 360                                pModal->xpaBiasLvlFreq[i] = word;
 361                        }
 362
 363                        for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
 364                                word = swab16(pModal->spurChans[i].spurChan);
 365                                pModal->spurChans[i].spurChan = word;
 366                        }
 367                }
 368        }
 369
 370        if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
 371            ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
 372                ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
 373                        sum, ah->eep_ops->get_eeprom_ver(ah));
 374                return -EINVAL;
 375        }
 376
 377        /* Enable fixup for AR_AN_TOP2 if necessary */
 378        if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
 379            ((eep->baseEepHeader.version & 0xff) > 0x0a) &&
 380            (eep->baseEepHeader.pwdclkind == 0))
 381                ah->need_an_top2_fixup = true;
 382
 383        if ((common->bus_ops->ath_bus_type == ATH_USB) &&
 384            (AR_SREV_9280(ah)))
 385                eep->modalHeader[0].xpaBiasLvl = 0;
 386
 387        return 0;
 388}
 389
 390static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
 391                                   enum eeprom_param param)
 392{
 393        struct ar5416_eeprom_def *eep = &ah->eeprom.def;
 394        struct modal_eep_header *pModal = eep->modalHeader;
 395        struct base_eep_header *pBase = &eep->baseEepHeader;
 396        int band = 0;
 397
 398        switch (param) {
 399        case EEP_NFTHRESH_5:
 400                return pModal[0].noiseFloorThreshCh[0];
 401        case EEP_NFTHRESH_2:
 402                return pModal[1].noiseFloorThreshCh[0];
 403        case EEP_MAC_LSW:
 404                return get_unaligned_be16(pBase->macAddr);
 405        case EEP_MAC_MID:
 406                return get_unaligned_be16(pBase->macAddr + 2);
 407        case EEP_MAC_MSW:
 408                return get_unaligned_be16(pBase->macAddr + 4);
 409        case EEP_REG_0:
 410                return pBase->regDmn[0];
 411        case EEP_OP_CAP:
 412                return pBase->deviceCap;
 413        case EEP_OP_MODE:
 414                return pBase->opCapFlags;
 415        case EEP_RF_SILENT:
 416                return pBase->rfSilent;
 417        case EEP_OB_5:
 418                return pModal[0].ob;
 419        case EEP_DB_5:
 420                return pModal[0].db;
 421        case EEP_OB_2:
 422                return pModal[1].ob;
 423        case EEP_DB_2:
 424                return pModal[1].db;
 425        case EEP_MINOR_REV:
 426                return AR5416_VER_MASK;
 427        case EEP_TX_MASK:
 428                return pBase->txMask;
 429        case EEP_RX_MASK:
 430                return pBase->rxMask;
 431        case EEP_FSTCLK_5G:
 432                return pBase->fastClk5g;
 433        case EEP_RXGAIN_TYPE:
 434                return pBase->rxGainType;
 435        case EEP_TXGAIN_TYPE:
 436                return pBase->txGainType;
 437        case EEP_OL_PWRCTRL:
 438                if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
 439                        return pBase->openLoopPwrCntl ? true : false;
 440                else
 441                        return false;
 442        case EEP_RC_CHAIN_MASK:
 443                if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
 444                        return pBase->rcChainMask;
 445                else
 446                        return 0;
 447        case EEP_DAC_HPWR_5G:
 448                if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
 449                        return pBase->dacHiPwrMode_5G;
 450                else
 451                        return 0;
 452        case EEP_FRAC_N_5G:
 453                if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
 454                        return pBase->frac_n_5g;
 455                else
 456                        return 0;
 457        case EEP_PWR_TABLE_OFFSET:
 458                if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_21)
 459                        return pBase->pwr_table_offset;
 460                else
 461                        return AR5416_PWR_TABLE_OFFSET_DB;
 462        case EEP_ANTENNA_GAIN_2G:
 463                band = 1;
 464                /* fall through */
 465        case EEP_ANTENNA_GAIN_5G:
 466                return max_t(u8, max_t(u8,
 467                        pModal[band].antennaGainCh[0],
 468                        pModal[band].antennaGainCh[1]),
 469                        pModal[band].antennaGainCh[2]);
 470        default:
 471                return 0;
 472        }
 473}
 474
 475static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 476                                  struct modal_eep_header *pModal,
 477                                  struct ar5416_eeprom_def *eep,
 478                                  u8 txRxAttenLocal, int regChainOffset, int i)
 479{
 480        if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
 481                txRxAttenLocal = pModal->txRxAttenCh[i];
 482
 483                if (AR_SREV_9280_20_OR_LATER(ah)) {
 484                        REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 485                              AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
 486                              pModal->bswMargin[i]);
 487                        REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 488                              AR_PHY_GAIN_2GHZ_XATTEN1_DB,
 489                              pModal->bswAtten[i]);
 490                        REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 491                              AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
 492                              pModal->xatten2Margin[i]);
 493                        REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 494                              AR_PHY_GAIN_2GHZ_XATTEN2_DB,
 495                              pModal->xatten2Db[i]);
 496                } else {
 497                        REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 498                          (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 499                           ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
 500                          | SM(pModal-> bswMargin[i],
 501                               AR_PHY_GAIN_2GHZ_BSW_MARGIN));
 502                        REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 503                          (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 504                           ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
 505                          | SM(pModal->bswAtten[i],
 506                               AR_PHY_GAIN_2GHZ_BSW_ATTEN));
 507                }
 508        }
 509
 510        if (AR_SREV_9280_20_OR_LATER(ah)) {
 511                REG_RMW_FIELD(ah,
 512                      AR_PHY_RXGAIN + regChainOffset,
 513                      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
 514                REG_RMW_FIELD(ah,
 515                      AR_PHY_RXGAIN + regChainOffset,
 516                      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
 517        } else {
 518                REG_WRITE(ah,
 519                          AR_PHY_RXGAIN + regChainOffset,
 520                          (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
 521                           ~AR_PHY_RXGAIN_TXRX_ATTEN)
 522                          | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
 523                REG_WRITE(ah,
 524                          AR_PHY_GAIN_2GHZ + regChainOffset,
 525                          (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 526                           ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
 527                          SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
 528        }
 529}
 530
 531static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
 532                                          struct ath9k_channel *chan)
 533{
 534        struct modal_eep_header *pModal;
 535        struct ar5416_eeprom_def *eep = &ah->eeprom.def;
 536        int i, regChainOffset;
 537        u8 txRxAttenLocal;
 538
 539        pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
 540        txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
 541
 542        REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff);
 543
 544        for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 545                if (AR_SREV_9280(ah)) {
 546                        if (i >= 2)
 547                                break;
 548                }
 549
 550                if ((ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
 551                        regChainOffset = (i == 1) ? 0x2000 : 0x1000;
 552                else
 553                        regChainOffset = i * 0x1000;
 554
 555                REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
 556                          pModal->antCtrlChain[i]);
 557
 558                REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
 559                          (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
 560                           ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
 561                             AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
 562                          SM(pModal->iqCalICh[i],
 563                             AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
 564                          SM(pModal->iqCalQCh[i],
 565                             AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
 566
 567                ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
 568                                      regChainOffset, i);
 569        }
 570
 571        if (AR_SREV_9280_20_OR_LATER(ah)) {
 572                if (IS_CHAN_2GHZ(chan)) {
 573                        ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
 574                                                  AR_AN_RF2G1_CH0_OB,
 575                                                  AR_AN_RF2G1_CH0_OB_S,
 576                                                  pModal->ob);
 577                        ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
 578                                                  AR_AN_RF2G1_CH0_DB,
 579                                                  AR_AN_RF2G1_CH0_DB_S,
 580                                                  pModal->db);
 581                        ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
 582                                                  AR_AN_RF2G1_CH1_OB,
 583                                                  AR_AN_RF2G1_CH1_OB_S,
 584                                                  pModal->ob_ch1);
 585                        ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
 586                                                  AR_AN_RF2G1_CH1_DB,
 587                                                  AR_AN_RF2G1_CH1_DB_S,
 588                                                  pModal->db_ch1);
 589                } else {
 590                        ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
 591                                                  AR_AN_RF5G1_CH0_OB5,
 592                                                  AR_AN_RF5G1_CH0_OB5_S,
 593                                                  pModal->ob);
 594                        ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
 595                                                  AR_AN_RF5G1_CH0_DB5,
 596                                                  AR_AN_RF5G1_CH0_DB5_S,
 597                                                  pModal->db);
 598                        ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
 599                                                  AR_AN_RF5G1_CH1_OB5,
 600                                                  AR_AN_RF5G1_CH1_OB5_S,
 601                                                  pModal->ob_ch1);
 602                        ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
 603                                                  AR_AN_RF5G1_CH1_DB5,
 604                                                  AR_AN_RF5G1_CH1_DB5_S,
 605                                                  pModal->db_ch1);
 606                }
 607                ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
 608                                          AR_AN_TOP2_XPABIAS_LVL,
 609                                          AR_AN_TOP2_XPABIAS_LVL_S,
 610                                          pModal->xpaBiasLvl);
 611                ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
 612                                          AR_AN_TOP2_LOCALBIAS,
 613                                          AR_AN_TOP2_LOCALBIAS_S,
 614                                          !!(pModal->lna_ctl &
 615                                             LNA_CTL_LOCAL_BIAS));
 616                REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
 617                              !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
 618        }
 619
 620        REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
 621                      pModal->switchSettling);
 622        REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
 623                      pModal->adcDesiredSize);
 624
 625        if (!AR_SREV_9280_20_OR_LATER(ah))
 626                REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
 627                              AR_PHY_DESIRED_SZ_PGA,
 628                              pModal->pgaDesiredSize);
 629
 630        REG_WRITE(ah, AR_PHY_RF_CTL4,
 631                  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
 632                  | SM(pModal->txEndToXpaOff,
 633                       AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
 634                  | SM(pModal->txFrameToXpaOn,
 635                       AR_PHY_RF_CTL4_FRAME_XPAA_ON)
 636                  | SM(pModal->txFrameToXpaOn,
 637                       AR_PHY_RF_CTL4_FRAME_XPAB_ON));
 638
 639        REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
 640                      pModal->txEndToRxOn);
 641
 642        if (AR_SREV_9280_20_OR_LATER(ah)) {
 643                REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
 644                              pModal->thresh62);
 645                REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
 646                              AR_PHY_EXT_CCA0_THRESH62,
 647                              pModal->thresh62);
 648        } else {
 649                REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
 650                              pModal->thresh62);
 651                REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
 652                              AR_PHY_EXT_CCA_THRESH62,
 653                              pModal->thresh62);
 654        }
 655
 656        if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
 657                REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
 658                              AR_PHY_TX_END_DATA_START,
 659                              pModal->txFrameToDataStart);
 660                REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
 661                              pModal->txFrameToPaOn);
 662        }
 663
 664        if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
 665                if (IS_CHAN_HT40(chan))
 666                        REG_RMW_FIELD(ah, AR_PHY_SETTLING,
 667                                      AR_PHY_SETTLING_SWITCH,
 668                                      pModal->swSettleHt40);
 669        }
 670
 671        if (AR_SREV_9280_20_OR_LATER(ah) &&
 672            AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
 673                REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
 674                              AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
 675                              pModal->miscBits);
 676
 677
 678        if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
 679                if (IS_CHAN_2GHZ(chan))
 680                        REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
 681                                        eep->baseEepHeader.dacLpMode);
 682                else if (eep->baseEepHeader.dacHiPwrMode_5G)
 683                        REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
 684                else
 685                        REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
 686                                      eep->baseEepHeader.dacLpMode);
 687
 688                udelay(100);
 689
 690                REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
 691                              pModal->miscBits >> 2);
 692
 693                REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
 694                              AR_PHY_TX_DESIRED_SCALE_CCK,
 695                              eep->baseEepHeader.desiredScaleCCK);
 696        }
 697}
 698
 699static void ath9k_hw_def_set_addac(struct ath_hw *ah,
 700                                   struct ath9k_channel *chan)
 701{
 702#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
 703        struct modal_eep_header *pModal;
 704        struct ar5416_eeprom_def *eep = &ah->eeprom.def;
 705        u8 biaslevel;
 706
 707        if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
 708                return;
 709
 710        if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
 711                return;
 712
 713        pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
 714
 715        if (pModal->xpaBiasLvl != 0xff) {
 716                biaslevel = pModal->xpaBiasLvl;
 717        } else {
 718                u16 resetFreqBin, freqBin, freqCount = 0;
 719                struct chan_centers centers;
 720
 721                ath9k_hw_get_channel_centers(ah, chan, &centers);
 722
 723                resetFreqBin = FREQ2FBIN(centers.synth_center,
 724                                         IS_CHAN_2GHZ(chan));
 725                freqBin = XPA_LVL_FREQ(0) & 0xff;
 726                biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
 727
 728                freqCount++;
 729
 730                while (freqCount < 3) {
 731                        if (XPA_LVL_FREQ(freqCount) == 0x0)
 732                                break;
 733
 734                        freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
 735                        if (resetFreqBin >= freqBin)
 736                                biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
 737                        else
 738                                break;
 739                        freqCount++;
 740                }
 741        }
 742
 743        if (IS_CHAN_2GHZ(chan)) {
 744                INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
 745                                        7, 1) & (~0x18)) | biaslevel << 3;
 746        } else {
 747                INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
 748                                        6, 1) & (~0xc0)) | biaslevel << 6;
 749        }
 750#undef XPA_LVL_FREQ
 751}
 752
 753static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
 754                                u16 *gb,
 755                                u16 numXpdGain,
 756                                u16 pdGainOverlap_t2,
 757                                int8_t pwr_table_offset,
 758                                int16_t *diff)
 759
 760{
 761        u16 k;
 762
 763        /* Prior to writing the boundaries or the pdadc vs. power table
 764         * into the chip registers the default starting point on the pdadc
 765         * vs. power table needs to be checked and the curve boundaries
 766         * adjusted accordingly
 767         */
 768        if (AR_SREV_9280_20_OR_LATER(ah)) {
 769                u16 gb_limit;
 770
 771                if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
 772                        /* get the difference in dB */
 773                        *diff = (u16)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB);
 774                        /* get the number of half dB steps */
 775                        *diff *= 2;
 776                        /* change the original gain boundary settings
 777                         * by the number of half dB steps
 778                         */
 779                        for (k = 0; k < numXpdGain; k++)
 780                                gb[k] = (u16)(gb[k] - *diff);
 781                }
 782                /* Because of a hardware limitation, ensure the gain boundary
 783                 * is not larger than (63 - overlap)
 784                 */
 785                gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2);
 786
 787                for (k = 0; k < numXpdGain; k++)
 788                        gb[k] = (u16)min(gb_limit, gb[k]);
 789        }
 790
 791        return *diff;
 792}
 793
 794static void ath9k_adjust_pdadc_values(struct ath_hw *ah,
 795                                      int8_t pwr_table_offset,
 796                                      int16_t diff,
 797                                      u8 *pdadcValues)
 798{
 799#define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
 800        u16 k;
 801
 802        /* If this is a board that has a pwrTableOffset that differs from
 803         * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the
 804         * pdadc vs pwr table needs to be adjusted prior to writing to the
 805         * chip.
 806         */
 807        if (AR_SREV_9280_20_OR_LATER(ah)) {
 808                if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
 809                        /* shift the table to start at the new offset */
 810                        for (k = 0; k < (u16)NUM_PDADC(diff); k++ ) {
 811                                pdadcValues[k] = pdadcValues[k + diff];
 812                        }
 813
 814                        /* fill the back of the table */
 815                        for (k = (u16)NUM_PDADC(diff); k < NUM_PDADC(0); k++) {
 816                                pdadcValues[k] = pdadcValues[NUM_PDADC(diff)];
 817                        }
 818                }
 819        }
 820#undef NUM_PDADC
 821}
 822
 823static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
 824                                  struct ath9k_channel *chan)
 825{
 826#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
 827#define SM_PDGAIN_B(x, y) \
 828                SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
 829        struct ath_common *common = ath9k_hw_common(ah);
 830        struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
 831        struct cal_data_per_freq *pRawDataset;
 832        u8 *pCalBChans = NULL;
 833        u16 pdGainOverlap_t2;
 834        static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
 835        u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
 836        u16 numPiers, i, j;
 837        int16_t diff = 0;
 838        u16 numXpdGain, xpdMask;
 839        u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
 840        u32 reg32, regOffset, regChainOffset;
 841        int16_t modalIdx;
 842        int8_t pwr_table_offset;
 843
 844        modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
 845        xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
 846
 847        pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET);
 848
 849        if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
 850            AR5416_EEP_MINOR_VER_2) {
 851                pdGainOverlap_t2 =
 852                        pEepData->modalHeader[modalIdx].pdGainOverlap;
 853        } else {
 854                pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
 855                                            AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
 856        }
 857
 858        if (IS_CHAN_2GHZ(chan)) {
 859                pCalBChans = pEepData->calFreqPier2G;
 860                numPiers = AR5416_NUM_2G_CAL_PIERS;
 861        } else {
 862                pCalBChans = pEepData->calFreqPier5G;
 863                numPiers = AR5416_NUM_5G_CAL_PIERS;
 864        }
 865
 866        if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
 867                pRawDataset = pEepData->calPierData2G[0];
 868                ah->initPDADC = ((struct calDataPerFreqOpLoop *)
 869                                 pRawDataset)->vpdPdg[0][0];
 870        }
 871
 872        numXpdGain = 0;
 873
 874        for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
 875                if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
 876                        if (numXpdGain >= AR5416_NUM_PD_GAINS)
 877                                break;
 878                        xpdGainValues[numXpdGain] =
 879                                (u16)(AR5416_PD_GAINS_IN_MASK - i);
 880                        numXpdGain++;
 881                }
 882        }
 883
 884        REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
 885                      (numXpdGain - 1) & 0x3);
 886        REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
 887                      xpdGainValues[0]);
 888        REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
 889                      xpdGainValues[1]);
 890        REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
 891                      xpdGainValues[2]);
 892
 893        for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 894                if ((ah->rxchainmask == 5 || ah->txchainmask == 5) &&
 895                    (i != 0)) {
 896                        regChainOffset = (i == 1) ? 0x2000 : 0x1000;
 897                } else
 898                        regChainOffset = i * 0x1000;
 899
 900                if (pEepData->baseEepHeader.txMask & (1 << i)) {
 901                        if (IS_CHAN_2GHZ(chan))
 902                                pRawDataset = pEepData->calPierData2G[i];
 903                        else
 904                                pRawDataset = pEepData->calPierData5G[i];
 905
 906
 907                        if (OLC_FOR_AR9280_20_LATER) {
 908                                u8 pcdacIdx;
 909                                u8 txPower;
 910
 911                                ath9k_get_txgain_index(ah, chan,
 912                                (struct calDataPerFreqOpLoop *)pRawDataset,
 913                                pCalBChans, numPiers, &txPower, &pcdacIdx);
 914                                ath9k_olc_get_pdadcs(ah, pcdacIdx,
 915                                                     txPower/2, pdadcValues);
 916                        } else {
 917                                ath9k_hw_get_gain_boundaries_pdadcs(ah,
 918                                                        chan, pRawDataset,
 919                                                        pCalBChans, numPiers,
 920                                                        pdGainOverlap_t2,
 921                                                        gainBoundaries,
 922                                                        pdadcValues,
 923                                                        numXpdGain);
 924                        }
 925
 926                        diff = ath9k_change_gain_boundary_setting(ah,
 927                                                           gainBoundaries,
 928                                                           numXpdGain,
 929                                                           pdGainOverlap_t2,
 930                                                           pwr_table_offset,
 931                                                           &diff);
 932
 933                        ENABLE_REGWRITE_BUFFER(ah);
 934
 935                        if (OLC_FOR_AR9280_20_LATER) {
 936                                REG_WRITE(ah,
 937                                        AR_PHY_TPCRG5 + regChainOffset,
 938                                        SM(0x6,
 939                                        AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
 940                                        SM_PD_GAIN(1) | SM_PD_GAIN(2) |
 941                                        SM_PD_GAIN(3) | SM_PD_GAIN(4));
 942                        } else {
 943                                REG_WRITE(ah,
 944                                        AR_PHY_TPCRG5 + regChainOffset,
 945                                        SM(pdGainOverlap_t2,
 946                                        AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
 947                                        SM_PDGAIN_B(0, 1) |
 948                                        SM_PDGAIN_B(1, 2) |
 949                                        SM_PDGAIN_B(2, 3) |
 950                                        SM_PDGAIN_B(3, 4));
 951                        }
 952
 953                        ath9k_adjust_pdadc_values(ah, pwr_table_offset,
 954                                                  diff, pdadcValues);
 955
 956                        regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
 957                        for (j = 0; j < 32; j++) {
 958                                reg32 = get_unaligned_le32(&pdadcValues[4 * j]);
 959                                REG_WRITE(ah, regOffset, reg32);
 960
 961                                ath_dbg(common, EEPROM,
 962                                        "PDADC (%d,%4x): %4.4x %8.8x\n",
 963                                        i, regChainOffset, regOffset,
 964                                        reg32);
 965                                ath_dbg(common, EEPROM,
 966                                        "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",
 967                                        i, 4 * j, pdadcValues[4 * j],
 968                                        4 * j + 1, pdadcValues[4 * j + 1],
 969                                        4 * j + 2, pdadcValues[4 * j + 2],
 970                                        4 * j + 3, pdadcValues[4 * j + 3]);
 971
 972                                regOffset += 4;
 973                        }
 974                        REGWRITE_BUFFER_FLUSH(ah);
 975                }
 976        }
 977
 978#undef SM_PD_GAIN
 979#undef SM_PDGAIN_B
 980}
 981
 982static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
 983                                                  struct ath9k_channel *chan,
 984                                                  int16_t *ratesArray,
 985                                                  u16 cfgCtl,
 986                                                  u16 antenna_reduction,
 987                                                  u16 powerLimit)
 988{
 989        struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
 990        u16 twiceMaxEdgePower;
 991        int i;
 992        struct cal_ctl_data *rep;
 993        struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
 994                0, { 0, 0, 0, 0}
 995        };
 996        struct cal_target_power_leg targetPowerOfdmExt = {
 997                0, { 0, 0, 0, 0} }, targetPowerCckExt = {
 998                0, { 0, 0, 0, 0 }
 999        };
1000        struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
1001                0, {0, 0, 0, 0}
1002        };
1003        u16 scaledPower = 0, minCtlPower;
1004        static const u16 ctlModesFor11a[] = {
1005                CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
1006        };
1007        static const u16 ctlModesFor11g[] = {
1008                CTL_11B, CTL_11G, CTL_2GHT20,
1009                CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
1010        };
1011        u16 numCtlModes;
1012        const u16 *pCtlMode;
1013        u16 ctlMode, freq;
1014        struct chan_centers centers;
1015        int tx_chainmask;
1016        u16 twiceMinEdgePower;
1017
1018        tx_chainmask = ah->txchainmask;
1019
1020        ath9k_hw_get_channel_centers(ah, chan, &centers);
1021
1022        scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
1023                                                antenna_reduction);
1024
1025        if (IS_CHAN_2GHZ(chan)) {
1026                numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
1027                        SUB_NUM_CTL_MODES_AT_2G_40;
1028                pCtlMode = ctlModesFor11g;
1029
1030                ath9k_hw_get_legacy_target_powers(ah, chan,
1031                        pEepData->calTargetPowerCck,
1032                        AR5416_NUM_2G_CCK_TARGET_POWERS,
1033                        &targetPowerCck, 4, false);
1034                ath9k_hw_get_legacy_target_powers(ah, chan,
1035                        pEepData->calTargetPower2G,
1036                        AR5416_NUM_2G_20_TARGET_POWERS,
1037                        &targetPowerOfdm, 4, false);
1038                ath9k_hw_get_target_powers(ah, chan,
1039                        pEepData->calTargetPower2GHT20,
1040                        AR5416_NUM_2G_20_TARGET_POWERS,
1041                        &targetPowerHt20, 8, false);
1042
1043                if (IS_CHAN_HT40(chan)) {
1044                        numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1045                        ath9k_hw_get_target_powers(ah, chan,
1046                                pEepData->calTargetPower2GHT40,
1047                                AR5416_NUM_2G_40_TARGET_POWERS,
1048                                &targetPowerHt40, 8, true);
1049                        ath9k_hw_get_legacy_target_powers(ah, chan,
1050                                pEepData->calTargetPowerCck,
1051                                AR5416_NUM_2G_CCK_TARGET_POWERS,
1052                                &targetPowerCckExt, 4, true);
1053                        ath9k_hw_get_legacy_target_powers(ah, chan,
1054                                pEepData->calTargetPower2G,
1055                                AR5416_NUM_2G_20_TARGET_POWERS,
1056                                &targetPowerOfdmExt, 4, true);
1057                }
1058        } else {
1059                numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1060                        SUB_NUM_CTL_MODES_AT_5G_40;
1061                pCtlMode = ctlModesFor11a;
1062
1063                ath9k_hw_get_legacy_target_powers(ah, chan,
1064                        pEepData->calTargetPower5G,
1065                        AR5416_NUM_5G_20_TARGET_POWERS,
1066                        &targetPowerOfdm, 4, false);
1067                ath9k_hw_get_target_powers(ah, chan,
1068                        pEepData->calTargetPower5GHT20,
1069                        AR5416_NUM_5G_20_TARGET_POWERS,
1070                        &targetPowerHt20, 8, false);
1071
1072                if (IS_CHAN_HT40(chan)) {
1073                        numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1074                        ath9k_hw_get_target_powers(ah, chan,
1075                                pEepData->calTargetPower5GHT40,
1076                                AR5416_NUM_5G_40_TARGET_POWERS,
1077                                &targetPowerHt40, 8, true);
1078                        ath9k_hw_get_legacy_target_powers(ah, chan,
1079                                pEepData->calTargetPower5G,
1080                                AR5416_NUM_5G_20_TARGET_POWERS,
1081                                &targetPowerOfdmExt, 4, true);
1082                }
1083        }
1084
1085        for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1086                bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1087                        (pCtlMode[ctlMode] == CTL_2GHT40);
1088                if (isHt40CtlMode)
1089                        freq = centers.synth_center;
1090                else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1091                        freq = centers.ext_center;
1092                else
1093                        freq = centers.ctl_center;
1094
1095                twiceMaxEdgePower = MAX_RATE_POWER;
1096
1097                for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1098                        if ((((cfgCtl & ~CTL_MODE_M) |
1099                              (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1100                             pEepData->ctlIndex[i]) ||
1101                            (((cfgCtl & ~CTL_MODE_M) |
1102                              (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1103                             ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
1104                                rep = &(pEepData->ctlData[i]);
1105
1106                                twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
1107                                rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
1108                                IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
1109
1110                                if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1111                                        twiceMaxEdgePower = min(twiceMaxEdgePower,
1112                                                                twiceMinEdgePower);
1113                                } else {
1114                                        twiceMaxEdgePower = twiceMinEdgePower;
1115                                        break;
1116                                }
1117                        }
1118                }
1119
1120                minCtlPower = min(twiceMaxEdgePower, scaledPower);
1121
1122                switch (pCtlMode[ctlMode]) {
1123                case CTL_11B:
1124                        for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
1125                                targetPowerCck.tPow2x[i] =
1126                                        min((u16)targetPowerCck.tPow2x[i],
1127                                            minCtlPower);
1128                        }
1129                        break;
1130                case CTL_11A:
1131                case CTL_11G:
1132                        for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
1133                                targetPowerOfdm.tPow2x[i] =
1134                                        min((u16)targetPowerOfdm.tPow2x[i],
1135                                            minCtlPower);
1136                        }
1137                        break;
1138                case CTL_5GHT20:
1139                case CTL_2GHT20:
1140                        for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
1141                                targetPowerHt20.tPow2x[i] =
1142                                        min((u16)targetPowerHt20.tPow2x[i],
1143                                            minCtlPower);
1144                        }
1145                        break;
1146                case CTL_11B_EXT:
1147                        targetPowerCckExt.tPow2x[0] = min((u16)
1148                                        targetPowerCckExt.tPow2x[0],
1149                                        minCtlPower);
1150                        break;
1151                case CTL_11A_EXT:
1152                case CTL_11G_EXT:
1153                        targetPowerOfdmExt.tPow2x[0] = min((u16)
1154                                        targetPowerOfdmExt.tPow2x[0],
1155                                        minCtlPower);
1156                        break;
1157                case CTL_5GHT40:
1158                case CTL_2GHT40:
1159                        for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1160                                targetPowerHt40.tPow2x[i] =
1161                                        min((u16)targetPowerHt40.tPow2x[i],
1162                                            minCtlPower);
1163                        }
1164                        break;
1165                default:
1166                        break;
1167                }
1168        }
1169
1170        ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1171                ratesArray[rate18mb] = ratesArray[rate24mb] =
1172                targetPowerOfdm.tPow2x[0];
1173        ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1174        ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1175        ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1176        ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1177
1178        for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1179                ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1180
1181        if (IS_CHAN_2GHZ(chan)) {
1182                ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1183                ratesArray[rate2s] = ratesArray[rate2l] =
1184                        targetPowerCck.tPow2x[1];
1185                ratesArray[rate5_5s] = ratesArray[rate5_5l] =
1186                        targetPowerCck.tPow2x[2];
1187                ratesArray[rate11s] = ratesArray[rate11l] =
1188                        targetPowerCck.tPow2x[3];
1189        }
1190        if (IS_CHAN_HT40(chan)) {
1191                for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1192                        ratesArray[rateHt40_0 + i] =
1193                                targetPowerHt40.tPow2x[i];
1194                }
1195                ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1196                ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1197                ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1198                if (IS_CHAN_2GHZ(chan)) {
1199                        ratesArray[rateExtCck] =
1200                                targetPowerCckExt.tPow2x[0];
1201                }
1202        }
1203}
1204
1205static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1206                                    struct ath9k_channel *chan,
1207                                    u16 cfgCtl,
1208                                    u8 twiceAntennaReduction,
1209                                    u8 powerLimit, bool test)
1210{
1211#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1212        struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1213        struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
1214        struct modal_eep_header *pModal =
1215                &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1216        int16_t ratesArray[Ar5416RateSize];
1217        u8 ht40PowerIncForPdadc = 2;
1218        int i, cck_ofdm_delta = 0;
1219
1220        memset(ratesArray, 0, sizeof(ratesArray));
1221
1222        if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1223            AR5416_EEP_MINOR_VER_2) {
1224                ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1225        }
1226
1227        ath9k_hw_set_def_power_per_rate_table(ah, chan,
1228                                               &ratesArray[0], cfgCtl,
1229                                               twiceAntennaReduction,
1230                                               powerLimit);
1231
1232        ath9k_hw_set_def_power_cal_table(ah, chan);
1233
1234        regulatory->max_power_level = 0;
1235        for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1236                if (ratesArray[i] > MAX_RATE_POWER)
1237                        ratesArray[i] = MAX_RATE_POWER;
1238                if (ratesArray[i] > regulatory->max_power_level)
1239                        regulatory->max_power_level = ratesArray[i];
1240        }
1241
1242        ath9k_hw_update_regulatory_maxpower(ah);
1243
1244        if (test)
1245                return;
1246
1247        if (AR_SREV_9280_20_OR_LATER(ah)) {
1248                for (i = 0; i < Ar5416RateSize; i++) {
1249                        int8_t pwr_table_offset;
1250
1251                        pwr_table_offset = ah->eep_ops->get_eeprom(ah,
1252                                                        EEP_PWR_TABLE_OFFSET);
1253                        ratesArray[i] -= pwr_table_offset * 2;
1254                }
1255        }
1256
1257        ENABLE_REGWRITE_BUFFER(ah);
1258
1259        REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1260                  ATH9K_POW_SM(ratesArray[rate18mb], 24)
1261                  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
1262                  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
1263                  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
1264        REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1265                  ATH9K_POW_SM(ratesArray[rate54mb], 24)
1266                  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
1267                  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
1268                  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
1269
1270        if (IS_CHAN_2GHZ(chan)) {
1271                if (OLC_FOR_AR9280_20_LATER) {
1272                        cck_ofdm_delta = 2;
1273                        REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1274                                ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
1275                                | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
1276                                | ATH9K_POW_SM(ratesArray[rateXr], 8)
1277                                | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
1278                        REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1279                                ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
1280                                | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
1281                                | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
1282                                | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
1283                } else {
1284                        REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1285                                ATH9K_POW_SM(ratesArray[rate2s], 24)
1286                                | ATH9K_POW_SM(ratesArray[rate2l], 16)
1287                                | ATH9K_POW_SM(ratesArray[rateXr], 8)
1288                                | ATH9K_POW_SM(ratesArray[rate1l], 0));
1289                        REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1290                                ATH9K_POW_SM(ratesArray[rate11s], 24)
1291                                | ATH9K_POW_SM(ratesArray[rate11l], 16)
1292                                | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
1293                                | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1294                }
1295        }
1296
1297        REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
1298                  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
1299                  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
1300                  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
1301                  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1302        REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1303                  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
1304                  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
1305                  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
1306                  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1307
1308        if (IS_CHAN_HT40(chan)) {
1309                REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
1310                          ATH9K_POW_SM(ratesArray[rateHt40_3] +
1311                                       ht40PowerIncForPdadc, 24)
1312                          | ATH9K_POW_SM(ratesArray[rateHt40_2] +
1313                                         ht40PowerIncForPdadc, 16)
1314                          | ATH9K_POW_SM(ratesArray[rateHt40_1] +
1315                                         ht40PowerIncForPdadc, 8)
1316                          | ATH9K_POW_SM(ratesArray[rateHt40_0] +
1317                                         ht40PowerIncForPdadc, 0));
1318                REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1319                          ATH9K_POW_SM(ratesArray[rateHt40_7] +
1320                                       ht40PowerIncForPdadc, 24)
1321                          | ATH9K_POW_SM(ratesArray[rateHt40_6] +
1322                                         ht40PowerIncForPdadc, 16)
1323                          | ATH9K_POW_SM(ratesArray[rateHt40_5] +
1324                                         ht40PowerIncForPdadc, 8)
1325                          | ATH9K_POW_SM(ratesArray[rateHt40_4] +
1326                                         ht40PowerIncForPdadc, 0));
1327                if (OLC_FOR_AR9280_20_LATER) {
1328                        REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1329                                ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1330                                | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
1331                                | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1332                                | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
1333                } else {
1334                        REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
1335                                ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
1336                                | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
1337                                | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
1338                                | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1339                }
1340        }
1341
1342        REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1343                  ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1344                  | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1345
1346        REGWRITE_BUFFER_FLUSH(ah);
1347}
1348
1349static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1350{
1351#define EEP_DEF_SPURCHAN \
1352        (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1353        struct ath_common *common = ath9k_hw_common(ah);
1354
1355        u16 spur_val = AR_NO_SPUR;
1356
1357        ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n",
1358                i, is2GHz, ah->config.spurchans[i][is2GHz]);
1359
1360        switch (ah->config.spurmode) {
1361        case SPUR_DISABLE:
1362                break;
1363        case SPUR_ENABLE_IOCTL:
1364                spur_val = ah->config.spurchans[i][is2GHz];
1365                ath_dbg(common, ANI, "Getting spur val from new loc. %d\n",
1366                        spur_val);
1367                break;
1368        case SPUR_ENABLE_EEPROM:
1369                spur_val = EEP_DEF_SPURCHAN;
1370                break;
1371        }
1372
1373        return spur_val;
1374
1375#undef EEP_DEF_SPURCHAN
1376}
1377
1378const struct eeprom_ops eep_def_ops = {
1379        .check_eeprom           = ath9k_hw_def_check_eeprom,
1380        .get_eeprom             = ath9k_hw_def_get_eeprom,
1381        .fill_eeprom            = ath9k_hw_def_fill_eeprom,
1382        .dump_eeprom            = ath9k_hw_def_dump_eeprom,
1383        .get_eeprom_ver         = ath9k_hw_def_get_eeprom_ver,
1384        .get_eeprom_rev         = ath9k_hw_def_get_eeprom_rev,
1385        .set_board_values       = ath9k_hw_def_set_board_values,
1386        .set_addac              = ath9k_hw_def_set_addac,
1387        .set_txpower            = ath9k_hw_def_set_txpower,
1388        .get_spur_channel       = ath9k_hw_def_get_spur_channel
1389};
1390