]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/ath/ath9k/calib.c
36c5f89e2fc795d151726edde40ebe861b7f5f4b
[karo-tx-linux.git] / drivers / net / wireless / ath / ath9k / calib.c
1 /*
2  * Copyright (c) 2008-2009 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
19 /* We can tune this as we go by monitoring really low values */
20 #define ATH9K_NF_TOO_LOW        -60
21
22 /* AR5416 may return very high value (like -31 dBm), in those cases the nf
23  * is incorrect and we should use the static NF value. Later we can try to
24  * find out why they are reporting these values */
25
26 static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
27 {
28         if (nf > ATH9K_NF_TOO_LOW) {
29                 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
30                           "noise floor value detected (%d) is "
31                           "lower than what we think is a "
32                           "reasonable value (%d)\n",
33                           nf, ATH9K_NF_TOO_LOW);
34                 return false;
35         }
36         return true;
37 }
38
39 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
40 {
41         int16_t nfval;
42         int16_t sort[ATH9K_NF_CAL_HIST_MAX];
43         int i, j;
44
45         for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
46                 sort[i] = nfCalBuffer[i];
47
48         for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
49                 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
50                         if (sort[j] > sort[j - 1]) {
51                                 nfval = sort[j];
52                                 sort[j] = sort[j - 1];
53                                 sort[j - 1] = nfval;
54                         }
55                 }
56         }
57         nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
58
59         return nfval;
60 }
61
62 static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
63                                               int16_t *nfarray)
64 {
65         int i;
66
67         for (i = 0; i < NUM_NF_READINGS; i++) {
68                 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
69
70                 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
71                         h[i].currIndex = 0;
72
73                 if (h[i].invalidNFcount > 0) {
74                         if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
75                             nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
76                                 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
77                         } else {
78                                 h[i].invalidNFcount--;
79                                 h[i].privNF = nfarray[i];
80                         }
81                 } else {
82                         h[i].privNF =
83                                 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
84                 }
85         }
86         return;
87 }
88
89 static void ath9k_hw_do_getnf(struct ath_hw *ah,
90                               int16_t nfarray[NUM_NF_READINGS])
91 {
92         struct ath_common *common = ath9k_hw_common(ah);
93         int16_t nf;
94
95         if (AR_SREV_9280_10_OR_LATER(ah))
96                 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
97         else
98                 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
99
100         if (nf & 0x100)
101                 nf = 0 - ((nf ^ 0x1ff) + 1);
102         ath_print(common, ATH_DBG_CALIBRATE,
103                   "NF calibrated [ctl] [chain 0] is %d\n", nf);
104         nfarray[0] = nf;
105
106         if (!AR_SREV_9285(ah)) {
107                 if (AR_SREV_9280_10_OR_LATER(ah))
108                         nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
109                                         AR9280_PHY_CH1_MINCCA_PWR);
110                 else
111                         nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
112                                         AR_PHY_CH1_MINCCA_PWR);
113
114                 if (nf & 0x100)
115                         nf = 0 - ((nf ^ 0x1ff) + 1);
116                 ath_print(common, ATH_DBG_CALIBRATE,
117                           "NF calibrated [ctl] [chain 1] is %d\n", nf);
118                 nfarray[1] = nf;
119
120                 if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
121                         nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
122                                         AR_PHY_CH2_MINCCA_PWR);
123                         if (nf & 0x100)
124                                 nf = 0 - ((nf ^ 0x1ff) + 1);
125                         ath_print(common, ATH_DBG_CALIBRATE,
126                                   "NF calibrated [ctl] [chain 2] is %d\n", nf);
127                         nfarray[2] = nf;
128                 }
129         }
130
131         if (AR_SREV_9280_10_OR_LATER(ah))
132                 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
133                         AR9280_PHY_EXT_MINCCA_PWR);
134         else
135                 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
136                         AR_PHY_EXT_MINCCA_PWR);
137
138         if (nf & 0x100)
139                 nf = 0 - ((nf ^ 0x1ff) + 1);
140         ath_print(common, ATH_DBG_CALIBRATE,
141                   "NF calibrated [ext] [chain 0] is %d\n", nf);
142         nfarray[3] = nf;
143
144         if (!AR_SREV_9285(ah)) {
145                 if (AR_SREV_9280_10_OR_LATER(ah))
146                         nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
147                                         AR9280_PHY_CH1_EXT_MINCCA_PWR);
148                 else
149                         nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
150                                         AR_PHY_CH1_EXT_MINCCA_PWR);
151
152                 if (nf & 0x100)
153                         nf = 0 - ((nf ^ 0x1ff) + 1);
154                 ath_print(common, ATH_DBG_CALIBRATE,
155                           "NF calibrated [ext] [chain 1] is %d\n", nf);
156                 nfarray[4] = nf;
157
158                 if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
159                         nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
160                                         AR_PHY_CH2_EXT_MINCCA_PWR);
161                         if (nf & 0x100)
162                                 nf = 0 - ((nf ^ 0x1ff) + 1);
163                         ath_print(common, ATH_DBG_CALIBRATE,
164                                   "NF calibrated [ext] [chain 2] is %d\n", nf);
165                         nfarray[5] = nf;
166                 }
167         }
168 }
169
170 static bool getNoiseFloorThresh(struct ath_hw *ah,
171                                 enum ieee80211_band band,
172                                 int16_t *nft)
173 {
174         switch (band) {
175         case IEEE80211_BAND_5GHZ:
176                 *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
177                 break;
178         case IEEE80211_BAND_2GHZ:
179                 *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
180                 break;
181         default:
182                 BUG_ON(1);
183                 return false;
184         }
185
186         return true;
187 }
188
189 static void ath9k_hw_setup_calibration(struct ath_hw *ah,
190                                        struct ath9k_cal_list *currCal)
191 {
192         struct ath_common *common = ath9k_hw_common(ah);
193
194         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
195                       AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
196                       currCal->calData->calCountMax);
197
198         switch (currCal->calData->calType) {
199         case IQ_MISMATCH_CAL:
200                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
201                 ath_print(common, ATH_DBG_CALIBRATE,
202                           "starting IQ Mismatch Calibration\n");
203                 break;
204         case ADC_GAIN_CAL:
205                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
206                 ath_print(common, ATH_DBG_CALIBRATE,
207                           "starting ADC Gain Calibration\n");
208                 break;
209         case ADC_DC_CAL:
210                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
211                 ath_print(common, ATH_DBG_CALIBRATE,
212                           "starting ADC DC Calibration\n");
213                 break;
214         case ADC_DC_INIT_CAL:
215                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
216                 ath_print(common, ATH_DBG_CALIBRATE,
217                           "starting Init ADC DC Calibration\n");
218                 break;
219         }
220
221         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
222                     AR_PHY_TIMING_CTRL4_DO_CAL);
223 }
224
225 static void ath9k_hw_reset_calibration(struct ath_hw *ah,
226                                        struct ath9k_cal_list *currCal)
227 {
228         int i;
229
230         ath9k_hw_setup_calibration(ah, currCal);
231
232         currCal->calState = CAL_RUNNING;
233
234         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
235                 ah->meas0.sign[i] = 0;
236                 ah->meas1.sign[i] = 0;
237                 ah->meas2.sign[i] = 0;
238                 ah->meas3.sign[i] = 0;
239         }
240
241         ah->cal_samples = 0;
242 }
243
244 static bool ath9k_hw_per_calibration(struct ath_hw *ah,
245                                      struct ath9k_channel *ichan,
246                                      u8 rxchainmask,
247                                      struct ath9k_cal_list *currCal)
248 {
249         bool iscaldone = false;
250
251         if (currCal->calState == CAL_RUNNING) {
252                 if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
253                       AR_PHY_TIMING_CTRL4_DO_CAL)) {
254
255                         currCal->calData->calCollect(ah);
256                         ah->cal_samples++;
257
258                         if (ah->cal_samples >= currCal->calData->calNumSamples) {
259                                 int i, numChains = 0;
260                                 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
261                                         if (rxchainmask & (1 << i))
262                                                 numChains++;
263                                 }
264
265                                 currCal->calData->calPostProc(ah, numChains);
266                                 ichan->CalValid |= currCal->calData->calType;
267                                 currCal->calState = CAL_DONE;
268                                 iscaldone = true;
269                         } else {
270                                 ath9k_hw_setup_calibration(ah, currCal);
271                         }
272                 }
273         } else if (!(ichan->CalValid & currCal->calData->calType)) {
274                 ath9k_hw_reset_calibration(ah, currCal);
275         }
276
277         return iscaldone;
278 }
279
280 /* Assumes you are talking about the currently configured channel */
281 static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
282                                      enum ath9k_cal_types calType)
283 {
284         struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
285
286         switch (calType & ah->supp_cals) {
287         case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
288                 return true;
289         case ADC_GAIN_CAL:
290         case ADC_DC_CAL:
291                 if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
292                       conf_is_ht20(conf)))
293                         return true;
294                 break;
295         }
296         return false;
297 }
298
299 static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
300 {
301         int i;
302
303         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
304                 ah->totalPowerMeasI[i] +=
305                         REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
306                 ah->totalPowerMeasQ[i] +=
307                         REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
308                 ah->totalIqCorrMeas[i] +=
309                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
310                 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
311                           "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
312                           ah->cal_samples, i, ah->totalPowerMeasI[i],
313                           ah->totalPowerMeasQ[i],
314                           ah->totalIqCorrMeas[i]);
315         }
316 }
317
318 static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
319 {
320         int i;
321
322         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
323                 ah->totalAdcIOddPhase[i] +=
324                         REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
325                 ah->totalAdcIEvenPhase[i] +=
326                         REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
327                 ah->totalAdcQOddPhase[i] +=
328                         REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
329                 ah->totalAdcQEvenPhase[i] +=
330                         REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
331
332                 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
333                           "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
334                           "oddq=0x%08x; evenq=0x%08x;\n",
335                           ah->cal_samples, i,
336                           ah->totalAdcIOddPhase[i],
337                           ah->totalAdcIEvenPhase[i],
338                           ah->totalAdcQOddPhase[i],
339                           ah->totalAdcQEvenPhase[i]);
340         }
341 }
342
343 static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
344 {
345         int i;
346
347         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
348                 ah->totalAdcDcOffsetIOddPhase[i] +=
349                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
350                 ah->totalAdcDcOffsetIEvenPhase[i] +=
351                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
352                 ah->totalAdcDcOffsetQOddPhase[i] +=
353                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
354                 ah->totalAdcDcOffsetQEvenPhase[i] +=
355                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
356
357                 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
358                           "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
359                           "oddq=0x%08x; evenq=0x%08x;\n",
360                           ah->cal_samples, i,
361                           ah->totalAdcDcOffsetIOddPhase[i],
362                           ah->totalAdcDcOffsetIEvenPhase[i],
363                           ah->totalAdcDcOffsetQOddPhase[i],
364                           ah->totalAdcDcOffsetQEvenPhase[i]);
365         }
366 }
367
368 static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
369 {
370         struct ath_common *common = ath9k_hw_common(ah);
371         u32 powerMeasQ, powerMeasI, iqCorrMeas;
372         u32 qCoffDenom, iCoffDenom;
373         int32_t qCoff, iCoff;
374         int iqCorrNeg, i;
375
376         for (i = 0; i < numChains; i++) {
377                 powerMeasI = ah->totalPowerMeasI[i];
378                 powerMeasQ = ah->totalPowerMeasQ[i];
379                 iqCorrMeas = ah->totalIqCorrMeas[i];
380
381                 ath_print(common, ATH_DBG_CALIBRATE,
382                           "Starting IQ Cal and Correction for Chain %d\n",
383                           i);
384
385                 ath_print(common, ATH_DBG_CALIBRATE,
386                           "Orignal: Chn %diq_corr_meas = 0x%08x\n",
387                           i, ah->totalIqCorrMeas[i]);
388
389                 iqCorrNeg = 0;
390
391                 if (iqCorrMeas > 0x80000000) {
392                         iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
393                         iqCorrNeg = 1;
394                 }
395
396                 ath_print(common, ATH_DBG_CALIBRATE,
397                           "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
398                 ath_print(common, ATH_DBG_CALIBRATE,
399                           "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
400                 ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
401                           iqCorrNeg);
402
403                 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
404                 qCoffDenom = powerMeasQ / 64;
405
406                 if (powerMeasQ != 0) {
407                         iCoff = iqCorrMeas / iCoffDenom;
408                         qCoff = powerMeasI / qCoffDenom - 64;
409                         ath_print(common, ATH_DBG_CALIBRATE,
410                                   "Chn %d iCoff = 0x%08x\n", i, iCoff);
411                         ath_print(common, ATH_DBG_CALIBRATE,
412                                   "Chn %d qCoff = 0x%08x\n", i, qCoff);
413
414                         iCoff = iCoff & 0x3f;
415                         ath_print(common, ATH_DBG_CALIBRATE,
416                                   "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
417                         if (iqCorrNeg == 0x0)
418                                 iCoff = 0x40 - iCoff;
419
420                         if (qCoff > 15)
421                                 qCoff = 15;
422                         else if (qCoff <= -16)
423                                 qCoff = 16;
424
425                         ath_print(common, ATH_DBG_CALIBRATE,
426                                   "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
427                                   i, iCoff, qCoff);
428
429                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
430                                       AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
431                                       iCoff);
432                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
433                                       AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
434                                       qCoff);
435                         ath_print(common, ATH_DBG_CALIBRATE,
436                                   "IQ Cal and Correction done for Chain %d\n",
437                                   i);
438                 }
439         }
440
441         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
442                     AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
443 }
444
445 static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
446 {
447         struct ath_common *common = ath9k_hw_common(ah);
448         u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
449         u32 qGainMismatch, iGainMismatch, val, i;
450
451         for (i = 0; i < numChains; i++) {
452                 iOddMeasOffset = ah->totalAdcIOddPhase[i];
453                 iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
454                 qOddMeasOffset = ah->totalAdcQOddPhase[i];
455                 qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
456
457                 ath_print(common, ATH_DBG_CALIBRATE,
458                           "Starting ADC Gain Cal for Chain %d\n", i);
459
460                 ath_print(common, ATH_DBG_CALIBRATE,
461                           "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
462                           iOddMeasOffset);
463                 ath_print(common, ATH_DBG_CALIBRATE,
464                           "Chn %d pwr_meas_even_i = 0x%08x\n", i,
465                           iEvenMeasOffset);
466                 ath_print(common, ATH_DBG_CALIBRATE,
467                           "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
468                           qOddMeasOffset);
469                 ath_print(common, ATH_DBG_CALIBRATE,
470                           "Chn %d pwr_meas_even_q = 0x%08x\n", i,
471                           qEvenMeasOffset);
472
473                 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
474                         iGainMismatch =
475                                 ((iEvenMeasOffset * 32) /
476                                  iOddMeasOffset) & 0x3f;
477                         qGainMismatch =
478                                 ((qOddMeasOffset * 32) /
479                                  qEvenMeasOffset) & 0x3f;
480
481                         ath_print(common, ATH_DBG_CALIBRATE,
482                                   "Chn %d gain_mismatch_i = 0x%08x\n", i,
483                                   iGainMismatch);
484                         ath_print(common, ATH_DBG_CALIBRATE,
485                                   "Chn %d gain_mismatch_q = 0x%08x\n", i,
486                                   qGainMismatch);
487
488                         val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
489                         val &= 0xfffff000;
490                         val |= (qGainMismatch) | (iGainMismatch << 6);
491                         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
492
493                         ath_print(common, ATH_DBG_CALIBRATE,
494                                   "ADC Gain Cal done for Chain %d\n", i);
495                 }
496         }
497
498         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
499                   REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
500                   AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
501 }
502
503 static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
504 {
505         struct ath_common *common = ath9k_hw_common(ah);
506         u32 iOddMeasOffset, iEvenMeasOffset, val, i;
507         int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
508         const struct ath9k_percal_data *calData =
509                 ah->cal_list_curr->calData;
510         u32 numSamples =
511                 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
512
513         for (i = 0; i < numChains; i++) {
514                 iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
515                 iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
516                 qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
517                 qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
518
519                 ath_print(common, ATH_DBG_CALIBRATE,
520                            "Starting ADC DC Offset Cal for Chain %d\n", i);
521
522                 ath_print(common, ATH_DBG_CALIBRATE,
523                           "Chn %d pwr_meas_odd_i = %d\n", i,
524                           iOddMeasOffset);
525                 ath_print(common, ATH_DBG_CALIBRATE,
526                           "Chn %d pwr_meas_even_i = %d\n", i,
527                           iEvenMeasOffset);
528                 ath_print(common, ATH_DBG_CALIBRATE,
529                           "Chn %d pwr_meas_odd_q = %d\n", i,
530                           qOddMeasOffset);
531                 ath_print(common, ATH_DBG_CALIBRATE,
532                           "Chn %d pwr_meas_even_q = %d\n", i,
533                           qEvenMeasOffset);
534
535                 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
536                                numSamples) & 0x1ff;
537                 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
538                                numSamples) & 0x1ff;
539
540                 ath_print(common, ATH_DBG_CALIBRATE,
541                           "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
542                           iDcMismatch);
543                 ath_print(common, ATH_DBG_CALIBRATE,
544                           "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
545                           qDcMismatch);
546
547                 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
548                 val &= 0xc0000fff;
549                 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
550                 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
551
552                 ath_print(common, ATH_DBG_CALIBRATE,
553                           "ADC DC Offset Cal done for Chain %d\n", i);
554         }
555
556         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
557                   REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
558                   AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
559 }
560
561 /* This is done for the currently configured channel */
562 bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
563 {
564         struct ath_common *common = ath9k_hw_common(ah);
565         struct ieee80211_conf *conf = &common->hw->conf;
566         struct ath9k_cal_list *currCal = ah->cal_list_curr;
567
568         if (!ah->curchan)
569                 return true;
570
571         if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
572                 return true;
573
574         if (currCal == NULL)
575                 return true;
576
577         if (currCal->calState != CAL_DONE) {
578                 ath_print(common, ATH_DBG_CALIBRATE,
579                           "Calibration state incorrect, %d\n",
580                           currCal->calState);
581                 return true;
582         }
583
584         if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
585                 return true;
586
587         ath_print(common, ATH_DBG_CALIBRATE,
588                   "Resetting Cal %d state for channel %u\n",
589                   currCal->calData->calType, conf->channel->center_freq);
590
591         ah->curchan->CalValid &= ~currCal->calData->calType;
592         currCal->calState = CAL_WAITING;
593
594         return false;
595 }
596
597 void ath9k_hw_start_nfcal(struct ath_hw *ah)
598 {
599         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
600                     AR_PHY_AGC_CONTROL_ENABLE_NF);
601         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
602                     AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
603         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
604 }
605
606 void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
607 {
608         struct ath9k_nfcal_hist *h;
609         int i, j;
610         int32_t val;
611         const u32 ar5416_cca_regs[6] = {
612                 AR_PHY_CCA,
613                 AR_PHY_CH1_CCA,
614                 AR_PHY_CH2_CCA,
615                 AR_PHY_EXT_CCA,
616                 AR_PHY_CH1_EXT_CCA,
617                 AR_PHY_CH2_EXT_CCA
618         };
619         u8 chainmask, rx_chain_status;
620
621         rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
622         if (AR_SREV_9285(ah))
623                 chainmask = 0x9;
624         else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
625                 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
626                         chainmask = 0x1B;
627                 else
628                         chainmask = 0x09;
629         } else {
630                 if (rx_chain_status & 0x4)
631                         chainmask = 0x3F;
632                 else if (rx_chain_status & 0x2)
633                         chainmask = 0x1B;
634                 else
635                         chainmask = 0x09;
636         }
637
638         h = ah->nfCalHist;
639
640         for (i = 0; i < NUM_NF_READINGS; i++) {
641                 if (chainmask & (1 << i)) {
642                         val = REG_READ(ah, ar5416_cca_regs[i]);
643                         val &= 0xFFFFFE00;
644                         val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
645                         REG_WRITE(ah, ar5416_cca_regs[i], val);
646                 }
647         }
648
649         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
650                     AR_PHY_AGC_CONTROL_ENABLE_NF);
651         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
652                     AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
653         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
654
655         for (j = 0; j < 1000; j++) {
656                 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
657                      AR_PHY_AGC_CONTROL_NF) == 0)
658                         break;
659                 udelay(10);
660         }
661
662         for (i = 0; i < NUM_NF_READINGS; i++) {
663                 if (chainmask & (1 << i)) {
664                         val = REG_READ(ah, ar5416_cca_regs[i]);
665                         val &= 0xFFFFFE00;
666                         val |= (((u32) (-50) << 1) & 0x1ff);
667                         REG_WRITE(ah, ar5416_cca_regs[i], val);
668                 }
669         }
670 }
671
672 int16_t ath9k_hw_getnf(struct ath_hw *ah,
673                        struct ath9k_channel *chan)
674 {
675         struct ath_common *common = ath9k_hw_common(ah);
676         int16_t nf, nfThresh;
677         int16_t nfarray[NUM_NF_READINGS] = { 0 };
678         struct ath9k_nfcal_hist *h;
679         struct ieee80211_channel *c = chan->chan;
680
681         chan->channelFlags &= (~CHANNEL_CW_INT);
682         if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
683                 ath_print(common, ATH_DBG_CALIBRATE,
684                           "NF did not complete in calibration window\n");
685                 nf = 0;
686                 chan->rawNoiseFloor = nf;
687                 return chan->rawNoiseFloor;
688         } else {
689                 ath9k_hw_do_getnf(ah, nfarray);
690                 nf = nfarray[0];
691                 if (getNoiseFloorThresh(ah, c->band, &nfThresh)
692                     && nf > nfThresh) {
693                         ath_print(common, ATH_DBG_CALIBRATE,
694                                   "noise floor failed detected; "
695                                   "detected %d, threshold %d\n",
696                                   nf, nfThresh);
697                         chan->channelFlags |= CHANNEL_CW_INT;
698                 }
699         }
700
701         h = ah->nfCalHist;
702
703         ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
704         chan->rawNoiseFloor = h[0].privNF;
705
706         return chan->rawNoiseFloor;
707 }
708
709 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
710 {
711         int i, j;
712         s16 noise_floor;
713
714         if (AR_SREV_9280(ah))
715                 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
716         else if (AR_SREV_9285(ah))
717                 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
718         else if (AR_SREV_9287(ah))
719                 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
720         else
721                 noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
722
723         for (i = 0; i < NUM_NF_READINGS; i++) {
724                 ah->nfCalHist[i].currIndex = 0;
725                 ah->nfCalHist[i].privNF = noise_floor;
726                 ah->nfCalHist[i].invalidNFcount =
727                         AR_PHY_CCA_FILTERWINDOW_LENGTH;
728                 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
729                         ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
730                 }
731         }
732 }
733
734 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
735 {
736         s16 nf;
737
738         if (chan->rawNoiseFloor == 0)
739                 nf = -96;
740         else
741                 nf = chan->rawNoiseFloor;
742
743         if (!ath9k_hw_nf_in_range(ah, nf))
744                 nf = ATH_DEFAULT_NOISE_FLOOR;
745
746         return nf;
747 }
748
749 static void ath9k_olc_temp_compensation(struct ath_hw *ah)
750 {
751         u32 rddata, i;
752         int delta, currPDADC, regval, slope;
753
754         rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
755         currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
756
757
758         if (OLC_FOR_AR9287_10_LATER) {
759                 if (ah->initPDADC == 0 || currPDADC == 0) {
760                         return;
761                 } else {
762                         slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
763                         if (slope == 0)
764                                 delta = 0;
765                         else
766                                 delta = ((currPDADC - ah->initPDADC)*4) / slope;
767                         REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
768                                         AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
769                         REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
770                                         AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
771                 }
772         } else {
773                 if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
774                         delta = (currPDADC - ah->initPDADC + 4) / 8;
775                 else
776                         delta = (currPDADC - ah->initPDADC + 5) / 10;
777
778                 if (delta != ah->PDADCdelta) {
779                         ah->PDADCdelta = delta;
780                         for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
781                                 regval = ah->originalGain[i] - delta;
782                                 if (regval < 0)
783                                         regval = 0;
784
785                                 REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
786                                                 AR_PHY_TX_GAIN, regval);
787                         }
788                 }
789         }
790 }
791
792 static void ath9k_hw_9271_pa_cal(struct ath_hw *ah)
793 {
794         u32 regVal;
795         unsigned int i;
796         u32 regList [][2] = {
797                 { 0x786c, 0 },
798                 { 0x7854, 0 },
799                 { 0x7820, 0 },
800                 { 0x7824, 0 },
801                 { 0x7868, 0 },
802                 { 0x783c, 0 },
803                 { 0x7838, 0 } ,
804                 { 0x7828, 0 } ,
805         };
806
807         for (i = 0; i < ARRAY_SIZE(regList); i++)
808                 regList[i][1] = REG_READ(ah, regList[i][0]);
809
810         regVal = REG_READ(ah, 0x7834);
811         regVal &= (~(0x1));
812         REG_WRITE(ah, 0x7834, regVal);
813         regVal = REG_READ(ah, 0x9808);
814         regVal |= (0x1 << 27);
815         REG_WRITE(ah, 0x9808, regVal);
816
817         /* 786c,b23,1, pwddac=1 */
818         REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
819         /* 7854, b5,1, pdrxtxbb=1 */
820         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
821         /* 7854, b7,1, pdv2i=1 */
822         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
823         /* 7854, b8,1, pddacinterface=1 */
824         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
825         /* 7824,b12,0, offcal=0 */
826         REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
827         /* 7838, b1,0, pwddb=0 */
828         REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
829         /* 7820,b11,0, enpacal=0 */
830         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
831         /* 7820,b25,1, pdpadrv1=0 */
832         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
833         /* 7820,b24,0, pdpadrv2=0 */
834         REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0);
835         /* 7820,b23,0, pdpaout=0 */
836         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
837         /* 783c,b14-16,7, padrvgn2tab_0=7 */
838         REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
839         /*
840          * 7838,b29-31,0, padrvgn1tab_0=0
841          * does not matter since we turn it off
842          */
843         REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
844
845         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
846
847         /* Set:
848          * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
849          * txon=1,paon=1,oscon=1,synthon_force=1
850          */
851         REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
852         udelay(30);
853         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
854
855         /* find off_6_1; */
856         for (i = 6; i >= 0; i--) {
857                 regVal = REG_READ(ah, 0x7834);
858                 regVal |= (1 << (20 + i));
859                 REG_WRITE(ah, 0x7834, regVal);
860                 udelay(1);
861                 //regVal = REG_READ(ah, 0x7834);
862                 regVal &= (~(0x1 << (20 + i)));
863                 regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
864                             << (20 + i));
865                 REG_WRITE(ah, 0x7834, regVal);
866         }
867
868         /*  Empirical offset correction  */
869 #if 0
870         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0x20);
871 #endif
872
873         regVal = REG_READ(ah, 0x7834);
874         regVal |= 0x1;
875         REG_WRITE(ah, 0x7834, regVal);
876         regVal = REG_READ(ah, 0x9808);
877         regVal &= (~(0x1 << 27));
878         REG_WRITE(ah, 0x9808, regVal);
879
880         for (i = 0; i < ARRAY_SIZE(regList); i++)
881                 REG_WRITE(ah, regList[i][0], regList[i][1]);
882 }
883
884 static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
885 {
886         struct ath_common *common = ath9k_hw_common(ah);
887         u32 regVal;
888         int i, offset, offs_6_1, offs_0;
889         u32 ccomp_org, reg_field;
890         u32 regList[][2] = {
891                 { 0x786c, 0 },
892                 { 0x7854, 0 },
893                 { 0x7820, 0 },
894                 { 0x7824, 0 },
895                 { 0x7868, 0 },
896                 { 0x783c, 0 },
897                 { 0x7838, 0 },
898         };
899
900         ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
901
902         /* PA CAL is not needed for high power solution */
903         if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
904             AR5416_EEP_TXGAIN_HIGH_POWER)
905                 return;
906
907         if (AR_SREV_9285_11(ah)) {
908                 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
909                 udelay(10);
910         }
911
912         for (i = 0; i < ARRAY_SIZE(regList); i++)
913                 regList[i][1] = REG_READ(ah, regList[i][0]);
914
915         regVal = REG_READ(ah, 0x7834);
916         regVal &= (~(0x1));
917         REG_WRITE(ah, 0x7834, regVal);
918         regVal = REG_READ(ah, 0x9808);
919         regVal |= (0x1 << 27);
920         REG_WRITE(ah, 0x9808, regVal);
921
922         REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
923         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
924         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
925         REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
926         REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
927         REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
928         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
929         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
930         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
931         REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
932         REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
933         REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
934         ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
935         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
936
937         REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
938         udelay(30);
939         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
940         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
941
942         for (i = 6; i > 0; i--) {
943                 regVal = REG_READ(ah, 0x7834);
944                 regVal |= (1 << (19 + i));
945                 REG_WRITE(ah, 0x7834, regVal);
946                 udelay(1);
947                 regVal = REG_READ(ah, 0x7834);
948                 regVal &= (~(0x1 << (19 + i)));
949                 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
950                 regVal |= (reg_field << (19 + i));
951                 REG_WRITE(ah, 0x7834, regVal);
952         }
953
954         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
955         udelay(1);
956         reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
957         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
958         offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
959         offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
960
961         offset = (offs_6_1<<1) | offs_0;
962         offset = offset - 0;
963         offs_6_1 = offset>>1;
964         offs_0 = offset & 1;
965
966         if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
967                 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
968                         ah->pacal_info.max_skipcount =
969                                 2 * ah->pacal_info.max_skipcount;
970                 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
971         } else {
972                 ah->pacal_info.max_skipcount = 1;
973                 ah->pacal_info.skipcount = 0;
974                 ah->pacal_info.prev_offset = offset;
975         }
976
977         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
978         REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
979
980         regVal = REG_READ(ah, 0x7834);
981         regVal |= 0x1;
982         REG_WRITE(ah, 0x7834, regVal);
983         regVal = REG_READ(ah, 0x9808);
984         regVal &= (~(0x1 << 27));
985         REG_WRITE(ah, 0x9808, regVal);
986
987         for (i = 0; i < ARRAY_SIZE(regList); i++)
988                 REG_WRITE(ah, regList[i][0], regList[i][1]);
989
990         REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
991
992         if (AR_SREV_9285_11(ah))
993                 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
994
995 }
996
997 bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
998                         u8 rxchainmask, bool longcal)
999 {
1000         bool iscaldone = true;
1001         struct ath9k_cal_list *currCal = ah->cal_list_curr;
1002
1003         if (currCal &&
1004             (currCal->calState == CAL_RUNNING ||
1005              currCal->calState == CAL_WAITING)) {
1006                 iscaldone = ath9k_hw_per_calibration(ah, chan,
1007                                                      rxchainmask, currCal);
1008                 if (iscaldone) {
1009                         ah->cal_list_curr = currCal = currCal->calNext;
1010
1011                         if (currCal->calState == CAL_WAITING) {
1012                                 iscaldone = false;
1013                                 ath9k_hw_reset_calibration(ah, currCal);
1014                         }
1015                 }
1016         }
1017
1018         /* Do NF cal only at longer intervals */
1019         if (longcal) {
1020                 /* Do periodic PAOffset Cal */
1021                 if (AR_SREV_9271(ah))
1022                         ath9k_hw_9271_pa_cal(ah);
1023                 else if (AR_SREV_9285_11_OR_LATER(ah)) {
1024                         if (!ah->pacal_info.skipcount)
1025                                 ath9k_hw_9285_pa_cal(ah, false);
1026                         else
1027                                 ah->pacal_info.skipcount--;
1028                 }
1029
1030                 if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
1031                         ath9k_olc_temp_compensation(ah);
1032
1033                 /* Get the value from the previous NF cal and update history buffer */
1034                 ath9k_hw_getnf(ah, chan);
1035
1036                 /*
1037                  * Load the NF from history buffer of the current channel.
1038                  * NF is slow time-variant, so it is OK to use a historical value.
1039                  */
1040                 ath9k_hw_loadnf(ah, ah->curchan);
1041
1042                 ath9k_hw_start_nfcal(ah);
1043         }
1044
1045         return iscaldone;
1046 }
1047
1048 static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
1049 {
1050         struct ath_common *common = ath9k_hw_common(ah);
1051
1052         REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1053         if (IS_CHAN_HT20(chan)) {
1054                 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
1055                 REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
1056                 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1057                             AR_PHY_AGC_CONTROL_FLTR_CAL);
1058                 REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
1059                 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
1060                 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1061                                   AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
1062                         ath_print(common, ATH_DBG_CALIBRATE, "offset "
1063                                   "calibration failed to complete in "
1064                                   "1ms; noisy ??\n");
1065                         return false;
1066                 }
1067                 REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
1068                 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
1069                 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1070         }
1071         REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
1072         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
1073         REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
1074         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
1075         if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
1076                           0, AH_WAIT_TIMEOUT)) {
1077                 ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
1078                           "failed to complete in 1ms; noisy ??\n");
1079                 return false;
1080         }
1081
1082         REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
1083         REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1084         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
1085
1086         return true;
1087 }
1088
1089 bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
1090 {
1091         struct ath_common *common = ath9k_hw_common(ah);
1092
1093         if (AR_SREV_9285_12_OR_LATER(ah)) {
1094                 if (!ar9285_clc(ah, chan))
1095                         return false;
1096         } else {
1097                 if (AR_SREV_9280_10_OR_LATER(ah)) {
1098                         if (!AR_SREV_9287_10_OR_LATER(ah))
1099                                 REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
1100                                             AR_PHY_ADC_CTL_OFF_PWDADC);
1101                         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1102                                     AR_PHY_AGC_CONTROL_FLTR_CAL);
1103                 }
1104
1105                 /* Calibrate the AGC */
1106                 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1107                           REG_READ(ah, AR_PHY_AGC_CONTROL) |
1108                           AR_PHY_AGC_CONTROL_CAL);
1109
1110                 /* Poll for offset calibration complete */
1111                 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
1112                                    0, AH_WAIT_TIMEOUT)) {
1113                         ath_print(common, ATH_DBG_CALIBRATE,
1114                                   "offset calibration failed to "
1115                                   "complete in 1ms; noisy environment?\n");
1116                         return false;
1117                 }
1118
1119                 if (AR_SREV_9280_10_OR_LATER(ah)) {
1120                         if (!AR_SREV_9287_10_OR_LATER(ah))
1121                                 REG_SET_BIT(ah, AR_PHY_ADC_CTL,
1122                                             AR_PHY_ADC_CTL_OFF_PWDADC);
1123                         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1124                                     AR_PHY_AGC_CONTROL_FLTR_CAL);
1125                 }
1126         }
1127
1128         /* Do PA Calibration */
1129         if (AR_SREV_9285_11_OR_LATER(ah))
1130                 ath9k_hw_9285_pa_cal(ah, true);
1131
1132         /* Do NF Calibration after DC offset and other calibrations */
1133         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1134                   REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
1135
1136         ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1137
1138         /* Enable IQ, ADC Gain and ADC DC offset CALs */
1139         if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
1140                 if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
1141                         INIT_CAL(&ah->adcgain_caldata);
1142                         INSERT_CAL(ah, &ah->adcgain_caldata);
1143                         ath_print(common, ATH_DBG_CALIBRATE,
1144                                   "enabling ADC Gain Calibration.\n");
1145                 }
1146                 if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
1147                         INIT_CAL(&ah->adcdc_caldata);
1148                         INSERT_CAL(ah, &ah->adcdc_caldata);
1149                         ath_print(common, ATH_DBG_CALIBRATE,
1150                                   "enabling ADC DC Calibration.\n");
1151                 }
1152                 if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
1153                         INIT_CAL(&ah->iq_caldata);
1154                         INSERT_CAL(ah, &ah->iq_caldata);
1155                         ath_print(common, ATH_DBG_CALIBRATE,
1156                                   "enabling IQ Calibration.\n");
1157                 }
1158
1159                 ah->cal_list_curr = ah->cal_list;
1160
1161                 if (ah->cal_list_curr)
1162                         ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1163         }
1164
1165         chan->CalValid = 0;
1166
1167         return true;
1168 }
1169
1170 const struct ath9k_percal_data iq_cal_multi_sample = {
1171         IQ_MISMATCH_CAL,
1172         MAX_CAL_SAMPLES,
1173         PER_MIN_LOG_COUNT,
1174         ath9k_hw_iqcal_collect,
1175         ath9k_hw_iqcalibrate
1176 };
1177 const struct ath9k_percal_data iq_cal_single_sample = {
1178         IQ_MISMATCH_CAL,
1179         MIN_CAL_SAMPLES,
1180         PER_MAX_LOG_COUNT,
1181         ath9k_hw_iqcal_collect,
1182         ath9k_hw_iqcalibrate
1183 };
1184 const struct ath9k_percal_data adc_gain_cal_multi_sample = {
1185         ADC_GAIN_CAL,
1186         MAX_CAL_SAMPLES,
1187         PER_MIN_LOG_COUNT,
1188         ath9k_hw_adc_gaincal_collect,
1189         ath9k_hw_adc_gaincal_calibrate
1190 };
1191 const struct ath9k_percal_data adc_gain_cal_single_sample = {
1192         ADC_GAIN_CAL,
1193         MIN_CAL_SAMPLES,
1194         PER_MAX_LOG_COUNT,
1195         ath9k_hw_adc_gaincal_collect,
1196         ath9k_hw_adc_gaincal_calibrate
1197 };
1198 const struct ath9k_percal_data adc_dc_cal_multi_sample = {
1199         ADC_DC_CAL,
1200         MAX_CAL_SAMPLES,
1201         PER_MIN_LOG_COUNT,
1202         ath9k_hw_adc_dccal_collect,
1203         ath9k_hw_adc_dccal_calibrate
1204 };
1205 const struct ath9k_percal_data adc_dc_cal_single_sample = {
1206         ADC_DC_CAL,
1207         MIN_CAL_SAMPLES,
1208         PER_MAX_LOG_COUNT,
1209         ath9k_hw_adc_dccal_collect,
1210         ath9k_hw_adc_dccal_calibrate
1211 };
1212 const struct ath9k_percal_data adc_init_dc_cal = {
1213         ADC_DC_INIT_CAL,
1214         MIN_CAL_SAMPLES,
1215         INIT_LOG_COUNT,
1216         ath9k_hw_adc_dccal_collect,
1217         ath9k_hw_adc_dccal_calibrate
1218 };