diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2008-10-29 00:46:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-10 15:16:05 -0500 |
commit | f1dc56003b23d2d5bb5a756de6b1633a76c9e697 (patch) | |
tree | f530aa716620322192bb0e7e083c903bf0e55544 /drivers/net/wireless/ath9k/calib.c | |
parent | 5640b08ef7e88b606c740e746cb77bc97d78508e (diff) |
ath9k: Refactor hw.c
Split hw.c into more manageable files:
ani.c
calib.c
eeprom.c
mac.c
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/calib.c')
-rw-r--r-- | drivers/net/wireless/ath9k/calib.c | 930 |
1 files changed, 930 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c new file mode 100644 index 000000000000..1690759fe7b8 --- /dev/null +++ b/drivers/net/wireless/ath9k/calib.c | |||
@@ -0,0 +1,930 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 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 "core.h" | ||
18 | #include "hw.h" | ||
19 | #include "reg.h" | ||
20 | #include "phy.h" | ||
21 | |||
22 | static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 }; | ||
23 | |||
24 | /* We can tune this as we go by monitoring really low values */ | ||
25 | #define ATH9K_NF_TOO_LOW -60 | ||
26 | |||
27 | /* AR5416 may return very high value (like -31 dBm), in those cases the nf | ||
28 | * is incorrect and we should use the static NF value. Later we can try to | ||
29 | * find out why they are reporting these values */ | ||
30 | |||
31 | static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf) | ||
32 | { | ||
33 | if (nf > ATH9K_NF_TOO_LOW) { | ||
34 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | ||
35 | "%s: noise floor value detected (%d) is " | ||
36 | "lower than what we think is a " | ||
37 | "reasonable value (%d)\n", | ||
38 | __func__, nf, ATH9K_NF_TOO_LOW); | ||
39 | return false; | ||
40 | } | ||
41 | return true; | ||
42 | } | ||
43 | |||
44 | static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) | ||
45 | { | ||
46 | int16_t nfval; | ||
47 | int16_t sort[ATH9K_NF_CAL_HIST_MAX]; | ||
48 | int i, j; | ||
49 | |||
50 | for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++) | ||
51 | sort[i] = nfCalBuffer[i]; | ||
52 | |||
53 | for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) { | ||
54 | for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) { | ||
55 | if (sort[j] > sort[j - 1]) { | ||
56 | nfval = sort[j]; | ||
57 | sort[j] = sort[j - 1]; | ||
58 | sort[j - 1] = nfval; | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1]; | ||
63 | |||
64 | return nfval; | ||
65 | } | ||
66 | |||
67 | static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, | ||
68 | int16_t *nfarray) | ||
69 | { | ||
70 | int i; | ||
71 | |||
72 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
73 | h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; | ||
74 | |||
75 | if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX) | ||
76 | h[i].currIndex = 0; | ||
77 | |||
78 | if (h[i].invalidNFcount > 0) { | ||
79 | if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE || | ||
80 | nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) { | ||
81 | h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX; | ||
82 | } else { | ||
83 | h[i].invalidNFcount--; | ||
84 | h[i].privNF = nfarray[i]; | ||
85 | } | ||
86 | } else { | ||
87 | h[i].privNF = | ||
88 | ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); | ||
89 | } | ||
90 | } | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | static void ath9k_hw_do_getnf(struct ath_hal *ah, | ||
95 | int16_t nfarray[NUM_NF_READINGS]) | ||
96 | { | ||
97 | int16_t nf; | ||
98 | |||
99 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
100 | nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); | ||
101 | else | ||
102 | nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); | ||
103 | |||
104 | if (nf & 0x100) | ||
105 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
106 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
107 | "NF calibrated [ctl] [chain 0] is %d\n", nf); | ||
108 | nfarray[0] = nf; | ||
109 | |||
110 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
111 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | ||
112 | AR9280_PHY_CH1_MINCCA_PWR); | ||
113 | else | ||
114 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | ||
115 | AR_PHY_CH1_MINCCA_PWR); | ||
116 | |||
117 | if (nf & 0x100) | ||
118 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
119 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | ||
120 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | ||
121 | nfarray[1] = nf; | ||
122 | |||
123 | if (!AR_SREV_9280(ah)) { | ||
124 | nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), | ||
125 | AR_PHY_CH2_MINCCA_PWR); | ||
126 | if (nf & 0x100) | ||
127 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
128 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | ||
129 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | ||
130 | nfarray[2] = nf; | ||
131 | } | ||
132 | |||
133 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
134 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), | ||
135 | AR9280_PHY_EXT_MINCCA_PWR); | ||
136 | else | ||
137 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), | ||
138 | AR_PHY_EXT_MINCCA_PWR); | ||
139 | |||
140 | if (nf & 0x100) | ||
141 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
142 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | ||
143 | "NF calibrated [ext] [chain 0] is %d\n", nf); | ||
144 | nfarray[3] = nf; | ||
145 | |||
146 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
147 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | ||
148 | AR9280_PHY_CH1_EXT_MINCCA_PWR); | ||
149 | else | ||
150 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | ||
151 | AR_PHY_CH1_EXT_MINCCA_PWR); | ||
152 | |||
153 | if (nf & 0x100) | ||
154 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
155 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
156 | "NF calibrated [ext] [chain 1] is %d\n", nf); | ||
157 | nfarray[4] = nf; | ||
158 | |||
159 | if (!AR_SREV_9280(ah)) { | ||
160 | nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), | ||
161 | AR_PHY_CH2_EXT_MINCCA_PWR); | ||
162 | if (nf & 0x100) | ||
163 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
164 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | ||
165 | "NF calibrated [ext] [chain 2] is %d\n", nf); | ||
166 | nfarray[5] = nf; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static bool getNoiseFloorThresh(struct ath_hal *ah, | ||
171 | const struct ath9k_channel *chan, | ||
172 | int16_t *nft) | ||
173 | { | ||
174 | switch (chan->chanmode) { | ||
175 | case CHANNEL_A: | ||
176 | case CHANNEL_A_HT20: | ||
177 | case CHANNEL_A_HT40PLUS: | ||
178 | case CHANNEL_A_HT40MINUS: | ||
179 | *nft = (int16_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5); | ||
180 | break; | ||
181 | case CHANNEL_B: | ||
182 | case CHANNEL_G: | ||
183 | case CHANNEL_G_HT20: | ||
184 | case CHANNEL_G_HT40PLUS: | ||
185 | case CHANNEL_G_HT40MINUS: | ||
186 | *nft = (int16_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2); | ||
187 | break; | ||
188 | default: | ||
189 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | ||
190 | "%s: invalid channel flags 0x%x\n", __func__, | ||
191 | chan->channelFlags); | ||
192 | return false; | ||
193 | } | ||
194 | |||
195 | return true; | ||
196 | } | ||
197 | |||
198 | static void ath9k_hw_setup_calibration(struct ath_hal *ah, | ||
199 | struct hal_cal_list *currCal) | ||
200 | { | ||
201 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), | ||
202 | AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, | ||
203 | currCal->calData->calCountMax); | ||
204 | |||
205 | switch (currCal->calData->calType) { | ||
206 | case IQ_MISMATCH_CAL: | ||
207 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | ||
208 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
209 | "%s: starting IQ Mismatch Calibration\n", | ||
210 | __func__); | ||
211 | break; | ||
212 | case ADC_GAIN_CAL: | ||
213 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); | ||
214 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
215 | "%s: starting ADC Gain Calibration\n", __func__); | ||
216 | break; | ||
217 | case ADC_DC_CAL: | ||
218 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); | ||
219 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
220 | "%s: starting ADC DC Calibration\n", __func__); | ||
221 | break; | ||
222 | case ADC_DC_INIT_CAL: | ||
223 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); | ||
224 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
225 | "%s: starting Init ADC DC Calibration\n", | ||
226 | __func__); | ||
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_hal *ah, | ||
235 | struct hal_cal_list *currCal) | ||
236 | { | ||
237 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
238 | int i; | ||
239 | |||
240 | ath9k_hw_setup_calibration(ah, currCal); | ||
241 | |||
242 | currCal->calState = CAL_RUNNING; | ||
243 | |||
244 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
245 | ahp->ah_Meas0.sign[i] = 0; | ||
246 | ahp->ah_Meas1.sign[i] = 0; | ||
247 | ahp->ah_Meas2.sign[i] = 0; | ||
248 | ahp->ah_Meas3.sign[i] = 0; | ||
249 | } | ||
250 | |||
251 | ahp->ah_CalSamples = 0; | ||
252 | } | ||
253 | |||
254 | static void ath9k_hw_per_calibration(struct ath_hal *ah, | ||
255 | struct ath9k_channel *ichan, | ||
256 | u8 rxchainmask, | ||
257 | struct hal_cal_list *currCal, | ||
258 | bool *isCalDone) | ||
259 | { | ||
260 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
261 | |||
262 | *isCalDone = false; | ||
263 | |||
264 | if (currCal->calState == CAL_RUNNING) { | ||
265 | if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & | ||
266 | AR_PHY_TIMING_CTRL4_DO_CAL)) { | ||
267 | |||
268 | currCal->calData->calCollect(ah); | ||
269 | ahp->ah_CalSamples++; | ||
270 | |||
271 | if (ahp->ah_CalSamples >= currCal->calData->calNumSamples) { | ||
272 | int i, numChains = 0; | ||
273 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
274 | if (rxchainmask & (1 << i)) | ||
275 | numChains++; | ||
276 | } | ||
277 | |||
278 | currCal->calData->calPostProc(ah, numChains); | ||
279 | ichan->CalValid |= currCal->calData->calType; | ||
280 | currCal->calState = CAL_DONE; | ||
281 | *isCalDone = true; | ||
282 | } else { | ||
283 | ath9k_hw_setup_calibration(ah, currCal); | ||
284 | } | ||
285 | } | ||
286 | } else if (!(ichan->CalValid & currCal->calData->calType)) { | ||
287 | ath9k_hw_reset_calibration(ah, currCal); | ||
288 | } | ||
289 | } | ||
290 | |||
291 | static bool ath9k_hw_iscal_supported(struct ath_hal *ah, | ||
292 | struct ath9k_channel *chan, | ||
293 | enum hal_cal_types calType) | ||
294 | { | ||
295 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
296 | bool retval = false; | ||
297 | |||
298 | switch (calType & ahp->ah_suppCals) { | ||
299 | case IQ_MISMATCH_CAL: | ||
300 | if (!IS_CHAN_B(chan)) | ||
301 | retval = true; | ||
302 | break; | ||
303 | case ADC_GAIN_CAL: | ||
304 | case ADC_DC_CAL: | ||
305 | if (!IS_CHAN_B(chan) | ||
306 | && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) | ||
307 | retval = true; | ||
308 | break; | ||
309 | } | ||
310 | |||
311 | return retval; | ||
312 | } | ||
313 | |||
314 | static void ath9k_hw_iqcal_collect(struct ath_hal *ah) | ||
315 | { | ||
316 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
317 | int i; | ||
318 | |||
319 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
320 | ahp->ah_totalPowerMeasI[i] += | ||
321 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
322 | ahp->ah_totalPowerMeasQ[i] += | ||
323 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
324 | ahp->ah_totalIqCorrMeas[i] += | ||
325 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
326 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
327 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | ||
328 | ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i], | ||
329 | ahp->ah_totalPowerMeasQ[i], | ||
330 | ahp->ah_totalIqCorrMeas[i]); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah) | ||
335 | { | ||
336 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
337 | int i; | ||
338 | |||
339 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
340 | ahp->ah_totalAdcIOddPhase[i] += | ||
341 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
342 | ahp->ah_totalAdcIEvenPhase[i] += | ||
343 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
344 | ahp->ah_totalAdcQOddPhase[i] += | ||
345 | REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
346 | ahp->ah_totalAdcQEvenPhase[i] += | ||
347 | REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | ||
348 | |||
349 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
350 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | ||
351 | "oddq=0x%08x; evenq=0x%08x;\n", | ||
352 | ahp->ah_CalSamples, i, | ||
353 | ahp->ah_totalAdcIOddPhase[i], | ||
354 | ahp->ah_totalAdcIEvenPhase[i], | ||
355 | ahp->ah_totalAdcQOddPhase[i], | ||
356 | ahp->ah_totalAdcQEvenPhase[i]); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah) | ||
361 | { | ||
362 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
363 | int i; | ||
364 | |||
365 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
366 | ahp->ah_totalAdcDcOffsetIOddPhase[i] += | ||
367 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
368 | ahp->ah_totalAdcDcOffsetIEvenPhase[i] += | ||
369 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
370 | ahp->ah_totalAdcDcOffsetQOddPhase[i] += | ||
371 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
372 | ahp->ah_totalAdcDcOffsetQEvenPhase[i] += | ||
373 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | ||
374 | |||
375 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
376 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | ||
377 | "oddq=0x%08x; evenq=0x%08x;\n", | ||
378 | ahp->ah_CalSamples, i, | ||
379 | ahp->ah_totalAdcDcOffsetIOddPhase[i], | ||
380 | ahp->ah_totalAdcDcOffsetIEvenPhase[i], | ||
381 | ahp->ah_totalAdcDcOffsetQOddPhase[i], | ||
382 | ahp->ah_totalAdcDcOffsetQEvenPhase[i]); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains) | ||
387 | { | ||
388 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
389 | u32 powerMeasQ, powerMeasI, iqCorrMeas; | ||
390 | u32 qCoffDenom, iCoffDenom; | ||
391 | int32_t qCoff, iCoff; | ||
392 | int iqCorrNeg, i; | ||
393 | |||
394 | for (i = 0; i < numChains; i++) { | ||
395 | powerMeasI = ahp->ah_totalPowerMeasI[i]; | ||
396 | powerMeasQ = ahp->ah_totalPowerMeasQ[i]; | ||
397 | iqCorrMeas = ahp->ah_totalIqCorrMeas[i]; | ||
398 | |||
399 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
400 | "Starting IQ Cal and Correction for Chain %d\n", | ||
401 | i); | ||
402 | |||
403 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
404 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", | ||
405 | i, ahp->ah_totalIqCorrMeas[i]); | ||
406 | |||
407 | iqCorrNeg = 0; | ||
408 | |||
409 | if (iqCorrMeas > 0x80000000) { | ||
410 | iqCorrMeas = (0xffffffff - iqCorrMeas) + 1; | ||
411 | iqCorrNeg = 1; | ||
412 | } | ||
413 | |||
414 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
415 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); | ||
416 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
417 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); | ||
418 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", | ||
419 | iqCorrNeg); | ||
420 | |||
421 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; | ||
422 | qCoffDenom = powerMeasQ / 64; | ||
423 | |||
424 | if (powerMeasQ != 0) { | ||
425 | iCoff = iqCorrMeas / iCoffDenom; | ||
426 | qCoff = powerMeasI / qCoffDenom - 64; | ||
427 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
428 | "Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
429 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
430 | "Chn %d qCoff = 0x%08x\n", i, qCoff); | ||
431 | |||
432 | iCoff = iCoff & 0x3f; | ||
433 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
434 | "New: Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
435 | if (iqCorrNeg == 0x0) | ||
436 | iCoff = 0x40 - iCoff; | ||
437 | |||
438 | if (qCoff > 15) | ||
439 | qCoff = 15; | ||
440 | else if (qCoff <= -16) | ||
441 | qCoff = 16; | ||
442 | |||
443 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
444 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", | ||
445 | i, iCoff, qCoff); | ||
446 | |||
447 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | ||
448 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, | ||
449 | iCoff); | ||
450 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | ||
451 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, | ||
452 | qCoff); | ||
453 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
454 | "IQ Cal and Correction done for Chain %d\n", | ||
455 | i); | ||
456 | } | ||
457 | } | ||
458 | |||
459 | REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), | ||
460 | AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); | ||
461 | } | ||
462 | |||
463 | static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains) | ||
464 | { | ||
465 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
466 | u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset; | ||
467 | u32 qGainMismatch, iGainMismatch, val, i; | ||
468 | |||
469 | for (i = 0; i < numChains; i++) { | ||
470 | iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i]; | ||
471 | iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i]; | ||
472 | qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i]; | ||
473 | qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i]; | ||
474 | |||
475 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
476 | "Starting ADC Gain Cal for Chain %d\n", i); | ||
477 | |||
478 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
479 | "Chn %d pwr_meas_odd_i = 0x%08x\n", i, | ||
480 | iOddMeasOffset); | ||
481 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
482 | "Chn %d pwr_meas_even_i = 0x%08x\n", i, | ||
483 | iEvenMeasOffset); | ||
484 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
485 | "Chn %d pwr_meas_odd_q = 0x%08x\n", i, | ||
486 | qOddMeasOffset); | ||
487 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
488 | "Chn %d pwr_meas_even_q = 0x%08x\n", i, | ||
489 | qEvenMeasOffset); | ||
490 | |||
491 | if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { | ||
492 | iGainMismatch = | ||
493 | ((iEvenMeasOffset * 32) / | ||
494 | iOddMeasOffset) & 0x3f; | ||
495 | qGainMismatch = | ||
496 | ((qOddMeasOffset * 32) / | ||
497 | qEvenMeasOffset) & 0x3f; | ||
498 | |||
499 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
500 | "Chn %d gain_mismatch_i = 0x%08x\n", i, | ||
501 | iGainMismatch); | ||
502 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
503 | "Chn %d gain_mismatch_q = 0x%08x\n", i, | ||
504 | qGainMismatch); | ||
505 | |||
506 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | ||
507 | val &= 0xfffff000; | ||
508 | val |= (qGainMismatch) | (iGainMismatch << 6); | ||
509 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | ||
510 | |||
511 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
512 | "ADC Gain Cal done for Chain %d\n", i); | ||
513 | } | ||
514 | } | ||
515 | |||
516 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | ||
517 | REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | | ||
518 | AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); | ||
519 | } | ||
520 | |||
521 | static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains) | ||
522 | { | ||
523 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
524 | u32 iOddMeasOffset, iEvenMeasOffset, val, i; | ||
525 | int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; | ||
526 | const struct hal_percal_data *calData = | ||
527 | ahp->ah_cal_list_curr->calData; | ||
528 | u32 numSamples = | ||
529 | (1 << (calData->calCountMax + 5)) * calData->calNumSamples; | ||
530 | |||
531 | for (i = 0; i < numChains; i++) { | ||
532 | iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i]; | ||
533 | iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i]; | ||
534 | qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i]; | ||
535 | qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i]; | ||
536 | |||
537 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
538 | "Starting ADC DC Offset Cal for Chain %d\n", i); | ||
539 | |||
540 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
541 | "Chn %d pwr_meas_odd_i = %d\n", i, | ||
542 | iOddMeasOffset); | ||
543 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
544 | "Chn %d pwr_meas_even_i = %d\n", i, | ||
545 | iEvenMeasOffset); | ||
546 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
547 | "Chn %d pwr_meas_odd_q = %d\n", i, | ||
548 | qOddMeasOffset); | ||
549 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
550 | "Chn %d pwr_meas_even_q = %d\n", i, | ||
551 | qEvenMeasOffset); | ||
552 | |||
553 | iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / | ||
554 | numSamples) & 0x1ff; | ||
555 | qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / | ||
556 | numSamples) & 0x1ff; | ||
557 | |||
558 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
559 | "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, | ||
560 | iDcMismatch); | ||
561 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
562 | "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, | ||
563 | qDcMismatch); | ||
564 | |||
565 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | ||
566 | val &= 0xc0000fff; | ||
567 | val |= (qDcMismatch << 12) | (iDcMismatch << 21); | ||
568 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | ||
569 | |||
570 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
571 | "ADC DC Offset Cal done for Chain %d\n", i); | ||
572 | } | ||
573 | |||
574 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | ||
575 | REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | | ||
576 | AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); | ||
577 | } | ||
578 | |||
579 | void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, | ||
580 | bool *isCalDone) | ||
581 | { | ||
582 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
583 | struct ath9k_channel *ichan = | ||
584 | ath9k_regd_check_channel(ah, chan); | ||
585 | struct hal_cal_list *currCal = ahp->ah_cal_list_curr; | ||
586 | |||
587 | *isCalDone = true; | ||
588 | |||
589 | if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) | ||
590 | return; | ||
591 | |||
592 | if (currCal == NULL) | ||
593 | return; | ||
594 | |||
595 | if (ichan == NULL) { | ||
596 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
597 | "%s: invalid channel %u/0x%x; no mapping\n", | ||
598 | __func__, chan->channel, chan->channelFlags); | ||
599 | return; | ||
600 | } | ||
601 | |||
602 | |||
603 | if (currCal->calState != CAL_DONE) { | ||
604 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
605 | "%s: Calibration state incorrect, %d\n", | ||
606 | __func__, currCal->calState); | ||
607 | return; | ||
608 | } | ||
609 | |||
610 | |||
611 | if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType)) | ||
612 | return; | ||
613 | |||
614 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
615 | "%s: Resetting Cal %d state for channel %u/0x%x\n", | ||
616 | __func__, currCal->calData->calType, chan->channel, | ||
617 | chan->channelFlags); | ||
618 | |||
619 | ichan->CalValid &= ~currCal->calData->calType; | ||
620 | currCal->calState = CAL_WAITING; | ||
621 | |||
622 | *isCalDone = false; | ||
623 | } | ||
624 | |||
625 | void ath9k_hw_start_nfcal(struct ath_hal *ah) | ||
626 | { | ||
627 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | ||
628 | AR_PHY_AGC_CONTROL_ENABLE_NF); | ||
629 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | ||
630 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | ||
631 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | ||
632 | } | ||
633 | |||
634 | void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan) | ||
635 | { | ||
636 | struct ath9k_nfcal_hist *h; | ||
637 | int i, j; | ||
638 | int32_t val; | ||
639 | const u32 ar5416_cca_regs[6] = { | ||
640 | AR_PHY_CCA, | ||
641 | AR_PHY_CH1_CCA, | ||
642 | AR_PHY_CH2_CCA, | ||
643 | AR_PHY_EXT_CCA, | ||
644 | AR_PHY_CH1_EXT_CCA, | ||
645 | AR_PHY_CH2_EXT_CCA | ||
646 | }; | ||
647 | u8 chainmask; | ||
648 | |||
649 | if (AR_SREV_9280(ah)) | ||
650 | chainmask = 0x1B; | ||
651 | else | ||
652 | chainmask = 0x3F; | ||
653 | |||
654 | #ifdef ATH_NF_PER_CHAN | ||
655 | h = chan->nfCalHist; | ||
656 | #else | ||
657 | h = ah->nfCalHist; | ||
658 | #endif | ||
659 | |||
660 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
661 | if (chainmask & (1 << i)) { | ||
662 | val = REG_READ(ah, ar5416_cca_regs[i]); | ||
663 | val &= 0xFFFFFE00; | ||
664 | val |= (((u32) (h[i].privNF) << 1) & 0x1ff); | ||
665 | REG_WRITE(ah, ar5416_cca_regs[i], val); | ||
666 | } | ||
667 | } | ||
668 | |||
669 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
670 | AR_PHY_AGC_CONTROL_ENABLE_NF); | ||
671 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
672 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | ||
673 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | ||
674 | |||
675 | for (j = 0; j < 1000; j++) { | ||
676 | if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & | ||
677 | AR_PHY_AGC_CONTROL_NF) == 0) | ||
678 | break; | ||
679 | udelay(10); | ||
680 | } | ||
681 | |||
682 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
683 | if (chainmask & (1 << i)) { | ||
684 | val = REG_READ(ah, ar5416_cca_regs[i]); | ||
685 | val &= 0xFFFFFE00; | ||
686 | val |= (((u32) (-50) << 1) & 0x1ff); | ||
687 | REG_WRITE(ah, ar5416_cca_regs[i], val); | ||
688 | } | ||
689 | } | ||
690 | } | ||
691 | |||
692 | int16_t ath9k_hw_getnf(struct ath_hal *ah, | ||
693 | struct ath9k_channel *chan) | ||
694 | { | ||
695 | int16_t nf, nfThresh; | ||
696 | int16_t nfarray[NUM_NF_READINGS] = { 0 }; | ||
697 | struct ath9k_nfcal_hist *h; | ||
698 | u8 chainmask; | ||
699 | |||
700 | if (AR_SREV_9280(ah)) | ||
701 | chainmask = 0x1B; | ||
702 | else | ||
703 | chainmask = 0x3F; | ||
704 | |||
705 | chan->channelFlags &= (~CHANNEL_CW_INT); | ||
706 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { | ||
707 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
708 | "%s: NF did not complete in calibration window\n", | ||
709 | __func__); | ||
710 | nf = 0; | ||
711 | chan->rawNoiseFloor = nf; | ||
712 | return chan->rawNoiseFloor; | ||
713 | } else { | ||
714 | ath9k_hw_do_getnf(ah, nfarray); | ||
715 | nf = nfarray[0]; | ||
716 | if (getNoiseFloorThresh(ah, chan, &nfThresh) | ||
717 | && nf > nfThresh) { | ||
718 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
719 | "%s: noise floor failed detected; " | ||
720 | "detected %d, threshold %d\n", __func__, | ||
721 | nf, nfThresh); | ||
722 | chan->channelFlags |= CHANNEL_CW_INT; | ||
723 | } | ||
724 | } | ||
725 | |||
726 | #ifdef ATH_NF_PER_CHAN | ||
727 | h = chan->nfCalHist; | ||
728 | #else | ||
729 | h = ah->nfCalHist; | ||
730 | #endif | ||
731 | |||
732 | ath9k_hw_update_nfcal_hist_buffer(h, nfarray); | ||
733 | chan->rawNoiseFloor = h[0].privNF; | ||
734 | |||
735 | return chan->rawNoiseFloor; | ||
736 | } | ||
737 | |||
738 | void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah) | ||
739 | { | ||
740 | int i, j; | ||
741 | |||
742 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
743 | ah->nfCalHist[i].currIndex = 0; | ||
744 | ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE; | ||
745 | ah->nfCalHist[i].invalidNFcount = | ||
746 | AR_PHY_CCA_FILTERWINDOW_LENGTH; | ||
747 | for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { | ||
748 | ah->nfCalHist[i].nfCalBuffer[j] = | ||
749 | AR_PHY_CCA_MAX_GOOD_VALUE; | ||
750 | } | ||
751 | } | ||
752 | return; | ||
753 | } | ||
754 | |||
755 | s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) | ||
756 | { | ||
757 | struct ath9k_channel *ichan; | ||
758 | s16 nf; | ||
759 | |||
760 | ichan = ath9k_regd_check_channel(ah, chan); | ||
761 | if (ichan == NULL) { | ||
762 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | ||
763 | "%s: invalid channel %u/0x%x; no mapping\n", | ||
764 | __func__, chan->channel, chan->channelFlags); | ||
765 | return ATH_DEFAULT_NOISE_FLOOR; | ||
766 | } | ||
767 | if (ichan->rawNoiseFloor == 0) { | ||
768 | enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan); | ||
769 | nf = NOISE_FLOOR[mode]; | ||
770 | } else | ||
771 | nf = ichan->rawNoiseFloor; | ||
772 | |||
773 | if (!ath9k_hw_nf_in_range(ah, nf)) | ||
774 | nf = ATH_DEFAULT_NOISE_FLOOR; | ||
775 | |||
776 | return nf; | ||
777 | } | ||
778 | |||
779 | bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, | ||
780 | u8 rxchainmask, bool longcal, | ||
781 | bool *isCalDone) | ||
782 | { | ||
783 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
784 | struct hal_cal_list *currCal = ahp->ah_cal_list_curr; | ||
785 | struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); | ||
786 | |||
787 | *isCalDone = true; | ||
788 | |||
789 | if (ichan == NULL) { | ||
790 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | ||
791 | "%s: invalid channel %u/0x%x; no mapping\n", | ||
792 | __func__, chan->channel, chan->channelFlags); | ||
793 | return false; | ||
794 | } | ||
795 | |||
796 | if (currCal && | ||
797 | (currCal->calState == CAL_RUNNING || | ||
798 | currCal->calState == CAL_WAITING)) { | ||
799 | ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal, | ||
800 | isCalDone); | ||
801 | if (*isCalDone) { | ||
802 | ahp->ah_cal_list_curr = currCal = currCal->calNext; | ||
803 | |||
804 | if (currCal->calState == CAL_WAITING) { | ||
805 | *isCalDone = false; | ||
806 | ath9k_hw_reset_calibration(ah, currCal); | ||
807 | } | ||
808 | } | ||
809 | } | ||
810 | |||
811 | if (longcal) { | ||
812 | ath9k_hw_getnf(ah, ichan); | ||
813 | ath9k_hw_loadnf(ah, ah->ah_curchan); | ||
814 | ath9k_hw_start_nfcal(ah); | ||
815 | |||
816 | if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) { | ||
817 | chan->channelFlags |= CHANNEL_CW_INT; | ||
818 | ichan->channelFlags &= ~CHANNEL_CW_INT; | ||
819 | } | ||
820 | } | ||
821 | |||
822 | return true; | ||
823 | } | ||
824 | |||
825 | bool ath9k_hw_init_cal(struct ath_hal *ah, | ||
826 | struct ath9k_channel *chan) | ||
827 | { | ||
828 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
829 | struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); | ||
830 | |||
831 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
832 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
833 | AR_PHY_AGC_CONTROL_CAL); | ||
834 | |||
835 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { | ||
836 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
837 | "%s: offset calibration failed to complete in 1ms; " | ||
838 | "noisy environment?\n", __func__); | ||
839 | return false; | ||
840 | } | ||
841 | |||
842 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
843 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
844 | AR_PHY_AGC_CONTROL_NF); | ||
845 | |||
846 | ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL; | ||
847 | |||
848 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { | ||
849 | if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) { | ||
850 | INIT_CAL(&ahp->ah_adcGainCalData); | ||
851 | INSERT_CAL(ahp, &ahp->ah_adcGainCalData); | ||
852 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
853 | "%s: enabling ADC Gain Calibration.\n", | ||
854 | __func__); | ||
855 | } | ||
856 | if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) { | ||
857 | INIT_CAL(&ahp->ah_adcDcCalData); | ||
858 | INSERT_CAL(ahp, &ahp->ah_adcDcCalData); | ||
859 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
860 | "%s: enabling ADC DC Calibration.\n", | ||
861 | __func__); | ||
862 | } | ||
863 | if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) { | ||
864 | INIT_CAL(&ahp->ah_iqCalData); | ||
865 | INSERT_CAL(ahp, &ahp->ah_iqCalData); | ||
866 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
867 | "%s: enabling IQ Calibration.\n", | ||
868 | __func__); | ||
869 | } | ||
870 | |||
871 | ahp->ah_cal_list_curr = ahp->ah_cal_list; | ||
872 | |||
873 | if (ahp->ah_cal_list_curr) | ||
874 | ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr); | ||
875 | } | ||
876 | |||
877 | ichan->CalValid = 0; | ||
878 | |||
879 | return true; | ||
880 | } | ||
881 | |||
882 | const struct hal_percal_data iq_cal_multi_sample = { | ||
883 | IQ_MISMATCH_CAL, | ||
884 | MAX_CAL_SAMPLES, | ||
885 | PER_MIN_LOG_COUNT, | ||
886 | ath9k_hw_iqcal_collect, | ||
887 | ath9k_hw_iqcalibrate | ||
888 | }; | ||
889 | const struct hal_percal_data iq_cal_single_sample = { | ||
890 | IQ_MISMATCH_CAL, | ||
891 | MIN_CAL_SAMPLES, | ||
892 | PER_MAX_LOG_COUNT, | ||
893 | ath9k_hw_iqcal_collect, | ||
894 | ath9k_hw_iqcalibrate | ||
895 | }; | ||
896 | const struct hal_percal_data adc_gain_cal_multi_sample = { | ||
897 | ADC_GAIN_CAL, | ||
898 | MAX_CAL_SAMPLES, | ||
899 | PER_MIN_LOG_COUNT, | ||
900 | ath9k_hw_adc_gaincal_collect, | ||
901 | ath9k_hw_adc_gaincal_calibrate | ||
902 | }; | ||
903 | const struct hal_percal_data adc_gain_cal_single_sample = { | ||
904 | ADC_GAIN_CAL, | ||
905 | MIN_CAL_SAMPLES, | ||
906 | PER_MAX_LOG_COUNT, | ||
907 | ath9k_hw_adc_gaincal_collect, | ||
908 | ath9k_hw_adc_gaincal_calibrate | ||
909 | }; | ||
910 | const struct hal_percal_data adc_dc_cal_multi_sample = { | ||
911 | ADC_DC_CAL, | ||
912 | MAX_CAL_SAMPLES, | ||
913 | PER_MIN_LOG_COUNT, | ||
914 | ath9k_hw_adc_dccal_collect, | ||
915 | ath9k_hw_adc_dccal_calibrate | ||
916 | }; | ||
917 | const struct hal_percal_data adc_dc_cal_single_sample = { | ||
918 | ADC_DC_CAL, | ||
919 | MIN_CAL_SAMPLES, | ||
920 | PER_MAX_LOG_COUNT, | ||
921 | ath9k_hw_adc_dccal_collect, | ||
922 | ath9k_hw_adc_dccal_calibrate | ||
923 | }; | ||
924 | const struct hal_percal_data adc_init_dc_cal = { | ||
925 | ADC_DC_INIT_CAL, | ||
926 | MIN_CAL_SAMPLES, | ||
927 | INIT_LOG_COUNT, | ||
928 | ath9k_hw_adc_dccal_collect, | ||
929 | ath9k_hw_adc_dccal_calibrate | ||
930 | }; | ||