aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/calib.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-07-30 18:12:01 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-04 15:27:37 -0400
commit4254bc1c4d7b53ac10e558dfe015725fdd693da4 (patch)
tree51c95b3f0f24ff8e1fabf698524c9ddd9f069879 /drivers/net/wireless/ath/ath9k/calib.c
parent20bd2a0952d01ba82a99b3f22d46e3832c255529 (diff)
ath9k_hw: fix a noise floor calibration related race condition
On AR5008-AR9002, other forms of calibration must not be started while the noise floor calibration is running, as this can create invalid readings which were sometimes not even recoverable by any further calibration attempts. This patch also ensures that the result of noise floor measurements are processed faster and also allows the result of the initial calibration on reset to make it into the NF history buffer Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/calib.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 18b5c0dcc1fc..45208690c0ec 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -156,6 +156,9 @@ EXPORT_SYMBOL(ath9k_hw_reset_calvalid);
156 156
157void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update) 157void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update)
158{ 158{
159 if (ah->caldata)
160 ah->caldata->nfcal_pending = true;
161
159 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, 162 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
160 AR_PHY_AGC_CONTROL_ENABLE_NF); 163 AR_PHY_AGC_CONTROL_ENABLE_NF);
161 164
@@ -288,8 +291,7 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
288 } 291 }
289} 292}
290 293
291int16_t ath9k_hw_getnf(struct ath_hw *ah, 294bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
292 struct ath9k_channel *chan)
293{ 295{
294 struct ath_common *common = ath9k_hw_common(ah); 296 struct ath_common *common = ath9k_hw_common(ah);
295 int16_t nf, nfThresh; 297 int16_t nf, nfThresh;
@@ -299,7 +301,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
299 struct ath9k_hw_cal_data *caldata = ah->caldata; 301 struct ath9k_hw_cal_data *caldata = ah->caldata;
300 302
301 if (!caldata) 303 if (!caldata)
302 return ath9k_hw_get_default_nf(ah, chan); 304 return false;
303 305
304 chan->channelFlags &= (~CHANNEL_CW_INT); 306 chan->channelFlags &= (~CHANNEL_CW_INT);
305 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { 307 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
@@ -307,7 +309,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
307 "NF did not complete in calibration window\n"); 309 "NF did not complete in calibration window\n");
308 nf = 0; 310 nf = 0;
309 caldata->rawNoiseFloor = nf; 311 caldata->rawNoiseFloor = nf;
310 return caldata->rawNoiseFloor; 312 return false;
311 } else { 313 } else {
312 ath9k_hw_do_getnf(ah, nfarray); 314 ath9k_hw_do_getnf(ah, nfarray);
313 ath9k_hw_nf_sanitize(ah, nfarray); 315 ath9k_hw_nf_sanitize(ah, nfarray);
@@ -323,11 +325,10 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
323 } 325 }
324 326
325 h = caldata->nfCalHist; 327 h = caldata->nfCalHist;
326 328 caldata->nfcal_pending = false;
327 ath9k_hw_update_nfcal_hist_buffer(h, nfarray); 329 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
328 caldata->rawNoiseFloor = h[0].privNF; 330 caldata->rawNoiseFloor = h[0].privNF;
329 331 return true;
330 return ah->caldata->rawNoiseFloor;
331} 332}
332 333
333void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, 334void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,