root/drivers/net/wireless/ath/ath9k/ar9003_calib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ar9003_hw_setup_calibration
  2. ar9003_hw_per_calibration
  3. ar9003_hw_calibrate
  4. ar9003_hw_iqcal_collect
  5. ar9003_hw_iqcalibrate
  6. ar9003_hw_init_cal_settings
  7. ar9003_hw_dynamic_osdac_selection
  8. ar9003_hw_solve_iq_cal
  9. ar9003_hw_find_mag_approx
  10. ar9003_hw_calc_iq_corr
  11. ar9003_hw_detect_outlier
  12. ar9003_hw_tx_iq_cal_outlier_detection
  13. ar9003_hw_tx_iq_cal_run
  14. __ar955x_tx_iq_cal_sort
  15. ar955x_tx_iq_cal_median
  16. ar9003_hw_tx_iq_cal_post_proc
  17. ar9003_hw_tx_iq_cal_reload
  18. ar9003_hw_manual_peak_cal
  19. ar9003_hw_do_pcoem_manual_peak_cal
  20. ar9003_hw_cl_cal_post_proc
  21. ar9003_hw_init_cal_common
  22. ar9003_hw_init_cal_pcoem
  23. do_ar9003_agc_cal
  24. ar9003_hw_init_cal_soc
  25. ar9003_hw_attach_calib_ops

   1 /*
   2  * Copyright (c) 2010-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 "hw.h"
  18 #include "hw-ops.h"
  19 #include "ar9003_phy.h"
  20 #include "ar9003_rtt.h"
  21 #include "ar9003_mci.h"
  22 
  23 #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT
  24 #define MAX_MAG_DELTA   11
  25 #define MAX_PHS_DELTA   10
  26 #define MAXIQCAL        3
  27 
  28 struct coeff {
  29         int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
  30         int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
  31         int iqc_coeff[2];
  32 };
  33 
  34 enum ar9003_cal_types {
  35         IQ_MISMATCH_CAL = BIT(0),
  36 };
  37 
  38 static void ar9003_hw_setup_calibration(struct ath_hw *ah,
  39                                         struct ath9k_cal_list *currCal)
  40 {
  41         struct ath_common *common = ath9k_hw_common(ah);
  42 
  43         /* Select calibration to run */
  44         switch (currCal->calData->calType) {
  45         case IQ_MISMATCH_CAL:
  46                 /*
  47                  * Start calibration with
  48                  * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples
  49                  */
  50                 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
  51                               AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
  52                               currCal->calData->calCountMax);
  53                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
  54 
  55                 ath_dbg(common, CALIBRATE,
  56                         "starting IQ Mismatch Calibration\n");
  57 
  58                 /* Kick-off cal */
  59                 REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
  60                 break;
  61         default:
  62                 ath_err(common, "Invalid calibration type\n");
  63                 break;
  64         }
  65 }
  66 
  67 /*
  68  * Generic calibration routine.
  69  * Recalibrate the lower PHY chips to account for temperature/environment
  70  * changes.
  71  */
  72 static bool ar9003_hw_per_calibration(struct ath_hw *ah,
  73                                       struct ath9k_channel *ichan,
  74                                       u8 rxchainmask,
  75                                       struct ath9k_cal_list *currCal)
  76 {
  77         struct ath9k_hw_cal_data *caldata = ah->caldata;
  78         const struct ath9k_percal_data *cur_caldata = currCal->calData;
  79 
  80         /* Calibration in progress. */
  81         if (currCal->calState == CAL_RUNNING) {
  82                 /* Check to see if it has finished. */
  83                 if (REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)
  84                         return false;
  85 
  86                 /*
  87                 * Accumulate cal measures for active chains
  88                 */
  89                 cur_caldata->calCollect(ah);
  90                 ah->cal_samples++;
  91 
  92                 if (ah->cal_samples >= cur_caldata->calNumSamples) {
  93                         unsigned int i, numChains = 0;
  94                         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
  95                                 if (rxchainmask & (1 << i))
  96                                         numChains++;
  97                         }
  98 
  99                         /*
 100                         * Process accumulated data
 101                         */
 102                         cur_caldata->calPostProc(ah, numChains);
 103 
 104                         /* Calibration has finished. */
 105                         caldata->CalValid |= cur_caldata->calType;
 106                         currCal->calState = CAL_DONE;
 107                         return true;
 108                 } else {
 109                         /*
 110                          * Set-up collection of another sub-sample until we
 111                          * get desired number
 112                          */
 113                         ar9003_hw_setup_calibration(ah, currCal);
 114                 }
 115         } else if (!(caldata->CalValid & cur_caldata->calType)) {
 116                 /* If current cal is marked invalid in channel, kick it off */
 117                 ath9k_hw_reset_calibration(ah, currCal);
 118         }
 119 
 120         return false;
 121 }
 122 
 123 static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 124                                u8 rxchainmask, bool longcal)
 125 {
 126         bool iscaldone = true;
 127         struct ath9k_cal_list *currCal = ah->cal_list_curr;
 128         int ret;
 129 
 130         /*
 131          * For given calibration:
 132          * 1. Call generic cal routine
 133          * 2. When this cal is done (isCalDone) if we have more cals waiting
 134          *    (eg after reset), mask this to upper layers by not propagating
 135          *    isCalDone if it is set to TRUE.
 136          *    Instead, change isCalDone to FALSE and setup the waiting cal(s)
 137          *    to be run.
 138          */
 139         if (currCal &&
 140             (currCal->calState == CAL_RUNNING ||
 141              currCal->calState == CAL_WAITING)) {
 142                 iscaldone = ar9003_hw_per_calibration(ah, chan,
 143                                                       rxchainmask, currCal);
 144                 if (iscaldone) {
 145                         ah->cal_list_curr = currCal = currCal->calNext;
 146 
 147                         if (currCal->calState == CAL_WAITING) {
 148                                 iscaldone = false;
 149                                 ath9k_hw_reset_calibration(ah, currCal);
 150                         }
 151                 }
 152         }
 153 
 154         /*
 155          * Do NF cal only at longer intervals. Get the value from
 156          * the previous NF cal and update history buffer.
 157          */
 158         if (longcal && ath9k_hw_getnf(ah, chan)) {
 159                 /*
 160                  * Load the NF from history buffer of the current channel.
 161                  * NF is slow time-variant, so it is OK to use a historical
 162                  * value.
 163                  */
 164                 ret = ath9k_hw_loadnf(ah, ah->curchan);
 165                 if (ret < 0)
 166                         return ret;
 167 
 168                 /* start NF calibration, without updating BB NF register */
 169                 ath9k_hw_start_nfcal(ah, false);
 170         }
 171 
 172         return iscaldone;
 173 }
 174 
 175 static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
 176 {
 177         int i;
 178 
 179         /* Accumulate IQ cal measures for active chains */
 180         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 181                 if (ah->txchainmask & BIT(i)) {
 182                         ah->totalPowerMeasI[i] +=
 183                                 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
 184                         ah->totalPowerMeasQ[i] +=
 185                                 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
 186                         ah->totalIqCorrMeas[i] +=
 187                                 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
 188                         ath_dbg(ath9k_hw_common(ah), CALIBRATE,
 189                                 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
 190                                 ah->cal_samples, i, ah->totalPowerMeasI[i],
 191                                 ah->totalPowerMeasQ[i],
 192                                 ah->totalIqCorrMeas[i]);
 193                 }
 194         }
 195 }
 196 
 197 static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
 198 {
 199         struct ath_common *common = ath9k_hw_common(ah);
 200         u32 powerMeasQ, powerMeasI, iqCorrMeas;
 201         u32 qCoffDenom, iCoffDenom;
 202         int32_t qCoff, iCoff;
 203         int iqCorrNeg, i;
 204         static const u_int32_t offset_array[3] = {
 205                 AR_PHY_RX_IQCAL_CORR_B0,
 206                 AR_PHY_RX_IQCAL_CORR_B1,
 207                 AR_PHY_RX_IQCAL_CORR_B2,
 208         };
 209 
 210         for (i = 0; i < numChains; i++) {
 211                 powerMeasI = ah->totalPowerMeasI[i];
 212                 powerMeasQ = ah->totalPowerMeasQ[i];
 213                 iqCorrMeas = ah->totalIqCorrMeas[i];
 214 
 215                 ath_dbg(common, CALIBRATE,
 216                         "Starting IQ Cal and Correction for Chain %d\n", i);
 217 
 218                 ath_dbg(common, CALIBRATE,
 219                         "Original: Chn %d iq_corr_meas = 0x%08x\n",
 220                         i, ah->totalIqCorrMeas[i]);
 221 
 222                 iqCorrNeg = 0;
 223 
 224                 if (iqCorrMeas > 0x80000000) {
 225                         iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
 226                         iqCorrNeg = 1;
 227                 }
 228 
 229                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_i = 0x%08x\n",
 230                         i, powerMeasI);
 231                 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_q = 0x%08x\n",
 232                         i, powerMeasQ);
 233                 ath_dbg(common, CALIBRATE, "iqCorrNeg is 0x%08x\n", iqCorrNeg);
 234 
 235                 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
 236                 qCoffDenom = powerMeasQ / 64;
 237 
 238                 if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
 239                         iCoff = iqCorrMeas / iCoffDenom;
 240                         qCoff = powerMeasI / qCoffDenom - 64;
 241                         ath_dbg(common, CALIBRATE, "Chn %d iCoff = 0x%08x\n",
 242                                 i, iCoff);
 243                         ath_dbg(common, CALIBRATE, "Chn %d qCoff = 0x%08x\n",
 244                                 i, qCoff);
 245 
 246                         /* Force bounds on iCoff */
 247                         if (iCoff >= 63)
 248                                 iCoff = 63;
 249                         else if (iCoff <= -63)
 250                                 iCoff = -63;
 251 
 252                         /* Negate iCoff if iqCorrNeg == 0 */
 253                         if (iqCorrNeg == 0x0)
 254                                 iCoff = -iCoff;
 255 
 256                         /* Force bounds on qCoff */
 257                         if (qCoff >= 63)
 258                                 qCoff = 63;
 259                         else if (qCoff <= -63)
 260                                 qCoff = -63;
 261 
 262                         iCoff = iCoff & 0x7f;
 263                         qCoff = qCoff & 0x7f;
 264 
 265                         ath_dbg(common, CALIBRATE,
 266                                 "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
 267                                 i, iCoff, qCoff);
 268                         ath_dbg(common, CALIBRATE,
 269                                 "Register offset (0x%04x) before update = 0x%x\n",
 270                                 offset_array[i],
 271                                 REG_READ(ah, offset_array[i]));
 272 
 273                         if (AR_SREV_9565(ah) &&
 274                             (iCoff == 63 || qCoff == 63 ||
 275                              iCoff == -63 || qCoff == -63))
 276                                 return;
 277 
 278                         REG_RMW_FIELD(ah, offset_array[i],
 279                                       AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
 280                                       iCoff);
 281                         REG_RMW_FIELD(ah, offset_array[i],
 282                                       AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
 283                                       qCoff);
 284                         ath_dbg(common, CALIBRATE,
 285                                 "Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n",
 286                                 offset_array[i],
 287                                 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
 288                                 REG_READ(ah, offset_array[i]));
 289                         ath_dbg(common, CALIBRATE,
 290                                 "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n",
 291                                 offset_array[i],
 292                                 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
 293                                 REG_READ(ah, offset_array[i]));
 294 
 295                         ath_dbg(common, CALIBRATE,
 296                                 "IQ Cal and Correction done for Chain %d\n", i);
 297                 }
 298         }
 299 
 300         REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
 301                     AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
 302         ath_dbg(common, CALIBRATE,
 303                 "IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n",
 304                 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
 305                 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
 306                 REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
 307 }
 308 
 309 static const struct ath9k_percal_data iq_cal_single_sample = {
 310         IQ_MISMATCH_CAL,
 311         MIN_CAL_SAMPLES,
 312         PER_MAX_LOG_COUNT,
 313         ar9003_hw_iqcal_collect,
 314         ar9003_hw_iqcalibrate
 315 };
 316 
 317 static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
 318 {
 319         ah->iq_caldata.calData = &iq_cal_single_sample;
 320 
 321         if (AR_SREV_9300_20_OR_LATER(ah)) {
 322                 ah->enabled_cals |= TX_IQ_CAL;
 323                 if (AR_SREV_9485_OR_LATER(ah) && !AR_SREV_9340(ah))
 324                         ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
 325         }
 326 
 327         ah->supp_cals = IQ_MISMATCH_CAL;
 328 }
 329 
 330 #define OFF_UPPER_LT 24
 331 #define OFF_LOWER_LT 7
 332 
 333 static bool ar9003_hw_dynamic_osdac_selection(struct ath_hw *ah,
 334                                               bool txiqcal_done)
 335 {
 336         struct ath_common *common = ath9k_hw_common(ah);
 337         int ch0_done, osdac_ch0, dc_off_ch0_i1, dc_off_ch0_q1, dc_off_ch0_i2,
 338                 dc_off_ch0_q2, dc_off_ch0_i3, dc_off_ch0_q3;
 339         int ch1_done, osdac_ch1, dc_off_ch1_i1, dc_off_ch1_q1, dc_off_ch1_i2,
 340                 dc_off_ch1_q2, dc_off_ch1_i3, dc_off_ch1_q3;
 341         int ch2_done, osdac_ch2, dc_off_ch2_i1, dc_off_ch2_q1, dc_off_ch2_i2,
 342                 dc_off_ch2_q2, dc_off_ch2_i3, dc_off_ch2_q3;
 343         bool status;
 344         u32 temp, val;
 345 
 346         /*
 347          * Clear offset and IQ calibration, run AGC cal.
 348          */
 349         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 350                     AR_PHY_AGC_CONTROL_OFFSET_CAL);
 351         REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
 352                     AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
 353         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
 354                   REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
 355 
 356         status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
 357                                AR_PHY_AGC_CONTROL_CAL,
 358                                0, AH_WAIT_TIMEOUT);
 359         if (!status) {
 360                 ath_dbg(common, CALIBRATE,
 361                         "AGC cal without offset cal failed to complete in 1ms");
 362                 return false;
 363         }
 364 
 365         /*
 366          * Allow only offset calibration and disable the others
 367          * (Carrier Leak calibration, TX Filter calibration and
 368          *  Peak Detector offset calibration).
 369          */
 370         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
 371                     AR_PHY_AGC_CONTROL_OFFSET_CAL);
 372         REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
 373                     AR_PHY_CL_CAL_ENABLE);
 374         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 375                     AR_PHY_AGC_CONTROL_FLTR_CAL);
 376         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 377                     AR_PHY_AGC_CONTROL_PKDET_CAL);
 378 
 379         ch0_done = 0;
 380         ch1_done = 0;
 381         ch2_done = 0;
 382 
 383         while ((ch0_done == 0) || (ch1_done == 0) || (ch2_done == 0)) {
 384                 osdac_ch0 = (REG_READ(ah, AR_PHY_65NM_CH0_BB1) >> 30) & 0x3;
 385                 osdac_ch1 = (REG_READ(ah, AR_PHY_65NM_CH1_BB1) >> 30) & 0x3;
 386                 osdac_ch2 = (REG_READ(ah, AR_PHY_65NM_CH2_BB1) >> 30) & 0x3;
 387 
 388                 REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
 389 
 390                 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
 391                           REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
 392 
 393                 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
 394                                        AR_PHY_AGC_CONTROL_CAL,
 395                                        0, AH_WAIT_TIMEOUT);
 396                 if (!status) {
 397                         ath_dbg(common, CALIBRATE,
 398                                 "DC offset cal failed to complete in 1ms");
 399                         return false;
 400                 }
 401 
 402                 REG_CLR_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
 403 
 404                 /*
 405                  * High gain.
 406                  */
 407                 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
 408                           ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (1 << 8)));
 409                 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
 410                           ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (1 << 8)));
 411                 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
 412                           ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (1 << 8)));
 413 
 414                 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
 415                 dc_off_ch0_i1 = (temp >> 26) & 0x1f;
 416                 dc_off_ch0_q1 = (temp >> 21) & 0x1f;
 417 
 418                 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
 419                 dc_off_ch1_i1 = (temp >> 26) & 0x1f;
 420                 dc_off_ch1_q1 = (temp >> 21) & 0x1f;
 421 
 422                 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
 423                 dc_off_ch2_i1 = (temp >> 26) & 0x1f;
 424                 dc_off_ch2_q1 = (temp >> 21) & 0x1f;
 425 
 426                 /*
 427                  * Low gain.
 428                  */
 429                 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
 430                           ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (2 << 8)));
 431                 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
 432                           ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (2 << 8)));
 433                 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
 434                           ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (2 << 8)));
 435 
 436                 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
 437                 dc_off_ch0_i2 = (temp >> 26) & 0x1f;
 438                 dc_off_ch0_q2 = (temp >> 21) & 0x1f;
 439 
 440                 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
 441                 dc_off_ch1_i2 = (temp >> 26) & 0x1f;
 442                 dc_off_ch1_q2 = (temp >> 21) & 0x1f;
 443 
 444                 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
 445                 dc_off_ch2_i2 = (temp >> 26) & 0x1f;
 446                 dc_off_ch2_q2 = (temp >> 21) & 0x1f;
 447 
 448                 /*
 449                  * Loopback.
 450                  */
 451                 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
 452                           ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (3 << 8)));
 453                 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
 454                           ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (3 << 8)));
 455                 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
 456                           ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (3 << 8)));
 457 
 458                 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
 459                 dc_off_ch0_i3 = (temp >> 26) & 0x1f;
 460                 dc_off_ch0_q3 = (temp >> 21) & 0x1f;
 461 
 462                 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
 463                 dc_off_ch1_i3 = (temp >> 26) & 0x1f;
 464                 dc_off_ch1_q3 = (temp >> 21) & 0x1f;
 465 
 466                 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
 467                 dc_off_ch2_i3 = (temp >> 26) & 0x1f;
 468                 dc_off_ch2_q3 = (temp >> 21) & 0x1f;
 469 
 470                 if ((dc_off_ch0_i1 > OFF_UPPER_LT) || (dc_off_ch0_i1 < OFF_LOWER_LT) ||
 471                     (dc_off_ch0_i2 > OFF_UPPER_LT) || (dc_off_ch0_i2 < OFF_LOWER_LT) ||
 472                     (dc_off_ch0_i3 > OFF_UPPER_LT) || (dc_off_ch0_i3 < OFF_LOWER_LT) ||
 473                     (dc_off_ch0_q1 > OFF_UPPER_LT) || (dc_off_ch0_q1 < OFF_LOWER_LT) ||
 474                     (dc_off_ch0_q2 > OFF_UPPER_LT) || (dc_off_ch0_q2 < OFF_LOWER_LT) ||
 475                     (dc_off_ch0_q3 > OFF_UPPER_LT) || (dc_off_ch0_q3 < OFF_LOWER_LT)) {
 476                         if (osdac_ch0 == 3) {
 477                                 ch0_done = 1;
 478                         } else {
 479                                 osdac_ch0++;
 480 
 481                                 val = REG_READ(ah, AR_PHY_65NM_CH0_BB1) & 0x3fffffff;
 482                                 val |= (osdac_ch0 << 30);
 483                                 REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, val);
 484 
 485                                 ch0_done = 0;
 486                         }
 487                 } else {
 488                         ch0_done = 1;
 489                 }
 490 
 491                 if ((dc_off_ch1_i1 > OFF_UPPER_LT) || (dc_off_ch1_i1 < OFF_LOWER_LT) ||
 492                     (dc_off_ch1_i2 > OFF_UPPER_LT) || (dc_off_ch1_i2 < OFF_LOWER_LT) ||
 493                     (dc_off_ch1_i3 > OFF_UPPER_LT) || (dc_off_ch1_i3 < OFF_LOWER_LT) ||
 494                     (dc_off_ch1_q1 > OFF_UPPER_LT) || (dc_off_ch1_q1 < OFF_LOWER_LT) ||
 495                     (dc_off_ch1_q2 > OFF_UPPER_LT) || (dc_off_ch1_q2 < OFF_LOWER_LT) ||
 496                     (dc_off_ch1_q3 > OFF_UPPER_LT) || (dc_off_ch1_q3 < OFF_LOWER_LT)) {
 497                         if (osdac_ch1 == 3) {
 498                                 ch1_done = 1;
 499                         } else {
 500                                 osdac_ch1++;
 501 
 502                                 val = REG_READ(ah, AR_PHY_65NM_CH1_BB1) & 0x3fffffff;
 503                                 val |= (osdac_ch1 << 30);
 504                                 REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, val);
 505 
 506                                 ch1_done = 0;
 507                         }
 508                 } else {
 509                         ch1_done = 1;
 510                 }
 511 
 512                 if ((dc_off_ch2_i1 > OFF_UPPER_LT) || (dc_off_ch2_i1 < OFF_LOWER_LT) ||
 513                     (dc_off_ch2_i2 > OFF_UPPER_LT) || (dc_off_ch2_i2 < OFF_LOWER_LT) ||
 514                     (dc_off_ch2_i3 > OFF_UPPER_LT) || (dc_off_ch2_i3 < OFF_LOWER_LT) ||
 515                     (dc_off_ch2_q1 > OFF_UPPER_LT) || (dc_off_ch2_q1 < OFF_LOWER_LT) ||
 516                     (dc_off_ch2_q2 > OFF_UPPER_LT) || (dc_off_ch2_q2 < OFF_LOWER_LT) ||
 517                     (dc_off_ch2_q3 > OFF_UPPER_LT) || (dc_off_ch2_q3 < OFF_LOWER_LT)) {
 518                         if (osdac_ch2 == 3) {
 519                                 ch2_done = 1;
 520                         } else {
 521                                 osdac_ch2++;
 522 
 523                                 val = REG_READ(ah, AR_PHY_65NM_CH2_BB1) & 0x3fffffff;
 524                                 val |= (osdac_ch2 << 30);
 525                                 REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, val);
 526 
 527                                 ch2_done = 0;
 528                         }
 529                 } else {
 530                         ch2_done = 1;
 531                 }
 532         }
 533 
 534         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 535                     AR_PHY_AGC_CONTROL_OFFSET_CAL);
 536         REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
 537 
 538         /*
 539          * We don't need to check txiqcal_done here since it is always
 540          * set for AR9550.
 541          */
 542         REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
 543                     AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
 544 
 545         return true;
 546 }
 547 
 548 /*
 549  * solve 4x4 linear equation used in loopback iq cal.
 550  */
 551 static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
 552                                    s32 sin_2phi_1,
 553                                    s32 cos_2phi_1,
 554                                    s32 sin_2phi_2,
 555                                    s32 cos_2phi_2,
 556                                    s32 mag_a0_d0,
 557                                    s32 phs_a0_d0,
 558                                    s32 mag_a1_d0,
 559                                    s32 phs_a1_d0,
 560                                    s32 solved_eq[])
 561 {
 562         s32 f1 = cos_2phi_1 - cos_2phi_2,
 563             f3 = sin_2phi_1 - sin_2phi_2,
 564             f2;
 565         s32 mag_tx, phs_tx, mag_rx, phs_rx;
 566         const s32 result_shift = 1 << 15;
 567         struct ath_common *common = ath9k_hw_common(ah);
 568 
 569         f2 = ((f1 >> 3) * (f1 >> 3) + (f3 >> 3) * (f3 >> 3)) >> 9;
 570 
 571         if (!f2) {
 572                 ath_dbg(common, CALIBRATE, "Divide by 0\n");
 573                 return false;
 574         }
 575 
 576         /* mag mismatch, tx */
 577         mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
 578         /* phs mismatch, tx */
 579         phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
 580 
 581         mag_tx = (mag_tx / f2);
 582         phs_tx = (phs_tx / f2);
 583 
 584         /* mag mismatch, rx */
 585         mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
 586                  result_shift;
 587         /* phs mismatch, rx */
 588         phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
 589                  result_shift;
 590 
 591         solved_eq[0] = mag_tx;
 592         solved_eq[1] = phs_tx;
 593         solved_eq[2] = mag_rx;
 594         solved_eq[3] = phs_rx;
 595 
 596         return true;
 597 }
 598 
 599 static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im)
 600 {
 601         s32 abs_i = abs(in_re),
 602             abs_q = abs(in_im),
 603             max_abs, min_abs;
 604 
 605         if (abs_i > abs_q) {
 606                 max_abs = abs_i;
 607                 min_abs = abs_q;
 608         } else {
 609                 max_abs = abs_q;
 610                 min_abs = abs_i;
 611         }
 612 
 613         return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
 614 }
 615 
 616 #define DELPT 32
 617 
 618 static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
 619                                    s32 chain_idx,
 620                                    const s32 iq_res[],
 621                                    s32 iqc_coeff[])
 622 {
 623         s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
 624             i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
 625             i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
 626             i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
 627         s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
 628             phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
 629             sin_2phi_1, cos_2phi_1,
 630             sin_2phi_2, cos_2phi_2;
 631         s32 mag_tx, phs_tx, mag_rx, phs_rx;
 632         s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
 633             q_q_coff, q_i_coff;
 634         const s32 res_scale = 1 << 15;
 635         const s32 delpt_shift = 1 << 8;
 636         s32 mag1, mag2;
 637         struct ath_common *common = ath9k_hw_common(ah);
 638 
 639         i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
 640         i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
 641         iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
 642 
 643         if (i2_m_q2_a0_d0 > 0x800)
 644                 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
 645 
 646         if (i2_p_q2_a0_d0 > 0x800)
 647                 i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
 648 
 649         if (iq_corr_a0_d0 > 0x800)
 650                 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
 651 
 652         i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
 653         i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
 654         iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
 655 
 656         if (i2_m_q2_a0_d1 > 0x800)
 657                 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
 658 
 659         if (iq_corr_a0_d1 > 0x800)
 660                 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
 661 
 662         i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
 663         i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
 664         iq_corr_a1_d0 = iq_res[4] & 0xfff;
 665 
 666         if (i2_m_q2_a1_d0 > 0x800)
 667                 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
 668 
 669         if (i2_p_q2_a1_d0 > 0x800)
 670                 i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
 671 
 672         if (iq_corr_a1_d0 > 0x800)
 673                 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
 674 
 675         i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
 676         i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
 677         iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
 678 
 679         if (i2_m_q2_a1_d1 > 0x800)
 680                 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
 681 
 682         if (i2_p_q2_a1_d1 > 0x800)
 683                 i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
 684 
 685         if (iq_corr_a1_d1 > 0x800)
 686                 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
 687 
 688         if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
 689             (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
 690                 ath_dbg(common, CALIBRATE,
 691                         "Divide by 0:\n"
 692                         "a0_d0=%d\n"
 693                         "a0_d1=%d\n"
 694                         "a2_d0=%d\n"
 695                         "a1_d1=%d\n",
 696                         i2_p_q2_a0_d0, i2_p_q2_a0_d1,
 697                         i2_p_q2_a1_d0, i2_p_q2_a1_d1);
 698                 return false;
 699         }
 700 
 701         if ((i2_p_q2_a0_d0 < 1024) || (i2_p_q2_a0_d0 > 2047) ||
 702             (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
 703             (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
 704             (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
 705             (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
 706             (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
 707             (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
 708             (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
 709             (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
 710             (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
 711                 return false;
 712         }
 713 
 714         mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
 715         phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
 716 
 717         mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
 718         phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
 719 
 720         mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
 721         phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
 722 
 723         mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
 724         phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
 725 
 726         /* w/o analog phase shift */
 727         sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
 728         /* w/o analog phase shift */
 729         cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
 730         /* w/  analog phase shift */
 731         sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
 732         /* w/  analog phase shift */
 733         cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
 734 
 735         /*
 736          * force sin^2 + cos^2 = 1;
 737          * find magnitude by approximation
 738          */
 739         mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
 740         mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
 741 
 742         if ((mag1 == 0) || (mag2 == 0)) {
 743                 ath_dbg(common, CALIBRATE, "Divide by 0: mag1=%d, mag2=%d\n",
 744                         mag1, mag2);
 745                 return false;
 746         }
 747 
 748         /* normalization sin and cos by mag */
 749         sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
 750         cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
 751         sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
 752         cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
 753 
 754         /* calculate IQ mismatch */
 755         if (!ar9003_hw_solve_iq_cal(ah,
 756                              sin_2phi_1, cos_2phi_1,
 757                              sin_2phi_2, cos_2phi_2,
 758                              mag_a0_d0, phs_a0_d0,
 759                              mag_a1_d0,
 760                              phs_a1_d0, solved_eq)) {
 761                 ath_dbg(common, CALIBRATE,
 762                         "Call to ar9003_hw_solve_iq_cal() failed\n");
 763                 return false;
 764         }
 765 
 766         mag_tx = solved_eq[0];
 767         phs_tx = solved_eq[1];
 768         mag_rx = solved_eq[2];
 769         phs_rx = solved_eq[3];
 770 
 771         ath_dbg(common, CALIBRATE,
 772                 "chain %d: mag mismatch=%d phase mismatch=%d\n",
 773                 chain_idx, mag_tx/res_scale, phs_tx/res_scale);
 774 
 775         if (res_scale == mag_tx) {
 776                 ath_dbg(common, CALIBRATE,
 777                         "Divide by 0: mag_tx=%d, res_scale=%d\n",
 778                         mag_tx, res_scale);
 779                 return false;
 780         }
 781 
 782         /* calculate and quantize Tx IQ correction factor */
 783         mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
 784         phs_corr_tx = -phs_tx;
 785 
 786         q_q_coff = (mag_corr_tx * 128 / res_scale);
 787         q_i_coff = (phs_corr_tx * 256 / res_scale);
 788 
 789         ath_dbg(common, CALIBRATE, "tx chain %d: mag corr=%d  phase corr=%d\n",
 790                 chain_idx, q_q_coff, q_i_coff);
 791 
 792         if (q_i_coff < -63)
 793                 q_i_coff = -63;
 794         if (q_i_coff > 63)
 795                 q_i_coff = 63;
 796         if (q_q_coff < -63)
 797                 q_q_coff = -63;
 798         if (q_q_coff > 63)
 799                 q_q_coff = 63;
 800 
 801         iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
 802 
 803         ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n",
 804                 chain_idx, iqc_coeff[0]);
 805 
 806         if (-mag_rx == res_scale) {
 807                 ath_dbg(common, CALIBRATE,
 808                         "Divide by 0: mag_rx=%d, res_scale=%d\n",
 809                         mag_rx, res_scale);
 810                 return false;
 811         }
 812 
 813         /* calculate and quantize Rx IQ correction factors */
 814         mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
 815         phs_corr_rx = -phs_rx;
 816 
 817         q_q_coff = (mag_corr_rx * 128 / res_scale);
 818         q_i_coff = (phs_corr_rx * 256 / res_scale);
 819 
 820         ath_dbg(common, CALIBRATE, "rx chain %d: mag corr=%d  phase corr=%d\n",
 821                 chain_idx, q_q_coff, q_i_coff);
 822 
 823         if (q_i_coff < -63)
 824                 q_i_coff = -63;
 825         if (q_i_coff > 63)
 826                 q_i_coff = 63;
 827         if (q_q_coff < -63)
 828                 q_q_coff = -63;
 829         if (q_q_coff > 63)
 830                 q_q_coff = 63;
 831 
 832         iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
 833 
 834         ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n",
 835                 chain_idx, iqc_coeff[1]);
 836 
 837         return true;
 838 }
 839 
 840 static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL],
 841                                      int nmeasurement,
 842                                      int max_delta)
 843 {
 844         int mp_max = -64, max_idx = 0;
 845         int mp_min = 63, min_idx = 0;
 846         int mp_avg = 0, i, outlier_idx = 0, mp_count = 0;
 847 
 848         /* find min/max mismatch across all calibrated gains */
 849         for (i = 0; i < nmeasurement; i++) {
 850                 if (mp_coeff[i][0] > mp_max) {
 851                         mp_max = mp_coeff[i][0];
 852                         max_idx = i;
 853                 } else if (mp_coeff[i][0] < mp_min) {
 854                         mp_min = mp_coeff[i][0];
 855                         min_idx = i;
 856                 }
 857         }
 858 
 859         /* find average (exclude max abs value) */
 860         for (i = 0; i < nmeasurement; i++) {
 861                 if ((abs(mp_coeff[i][0]) < abs(mp_max)) ||
 862                     (abs(mp_coeff[i][0]) < abs(mp_min))) {
 863                         mp_avg += mp_coeff[i][0];
 864                         mp_count++;
 865                 }
 866         }
 867 
 868         /*
 869          * finding mean magnitude/phase if possible, otherwise
 870          * just use the last value as the mean
 871          */
 872         if (mp_count)
 873                 mp_avg /= mp_count;
 874         else
 875                 mp_avg = mp_coeff[nmeasurement - 1][0];
 876 
 877         /* detect outlier */
 878         if (abs(mp_max - mp_min) > max_delta) {
 879                 if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
 880                         outlier_idx = max_idx;
 881                 else
 882                         outlier_idx = min_idx;
 883 
 884                 mp_coeff[outlier_idx][0] = mp_avg;
 885         }
 886 }
 887 
 888 static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah,
 889                                                   struct coeff *coeff,
 890                                                   bool is_reusable)
 891 {
 892         int i, im, nmeasurement;
 893         int magnitude, phase;
 894         u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
 895         struct ath9k_hw_cal_data *caldata = ah->caldata;
 896 
 897         memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
 898         for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
 899                 tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
 900                                         AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
 901                 if (!AR_SREV_9485(ah)) {
 902                         tx_corr_coeff[i * 2][1] =
 903                         tx_corr_coeff[(i * 2) + 1][1] =
 904                                         AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
 905 
 906                         tx_corr_coeff[i * 2][2] =
 907                         tx_corr_coeff[(i * 2) + 1][2] =
 908                                         AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
 909                 }
 910         }
 911 
 912         /* Load the average of 2 passes */
 913         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
 914                 if (!(ah->txchainmask & (1 << i)))
 915                         continue;
 916                 nmeasurement = REG_READ_FIELD(ah,
 917                                 AR_PHY_TX_IQCAL_STATUS_B0,
 918                                 AR_PHY_CALIBRATED_GAINS_0);
 919 
 920                 if (nmeasurement > MAX_MEASUREMENT)
 921                         nmeasurement = MAX_MEASUREMENT;
 922 
 923                 /*
 924                  * Skip normal outlier detection for AR9550.
 925                  */
 926                 if (!AR_SREV_9550(ah)) {
 927                         /* detect outlier only if nmeasurement > 1 */
 928                         if (nmeasurement > 1) {
 929                                 /* Detect magnitude outlier */
 930                                 ar9003_hw_detect_outlier(coeff->mag_coeff[i],
 931                                                          nmeasurement,
 932                                                          MAX_MAG_DELTA);
 933 
 934                                 /* Detect phase outlier */
 935                                 ar9003_hw_detect_outlier(coeff->phs_coeff[i],
 936                                                          nmeasurement,
 937                                                          MAX_PHS_DELTA);
 938                         }
 939                 }
 940 
 941                 for (im = 0; im < nmeasurement; im++) {
 942                         magnitude = coeff->mag_coeff[i][im][0];
 943                         phase = coeff->phs_coeff[i][im][0];
 944 
 945                         coeff->iqc_coeff[0] =
 946                                 (phase & 0x7f) | ((magnitude & 0x7f) << 7);
 947 
 948                         if ((im % 2) == 0)
 949                                 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
 950                                         AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
 951                                         coeff->iqc_coeff[0]);
 952                         else
 953                                 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
 954                                         AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
 955                                         coeff->iqc_coeff[0]);
 956 
 957                         if (caldata)
 958                                 caldata->tx_corr_coeff[im][i] =
 959                                         coeff->iqc_coeff[0];
 960                 }
 961                 if (caldata)
 962                         caldata->num_measures[i] = nmeasurement;
 963         }
 964 
 965         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
 966                       AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
 967         REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
 968                       AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
 969 
 970         if (caldata) {
 971                 if (is_reusable)
 972                         set_bit(TXIQCAL_DONE, &caldata->cal_flags);
 973                 else
 974                         clear_bit(TXIQCAL_DONE, &caldata->cal_flags);
 975         }
 976 
 977         return;
 978 }
 979 
 980 static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
 981 {
 982         struct ath_common *common = ath9k_hw_common(ah);
 983         u8 tx_gain_forced;
 984 
 985         tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
 986                                         AR_PHY_TXGAIN_FORCE);
 987         if (tx_gain_forced)
 988                 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
 989                               AR_PHY_TXGAIN_FORCE, 0);
 990 
 991         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
 992                       AR_PHY_TX_IQCAL_START_DO_CAL, 1);
 993 
 994         if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
 995                         AR_PHY_TX_IQCAL_START_DO_CAL, 0,
 996                         AH_WAIT_TIMEOUT)) {
 997                 ath_dbg(common, CALIBRATE, "Tx IQ Cal is not completed\n");
 998                 return false;
 999         }
