aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c99
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h24
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c32
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c2
12 files changed, 130 insertions, 94 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 2387ad1a23a..d28a8d37f01 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -63,6 +63,7 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah,
63 u8 rxchainmask, 63 u8 rxchainmask,
64 struct ath9k_cal_list *currCal) 64 struct ath9k_cal_list *currCal)
65{ 65{
66 struct ath9k_hw_cal_data *caldata = ah->caldata;
66 bool iscaldone = false; 67 bool iscaldone = false;
67 68
68 if (currCal->calState == CAL_RUNNING) { 69 if (currCal->calState == CAL_RUNNING) {
@@ -81,14 +82,14 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah,
81 } 82 }
82 83
83 currCal->calData->calPostProc(ah, numChains); 84 currCal->calData->calPostProc(ah, numChains);
84 ichan->CalValid |= currCal->calData->calType; 85 caldata->CalValid |= currCal->calData->calType;
85 currCal->calState = CAL_DONE; 86 currCal->calState = CAL_DONE;
86 iscaldone = true; 87 iscaldone = true;
87 } else { 88 } else {
88 ar9002_hw_setup_calibration(ah, currCal); 89 ar9002_hw_setup_calibration(ah, currCal);
89 } 90 }
90 } 91 }
91 } else if (!(ichan->CalValid & currCal->calData->calType)) { 92 } else if (!(caldata->CalValid & currCal->calData->calType)) {
92 ath9k_hw_reset_calibration(ah, currCal); 93 ath9k_hw_reset_calibration(ah, currCal);
93 } 94 }
94 95
@@ -900,7 +901,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
900 ath9k_hw_reset_calibration(ah, ah->cal_list_curr); 901 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
901 } 902 }
902 903
903 chan->CalValid = 0; 904 if (ah->caldata)
905 ah->caldata->CalValid = 0;
904 906
905 return true; 907 return true;
906} 908}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index f51ab89c989..4674ea8c9c9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -68,6 +68,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
68 u8 rxchainmask, 68 u8 rxchainmask,
69 struct ath9k_cal_list *currCal) 69 struct ath9k_cal_list *currCal)
70{ 70{
71 struct ath9k_hw_cal_data *caldata = ah->caldata;
71 /* Cal is assumed not done until explicitly set below */ 72 /* Cal is assumed not done until explicitly set below */
72 bool iscaldone = false; 73 bool iscaldone = false;
73 74
@@ -95,7 +96,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
95 currCal->calData->calPostProc(ah, numChains); 96 currCal->calData->calPostProc(ah, numChains);
96 97
97 /* Calibration has finished. */ 98 /* Calibration has finished. */
98 ichan->CalValid |= currCal->calData->calType; 99 caldata->CalValid |= currCal->calData->calType;
99 currCal->calState = CAL_DONE; 100 currCal->calState = CAL_DONE;
100 iscaldone = true; 101 iscaldone = true;
101 } else { 102 } else {
@@ -106,7 +107,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
106 ar9003_hw_setup_calibration(ah, currCal); 107 ar9003_hw_setup_calibration(ah, currCal);
107 } 108 }
108 } 109 }
109 } else if (!(ichan->CalValid & currCal->calData->calType)) { 110 } else if (!(caldata->CalValid & currCal->calData->calType)) {
110 /* If current cal is marked invalid in channel, kick it off */ 111 /* If current cal is marked invalid in channel, kick it off */
111 ath9k_hw_reset_calibration(ah, currCal); 112 ath9k_hw_reset_calibration(ah, currCal);
112 } 113 }
@@ -793,7 +794,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
793 if (ah->cal_list_curr) 794 if (ah->cal_list_curr)
794 ath9k_hw_reset_calibration(ah, ah->cal_list_curr); 795 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
795 796
796 chan->CalValid = 0; 797 if (ah->caldata)
798 ah->caldata->CalValid = 0;
797 799
798 return true; 800 return true;
799} 801}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 49e0c865ce5..7c38229ba67 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -577,10 +577,11 @@ static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain)
577} 577}
578 578
579void ar9003_paprd_populate_single_table(struct ath_hw *ah, 579void ar9003_paprd_populate_single_table(struct ath_hw *ah,
580 struct ath9k_channel *chan, int chain) 580 struct ath9k_hw_cal_data *caldata,
581 int chain)
581{ 582{
582 u32 *paprd_table_val = chan->pa_table[chain]; 583 u32 *paprd_table_val = caldata->pa_table[chain];
583 u32 small_signal_gain = chan->small_signal_gain[chain]; 584 u32 small_signal_gain = caldata->small_signal_gain[chain];
584 u32 training_power; 585 u32 training_power;
585 u32 reg = 0; 586 u32 reg = 0;
586 int i; 587 int i;
@@ -654,17 +655,17 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
654} 655}
655EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); 656EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);
656 657
657int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, 658int ar9003_paprd_create_curve(struct ath_hw *ah,
658 int chain) 659 struct ath9k_hw_cal_data *caldata, int chain)
659{ 660{
660 u16 *small_signal_gain = &chan->small_signal_gain[chain]; 661 u16 *small_signal_gain = &caldata->small_signal_gain[chain];
661 u32 *pa_table = chan->pa_table[chain]; 662 u32 *pa_table = caldata->pa_table[chain];
662 u32 *data_L, *data_U; 663 u32 *data_L, *data_U;
663 int i, status = 0; 664 int i, status = 0;
664 u32 *buf; 665 u32 *buf;
665 u32 reg; 666 u32 reg;
666 667
667 memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain])); 668 memset(caldata->pa_table[chain], 0, sizeof(caldata->pa_table[chain]));
668 669
669 buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC); 670 buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC);
670 if (!buf) 671 if (!buf)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 11fc69bee58..07f26ee7a72 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -609,6 +609,7 @@ struct ath_softc {
609struct ath_wiphy { 609struct ath_wiphy {
610 struct ath_softc *sc; /* shared for all virtual wiphys */ 610 struct ath_softc *sc; /* shared for all virtual wiphys */
611 struct ieee80211_hw *hw; 611 struct ieee80211_hw *hw;
612 struct ath9k_hw_cal_data caldata;
612 enum ath_wiphy_state { 613 enum ath_wiphy_state {
613 ATH_WIPHY_INACTIVE, 614 ATH_WIPHY_INACTIVE,
614 ATH_WIPHY_ACTIVE, 615 ATH_WIPHY_ACTIVE,
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 294016f9ce7..18b5c0dcc1f 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -22,23 +22,6 @@
22/* We can tune this as we go by monitoring really low values */ 22/* We can tune this as we go by monitoring really low values */
23#define ATH9K_NF_TOO_LOW -60 23#define ATH9K_NF_TOO_LOW -60
24 24
25/* AR5416 may return very high value (like -31 dBm), in those cases the nf
26 * is incorrect and we should use the static NF value. Later we can try to
27 * find out why they are reporting these values */
28
29static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
30{
31 if (nf > ATH9K_NF_TOO_LOW) {
32 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
33 "noise floor value detected (%d) is "
34 "lower than what we think is a "
35 "reasonable value (%d)\n",
36 nf, ATH9K_NF_TOO_LOW);
37 return false;
38 }
39 return true;
40}
41
42static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) 25static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
43{ 26{
44 int16_t nfval; 27 int16_t nfval;
@@ -121,6 +104,19 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah,
121 ah->cal_samples = 0; 104 ah->cal_samples = 0;
122} 105}
123 106
107static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
108 struct ath9k_channel *chan)
109{
110 struct ath_nf_limits *limit;
111
112 if (!chan || IS_CHAN_2GHZ(chan))
113 limit = &ah->nf_2g;
114 else
115 limit = &ah->nf_5g;
116
117 return limit->nominal;
118}
119
124/* This is done for the currently configured channel */ 120/* This is done for the currently configured channel */
125bool ath9k_hw_reset_calvalid(struct ath_hw *ah) 121bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
126{ 122{
@@ -128,7 +124,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
128 struct ieee80211_conf *conf = &common->hw->conf; 124 struct ieee80211_conf *conf = &common->hw->conf;
129 struct ath9k_cal_list *currCal = ah->cal_list_curr; 125 struct ath9k_cal_list *currCal = ah->cal_list_curr;
130 126
131 if (!ah->curchan) 127 if (!ah->caldata)
132 return true; 128 return true;
133 129
134 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) 130 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
@@ -151,7 +147,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
151 "Resetting Cal %d state for channel %u\n", 147 "Resetting Cal %d state for channel %u\n",
152 currCal->calData->calType, conf->channel->center_freq); 148 currCal->calData->calType, conf->channel->center_freq);
153 149
154 ah->curchan->CalValid &= ~currCal->calData->calType; 150 ah->caldata->CalValid &= ~currCal->calData->calType;
155 currCal->calState = CAL_WAITING; 151 currCal->calState = CAL_WAITING;
156 152
157 return false; 153 return false;
@@ -175,19 +171,28 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update)
175 171
176void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) 172void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
177{ 173{
178 struct ath9k_nfcal_hist *h; 174 struct ath9k_nfcal_hist *h = NULL;
179 unsigned i, j; 175 unsigned i, j;
180 int32_t val; 176 int32_t val;
181 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; 177 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
182 struct ath_common *common = ath9k_hw_common(ah); 178 struct ath_common *common = ath9k_hw_common(ah);
179 s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
183 180
184 h = ah->nfCalHist; 181 if (ah->caldata)
182 h = ah->caldata->nfCalHist;
185 183
186 for (i = 0; i < NUM_NF_READINGS; i++) { 184 for (i = 0; i < NUM_NF_READINGS; i++) {
187 if (chainmask & (1 << i)) { 185 if (chainmask & (1 << i)) {
186 s16 nfval;
187
188 if (h)
189 nfval = h[i].privNF;
190 else
191 nfval = default_nf;
192
188 val = REG_READ(ah, ah->nf_regs[i]); 193 val = REG_READ(ah, ah->nf_regs[i]);
189 val &= 0xFFFFFE00; 194 val &= 0xFFFFFE00;
190 val |= (((u32) (h[i].privNF) << 1) & 0x1ff); 195 val |= (((u32) nfval << 1) & 0x1ff);
191 REG_WRITE(ah, ah->nf_regs[i], val); 196 REG_WRITE(ah, ah->nf_regs[i], val);
192 } 197 }
193 } 198 }
@@ -291,14 +296,18 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
291 int16_t nfarray[NUM_NF_READINGS] = { 0 }; 296 int16_t nfarray[NUM_NF_READINGS] = { 0 };
292 struct ath9k_nfcal_hist *h; 297 struct ath9k_nfcal_hist *h;
293 struct ieee80211_channel *c = chan->chan; 298 struct ieee80211_channel *c = chan->chan;
299 struct ath9k_hw_cal_data *caldata = ah->caldata;
300
301 if (!caldata)
302 return ath9k_hw_get_default_nf(ah, chan);
294 303
295 chan->channelFlags &= (~CHANNEL_CW_INT); 304 chan->channelFlags &= (~CHANNEL_CW_INT);
296 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { 305 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
297 ath_print(common, ATH_DBG_CALIBRATE, 306 ath_print(common, ATH_DBG_CALIBRATE,
298 "NF did not complete in calibration window\n"); 307 "NF did not complete in calibration window\n");
299 nf = 0; 308 nf = 0;
300 chan->rawNoiseFloor = nf; 309 caldata->rawNoiseFloor = nf;
301 return chan->rawNoiseFloor; 310 return caldata->rawNoiseFloor;
302 } else { 311 } else {
303 ath9k_hw_do_getnf(ah, nfarray); 312 ath9k_hw_do_getnf(ah, nfarray);
304 ath9k_hw_nf_sanitize(ah, nfarray); 313 ath9k_hw_nf_sanitize(ah, nfarray);
@@ -313,47 +322,41 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
313 } 322 }
314 } 323 }
315 324
316 h = ah->nfCalHist; 325 h = caldata->nfCalHist;
317 326
318 ath9k_hw_update_nfcal_hist_buffer(h, nfarray); 327 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
319 chan->rawNoiseFloor = h[0].privNF; 328 caldata->rawNoiseFloor = h[0].privNF;
320 329
321 return chan->rawNoiseFloor; 330 return ah->caldata->rawNoiseFloor;
322} 331}
323 332
324void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah) 333void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
334 struct ath9k_channel *chan)
325{ 335{
326 struct ath_nf_limits *limit; 336 struct ath9k_nfcal_hist *h;
337 s16 default_nf;
327 int i, j; 338 int i, j;
328 339
329 if (!ah->curchan || IS_CHAN_2GHZ(ah->curchan)) 340 if (!ah->caldata)
330 limit = &ah->nf_2g; 341 return;
331 else
332 limit = &ah->nf_5g;
333 342
343 h = ah->caldata->nfCalHist;
344 default_nf = ath9k_hw_get_default_nf(ah, chan);
334 for (i = 0; i < NUM_NF_READINGS; i++) { 345 for (i = 0; i < NUM_NF_READINGS; i++) {
335 ah->nfCalHist[i].currIndex = 0; 346 h[i].currIndex = 0;
336 ah->nfCalHist[i].privNF = limit->nominal; 347 h[i].privNF = default_nf;
337 ah->nfCalHist[i].invalidNFcount = 348 h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH;
338 AR_PHY_CCA_FILTERWINDOW_LENGTH;
339 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { 349 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
340 ah->nfCalHist[i].nfCalBuffer[j] = limit->nominal; 350 h[i].nfCalBuffer[j] = default_nf;
341 } 351 }
342 } 352 }
343} 353}
344 354
345s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) 355s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
346{ 356{
347 s16 nf; 357 if (!ah->caldata || !ah->caldata->rawNoiseFloor)
348 358 return ath9k_hw_get_default_nf(ah, chan);
349 if (chan->rawNoiseFloor == 0)
350 nf = -96;
351 else
352 nf = chan->rawNoiseFloor;
353
354 if (!ath9k_hw_nf_in_range(ah, nf))
355 nf = ATH_DEFAULT_NOISE_FLOOR;
356 359
357 return nf; 360 return ah->caldata->rawNoiseFloor;
358} 361}
359EXPORT_SYMBOL(ath9k_hw_getchan_noise); 362EXPORT_SYMBOL(ath9k_hw_getchan_noise);
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index bf4474220d1..ca2e6b39c1d 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -112,7 +112,8 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update);
112void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); 112void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
113int16_t ath9k_hw_getnf(struct ath_hw *ah, 113int16_t ath9k_hw_getnf(struct ath_hw *ah,
114 struct ath9k_channel *chan); 114 struct ath9k_channel *chan);
115void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); 115void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
116 struct ath9k_channel *chan);
116s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); 117s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
117void ath9k_hw_reset_calibration(struct ath_hw *ah, 118void ath9k_hw_reset_calibration(struct ath_hw *ah,
118 struct ath9k_cal_list *currCal); 119 struct ath9k_cal_list *currCal);
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 3756400e6bf..43b9e21bc56 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -353,6 +353,8 @@ struct ath9k_htc_priv {
353 u16 seq_no; 353 u16 seq_no;
354 u32 bmiss_cnt; 354 u32 bmiss_cnt;
355 355
356 struct ath9k_hw_cal_data caldata[38];
357
356 spinlock_t beacon_lock; 358 spinlock_t beacon_lock;
357 359
358 bool tx_queues_stop; 360 bool tx_queues_stop;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index cf9bcc67ade..ebed9d1691a 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -125,6 +125,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
125 struct ieee80211_conf *conf = &common->hw->conf; 125 struct ieee80211_conf *conf = &common->hw->conf;
126 bool fastcc = true; 126 bool fastcc = true;
127 struct ieee80211_channel *channel = hw->conf.channel; 127 struct ieee80211_channel *channel = hw->conf.channel;
128 struct ath9k_hw_cal_data *caldata;
128 enum htc_phymode mode; 129 enum htc_phymode mode;
129 __be16 htc_mode; 130 __be16 htc_mode;
130 u8 cmd_rsp; 131 u8 cmd_rsp;
@@ -149,7 +150,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
149 priv->ah->curchan->channel, 150 priv->ah->curchan->channel,
150 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf)); 151 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
151 152
152 ret = ath9k_hw_reset(ah, hchan, fastcc); 153 caldata = &priv->caldata[channel->hw_value];
154 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
153 if (ret) { 155 if (ret) {
154 ath_print(common, ATH_DBG_FATAL, 156 ath_print(common, ATH_DBG_FATAL,
155 "Unable to reset channel (%u Mhz) " 157 "Unable to reset channel (%u Mhz) "
@@ -1028,7 +1030,7 @@ static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
1028 ah->curchan = ath9k_cmn_get_curchannel(hw, ah); 1030 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1029 1031
1030 /* Reset the HW */ 1032 /* Reset the HW */
1031 ret = ath9k_hw_reset(ah, ah->curchan, false); 1033 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
1032 if (ret) { 1034 if (ret) {
1033 ath_print(common, ATH_DBG_FATAL, 1035 ath_print(common, ATH_DBG_FATAL,
1034 "Unable to reset hardware; reset status %d " 1036 "Unable to reset hardware; reset status %d "
@@ -1091,7 +1093,7 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1091 ah->curchan = ath9k_cmn_get_curchannel(hw, ah); 1093 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1092 1094
1093 /* Reset the HW */ 1095 /* Reset the HW */
1094 ret = ath9k_hw_reset(ah, ah->curchan, false); 1096 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
1095 if (ret) { 1097 if (ret) {
1096 ath_print(common, ATH_DBG_FATAL, 1098 ath_print(common, ATH_DBG_FATAL,
1097 "Unable to reset hardware; reset status %d " 1099 "Unable to reset hardware; reset status %d "
@@ -1179,7 +1181,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1179 ath9k_hw_configpcipowersave(ah, 0, 0); 1181 ath9k_hw_configpcipowersave(ah, 0, 0);
1180 1182
1181 ath9k_hw_htc_resetinit(ah); 1183 ath9k_hw_htc_resetinit(ah);
1182 ret = ath9k_hw_reset(ah, init_channel, false); 1184 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
1183 if (ret) { 1185 if (ret) {
1184 ath_print(common, ATH_DBG_FATAL, 1186 ath_print(common, ATH_DBG_FATAL,
1185 "Unable to reset hardware; reset status %d " 1187 "Unable to reset hardware; reset status %d "
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 257b623185c..3384ca16456 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -610,7 +610,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
610 else 610 else
611 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); 611 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
612 612
613 ath9k_init_nfcal_hist_buffer(ah);
614 ah->bb_watchdog_timeout_ms = 25; 613 ah->bb_watchdog_timeout_ms = 25;
615 614
616 common->state = ATH_HW_INITIALIZED; 615 common->state = ATH_HW_INITIALIZED;
@@ -1183,9 +1182,6 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1183 1182
1184 ath9k_hw_spur_mitigate_freq(ah, chan); 1183 ath9k_hw_spur_mitigate_freq(ah, chan);
1185 1184
1186 if (!chan->oneTimeCalsDone)
1187 chan->oneTimeCalsDone = true;
1188
1189 return true; 1185 return true;
1190} 1186}
1191 1187
@@ -1218,7 +1214,7 @@ bool ath9k_hw_check_alive(struct ath_hw *ah)
1218EXPORT_SYMBOL(ath9k_hw_check_alive); 1214EXPORT_SYMBOL(ath9k_hw_check_alive);
1219 1215
1220int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 1216int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1221 bool bChannelChange) 1217 struct ath9k_hw_cal_data *caldata, bool bChannelChange)
1222{ 1218{
1223 struct ath_common *common = ath9k_hw_common(ah); 1219 struct ath_common *common = ath9k_hw_common(ah);
1224 u32 saveLedState; 1220 u32 saveLedState;
@@ -1243,9 +1239,19 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1243 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 1239 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
1244 return -EIO; 1240 return -EIO;
1245 1241
1246 if (curchan && !ah->chip_fullsleep) 1242 if (curchan && !ah->chip_fullsleep && ah->caldata)
1247 ath9k_hw_getnf(ah, curchan); 1243 ath9k_hw_getnf(ah, curchan);
1248 1244
1245 ah->caldata = caldata;
1246 if (caldata &&
1247 (chan->channel != caldata->channel ||
1248 (chan->channelFlags & ~CHANNEL_CW_INT) !=
1249 (caldata->channelFlags & ~CHANNEL_CW_INT))) {
1250 /* Operating channel changed, reset channel calibration data */
1251 memset(caldata, 0, sizeof(*caldata));
1252 ath9k_init_nfcal_hist_buffer(ah, chan);
1253 }
1254
1249 if (bChannelChange && 1255 if (bChannelChange &&
1250 (ah->chip_fullsleep != true) && 1256 (ah->chip_fullsleep != true) &&
1251 (ah->curchan != NULL) && 1257 (ah->curchan != NULL) &&
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 2d30efc0b94..c1b701119d8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -346,19 +346,24 @@ enum ath9k_int {
346 CHANNEL_HT40PLUS | \ 346 CHANNEL_HT40PLUS | \
347 CHANNEL_HT40MINUS) 347 CHANNEL_HT40MINUS)
348 348
349struct ath9k_channel { 349struct ath9k_hw_cal_data {
350 struct ieee80211_channel *chan;
351 u16 channel; 350 u16 channel;
352 u32 channelFlags; 351 u32 channelFlags;
353 u32 chanmode;
354 int32_t CalValid; 352 int32_t CalValid;
355 bool oneTimeCalsDone;
356 int8_t iCoff; 353 int8_t iCoff;
357 int8_t qCoff; 354 int8_t qCoff;
358 int16_t rawNoiseFloor; 355 int16_t rawNoiseFloor;
359 bool paprd_done; 356 bool paprd_done;
360 u16 small_signal_gain[AR9300_MAX_CHAINS]; 357 u16 small_signal_gain[AR9300_MAX_CHAINS];
361 u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; 358 u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
359 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
360};
361
362struct ath9k_channel {
363 struct ieee80211_channel *chan;
364 u16 channel;
365 u32 channelFlags;
366 u32 chanmode;
362}; 367};
363 368
364#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ 369#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
@@ -669,7 +674,7 @@ struct ath_hw {
669 enum nl80211_iftype opmode; 674 enum nl80211_iftype opmode;
670 enum ath9k_power_mode power_mode; 675 enum ath9k_power_mode power_mode;
671 676
672 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; 677 struct ath9k_hw_cal_data *caldata;
673 struct ath9k_pacal_info pacal_info; 678 struct ath9k_pacal_info pacal_info;
674 struct ar5416Stats stats; 679 struct ar5416Stats stats;
675 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; 680 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
@@ -863,7 +868,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid);
863void ath9k_hw_deinit(struct ath_hw *ah); 868void ath9k_hw_deinit(struct ath_hw *ah);
864int ath9k_hw_init(struct ath_hw *ah); 869int ath9k_hw_init(struct ath_hw *ah);
865int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 870int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
866 bool bChannelChange); 871 struct ath9k_hw_cal_data *caldata, bool bChannelChange);
867int ath9k_hw_fill_cap_info(struct ath_hw *ah); 872int ath9k_hw_fill_cap_info(struct ath_hw *ah);
868u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); 873u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
869 874
@@ -958,9 +963,10 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
958void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); 963void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);
959void ar9003_paprd_enable(struct ath_hw *ah, bool val); 964void ar9003_paprd_enable(struct ath_hw *ah, bool val);
960void ar9003_paprd_populate_single_table(struct ath_hw *ah, 965void ar9003_paprd_populate_single_table(struct ath_hw *ah,
961 struct ath9k_channel *chan, int chain); 966 struct ath9k_hw_cal_data *caldata,
962int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, 967 int chain);
963 int chain); 968int ar9003_paprd_create_curve(struct ath_hw *ah,
969 struct ath9k_hw_cal_data *caldata, int chain);
964int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); 970int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
965int ar9003_paprd_init_table(struct ath_hw *ah); 971int ar9003_paprd_init_table(struct ath_hw *ah);
966bool ar9003_paprd_is_done(struct ath_hw *ah); 972bool ar9003_paprd_is_done(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 8387ad5b489..3caa32316e7 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -183,11 +183,13 @@ static void ath_start_ani(struct ath_common *common)
183int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, 183int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
184 struct ath9k_channel *hchan) 184 struct ath9k_channel *hchan)
185{ 185{
186 struct ath_wiphy *aphy = hw->priv;
186 struct ath_hw *ah = sc->sc_ah; 187 struct ath_hw *ah = sc->sc_ah;
187 struct ath_common *common = ath9k_hw_common(ah); 188 struct ath_common *common = ath9k_hw_common(ah);
188 struct ieee80211_conf *conf = &common->hw->conf; 189 struct ieee80211_conf *conf = &common->hw->conf;
189 bool fastcc = true, stopped; 190 bool fastcc = true, stopped;
190 struct ieee80211_channel *channel = hw->conf.channel; 191 struct ieee80211_channel *channel = hw->conf.channel;
192 struct ath9k_hw_cal_data *caldata = NULL;
191 int r; 193 int r;
192 194
193 if (sc->sc_flags & SC_OP_INVALID) 195 if (sc->sc_flags & SC_OP_INVALID)
@@ -220,6 +222,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
220 if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL)) 222 if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
221 fastcc = false; 223 fastcc = false;
222 224
225 if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
226 caldata = &aphy->caldata;
227
223 ath_print(common, ATH_DBG_CONFIG, 228 ath_print(common, ATH_DBG_CONFIG,
224 "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n", 229 "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n",
225 sc->sc_ah->curchan->channel, 230 sc->sc_ah->curchan->channel,
@@ -227,7 +232,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
227 232
228 spin_lock_bh(&sc->sc_resetlock); 233 spin_lock_bh(&sc->sc_resetlock);
229 234
230 r = ath9k_hw_reset(ah, hchan, fastcc); 235 r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
231 if (r) { 236 if (r) {
232 ath_print(common, ATH_DBG_FATAL, 237 ath_print(common, ATH_DBG_FATAL,
233 "Unable to reset channel (%u MHz), " 238 "Unable to reset channel (%u MHz), "
@@ -263,9 +268,10 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
263static void ath_paprd_activate(struct ath_softc *sc) 268static void ath_paprd_activate(struct ath_softc *sc)
264{ 269{
265 struct ath_hw *ah = sc->sc_ah; 270 struct ath_hw *ah = sc->sc_ah;
271 struct ath9k_hw_cal_data *caldata = ah->caldata;
266 int chain; 272 int chain;
267 273
268 if (!ah->curchan->paprd_done) 274 if (!caldata || !caldata->paprd_done)
269 return; 275 return;
270 276
271 ath9k_ps_wakeup(sc); 277 ath9k_ps_wakeup(sc);
@@ -274,7 +280,7 @@ static void ath_paprd_activate(struct ath_softc *sc)
274 if (!(ah->caps.tx_chainmask & BIT(chain))) 280 if (!(ah->caps.tx_chainmask & BIT(chain)))
275 continue; 281 continue;
276 282
277 ar9003_paprd_populate_single_table(ah, ah->curchan, chain); 283 ar9003_paprd_populate_single_table(ah, caldata, chain);
278 } 284 }
279 285
280 ar9003_paprd_enable(ah, true); 286 ar9003_paprd_enable(ah, true);
@@ -292,6 +298,7 @@ void ath_paprd_calibrate(struct work_struct *work)
292 int band = hw->conf.channel->band; 298 int band = hw->conf.channel->band;
293 struct ieee80211_supported_band *sband = &sc->sbands[band]; 299 struct ieee80211_supported_band *sband = &sc->sbands[band];
294 struct ath_tx_control txctl; 300 struct ath_tx_control txctl;
301 struct ath9k_hw_cal_data *caldata = ah->caldata;
295 int qnum, ftype; 302 int qnum, ftype;
296 int chain_ok = 0; 303 int chain_ok = 0;
297 int chain; 304 int chain;
@@ -299,6 +306,9 @@ void ath_paprd_calibrate(struct work_struct *work)
299 int time_left; 306 int time_left;
300 int i; 307 int i;
301 308
309 if (!caldata)
310 return;
311
302 skb = alloc_skb(len, GFP_KERNEL); 312 skb = alloc_skb(len, GFP_KERNEL);
303 if (!skb) 313 if (!skb)
304 return; 314 return;
@@ -353,7 +363,7 @@ void ath_paprd_calibrate(struct work_struct *work)
353 if (!ar9003_paprd_is_done(ah)) 363 if (!ar9003_paprd_is_done(ah))
354 break; 364 break;
355 365
356 if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0) 366 if (ar9003_paprd_create_curve(ah, caldata, chain) != 0)
357 break; 367 break;
358 368
359 chain_ok = 1; 369 chain_ok = 1;
@@ -361,7 +371,7 @@ void ath_paprd_calibrate(struct work_struct *work)
361 kfree_skb(skb); 371 kfree_skb(skb);
362 372
363 if (chain_ok) { 373 if (chain_ok) {
364 ah->curchan->paprd_done = true; 374 caldata->paprd_done = true;
365 ath_paprd_activate(sc); 375 ath_paprd_activate(sc);
366 } 376 }
367 377
@@ -470,8 +480,8 @@ set_timer:
470 cal_interval = min(cal_interval, (u32)short_cal_interval); 480 cal_interval = min(cal_interval, (u32)short_cal_interval);
471 481
472 mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); 482 mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
473 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) { 483 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
474 if (!sc->sc_ah->curchan->paprd_done) 484 if (!ah->caldata->paprd_done)
475 ieee80211_queue_work(sc->hw, &sc->paprd_work); 485 ieee80211_queue_work(sc->hw, &sc->paprd_work);
476 else 486 else
477 ath_paprd_activate(sc); 487 ath_paprd_activate(sc);
@@ -829,7 +839,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
829 ah->curchan = ath_get_curchannel(sc, sc->hw); 839 ah->curchan = ath_get_curchannel(sc, sc->hw);
830 840
831 spin_lock_bh(&sc->sc_resetlock); 841 spin_lock_bh(&sc->sc_resetlock);
832 r = ath9k_hw_reset(ah, ah->curchan, false); 842 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
833 if (r) { 843 if (r) {
834 ath_print(common, ATH_DBG_FATAL, 844 ath_print(common, ATH_DBG_FATAL,
835 "Unable to reset channel (%u MHz), " 845 "Unable to reset channel (%u MHz), "
@@ -889,7 +899,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
889 ah->curchan = ath_get_curchannel(sc, hw); 899 ah->curchan = ath_get_curchannel(sc, hw);
890 900
891 spin_lock_bh(&sc->sc_resetlock); 901 spin_lock_bh(&sc->sc_resetlock);
892 r = ath9k_hw_reset(ah, ah->curchan, false); 902 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
893 if (r) { 903 if (r) {
894 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, 904 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
895 "Unable to reset channel (%u MHz), " 905 "Unable to reset channel (%u MHz), "
@@ -922,7 +932,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
922 ath_flushrecv(sc); 932 ath_flushrecv(sc);
923 933
924 spin_lock_bh(&sc->sc_resetlock); 934 spin_lock_bh(&sc->sc_resetlock);
925 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); 935 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
926 if (r) 936 if (r)
927 ath_print(common, ATH_DBG_FATAL, 937 ath_print(common, ATH_DBG_FATAL,
928 "Unable to reset hardware; reset status %d\n", r); 938 "Unable to reset hardware; reset status %d\n", r);
@@ -1097,7 +1107,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
1097 * and then setup of the interrupt mask. 1107 * and then setup of the interrupt mask.
1098 */ 1108 */
1099 spin_lock_bh(&sc->sc_resetlock); 1109 spin_lock_bh(&sc->sc_resetlock);
1100 r = ath9k_hw_reset(ah, init_channel, false); 1110 r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
1101 if (r) { 1111 if (r) {
1102 ath_print(common, ATH_DBG_FATAL, 1112 ath_print(common, ATH_DBG_FATAL,
1103 "Unable to reset hardware; reset status %d " 1113 "Unable to reset hardware; reset status %d "
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 501b72821b4..700ba8dee5a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1181,7 +1181,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1181 "Failed to stop TX DMA. Resetting hardware!\n"); 1181 "Failed to stop TX DMA. Resetting hardware!\n");
1182 1182
1183 spin_lock_bh(&sc->sc_resetlock); 1183 spin_lock_bh(&sc->sc_resetlock);
1184 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); 1184 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
1185 if (r) 1185 if (r)
1186 ath_print(common, ATH_DBG_FATAL, 1186 ath_print(common, ATH_DBG_FATAL,
1187 "Unable to reset hardware; reset status %d\n", 1187 "Unable to reset hardware; reset status %d\n",