diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ath/ath9k/calib.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/calib.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/calib.c | 421 |
1 files changed, 235 insertions, 186 deletions
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 0ad6d0b76e9e..238a5744d8e9 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "ath9k.h" | 17 | #include "hw.h" |
18 | 18 | ||
19 | /* We can tune this as we go by monitoring really low values */ | 19 | /* We can tune this as we go by monitoring really low values */ |
20 | #define ATH9K_NF_TOO_LOW -60 | 20 | #define ATH9K_NF_TOO_LOW -60 |
@@ -26,11 +26,11 @@ | |||
26 | static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf) | 26 | static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf) |
27 | { | 27 | { |
28 | if (nf > ATH9K_NF_TOO_LOW) { | 28 | if (nf > ATH9K_NF_TOO_LOW) { |
29 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 29 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, |
30 | "noise floor value detected (%d) is " | 30 | "noise floor value detected (%d) is " |
31 | "lower than what we think is a " | 31 | "lower than what we think is a " |
32 | "reasonable value (%d)\n", | 32 | "reasonable value (%d)\n", |
33 | nf, ATH9K_NF_TOO_LOW); | 33 | nf, ATH9K_NF_TOO_LOW); |
34 | return false; | 34 | return false; |
35 | } | 35 | } |
36 | return true; | 36 | return true; |
@@ -89,6 +89,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, | |||
89 | static void ath9k_hw_do_getnf(struct ath_hw *ah, | 89 | static void ath9k_hw_do_getnf(struct ath_hw *ah, |
90 | int16_t nfarray[NUM_NF_READINGS]) | 90 | int16_t nfarray[NUM_NF_READINGS]) |
91 | { | 91 | { |
92 | struct ath_common *common = ath9k_hw_common(ah); | ||
92 | int16_t nf; | 93 | int16_t nf; |
93 | 94 | ||
94 | if (AR_SREV_9280_10_OR_LATER(ah)) | 95 | if (AR_SREV_9280_10_OR_LATER(ah)) |
@@ -98,8 +99,8 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah, | |||
98 | 99 | ||
99 | if (nf & 0x100) | 100 | if (nf & 0x100) |
100 | nf = 0 - ((nf ^ 0x1ff) + 1); | 101 | nf = 0 - ((nf ^ 0x1ff) + 1); |
101 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 102 | ath_print(common, ATH_DBG_CALIBRATE, |
102 | "NF calibrated [ctl] [chain 0] is %d\n", nf); | 103 | "NF calibrated [ctl] [chain 0] is %d\n", nf); |
103 | nfarray[0] = nf; | 104 | nfarray[0] = nf; |
104 | 105 | ||
105 | if (!AR_SREV_9285(ah)) { | 106 | if (!AR_SREV_9285(ah)) { |
@@ -112,8 +113,8 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah, | |||
112 | 113 | ||
113 | if (nf & 0x100) | 114 | if (nf & 0x100) |
114 | nf = 0 - ((nf ^ 0x1ff) + 1); | 115 | nf = 0 - ((nf ^ 0x1ff) + 1); |
115 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 116 | ath_print(common, ATH_DBG_CALIBRATE, |
116 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | 117 | "NF calibrated [ctl] [chain 1] is %d\n", nf); |
117 | nfarray[1] = nf; | 118 | nfarray[1] = nf; |
118 | 119 | ||
119 | if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) { | 120 | if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) { |
@@ -121,8 +122,8 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah, | |||
121 | AR_PHY_CH2_MINCCA_PWR); | 122 | AR_PHY_CH2_MINCCA_PWR); |
122 | if (nf & 0x100) | 123 | if (nf & 0x100) |
123 | nf = 0 - ((nf ^ 0x1ff) + 1); | 124 | nf = 0 - ((nf ^ 0x1ff) + 1); |
124 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 125 | ath_print(common, ATH_DBG_CALIBRATE, |
125 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | 126 | "NF calibrated [ctl] [chain 2] is %d\n", nf); |
126 | nfarray[2] = nf; | 127 | nfarray[2] = nf; |
127 | } | 128 | } |
128 | } | 129 | } |
@@ -136,8 +137,8 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah, | |||
136 | 137 | ||
137 | if (nf & 0x100) | 138 | if (nf & 0x100) |
138 | nf = 0 - ((nf ^ 0x1ff) + 1); | 139 | nf = 0 - ((nf ^ 0x1ff) + 1); |
139 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 140 | ath_print(common, ATH_DBG_CALIBRATE, |
140 | "NF calibrated [ext] [chain 0] is %d\n", nf); | 141 | "NF calibrated [ext] [chain 0] is %d\n", nf); |
141 | nfarray[3] = nf; | 142 | nfarray[3] = nf; |
142 | 143 | ||
143 | if (!AR_SREV_9285(ah)) { | 144 | if (!AR_SREV_9285(ah)) { |
@@ -150,8 +151,8 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah, | |||
150 | 151 | ||
151 | if (nf & 0x100) | 152 | if (nf & 0x100) |
152 | nf = 0 - ((nf ^ 0x1ff) + 1); | 153 | nf = 0 - ((nf ^ 0x1ff) + 1); |
153 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 154 | ath_print(common, ATH_DBG_CALIBRATE, |
154 | "NF calibrated [ext] [chain 1] is %d\n", nf); | 155 | "NF calibrated [ext] [chain 1] is %d\n", nf); |
155 | nfarray[4] = nf; | 156 | nfarray[4] = nf; |
156 | 157 | ||
157 | if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) { | 158 | if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) { |
@@ -159,8 +160,8 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah, | |||
159 | AR_PHY_CH2_EXT_MINCCA_PWR); | 160 | AR_PHY_CH2_EXT_MINCCA_PWR); |
160 | if (nf & 0x100) | 161 | if (nf & 0x100) |
161 | nf = 0 - ((nf ^ 0x1ff) + 1); | 162 | nf = 0 - ((nf ^ 0x1ff) + 1); |
162 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 163 | ath_print(common, ATH_DBG_CALIBRATE, |
163 | "NF calibrated [ext] [chain 2] is %d\n", nf); | 164 | "NF calibrated [ext] [chain 2] is %d\n", nf); |
164 | nfarray[5] = nf; | 165 | nfarray[5] = nf; |
165 | } | 166 | } |
166 | } | 167 | } |
@@ -188,6 +189,8 @@ static bool getNoiseFloorThresh(struct ath_hw *ah, | |||
188 | static void ath9k_hw_setup_calibration(struct ath_hw *ah, | 189 | static void ath9k_hw_setup_calibration(struct ath_hw *ah, |
189 | struct ath9k_cal_list *currCal) | 190 | struct ath9k_cal_list *currCal) |
190 | { | 191 | { |
192 | struct ath_common *common = ath9k_hw_common(ah); | ||
193 | |||
191 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), | 194 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), |
192 | AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, | 195 | AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, |
193 | currCal->calData->calCountMax); | 196 | currCal->calData->calCountMax); |
@@ -195,23 +198,23 @@ static void ath9k_hw_setup_calibration(struct ath_hw *ah, | |||
195 | switch (currCal->calData->calType) { | 198 | switch (currCal->calData->calType) { |
196 | case IQ_MISMATCH_CAL: | 199 | case IQ_MISMATCH_CAL: |
197 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | 200 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); |
198 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 201 | ath_print(common, ATH_DBG_CALIBRATE, |
199 | "starting IQ Mismatch Calibration\n"); | 202 | "starting IQ Mismatch Calibration\n"); |
200 | break; | 203 | break; |
201 | case ADC_GAIN_CAL: | 204 | case ADC_GAIN_CAL: |
202 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); | 205 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); |
203 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 206 | ath_print(common, ATH_DBG_CALIBRATE, |
204 | "starting ADC Gain Calibration\n"); | 207 | "starting ADC Gain Calibration\n"); |
205 | break; | 208 | break; |
206 | case ADC_DC_CAL: | 209 | case ADC_DC_CAL: |
207 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); | 210 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); |
208 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 211 | ath_print(common, ATH_DBG_CALIBRATE, |
209 | "starting ADC DC Calibration\n"); | 212 | "starting ADC DC Calibration\n"); |
210 | break; | 213 | break; |
211 | case ADC_DC_INIT_CAL: | 214 | case ADC_DC_INIT_CAL: |
212 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); | 215 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); |
213 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 216 | ath_print(common, ATH_DBG_CALIBRATE, |
214 | "starting Init ADC DC Calibration\n"); | 217 | "starting Init ADC DC Calibration\n"); |
215 | break; | 218 | break; |
216 | } | 219 | } |
217 | 220 | ||
@@ -278,7 +281,7 @@ static bool ath9k_hw_per_calibration(struct ath_hw *ah, | |||
278 | static bool ath9k_hw_iscal_supported(struct ath_hw *ah, | 281 | static bool ath9k_hw_iscal_supported(struct ath_hw *ah, |
279 | enum ath9k_cal_types calType) | 282 | enum ath9k_cal_types calType) |
280 | { | 283 | { |
281 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | 284 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
282 | 285 | ||
283 | switch (calType & ah->supp_cals) { | 286 | switch (calType & ah->supp_cals) { |
284 | case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ | 287 | case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ |
@@ -304,11 +307,11 @@ static void ath9k_hw_iqcal_collect(struct ath_hw *ah) | |||
304 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | 307 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); |
305 | ah->totalIqCorrMeas[i] += | 308 | ah->totalIqCorrMeas[i] += |
306 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | 309 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); |
307 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 310 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, |
308 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | 311 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", |
309 | ah->cal_samples, i, ah->totalPowerMeasI[i], | 312 | ah->cal_samples, i, ah->totalPowerMeasI[i], |
310 | ah->totalPowerMeasQ[i], | 313 | ah->totalPowerMeasQ[i], |
311 | ah->totalIqCorrMeas[i]); | 314 | ah->totalIqCorrMeas[i]); |
312 | } | 315 | } |
313 | } | 316 | } |
314 | 317 | ||
@@ -326,14 +329,14 @@ static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah) | |||
326 | ah->totalAdcQEvenPhase[i] += | 329 | ah->totalAdcQEvenPhase[i] += |
327 | REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | 330 | REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); |
328 | 331 | ||
329 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 332 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, |
330 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | 333 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " |
331 | "oddq=0x%08x; evenq=0x%08x;\n", | 334 | "oddq=0x%08x; evenq=0x%08x;\n", |
332 | ah->cal_samples, i, | 335 | ah->cal_samples, i, |
333 | ah->totalAdcIOddPhase[i], | 336 | ah->totalAdcIOddPhase[i], |
334 | ah->totalAdcIEvenPhase[i], | 337 | ah->totalAdcIEvenPhase[i], |
335 | ah->totalAdcQOddPhase[i], | 338 | ah->totalAdcQOddPhase[i], |
336 | ah->totalAdcQEvenPhase[i]); | 339 | ah->totalAdcQEvenPhase[i]); |
337 | } | 340 | } |
338 | } | 341 | } |
339 | 342 | ||
@@ -351,19 +354,20 @@ static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah) | |||
351 | ah->totalAdcDcOffsetQEvenPhase[i] += | 354 | ah->totalAdcDcOffsetQEvenPhase[i] += |
352 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | 355 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); |
353 | 356 | ||
354 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 357 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, |
355 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | 358 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " |
356 | "oddq=0x%08x; evenq=0x%08x;\n", | 359 | "oddq=0x%08x; evenq=0x%08x;\n", |
357 | ah->cal_samples, i, | 360 | ah->cal_samples, i, |
358 | ah->totalAdcDcOffsetIOddPhase[i], | 361 | ah->totalAdcDcOffsetIOddPhase[i], |
359 | ah->totalAdcDcOffsetIEvenPhase[i], | 362 | ah->totalAdcDcOffsetIEvenPhase[i], |
360 | ah->totalAdcDcOffsetQOddPhase[i], | 363 | ah->totalAdcDcOffsetQOddPhase[i], |
361 | ah->totalAdcDcOffsetQEvenPhase[i]); | 364 | ah->totalAdcDcOffsetQEvenPhase[i]); |
362 | } | 365 | } |
363 | } | 366 | } |
364 | 367 | ||
365 | static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | 368 | static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) |
366 | { | 369 | { |
370 | struct ath_common *common = ath9k_hw_common(ah); | ||
367 | u32 powerMeasQ, powerMeasI, iqCorrMeas; | 371 | u32 powerMeasQ, powerMeasI, iqCorrMeas; |
368 | u32 qCoffDenom, iCoffDenom; | 372 | u32 qCoffDenom, iCoffDenom; |
369 | int32_t qCoff, iCoff; | 373 | int32_t qCoff, iCoff; |
@@ -374,13 +378,13 @@ static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
374 | powerMeasQ = ah->totalPowerMeasQ[i]; | 378 | powerMeasQ = ah->totalPowerMeasQ[i]; |
375 | iqCorrMeas = ah->totalIqCorrMeas[i]; | 379 | iqCorrMeas = ah->totalIqCorrMeas[i]; |
376 | 380 | ||
377 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 381 | ath_print(common, ATH_DBG_CALIBRATE, |
378 | "Starting IQ Cal and Correction for Chain %d\n", | 382 | "Starting IQ Cal and Correction for Chain %d\n", |
379 | i); | 383 | i); |
380 | 384 | ||
381 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 385 | ath_print(common, ATH_DBG_CALIBRATE, |
382 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", | 386 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", |
383 | i, ah->totalIqCorrMeas[i]); | 387 | i, ah->totalIqCorrMeas[i]); |
384 | 388 | ||
385 | iqCorrNeg = 0; | 389 | iqCorrNeg = 0; |
386 | 390 | ||
@@ -389,27 +393,28 @@ static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
389 | iqCorrNeg = 1; | 393 | iqCorrNeg = 1; |
390 | } | 394 | } |
391 | 395 | ||
392 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 396 | ath_print(common, ATH_DBG_CALIBRATE, |
393 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); | 397 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); |
394 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 398 | ath_print(common, ATH_DBG_CALIBRATE, |
395 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); | 399 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); |
396 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", | 400 | ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", |
397 | iqCorrNeg); | 401 | iqCorrNeg); |
398 | 402 | ||
399 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; | 403 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; |
400 | qCoffDenom = powerMeasQ / 64; | 404 | qCoffDenom = powerMeasQ / 64; |
401 | 405 | ||
402 | if (powerMeasQ != 0) { | 406 | if ((powerMeasQ != 0) && (iCoffDenom != 0) && |
407 | (qCoffDenom != 0)) { | ||
403 | iCoff = iqCorrMeas / iCoffDenom; | 408 | iCoff = iqCorrMeas / iCoffDenom; |
404 | qCoff = powerMeasI / qCoffDenom - 64; | 409 | qCoff = powerMeasI / qCoffDenom - 64; |
405 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 410 | ath_print(common, ATH_DBG_CALIBRATE, |
406 | "Chn %d iCoff = 0x%08x\n", i, iCoff); | 411 | "Chn %d iCoff = 0x%08x\n", i, iCoff); |
407 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 412 | ath_print(common, ATH_DBG_CALIBRATE, |
408 | "Chn %d qCoff = 0x%08x\n", i, qCoff); | 413 | "Chn %d qCoff = 0x%08x\n", i, qCoff); |
409 | 414 | ||
410 | iCoff = iCoff & 0x3f; | 415 | iCoff = iCoff & 0x3f; |
411 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 416 | ath_print(common, ATH_DBG_CALIBRATE, |
412 | "New: Chn %d iCoff = 0x%08x\n", i, iCoff); | 417 | "New: Chn %d iCoff = 0x%08x\n", i, iCoff); |
413 | if (iqCorrNeg == 0x0) | 418 | if (iqCorrNeg == 0x0) |
414 | iCoff = 0x40 - iCoff; | 419 | iCoff = 0x40 - iCoff; |
415 | 420 | ||
@@ -418,9 +423,9 @@ static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
418 | else if (qCoff <= -16) | 423 | else if (qCoff <= -16) |
419 | qCoff = 16; | 424 | qCoff = 16; |
420 | 425 | ||
421 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 426 | ath_print(common, ATH_DBG_CALIBRATE, |
422 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", | 427 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", |
423 | i, iCoff, qCoff); | 428 | i, iCoff, qCoff); |
424 | 429 | ||
425 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | 430 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), |
426 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, | 431 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, |
@@ -428,9 +433,9 @@ static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
428 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | 433 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), |
429 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, | 434 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, |
430 | qCoff); | 435 | qCoff); |
431 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 436 | ath_print(common, ATH_DBG_CALIBRATE, |
432 | "IQ Cal and Correction done for Chain %d\n", | 437 | "IQ Cal and Correction done for Chain %d\n", |
433 | i); | 438 | i); |
434 | } | 439 | } |
435 | } | 440 | } |
436 | 441 | ||
@@ -440,6 +445,7 @@ static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
440 | 445 | ||
441 | static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | 446 | static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) |
442 | { | 447 | { |
448 | struct ath_common *common = ath9k_hw_common(ah); | ||
443 | u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset; | 449 | u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset; |
444 | u32 qGainMismatch, iGainMismatch, val, i; | 450 | u32 qGainMismatch, iGainMismatch, val, i; |
445 | 451 | ||
@@ -449,21 +455,21 @@ static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | |||
449 | qOddMeasOffset = ah->totalAdcQOddPhase[i]; | 455 | qOddMeasOffset = ah->totalAdcQOddPhase[i]; |
450 | qEvenMeasOffset = ah->totalAdcQEvenPhase[i]; | 456 | qEvenMeasOffset = ah->totalAdcQEvenPhase[i]; |
451 | 457 | ||
452 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 458 | ath_print(common, ATH_DBG_CALIBRATE, |
453 | "Starting ADC Gain Cal for Chain %d\n", i); | 459 | "Starting ADC Gain Cal for Chain %d\n", i); |
454 | 460 | ||
455 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 461 | ath_print(common, ATH_DBG_CALIBRATE, |
456 | "Chn %d pwr_meas_odd_i = 0x%08x\n", i, | 462 | "Chn %d pwr_meas_odd_i = 0x%08x\n", i, |
457 | iOddMeasOffset); | 463 | iOddMeasOffset); |
458 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 464 | ath_print(common, ATH_DBG_CALIBRATE, |
459 | "Chn %d pwr_meas_even_i = 0x%08x\n", i, | 465 | "Chn %d pwr_meas_even_i = 0x%08x\n", i, |
460 | iEvenMeasOffset); | 466 | iEvenMeasOffset); |
461 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 467 | ath_print(common, ATH_DBG_CALIBRATE, |
462 | "Chn %d pwr_meas_odd_q = 0x%08x\n", i, | 468 | "Chn %d pwr_meas_odd_q = 0x%08x\n", i, |
463 | qOddMeasOffset); | 469 | qOddMeasOffset); |
464 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 470 | ath_print(common, ATH_DBG_CALIBRATE, |
465 | "Chn %d pwr_meas_even_q = 0x%08x\n", i, | 471 | "Chn %d pwr_meas_even_q = 0x%08x\n", i, |
466 | qEvenMeasOffset); | 472 | qEvenMeasOffset); |
467 | 473 | ||
468 | if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { | 474 | if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { |
469 | iGainMismatch = | 475 | iGainMismatch = |
@@ -473,20 +479,20 @@ static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | |||
473 | ((qOddMeasOffset * 32) / | 479 | ((qOddMeasOffset * 32) / |
474 | qEvenMeasOffset) & 0x3f; | 480 | qEvenMeasOffset) & 0x3f; |
475 | 481 | ||
476 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 482 | ath_print(common, ATH_DBG_CALIBRATE, |
477 | "Chn %d gain_mismatch_i = 0x%08x\n", i, | 483 | "Chn %d gain_mismatch_i = 0x%08x\n", i, |
478 | iGainMismatch); | 484 | iGainMismatch); |
479 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 485 | ath_print(common, ATH_DBG_CALIBRATE, |
480 | "Chn %d gain_mismatch_q = 0x%08x\n", i, | 486 | "Chn %d gain_mismatch_q = 0x%08x\n", i, |
481 | qGainMismatch); | 487 | qGainMismatch); |
482 | 488 | ||
483 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | 489 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); |
484 | val &= 0xfffff000; | 490 | val &= 0xfffff000; |
485 | val |= (qGainMismatch) | (iGainMismatch << 6); | 491 | val |= (qGainMismatch) | (iGainMismatch << 6); |
486 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | 492 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); |
487 | 493 | ||
488 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 494 | ath_print(common, ATH_DBG_CALIBRATE, |
489 | "ADC Gain Cal done for Chain %d\n", i); | 495 | "ADC Gain Cal done for Chain %d\n", i); |
490 | } | 496 | } |
491 | } | 497 | } |
492 | 498 | ||
@@ -497,6 +503,7 @@ static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | |||
497 | 503 | ||
498 | static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) | 504 | static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) |
499 | { | 505 | { |
506 | struct ath_common *common = ath9k_hw_common(ah); | ||
500 | u32 iOddMeasOffset, iEvenMeasOffset, val, i; | 507 | u32 iOddMeasOffset, iEvenMeasOffset, val, i; |
501 | int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; | 508 | int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; |
502 | const struct ath9k_percal_data *calData = | 509 | const struct ath9k_percal_data *calData = |
@@ -510,41 +517,41 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) | |||
510 | qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i]; | 517 | qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i]; |
511 | qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i]; | 518 | qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i]; |
512 | 519 | ||
513 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 520 | ath_print(common, ATH_DBG_CALIBRATE, |
514 | "Starting ADC DC Offset Cal for Chain %d\n", i); | 521 | "Starting ADC DC Offset Cal for Chain %d\n", i); |
515 | 522 | ||
516 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 523 | ath_print(common, ATH_DBG_CALIBRATE, |
517 | "Chn %d pwr_meas_odd_i = %d\n", i, | 524 | "Chn %d pwr_meas_odd_i = %d\n", i, |
518 | iOddMeasOffset); | 525 | iOddMeasOffset); |
519 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 526 | ath_print(common, ATH_DBG_CALIBRATE, |
520 | "Chn %d pwr_meas_even_i = %d\n", i, | 527 | "Chn %d pwr_meas_even_i = %d\n", i, |
521 | iEvenMeasOffset); | 528 | iEvenMeasOffset); |
522 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 529 | ath_print(common, ATH_DBG_CALIBRATE, |
523 | "Chn %d pwr_meas_odd_q = %d\n", i, | 530 | "Chn %d pwr_meas_odd_q = %d\n", i, |
524 | qOddMeasOffset); | 531 | qOddMeasOffset); |
525 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 532 | ath_print(common, ATH_DBG_CALIBRATE, |
526 | "Chn %d pwr_meas_even_q = %d\n", i, | 533 | "Chn %d pwr_meas_even_q = %d\n", i, |
527 | qEvenMeasOffset); | 534 | qEvenMeasOffset); |
528 | 535 | ||
529 | iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / | 536 | iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / |
530 | numSamples) & 0x1ff; | 537 | numSamples) & 0x1ff; |
531 | qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / | 538 | qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / |
532 | numSamples) & 0x1ff; | 539 | numSamples) & 0x1ff; |
533 | 540 | ||
534 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 541 | ath_print(common, ATH_DBG_CALIBRATE, |
535 | "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, | 542 | "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, |
536 | iDcMismatch); | 543 | iDcMismatch); |
537 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 544 | ath_print(common, ATH_DBG_CALIBRATE, |
538 | "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, | 545 | "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, |
539 | qDcMismatch); | 546 | qDcMismatch); |
540 | 547 | ||
541 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | 548 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); |
542 | val &= 0xc0000fff; | 549 | val &= 0xc0000fff; |
543 | val |= (qDcMismatch << 12) | (iDcMismatch << 21); | 550 | val |= (qDcMismatch << 12) | (iDcMismatch << 21); |
544 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | 551 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); |
545 | 552 | ||
546 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 553 | ath_print(common, ATH_DBG_CALIBRATE, |
547 | "ADC DC Offset Cal done for Chain %d\n", i); | 554 | "ADC DC Offset Cal done for Chain %d\n", i); |
548 | } | 555 | } |
549 | 556 | ||
550 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | 557 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), |
@@ -555,7 +562,8 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) | |||
555 | /* This is done for the currently configured channel */ | 562 | /* This is done for the currently configured channel */ |
556 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | 563 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah) |
557 | { | 564 | { |
558 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | 565 | struct ath_common *common = ath9k_hw_common(ah); |
566 | struct ieee80211_conf *conf = &common->hw->conf; | ||
559 | struct ath9k_cal_list *currCal = ah->cal_list_curr; | 567 | struct ath9k_cal_list *currCal = ah->cal_list_curr; |
560 | 568 | ||
561 | if (!ah->curchan) | 569 | if (!ah->curchan) |
@@ -568,24 +576,25 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | |||
568 | return true; | 576 | return true; |
569 | 577 | ||
570 | if (currCal->calState != CAL_DONE) { | 578 | if (currCal->calState != CAL_DONE) { |
571 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 579 | ath_print(common, ATH_DBG_CALIBRATE, |
572 | "Calibration state incorrect, %d\n", | 580 | "Calibration state incorrect, %d\n", |
573 | currCal->calState); | 581 | currCal->calState); |
574 | return true; | 582 | return true; |
575 | } | 583 | } |
576 | 584 | ||
577 | if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType)) | 585 | if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType)) |
578 | return true; | 586 | return true; |
579 | 587 | ||
580 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 588 | ath_print(common, ATH_DBG_CALIBRATE, |
581 | "Resetting Cal %d state for channel %u\n", | 589 | "Resetting Cal %d state for channel %u\n", |
582 | currCal->calData->calType, conf->channel->center_freq); | 590 | currCal->calData->calType, conf->channel->center_freq); |
583 | 591 | ||
584 | ah->curchan->CalValid &= ~currCal->calData->calType; | 592 | ah->curchan->CalValid &= ~currCal->calData->calType; |
585 | currCal->calState = CAL_WAITING; | 593 | currCal->calState = CAL_WAITING; |
586 | 594 | ||
587 | return false; | 595 | return false; |
588 | } | 596 | } |
597 | EXPORT_SYMBOL(ath9k_hw_reset_calvalid); | ||
589 | 598 | ||
590 | void ath9k_hw_start_nfcal(struct ath_hw *ah) | 599 | void ath9k_hw_start_nfcal(struct ath_hw *ah) |
591 | { | 600 | { |
@@ -645,11 +654,11 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
645 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | 654 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); |
646 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | 655 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); |
647 | 656 | ||
648 | for (j = 0; j < 1000; j++) { | 657 | for (j = 0; j < 5; j++) { |
649 | if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & | 658 | if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & |
650 | AR_PHY_AGC_CONTROL_NF) == 0) | 659 | AR_PHY_AGC_CONTROL_NF) == 0) |
651 | break; | 660 | break; |
652 | udelay(10); | 661 | udelay(50); |
653 | } | 662 | } |
654 | 663 | ||
655 | for (i = 0; i < NUM_NF_READINGS; i++) { | 664 | for (i = 0; i < NUM_NF_READINGS; i++) { |
@@ -665,6 +674,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
665 | int16_t ath9k_hw_getnf(struct ath_hw *ah, | 674 | int16_t ath9k_hw_getnf(struct ath_hw *ah, |
666 | struct ath9k_channel *chan) | 675 | struct ath9k_channel *chan) |
667 | { | 676 | { |
677 | struct ath_common *common = ath9k_hw_common(ah); | ||
668 | int16_t nf, nfThresh; | 678 | int16_t nf, nfThresh; |
669 | int16_t nfarray[NUM_NF_READINGS] = { 0 }; | 679 | int16_t nfarray[NUM_NF_READINGS] = { 0 }; |
670 | struct ath9k_nfcal_hist *h; | 680 | struct ath9k_nfcal_hist *h; |
@@ -672,8 +682,8 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah, | |||
672 | 682 | ||
673 | chan->channelFlags &= (~CHANNEL_CW_INT); | 683 | chan->channelFlags &= (~CHANNEL_CW_INT); |
674 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { | 684 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { |
675 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 685 | ath_print(common, ATH_DBG_CALIBRATE, |
676 | "NF did not complete in calibration window\n"); | 686 | "NF did not complete in calibration window\n"); |
677 | nf = 0; | 687 | nf = 0; |
678 | chan->rawNoiseFloor = nf; | 688 | chan->rawNoiseFloor = nf; |
679 | return chan->rawNoiseFloor; | 689 | return chan->rawNoiseFloor; |
@@ -682,10 +692,10 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah, | |||
682 | nf = nfarray[0]; | 692 | nf = nfarray[0]; |
683 | if (getNoiseFloorThresh(ah, c->band, &nfThresh) | 693 | if (getNoiseFloorThresh(ah, c->band, &nfThresh) |
684 | && nf > nfThresh) { | 694 | && nf > nfThresh) { |
685 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 695 | ath_print(common, ATH_DBG_CALIBRATE, |
686 | "noise floor failed detected; " | 696 | "noise floor failed detected; " |
687 | "detected %d, threshold %d\n", | 697 | "detected %d, threshold %d\n", |
688 | nf, nfThresh); | 698 | nf, nfThresh); |
689 | chan->channelFlags |= CHANNEL_CW_INT; | 699 | chan->channelFlags |= CHANNEL_CW_INT; |
690 | } | 700 | } |
691 | } | 701 | } |
@@ -737,51 +747,73 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) | |||
737 | 747 | ||
738 | return nf; | 748 | return nf; |
739 | } | 749 | } |
750 | EXPORT_SYMBOL(ath9k_hw_getchan_noise); | ||
740 | 751 | ||
741 | static void ath9k_olc_temp_compensation(struct ath_hw *ah) | 752 | static void ath9k_olc_temp_compensation_9287(struct ath_hw *ah) |
742 | { | 753 | { |
743 | u32 rddata, i; | 754 | u32 rddata; |
744 | int delta, currPDADC, regval, slope; | 755 | int32_t delta, currPDADC, slope; |
745 | 756 | ||
746 | rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); | 757 | rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); |
747 | currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); | 758 | currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); |
748 | 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; | ||
749 | 785 | ||
750 | if (OLC_FOR_AR9287_10_LATER) { | 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 | |||
751 | if (ah->initPDADC == 0 || currPDADC == 0) { | 792 | if (ah->initPDADC == 0 || currPDADC == 0) { |
752 | return; | 793 | return; |
753 | } else { | 794 | } else { |
754 | slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE); | 795 | if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G)) |
755 | if (slope == 0) | 796 | delta = (currPDADC - ah->initPDADC + 4) / 8; |
756 | delta = 0; | ||
757 | else | 797 | else |
758 | delta = ((currPDADC - ah->initPDADC)*4) / slope; | 798 | delta = (currPDADC - ah->initPDADC + 5) / 10; |
759 | REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11, | 799 | |
760 | AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta); | 800 | if (delta != ah->PDADCdelta) { |
761 | REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11, | 801 | ah->PDADCdelta = delta; |
762 | AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta); | 802 | for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { |
763 | } | 803 | regval = ah->originalGain[i] - delta; |
764 | } else { | 804 | if (regval < 0) |
765 | if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G)) | 805 | regval = 0; |
766 | delta = (currPDADC - ah->initPDADC + 4) / 8; | 806 | |
767 | else | 807 | REG_RMW_FIELD(ah, |
768 | delta = (currPDADC - ah->initPDADC + 5) / 10; | 808 | AR_PHY_TX_GAIN_TBL1 + i * 4, |
769 | 809 | AR_PHY_TX_GAIN, regval); | |
770 | if (delta != ah->PDADCdelta) { | 810 | } |
771 | ah->PDADCdelta = delta; | ||
772 | for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { | ||
773 | regval = ah->originalGain[i] - delta; | ||
774 | if (regval < 0) | ||
775 | regval = 0; | ||
776 | |||
777 | REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4, | ||
778 | AR_PHY_TX_GAIN, regval); | ||
779 | } | 811 | } |
780 | } | 812 | } |
781 | } | 813 | } |
782 | } | 814 | } |
783 | 815 | ||
784 | static void ath9k_hw_9271_pa_cal(struct ath_hw *ah) | 816 | static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset) |
785 | { | 817 | { |
786 | u32 regVal; | 818 | u32 regVal; |
787 | unsigned int i; | 819 | unsigned int i; |
@@ -845,7 +877,7 @@ static void ath9k_hw_9271_pa_cal(struct ath_hw *ah) | |||
845 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0); | 877 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0); |
846 | 878 | ||
847 | /* find off_6_1; */ | 879 | /* find off_6_1; */ |
848 | for (i = 6; i >= 0; i--) { | 880 | for (i = 6; i > 0; i--) { |
849 | regVal = REG_READ(ah, 0x7834); | 881 | regVal = REG_READ(ah, 0x7834); |
850 | regVal |= (1 << (20 + i)); | 882 | regVal |= (1 << (20 + i)); |
851 | REG_WRITE(ah, 0x7834, regVal); | 883 | REG_WRITE(ah, 0x7834, regVal); |
@@ -857,10 +889,19 @@ static void ath9k_hw_9271_pa_cal(struct ath_hw *ah) | |||
857 | REG_WRITE(ah, 0x7834, regVal); | 889 | REG_WRITE(ah, 0x7834, regVal); |
858 | } | 890 | } |
859 | 891 | ||
860 | /* Empirical offset correction */ | 892 | regVal = (regVal >>20) & 0x7f; |
861 | #if 0 | 893 | |
862 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0x20); | 894 | /* Update PA cal info */ |
863 | #endif | 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 | } | ||
864 | 905 | ||
865 | regVal = REG_READ(ah, 0x7834); | 906 | regVal = REG_READ(ah, 0x7834); |
866 | regVal |= 0x1; | 907 | regVal |= 0x1; |
@@ -875,7 +916,7 @@ static void ath9k_hw_9271_pa_cal(struct ath_hw *ah) | |||
875 | 916 | ||
876 | static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset) | 917 | static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset) |
877 | { | 918 | { |
878 | 919 | struct ath_common *common = ath9k_hw_common(ah); | |
879 | u32 regVal; | 920 | u32 regVal; |
880 | int i, offset, offs_6_1, offs_0; | 921 | int i, offset, offs_6_1, offs_0; |
881 | u32 ccomp_org, reg_field; | 922 | u32 ccomp_org, reg_field; |
@@ -889,7 +930,7 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset) | |||
889 | { 0x7838, 0 }, | 930 | { 0x7838, 0 }, |
890 | }; | 931 | }; |
891 | 932 | ||
892 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Running PA Calibration\n"); | 933 | ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n"); |
893 | 934 | ||
894 | /* PA CAL is not needed for high power solution */ | 935 | /* PA CAL is not needed for high power solution */ |
895 | if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == | 936 | if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == |
@@ -1011,7 +1052,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1011 | if (longcal) { | 1052 | if (longcal) { |
1012 | /* Do periodic PAOffset Cal */ | 1053 | /* Do periodic PAOffset Cal */ |
1013 | if (AR_SREV_9271(ah)) | 1054 | if (AR_SREV_9271(ah)) |
1014 | ath9k_hw_9271_pa_cal(ah); | 1055 | ath9k_hw_9271_pa_cal(ah, false); |
1015 | else if (AR_SREV_9285_11_OR_LATER(ah)) { | 1056 | else if (AR_SREV_9285_11_OR_LATER(ah)) { |
1016 | if (!ah->pacal_info.skipcount) | 1057 | if (!ah->pacal_info.skipcount) |
1017 | ath9k_hw_9285_pa_cal(ah, false); | 1058 | ath9k_hw_9285_pa_cal(ah, false); |
@@ -1036,9 +1077,13 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1036 | 1077 | ||
1037 | return iscaldone; | 1078 | return iscaldone; |
1038 | } | 1079 | } |
1080 | EXPORT_SYMBOL(ath9k_hw_calibrate); | ||
1039 | 1081 | ||
1082 | /* Carrier leakage Calibration fix */ | ||
1040 | static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) | 1083 | static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) |
1041 | { | 1084 | { |
1085 | struct ath_common *common = ath9k_hw_common(ah); | ||
1086 | |||
1042 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | 1087 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); |
1043 | if (IS_CHAN_HT20(chan)) { | 1088 | if (IS_CHAN_HT20(chan)) { |
1044 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); | 1089 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); |
@@ -1049,9 +1094,9 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1049 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | 1094 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); |
1050 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | 1095 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, |
1051 | AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { | 1096 | AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { |
1052 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset " | 1097 | ath_print(common, ATH_DBG_CALIBRATE, "offset " |
1053 | "calibration failed to complete in " | 1098 | "calibration failed to complete in " |
1054 | "1ms; noisy ??\n"); | 1099 | "1ms; noisy ??\n"); |
1055 | return false; | 1100 | return false; |
1056 | } | 1101 | } |
1057 | REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); | 1102 | REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); |
@@ -1064,8 +1109,8 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1064 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | 1109 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); |
1065 | if (!ath9k_hw_wait(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, |
1066 | 0, AH_WAIT_TIMEOUT)) { | 1111 | 0, AH_WAIT_TIMEOUT)) { |
1067 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration " | 1112 | ath_print(common, ATH_DBG_CALIBRATE, "offset calibration " |
1068 | "failed to complete in 1ms; noisy ??\n"); | 1113 | "failed to complete in 1ms; noisy ??\n"); |
1069 | return false; | 1114 | return false; |
1070 | } | 1115 | } |
1071 | 1116 | ||
@@ -1078,7 +1123,9 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1078 | 1123 | ||
1079 | bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | 1124 | bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) |
1080 | { | 1125 | { |
1081 | if (AR_SREV_9285_12_OR_LATER(ah)) { | 1126 | struct ath_common *common = ath9k_hw_common(ah); |
1127 | |||
1128 | if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) { | ||
1082 | if (!ar9285_clc(ah, chan)) | 1129 | if (!ar9285_clc(ah, chan)) |
1083 | return false; | 1130 | return false; |
1084 | } else { | 1131 | } else { |
@@ -1098,9 +1145,9 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1098 | /* Poll for offset calibration complete */ | 1145 | /* Poll for offset calibration complete */ |
1099 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, | 1146 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, |
1100 | 0, AH_WAIT_TIMEOUT)) { | 1147 | 0, AH_WAIT_TIMEOUT)) { |
1101 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 1148 | ath_print(common, ATH_DBG_CALIBRATE, |
1102 | "offset calibration failed to complete in 1ms; " | 1149 | "offset calibration failed to " |
1103 | "noisy environment?\n"); | 1150 | "complete in 1ms; noisy environment?\n"); |
1104 | return false; | 1151 | return false; |
1105 | } | 1152 | } |
1106 | 1153 | ||
@@ -1114,7 +1161,9 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1114 | } | 1161 | } |
1115 | 1162 | ||
1116 | /* Do PA Calibration */ | 1163 | /* Do PA Calibration */ |
1117 | if (AR_SREV_9285_11_OR_LATER(ah)) | 1164 | if (AR_SREV_9271(ah)) |
1165 | ath9k_hw_9271_pa_cal(ah, true); | ||
1166 | else if (AR_SREV_9285_11_OR_LATER(ah)) | ||
1118 | ath9k_hw_9285_pa_cal(ah, true); | 1167 | ath9k_hw_9285_pa_cal(ah, true); |
1119 | 1168 | ||
1120 | /* Do NF Calibration after DC offset and other calibrations */ | 1169 | /* Do NF Calibration after DC offset and other calibrations */ |
@@ -1128,20 +1177,20 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1128 | if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) { | 1177 | if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) { |
1129 | INIT_CAL(&ah->adcgain_caldata); | 1178 | INIT_CAL(&ah->adcgain_caldata); |
1130 | INSERT_CAL(ah, &ah->adcgain_caldata); | 1179 | INSERT_CAL(ah, &ah->adcgain_caldata); |
1131 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 1180 | ath_print(common, ATH_DBG_CALIBRATE, |
1132 | "enabling ADC Gain Calibration.\n"); | 1181 | "enabling ADC Gain Calibration.\n"); |
1133 | } | 1182 | } |
1134 | if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) { | 1183 | if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) { |
1135 | INIT_CAL(&ah->adcdc_caldata); | 1184 | INIT_CAL(&ah->adcdc_caldata); |
1136 | INSERT_CAL(ah, &ah->adcdc_caldata); | 1185 | INSERT_CAL(ah, &ah->adcdc_caldata); |
1137 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 1186 | ath_print(common, ATH_DBG_CALIBRATE, |
1138 | "enabling ADC DC Calibration.\n"); | 1187 | "enabling ADC DC Calibration.\n"); |
1139 | } | 1188 | } |
1140 | if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { | 1189 | if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { |
1141 | INIT_CAL(&ah->iq_caldata); | 1190 | INIT_CAL(&ah->iq_caldata); |
1142 | INSERT_CAL(ah, &ah->iq_caldata); | 1191 | INSERT_CAL(ah, &ah->iq_caldata); |
1143 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 1192 | ath_print(common, ATH_DBG_CALIBRATE, |
1144 | "enabling IQ Calibration.\n"); | 1193 | "enabling IQ Calibration.\n"); |
1145 | } | 1194 | } |
1146 | 1195 | ||
1147 | ah->cal_list_curr = ah->cal_list; | 1196 | ah->cal_list_curr = ah->cal_list; |