]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/ath/ath9k/ar9003_calib.c
Merge remote-tracking branch 'net-next/master'
[karo-tx-linux.git] / drivers / net / wireless / ath / ath9k / ar9003_calib.c
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 /*
330  * solve 4x4 linear equation used in loopback iq cal.
331  */
332 static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
333                                    s32 sin_2phi_1,
334                                    s32 cos_2phi_1,
335                                    s32 sin_2phi_2,
336                                    s32 cos_2phi_2,
337                                    s32 mag_a0_d0,
338                                    s32 phs_a0_d0,
339                                    s32 mag_a1_d0,
340                                    s32 phs_a1_d0,
341                                    s32 solved_eq[])
342 {
343         s32 f1 = cos_2phi_1 - cos_2phi_2,
344             f3 = sin_2phi_1 - sin_2phi_2,
345             f2;
346         s32 mag_tx, phs_tx, mag_rx, phs_rx;
347         const s32 result_shift = 1 << 15;
348         struct ath_common *common = ath9k_hw_common(ah);
349
350         f2 = (f1 * f1 + f3 * f3) / result_shift;
351
352         if (!f2) {
353                 ath_dbg(common, CALIBRATE, "Divide by 0\n");
354                 return false;
355         }
356
357         /* mag mismatch, tx */
358         mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
359         /* phs mismatch, tx */
360         phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
361
362         mag_tx = (mag_tx / f2);
363         phs_tx = (phs_tx / f2);
364
365         /* mag mismatch, rx */
366         mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
367                  result_shift;
368         /* phs mismatch, rx */
369         phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
370                  result_shift;
371
372         solved_eq[0] = mag_tx;
373         solved_eq[1] = phs_tx;
374         solved_eq[2] = mag_rx;
375         solved_eq[3] = phs_rx;
376
377         return true;
378 }
379
380 static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im)
381 {
382         s32 abs_i = abs(in_re),
383             abs_q = abs(in_im),
384             max_abs, min_abs;
385
386         if (abs_i > abs_q) {
387                 max_abs = abs_i;
388                 min_abs = abs_q;
389         } else {
390                 max_abs = abs_q;
391                 min_abs = abs_i;
392         }
393
394         return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
395 }
396
397 #define DELPT 32
398
399 static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
400                                    s32 chain_idx,
401                                    const s32 iq_res[],
402                                    s32 iqc_coeff[])
403 {
404         s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
405             i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
406             i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
407             i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
408         s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
409             phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
410             sin_2phi_1, cos_2phi_1,
411             sin_2phi_2, cos_2phi_2;
412         s32 mag_tx, phs_tx, mag_rx, phs_rx;
413         s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
414             q_q_coff, q_i_coff;
415         const s32 res_scale = 1 << 15;
416         const s32 delpt_shift = 1 << 8;
417         s32 mag1, mag2;
418         struct ath_common *common = ath9k_hw_common(ah);
419
420         i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
421         i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
422         iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
423
424         if (i2_m_q2_a0_d0 > 0x800)
425                 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
426
427         if (i2_p_q2_a0_d0 > 0x800)
428                 i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
429
430         if (iq_corr_a0_d0 > 0x800)
431                 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
432
433         i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
434         i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
435         iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
436
437         if (i2_m_q2_a0_d1 > 0x800)
438                 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
439
440         if (i2_p_q2_a0_d1 > 0x800)
441                 i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1);
442
443         if (iq_corr_a0_d1 > 0x800)
444                 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
445
446         i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
447         i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
448         iq_corr_a1_d0 = iq_res[4] & 0xfff;
449
450         if (i2_m_q2_a1_d0 > 0x800)
451                 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
452
453         if (i2_p_q2_a1_d0 > 0x800)
454                 i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
455
456         if (iq_corr_a1_d0 > 0x800)
457                 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
458
459         i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
460         i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
461         iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
462
463         if (i2_m_q2_a1_d1 > 0x800)
464                 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
465
466         if (i2_p_q2_a1_d1 > 0x800)
467                 i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
468
469         if (iq_corr_a1_d1 > 0x800)
470                 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
471
472         if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
473             (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
474                 ath_dbg(common, CALIBRATE,
475                         "Divide by 0:\n"
476                         "a0_d0=%d\n"
477                         "a0_d1=%d\n"
478                         "a2_d0=%d\n"
479                         "a1_d1=%d\n",
480                         i2_p_q2_a0_d0, i2_p_q2_a0_d1,
481                         i2_p_q2_a1_d0, i2_p_q2_a1_d1);
482                 return false;
483         }
484
485         mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
486         phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
487
488         mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
489         phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
490
491         mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
492         phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
493
494         mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
495         phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
496
497         /* w/o analog phase shift */
498         sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
499         /* w/o analog phase shift */
500         cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
501         /* w/  analog phase shift */
502         sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
503         /* w/  analog phase shift */
504         cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
505
506         /*
507          * force sin^2 + cos^2 = 1;
508          * find magnitude by approximation
509          */
510         mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
511         mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
512
513         if ((mag1 == 0) || (mag2 == 0)) {
514                 ath_dbg(common, CALIBRATE, "Divide by 0: mag1=%d, mag2=%d\n",
515                         mag1, mag2);
516                 return false;
517         }
518
519         /* normalization sin and cos by mag */
520         sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
521         cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
522         sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
523         cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
524
525         /* calculate IQ mismatch */
526         if (!ar9003_hw_solve_iq_cal(ah,
527                              sin_2phi_1, cos_2phi_1,
528                              sin_2phi_2, cos_2phi_2,
529                              mag_a0_d0, phs_a0_d0,
530                              mag_a1_d0,
531                              phs_a1_d0, solved_eq)) {
532                 ath_dbg(common, CALIBRATE,
533                         "Call to ar9003_hw_solve_iq_cal() failed\n");
534                 return false;
535         }
536
537         mag_tx = solved_eq[0];
538         phs_tx = solved_eq[1];
539         mag_rx = solved_eq[2];
540         phs_rx = solved_eq[3];
541
542         ath_dbg(common, CALIBRATE,
543                 "chain %d: mag mismatch=%d phase mismatch=%d\n",
544                 chain_idx, mag_tx/res_scale, phs_tx/res_scale);
545
546         if (res_scale == mag_tx) {
547                 ath_dbg(common, CALIBRATE,
548                         "Divide by 0: mag_tx=%d, res_scale=%d\n",
549                         mag_tx, res_scale);
550                 return false;
551         }
552
553         /* calculate and quantize Tx IQ correction factor */
554         mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
555         phs_corr_tx = -phs_tx;
556
557         q_q_coff = (mag_corr_tx * 128 / res_scale);
558         q_i_coff = (phs_corr_tx * 256 / res_scale);
559
560         ath_dbg(common, CALIBRATE, "tx chain %d: mag corr=%d  phase corr=%d\n",
561                 chain_idx, q_q_coff, q_i_coff);
562
563         if (q_i_coff < -63)
564                 q_i_coff = -63;
565         if (q_i_coff > 63)
566                 q_i_coff = 63;
567         if (q_q_coff < -63)
568                 q_q_coff = -63;
569         if (q_q_coff > 63)
570                 q_q_coff = 63;
571
572         iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
573
574         ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n",
575                 chain_idx, iqc_coeff[0]);
576
577         if (-mag_rx == res_scale) {
578                 ath_dbg(common, CALIBRATE,
579                         "Divide by 0: mag_rx=%d, res_scale=%d\n",
580                         mag_rx, res_scale);
581                 return false;
582         }
583
584         /* calculate and quantize Rx IQ correction factors */
585         mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
586         phs_corr_rx = -phs_rx;
587
588         q_q_coff = (mag_corr_rx * 128 / res_scale);
589         q_i_coff = (phs_corr_rx * 256 / res_scale);
590
591         ath_dbg(common, CALIBRATE, "rx chain %d: mag corr=%d  phase corr=%d\n",
592                 chain_idx, q_q_coff, q_i_coff);
593
594         if (q_i_coff < -63)
595                 q_i_coff = -63;
596         if (q_i_coff > 63)
597                 q_i_coff = 63;
598         if (q_q_coff < -63)
599                 q_q_coff = -63;
600         if (q_q_coff > 63)
601                 q_q_coff = 63;
602
603         iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
604
605         ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n",
606                 chain_idx, iqc_coeff[1]);
607
608         return true;
609 }
610
611 static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
612                                      int max_delta)
613 {
614         int mp_max = -64, max_idx = 0;
615         int mp_min = 63, min_idx = 0;
616         int mp_avg = 0, i, outlier_idx = 0, mp_count = 0;
617
618         /* find min/max mismatch across all calibrated gains */
619         for (i = 0; i < nmeasurement; i++) {
620                 if (mp_coeff[i] > mp_max) {
621                         mp_max = mp_coeff[i];
622                         max_idx = i;
623                 } else if (mp_coeff[i] < mp_min) {
624                         mp_min = mp_coeff[i];
625                         min_idx = i;
626                 }
627         }
628
629         /* find average (exclude max abs value) */
630         for (i = 0; i < nmeasurement; i++) {
631                 if ((abs(mp_coeff[i]) < abs(mp_max)) ||
632                     (abs(mp_coeff[i]) < abs(mp_min))) {
633                         mp_avg += mp_coeff[i];
634                         mp_count++;
635                 }
636         }
637
638         /*
639          * finding mean magnitude/phase if possible, otherwise
640          * just use the last value as the mean
641          */
642         if (mp_count)
643                 mp_avg /= mp_count;
644         else
645                 mp_avg = mp_coeff[nmeasurement - 1];
646
647         /* detect outlier */
648         if (abs(mp_max - mp_min) > max_delta) {
649                 if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
650                         outlier_idx = max_idx;
651                 else
652                         outlier_idx = min_idx;
653
654                 mp_coeff[outlier_idx] = mp_avg;
655         }
656 }
657
658 static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
659                                                  struct coeff *coeff,
660                                                  bool is_reusable)
661 {
662         int i, im, nmeasurement;
663         u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
664         struct ath9k_hw_cal_data *caldata = ah->caldata;
665
666         memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
667         for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
668                 tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
669                                         AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
670                 if (!AR_SREV_9485(ah)) {
671                         tx_corr_coeff[i * 2][1] =
672                         tx_corr_coeff[(i * 2) + 1][1] =
673                                         AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
674
675                         tx_corr_coeff[i * 2][2] =
676                         tx_corr_coeff[(i * 2) + 1][2] =
677                                         AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
678                 }
679         }
680
681         /* Load the average of 2 passes */
682         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
683                 if (!(ah->txchainmask & (1 << i)))
684                         continue;
685                 nmeasurement = REG_READ_FIELD(ah,
686                                 AR_PHY_TX_IQCAL_STATUS_B0,
687                                 AR_PHY_CALIBRATED_GAINS_0);
688
689                 if (nmeasurement > MAX_MEASUREMENT)
690                         nmeasurement = MAX_MEASUREMENT;
691
692                 /* detect outlier only if nmeasurement > 1 */
693                 if (nmeasurement > 1) {
694                         /* Detect magnitude outlier */
695                         ar9003_hw_detect_outlier(coeff->mag_coeff[i],
696                                         nmeasurement, MAX_MAG_DELTA);
697
698                         /* Detect phase outlier */
699                         ar9003_hw_detect_outlier(coeff->phs_coeff[i],
700                                         nmeasurement, MAX_PHS_DELTA);
701                 }
702
703                 for (im = 0; im < nmeasurement; im++) {
704
705                         coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
706                                 ((coeff->phs_coeff[i][im] & 0x7f) << 7);
707
708                         if ((im % 2) == 0)
709                                 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
710                                         AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
711                                         coeff->iqc_coeff[0]);
712                         else
713                                 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
714                                         AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
715                                         coeff->iqc_coeff[0]);
716
717                         if (caldata)
718                                 caldata->tx_corr_coeff[im][i] =
719                                         coeff->iqc_coeff[0];
720                 }
721                 if (caldata)
722                         caldata->num_measures[i] = nmeasurement;
723         }
724
725         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
726                       AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
727         REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
728                       AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
729
730         if (caldata) {
731                 if (is_reusable)
732                         set_bit(TXIQCAL_DONE, &caldata->cal_flags);
733                 else
734                         clear_bit(TXIQCAL_DONE, &caldata->cal_flags);
735         }
736
737         return;
738 }
739
740 static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
741 {
742         struct ath_common *common = ath9k_hw_common(ah);
743         u8 tx_gain_forced;
744
745         tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
746                                         AR_PHY_TXGAIN_FORCE);
747         if (tx_gain_forced)
748                 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
749                               AR_PHY_TXGAIN_FORCE, 0);
750
751         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
752                       AR_PHY_TX_IQCAL_START_DO_CAL, 1);
753
754         if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
755                         AR_PHY_TX_IQCAL_START_DO_CAL, 0,
756                         AH_WAIT_TIMEOUT)) {
757                 ath_dbg(common, CALIBRATE, "Tx IQ Cal is not completed\n");
758                 return false;
759         }
760         return true;
761 }
762
763 static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable)
764 {
765         struct ath_common *common = ath9k_hw_common(ah);
766         const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
767                 AR_PHY_TX_IQCAL_STATUS_B0,
768                 AR_PHY_TX_IQCAL_STATUS_B1,
769                 AR_PHY_TX_IQCAL_STATUS_B2,
770         };
771         const u_int32_t chan_info_tab[] = {
772                 AR_PHY_CHAN_INFO_TAB_0,
773                 AR_PHY_CHAN_INFO_TAB_1,
774                 AR_PHY_CHAN_INFO_TAB_2,
775         };
776         struct coeff coeff;
777         s32 iq_res[6];
778         int i, im, j;
779         int nmeasurement;
780
781         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
782                 if (!(ah->txchainmask & (1 << i)))
783                         continue;
784
785                 nmeasurement = REG_READ_FIELD(ah,
786                                 AR_PHY_TX_IQCAL_STATUS_B0,
787                                 AR_PHY_CALIBRATED_GAINS_0);
788                 if (nmeasurement > MAX_MEASUREMENT)
789                         nmeasurement = MAX_MEASUREMENT;
790
791                 for (im = 0; im < nmeasurement; im++) {
792                         ath_dbg(common, CALIBRATE,
793                                 "Doing Tx IQ Cal for chain %d\n", i);
794
795                         if (REG_READ(ah, txiqcal_status[i]) &
796                                         AR_PHY_TX_IQCAL_STATUS_FAILED) {
797                                 ath_dbg(common, CALIBRATE,
798                                         "Tx IQ Cal failed for chain %d\n", i);
799                                 goto tx_iqcal_fail;
800                         }
801
802                         for (j = 0; j < 3; j++) {
803                                 u32 idx = 2 * j, offset = 4 * (3 * im + j);
804
805                                 REG_RMW_FIELD(ah,
806                                                 AR_PHY_CHAN_INFO_MEMORY,
807                                                 AR_PHY_CHAN_INFO_TAB_S2_READ,
808                                                 0);
809
810                                 /* 32 bits */
811                                 iq_res[idx] = REG_READ(ah,
812                                                 chan_info_tab[i] +
813                                                 offset);
814
815                                 REG_RMW_FIELD(ah,
816                                                 AR_PHY_CHAN_INFO_MEMORY,
817                                                 AR_PHY_CHAN_INFO_TAB_S2_READ,
818                                                 1);
819
820                                 /* 16 bits */
821                                 iq_res[idx + 1] = 0xffff & REG_READ(ah,
822                                                 chan_info_tab[i] + offset);
823
824                                 ath_dbg(common, CALIBRATE,
825                                         "IQ_RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
826                                         idx, iq_res[idx], idx + 1,
827                                         iq_res[idx + 1]);
828                         }
829
830                         if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
831                                                 coeff.iqc_coeff)) {
832                                 ath_dbg(common, CALIBRATE,
833                                         "Failed in calculation of IQ correction\n");
834                                 goto tx_iqcal_fail;
835                         }
836
837                         coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
838                         coeff.phs_coeff[i][im] =
839                                 (coeff.iqc_coeff[0] >> 7) & 0x7f;
840
841                         if (coeff.mag_coeff[i][im] > 63)
842                                 coeff.mag_coeff[i][im] -= 128;
843                         if (coeff.phs_coeff[i][im] > 63)
844                                 coeff.phs_coeff[i][im] -= 128;
845                 }
846         }
847         ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable);
848
849         return;
850
851 tx_iqcal_fail:
852         ath_dbg(common, CALIBRATE, "Tx IQ Cal failed\n");
853         return;
854 }
855
856 static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
857 {
858         struct ath9k_hw_cal_data *caldata = ah->caldata;
859         u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
860         int i, im;
861
862         memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
863         for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
864                 tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
865                                         AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
866                 if (!AR_SREV_9485(ah)) {
867                         tx_corr_coeff[i * 2][1] =
868                         tx_corr_coeff[(i * 2) + 1][1] =
869                                         AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
870
871                         tx_corr_coeff[i * 2][2] =
872                         tx_corr_coeff[(i * 2) + 1][2] =
873                                         AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
874                 }
875         }
876
877         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
878                 if (!(ah->txchainmask & (1 << i)))
879                         continue;
880
881                 for (im = 0; im < caldata->num_measures[i]; im++) {
882                         if ((im % 2) == 0)
883                                 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
884                                      AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
885                                      caldata->tx_corr_coeff[im][i]);
886                         else
887                                 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
888                                      AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
889                                      caldata->tx_corr_coeff[im][i]);
890                 }
891         }
892
893         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
894                       AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
895         REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
896                       AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
897 }
898
899 static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
900 {
901         int offset[8], total = 0, test;
902         int agc_out, i;
903
904         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
905                       AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1);
906         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
907                       AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0);
908         if (is_2g)
909                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
910                               AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
911         else
912                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
913                               AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
914
915         REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
916                       AR_PHY_65NM_RXTX2_RXON_OVR, 0x1);
917         REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
918                       AR_PHY_65NM_RXTX2_RXON, 0x0);
919
920         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
921                       AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
922         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
923                       AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1);
924         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
925                       AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
926         if (is_2g)
927                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
928                               AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0);
929         else
930                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
931                               AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0);
932
933         for (i = 6; i > 0; i--) {
934                 offset[i] = BIT(i - 1);
935                 test = total + offset[i];
936
937                 if (is_2g)
938                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
939                                       AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
940                                       test);
941                 else
942                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
943                                       AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
944                                       test);
945                 udelay(100);
946                 agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
947                                          AR_PHY_65NM_RXRF_AGC_AGC_OUT);
948                 offset[i] = (agc_out) ? 0 : 1;
949                 total += (offset[i] << (i - 1));
950         }
951
952         if (is_2g)
953                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
954                               AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total);
955         else
956                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
957                               AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total);
958
959         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
960                       AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0);
961         REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
962                       AR_PHY_65NM_RXTX2_RXON_OVR, 0);
963         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
964                       AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
965 }
966
967 static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah,
968                                          struct ath9k_channel *chan,
969                                          bool run_rtt_cal)
970 {
971         struct ath9k_hw_cal_data *caldata = ah->caldata;
972         int i;
973
974         if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah))
975                 return;
976
977         if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal)
978                 return;
979
980         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
981                 if (!(ah->rxchainmask & (1 << i)))
982                         continue;
983                 ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan));
984         }
985
986         if (caldata)
987                 set_bit(SW_PKDET_DONE, &caldata->cal_flags);
988
989         if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) {
990                 if (IS_CHAN_2GHZ(chan)){
991                         caldata->caldac[0] = REG_READ_FIELD(ah,
992                                                     AR_PHY_65NM_RXRF_AGC(0),
993                                                     AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
994                         caldata->caldac[1] = REG_READ_FIELD(ah,
995                                                     AR_PHY_65NM_RXRF_AGC(1),
996                                                     AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
997                 } else {
998                         caldata->caldac[0] = REG_READ_FIELD(ah,
999                                                     AR_PHY_65NM_RXRF_AGC(0),
1000                                                     AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
1001                         caldata->caldac[1] = REG_READ_FIELD(ah,
1002                                                     AR_PHY_65NM_RXRF_AGC(1),
1003                                                     AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
1004                 }
1005         }
1006 }
1007
1008 static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
1009 {
1010         u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
1011                                           AR_PHY_CL_TAB_1,
1012                                           AR_PHY_CL_TAB_2 };
1013         struct ath9k_hw_cal_data *caldata = ah->caldata;
1014         bool txclcal_done = false;
1015         int i, j;
1016
1017         if (!caldata || !(ah->enabled_cals & TX_CL_CAL))
1018                 return;
1019
1020         txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
1021                           AR_PHY_AGC_CONTROL_CLC_SUCCESS);
1022
1023         if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) {
1024                 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1025                         if (!(ah->txchainmask & (1 << i)))
1026                                 continue;
1027                         for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1028                                 REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
1029                                           caldata->tx_clcal[i][j]);
1030                 }
1031         } else if (is_reusable && txclcal_done) {
1032                 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1033                         if (!(ah->txchainmask & (1 << i)))
1034                                 continue;
1035                         for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1036                                 caldata->tx_clcal[i][j] =
1037                                         REG_READ(ah, CL_TAB_ENTRY(cl_idx[i]));
1038                 }
1039                 set_bit(TXCLCAL_DONE, &caldata->cal_flags);
1040         }
1041 }
1042
1043 static bool ar9003_hw_init_cal(struct ath_hw *ah,
1044                                struct ath9k_channel *chan)
1045 {
1046         struct ath_common *common = ath9k_hw_common(ah);
1047         struct ath9k_hw_cal_data *caldata = ah->caldata;
1048         bool txiqcal_done = false;
1049         bool is_reusable = true, status = true;
1050         bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false;
1051         bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
1052         u32 rx_delay = 0;
1053         u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
1054                                           AR_PHY_AGC_CONTROL_FLTR_CAL   |
1055                                           AR_PHY_AGC_CONTROL_PKDET_CAL;
1056
1057         /* Use chip chainmask only for calibration */
1058         ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1059
1060         if (rtt) {
1061                 if (!ar9003_hw_rtt_restore(ah, chan))
1062                         run_rtt_cal = true;
1063
1064                 if (run_rtt_cal)
1065                         ath_dbg(common, CALIBRATE, "RTT calibration to be done\n");
1066         }
1067
1068         run_agc_cal = run_rtt_cal;
1069
1070         if (run_rtt_cal) {
1071                 ar9003_hw_rtt_enable(ah);
1072                 ar9003_hw_rtt_set_mask(ah, 0x00);
1073                 ar9003_hw_rtt_clear_hist(ah);
1074         }
1075
1076         if (rtt) {
1077                 if (!run_rtt_cal) {
1078                         agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL);
1079                         agc_supp_cals &= agc_ctrl;
1080                         agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL |
1081                                       AR_PHY_AGC_CONTROL_FLTR_CAL |
1082                                       AR_PHY_AGC_CONTROL_PKDET_CAL);
1083                         REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1084                 } else {
1085                         if (ah->ah_flags & AH_FASTCC)
1086                                 run_agc_cal = true;
1087                 }
1088         }
1089
1090         if (ah->enabled_cals & TX_CL_CAL) {
1091                 if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags))
1092                         REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
1093                                     AR_PHY_CL_CAL_ENABLE);
1094                 else {
1095                         REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL,
1096                                     AR_PHY_CL_CAL_ENABLE);
1097                         run_agc_cal = true;
1098                 }
1099         }
1100
1101         if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ||
1102             !(ah->enabled_cals & TX_IQ_CAL))
1103                 goto skip_tx_iqcal;
1104
1105         /* Do Tx IQ Calibration */
1106         REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
1107                       AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
1108                       DELPT);
1109
1110         /*
1111          * For AR9485 or later chips, TxIQ cal runs as part of
1112          * AGC calibration
1113          */
1114         if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
1115                 if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags))
1116                         REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1117                                     AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1118                 else
1119                         REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1120                                     AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1121                 txiqcal_done = run_agc_cal = true;
1122         } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) {
1123                 run_agc_cal = true;
1124                 sep_iq_cal = true;
1125         }
1126
1127 skip_tx_iqcal:
1128         if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1129                 ar9003_mci_init_cal_req(ah, &is_reusable);
1130
1131         if (sep_iq_cal) {
1132                 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
1133                 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1134                 udelay(5);
1135                 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1136         }
1137
1138         if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1139                 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
1140                 /* Disable BB_active */
1141                 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1142                 udelay(5);
1143                 REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY);
1144                 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1145         }
1146
1147         if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1148                 /* Calibrate the AGC */
1149                 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1150                           REG_READ(ah, AR_PHY_AGC_CONTROL) |
1151                           AR_PHY_AGC_CONTROL_CAL);
1152
1153                 /* Poll for offset calibration complete */
1154                 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1155                                        AR_PHY_AGC_CONTROL_CAL,
1156                                        0, AH_WAIT_TIMEOUT);
1157
1158                 ar9003_hw_do_manual_peak_cal(ah, chan, run_rtt_cal);
1159         }
1160
1161         if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1162                 REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay);
1163                 udelay(5);
1164         }
1165
1166         if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1167                 ar9003_mci_init_cal_done(ah);
1168
1169         if (rtt && !run_rtt_cal) {
1170                 agc_ctrl |= agc_supp_cals;
1171                 REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1172         }
1173
1174         if (!status) {
1175                 if (run_rtt_cal)
1176                         ar9003_hw_rtt_disable(ah);
1177
1178                 ath_dbg(common, CALIBRATE,
1179                         "offset calibration failed to complete in %d ms; noisy environment?\n",
1180                         AH_WAIT_TIMEOUT / 1000);
1181                 return false;
1182         }
1183
1184         if (txiqcal_done)
1185                 ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
1186         else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags))
1187                 ar9003_hw_tx_iq_cal_reload(ah);
1188
1189         ar9003_hw_cl_cal_post_proc(ah, is_reusable);
1190
1191         if (run_rtt_cal && caldata) {
1192                 if (is_reusable) {
1193                         if (!ath9k_hw_rfbus_req(ah)) {
1194                                 ath_err(ath9k_hw_common(ah),
1195                                         "Could not stop baseband\n");
1196                         } else {
1197                                 ar9003_hw_rtt_fill_hist(ah);
1198
1199                                 if (test_bit(SW_PKDET_DONE, &caldata->cal_flags))
1200                                         ar9003_hw_rtt_load_hist(ah);
1201                         }
1202
1203                         ath9k_hw_rfbus_done(ah);
1204                 }
1205
1206                 ar9003_hw_rtt_disable(ah);
1207         }
1208
1209         /* Revert chainmask to runtime parameters */
1210         ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1211
1212         /* Initialize list pointers */
1213         ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1214
1215         INIT_CAL(&ah->iq_caldata);
1216         INSERT_CAL(ah, &ah->iq_caldata);
1217         ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
1218
1219         /* Initialize current pointer to first element in list */
1220         ah->cal_list_curr = ah->cal_list;
1221
1222         if (ah->cal_list_curr)
1223                 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1224
1225         if (caldata)
1226                 caldata->CalValid = 0;
1227
1228         return true;
1229 }
1230
1231 void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
1232 {
1233         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1234         struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1235
1236         priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
1237         priv_ops->init_cal = ar9003_hw_init_cal;
1238         priv_ops->setup_calibration = ar9003_hw_setup_calibration;
1239
1240         ops->calibrate = ar9003_hw_calibrate;
1241 }