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 "arn_core.h"
  23 #include "arn_hw.h"
  24 #include "arn_reg.h"
  25 #include "arn_phy.h"
  26 
  27 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
  28 
  29 /* We can tune this as we go by monitoring really low values */
  30 #define ATH9K_NF_TOO_LOW        -60
  31 
  32 /*
  33  * AR5416 may return very high value (like -31 dBm), in those cases the nf
  34  * is incorrect and we should use the static NF value. Later we can try to
  35  * find out why they are reporting these values
  36  */
  37 
  38 /* ARGSUSED */
  39 static boolean_t
  40 ath9k_hw_nf_in_range(struct ath_hal *ah, signed short nf)
  41 {
  42         if (nf > ATH9K_NF_TOO_LOW) {
  43                 ARN_DBG((ARN_DBG_CALIBRATE,
  44                     "%s: noise floor value detected (%d) is "
  45                     "lower than what we think is a "
  46                     "reasonable value (%d)\n",
  47                     __func__, nf, ATH9K_NF_TOO_LOW));
  48 
  49                 return (B_FALSE);
  50         }
  51         return (B_TRUE);
  52 }
  53 
  54 static int16_t
  55 ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
  56 {
  57         int16_t nfval;
  58         int16_t sort[ATH9K_NF_CAL_HIST_MAX];
  59         int i, j;
  60 
  61         for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
  62                 sort[i] = nfCalBuffer[i];
  63 
  64         for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
  65                 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
  66                         if (sort[j] > sort[j - 1]) {
  67                                 nfval = sort[j];
  68                                 sort[j] = sort[j - 1];
  69                                 sort[j - 1] = nfval;
  70                         }
  71                 }
  72         }
  73         nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
  74 
  75         return (nfval);
  76 }
  77 
  78 static void
  79 ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
  80     int16_t *nfarray)
  81 {
  82         int i;
  83 
  84         for (i = 0; i < NUM_NF_READINGS; i++) {
  85                 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
  86 
  87                 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
  88                         h[i].currIndex = 0;
  89 
  90                 if (h[i].invalidNFcount > 0) {
  91                         if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
  92                             nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
  93                                 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
  94                         } else {
  95                                 h[i].invalidNFcount--;
  96                                 h[i].privNF = nfarray[i];
  97                         }
  98                 } else {
  99                         h[i].privNF =
 100                             ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
 101                 }
 102         }
 103 }
 104 
 105 static void
 106 ath9k_hw_do_getnf(struct ath_hal *ah,
 107     int16_t nfarray[NUM_NF_READINGS])
 108 {
 109         int16_t nf;
 110 
 111         if (AR_SREV_9280_10_OR_LATER(ah))
 112                 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
 113         else
 114                 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
 115 
 116         if (nf & 0x100)
 117                 nf = 0 - ((nf ^ 0x1ff) + 1);
 118         ARN_DBG((ARN_DBG_CALIBRATE,
 119             "NF calibrated [ctl] [chain 0] is %d\n", nf));
 120         nfarray[0] = nf;
 121 
 122         if (AR_SREV_9280_10_OR_LATER(ah))
 123                 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
 124                     AR9280_PHY_CH1_MINCCA_PWR);
 125         else
 126                 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
 127                     AR_PHY_CH1_MINCCA_PWR);
 128 
 129         if (nf & 0x100)
 130                 nf = 0 - ((nf ^ 0x1ff) + 1);
 131         ARN_DBG((ARN_DBG_CALIBRATE,
 132             "NF calibrated [ctl] [chain 1] is %d\n", nf));
 133         nfarray[1] = nf;
 134 
 135         if (!AR_SREV_9280(ah)) {
 136                 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
 137                     AR_PHY_CH2_MINCCA_PWR);
 138                 if (nf & 0x100)
 139                         nf = 0 - ((nf ^ 0x1ff) + 1);
 140                 ARN_DBG((ARN_DBG_CALIBRATE,
 141                     "NF calibrated [ctl] [chain 2] is %d\n", nf));
 142                 nfarray[2] = nf;
 143         }
 144 
 145         if (AR_SREV_9280_10_OR_LATER(ah))
 146                 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
 147                     AR9280_PHY_EXT_MINCCA_PWR);
 148         else
 149                 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
 150                     AR_PHY_EXT_MINCCA_PWR);
 151 
 152         if (nf & 0x100)
 153                 nf = 0 - ((nf ^ 0x1ff) + 1);
 154         ARN_DBG((ARN_DBG_CALIBRATE,
 155             "NF calibrated [ext] [chain 0] is %d\n", nf));
 156         nfarray[3] = nf;
 157 
 158         if (AR_SREV_9280_10_OR_LATER(ah))
 159                 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
 160                     AR9280_PHY_CH1_EXT_MINCCA_PWR);
 161         else
 162                 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
 163                     AR_PHY_CH1_EXT_MINCCA_PWR);
 164 
 165         if (nf & 0x100)
 166                 nf = 0 - ((nf ^ 0x1ff) + 1);
 167         ARN_DBG((ARN_DBG_CALIBRATE,
 168             "NF calibrated [ext] [chain 1] is %d\n", nf));
 169         nfarray[4] = nf;
 170 
 171         if (!AR_SREV_9280(ah)) {
 172                 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
 173                     AR_PHY_CH2_EXT_MINCCA_PWR);
 174                 if (nf & 0x100)
 175                         nf = 0 - ((nf ^ 0x1ff) + 1);
 176                 ARN_DBG((ARN_DBG_CALIBRATE,
 177                     "NF calibrated [ext] [chain 2] is %d\n", nf));
 178                 nfarray[5] = nf;
 179         }
 180 }
 181 
 182 static boolean_t
 183 getNoiseFloorThresh(struct ath_hal *ah,
 184     const struct ath9k_channel *chan,
 185     int16_t *nft)
 186 {
 187         switch (chan->chanmode) {
 188         case CHANNEL_A:
 189         case CHANNEL_A_HT20:
 190         case CHANNEL_A_HT40PLUS:
 191         case CHANNEL_A_HT40MINUS:
 192                 *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
 193                 break;
 194         case CHANNEL_B:
 195         case CHANNEL_G:
 196         case CHANNEL_G_HT20:
 197         case CHANNEL_G_HT40PLUS:
 198         case CHANNEL_G_HT40MINUS:
 199                 *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
 200                 break;
 201         default:
 202                 ARN_DBG((ARN_DBG_CHANNEL,
 203                     "%s: invalid channel flags 0x%x\n", __func__,
 204                     chan->channelFlags));
 205                 return (B_FALSE);
 206         }
 207 
 208         return (B_TRUE);
 209 }
 210 
 211 static void
 212 ath9k_hw_setup_calibration(struct ath_hal *ah,
 213     struct hal_cal_list *currCal)
 214 {
 215         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
 216             AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
 217             currCal->calData->calCountMax);
 218 
 219         switch (currCal->calData->calType) {
 220         case IQ_MISMATCH_CAL:
 221                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
 222                 ARN_DBG((ARN_DBG_CALIBRATE,
 223                     "%s: starting IQ Mismatch Calibration\n",
 224                     __func__));
 225                 break;
 226         case ADC_GAIN_CAL:
 227                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
 228                 ARN_DBG((ARN_DBG_CALIBRATE,
 229                     "%s: starting ADC Gain Calibration\n", __func__));
 230                 break;
 231         case ADC_DC_CAL:
 232                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
 233                 ARN_DBG((ARN_DBG_CALIBRATE,
 234                     "%s: starting ADC DC Calibration\n", __func__));
 235                 break;
 236         case ADC_DC_INIT_CAL:
 237                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
 238                 ARN_DBG((ARN_DBG_CALIBRATE,
 239                     "%s: starting Init ADC DC Calibration\n",
 240                     __func__));
 241                 break;
 242         }
 243 
 244         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
 245             AR_PHY_TIMING_CTRL4_DO_CAL);
 246 }
 247 
 248 static void
 249 ath9k_hw_reset_calibration(struct ath_hal *ah,
 250     struct hal_cal_list *currCal)
 251 {
 252         struct ath_hal_5416 *ahp = AH5416(ah);
 253         int i;
 254 
 255         ath9k_hw_setup_calibration(ah, currCal);
 256 
 257         currCal->calState = CAL_RUNNING;
 258 
 259         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 260                 ahp->ah_Meas0.sign[i] = 0;
 261                 ahp->ah_Meas1.sign[i] = 0;
 262                 ahp->ah_Meas2.sign[i] = 0;
 263                 ahp->ah_Meas3.sign[i] = 0;
 264         }
 265 
 266         ahp->ah_CalSamples = 0;
 267 }
 268 
 269 static void
 270 ath9k_hw_per_calibration(struct ath_hal *ah,
 271     struct ath9k_channel *ichan,
 272     uint8_t rxchainmask,
 273     struct hal_cal_list *currCal,
 274     boolean_t *isCalDone)
 275 {
 276         struct ath_hal_5416 *ahp = AH5416(ah);
 277 
 278         *isCalDone = B_FALSE;
 279 
 280         if (currCal->calState == CAL_RUNNING) {
 281                 if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
 282                     AR_PHY_TIMING_CTRL4_DO_CAL)) {
 283 
 284                         currCal->calData->calCollect(ah);
 285                         ahp->ah_CalSamples++;
 286 
 287                         if (ahp->ah_CalSamples >=
 288                             currCal->calData->calNumSamples) {
 289                                 int i, numChains = 0;
 290                                 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 291                                         if (rxchainmask & (1 << i))
 292                                                 numChains++;
 293                                 }
 294 
 295                                 currCal->calData->calPostProc(ah, numChains);
 296                                 ichan->CalValid |= currCal->calData->calType;
 297                                 currCal->calState = CAL_DONE;
 298                                 *isCalDone = B_TRUE;
 299                         } else {
 300                                 ath9k_hw_setup_calibration(ah, currCal);
 301                         }
 302                 }
 303         } else if (!(ichan->CalValid & currCal->calData->calType)) {
 304                 ath9k_hw_reset_calibration(ah, currCal);
 305         }
 306 }
 307 
 308 static boolean_t
 309 ath9k_hw_iscal_supported(struct ath_hal *ah,
 310     struct ath9k_channel *chan,
 311     enum hal_cal_types calType)
 312 {
 313         struct ath_hal_5416 *ahp = AH5416(ah);
 314         boolean_t retval = B_FALSE;
 315 
 316         switch (calType & ahp->ah_suppCals) {
 317         case IQ_MISMATCH_CAL:
 318                 if (!IS_CHAN_B(chan))
 319                         retval = B_TRUE;
 320                 break;
 321         case ADC_GAIN_CAL:
 322         case ADC_DC_CAL:
 323                 if (!IS_CHAN_B(chan) &&
 324                     !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
 325                         retval = B_TRUE;
 326                 break;
 327         }
 328 
 329         return (retval);
 330 }
 331 
 332 static void
 333 ath9k_hw_iqcal_collect(struct ath_hal *ah)
 334 {
 335         struct ath_hal_5416 *ahp = AH5416(ah);
 336         int i;
 337 
 338         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 339                 ahp->ah_totalPowerMeasI[i] +=
 340                     REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
 341                 ahp->ah_totalPowerMeasQ[i] +=
 342                     REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
 343                 ahp->ah_totalIqCorrMeas[i] +=
 344                     (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
 345                 ARN_DBG((ARN_DBG_CALIBRATE,
 346                     "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
 347                     ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
 348                     ahp->ah_totalPowerMeasQ[i],
 349                     ahp->ah_totalIqCorrMeas[i]));
 350         }
 351 }
 352 
 353 static void
 354 ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
 355 {
 356         struct ath_hal_5416 *ahp = AH5416(ah);
 357         int i;
 358 
 359         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 360                 ahp->ah_totalAdcIOddPhase[i] +=
 361                     REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
 362                 ahp->ah_totalAdcIEvenPhase[i] +=
 363                     REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
 364                 ahp->ah_totalAdcQOddPhase[i] +=
 365                     REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
 366                 ahp->ah_totalAdcQEvenPhase[i] +=
 367                     REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
 368                 ARN_DBG((ARN_DBG_CALIBRATE,
 369                     "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
 370                     "oddq=0x%08x; evenq=0x%08x;\n",
 371                     ahp->ah_CalSamples, i,
 372                     ahp->ah_totalAdcIOddPhase[i],
 373                     ahp->ah_totalAdcIEvenPhase[i],
 374                     ahp->ah_totalAdcQOddPhase[i],
 375                     ahp->ah_totalAdcQEvenPhase[i]));
 376         }
 377 }
 378 
 379 static void
 380 ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
 381 {
 382         struct ath_hal_5416 *ahp = AH5416(ah);
 383         int i;
 384 
 385         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 386                 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
 387                     (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
 388                 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
 389                     (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
 390                 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
 391                     (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
 392                 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
 393                     (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
 394                 ARN_DBG((ARN_DBG_CALIBRATE,
 395                     "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
 396                     "oddq=0x%08x; evenq=0x%08x;\n",
 397                     ahp->ah_CalSamples, i,
 398                     ahp->ah_totalAdcDcOffsetIOddPhase[i],
 399                     ahp->ah_totalAdcDcOffsetIEvenPhase[i],
 400                     ahp->ah_totalAdcDcOffsetQOddPhase[i],
 401                     ahp->ah_totalAdcDcOffsetQEvenPhase[i]));
 402         }
 403 }
 404 
 405 static void
 406 ath9k_hw_iqcalibrate(struct ath_hal *ah, uint8_t numChains)
 407 {
 408         struct ath_hal_5416 *ahp = AH5416(ah);
 409         uint32_t powerMeasQ, powerMeasI, iqCorrMeas;
 410         uint32_t qCoffDenom, iCoffDenom;
 411         int32_t qCoff, iCoff;
 412         int iqCorrNeg, i;
 413 
 414         for (i = 0; i < numChains; i++) {
 415                 powerMeasI = ahp->ah_totalPowerMeasI[i];
 416                 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
 417                 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
 418                 ARN_DBG((ARN_DBG_CALIBRATE,
 419                     "Starting IQ Cal and Correction for Chain %d\n",
 420                     i));
 421 
 422                 ARN_DBG((ARN_DBG_CALIBRATE,
 423                     "Orignal: Chn %diq_corr_meas = 0x%08x\n",
 424                     i, ahp->ah_totalIqCorrMeas[i]));
 425 
 426                 iqCorrNeg = 0;
 427 
 428                 if (iqCorrMeas > 0x80000000) {
 429                         iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
 430                         iqCorrNeg = 1;
 431                 }
 432 
 433                 ARN_DBG((ARN_DBG_CALIBRATE,
 434                     "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI));
 435                 ARN_DBG((ARN_DBG_CALIBRATE,
 436                     "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ));
 437                 ARN_DBG((ARN_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
 438                     iqCorrNeg));
 439 
 440                 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
 441                 qCoffDenom = powerMeasQ / 64;
 442 
 443                 if (powerMeasQ != 0) {
 444                         iCoff = iqCorrMeas / iCoffDenom;
 445                         qCoff = powerMeasI / qCoffDenom - 64;
 446 
 447                         ARN_DBG((ARN_DBG_CALIBRATE,
 448                             "Chn %d iCoff = 0x%08x\n", i, iCoff));
 449                         ARN_DBG((ARN_DBG_CALIBRATE,
 450                             "Chn %d qCoff = 0x%08x\n", i, qCoff));
 451 
 452                         iCoff = iCoff & 0x3f;
 453 
 454                         ARN_DBG((ARN_DBG_CALIBRATE,
 455                             "New: Chn %d iCoff = 0x%08x\n", i, iCoff));
 456 
 457                         if (iqCorrNeg == 0x0)
 458                                 iCoff = 0x40 - iCoff;
 459 
 460                         if (qCoff > 15)
 461                                 qCoff = 15;
 462                         else if (qCoff <= -16)
 463                                 qCoff = 16;
 464 
 465                         ARN_DBG((ARN_DBG_CALIBRATE,
 466                             "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
 467                             i, iCoff, qCoff));
 468 
 469                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
 470                             AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
 471                             iCoff);
 472                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
 473                             AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
 474                             qCoff);
 475 
 476                         ARN_DBG((ARN_DBG_CALIBRATE,
 477                             "IQ Cal and Correction done for Chain %d\n",
 478                             i));
 479                 }
 480         }
 481 
 482         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
 483             AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
 484 }
 485 
 486 static void
 487 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, uint8_t numChains)
 488 {
 489         struct ath_hal_5416 *ahp = AH5416(ah);
 490         uint32_t iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
 491             qEvenMeasOffset;
 492         uint32_t qGainMismatch, iGainMismatch, val, i;
 493 
 494         for (i = 0; i < numChains; i++) {
 495                 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
 496                 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
 497                 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
 498                 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
 499 
 500                 ARN_DBG((ARN_DBG_CALIBRATE,
 501                     "Starting ADC Gain Cal for Chain %d\n", i));
 502 
 503                 ARN_DBG((ARN_DBG_CALIBRATE,
 504                     "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
 505                     iOddMeasOffset));
 506                 ARN_DBG((ARN_DBG_CALIBRATE,
 507                     "Chn %d pwr_meas_even_i = 0x%08x\n", i,
 508                     iEvenMeasOffset));
 509                 ARN_DBG((ARN_DBG_CALIBRATE,
 510                     "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
 511                     qOddMeasOffset));
 512                 ARN_DBG((ARN_DBG_CALIBRATE,
 513                     "Chn %d pwr_meas_even_q = 0x%08x\n", i,
 514                     qEvenMeasOffset));
 515 
 516                 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
 517                         iGainMismatch =
 518                             ((iEvenMeasOffset * 32) /
 519                             iOddMeasOffset) & 0x3f;
 520                         qGainMismatch =
 521                             ((qOddMeasOffset * 32) /
 522                             qEvenMeasOffset) & 0x3f;
 523 
 524                         ARN_DBG((ARN_DBG_CALIBRATE,
 525                             "Chn %d gain_mismatch_i = 0x%08x\n", i,
 526                             iGainMismatch));
 527                         ARN_DBG((ARN_DBG_CALIBRATE,
 528                             "Chn %d gain_mismatch_q = 0x%08x\n", i,
 529                             qGainMismatch));
 530 
 531                         val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
 532                         val &= 0xfffff000;
 533                         val |= (qGainMismatch) | (iGainMismatch << 6);
 534                         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
 535 
 536                         ARN_DBG((ARN_DBG_CALIBRATE,
 537                             "ADC Gain Cal done for Chain %d\n", i));
 538                 }
 539         }
 540 
 541         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
 542             REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
 543             AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
 544 }
 545 
 546 static void
 547 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, uint8_t numChains)
 548 {
 549         struct ath_hal_5416 *ahp = AH5416(ah);
 550         uint32_t iOddMeasOffset, iEvenMeasOffset, val, i;
 551         int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
 552         const struct hal_percal_data *calData =
 553             ahp->ah_cal_list_curr->calData;
 554         uint32_t numSamples =
 555             (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
 556 
 557         for (i = 0; i < numChains; i++) {
 558                 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
 559                 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
 560                 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
 561                 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
 562 
 563                 ARN_DBG((ARN_DBG_CALIBRATE,
 564                     "Starting ADC DC Offset Cal for Chain %d\n", i));
 565 
 566                 ARN_DBG((ARN_DBG_CALIBRATE,
 567                     "Chn %d pwr_meas_odd_i = %d\n", i,
 568                     iOddMeasOffset));
 569                 ARN_DBG((ARN_DBG_CALIBRATE,
 570                     "Chn %d pwr_meas_even_i = %d\n", i,
 571                     iEvenMeasOffset));
 572                 ARN_DBG((ARN_DBG_CALIBRATE,
 573                     "Chn %d pwr_meas_odd_q = %d\n", i,
 574                     qOddMeasOffset));
 575                 ARN_DBG((ARN_DBG_CALIBRATE,
 576                     "Chn %d pwr_meas_even_q = %d\n", i,
 577                     qEvenMeasOffset));
 578 
 579                 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
 580                     numSamples) & 0x1ff;
 581                 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
 582                     numSamples) & 0x1ff;
 583 
 584                 ARN_DBG((ARN_DBG_CALIBRATE,
 585                     "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
 586                     iDcMismatch));
 587                 ARN_DBG((ARN_DBG_CALIBRATE,
 588                     "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
 589                     qDcMismatch));
 590 
 591                 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
 592                 val &= 0xc0000fff;
 593                 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
 594                 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
 595 
 596                 ARN_DBG((ARN_DBG_CALIBRATE,
 597                     "ADC DC Offset Cal done for Chain %d\n", i));
 598         }
 599 
 600         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
 601             REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
 602             AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
 603 }
 604 
 605 void
 606 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
 607     boolean_t *isCalDone)
 608 {
 609         struct ath_hal_5416 *ahp = AH5416(ah);
 610         struct ath9k_channel *ichan =
 611             ath9k_regd_check_channel(ah, chan);
 612         struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
 613 
 614         *isCalDone = B_TRUE;
 615 
 616         if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
 617                 return;
 618 
 619         if (currCal == NULL)
 620                 return;
 621 
 622         if (ichan == NULL) {
 623                 ARN_DBG((ARN_DBG_CALIBRATE,
 624                     "%s: invalid channel %u/0x%x; no mapping\n",
 625                     __func__, chan->channel, chan->channelFlags));
 626                 return;
 627         }
 628 
 629 
 630         if (currCal->calState != CAL_DONE) {
 631                 ARN_DBG((ARN_DBG_CALIBRATE,
 632                     "%s: Calibration state incorrect, %d\n",
 633                     __func__, currCal->calState));
 634                 return;
 635         }
 636 
 637 
 638         if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
 639                 return;
 640         ARN_DBG((ARN_DBG_CALIBRATE,
 641             "%s: Resetting Cal %d state for channel %u/0x%x\n",
 642             __func__, currCal->calData->calType, chan->channel,
 643             chan->channelFlags));
 644 
 645         ichan->CalValid &= ~currCal->calData->calType;
 646         currCal->calState = CAL_WAITING;
 647 
 648         *isCalDone = B_FALSE;
 649 }
 650 
 651 void
 652 ath9k_hw_start_nfcal(struct ath_hal *ah)
 653 {
 654         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
 655             AR_PHY_AGC_CONTROL_ENABLE_NF);
 656         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
 657             AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
 658         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 659 }
 660 
 661 /* ARGSUSED */
 662 void
 663 ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
 664 {
 665         struct ath9k_nfcal_hist *h;
 666         int i, j;
 667         int32_t val;
 668         const uint32_t ar5416_cca_regs[6] = {
 669                 AR_PHY_CCA,
 670                 AR_PHY_CH1_CCA,
 671                 AR_PHY_CH2_CCA,
 672                 AR_PHY_EXT_CCA,
 673                 AR_PHY_CH1_EXT_CCA,
 674                 AR_PHY_CH2_EXT_CCA
 675         };
 676         uint8_t chainmask;
 677 
 678         if (AR_SREV_9280(ah))
 679                 chainmask = 0x1B;
 680         else
 681                 chainmask = 0x3F;
 682 
 683 #ifdef ARN_NF_PER_CHAN
 684         h = chan->nfCalHist;
 685 #else
 686         h = ah->nfCalHist;
 687 #endif
 688 
 689         for (i = 0; i < NUM_NF_READINGS; i++) {
 690                 if (chainmask & (1 << i)) {
 691                         val = REG_READ(ah, ar5416_cca_regs[i]);
 692                         val &= 0xFFFFFE00;
 693                         val |= (((uint32_t)(h[i].privNF) << 1) & 0x1ff);
 694                         REG_WRITE(ah, ar5416_cca_regs[i], val);
 695                 }
 696         }
 697 
 698         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 699             AR_PHY_AGC_CONTROL_ENABLE_NF);
 700         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 701             AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
 702         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 703 
 704         for (j = 0; j < 1000; j++) {
 705                 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
 706                     AR_PHY_AGC_CONTROL_NF) == 0)
 707                         break;
 708                 drv_usecwait(10);
 709         }
 710 
 711         for (i = 0; i < NUM_NF_READINGS; i++) {
 712                 if (chainmask & (1 << i)) {
 713                         val = REG_READ(ah, ar5416_cca_regs[i]);
 714                         val &= 0xFFFFFE00;
 715                         val |= (((uint32_t)(-50) << 1) & 0x1ff);
 716                         REG_WRITE(ah, ar5416_cca_regs[i], val);
 717                 }
 718         }
 719 }
 720 
 721 int16_t
 722 ath9k_hw_getnf(struct ath_hal *ah, struct ath9k_channel *chan)
 723 {
 724         int16_t nf, nfThresh;
 725         int16_t nfarray[NUM_NF_READINGS] = { 0 };
 726         struct ath9k_nfcal_hist *h;
 727         /* LINTED E_FUNC_SET_NOT_USED */
 728         uint8_t chainmask;
 729 
 730         if (AR_SREV_9280(ah))
 731                 chainmask = 0x1B;
 732         else
 733                 chainmask = 0x3F;
 734 
 735         chan->channelFlags &= (~CHANNEL_CW_INT);
 736         if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
 737                 ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
 738                     "%s: NF did not complete in calibration window\n",
 739                     __func__));
 740                 nf = 0;
 741                 chan->rawNoiseFloor = nf;
 742                 return (chan->rawNoiseFloor);
 743         } else {
 744                 ath9k_hw_do_getnf(ah, nfarray);
 745                 nf = nfarray[0];
 746                 if (getNoiseFloorThresh(ah, chan, &nfThresh) &&
 747                     nf > nfThresh) {
 748                         ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
 749                             "%s: noise floor failed detected; "
 750                             "detected %d, threshold %d\n", __func__,
 751                             nf, nfThresh));
 752                         chan->channelFlags |= CHANNEL_CW_INT;
 753                 }
 754         }
 755 
 756 #ifdef ARN_NF_PER_CHAN
 757         h = chan->nfCalHist;
 758 #else
 759         h = ah->nfCalHist;
 760 #endif
 761 
 762         ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
 763         chan->rawNoiseFloor = h[0].privNF;
 764 
 765         return (chan->rawNoiseFloor);
 766 }
 767 
 768 void
 769 ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
 770 {
 771         int i, j;
 772         int16_t noise_floor;
 773 
 774         if (AR_SREV_9280(ah))
 775                 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
 776         else if (AR_SREV_9285(ah))
 777                 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
 778         else
 779                 noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
 780 
 781         for (i = 0; i < NUM_NF_READINGS; i++) {
 782                 ah->nfCalHist[i].currIndex = 0;
 783                 ah->nfCalHist[i].privNF = noise_floor;
 784                 ah->nfCalHist[i].invalidNFcount =
 785                     AR_PHY_CCA_FILTERWINDOW_LENGTH;
 786                 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
 787                         ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
 788                 }
 789         }
 790 }
 791 
 792 signed short
 793 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
 794 {
 795         struct ath9k_channel *ichan;
 796         signed short nf;
 797 
 798         ichan = ath9k_regd_check_channel(ah, chan);
 799         if (ichan == NULL) {
 800                 ARN_DBG((ARN_DBG_CALIBRATE,
 801                     "%s: invalid channel %u/0x%x; no mapping\n",
 802                     __func__, chan->channel, chan->channelFlags));
 803                 return (ATH_DEFAULT_NOISE_FLOOR);
 804         }
 805         if (ichan->rawNoiseFloor == 0) {
 806                 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
 807                 nf = NOISE_FLOOR[mode];
 808         } else
 809                 nf = ichan->rawNoiseFloor;
 810 
 811         if (!ath9k_hw_nf_in_range(ah, nf))
 812                 nf = ATH_DEFAULT_NOISE_FLOOR;
 813 
 814         return (nf);
 815 }
 816 
 817 boolean_t
 818 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
 819     uint8_t rxchainmask, boolean_t longcal,
 820     boolean_t *isCalDone)
 821 {
 822         struct ath_hal_5416 *ahp = AH5416(ah);
 823         struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
 824         struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
 825 
 826         *isCalDone = B_TRUE;
 827 
 828         if (ichan == NULL) {
 829                 ARN_DBG((ARN_DBG_CHANNEL,
 830                     "%s: invalid channel %u/0x%x; no mapping\n",
 831                     __func__, chan->channel, chan->channelFlags));
 832                 return (B_FALSE);
 833         }
 834 
 835         if (currCal &&
 836             (currCal->calState == CAL_RUNNING ||
 837             currCal->calState == CAL_WAITING)) {
 838                 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
 839                     isCalDone);
 840                 if (*isCalDone) {
 841                         ahp->ah_cal_list_curr = currCal = currCal->calNext;
 842 
 843                         if (currCal->calState == CAL_WAITING) {
 844                                 *isCalDone = B_FALSE;
 845                                 ath9k_hw_reset_calibration(ah, currCal);
 846                         }
 847                 }
 848         }
 849 
 850         if (longcal) {
 851                 (void) ath9k_hw_getnf(ah, ichan);
 852                 ath9k_hw_loadnf(ah, ah->ah_curchan);
 853                 ath9k_hw_start_nfcal(ah);
 854 
 855                 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
 856                         chan->channelFlags |= CHANNEL_CW_INT;
 857                         ichan->channelFlags &= ~CHANNEL_CW_INT;
 858                 }
 859         }
 860 
 861         return (B_TRUE);
 862 }
 863 
 864 /* AR9285 */
 865 static inline void
 866 ath9k_hw_9285_pa_cal(struct ath_hal *ah)
 867 {
 868 
 869         uint32_t regVal;
 870         int i, offset, offs_6_1, offs_0;
 871         uint32_t ccomp_org, reg_field;
 872         uint32_t regList[][2] = {
 873             { 0x786c, 0 },
 874             { 0x7854, 0 },
 875             { 0x7820, 0 },
 876             { 0x7824, 0 },
 877             { 0x7868, 0 },
 878             { 0x783c, 0 },
 879             { 0x7838, 0 },
 880         };
 881 
 882         if (AR_SREV_9285_11(ah)) {
 883                 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
 884                 drv_usecwait(10);
 885         }
 886 
 887         for (i = 0; i < ARRAY_SIZE(regList); i++)
 888                 regList[i][1] = REG_READ(ah, regList[i][0]);
 889 
 890         regVal = REG_READ(ah, 0x7834);
 891         regVal &= (~(0x1));
 892         REG_WRITE(ah, 0x7834, regVal);
 893         regVal = REG_READ(ah, 0x9808);
 894         regVal |= (0x1 << 27);
 895         REG_WRITE(ah, 0x9808, regVal);
 896 
 897         REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
 898         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
 899         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
 900         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
 901         REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
 902         REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
 903         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
 904         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1);
 905         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
 906         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
 907         REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
 908         REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
 909         ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
 910         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7);
 911 
 912         REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
 913         drv_usecwait(30);
 914         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
 915         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
 916 
 917         for (i = 6; i > 0; i--) {
 918                 regVal = REG_READ(ah, 0x7834);
 919                 regVal |= (1 << (19 + i));
 920                 REG_WRITE(ah, 0x7834, regVal);
 921                 drv_usecwait(1);
 922                 regVal = REG_READ(ah, 0x7834);
 923                 regVal &= (~(0x1 << (19 + i)));
 924                 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
 925                 regVal |= (reg_field << (19 + i));
 926                 REG_WRITE(ah, 0x7834, regVal);
 927         }
 928 
 929         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
 930         drv_usecwait(1);
 931         reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
 932         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
 933         offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
 934         offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
 935 
 936         offset = (offs_6_1<<1) | offs_0;
 937         offset = offset - 0;
 938         offs_6_1 = offset>>1;
 939         offs_0 = offset & 1;
 940 
 941         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
 942         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
 943 
 944         regVal = REG_READ(ah, 0x7834);
 945         regVal |= 0x1;
 946         REG_WRITE(ah, 0x7834, regVal);
 947         regVal = REG_READ(ah, 0x9808);
 948         regVal &= (~(0x1 << 27));
 949         REG_WRITE(ah, 0x9808, regVal);
 950 
 951         for (i = 0; i < ARRAY_SIZE(regList); i++)
 952                 REG_WRITE(ah, regList[i][0], regList[i][1]);
 953 
 954         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
 955 
 956         if (AR_SREV_9285_11(ah))
 957                 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
 958 
 959 }
 960 
 961 boolean_t
 962 ath9k_hw_init_cal(struct ath_hal *ah,
 963     struct ath9k_channel *chan)
 964 {
 965         struct ath_hal_5416 *ahp = AH5416(ah);
 966         struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
 967 
 968         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
 969             REG_READ(ah, AR_PHY_AGC_CONTROL) |
 970             AR_PHY_AGC_CONTROL_CAL);
 971 
 972         if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
 973                 ARN_DBG((ARN_DBG_CALIBRATE,
 974                     "%s: offset calibration failed to complete in 1ms; "
 975                     "noisy environment?\n", __func__));
 976                 return (B_FALSE);
 977         }
 978 
 979         if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
 980                         ath9k_hw_9285_pa_cal(ah);
 981 
 982         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
 983             REG_READ(ah, AR_PHY_AGC_CONTROL) |
 984             AR_PHY_AGC_CONTROL_NF);
 985 
 986         ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
 987 
 988         if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
 989                 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
 990                         /* LINTED: E_CONSTANT_CONDITION */
 991                         INIT_CAL(&ahp->ah_adcGainCalData);
 992                         /* LINTED: E_CONSTANT_CONDITION */
 993                         INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
 994                         ARN_DBG((ARN_DBG_CALIBRATE,
 995                             "%s: enabling ADC Gain Calibration.\n",
 996                             __func__));
 997                 }
 998                 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
 999                         /* LINTED: E_CONSTANT_CONDITION */
