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) && (iCoffDenom != 0) &&
407 		    (qCoffDenom != 0)) {
408 			iCoff = iqCorrMeas / iCoffDenom;
409 			qCoff = powerMeasI / qCoffDenom - 64;
410 			ath_print(common, ATH_DBG_CALIBRATE,
411 				  "Chn %d iCoff = 0x%08x\n", i, iCoff);
412 			ath_print(common, ATH_DBG_CALIBRATE,
413 				  "Chn %d qCoff = 0x%08x\n", i, qCoff);
414 
415 			iCoff = iCoff & 0x3f;
416 			ath_print(common, ATH_DBG_CALIBRATE,
417 				  "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
418 			if (iqCorrNeg == 0x0)
419 				iCoff = 0x40 - iCoff;
420 
421 			if (qCoff > 15)
422 				qCoff = 15;
423 			else if (qCoff <= -16)
424 				qCoff = 16;
425 
426 			ath_print(common, ATH_DBG_CALIBRATE,
427 				  "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
428 				  i, iCoff, qCoff);
429 
430 			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
431 				      AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
432 				      iCoff);
433 			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
434 				      AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
435 				      qCoff);
436 			ath_print(common, ATH_DBG_CALIBRATE,
437 				  "IQ Cal and Correction done for Chain %d\n",
438 				  i);
439 		}
440 	}
441 
442 	REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
443 		    AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
444 }
445 
446 static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
447 {
448 	struct ath_common *common = ath9k_hw_common(ah);
449 	u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
450 	u32 qGainMismatch, iGainMismatch, val, i;
451 
452 	for (i = 0; i < numChains; i++) {
453 		iOddMeasOffset = ah->totalAdcIOddPhase[i];
454 		iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
455 		qOddMeasOffset = ah->totalAdcQOddPhase[i];
456 		qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
457 
458 		ath_print(common, ATH_DBG_CALIBRATE,
459 			  "Starting ADC Gain Cal for Chain %d\n", i);
460 
461 		ath_print(common, ATH_DBG_CALIBRATE,
462 			  "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
463 			  iOddMeasOffset);
464 		ath_print(common, ATH_DBG_CALIBRATE,
465 			  "Chn %d pwr_meas_even_i = 0x%08x\n", i,
466 			  iEvenMeasOffset);
467 		ath_print(common, ATH_DBG_CALIBRATE,
468 			  "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
469 			  qOddMeasOffset);
470 		ath_print(common, ATH_DBG_CALIBRATE,
471 			  "Chn %d pwr_meas_even_q = 0x%08x\n", i,
472 			  qEvenMeasOffset);
473 
474 		if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
475 			iGainMismatch =
476 				((iEvenMeasOffset * 32) /
477 				 iOddMeasOffset) & 0x3f;
478 			qGainMismatch =
479 				((qOddMeasOffset * 32) /
480 				 qEvenMeasOffset) & 0x3f;
481 
482 			ath_print(common, ATH_DBG_CALIBRATE,
483 				  "Chn %d gain_mismatch_i = 0x%08x\n", i,
484 				  iGainMismatch);
485 			ath_print(common, ATH_DBG_CALIBRATE,
486 				  "Chn %d gain_mismatch_q = 0x%08x\n", i,
487 				  qGainMismatch);
488 
489 			val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
490 			val &= 0xfffff000;
491 			val |= (qGainMismatch) | (iGainMismatch << 6);
492 			REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
493 
494 			ath_print(common, ATH_DBG_CALIBRATE,
495 				  "ADC Gain Cal done for Chain %d\n", i);
496 		}
497 	}
498 
499 	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
500 		  REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
501 		  AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
502 }
503 
504 static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
505 {
506 	struct ath_common *common = ath9k_hw_common(ah);
507 	u32 iOddMeasOffset, iEvenMeasOffset, val, i;
508 	int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
509 	const struct ath9k_percal_data *calData =
510 		ah->cal_list_curr->calData;
511 	u32 numSamples =
512 		(1 << (calData->calCountMax + 5)) * calData->calNumSamples;
513 
514 	for (i = 0; i < numChains; i++) {
515 		iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
516 		iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
517 		qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
518 		qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
519 
520 		ath_print(common, ATH_DBG_CALIBRATE,
521 			   "Starting ADC DC Offset Cal for Chain %d\n", i);
522 
523 		ath_print(common, ATH_DBG_CALIBRATE,
524 			  "Chn %d pwr_meas_odd_i = %d\n", i,
525 			  iOddMeasOffset);
526 		ath_print(common, ATH_DBG_CALIBRATE,
527 			  "Chn %d pwr_meas_even_i = %d\n", i,
528 			  iEvenMeasOffset);
529 		ath_print(common, ATH_DBG_CALIBRATE,
530 			  "Chn %d pwr_meas_odd_q = %d\n", i,
531 			  qOddMeasOffset);
532 		ath_print(common, ATH_DBG_CALIBRATE,
533 			  "Chn %d pwr_meas_even_q = %d\n", i,
534 			  qEvenMeasOffset);
535 
536 		iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
537 			       numSamples) & 0x1ff;
538 		qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
539 			       numSamples) & 0x1ff;
540 
541 		ath_print(common, ATH_DBG_CALIBRATE,
542 			  "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
543 			  iDcMismatch);
544 		ath_print(common, ATH_DBG_CALIBRATE,
545 			  "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
546 			  qDcMismatch);
547 
548 		val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
549 		val &= 0xc0000fff;
550 		val |= (qDcMismatch << 12) | (iDcMismatch << 21);
551 		REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
552 
553 		ath_print(common, ATH_DBG_CALIBRATE,
554 			  "ADC DC Offset Cal done for Chain %d\n", i);
555 	}
556 
557 	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
558 		  REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
559 		  AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
560 }
561 
562 /* This is done for the currently configured channel */
563 bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
564 {
565 	struct ath_common *common = ath9k_hw_common(ah);
566 	struct ieee80211_conf *conf = &common->hw->conf;
567 	struct ath9k_cal_list *currCal = ah->cal_list_curr;
568 
569 	if (!ah->curchan)
570 		return true;
571 
572 	if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
573 		return true;
574 
575 	if (currCal == NULL)
576 		return true;
577 
578 	if (currCal->calState != CAL_DONE) {
579 		ath_print(common, ATH_DBG_CALIBRATE,
580 			  "Calibration state incorrect, %d\n",
581 			  currCal->calState);
582 		return true;
583 	}
584 
585 	if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
586 		return true;
587 
588 	ath_print(common, ATH_DBG_CALIBRATE,
589 		  "Resetting Cal %d state for channel %u\n",
590 		  currCal->calData->calType, conf->channel->center_freq);
591 
592 	ah->curchan->CalValid &= ~currCal->calData->calType;
593 	currCal->calState = CAL_WAITING;
594 
595 	return false;
596 }
597 EXPORT_SYMBOL(ath9k_hw_reset_calvalid);
598 
599 void ath9k_hw_start_nfcal(struct ath_hw *ah)
600 {
601 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
602 		    AR_PHY_AGC_CONTROL_ENABLE_NF);
603 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
604 		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
605 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
606 }
607 
608 void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
609 {
610 	struct ath9k_nfcal_hist *h;
611 	int i, j;
612 	int32_t val;
613 	const u32 ar5416_cca_regs[6] = {
614 		AR_PHY_CCA,
615 		AR_PHY_CH1_CCA,
616 		AR_PHY_CH2_CCA,
617 		AR_PHY_EXT_CCA,
618 		AR_PHY_CH1_EXT_CCA,
619 		AR_PHY_CH2_EXT_CCA
620 	};
621 	u8 chainmask, rx_chain_status;
622 
623 	rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
624 	if (AR_SREV_9285(ah))
625 		chainmask = 0x9;
626 	else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
627 		if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
628 			chainmask = 0x1B;
629 		else
630 			chainmask = 0x09;
631 	} else {
632 		if (rx_chain_status & 0x4)
633 			chainmask = 0x3F;
634 		else if (rx_chain_status & 0x2)
635 			chainmask = 0x1B;
636 		else
637 			chainmask = 0x09;
638 	}
639 
640 	h = ah->nfCalHist;
641 
642 	for (i = 0; i < NUM_NF_READINGS; i++) {
643 		if (chainmask & (1 << i)) {
644 			val = REG_READ(ah, ar5416_cca_regs[i]);
645 			val &= 0xFFFFFE00;
646 			val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
647 			REG_WRITE(ah, ar5416_cca_regs[i], val);
648 		}
649 	}
650 
651 	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
652 		    AR_PHY_AGC_CONTROL_ENABLE_NF);
653 	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
654 		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
655 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
656 
657 	for (j = 0; j < 5; j++) {
658 		if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
659 		     AR_PHY_AGC_CONTROL_NF) == 0)
660 			break;
661 		udelay(50);
662 	}
663 
664 	for (i = 0; i < NUM_NF_READINGS; i++) {
665 		if (chainmask & (1 << i)) {
666 			val = REG_READ(ah, ar5416_cca_regs[i]);
667 			val &= 0xFFFFFE00;
668 			val |= (((u32) (-50) << 1) & 0x1ff);
669 			REG_WRITE(ah, ar5416_cca_regs[i], val);
670 		}
671 	}
672 }
673 
674 int16_t ath9k_hw_getnf(struct ath_hw *ah,
675 		       struct ath9k_channel *chan)
676 {
677 	struct ath_common *common = ath9k_hw_common(ah);
678 	int16_t nf, nfThresh;
679 	int16_t nfarray[NUM_NF_READINGS] = { 0 };
680 	struct ath9k_nfcal_hist *h;
681 	struct ieee80211_channel *c = chan->chan;
682 
683 	chan->channelFlags &= (~CHANNEL_CW_INT);
684 	if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
685 		ath_print(common, ATH_DBG_CALIBRATE,
686 			  "NF did not complete in calibration window\n");
687 		nf = 0;
688 		chan->rawNoiseFloor = nf;
689 		return chan->rawNoiseFloor;
690 	} else {
691 		ath9k_hw_do_getnf(ah, nfarray);
692 		nf = nfarray[0];
693 		if (getNoiseFloorThresh(ah, c->band, &nfThresh)
694 		    && nf > nfThresh) {
695 			ath_print(common, ATH_DBG_CALIBRATE,
696 				  "noise floor failed detected; "
697 				  "detected %d, threshold %d\n",
698 				  nf, nfThresh);
699 			chan->channelFlags |= CHANNEL_CW_INT;
700 		}
701 	}
702 
703 	h = ah->nfCalHist;
704 
705 	ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
706 	chan->rawNoiseFloor = h[0].privNF;
707 
708 	return chan->rawNoiseFloor;
709 }
710 
711 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
712 {
713 	int i, j;
714 	s16 noise_floor;
715 
716 	if (AR_SREV_9280(ah))
717 		noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
718 	else if (AR_SREV_9285(ah))
719 		noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
720 	else if (AR_SREV_9287(ah))
721 		noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
722 	else
723 		noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
724 
725 	for (i = 0; i < NUM_NF_READINGS; i++) {
726 		ah->nfCalHist[i].currIndex = 0;
727 		ah->nfCalHist[i].privNF = noise_floor;
728 		ah->nfCalHist[i].invalidNFcount =
729 			AR_PHY_CCA_FILTERWINDOW_LENGTH;
730 		for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
731 			ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
732 		}
733 	}
734 }
735 
736 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
737 {
738 	s16 nf;
739 
740 	if (chan->rawNoiseFloor == 0)
741 		nf = -96;
742 	else
743 		nf = chan->rawNoiseFloor;
744 
745 	if (!ath9k_hw_nf_in_range(ah, nf))
746 		nf = ATH_DEFAULT_NOISE_FLOOR;
747 
748 	return nf;
749 }
750 EXPORT_SYMBOL(ath9k_hw_getchan_noise);
751 
752 static void ath9k_olc_temp_compensation_9287(struct ath_hw *ah)
753 {
754 	u32 rddata;
755 	int32_t delta, currPDADC, slope;
756 
757 	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
758 	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
759 
760 	if (ah->initPDADC == 0 || currPDADC == 0) {
761 		/*
762 		 * Zero value indicates that no frames have been transmitted yet,
763 		 * can't do temperature compensation until frames are transmitted.
764 		 */
765 		return;
766 	} else {
767 		slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
768 
769 		if (slope == 0) { /* to avoid divide by zero case */
770 			delta = 0;
771 		} else {
772 			delta = ((currPDADC - ah->initPDADC)*4) / slope;
773 		}
774 		REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
775 			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
776 		REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
777 			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
778 	}
779 }
780 
781 static void ath9k_olc_temp_compensation(struct ath_hw *ah)
782 {
783 	u32 rddata, i;
784 	int delta, currPDADC, regval;
785 
786 	if (OLC_FOR_AR9287_10_LATER) {
787 		ath9k_olc_temp_compensation_9287(ah);
788 	} else {
789 		rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
790 		currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
791 
792 		if (ah->initPDADC == 0 || currPDADC == 0) {
793 			return;
794 		} else {
795 			if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
796 				delta = (currPDADC - ah->initPDADC + 4) / 8;
797 			else
798 				delta = (currPDADC - ah->initPDADC + 5) / 10;
799 
800 			if (delta != ah->PDADCdelta) {
801 				ah->PDADCdelta = delta;
802 				for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
803 					regval = ah->originalGain[i] - delta;
804 					if (regval < 0)
805 						regval = 0;
806 
807 					REG_RMW_FIELD(ah,
808 						      AR_PHY_TX_GAIN_TBL1 + i * 4,
809 						      AR_PHY_TX_GAIN, regval);
810 				}
811 			}
812 		}
813 	}
814 }
815 
816 static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset)
817 {
818 	u32 regVal;
819 	unsigned int i;
820 	u32 regList [][2] = {
821 		{ 0x786c, 0 },
822 		{ 0x7854, 0 },
823 		{ 0x7820, 0 },
824 		{ 0x7824, 0 },
825 		{ 0x7868, 0 },
826 		{ 0x783c, 0 },
827 		{ 0x7838, 0 } ,
828 		{ 0x7828, 0 } ,
829 	};
830 
831 	for (i = 0; i < ARRAY_SIZE(regList); i++)
832 		regList[i][1] = REG_READ(ah, regList[i][0]);
833 
834 	regVal = REG_READ(ah, 0x7834);
835 	regVal &= (~(0x1));
836 	REG_WRITE(ah, 0x7834, regVal);
837 	regVal = REG_READ(ah, 0x9808);
838 	regVal |= (0x1 << 27);
839 	REG_WRITE(ah, 0x9808, regVal);
840 
841 	/* 786c,b23,1, pwddac=1 */
842 	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
843 	/* 7854, b5,1, pdrxtxbb=1 */
844 	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
845 	/* 7854, b7,1, pdv2i=1 */
846 	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
847 	/* 7854, b8,1, pddacinterface=1 */
848 	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
849 	/* 7824,b12,0, offcal=0 */
850 	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
851 	/* 7838, b1,0, pwddb=0 */
852 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
853 	/* 7820,b11,0, enpacal=0 */
854 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
855 	/* 7820,b25,1, pdpadrv1=0 */
856 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
857 	/* 7820,b24,0, pdpadrv2=0 */
858 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0);
859 	/* 7820,b23,0, pdpaout=0 */
860 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
861 	/* 783c,b14-16,7, padrvgn2tab_0=7 */
862 	REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
863 	/*
864 	 * 7838,b29-31,0, padrvgn1tab_0=0
865 	 * does not matter since we turn it off
866 	 */
867 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
868 
869 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
870 
871 	/* Set:
872 	 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
873 	 * txon=1,paon=1,oscon=1,synthon_force=1
874 	 */
875 	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
876 	udelay(30);
877 	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
878 
879 	/* find off_6_1; */
880 	for (i = 6; i > 0; i--) {
881 		regVal = REG_READ(ah, 0x7834);
882 		regVal |= (1 << (20 + i));
883 		REG_WRITE(ah, 0x7834, regVal);
884 		udelay(1);
885 		//regVal = REG_READ(ah, 0x7834);
886 		regVal &= (~(0x1 << (20 + i)));
887 		regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
888 			    << (20 + i));
889 		REG_WRITE(ah, 0x7834, regVal);
890 	}
891 
892 	regVal = (regVal >>20) & 0x7f;
893 
894 	/* Update PA cal info */
895 	if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
896 		if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
897 			ah->pacal_info.max_skipcount =
898 				2 * ah->pacal_info.max_skipcount;
899 		ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
900 	} else {
901 		ah->pacal_info.max_skipcount = 1;
902 		ah->pacal_info.skipcount = 0;
903 		ah->pacal_info.prev_offset = regVal;
904 	}
905 
906 	regVal = REG_READ(ah, 0x7834);
907 	regVal |= 0x1;
908 	REG_WRITE(ah, 0x7834, regVal);
909 	regVal = REG_READ(ah, 0x9808);
910 	regVal &= (~(0x1 << 27));
911 	REG_WRITE(ah, 0x9808, regVal);
912 
913 	for (i = 0; i < ARRAY_SIZE(regList); i++)
914 		REG_WRITE(ah, regList[i][0], regList[i][1]);
915 }
916 
917 static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
918 {
919 	struct ath_common *common = ath9k_hw_common(ah);
920 	u32 regVal;
921 	int i, offset, offs_6_1, offs_0;
922 	u32 ccomp_org, reg_field;
923 	u32 regList[][2] = {
924 		{ 0x786c, 0 },
925 		{ 0x7854, 0 },
926 		{ 0x7820, 0 },
927 		{ 0x7824, 0 },
928 		{ 0x7868, 0 },
929 		{ 0x783c, 0 },
930 		{ 0x7838, 0 },
931 	};
932 
933 	ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
934 
935 	/* PA CAL is not needed for high power solution */
936 	if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
937 	    AR5416_EEP_TXGAIN_HIGH_POWER)
938 		return;
939 
940 	if (AR_SREV_9285_11(ah)) {
941 		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
942 		udelay(10);
943 	}
944 
945 	for (i = 0; i < ARRAY_SIZE(regList); i++)
946 		regList[i][1] = REG_READ(ah, regList[i][0]);
947 
948 	regVal = REG_READ(ah, 0x7834);
949 	regVal &= (~(0x1));
950 	REG_WRITE(ah, 0x7834, regVal);
951 	regVal = REG_READ(ah, 0x9808);
952 	regVal |= (0x1 << 27);
953 	REG_WRITE(ah, 0x9808, regVal);
954 
955 	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
956 	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
957 	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
958 	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
959 	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
960 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
961 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
962 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
963 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
964 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
965 	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
966 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
967 	ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
968 	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
969 
970 	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
971 	udelay(30);
972 	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
973 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
974 
975 	for (i = 6; i > 0; i--) {
976 		regVal = REG_READ(ah, 0x7834);
977 		regVal |= (1 << (19 + i));
978 		REG_WRITE(ah, 0x7834, regVal);
979 		udelay(1);
980 		regVal = REG_READ(ah, 0x7834);
981 		regVal &= (~(0x1 << (19 + i)));
982 		reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
983 		regVal |= (reg_field << (19 + i));
984 		REG_WRITE(ah, 0x7834, regVal);
985 	}
986 
987 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
988 	udelay(1);
989 	reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
990 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
991 	offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
992 	offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
993 
994 	offset = (offs_6_1<<1) | offs_0;
995 	offset = offset - 0;
996 	offs_6_1 = offset>>1;
997 	offs_0 = offset & 1;
998 
999 	if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
1000 		if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
1001 			ah->pacal_info.max_skipcount =
1002 				2 * ah->pacal_info.max_skipcount;
1003 		ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
1004 	} else {
1005 		ah->pacal_info.max_skipcount = 1;
1006 		ah->pacal_info.skipcount = 0;
1007 		ah->pacal_info.prev_offset = offset;
1008 	}
1009 
1010 	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
1011 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
1012 
1013 	regVal = REG_READ(ah, 0x7834);
1014 	regVal |= 0x1;
1015 	REG_WRITE(ah, 0x7834, regVal);
1016 	regVal = REG_READ(ah, 0x9808);
1017 	regVal &= (~(0x1 << 27));
1018 	REG_WRITE(ah, 0x9808, regVal);
1019 
1020 	for (i = 0; i < ARRAY_SIZE(regList); i++)
1021 		REG_WRITE(ah, regList[i][0], regList[i][1]);
1022 
1023 	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
1024 
1025 	if (AR_SREV_9285_11(ah))
1026 		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
1027 
1028 }
1029 
1030 bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
1031 			u8 rxchainmask, bool longcal)
1032 {
1033 	bool iscaldone = true;
1034 	struct ath9k_cal_list *currCal = ah->cal_list_curr;
1035 
1036 	if (currCal &&
1037 	    (currCal->calState == CAL_RUNNING ||
1038 	     currCal->calState == CAL_WAITING)) {
1039 		iscaldone = ath9k_hw_per_calibration(ah, chan,
1040 						     rxchainmask, currCal);
1041 		if (iscaldone) {
1042 			ah->cal_list_curr = currCal = currCal->calNext;
1043 
1044 			if (currCal->calState == CAL_WAITING) {
1045 				iscaldone = false;
1046 				ath9k_hw_reset_calibration(ah, currCal);
1047 			}
1048 		}
1049 	}
1050 
1051 	/* Do NF cal only at longer intervals */
1052 	if (longcal) {
1053 		/* Do periodic PAOffset Cal */
1054 		if (AR_SREV_9271(ah))
1055 			ath9k_hw_9271_pa_cal(ah, false);
1056 		else if (AR_SREV_9285_11_OR_LATER(ah)) {
1057 			if (!ah->pacal_info.skipcount)
1058 				ath9k_hw_9285_pa_cal(ah, false);
1059 			else
1060 				ah->pacal_info.skipcount--;
1061 		}
1062 
1063 		if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
1064 			ath9k_olc_temp_compensation(ah);
1065 
1066 		/* Get the value from the previous NF cal and update history buffer */
1067 		ath9k_hw_getnf(ah, chan);
1068 
1069 		/*
1070 		 * Load the NF from history buffer of the current channel.
1071 		 * NF is slow time-variant, so it is OK to use a historical value.
1072 		 */
1073 		ath9k_hw_loadnf(ah, ah->curchan);
1074 
1075 		ath9k_hw_start_nfcal(ah);
1076 	}
1077 
1078 	return iscaldone;
1079 }
1080 EXPORT_SYMBOL(ath9k_hw_calibrate);
1081 
1082 /* Carrier leakage Calibration fix */
1083 static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
1084 {
1085 	struct ath_common *common = ath9k_hw_common(ah);
1086 
1087 	REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1088 	if (IS_CHAN_HT20(chan)) {
1089 		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
1090 		REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
1091 		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1092 			    AR_PHY_AGC_CONTROL_FLTR_CAL);
1093 		REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
1094 		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
1095 		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1096 				  AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
1097 			ath_print(common, ATH_DBG_CALIBRATE, "offset "
1098 				  "calibration failed to complete in "
1099 				  "1ms; noisy ??\n");
1100 			return false;
1101 		}
1102 		REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
1103 		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
1104 		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1105 	}
1106 	REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
1107 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
1108 	REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
1109 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
1110 	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
1111 			  0, AH_WAIT_TIMEOUT)) {
1112 		ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
1113 			  "failed to complete in 1ms; noisy ??\n");
1114 		return false;
1115 	}
1116 
1117 	REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
1118 	REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1119 	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
1120 
1121 	return true;
1122 }
1123 
1124 bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
1125 {
1126 	struct ath_common *common = ath9k_hw_common(ah);
1127 
1128 	if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
1129 		if (!ar9285_clc(ah, chan))
1130 			return false;
1131 	} else {
1132 		if (AR_SREV_9280_10_OR_LATER(ah)) {
1133 			if (!AR_SREV_9287_10_OR_LATER(ah))
1134 				REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
1135 					    AR_PHY_ADC_CTL_OFF_PWDADC);
1136 			REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1137 				    AR_PHY_AGC_CONTROL_FLTR_CAL);
1138 		}
1139 
1140 		/* Calibrate the AGC */
1141 		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1142 			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
1143 			  AR_PHY_AGC_CONTROL_CAL);
1144 
1145 		/* Poll for offset calibration complete */
1146 		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
1147 				   0, AH_WAIT_TIMEOUT)) {
1148 			ath_print(common, ATH_DBG_CALIBRATE,
1149 				  "offset calibration failed to "
1150 				  "complete in 1ms; noisy environment?\n");
1151 			return false;
1152 		}
1153 
1154 		if (AR_SREV_9280_10_OR_LATER(ah)) {
1155 			if (!AR_SREV_9287_10_OR_LATER(ah))
1156 				REG_SET_BIT(ah, AR_PHY_ADC_CTL,
1157 					    AR_PHY_ADC_CTL_OFF_PWDADC);
1158 			REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1159 				    AR_PHY_AGC_CONTROL_FLTR_CAL);
1160 		}
1161 	}
1162 
1163 	/* Do PA Calibration */
1164 	if (AR_SREV_9271(ah))
1165 		ath9k_hw_9271_pa_cal(ah, true);
1166 	else if (AR_SREV_9285_11_OR_LATER(ah))
1167 		ath9k_hw_9285_pa_cal(ah, true);
1168 
1169 	/* Do NF Calibration after DC offset and other calibrations */
1170 	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1171 		  REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
1172 
1173 	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1174 
1175 	/* Enable IQ, ADC Gain and ADC DC offset CALs */
1176 	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
1177 		if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
1178 			INIT_CAL(&ah->adcgain_caldata);
1179 			INSERT_CAL(ah, &ah->adcgain_caldata);
1180 			ath_print(common, ATH_DBG_CALIBRATE,
1181 				  "enabling ADC Gain Calibration.\n");
1182 		}
1183 		if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
1184 			INIT_CAL(&ah->adcdc_caldata);
1185 			INSERT_CAL(ah, &ah->adcdc_caldata);
1186 			ath_print(common, ATH_DBG_CALIBRATE,
1187 				  "enabling ADC DC Calibration.\n");
1188 		}
1189 		if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
1190 			INIT_CAL(&ah->iq_caldata);
1191 			INSERT_CAL(ah, &ah->iq_caldata);
1192 			ath_print(common, ATH_DBG_CALIBRATE,
1193 				  "enabling IQ Calibration.\n");
1194 		}
1195 
1196 		ah->cal_list_curr = ah->cal_list;
1197 
1198 		if (ah->cal_list_curr)
1199 			ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1200 	}
1201 
1202 	chan->CalValid = 0;
1203 
1204 	return true;
1205 }
1206 
1207 const struct ath9k_percal_data iq_cal_multi_sample = {
1208 	IQ_MISMATCH_CAL,
1209 	MAX_CAL_SAMPLES,
1210 	PER_MIN_LOG_COUNT,
1211 	ath9k_hw_iqcal_collect,
1212 	ath9k_hw_iqcalibrate
1213 };
1214 const struct ath9k_percal_data iq_cal_single_sample = {
1215 	IQ_MISMATCH_CAL,
1216 	MIN_CAL_SAMPLES,
1217 	PER_MAX_LOG_COUNT,
1218 	ath9k_hw_iqcal_collect,
1219 	ath9k_hw_iqcalibrate
1220 };
1221 const struct ath9k_percal_data adc_gain_cal_multi_sample = {
1222 	ADC_GAIN_CAL,
1223 	MAX_CAL_SAMPLES,
1224 	PER_MIN_LOG_COUNT,
1225 	ath9k_hw_adc_gaincal_collect,
1226 	ath9k_hw_adc_gaincal_calibrate
1227 };
1228 const struct ath9k_percal_data adc_gain_cal_single_sample = {
1229 	ADC_GAIN_CAL,
1230 	MIN_CAL_SAMPLES,
1231 	PER_MAX_LOG_COUNT,
1232 	ath9k_hw_adc_gaincal_collect,
1233 	ath9k_hw_adc_gaincal_calibrate
1234 };
1235 const struct ath9k_percal_data adc_dc_cal_multi_sample = {
1236 	ADC_DC_CAL,
1237 	MAX_CAL_SAMPLES,
1238 	PER_MIN_LOG_COUNT,
1239 	ath9k_hw_adc_dccal_collect,
1240 	ath9k_hw_adc_dccal_calibrate
1241 };
1242 const struct ath9k_percal_data adc_dc_cal_single_sample = {
1243 	ADC_DC_CAL,
1244 	MIN_CAL_SAMPLES,
1245 	PER_MAX_LOG_COUNT,
1246 	ath9k_hw_adc_dccal_collect,
1247 	ath9k_hw_adc_dccal_calibrate
1248 };
1249 const struct ath9k_percal_data adc_init_dc_cal = {
1250 	ADC_DC_INIT_CAL,
1251 	MIN_CAL_SAMPLES,
1252 	INIT_LOG_COUNT,
1253 	ath9k_hw_adc_dccal_collect,
1254 	ath9k_hw_adc_dccal_calibrate
1255 };
1256