mac80211: update to 2010-07-29, add pending patches to fix further issues with calibr...
[oweals/openwrt.git] / package / mac80211 / patches / 520-pending_work.patch
1 --- a/net/mac80211/main.c
2 +++ b/net/mac80211/main.c
3 @@ -103,11 +103,13 @@ int ieee80211_hw_config(struct ieee80211
4         int ret = 0;
5         int power;
6         enum nl80211_channel_type channel_type;
7 +       u32 offchannel_flag;
8  
9         might_sleep();
10  
11         scan_chan = local->scan_channel;
12  
13 +       offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
14         if (scan_chan) {
15                 chan = scan_chan;
16                 channel_type = NL80211_CHAN_NO_HT;
17 @@ -121,8 +123,9 @@ int ieee80211_hw_config(struct ieee80211
18                 channel_type = local->_oper_channel_type;
19                 local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
20         }
21 +       offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
22  
23 -       if (chan != local->hw.conf.channel ||
24 +       if (offchannel_flag || chan != local->hw.conf.channel ||
25             channel_type != local->hw.conf.channel_type) {
26                 local->hw.conf.channel = chan;
27                 local->hw.conf.channel_type = channel_type;
28 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
29 +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
30 @@ -63,6 +63,7 @@ static bool ar9002_hw_per_calibration(st
31                                       u8 rxchainmask,
32                                       struct ath9k_cal_list *currCal)
33  {
34 +       struct ath9k_hw_cal_data *caldata = ah->caldata;
35         bool iscaldone = false;
36  
37         if (currCal->calState == CAL_RUNNING) {
38 @@ -81,14 +82,14 @@ static bool ar9002_hw_per_calibration(st
39                                 }
40  
41                                 currCal->calData->calPostProc(ah, numChains);
42 -                               ichan->CalValid |= currCal->calData->calType;
43 +                               caldata->CalValid |= currCal->calData->calType;
44                                 currCal->calState = CAL_DONE;
45                                 iscaldone = true;
46                         } else {
47                                 ar9002_hw_setup_calibration(ah, currCal);
48                         }
49                 }
50 -       } else if (!(ichan->CalValid & currCal->calData->calType)) {
51 +       } else if (!(caldata->CalValid & currCal->calData->calType)) {
52                 ath9k_hw_reset_calibration(ah, currCal);
53         }
54  
55 @@ -686,8 +687,13 @@ static bool ar9002_hw_calibrate(struct a
56  {
57         bool iscaldone = true;
58         struct ath9k_cal_list *currCal = ah->cal_list_curr;
59 +       bool nfcal, nfcal_pending = false;
60  
61 -       if (currCal &&
62 +       nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
63 +       if (ah->caldata)
64 +               nfcal_pending = ah->caldata->nfcal_pending;
65 +
66 +       if (currCal && !nfcal &&
67             (currCal->calState == CAL_RUNNING ||
68              currCal->calState == CAL_WAITING)) {
69                 iscaldone = ar9002_hw_per_calibration(ah, chan,
70 @@ -703,7 +709,7 @@ static bool ar9002_hw_calibrate(struct a
71         }
72  
73         /* Do NF cal only at longer intervals */
74 -       if (longcal) {
75 +       if (longcal || nfcal_pending) {
76                 /* Do periodic PAOffset Cal */
77                 ar9002_hw_pa_cal(ah, false);
78                 ar9002_hw_olc_temp_compensation(ah);
79 @@ -712,16 +718,18 @@ static bool ar9002_hw_calibrate(struct a
80                  * Get the value from the previous NF cal and update
81                  * history buffer.
82                  */
83 -               ath9k_hw_getnf(ah, chan);
84 -
85 -               /*
86 -                * Load the NF from history buffer of the current channel.
87 -                * NF is slow time-variant, so it is OK to use a historical
88 -                * value.
89 -                */
90 -               ath9k_hw_loadnf(ah, ah->curchan);
91 +               if (ath9k_hw_getnf(ah, chan)) {
92 +                       /*
93 +                        * Load the NF from history buffer of the current
94 +                        * channel.
95 +                        * NF is slow time-variant, so it is OK to use a
96 +                        * historical value.
97 +                        */
98 +                       ath9k_hw_loadnf(ah, ah->curchan);
99 +               }
100  
101 -               ath9k_hw_start_nfcal(ah);
102 +               if (longcal)
103 +                       ath9k_hw_start_nfcal(ah, false);
104         }
105  
106         return iscaldone;
107 @@ -869,8 +877,10 @@ static bool ar9002_hw_init_cal(struct at
108         ar9002_hw_pa_cal(ah, true);
109  
110         /* Do NF Calibration after DC offset and other calibrations */
111 -       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
112 -                 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
113 +       ath9k_hw_start_nfcal(ah, true);
114 +
115 +       if (ah->caldata)
116 +               ah->caldata->nfcal_pending = true;
117  
118         ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
119  
120 @@ -901,7 +911,8 @@ static bool ar9002_hw_init_cal(struct at
121                         ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
122         }
123  
124 -       chan->CalValid = 0;
125 +       if (ah->caldata)
126 +               ah->caldata->CalValid = 0;
127  
128         return true;
129  }
130 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
131 +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
132 @@ -68,6 +68,7 @@ static bool ar9003_hw_per_calibration(st
133                                       u8 rxchainmask,
134                                       struct ath9k_cal_list *currCal)
135  {
136 +       struct ath9k_hw_cal_data *caldata = ah->caldata;
137         /* Cal is assumed not done until explicitly set below */
138         bool iscaldone = false;
139  
140 @@ -95,7 +96,7 @@ static bool ar9003_hw_per_calibration(st
141                                 currCal->calData->calPostProc(ah, numChains);
142  
143                                 /* Calibration has finished. */
144 -                               ichan->CalValid |= currCal->calData->calType;
145 +                               caldata->CalValid |= currCal->calData->calType;
146                                 currCal->calState = CAL_DONE;
147                                 iscaldone = true;
148                         } else {
149 @@ -106,7 +107,7 @@ static bool ar9003_hw_per_calibration(st
150                         ar9003_hw_setup_calibration(ah, currCal);
151                         }
152                 }
153 -       } else if (!(ichan->CalValid & currCal->calData->calType)) {
154 +       } else if (!(caldata->CalValid & currCal->calData->calType)) {
155                 /* If current cal is marked invalid in channel, kick it off */
156                 ath9k_hw_reset_calibration(ah, currCal);
157         }
158 @@ -149,6 +150,12 @@ static bool ar9003_hw_calibrate(struct a
159         /* Do NF cal only at longer intervals */
160         if (longcal) {
161                 /*
162 +                * Get the value from the previous NF cal and update
163 +                * history buffer.
164 +                */
165 +               ath9k_hw_getnf(ah, chan);
166 +
167 +               /*
168                  * Load the NF from history buffer of the current channel.
169                  * NF is slow time-variant, so it is OK to use a historical
170                  * value.
171 @@ -156,7 +163,7 @@ static bool ar9003_hw_calibrate(struct a
172                 ath9k_hw_loadnf(ah, ah->curchan);
173  
174                 /* start NF calibration, without updating BB NF register */
175 -               ath9k_hw_start_nfcal(ah);
176 +               ath9k_hw_start_nfcal(ah, false);
177         }
178  
179         return iscaldone;
180 @@ -762,6 +769,8 @@ static bool ar9003_hw_init_cal(struct at
181         /* Revert chainmasks to their original values before NF cal */
182         ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
183  
184 +       ath9k_hw_start_nfcal(ah, true);
185 +
186         /* Initialize list pointers */
187         ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
188  
189 @@ -785,7 +794,8 @@ static bool ar9003_hw_init_cal(struct at
190         if (ah->cal_list_curr)
191                 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
192  
193 -       chan->CalValid = 0;
194 +       if (ah->caldata)
195 +               ah->caldata->CalValid = 0;
196  
197         return true;
198  }
199 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
200 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
201 @@ -542,7 +542,11 @@ static void ar9003_hw_prog_ini(struct at
202                 u32 reg = INI_RA(iniArr, i, 0);
203                 u32 val = INI_RA(iniArr, i, column);
204  
205 -               REG_WRITE(ah, reg, val);
206 +               if (reg >= 0x16000 && reg < 0x17000)
207 +                       ath9k_hw_analog_shift_regwrite(ah, reg, val);
208 +               else
209 +                       REG_WRITE(ah, reg, val);
210 +
211                 DO_DELAY(regWrites);
212         }
213  }
214 --- a/drivers/net/wireless/ath/ath9k/calib.c
215 +++ b/drivers/net/wireless/ath/ath9k/calib.c
216 @@ -22,23 +22,6 @@
217  /* We can tune this as we go by monitoring really low values */
218  #define ATH9K_NF_TOO_LOW       -60
219  
220 -/* AR5416 may return very high value (like -31 dBm), in those cases the nf
221 - * is incorrect and we should use the static NF value. Later we can try to
222 - * find out why they are reporting these values */
223 -
224 -static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
225 -{
226 -       if (nf > ATH9K_NF_TOO_LOW) {
227 -               ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
228 -                         "noise floor value detected (%d) is "
229 -                         "lower than what we think is a "
230 -                         "reasonable value (%d)\n",
231 -                         nf, ATH9K_NF_TOO_LOW);
232 -               return false;
233 -       }
234 -       return true;
235 -}
236 -
237  static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
238  {
239         int16_t nfval;
240 @@ -121,6 +104,19 @@ void ath9k_hw_reset_calibration(struct a
241         ah->cal_samples = 0;
242  }
243  
244 +static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
245 +                                  struct ath9k_channel *chan)
246 +{
247 +       struct ath_nf_limits *limit;
248 +
249 +       if (!chan || IS_CHAN_2GHZ(chan))
250 +               limit = &ah->nf_2g;
251 +       else
252 +               limit = &ah->nf_5g;
253 +
254 +       return limit->nominal;
255 +}
256 +
257  /* This is done for the currently configured channel */
258  bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
259  {
260 @@ -128,7 +124,7 @@ bool ath9k_hw_reset_calvalid(struct ath_
261         struct ieee80211_conf *conf = &common->hw->conf;
262         struct ath9k_cal_list *currCal = ah->cal_list_curr;
263  
264 -       if (!ah->curchan)
265 +       if (!ah->caldata)
266                 return true;
267  
268         if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
269 @@ -151,37 +147,55 @@ bool ath9k_hw_reset_calvalid(struct ath_
270                   "Resetting Cal %d state for channel %u\n",
271                   currCal->calData->calType, conf->channel->center_freq);
272  
273 -       ah->curchan->CalValid &= ~currCal->calData->calType;
274 +       ah->caldata->CalValid &= ~currCal->calData->calType;
275         currCal->calState = CAL_WAITING;
276  
277         return false;
278  }
279  EXPORT_SYMBOL(ath9k_hw_reset_calvalid);
280  
281 -void ath9k_hw_start_nfcal(struct ath_hw *ah)
282 +void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update)
283  {
284 +       if (ah->caldata)
285 +               ah->caldata->nfcal_pending = true;
286 +
287         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
288                     AR_PHY_AGC_CONTROL_ENABLE_NF);
289 -       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
290 +
291 +       if (update)
292 +               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
293 +                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
294 +       else
295 +               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
296                     AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
297 +
298         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
299  }
300  
301  void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
302  {
303 -       struct ath9k_nfcal_hist *h;
304 +       struct ath9k_nfcal_hist *h = NULL;
305         unsigned i, j;
306         int32_t val;
307         u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
308         struct ath_common *common = ath9k_hw_common(ah);
309 +       s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
310  
311 -       h = ah->nfCalHist;
312 +       if (ah->caldata)
313 +               h = ah->caldata->nfCalHist;
314  
315         for (i = 0; i < NUM_NF_READINGS; i++) {
316                 if (chainmask & (1 << i)) {
317 +                       s16 nfval;
318 +
319 +                       if (h)
320 +                               nfval = h[i].privNF;
321 +                       else
322 +                               nfval = default_nf;
323 +
324                         val = REG_READ(ah, ah->nf_regs[i]);
325                         val &= 0xFFFFFE00;
326 -                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
327 +                       val |= (((u32) nfval << 1) & 0x1ff);
328                         REG_WRITE(ah, ah->nf_regs[i], val);
329                 }
330         }
331 @@ -277,22 +291,25 @@ static void ath9k_hw_nf_sanitize(struct 
332         }
333  }
334  
335 -int16_t ath9k_hw_getnf(struct ath_hw *ah,
336 -                      struct ath9k_channel *chan)
337 +bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
338  {
339         struct ath_common *common = ath9k_hw_common(ah);
340         int16_t nf, nfThresh;
341         int16_t nfarray[NUM_NF_READINGS] = { 0 };
342         struct ath9k_nfcal_hist *h;
343         struct ieee80211_channel *c = chan->chan;
344 +       struct ath9k_hw_cal_data *caldata = ah->caldata;
345 +
346 +       if (!caldata)
347 +               return false;
348  
349         chan->channelFlags &= (~CHANNEL_CW_INT);
350         if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
351                 ath_print(common, ATH_DBG_CALIBRATE,
352                           "NF did not complete in calibration window\n");
353                 nf = 0;
354 -               chan->rawNoiseFloor = nf;
355 -               return chan->rawNoiseFloor;
356 +               caldata->rawNoiseFloor = nf;
357 +               return false;
358         } else {
359                 ath9k_hw_do_getnf(ah, nfarray);
360                 ath9k_hw_nf_sanitize(ah, nfarray);
361 @@ -307,47 +324,40 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
362                 }
363         }
364  
365 -       h = ah->nfCalHist;
366 -
367 +       h = caldata->nfCalHist;
368 +       caldata->nfcal_pending = false;
369         ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
370 -       chan->rawNoiseFloor = h[0].privNF;
371 -
372 -       return chan->rawNoiseFloor;
373 +       caldata->rawNoiseFloor = h[0].privNF;
374 +       return true;
375  }
376  
377 -void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
378 +void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
379 +                                 struct ath9k_channel *chan)
380  {
381 -       struct ath_nf_limits *limit;
382 +       struct ath9k_nfcal_hist *h;
383 +       s16 default_nf;
384         int i, j;
385  
386 -       if (!ah->curchan || IS_CHAN_2GHZ(ah->curchan))
387 -               limit = &ah->nf_2g;
388 -       else
389 -               limit = &ah->nf_5g;
390 +       if (!ah->caldata)
391 +               return;
392  
393 +       h = ah->caldata->nfCalHist;
394 +       default_nf = ath9k_hw_get_default_nf(ah, chan);
395         for (i = 0; i < NUM_NF_READINGS; i++) {
396 -               ah->nfCalHist[i].currIndex = 0;
397 -               ah->nfCalHist[i].privNF = limit->nominal;
398 -               ah->nfCalHist[i].invalidNFcount =
399 -                       AR_PHY_CCA_FILTERWINDOW_LENGTH;
400 +               h[i].currIndex = 0;
401 +               h[i].privNF = default_nf;
402 +               h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH;
403                 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
404 -                       ah->nfCalHist[i].nfCalBuffer[j] = limit->nominal;
405 +                       h[i].nfCalBuffer[j] = default_nf;
406                 }
407         }
408  }
409  
410  s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
411  {
412 -       s16 nf;
413 -
414 -       if (chan->rawNoiseFloor == 0)
415 -               nf = -96;
416 -       else
417 -               nf = chan->rawNoiseFloor;
418 -
419 -       if (!ath9k_hw_nf_in_range(ah, nf))
420 -               nf = ATH_DEFAULT_NOISE_FLOOR;
421 +       if (!ah->caldata || !ah->caldata->rawNoiseFloor)
422 +               return ath9k_hw_get_default_nf(ah, chan);
423  
424 -       return nf;
425 +       return ah->caldata->rawNoiseFloor;
426  }
427  EXPORT_SYMBOL(ath9k_hw_getchan_noise);
428 --- a/drivers/net/wireless/ath/ath9k/calib.h
429 +++ b/drivers/net/wireless/ath/ath9k/calib.h
430 @@ -108,11 +108,11 @@ struct ath9k_pacal_info{
431  };
432  
433  bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
434 -void ath9k_hw_start_nfcal(struct ath_hw *ah);
435 +void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update);
436  void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
437 -int16_t ath9k_hw_getnf(struct ath_hw *ah,
438 -                      struct ath9k_channel *chan);
439 -void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
440 +bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
441 +void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
442 +                                 struct ath9k_channel *chan);
443  s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
444  void ath9k_hw_reset_calibration(struct ath_hw *ah,
445                                 struct ath9k_cal_list *currCal);
446 --- a/drivers/net/wireless/ath/ath9k/hw.c
447 +++ b/drivers/net/wireless/ath/ath9k/hw.c
448 @@ -622,7 +622,6 @@ static int __ath9k_hw_init(struct ath_hw
449         else
450                 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
451  
452 -       ath9k_init_nfcal_hist_buffer(ah);
453         ah->bb_watchdog_timeout_ms = 25;
454  
455         common->state = ATH_HW_INITIALIZED;
456 @@ -1195,9 +1194,6 @@ static bool ath9k_hw_channel_change(stru
457  
458         ath9k_hw_spur_mitigate_freq(ah, chan);
459  
460 -       if (!chan->oneTimeCalsDone)
461 -               chan->oneTimeCalsDone = true;
462 -
463         return true;
464  }
465  
466 @@ -1230,7 +1226,7 @@ bool ath9k_hw_check_alive(struct ath_hw 
467  EXPORT_SYMBOL(ath9k_hw_check_alive);
468  
469  int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
470 -                   bool bChannelChange)
471 +                  struct ath9k_hw_cal_data *caldata, bool bChannelChange)
472  {
473         struct ath_common *common = ath9k_hw_common(ah);
474         u32 saveLedState;
475 @@ -1255,9 +1251,19 @@ int ath9k_hw_reset(struct ath_hw *ah, st
476         if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
477                 return -EIO;
478  
479 -       if (curchan && !ah->chip_fullsleep)
480 +       if (curchan && !ah->chip_fullsleep && ah->caldata)
481                 ath9k_hw_getnf(ah, curchan);
482  
483 +       ah->caldata = caldata;
484 +       if (caldata &&
485 +           (chan->channel != caldata->channel ||
486 +            (chan->channelFlags & ~CHANNEL_CW_INT) !=
487 +            (caldata->channelFlags & ~CHANNEL_CW_INT))) {
488 +               /* Operating channel changed, reset channel calibration data */
489 +               memset(caldata, 0, sizeof(*caldata));
490 +               ath9k_init_nfcal_hist_buffer(ah, chan);
491 +       }
492 +
493         if (bChannelChange &&
494             (ah->chip_fullsleep != true) &&
495             (ah->curchan != NULL) &&
496 @@ -1268,7 +1274,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
497  
498                 if (ath9k_hw_channel_change(ah, chan)) {
499                         ath9k_hw_loadnf(ah, ah->curchan);
500 -                       ath9k_hw_start_nfcal(ah);
501 +                       ath9k_hw_start_nfcal(ah, true);
502                         return 0;
503                 }
504         }
505 @@ -1473,11 +1479,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
506         if (ah->btcoex_hw.enabled)
507                 ath9k_hw_btcoex_enable(ah);
508  
509 -       if (AR_SREV_9300_20_OR_LATER(ah)) {
510 -               ath9k_hw_loadnf(ah, curchan);
511 -               ath9k_hw_start_nfcal(ah);
512 +       if (AR_SREV_9300_20_OR_LATER(ah))
513                 ar9003_hw_bb_watchdog_config(ah);
514 -       }
515  
516         return 0;
517  }
518 --- a/drivers/net/wireless/ath/ath9k/main.c
519 +++ b/drivers/net/wireless/ath/ath9k/main.c
520 @@ -155,6 +155,27 @@ void ath9k_ps_restore(struct ath_softc *
521         spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
522  }
523  
524 +static void ath_start_ani(struct ath_common *common)
525 +{
526 +       struct ath_hw *ah = common->ah;
527 +       unsigned long timestamp = jiffies_to_msecs(jiffies);
528 +       struct ath_softc *sc = (struct ath_softc *) common->priv;
529 +
530 +       if (!(sc->sc_flags & SC_OP_ANI_RUN))
531 +               return;
532 +
533 +       if (sc->sc_flags & SC_OP_OFFCHANNEL)
534 +               return;
535 +
536 +       common->ani.longcal_timer = timestamp;
537 +       common->ani.shortcal_timer = timestamp;
538 +       common->ani.checkani_timer = timestamp;
539 +
540 +       mod_timer(&common->ani.timer,
541 +                 jiffies +
542 +                       msecs_to_jiffies((u32)ah->config.ani_poll_interval));
543 +}
544 +
545  /*
546   * Set/change channels.  If the channel is really being changed, it's done
547   * by reseting the chip.  To accomplish this we must first cleanup any pending
548 @@ -163,16 +184,23 @@ void ath9k_ps_restore(struct ath_softc *
549  int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
550                     struct ath9k_channel *hchan)
551  {
552 +       struct ath_wiphy *aphy = hw->priv;
553         struct ath_hw *ah = sc->sc_ah;
554         struct ath_common *common = ath9k_hw_common(ah);
555         struct ieee80211_conf *conf = &common->hw->conf;
556         bool fastcc = true, stopped;
557         struct ieee80211_channel *channel = hw->conf.channel;
558 +       struct ath9k_hw_cal_data *caldata = NULL;
559         int r;
560  
561         if (sc->sc_flags & SC_OP_INVALID)
562                 return -EIO;
563  
564 +       del_timer_sync(&common->ani.timer);
565 +       cancel_work_sync(&sc->paprd_work);
566 +       cancel_work_sync(&sc->hw_check_work);
567 +       cancel_delayed_work_sync(&sc->tx_complete_work);
568 +
569         ath9k_ps_wakeup(sc);
570  
571         /*
572 @@ -192,9 +220,12 @@ int ath_set_channel(struct ath_softc *sc
573          * to flush data frames already in queue because of
574          * changing channel. */
575  
576 -       if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
577 +       if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
578                 fastcc = false;
579  
580 +       if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
581 +               caldata = &aphy->caldata;
582 +
583         ath_print(common, ATH_DBG_CONFIG,
584                   "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n",
585                   sc->sc_ah->curchan->channel,
586 @@ -202,7 +233,7 @@ int ath_set_channel(struct ath_softc *sc
587  
588         spin_lock_bh(&sc->sc_resetlock);
589  
590 -       r = ath9k_hw_reset(ah, hchan, fastcc);
591 +       r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
592         if (r) {
593                 ath_print(common, ATH_DBG_FATAL,
594                           "Unable to reset channel (%u MHz), "
595 @@ -213,8 +244,6 @@ int ath_set_channel(struct ath_softc *sc
596         }
597         spin_unlock_bh(&sc->sc_resetlock);
598  
599 -       sc->sc_flags &= ~SC_OP_FULL_RESET;
600 -
601         if (ath_startrecv(sc) != 0) {
602                 ath_print(common, ATH_DBG_FATAL,
603                           "Unable to restart recv logic\n");
604 @@ -226,6 +255,12 @@ int ath_set_channel(struct ath_softc *sc
605         ath_update_txpow(sc);
606         ath9k_hw_set_interrupts(ah, ah->imask);
607  
608 +       if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) {
609 +               ath_start_ani(common);
610 +               ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
611 +               ath_beacon_config(sc, NULL);
612 +       }
613 +
614   ps_restore:
615         ath9k_ps_restore(sc);
616         return r;
617 @@ -234,17 +269,19 @@ int ath_set_channel(struct ath_softc *sc
618  static void ath_paprd_activate(struct ath_softc *sc)
619  {
620         struct ath_hw *ah = sc->sc_ah;
621 +       struct ath9k_hw_cal_data *caldata = ah->caldata;
622         int chain;
623  
624 -       if (!ah->curchan->paprd_done)
625 +       if (!caldata || !caldata->paprd_done)
626                 return;
627  
628         ath9k_ps_wakeup(sc);
629 +       ar9003_paprd_enable(ah, false);
630         for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
631                 if (!(ah->caps.tx_chainmask & BIT(chain)))
632                         continue;
633  
634 -               ar9003_paprd_populate_single_table(ah, ah->curchan, chain);
635 +               ar9003_paprd_populate_single_table(ah, caldata, chain);
636         }
637  
638         ar9003_paprd_enable(ah, true);
639 @@ -262,6 +299,7 @@ void ath_paprd_calibrate(struct work_str
640         int band = hw->conf.channel->band;
641         struct ieee80211_supported_band *sband = &sc->sbands[band];
642         struct ath_tx_control txctl;
643 +       struct ath9k_hw_cal_data *caldata = ah->caldata;
644         int qnum, ftype;
645         int chain_ok = 0;
646         int chain;
647 @@ -269,6 +307,9 @@ void ath_paprd_calibrate(struct work_str
648         int time_left;
649         int i;
650  
651 +       if (!caldata)
652 +               return;
653 +
654         skb = alloc_skb(len, GFP_KERNEL);
655         if (!skb)
656                 return;
657 @@ -323,7 +364,7 @@ void ath_paprd_calibrate(struct work_str
658                 if (!ar9003_paprd_is_done(ah))
659                         break;
660  
661 -               if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0)
662 +               if (ar9003_paprd_create_curve(ah, caldata, chain) != 0)
663                         break;
664  
665                 chain_ok = 1;
666 @@ -331,7 +372,7 @@ void ath_paprd_calibrate(struct work_str
667         kfree_skb(skb);
668  
669         if (chain_ok) {
670 -               ah->curchan->paprd_done = true;
671 +               caldata->paprd_done = true;
672                 ath_paprd_activate(sc);
673         }
674  
675 @@ -440,33 +481,14 @@ set_timer:
676                 cal_interval = min(cal_interval, (u32)short_cal_interval);
677  
678         mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
679 -       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
680 -           !(sc->sc_flags & SC_OP_SCANNING)) {
681 -               if (!sc->sc_ah->curchan->paprd_done)
682 +       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
683 +               if (!ah->caldata->paprd_done)
684                         ieee80211_queue_work(sc->hw, &sc->paprd_work);
685                 else
686                         ath_paprd_activate(sc);
687         }
688  }
689  
690 -static void ath_start_ani(struct ath_common *common)
691 -{
692 -       struct ath_hw *ah = common->ah;
693 -       unsigned long timestamp = jiffies_to_msecs(jiffies);
694 -       struct ath_softc *sc = (struct ath_softc *) common->priv;
695 -
696 -       if (!(sc->sc_flags & SC_OP_ANI_RUN))
697 -               return;
698 -
699 -       common->ani.longcal_timer = timestamp;
700 -       common->ani.shortcal_timer = timestamp;
701 -       common->ani.checkani_timer = timestamp;
702 -
703 -       mod_timer(&common->ani.timer,
704 -                 jiffies +
705 -                       msecs_to_jiffies((u32)ah->config.ani_poll_interval));
706 -}
707 -
708  /*
709   * Update tx/rx chainmask. For legacy association,
710   * hard code chainmask to 1x1, for 11n association, use
711 @@ -478,7 +500,7 @@ void ath_update_chainmask(struct ath_sof
712         struct ath_hw *ah = sc->sc_ah;
713         struct ath_common *common = ath9k_hw_common(ah);
714  
715 -       if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
716 +       if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
717             (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
718                 common->tx_chainmask = ah->caps.tx_chainmask;
719                 common->rx_chainmask = ah->caps.rx_chainmask;
720 @@ -818,7 +840,7 @@ void ath_radio_enable(struct ath_softc *
721                 ah->curchan = ath_get_curchannel(sc, sc->hw);
722  
723         spin_lock_bh(&sc->sc_resetlock);
724 -       r = ath9k_hw_reset(ah, ah->curchan, false);
725 +       r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
726         if (r) {
727                 ath_print(common, ATH_DBG_FATAL,
728                           "Unable to reset channel (%u MHz), "
729 @@ -878,7 +900,7 @@ void ath_radio_disable(struct ath_softc 
730                 ah->curchan = ath_get_curchannel(sc, hw);
731  
732         spin_lock_bh(&sc->sc_resetlock);
733 -       r = ath9k_hw_reset(ah, ah->curchan, false);
734 +       r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
735         if (r) {
736                 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
737                           "Unable to reset channel (%u MHz), "
738 @@ -911,7 +933,7 @@ int ath_reset(struct ath_softc *sc, bool
739         ath_flushrecv(sc);
740  
741         spin_lock_bh(&sc->sc_resetlock);
742 -       r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
743 +       r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
744         if (r)
745                 ath_print(common, ATH_DBG_FATAL,
746                           "Unable to reset hardware; reset status %d\n", r);
747 @@ -1086,7 +1108,7 @@ static int ath9k_start(struct ieee80211_
748          * and then setup of the interrupt mask.
749          */
750         spin_lock_bh(&sc->sc_resetlock);
751 -       r = ath9k_hw_reset(ah, init_channel, false);
752 +       r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
753         if (r) {
754                 ath_print(common, ATH_DBG_FATAL,
755                           "Unable to reset hardware; reset status %d "
756 @@ -1580,6 +1602,10 @@ static int ath9k_config(struct ieee80211
757  
758                 aphy->chan_idx = pos;
759                 aphy->chan_is_ht = conf_is_ht(conf);
760 +               if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
761 +                       sc->sc_flags |= SC_OP_OFFCHANNEL;
762 +               else
763 +                       sc->sc_flags &= ~SC_OP_OFFCHANNEL;
764  
765                 if (aphy->state == ATH_WIPHY_SCAN ||
766                     aphy->state == ATH_WIPHY_ACTIVE)
767 @@ -1991,7 +2017,6 @@ static void ath9k_sw_scan_start(struct i
768  {
769         struct ath_wiphy *aphy = hw->priv;
770         struct ath_softc *sc = aphy->sc;
771 -       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
772  
773         mutex_lock(&sc->mutex);
774         if (ath9k_wiphy_scanning(sc)) {
775 @@ -2009,10 +2034,6 @@ static void ath9k_sw_scan_start(struct i
776         aphy->state = ATH_WIPHY_SCAN;
777         ath9k_wiphy_pause_all_forced(sc, aphy);
778         sc->sc_flags |= SC_OP_SCANNING;
779 -       del_timer_sync(&common->ani.timer);
780 -       cancel_work_sync(&sc->paprd_work);
781 -       cancel_work_sync(&sc->hw_check_work);
782 -       cancel_delayed_work_sync(&sc->tx_complete_work);
783         mutex_unlock(&sc->mutex);
784  }
785  
786 @@ -2024,15 +2045,10 @@ static void ath9k_sw_scan_complete(struc
787  {
788         struct ath_wiphy *aphy = hw->priv;
789         struct ath_softc *sc = aphy->sc;
790 -       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
791  
792         mutex_lock(&sc->mutex);
793         aphy->state = ATH_WIPHY_ACTIVE;
794         sc->sc_flags &= ~SC_OP_SCANNING;
795 -       sc->sc_flags |= SC_OP_FULL_RESET;
796 -       ath_start_ani(common);
797 -       ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
798 -       ath_beacon_config(sc, NULL);
799         mutex_unlock(&sc->mutex);
800  }
801  
802 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
803 +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
804 @@ -577,10 +577,11 @@ static bool create_pa_curve(u32 *data_L,
805  }
806  
807  void ar9003_paprd_populate_single_table(struct ath_hw *ah,
808 -                                       struct ath9k_channel *chan, int chain)
809 +                                       struct ath9k_hw_cal_data *caldata,
810 +                                       int chain)
811  {
812 -       u32 *paprd_table_val = chan->pa_table[chain];
813 -       u32 small_signal_gain = chan->small_signal_gain[chain];
814 +       u32 *paprd_table_val = caldata->pa_table[chain];
815 +       u32 small_signal_gain = caldata->small_signal_gain[chain];
816         u32 training_power;
817         u32 reg = 0;
818         int i;
819 @@ -654,17 +655,17 @@ int ar9003_paprd_setup_gain_table(struct
820  }
821  EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);
822  
823 -int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan,
824 -                             int chain)
825 +int ar9003_paprd_create_curve(struct ath_hw *ah,
826 +                             struct ath9k_hw_cal_data *caldata, int chain)
827  {
828 -       u16 *small_signal_gain = &chan->small_signal_gain[chain];
829 -       u32 *pa_table = chan->pa_table[chain];
830 +       u16 *small_signal_gain = &caldata->small_signal_gain[chain];
831 +       u32 *pa_table = caldata->pa_table[chain];
832         u32 *data_L, *data_U;
833         int i, status = 0;
834         u32 *buf;
835         u32 reg;
836  
837 -       memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain]));
838 +       memset(caldata->pa_table[chain], 0, sizeof(caldata->pa_table[chain]));
839  
840         buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC);
841         if (!buf)
842 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
843 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
844 @@ -511,7 +511,7 @@ void ath_deinit_leds(struct ath_softc *s
845  #define SC_OP_BEACONS                BIT(1)
846  #define SC_OP_RXAGGR                 BIT(2)
847  #define SC_OP_TXAGGR                 BIT(3)
848 -#define SC_OP_FULL_RESET             BIT(4)
849 +#define SC_OP_OFFCHANNEL             BIT(4)
850  #define SC_OP_PREAMBLE_SHORT         BIT(5)
851  #define SC_OP_PROTECT_ENABLE         BIT(6)
852  #define SC_OP_RXFLUSH                BIT(7)
853 @@ -612,6 +612,7 @@ struct ath_softc {
854  struct ath_wiphy {
855         struct ath_softc *sc; /* shared for all virtual wiphys */
856         struct ieee80211_hw *hw;
857 +       struct ath9k_hw_cal_data caldata;
858         enum ath_wiphy_state {
859                 ATH_WIPHY_INACTIVE,
860                 ATH_WIPHY_ACTIVE,
861 --- a/drivers/net/wireless/ath/ath9k/htc.h
862 +++ b/drivers/net/wireless/ath/ath9k/htc.h
863 @@ -353,6 +353,8 @@ struct ath9k_htc_priv {
864         u16 seq_no;
865         u32 bmiss_cnt;
866  
867 +       struct ath9k_hw_cal_data caldata[38];
868 +
869         spinlock_t beacon_lock;
870  
871         bool tx_queues_stop;
872 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
873 +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
874 @@ -125,6 +125,7 @@ static int ath9k_htc_set_channel(struct 
875         struct ieee80211_conf *conf = &common->hw->conf;
876         bool fastcc = true;
877         struct ieee80211_channel *channel = hw->conf.channel;
878 +       struct ath9k_hw_cal_data *caldata;
879         enum htc_phymode mode;
880         __be16 htc_mode;
881         u8 cmd_rsp;
882 @@ -149,7 +150,8 @@ static int ath9k_htc_set_channel(struct 
883                   priv->ah->curchan->channel,
884                   channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
885  
886 -       ret = ath9k_hw_reset(ah, hchan, fastcc);
887 +       caldata = &priv->caldata[channel->hw_value];
888 +       ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
889         if (ret) {
890                 ath_print(common, ATH_DBG_FATAL,
891                           "Unable to reset channel (%u Mhz) "
892 @@ -1028,7 +1030,7 @@ static void ath9k_htc_radio_enable(struc
893                 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
894  
895         /* Reset the HW */
896 -       ret = ath9k_hw_reset(ah, ah->curchan, false);
897 +       ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
898         if (ret) {
899                 ath_print(common, ATH_DBG_FATAL,
900                           "Unable to reset hardware; reset status %d "
901 @@ -1091,7 +1093,7 @@ static void ath9k_htc_radio_disable(stru
902                 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
903  
904         /* Reset the HW */
905 -       ret = ath9k_hw_reset(ah, ah->curchan, false);
906 +       ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
907         if (ret) {
908                 ath_print(common, ATH_DBG_FATAL,
909                           "Unable to reset hardware; reset status %d "
910 @@ -1179,7 +1181,7 @@ static int ath9k_htc_start(struct ieee80
911         ath9k_hw_configpcipowersave(ah, 0, 0);
912  
913         ath9k_hw_htc_resetinit(ah);
914 -       ret = ath9k_hw_reset(ah, init_channel, false);
915 +       ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
916         if (ret) {
917                 ath_print(common, ATH_DBG_FATAL,
918                           "Unable to reset hardware; reset status %d "
919 --- a/drivers/net/wireless/ath/ath9k/hw.h
920 +++ b/drivers/net/wireless/ath/ath9k/hw.h
921 @@ -346,19 +346,25 @@ enum ath9k_int {
922          CHANNEL_HT40PLUS |                     \
923          CHANNEL_HT40MINUS)
924  
925 -struct ath9k_channel {
926 -       struct ieee80211_channel *chan;
927 +struct ath9k_hw_cal_data {
928         u16 channel;
929         u32 channelFlags;
930 -       u32 chanmode;
931         int32_t CalValid;
932 -       bool oneTimeCalsDone;
933         int8_t iCoff;
934         int8_t qCoff;
935         int16_t rawNoiseFloor;
936         bool paprd_done;
937 +       bool nfcal_pending;
938         u16 small_signal_gain[AR9300_MAX_CHAINS];
939         u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
940 +       struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
941 +};
942 +
943 +struct ath9k_channel {
944 +       struct ieee80211_channel *chan;
945 +       u16 channel;
946 +       u32 channelFlags;
947 +       u32 chanmode;
948  };
949  
950  #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
951 @@ -669,7 +675,7 @@ struct ath_hw {
952         enum nl80211_iftype opmode;
953         enum ath9k_power_mode power_mode;
954  
955 -       struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
956 +       struct ath9k_hw_cal_data *caldata;
957         struct ath9k_pacal_info pacal_info;
958         struct ar5416Stats stats;
959         struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
960 @@ -863,7 +869,7 @@ const char *ath9k_hw_probe(u16 vendorid,
961  void ath9k_hw_deinit(struct ath_hw *ah);
962  int ath9k_hw_init(struct ath_hw *ah);
963  int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
964 -                  bool bChannelChange);
965 +                  struct ath9k_hw_cal_data *caldata, bool bChannelChange);
966  int ath9k_hw_fill_cap_info(struct ath_hw *ah);
967  u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
968  
969 @@ -958,9 +964,10 @@ void ar9003_hw_bb_watchdog_read(struct a
970  void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);
971  void ar9003_paprd_enable(struct ath_hw *ah, bool val);
972  void ar9003_paprd_populate_single_table(struct ath_hw *ah,
973 -                                       struct ath9k_channel *chan, int chain);
974 -int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan,
975 -                             int chain);
976 +                                       struct ath9k_hw_cal_data *caldata,
977 +                                       int chain);
978 +int ar9003_paprd_create_curve(struct ath_hw *ah,
979 +                             struct ath9k_hw_cal_data *caldata, int chain);
980  int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
981  int ar9003_paprd_init_table(struct ath_hw *ah);
982  bool ar9003_paprd_is_done(struct ath_hw *ah);
983 --- a/drivers/net/wireless/ath/ath9k/xmit.c
984 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
985 @@ -1181,7 +1181,7 @@ void ath_drain_all_txq(struct ath_softc 
986                           "Failed to stop TX DMA. Resetting hardware!\n");
987  
988                 spin_lock_bh(&sc->sc_resetlock);
989 -               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
990 +               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
991                 if (r)
992                         ath_print(common, ATH_DBG_FATAL,
993                                   "Unable to reset hardware; reset status %d\n",