1000                         INIT_CAL(&ahp->ah_adcDcCalData);
1001                         /* LINTED: E_CONSTANT_CONDITION */
1002                         INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
1003                         ARN_DBG((ARN_DBG_CALIBRATE,
1004                             "%s: enabling ADC DC Calibration.\n",
1005                             __func__));
1006                 }
1007                 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
1008                         /* LINTED: E_CONSTANT_CONDITION */
1009                         INIT_CAL(&ahp->ah_iqCalData);
1010                         /* LINTED: E_CONSTANT_CONDITION */
1011                         INSERT_CAL(ahp, &ahp->ah_iqCalData);
1012                         ARN_DBG((ARN_DBG_CALIBRATE,
1013                             "%s: enabling IQ Calibration.\n",
1014                             __func__));
1015                 }
1016 
1017                 ahp->ah_cal_list_curr = ahp->ah_cal_list;
1018 
1019                 if (ahp->ah_cal_list_curr)
1020                         ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr);
1021         }
1022 
1023         ichan->CalValid = 0;
1024 
1025         return (B_TRUE);
1026 }
1027 
1028 const struct hal_percal_data iq_cal_multi_sample = {
1029         IQ_MISMATCH_CAL,
1030         MAX_CAL_SAMPLES,
1031         PER_MIN_LOG_COUNT,
1032         ath9k_hw_iqcal_collect,
1033         ath9k_hw_iqcalibrate
1034 };
1035 const struct hal_percal_data iq_cal_single_sample = {
1036         IQ_MISMATCH_CAL,
1037         MIN_CAL_SAMPLES,
1038         PER_MAX_LOG_COUNT,
1039         ath9k_hw_iqcal_collect,
1040         ath9k_hw_iqcalibrate
1041 };
1042 const struct hal_percal_data adc_gain_cal_multi_sample = {
1043         ADC_GAIN_CAL,
1044         MAX_CAL_SAMPLES,
1045         PER_MIN_LOG_COUNT,
1046         ath9k_hw_adc_gaincal_collect,
1047         ath9k_hw_adc_gaincal_calibrate
1048 };
1049 const struct hal_percal_data adc_gain_cal_single_sample = {
1050         ADC_GAIN_CAL,
1051         MIN_CAL_SAMPLES,
1052         PER_MAX_LOG_COUNT,
1053         ath9k_hw_adc_gaincal_collect,
1054         ath9k_hw_adc_gaincal_calibrate
1055 };
1056 const struct hal_percal_data adc_dc_cal_multi_sample = {
1057         ADC_DC_CAL,
1058         MAX_CAL_SAMPLES,
1059         PER_MIN_LOG_COUNT,
1060         ath9k_hw_adc_dccal_collect,
1061         ath9k_hw_adc_dccal_calibrate
1062 };
1063 const struct hal_percal_data adc_dc_cal_single_sample = {
1064         ADC_DC_CAL,
1065         MIN_CAL_SAMPLES,
1066         PER_MAX_LOG_COUNT,
1067         ath9k_hw_adc_dccal_collect,
1068         ath9k_hw_adc_dccal_calibrate
1069 };
1070 const struct hal_percal_data adc_init_dc_cal = {
1071         ADC_DC_INIT_CAL,
1072         MIN_CAL_SAMPLES,
1073         INIT_LOG_COUNT,
1074         ath9k_hw_adc_dccal_collect,
1075         ath9k_hw_adc_dccal_calibrate
1076 };