1000         return true;
1001 }
1002 
1003 static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah,
1004                                     struct coeff *coeff,
1005                                     int i, int nmeasurement)
1006 {
1007         struct ath_common *common = ath9k_hw_common(ah);
1008         int im, ix, iy, temp;
1009 
1010         for (im = 0; im < nmeasurement; im++) {
1011                 for (ix = 0; ix < MAXIQCAL - 1; ix++) {
1012                         for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) {
1013                                 if (coeff->mag_coeff[i][im][iy] <
1014                                     coeff->mag_coeff[i][im][ix]) {
1015                                         temp = coeff->mag_coeff[i][im][ix];
1016                                         coeff->mag_coeff[i][im][ix] =
1017                                                 coeff->mag_coeff[i][im][iy];
1018                                         coeff->mag_coeff[i][im][iy] = temp;
1019                                 }
1020                                 if (coeff->phs_coeff[i][im][iy] <
1021                                     coeff->phs_coeff[i][im][ix]) {
1022                                         temp = coeff->phs_coeff[i][im][ix];
1023                                         coeff->phs_coeff[i][im][ix] =
1024                                                 coeff->phs_coeff[i][im][iy];
1025                                         coeff->phs_coeff[i][im][iy] = temp;
1026                                 }
1027                         }
1028                 }
1029                 coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2];
1030                 coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2];
1031 
1032                 ath_dbg(common, CALIBRATE,
1033                         "IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n",
1034                         i, im,
1035                         coeff->mag_coeff[i][im][0],
1036                         coeff->phs_coeff[i][im][0]);
1037         }
1038 }
1039 
1040 static bool ar955x_tx_iq_cal_median(struct ath_hw *ah,
1041                                     struct coeff *coeff,
1042                                     int iqcal_idx,
1043                                     int nmeasurement)
1044 {
1045         int i;
1046 
1047         if ((iqcal_idx + 1) != MAXIQCAL)
1048                 return false;
1049 
1050         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1051                 __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement);
1052         }
1053 
1054         return true;
1055 }
1056 
1057 static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah,
1058                                           int iqcal_idx,
1059                                           bool is_reusable)
1060 {
1061         struct ath_common *common = ath9k_hw_common(ah);
1062         const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
1063                 AR_PHY_TX_IQCAL_STATUS_B0,
1064                 AR_PHY_TX_IQCAL_STATUS_B1,
1065                 AR_PHY_TX_IQCAL_STATUS_B2,
1066         };
1067         const u_int32_t chan_info_tab[] = {
1068                 AR_PHY_CHAN_INFO_TAB_0,
1069                 AR_PHY_CHAN_INFO_TAB_1,
1070                 AR_PHY_CHAN_INFO_TAB_2,
1071         };
1072         static struct coeff coeff;
1073         s32 iq_res[6];
1074         int i, im, j;
1075         int nmeasurement = 0;
1076         bool outlier_detect = true;
1077 
1078         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1079                 if (!(ah->txchainmask & (1 << i)))
1080                         continue;
1081 
1082                 nmeasurement = REG_READ_FIELD(ah,
1083                                 AR_PHY_TX_IQCAL_STATUS_B0,
1084                                 AR_PHY_CALIBRATED_GAINS_0);
1085                 if (nmeasurement > MAX_MEASUREMENT)
1086                         nmeasurement = MAX_MEASUREMENT;
1087 
1088                 for (im = 0; im < nmeasurement; im++) {
1089                         ath_dbg(common, CALIBRATE,
1090                                 "Doing Tx IQ Cal for chain %d\n", i);
1091 
1092                         if (REG_READ(ah, txiqcal_status[i]) &
1093                                         AR_PHY_TX_IQCAL_STATUS_FAILED) {
1094                                 ath_dbg(common, CALIBRATE,
1095                                         "Tx IQ Cal failed for chain %d\n", i);
1096                                 goto tx_iqcal_fail;
1097                         }
1098 
1099                         for (j = 0; j < 3; j++) {
1100                                 u32 idx = 2 * j, offset = 4 * (3 * im + j);
1101 
1102                                 REG_RMW_FIELD(ah,
1103                                                 AR_PHY_CHAN_INFO_MEMORY,
1104                                                 AR_PHY_CHAN_INFO_TAB_S2_READ,
1105                                                 0);
1106 
1107                                 /* 32 bits */
1108                                 iq_res[idx] = REG_READ(ah,
1109                                                 chan_info_tab[i] +
1110                                                 offset);
1111 
1112                                 REG_RMW_FIELD(ah,
1113                                                 AR_PHY_CHAN_INFO_MEMORY,
1114                                                 AR_PHY_CHAN_INFO_TAB_S2_READ,
1115                                                 1);
1116 
1117                                 /* 16 bits */
1118                                 iq_res[idx + 1] = 0xffff & REG_READ(ah,
1119                                                 chan_info_tab[i] + offset);
1120 
1121                                 ath_dbg(common, CALIBRATE,
1122                                         "IQ_RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
1123                                         idx, iq_res[idx], idx + 1,
1124                                         iq_res[idx + 1]);
1125                         }
1126 
1127                         if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
1128                                                 coeff.iqc_coeff)) {
1129                                 ath_dbg(common, CALIBRATE,
1130                                         "Failed in calculation of IQ correction\n");
1131                                 goto tx_iqcal_fail;
1132                         }
1133 
1134                         coeff.phs_coeff[i][im][iqcal_idx] =
1135                                 coeff.iqc_coeff[0] & 0x7f;
1136                         coeff.mag_coeff[i][im][iqcal_idx] =
1137                                 (coeff.iqc_coeff[0] >> 7) & 0x7f;
1138 
1139                         if (coeff.mag_coeff[i][im][iqcal_idx] > 63)
1140                                 coeff.mag_coeff[i][im][iqcal_idx] -= 128;
1141                         if (coeff.phs_coeff[i][im][iqcal_idx] > 63)
1142                                 coeff.phs_coeff[i][im][iqcal_idx] -= 128;
1143                 }
1144         }
1145 
1146         if (AR_SREV_9550(ah))
1147                 outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff,
1148                                                          iqcal_idx, nmeasurement);
1149         if (outlier_detect)
1150                 ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable);
1151 
1152         return;
1153 
1154 tx_iqcal_fail:
1155         ath_dbg(common, CALIBRATE, "Tx IQ Cal failed\n");
1156         return;
1157 }
1158 
1159 static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
1160 {
1161         struct ath9k_hw_cal_data *caldata = ah->caldata;
1162         u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
1163         int i, im;
1164 
1165         memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
1166         for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
1167                 tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
1168                                         AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
1169                 if (!AR_SREV_9485(ah)) {
1170                         tx_corr_coeff[i * 2][1] =
1171                         tx_corr_coeff[(i * 2) + 1][1] =
1172                                         AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
1173 
1174                         tx_corr_coeff[i * 2][2] =
1175                         tx_corr_coeff[(i * 2) + 1][2] =
1176                                         AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
1177                 }
1178         }
1179 
1180         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1181                 if (!(ah->txchainmask & (1 << i)))
1182                         continue;
1183 
1184                 for (im = 0; im < caldata->num_measures[i]; im++) {
1185                         if ((im % 2) == 0)
1186                                 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
1187                                      AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
1188                                      caldata->tx_corr_coeff[im][i]);
1189                         else
1190                                 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
1191                                      AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
1192                                      caldata->tx_corr_coeff[im][i]);
1193                 }
1194         }
1195 
1196         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
1197                       AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
1198         REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
1199                       AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
1200 }
1201 
1202 static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
1203 {
1204         int offset[8] = {0}, total = 0, test;
1205         int agc_out, i, peak_detect_threshold = 0;
1206 
1207         if (AR_SREV_9550(ah) || AR_SREV_9531(ah))
1208                 peak_detect_threshold = 8;
1209         else if (AR_SREV_9561(ah))
1210                 peak_detect_threshold = 11;
1211 
1212         /*
1213          * Turn off LNA/SW.
1214          */
1215         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1216                       AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1);
1217         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1218                       AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0);
1219 
1220         if (AR_SREV_9003_PCOEM(ah) || AR_SREV_9330_11(ah)) {
1221                 if (is_2g)
1222                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1223                                       AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
1224                 else
1225                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1226                                       AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
1227         }
1228 
1229         /*
1230          * Turn off RXON.
1231          */
1232         REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1233                       AR_PHY_65NM_RXTX2_RXON_OVR, 0x1);
1234         REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1235                       AR_PHY_65NM_RXTX2_RXON, 0x0);
1236 
1237         /*
1238          * Turn on AGC for cal.
1239          */
1240         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1241                       AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
1242         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1243                       AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1);
1244         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1245                       AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
1246 
1247         if (AR_SREV_9330_11(ah))
1248                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1249                               AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0);
1250 
1251         if (is_2g)
1252                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1253                               AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR,
1254                               peak_detect_threshold);
1255         else
1256                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1257                               AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR,
1258                               peak_detect_threshold);
1259 
1260         for (i = 6; i > 0; i--) {
1261                 offset[i] = BIT(i - 1);
1262                 test = total + offset[i];
1263 
1264                 if (is_2g)
1265                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1266                                       AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
1267                                       test);
1268                 else
1269                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1270                                       AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
1271                                       test);
1272                 udelay(100);
1273                 agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1274                                          AR_PHY_65NM_RXRF_AGC_AGC_OUT);
1275                 offset[i] = (agc_out) ? 0 : 1;
1276                 total += (offset[i] << (i - 1));
1277         }
1278 
1279         if (is_2g)
1280                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1281                               AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total);
1282         else
1283                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1284                               AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total);
1285 
1286         /*
1287          * Turn on LNA.
1288          */
1289         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1290                       AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0);
1291         /*
1292          * Turn off RXON.
1293          */
1294         REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1295                       AR_PHY_65NM_RXTX2_RXON_OVR, 0);
1296         /*
1297          * Turn off peak detect calibration.
1298          */
1299         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1300                       AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
1301 }
1302 
1303 static void ar9003_hw_do_pcoem_manual_peak_cal(struct ath_hw *ah,
1304                                                struct ath9k_channel *chan,
1305                                                bool run_rtt_cal)
1306 {
1307         struct ath9k_hw_cal_data *caldata = ah->caldata;
1308         int i;
1309 
1310         if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal)
1311                 return;
1312 
1313         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1314                 if (!(ah->rxchainmask & (1 << i)))
1315                         continue;
1316                 ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan));
1317         }
1318 
1319         if (caldata)
1320                 set_bit(SW_PKDET_DONE, &caldata->cal_flags);
1321 
1322         if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) {
1323                 if (IS_CHAN_2GHZ(chan)){
1324                         caldata->caldac[0] = REG_READ_FIELD(ah,
1325                                                     AR_PHY_65NM_RXRF_AGC(0),
1326                                                     AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
1327                         caldata->caldac[1] = REG_READ_FIELD(ah,
1328                                                     AR_PHY_65NM_RXRF_AGC(1),
1329                                                     AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
1330                 } else {
1331                         caldata->caldac[0] = REG_READ_FIELD(ah,
1332                                                     AR_PHY_65NM_RXRF_AGC(0),
1333                                                     AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
1334                         caldata->caldac[1] = REG_READ_FIELD(ah,
1335                                                     AR_PHY_65NM_RXRF_AGC(1),
1336                                                     AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
1337                 }
1338         }
1339 }
1340 
1341 static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
1342 {
1343         u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
1344                                           AR_PHY_CL_TAB_1,
1345                                           AR_PHY_CL_TAB_2 };
1346         struct ath9k_hw_cal_data *caldata = ah->caldata;
1347         bool txclcal_done = false;
1348         int i, j;
1349 
1350         if (!caldata || !(ah->enabled_cals & TX_CL_CAL))
1351                 return;
1352 
1353         txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
1354                           AR_PHY_AGC_CONTROL_CLC_SUCCESS);
1355 
1356         if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) {
1357                 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1358                         if (!(ah->txchainmask & (1 << i)))
1359                                 continue;
1360                         for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1361                                 REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
1362                                           caldata->tx_clcal[i][j]);
1363                 }
1364         } else if (is_reusable && txclcal_done) {
1365                 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1366                         if (!(ah->txchainmask & (1 << i)))
1367                                 continue;
1368                         for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1369                                 caldata->tx_clcal[i][j] =
1370                                         REG_READ(ah, CL_TAB_ENTRY(cl_idx[i]));
1371                 }
1372                 set_bit(TXCLCAL_DONE, &caldata->cal_flags);
1373         }
1374 }
1375 
1376 static void ar9003_hw_init_cal_common(struct ath_hw *ah)
1377 {
1378         struct ath9k_hw_cal_data *caldata = ah->caldata;
1379 
1380         /* Initialize list pointers */
1381         ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1382 
1383         INIT_CAL(&ah->iq_caldata);
1384         INSERT_CAL(ah, &ah->iq_caldata);
1385 
1386         /* Initialize current pointer to first element in list */
1387         ah->cal_list_curr = ah->cal_list;
1388 
1389         if (ah->cal_list_curr)
1390                 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1391 
1392         if (caldata)
1393                 caldata->CalValid = 0;
1394 }
1395 
1396 static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
1397                                      struct ath9k_channel *chan)
1398 {
1399         struct ath_common *common = ath9k_hw_common(ah);
1400         struct ath9k_hw_cal_data *caldata = ah->caldata;
1401         bool txiqcal_done = false;
1402         bool is_reusable = true, status = true;
1403         bool run_rtt_cal = false, run_agc_cal;
1404         bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
1405         u32 rx_delay = 0;
1406         u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
1407                                           AR_PHY_AGC_CONTROL_FLTR_CAL   |
1408                                           AR_PHY_AGC_CONTROL_PKDET_CAL;
1409 
1410         /* Use chip chainmask only for calibration */
1411         ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1412 
1413         if (rtt) {
1414                 if (!ar9003_hw_rtt_restore(ah, chan))
1415                         run_rtt_cal = true;
1416 
1417                 if (run_rtt_cal)
1418                         ath_dbg(common, CALIBRATE, "RTT calibration to be done\n");
1419         }
1420 
1421         run_agc_cal = run_rtt_cal;
1422 
1423         if (run_rtt_cal) {
1424                 ar9003_hw_rtt_enable(ah);
1425                 ar9003_hw_rtt_set_mask(ah, 0x00);
1426                 ar9003_hw_rtt_clear_hist(ah);
1427         }
1428 
1429         if (rtt) {
1430                 if (!run_rtt_cal) {
1431                         agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL);
1432                         agc_supp_cals &= agc_ctrl;
1433                         agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL |
1434                                       AR_PHY_AGC_CONTROL_FLTR_CAL |
1435                                       AR_PHY_AGC_CONTROL_PKDET_CAL);
1436                         REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1437                 } else {
1438                         if (ah->ah_flags & AH_FASTCC)
1439                                 run_agc_cal = true;
1440                 }
1441         }
1442 
1443         if (ah->enabled_cals & TX_CL_CAL) {
1444                 if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags))
1445                         REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
1446                                     AR_PHY_CL_CAL_ENABLE);
1447                 else {
1448                         REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL,
1449                                     AR_PHY_CL_CAL_ENABLE);
1450                         run_agc_cal = true;
1451                 }
1452         }
1453 
1454         if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ||
1455             !(ah->enabled_cals & TX_IQ_CAL))
1456                 goto skip_tx_iqcal;
1457 
1458         /* Do Tx IQ Calibration */
1459         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
1460                       AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
1461                       DELPT);
1462 
1463         /*
1464          * For AR9485 or later chips, TxIQ cal runs as part of
1465          * AGC calibration
1466          */
1467         if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
1468                 if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags))
1469                         REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1470                                     AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1471                 else
1472                         REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1473                                     AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1474                 txiqcal_done = run_agc_cal = true;
1475         }
1476 
1477 skip_tx_iqcal:
1478         if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1479                 ar9003_mci_init_cal_req(ah, &is_reusable);
1480 
1481         if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1482                 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
1483                 /* Disable BB_active */
1484                 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1485                 udelay(5);
1486                 REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY);
1487                 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1488         }
1489 
1490         if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1491                 /* Calibrate the AGC */
1492                 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1493                           REG_READ(ah, AR_PHY_AGC_CONTROL) |
1494                           AR_PHY_AGC_CONTROL_CAL);
1495 
1496                 /* Poll for offset calibration complete */
1497                 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1498                                        AR_PHY_AGC_CONTROL_CAL,
1499                                        0, AH_WAIT_TIMEOUT);
1500 
1501                 ar9003_hw_do_pcoem_manual_peak_cal(ah, chan, run_rtt_cal);
1502         }
1503 
1504         if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1505                 REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay);
1506                 udelay(5);
1507         }
1508 
1509         if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1510                 ar9003_mci_init_cal_done(ah);
1511 
1512         if (rtt && !run_rtt_cal) {
1513                 agc_ctrl |= agc_supp_cals;
1514                 REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1515         }
1516 
1517         if (!status) {
1518                 if (run_rtt_cal)
1519                         ar9003_hw_rtt_disable(ah);
1520 
1521                 ath_dbg(common, CALIBRATE,
1522                         "offset calibration failed to complete in %d ms; noisy environment?\n",
1523                         AH_WAIT_TIMEOUT / 1000);
1524                 return false;
1525         }
1526 
1527         if (txiqcal_done)
1528                 ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable);
1529         else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags))
1530                 ar9003_hw_tx_iq_cal_reload(ah);
1531 
1532         ar9003_hw_cl_cal_post_proc(ah, is_reusable);
1533 
1534         if (run_rtt_cal && caldata) {
1535                 if (is_reusable) {
1536                         if (!ath9k_hw_rfbus_req(ah)) {
1537                                 ath_err(ath9k_hw_common(ah),
1538                                         "Could not stop baseband\n");
1539                         } else {
1540                                 ar9003_hw_rtt_fill_hist(ah);
1541 
1542                                 if (test_bit(SW_PKDET_DONE, &caldata->cal_flags))
1543                                         ar9003_hw_rtt_load_hist(ah);
1544                         }
1545 
1546                         ath9k_hw_rfbus_done(ah);
1547                 }
1548 
1549                 ar9003_hw_rtt_disable(ah);
1550         }
1551 
1552         /* Revert chainmask to runtime parameters */
1553         ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1554 
1555         ar9003_hw_init_cal_common(ah);
1556 
1557         return true;
1558 }
1559 
1560 static bool do_ar9003_agc_cal(struct ath_hw *ah)
1561 {
1562         struct ath_common *common = ath9k_hw_common(ah);
1563         bool status;
1564 
1565         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1566                   REG_READ(ah, AR_PHY_AGC_CONTROL) |
1567                   AR_PHY_AGC_CONTROL_CAL);
1568 
1569         status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1570                                AR_PHY_AGC_CONTROL_CAL,
1571                                0, AH_WAIT_TIMEOUT);
1572         if (!status) {
1573                 ath_dbg(common, CALIBRATE,
1574                         "offset calibration failed to complete in %d ms,"
1575                         "noisy environment?\n",
1576                         AH_WAIT_TIMEOUT / 1000);
1577                 return false;
1578         }
1579 
1580         return true;
1581 }
1582 
1583 static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
1584                                    struct ath9k_channel *chan)
1585 {
1586         bool txiqcal_done = false;
1587         bool status = true;
1588         bool run_agc_cal = false, sep_iq_cal = false;
1589         int i = 0;
1590 
1591         /* Use chip chainmask only for calibration */
1592         ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1593 
1594         if (ah->enabled_cals & TX_CL_CAL) {
1595                 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1596                 run_agc_cal = true;
1597         }
1598 
1599         if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
1600                 goto skip_tx_iqcal;
1601 
1602         /* Do Tx IQ Calibration */
1603         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
1604                       AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
1605                       DELPT);
1606 
1607         /*
1608          * For AR9485 or later chips, TxIQ cal runs as part of
1609          * AGC calibration. Specifically, AR9550 in SoC chips.
1610          */
1611         if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
1612                 if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1613                                    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) {
1614                                 txiqcal_done = true;
1615                 } else {
1616                         txiqcal_done = false;
1617                 }
1618                 run_agc_cal = true;
1619         } else {
1620                 sep_iq_cal = true;
1621                 run_agc_cal = true;
1622         }
1623 
1624         /*
1625          * In the SoC family, this will run for AR9300, AR9331 and AR9340.
1626          */
1627         if (sep_iq_cal) {
1628                 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
1629                 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1630                 udelay(5);
1631                 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1632         }
1633 
1634         if (AR_SREV_9550(ah) && IS_CHAN_2GHZ(chan)) {
1635                 if (!ar9003_hw_dynamic_osdac_selection(ah, txiqcal_done))
1636                         return false;
1637         }
1638 
1639 skip_tx_iqcal:
1640         if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1641                 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1642                         if (!(ah->rxchainmask & (1 << i)))
1643                                 continue;
1644 
1645                         ar9003_hw_manual_peak_cal(ah, i,
1646                                                   IS_CHAN_2GHZ(chan));
1647                 }
1648 
1649                 /*
1650                  * For non-AR9550 chips, we just trigger AGC calibration
1651                  * in the HW, poll for completion and then process
1652                  * the results.
1653                  *
1654                  * For AR955x, we run it multiple times and use
1655                  * median IQ correction.
1656                  */
1657                 if (!AR_SREV_9550(ah)) {
1658                         status = do_ar9003_agc_cal(ah);
1659                         if (!status)
1660                                 return false;
1661 
1662                         if (txiqcal_done)
1663                                 ar9003_hw_tx_iq_cal_post_proc(ah, 0, false);
1664                 } else {
1665                         if (!txiqcal_done) {
1666                                 status = do_ar9003_agc_cal(ah);
1667                                 if (!status)
1668                                         return false;
1669                         } else {
1670                                 for (i = 0; i < MAXIQCAL; i++) {
1671                                         status = do_ar9003_agc_cal(ah);
1672                                         if (!status)
1673                                                 return false;
1674                                         ar9003_hw_tx_iq_cal_post_proc(ah, i, false);
1675                                 }
1676                         }
1677                 }
1678         }
1679 
1680         /* Revert chainmask to runtime parameters */
1681         ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1682 
1683         ar9003_hw_init_cal_common(ah);
1684 
1685         return true;
1686 }
1687 
1688 void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
1689 {
1690         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1691         struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1692 
1693         if (AR_SREV_9003_PCOEM(ah))
1694                 priv_ops->init_cal = ar9003_hw_init_cal_pcoem;
1695         else
1696                 priv_ops->init_cal = ar9003_hw_init_cal_soc;
1697 
1698         priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
1699         priv_ops->setup_calibration = ar9003_hw_setup_calibration;
1700 
1701         ops->calibrate = ar9003_hw_calibrate;
1702 }

/* [<][>][^][v][top][bottom][index][help] */