diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-07-28 11:40:38 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-07-28 11:40:38 +0000 |
commit | 53e5fdd4e4c2cf8b53702e559797185f2d009187 (patch) | |
tree | 94096c4dc8af0d9a8d8b498f88364d50abae6794 /package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch | |
parent | 2122c93af5a8b5b8d2c4c2bdb6274fc1eaf42a62 (diff) |
ath9k: fix various calibration related bugs and clean up the code
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22408 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch')
-rw-r--r-- | package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch b/package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch new file mode 100644 index 000000000..90363605e --- /dev/null +++ b/package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch @@ -0,0 +1,140 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -354,6 +354,7 @@ struct ath9k_hw_cal_data { + int8_t qCoff; + int16_t rawNoiseFloor; + bool paprd_done; ++ bool nfcal_pending; + u16 small_signal_gain[AR9300_MAX_CHAINS]; + u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; + struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; +--- 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); + + void ath9k_hw_start_nfcal(struct ath_hw *ah) + { ++ if (ah->caldata) ++ ah->caldata->nfcal_pending = true; ++ + REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, + AR_PHY_AGC_CONTROL_ENABLE_NF); + REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, +@@ -282,8 +285,7 @@ static void ath9k_hw_nf_sanitize(struct + } + } + +-int16_t ath9k_hw_getnf(struct ath_hw *ah, +- struct ath9k_channel *chan) ++bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) + { + struct ath_common *common = ath9k_hw_common(ah); + int16_t nf, nfThresh; +@@ -293,7 +295,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah + struct ath9k_hw_cal_data *caldata = ah->caldata; + + if (!caldata) +- return ath9k_hw_get_default_nf(ah, chan); ++ return false; + + chan->channelFlags &= (~CHANNEL_CW_INT); + if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { +@@ -301,7 +303,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah + "NF did not complete in calibration window\n"); + nf = 0; + caldata->rawNoiseFloor = nf; +- return caldata->rawNoiseFloor; ++ return false; + } else { + ath9k_hw_do_getnf(ah, nfarray); + ath9k_hw_nf_sanitize(ah, nfarray); +@@ -317,11 +319,10 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah + } + + h = caldata->nfCalHist; +- ++ caldata->nfcal_pending = false; + ath9k_hw_update_nfcal_hist_buffer(h, nfarray); + caldata->rawNoiseFloor = h[0].privNF; +- +- return ah->caldata->rawNoiseFloor; ++ return true; + } + + void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, +--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c +@@ -687,8 +687,13 @@ static bool ar9002_hw_calibrate(struct a + { + bool iscaldone = true; + struct ath9k_cal_list *currCal = ah->cal_list_curr; ++ bool nfcal, nfcal_pending = false; + +- if (currCal && ++ nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF); ++ if (ah->caldata) ++ nfcal_pending = ah->caldata->nfcal_pending; ++ ++ if (currCal && !nfcal && + (currCal->calState == CAL_RUNNING || + currCal->calState == CAL_WAITING)) { + iscaldone = ar9002_hw_per_calibration(ah, chan, +@@ -704,7 +709,7 @@ static bool ar9002_hw_calibrate(struct a + } + + /* Do NF cal only at longer intervals */ +- if (longcal) { ++ if (longcal || nfcal_pending) { + /* Do periodic PAOffset Cal */ + ar9002_hw_pa_cal(ah, false); + ar9002_hw_olc_temp_compensation(ah); +@@ -713,16 +718,18 @@ static bool ar9002_hw_calibrate(struct a + * Get the value from the previous NF cal and update + * history buffer. + */ +- ath9k_hw_getnf(ah, chan); +- +- /* +- * Load the NF from history buffer of the current channel. +- * NF is slow time-variant, so it is OK to use a historical +- * value. +- */ +- ath9k_hw_loadnf(ah, ah->curchan); ++ if (ath9k_hw_getnf(ah, chan)) { ++ /* ++ * Load the NF from history buffer of the current ++ * channel. ++ * NF is slow time-variant, so it is OK to use a ++ * historical value. ++ */ ++ ath9k_hw_loadnf(ah, ah->curchan); ++ } + +- ath9k_hw_start_nfcal(ah); ++ if (longcal) ++ ath9k_hw_start_nfcal(ah); + } + + return iscaldone; +@@ -873,6 +880,9 @@ static bool ar9002_hw_init_cal(struct at + REG_WRITE(ah, AR_PHY_AGC_CONTROL, + REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF); + ++ if (ah->caldata) ++ ah->caldata->nfcal_pending = true; ++ + ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; + + /* Enable IQ, ADC Gain and ADC DC offset CALs */ +--- a/drivers/net/wireless/ath/ath9k/calib.h ++++ b/drivers/net/wireless/ath/ath9k/calib.h +@@ -110,8 +110,7 @@ struct ath9k_pacal_info{ + bool ath9k_hw_reset_calvalid(struct ath_hw *ah); + void ath9k_hw_start_nfcal(struct ath_hw *ah); + void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); +-int16_t ath9k_hw_getnf(struct ath_hw *ah, +- struct ath9k_channel *chan); ++bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan); + void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, + struct ath9k_channel *chan); + s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); |