1 /*
2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * Copyright (c) 2008 Atheros Communications Inc.
8 *
9 * Permission to use, copy, modify, and/or distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22 #include "arn_core.h"
23 #include "arn_hw.h"
24 #include "arn_reg.h"
25 #include "arn_phy.h"
26
27 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
28
29 /* We can tune this as we go by monitoring really low values */
30 #define ATH9K_NF_TOO_LOW -60
31
32 /*
33 * AR5416 may return very high value (like -31 dBm), in those cases the nf
34 * is incorrect and we should use the static NF value. Later we can try to
35 * find out why they are reporting these values
36 */
37
38 /* ARGSUSED */
39 static boolean_t
ath9k_hw_nf_in_range(struct ath_hal * ah,signed short nf)40 ath9k_hw_nf_in_range(struct ath_hal *ah, signed short nf)
41 {
42 if (nf > ATH9K_NF_TOO_LOW) {
43 ARN_DBG((ARN_DBG_CALIBRATE,
44 "%s: noise floor value detected (%d) is "
45 "lower than what we think is a "
46 "reasonable value (%d)\n",
47 __func__, nf, ATH9K_NF_TOO_LOW));
48
49 return (B_FALSE);
50 }
51 return (B_TRUE);
52 }
53
54 static int16_t
ath9k_hw_get_nf_hist_mid(int16_t * nfCalBuffer)55 ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
56 {
57 int16_t nfval;
58 int16_t sort[ATH9K_NF_CAL_HIST_MAX];
59 int i, j;
60
61 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
62 sort[i] = nfCalBuffer[i];
63
64 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
65 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
66 if (sort[j] > sort[j - 1]) {
67 nfval = sort[j];
68 sort[j] = sort[j - 1];
69 sort[j - 1] = nfval;
70 }
71 }
72 }
73 nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
74
75 return (nfval);
76 }
77
78 static void
ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist * h,int16_t * nfarray)79 ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
80 int16_t *nfarray)
81 {
82 int i;
83
84 for (i = 0; i < NUM_NF_READINGS; i++) {
85 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
86
87 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
88 h[i].currIndex = 0;
89
90 if (h[i].invalidNFcount > 0) {
91 if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
92 nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
93 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
94 } else {
95 h[i].invalidNFcount--;
96 h[i].privNF = nfarray[i];
97 }
98 } else {
99 h[i].privNF =
100 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
101 }
102 }
103 }
104
105 static void
ath9k_hw_do_getnf(struct ath_hal * ah,int16_t nfarray[NUM_NF_READINGS])106 ath9k_hw_do_getnf(struct ath_hal *ah,
107 int16_t nfarray[NUM_NF_READINGS])
108 {
109 int16_t nf;
110
111 if (AR_SREV_9280_10_OR_LATER(ah))
112 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
113 else
114 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
115
116 if (nf & 0x100)
117 nf = 0 - ((nf ^ 0x1ff) + 1);
118 ARN_DBG((ARN_DBG_CALIBRATE,
119 "NF calibrated [ctl] [chain 0] is %d\n", nf));
120 nfarray[0] = nf;
121
122 if (AR_SREV_9280_10_OR_LATER(ah))
123 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
124 AR9280_PHY_CH1_MINCCA_PWR);
125 else
126 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
127 AR_PHY_CH1_MINCCA_PWR);
128
129 if (nf & 0x100)
130 nf = 0 - ((nf ^ 0x1ff) + 1);
131 ARN_DBG((ARN_DBG_CALIBRATE,
132 "NF calibrated [ctl] [chain 1] is %d\n", nf));
133 nfarray[1] = nf;
134
135 if (!AR_SREV_9280(ah)) {
136 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
137 AR_PHY_CH2_MINCCA_PWR);
138 if (nf & 0x100)
139 nf = 0 - ((nf ^ 0x1ff) + 1);
140 ARN_DBG((ARN_DBG_CALIBRATE,
141 "NF calibrated [ctl] [chain 2] is %d\n", nf));
142 nfarray[2] = nf;
143 }
144
145 if (AR_SREV_9280_10_OR_LATER(ah))
146 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
147 AR9280_PHY_EXT_MINCCA_PWR);
148 else
149 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
150 AR_PHY_EXT_MINCCA_PWR);
151
152 if (nf & 0x100)
153 nf = 0 - ((nf ^ 0x1ff) + 1);
154 ARN_DBG((ARN_DBG_CALIBRATE,
155 "NF calibrated [ext] [chain 0] is %d\n", nf));
156 nfarray[3] = nf;
157
158 if (AR_SREV_9280_10_OR_LATER(ah))
159 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
160 AR9280_PHY_CH1_EXT_MINCCA_PWR);
161 else
162 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
163 AR_PHY_CH1_EXT_MINCCA_PWR);
164
165 if (nf & 0x100)
166 nf = 0 - ((nf ^ 0x1ff) + 1);
167 ARN_DBG((ARN_DBG_CALIBRATE,
168 "NF calibrated [ext] [chain 1] is %d\n", nf));
169 nfarray[4] = nf;
170
171 if (!AR_SREV_9280(ah)) {
172 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
173 AR_PHY_CH2_EXT_MINCCA_PWR);
174 if (nf & 0x100)
175 nf = 0 - ((nf ^ 0x1ff) + 1);
176 ARN_DBG((ARN_DBG_CALIBRATE,
177 "NF calibrated [ext] [chain 2] is %d\n", nf));
178 nfarray[5] = nf;
179 }
180 }
181
182 static boolean_t
getNoiseFloorThresh(struct ath_hal * ah,const struct ath9k_channel * chan,int16_t * nft)183 getNoiseFloorThresh(struct ath_hal *ah,
184 const struct ath9k_channel *chan,
185 int16_t *nft)
186 {
187 switch (chan->chanmode) {
188 case CHANNEL_A:
189 case CHANNEL_A_HT20:
190 case CHANNEL_A_HT40PLUS:
191 case CHANNEL_A_HT40MINUS:
192 *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
193 break;
194 case CHANNEL_B:
195 case CHANNEL_G:
196 case CHANNEL_G_HT20:
197 case CHANNEL_G_HT40PLUS:
198 case CHANNEL_G_HT40MINUS:
199 *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
200 break;
201 default:
202 ARN_DBG((ARN_DBG_CHANNEL,
203 "%s: invalid channel flags 0x%x\n", __func__,
204 chan->channelFlags));
205 return (B_FALSE);
206 }
207
208 return (B_TRUE);
209 }
210
211 static void
ath9k_hw_setup_calibration(struct ath_hal * ah,struct hal_cal_list * currCal)212 ath9k_hw_setup_calibration(struct ath_hal *ah,
213 struct hal_cal_list *currCal)
214 {
215 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
216 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
217 currCal->calData->calCountMax);
218
219 switch (currCal->calData->calType) {
220 case IQ_MISMATCH_CAL:
221 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
222 ARN_DBG((ARN_DBG_CALIBRATE,
223 "%s: starting IQ Mismatch Calibration\n",
224 __func__));
225 break;
226 case ADC_GAIN_CAL:
227 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
228 ARN_DBG((ARN_DBG_CALIBRATE,
229 "%s: starting ADC Gain Calibration\n", __func__));
230 break;
231 case ADC_DC_CAL:
232 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
233 ARN_DBG((ARN_DBG_CALIBRATE,
234 "%s: starting ADC DC Calibration\n", __func__));
235 break;
236 case ADC_DC_INIT_CAL:
237 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
238 ARN_DBG((ARN_DBG_CALIBRATE,
239 "%s: starting Init ADC DC Calibration\n",
240 __func__));
241 break;
242 }
243
244 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
245 AR_PHY_TIMING_CTRL4_DO_CAL);
246 }
247
248 static void
ath9k_hw_reset_calibration(struct ath_hal * ah,struct hal_cal_list * currCal)249 ath9k_hw_reset_calibration(struct ath_hal *ah,
250 struct hal_cal_list *currCal)
251 {
252 struct ath_hal_5416 *ahp = AH5416(ah);
253 int i;
254
255 ath9k_hw_setup_calibration(ah, currCal);
256
257 currCal->calState = CAL_RUNNING;
258
259 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
260 ahp->ah_Meas0.sign[i] = 0;
261 ahp->ah_Meas1.sign[i] = 0;
262 ahp->ah_Meas2.sign[i] = 0;
263 ahp->ah_Meas3.sign[i] = 0;
264 }
265
266 ahp->ah_CalSamples = 0;
267 }
268
269 static void
ath9k_hw_per_calibration(struct ath_hal * ah,struct ath9k_channel * ichan,uint8_t rxchainmask,struct hal_cal_list * currCal,boolean_t * isCalDone)270 ath9k_hw_per_calibration(struct ath_hal *ah,
271 struct ath9k_channel *ichan,
272 uint8_t rxchainmask,
273 struct hal_cal_list *currCal,
274 boolean_t *isCalDone)
275 {
276 struct ath_hal_5416 *ahp = AH5416(ah);
277
278 *isCalDone = B_FALSE;
279
280 if (currCal->calState == CAL_RUNNING) {
281 if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
282 AR_PHY_TIMING_CTRL4_DO_CAL)) {
283
284 currCal->calData->calCollect(ah);
285 ahp->ah_CalSamples++;
286
287 if (ahp->ah_CalSamples >=
288 currCal->calData->calNumSamples) {
289 int i, numChains = 0;
290 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
291 if (rxchainmask & (1 << i))
292 numChains++;
293 }
294
295 currCal->calData->calPostProc(ah, numChains);
296 ichan->CalValid |= currCal->calData->calType;
297 currCal->calState = CAL_DONE;
298 *isCalDone = B_TRUE;
299 } else {
300 ath9k_hw_setup_calibration(ah, currCal);
301 }
302 }
303 } else if (!(ichan->CalValid & currCal->calData->calType)) {
304 ath9k_hw_reset_calibration(ah, currCal);
305 }
306 }
307
308 static boolean_t
ath9k_hw_iscal_supported(struct ath_hal * ah,struct ath9k_channel * chan,enum hal_cal_types calType)309 ath9k_hw_iscal_supported(struct ath_hal *ah,
310 struct ath9k_channel *chan,
311 enum hal_cal_types calType)
312 {
313 struct ath_hal_5416 *ahp = AH5416(ah);
314 boolean_t retval = B_FALSE;
315
316 switch (calType & ahp->ah_suppCals) {
317 case IQ_MISMATCH_CAL:
318 if (!IS_CHAN_B(chan))
319 retval = B_TRUE;
320 break;
321 case ADC_GAIN_CAL:
322 case ADC_DC_CAL:
323 if (!IS_CHAN_B(chan) &&
324 !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
325 retval = B_TRUE;
326 break;
327 }
328
329 return (retval);
330 }
331
332 static void
ath9k_hw_iqcal_collect(struct ath_hal * ah)333 ath9k_hw_iqcal_collect(struct ath_hal *ah)
334 {
335 struct ath_hal_5416 *ahp = AH5416(ah);
336 int i;
337
338 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
339 ahp->ah_totalPowerMeasI[i] +=
340 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
341 ahp->ah_totalPowerMeasQ[i] +=
342 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
343 ahp->ah_totalIqCorrMeas[i] +=
344 (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
345 ARN_DBG((ARN_DBG_CALIBRATE,
346 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
347 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
348 ahp->ah_totalPowerMeasQ[i],
349 ahp->ah_totalIqCorrMeas[i]));
350 }
351 }
352
353 static void
ath9k_hw_adc_gaincal_collect(struct ath_hal * ah)354 ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
355 {
356 struct ath_hal_5416 *ahp = AH5416(ah);
357 int i;
358
359 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
360 ahp->ah_totalAdcIOddPhase[i] +=
361 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
362 ahp->ah_totalAdcIEvenPhase[i] +=
363 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
364 ahp->ah_totalAdcQOddPhase[i] +=
365 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
366 ahp->ah_totalAdcQEvenPhase[i] +=
367 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
368 ARN_DBG((ARN_DBG_CALIBRATE,
369 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
370 "oddq=0x%08x; evenq=0x%08x;\n",
371 ahp->ah_CalSamples, i,
372 ahp->ah_totalAdcIOddPhase[i],
373 ahp->ah_totalAdcIEvenPhase[i],
374 ahp->ah_totalAdcQOddPhase[i],
375 ahp->ah_totalAdcQEvenPhase[i]));
376 }
377 }
378
379 static void
ath9k_hw_adc_dccal_collect(struct ath_hal * ah)380 ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
381 {
382 struct ath_hal_5416 *ahp = AH5416(ah);
383 int i;
384
385 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
386 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
387 (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
388 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
389 (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
390 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
391 (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
392 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
393 (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
394 ARN_DBG((ARN_DBG_CALIBRATE,
395 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
396 "oddq=0x%08x; evenq=0x%08x;\n",
397 ahp->ah_CalSamples, i,
398 ahp->ah_totalAdcDcOffsetIOddPhase[i],
399 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
400 ahp->ah_totalAdcDcOffsetQOddPhase[i],
401 ahp->ah_totalAdcDcOffsetQEvenPhase[i]));
402 }
403 }
404
405 static void
ath9k_hw_iqcalibrate(struct ath_hal * ah,uint8_t numChains)406 ath9k_hw_iqcalibrate(struct ath_hal *ah, uint8_t numChains)
407 {
408 struct ath_hal_5416 *ahp = AH5416(ah);
409 uint32_t powerMeasQ, powerMeasI, iqCorrMeas;
410 uint32_t qCoffDenom, iCoffDenom;
411 int32_t qCoff, iCoff;
412 int iqCorrNeg, i;
413
414 for (i = 0; i < numChains; i++) {
415 powerMeasI = ahp->ah_totalPowerMeasI[i];
416 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
417 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
418 ARN_DBG((ARN_DBG_CALIBRATE,
419 "Starting IQ Cal and Correction for Chain %d\n",
420 i));
421
422 ARN_DBG((ARN_DBG_CALIBRATE,
423 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
424 i, ahp->ah_totalIqCorrMeas[i]));
425
426 iqCorrNeg = 0;
427
428 if (iqCorrMeas > 0x80000000) {
429 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
430 iqCorrNeg = 1;
431 }
432
433 ARN_DBG((ARN_DBG_CALIBRATE,
434 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI));
435 ARN_DBG((ARN_DBG_CALIBRATE,
436 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ));
437 ARN_DBG((ARN_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
438 iqCorrNeg));
439
440 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
441 qCoffDenom = powerMeasQ / 64;
442
443 if (powerMeasQ != 0) {
444 iCoff = iqCorrMeas / iCoffDenom;
445 qCoff = powerMeasI / qCoffDenom - 64;
446
447 ARN_DBG((ARN_DBG_CALIBRATE,
448 "Chn %d iCoff = 0x%08x\n", i, iCoff));
449 ARN_DBG((ARN_DBG_CALIBRATE,
450 "Chn %d qCoff = 0x%08x\n", i, qCoff));
451
452 iCoff = iCoff & 0x3f;
453
454 ARN_DBG((ARN_DBG_CALIBRATE,
455 "New: Chn %d iCoff = 0x%08x\n", i, iCoff));
456
457 if (iqCorrNeg == 0x0)
458 iCoff = 0x40 - iCoff;
459
460 if (qCoff > 15)
461 qCoff = 15;
462 else if (qCoff <= -16)
463 qCoff = 16;
464
465 ARN_DBG((ARN_DBG_CALIBRATE,
466 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
467 i, iCoff, qCoff));
468
469 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
470 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
471 iCoff);
472 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
473 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
474 qCoff);
475
476 ARN_DBG((ARN_DBG_CALIBRATE,
477 "IQ Cal and Correction done for Chain %d\n",
478 i));
479 }
480 }
481
482 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
483 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
484 }
485
486 static void
ath9k_hw_adc_gaincal_calibrate(struct ath_hal * ah,uint8_t numChains)487 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, uint8_t numChains)
488 {
489 struct ath_hal_5416 *ahp = AH5416(ah);
490 uint32_t iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
491 qEvenMeasOffset;
492 uint32_t qGainMismatch, iGainMismatch, val, i;
493
494 for (i = 0; i < numChains; i++) {
495 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
496 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
497 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
498 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
499
500 ARN_DBG((ARN_DBG_CALIBRATE,
501 "Starting ADC Gain Cal for Chain %d\n", i));
502
503 ARN_DBG((ARN_DBG_CALIBRATE,
504 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
505 iOddMeasOffset));
506 ARN_DBG((ARN_DBG_CALIBRATE,
507 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
508 iEvenMeasOffset));
509 ARN_DBG((ARN_DBG_CALIBRATE,
510 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
511 qOddMeasOffset));
512 ARN_DBG((ARN_DBG_CALIBRATE,
513 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
514 qEvenMeasOffset));
515
516 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
517 iGainMismatch =
518 ((iEvenMeasOffset * 32) /
519 iOddMeasOffset) & 0x3f;
520 qGainMismatch =
521 ((qOddMeasOffset * 32) /
522 qEvenMeasOffset) & 0x3f;
523
524 ARN_DBG((ARN_DBG_CALIBRATE,
525 "Chn %d gain_mismatch_i = 0x%08x\n", i,
526 iGainMismatch));
527 ARN_DBG((ARN_DBG_CALIBRATE,
528 "Chn %d gain_mismatch_q = 0x%08x\n", i,
529 qGainMismatch));
530
531 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
532 val &= 0xfffff000;
533 val |= (qGainMismatch) | (iGainMismatch << 6);
534 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
535
536 ARN_DBG((ARN_DBG_CALIBRATE,
537 "ADC Gain Cal done for Chain %d\n", i));
538 }
539 }
540
541 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
542 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
543 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
544 }
545
546 static void
ath9k_hw_adc_dccal_calibrate(struct ath_hal * ah,uint8_t numChains)547 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, uint8_t numChains)
548 {
549 struct ath_hal_5416 *ahp = AH5416(ah);
550 uint32_t iOddMeasOffset, iEvenMeasOffset, val, i;
551 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
552 const struct hal_percal_data *calData =
553 ahp->ah_cal_list_curr->calData;
554 uint32_t numSamples =
555 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
556
557 for (i = 0; i < numChains; i++) {
558 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
559 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
560 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
561 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
562
563 ARN_DBG((ARN_DBG_CALIBRATE,
564 "Starting ADC DC Offset Cal for Chain %d\n", i));
565
566 ARN_DBG((ARN_DBG_CALIBRATE,
567 "Chn %d pwr_meas_odd_i = %d\n", i,
568 iOddMeasOffset));
569 ARN_DBG((ARN_DBG_CALIBRATE,
570 "Chn %d pwr_meas_even_i = %d\n", i,
571 iEvenMeasOffset));
572 ARN_DBG((ARN_DBG_CALIBRATE,
573 "Chn %d pwr_meas_odd_q = %d\n", i,
574 qOddMeasOffset));
575 ARN_DBG((ARN_DBG_CALIBRATE,
576 "Chn %d pwr_meas_even_q = %d\n", i,
577 qEvenMeasOffset));
578
579 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
580 numSamples) & 0x1ff;
581 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
582 numSamples) & 0x1ff;
583
584 ARN_DBG((ARN_DBG_CALIBRATE,
585 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
586 iDcMismatch));
587 ARN_DBG((ARN_DBG_CALIBRATE,
588 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
589 qDcMismatch));
590
591 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
592 val &= 0xc0000fff;
593 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
594 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
595
596 ARN_DBG((ARN_DBG_CALIBRATE,
597 "ADC DC Offset Cal done for Chain %d\n", i));
598 }
599
600 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
601 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
602 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
603 }
604
605 void
ath9k_hw_reset_calvalid(struct ath_hal * ah,struct ath9k_channel * chan,boolean_t * isCalDone)606 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
607 boolean_t *isCalDone)
608 {
609 struct ath_hal_5416 *ahp = AH5416(ah);
610 struct ath9k_channel *ichan =
611 ath9k_regd_check_channel(ah, chan);
612 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
613
614 *isCalDone = B_TRUE;
615
616 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
617 return;
618
619 if (currCal == NULL)
620 return;
621
622 if (ichan == NULL) {
623 ARN_DBG((ARN_DBG_CALIBRATE,
624 "%s: invalid channel %u/0x%x; no mapping\n",
625 __func__, chan->channel, chan->channelFlags));
626 return;
627 }
628
629
630 if (currCal->calState != CAL_DONE) {
631 ARN_DBG((ARN_DBG_CALIBRATE,
632 "%s: Calibration state incorrect, %d\n",
633 __func__, currCal->calState));
634 return;
635 }
636
637
638 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
639 return;
640 ARN_DBG((ARN_DBG_CALIBRATE,
641 "%s: Resetting Cal %d state for channel %u/0x%x\n",
642 __func__, currCal->calData->calType, chan->channel,
643 chan->channelFlags));
644
645 ichan->CalValid &= ~currCal->calData->calType;
646 currCal->calState = CAL_WAITING;
647
648 *isCalDone = B_FALSE;
649 }
650
651 void
ath9k_hw_start_nfcal(struct ath_hal * ah)652 ath9k_hw_start_nfcal(struct ath_hal *ah)
653 {
654 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
655 AR_PHY_AGC_CONTROL_ENABLE_NF);
656 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
657 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
658 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
659 }
660
661 /* ARGSUSED */
662 void
ath9k_hw_loadnf(struct ath_hal * ah,struct ath9k_channel * chan)663 ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
664 {
665 struct ath9k_nfcal_hist *h;
666 int i, j;
667 int32_t val;
668 const uint32_t ar5416_cca_regs[6] = {
669 AR_PHY_CCA,
670 AR_PHY_CH1_CCA,
671 AR_PHY_CH2_CCA,
672 AR_PHY_EXT_CCA,
673 AR_PHY_CH1_EXT_CCA,
674 AR_PHY_CH2_EXT_CCA
675 };
676 uint8_t chainmask;
677
678 if (AR_SREV_9280(ah))
679 chainmask = 0x1B;
680 else
681 chainmask = 0x3F;
682
683 #ifdef ARN_NF_PER_CHAN
684 h = chan->nfCalHist;
685 #else
686 h = ah->nfCalHist;
687 #endif
688
689 for (i = 0; i < NUM_NF_READINGS; i++) {
690 if (chainmask & (1 << i)) {
691 val = REG_READ(ah, ar5416_cca_regs[i]);
692 val &= 0xFFFFFE00;
693 val |= (((uint32_t)(h[i].privNF) << 1) & 0x1ff);
694 REG_WRITE(ah, ar5416_cca_regs[i], val);
695 }
696 }
697
698 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
699 AR_PHY_AGC_CONTROL_ENABLE_NF);
700 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
701 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
702 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
703
704 for (j = 0; j < 1000; j++) {
705 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
706 AR_PHY_AGC_CONTROL_NF) == 0)
707 break;
708 drv_usecwait(10);
709 }
710
711 for (i = 0; i < NUM_NF_READINGS; i++) {
712 if (chainmask & (1 << i)) {
713 val = REG_READ(ah, ar5416_cca_regs[i]);
714 val &= 0xFFFFFE00;
715 val |= (((uint32_t)(-50) << 1) & 0x1ff);
716 REG_WRITE(ah, ar5416_cca_regs[i], val);
717 }
718 }
719 }
720
721 int16_t
ath9k_hw_getnf(struct ath_hal * ah,struct ath9k_channel * chan)722 ath9k_hw_getnf(struct ath_hal *ah, struct ath9k_channel *chan)
723 {
724 int16_t nf, nfThresh;
725 int16_t nfarray[NUM_NF_READINGS] = { 0 };
726 struct ath9k_nfcal_hist *h;
727 /* LINTED E_FUNC_SET_NOT_USED */
728 uint8_t chainmask;
729
730 if (AR_SREV_9280(ah))
731 chainmask = 0x1B;
732 else
733 chainmask = 0x3F;
734
735 chan->channelFlags &= (~CHANNEL_CW_INT);
736 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
737 ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
738 "%s: NF did not complete in calibration window\n",
739 __func__));
740 nf = 0;
741 chan->rawNoiseFloor = nf;
742 return (chan->rawNoiseFloor);
743 } else {
744 ath9k_hw_do_getnf(ah, nfarray);
745 nf = nfarray[0];
746 if (getNoiseFloorThresh(ah, chan, &nfThresh) &&
747 nf > nfThresh) {
748 ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
749 "%s: noise floor failed detected; "
750 "detected %d, threshold %d\n", __func__,
751 nf, nfThresh));
752 chan->channelFlags |= CHANNEL_CW_INT;
753 }
754 }
755
756 #ifdef ARN_NF_PER_CHAN
757 h = chan->nfCalHist;
758 #else
759 h = ah->nfCalHist;
760 #endif
761
762 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
763 chan->rawNoiseFloor = h[0].privNF;
764
765 return (chan->rawNoiseFloor);
766 }
767
768 void
ath9k_init_nfcal_hist_buffer(struct ath_hal * ah)769 ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
770 {
771 int i, j;
772 int16_t noise_floor;
773
774 if (AR_SREV_9280(ah))
775 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
776 else if (AR_SREV_9285(ah))
777 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
778 else
779 noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
780
781 for (i = 0; i < NUM_NF_READINGS; i++) {
782 ah->nfCalHist[i].currIndex = 0;
783 ah->nfCalHist[i].privNF = noise_floor;
784 ah->nfCalHist[i].invalidNFcount =
785 AR_PHY_CCA_FILTERWINDOW_LENGTH;
786 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
787 ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
788 }
789 }
790 }
791
792 signed short
ath9k_hw_getchan_noise(struct ath_hal * ah,struct ath9k_channel * chan)793 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
794 {
795 struct ath9k_channel *ichan;
796 signed short nf;
797
798 ichan = ath9k_regd_check_channel(ah, chan);
799 if (ichan == NULL) {
800 ARN_DBG((ARN_DBG_CALIBRATE,
801 "%s: invalid channel %u/0x%x; no mapping\n",
802 __func__, chan->channel, chan->channelFlags));
803 return (ATH_DEFAULT_NOISE_FLOOR);
804 }
805 if (ichan->rawNoiseFloor == 0) {
806 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
807 nf = NOISE_FLOOR[mode];
808 } else
809 nf = ichan->rawNoiseFloor;
810
811 if (!ath9k_hw_nf_in_range(ah, nf))
812 nf = ATH_DEFAULT_NOISE_FLOOR;
813
814 return (nf);
815 }
816
817 boolean_t
ath9k_hw_calibrate(struct ath_hal * ah,struct ath9k_channel * chan,uint8_t rxchainmask,boolean_t longcal,boolean_t * isCalDone)818 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
819 uint8_t rxchainmask, boolean_t longcal,
820 boolean_t *isCalDone)
821 {
822 struct ath_hal_5416 *ahp = AH5416(ah);
823 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
824 struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
825
826 *isCalDone = B_TRUE;
827
828 if (ichan == NULL) {
829 ARN_DBG((ARN_DBG_CHANNEL,
830 "%s: invalid channel %u/0x%x; no mapping\n",
831 __func__, chan->channel, chan->channelFlags));
832 return (B_FALSE);
833 }
834
835 if (currCal &&
836 (currCal->calState == CAL_RUNNING ||
837 currCal->calState == CAL_WAITING)) {
838 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
839 isCalDone);
840 if (*isCalDone) {
841 ahp->ah_cal_list_curr = currCal = currCal->calNext;
842
843 if (currCal->calState == CAL_WAITING) {
844 *isCalDone = B_FALSE;
845 ath9k_hw_reset_calibration(ah, currCal);
846 }
847 }
848 }
849
850 if (longcal) {
851 (void) ath9k_hw_getnf(ah, ichan);
852 ath9k_hw_loadnf(ah, ah->ah_curchan);
853 ath9k_hw_start_nfcal(ah);
854
855 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
856 chan->channelFlags |= CHANNEL_CW_INT;
857 ichan->channelFlags &= ~CHANNEL_CW_INT;
858 }
859 }
860
861 return (B_TRUE);
862 }
863
864 /* AR9285 */
865 static inline void
ath9k_hw_9285_pa_cal(struct ath_hal * ah)866 ath9k_hw_9285_pa_cal(struct ath_hal *ah)
867 {
868
869 uint32_t regVal;
870 int i, offset, offs_6_1, offs_0;
871 uint32_t ccomp_org, reg_field;
872 uint32_t regList[][2] = {
873 { 0x786c, 0 },
874 { 0x7854, 0 },
875 { 0x7820, 0 },
876 { 0x7824, 0 },
877 { 0x7868, 0 },
878 { 0x783c, 0 },
879 { 0x7838, 0 },
880 };
881
882 if (AR_SREV_9285_11(ah)) {
883 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
884 drv_usecwait(10);
885 }
886
887 for (i = 0; i < ARRAY_SIZE(regList); i++)
888 regList[i][1] = REG_READ(ah, regList[i][0]);
889
890 regVal = REG_READ(ah, 0x7834);
891 regVal &= (~(0x1));
892 REG_WRITE(ah, 0x7834, regVal);
893 regVal = REG_READ(ah, 0x9808);
894 regVal |= (0x1 << 27);
895 REG_WRITE(ah, 0x9808, regVal);
896
897 REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
898 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
899 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
900 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
901 REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
902 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
903 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
904 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1);
905 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
906 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
907 REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
908 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
909 ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
910 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7);
911
912 REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
913 drv_usecwait(30);
914 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
915 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
916
917 for (i = 6; i > 0; i--) {
918 regVal = REG_READ(ah, 0x7834);
919 regVal |= (1 << (19 + i));
920 REG_WRITE(ah, 0x7834, regVal);
921 drv_usecwait(1);
922 regVal = REG_READ(ah, 0x7834);
923 regVal &= (~(0x1 << (19 + i)));
924 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
925 regVal |= (reg_field << (19 + i));
926 REG_WRITE(ah, 0x7834, regVal);
927 }
928
929 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
930 drv_usecwait(1);
931 reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
932 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
933 offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
934 offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
935
936 offset = (offs_6_1<<1) | offs_0;
937 offset = offset - 0;
938 offs_6_1 = offset>>1;
939 offs_0 = offset & 1;
940
941 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
942 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
943
944 regVal = REG_READ(ah, 0x7834);
945 regVal |= 0x1;
946 REG_WRITE(ah, 0x7834, regVal);
947 regVal = REG_READ(ah, 0x9808);
948 regVal &= (~(0x1 << 27));
949 REG_WRITE(ah, 0x9808, regVal);
950
951 for (i = 0; i < ARRAY_SIZE(regList); i++)
952 REG_WRITE(ah, regList[i][0], regList[i][1]);
953
954 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
955
956 if (AR_SREV_9285_11(ah))
957 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
958
959 }
960
961 boolean_t
ath9k_hw_init_cal(struct ath_hal * ah,struct ath9k_channel * chan)962 ath9k_hw_init_cal(struct ath_hal *ah,
963 struct ath9k_channel *chan)
964 {
965 struct ath_hal_5416 *ahp = AH5416(ah);
966 struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
967
968 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
969 REG_READ(ah, AR_PHY_AGC_CONTROL) |
970 AR_PHY_AGC_CONTROL_CAL);
971
972 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
973 ARN_DBG((ARN_DBG_CALIBRATE,
974 "%s: offset calibration failed to complete in 1ms; "
975 "noisy environment?\n", __func__));
976 return (B_FALSE);
977 }
978
979 if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
980 ath9k_hw_9285_pa_cal(ah);
981
982 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
983 REG_READ(ah, AR_PHY_AGC_CONTROL) |
984 AR_PHY_AGC_CONTROL_NF);
985
986 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
987
988 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
989 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
990 /* LINTED: E_CONSTANT_CONDITION */
991 INIT_CAL(&ahp->ah_adcGainCalData);
992 /* LINTED: E_CONSTANT_CONDITION */
993 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
994 ARN_DBG((ARN_DBG_CALIBRATE,
995 "%s: enabling ADC Gain Calibration.\n",
996 __func__));
997 }
998 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
999 /* LINTED: E_CONSTANT_CONDITION */
1000 INIT_CAL(&ahp->ah_adcDcCalData);
1001 /* LINTED: E_CONSTANT_CONDITION */
1002 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
1003 ARN_DBG((ARN_DBG_CALIBRATE,
1004 "%s: enabling ADC DC Calibration.\n",
1005 __func__));
1006 }
1007 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
1008 /* LINTED: E_CONSTANT_CONDITION */
1009 INIT_CAL(&ahp->ah_iqCalData);
1010 /* LINTED: E_CONSTANT_CONDITION */
1011 INSERT_CAL(ahp, &ahp->ah_iqCalData);
1012 ARN_DBG((ARN_DBG_CALIBRATE,
1013 "%s: enabling IQ Calibration.\n",
1014 __func__));
1015 }
1016
1017 ahp->ah_cal_list_curr = ahp->ah_cal_list;
1018
1019 if (ahp->ah_cal_list_curr)
1020 ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr);
1021 }
1022
1023 ichan->CalValid = 0;
1024
1025 return (B_TRUE);
1026 }
1027
1028 const struct hal_percal_data iq_cal_multi_sample = {
1029 IQ_MISMATCH_CAL,
1030 MAX_CAL_SAMPLES,
1031 PER_MIN_LOG_COUNT,
1032 ath9k_hw_iqcal_collect,
1033 ath9k_hw_iqcalibrate
1034 };
1035 const struct hal_percal_data iq_cal_single_sample = {
1036 IQ_MISMATCH_CAL,
1037 MIN_CAL_SAMPLES,
1038 PER_MAX_LOG_COUNT,
1039 ath9k_hw_iqcal_collect,
1040 ath9k_hw_iqcalibrate
1041 };
1042 const struct hal_percal_data adc_gain_cal_multi_sample = {
1043 ADC_GAIN_CAL,
1044 MAX_CAL_SAMPLES,
1045 PER_MIN_LOG_COUNT,
1046 ath9k_hw_adc_gaincal_collect,
1047 ath9k_hw_adc_gaincal_calibrate
1048 };
1049 const struct hal_percal_data adc_gain_cal_single_sample = {
1050 ADC_GAIN_CAL,
1051 MIN_CAL_SAMPLES,
1052 PER_MAX_LOG_COUNT,
1053 ath9k_hw_adc_gaincal_collect,
1054 ath9k_hw_adc_gaincal_calibrate
1055 };
1056 const struct hal_percal_data adc_dc_cal_multi_sample = {
1057 ADC_DC_CAL,
1058 MAX_CAL_SAMPLES,
1059 PER_MIN_LOG_COUNT,
1060 ath9k_hw_adc_dccal_collect,
1061 ath9k_hw_adc_dccal_calibrate
1062 };
1063 const struct hal_percal_data adc_dc_cal_single_sample = {
1064 ADC_DC_CAL,
1065 MIN_CAL_SAMPLES,
1066 PER_MAX_LOG_COUNT,
1067 ath9k_hw_adc_dccal_collect,
1068 ath9k_hw_adc_dccal_calibrate
1069 };
1070 const struct hal_percal_data adc_init_dc_cal = {
1071 ADC_DC_INIT_CAL,
1072 MIN_CAL_SAMPLES,
1073 INIT_LOG_COUNT,
1074 ath9k_hw_adc_dccal_collect,
1075 ath9k_hw_adc_dccal_calibrate
1076 };
1077