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