1 --- a/drivers/net/wireless/ath/ath9k/hw.h
2 +++ b/drivers/net/wireless/ath/ath9k/hw.h
3 @@ -354,6 +354,7 @@ struct ath9k_hw_cal_data {
8 u16 small_signal_gain[AR9300_MAX_CHAINS];
9 u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
10 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
11 --- a/drivers/net/wireless/ath/ath9k/calib.c
12 +++ b/drivers/net/wireless/ath/ath9k/calib.c
13 @@ -156,6 +156,9 @@ EXPORT_SYMBOL(ath9k_hw_reset_calvalid);
15 void ath9k_hw_start_nfcal(struct ath_hw *ah)
18 + ah->caldata->nfcal_pending = true;
20 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
21 AR_PHY_AGC_CONTROL_ENABLE_NF);
22 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
23 @@ -282,8 +285,7 @@ static void ath9k_hw_nf_sanitize(struct
27 -int16_t ath9k_hw_getnf(struct ath_hw *ah,
28 - struct ath9k_channel *chan)
29 +bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
31 struct ath_common *common = ath9k_hw_common(ah);
33 @@ -293,7 +295,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
34 struct ath9k_hw_cal_data *caldata = ah->caldata;
37 - return ath9k_hw_get_default_nf(ah, chan);
40 chan->channelFlags &= (~CHANNEL_CW_INT);
41 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
42 @@ -301,7 +303,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
43 "NF did not complete in calibration window\n");
45 caldata->rawNoiseFloor = nf;
46 - return caldata->rawNoiseFloor;
49 ath9k_hw_do_getnf(ah, nfarray);
50 ath9k_hw_nf_sanitize(ah, nfarray);
51 @@ -317,11 +319,10 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
54 h = caldata->nfCalHist;
56 + caldata->nfcal_pending = false;
57 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
58 caldata->rawNoiseFloor = h[0].privNF;
60 - return ah->caldata->rawNoiseFloor;
64 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
65 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
66 +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
67 @@ -687,8 +687,13 @@ static bool ar9002_hw_calibrate(struct a
69 bool iscaldone = true;
70 struct ath9k_cal_list *currCal = ah->cal_list_curr;
71 + bool nfcal, nfcal_pending = false;
74 + nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
76 + nfcal_pending = ah->caldata->nfcal_pending;
78 + if (currCal && !nfcal &&
79 (currCal->calState == CAL_RUNNING ||
80 currCal->calState == CAL_WAITING)) {
81 iscaldone = ar9002_hw_per_calibration(ah, chan,
82 @@ -704,7 +709,7 @@ static bool ar9002_hw_calibrate(struct a
85 /* Do NF cal only at longer intervals */
87 + if (longcal || nfcal_pending) {
88 /* Do periodic PAOffset Cal */
89 ar9002_hw_pa_cal(ah, false);
90 ar9002_hw_olc_temp_compensation(ah);
91 @@ -713,16 +718,18 @@ static bool ar9002_hw_calibrate(struct a
92 * Get the value from the previous NF cal and update
95 - ath9k_hw_getnf(ah, chan);
98 - * Load the NF from history buffer of the current channel.
99 - * NF is slow time-variant, so it is OK to use a historical
102 - ath9k_hw_loadnf(ah, ah->curchan);
103 + if (ath9k_hw_getnf(ah, chan)) {
105 + * Load the NF from history buffer of the current
107 + * NF is slow time-variant, so it is OK to use a
108 + * historical value.
110 + ath9k_hw_loadnf(ah, ah->curchan);
113 - ath9k_hw_start_nfcal(ah);
115 + ath9k_hw_start_nfcal(ah);
119 @@ -873,6 +880,9 @@ static bool ar9002_hw_init_cal(struct at
120 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
121 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
124 + ah->caldata->nfcal_pending = true;
126 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
128 /* Enable IQ, ADC Gain and ADC DC offset CALs */
129 --- a/drivers/net/wireless/ath/ath9k/calib.h
130 +++ b/drivers/net/wireless/ath/ath9k/calib.h
131 @@ -110,8 +110,7 @@ struct ath9k_pacal_info{
132 bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
133 void ath9k_hw_start_nfcal(struct ath_hw *ah);
134 void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
135 -int16_t ath9k_hw_getnf(struct ath_hw *ah,
136 - struct ath9k_channel *chan);
137 +bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
138 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
139 struct ath9k_channel *chan);
140 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);