aboutsummaryrefslogtreecommitdiffstats
path: root/package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch')
-rw-r--r--package/mac80211/patches/523-ath9k_nfcal_timeout_handling.patch140
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 0000000000..90363605eb
--- /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);