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