madwifi: reduce the size of the multicall tool binary
[openwrt.git] / package / madwifi / patches / 421-channel_handling.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -148,7 +148,6 @@ static int ath_key_set(struct ieee80211v
4  static void ath_key_update_begin(struct ieee80211vap *);
5  static void ath_key_update_end(struct ieee80211vap *);
6  static void ath_mode_init(struct net_device *);
7 -static void ath_setslottime(struct ath_softc *);
8  static void ath_updateslot(struct net_device *);
9  static int ath_beaconq_setup(struct ath_softc *);
10  static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *);
11 @@ -240,7 +239,7 @@ static void ath_setup_stationkey(struct 
12  static void ath_setup_stationwepkey(struct ieee80211_node *);
13  static void ath_setup_keycacheslot(struct ath_softc *, struct ieee80211_node *);
14  static void ath_newassoc(struct ieee80211_node *, int);
15 -static int ath_getchannels(struct net_device *, u_int, HAL_BOOL, HAL_BOOL);
16 +static int ath_getchannels(struct net_device *);
17  static void ath_led_event(struct ath_softc *, int);
18  static void ath_update_txpow(struct ath_softc *);
19  
20 @@ -265,7 +264,6 @@ static int ath_change_mtu(struct net_dev
21  static int ath_ioctl(struct net_device *, struct ifreq *, int);
22  
23  static int ath_rate_setup(struct net_device *, u_int);
24 -static void ath_setup_subrates(struct net_device *);
25  #ifdef ATH_SUPERG_XR
26  static int ath_xr_rate_setup(struct net_device *);
27  static void ath_grppoll_txq_setup(struct ath_softc *, int, int);
28 @@ -387,8 +385,6 @@ static void ath_fetch_idle_time(struct a
29  
30  /* calibrate every 30 secs in steady state but check every second at first. */
31  static int ath_calinterval = ATH_SHORT_CALINTERVAL;
32 -static int ath_countrycode = CTRY_DEFAULT;     /* country code */
33 -static int ath_outdoor = AH_FALSE;             /* enable outdoor use */
34  static int ath_xchanmode = AH_TRUE;            /* enable extended channels */
35  static int ath_maxvaps = ATH_MAXVAPS_DEFAULT;   /* set default maximum vaps */
36  static int bstuck_thresh = BSTUCK_THRESH;       /* Stuck beacon count required for reset */
37 @@ -396,9 +392,7 @@ static char *autocreate = NULL;
38  static char *ratectl = DEF_RATE_CTL;
39  static int rfkill = 0;
40  static int tpc = 1;
41 -static int countrycode = -1;
42  static int maxvaps = -1;
43 -static int outdoor = -1;
44  static int xchanmode = -1;
45  #include "ath_wprobe.c"
46  static int beacon_cal = 1;
47 @@ -437,9 +431,7 @@ static struct notifier_block ath_event_b
48  
49  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
50  MODULE_PARM(beacon_cal, "i");
51 -MODULE_PARM(countrycode, "i");
52  MODULE_PARM(maxvaps, "i");
53 -MODULE_PARM(outdoor, "i");
54  MODULE_PARM(xchanmode, "i");
55  MODULE_PARM(rfkill, "i");
56  #ifdef ATH_CAP_TPC
57 @@ -451,9 +443,7 @@ MODULE_PARM(ratectl, "s");
58  #else
59  #include <linux/moduleparam.h>
60  module_param(beacon_cal, int, 0600);
61 -module_param(countrycode, int, 0600);
62  module_param(maxvaps, int, 0600);
63 -module_param(outdoor, int, 0600);
64  module_param(xchanmode, int, 0600);
65  module_param(rfkill, int, 0600);
66  #ifdef ATH_CAP_TPC
67 @@ -463,9 +453,7 @@ module_param(bstuck_thresh, int, 0600);
68  module_param(autocreate, charp, 0600);
69  module_param(ratectl, charp, 0600);
70  #endif
71 -MODULE_PARM_DESC(countrycode, "Override default country code");
72  MODULE_PARM_DESC(maxvaps, "Maximum VAPs");
73 -MODULE_PARM_DESC(outdoor, "Enable/disable outdoor use");
74  MODULE_PARM_DESC(xchanmode, "Enable/disable extended channel mode");
75  MODULE_PARM_DESC(rfkill, "Enable/disable RFKILL capability");
76  #ifdef ATH_CAP_TPC
77 @@ -531,6 +519,50 @@ MODULE_PARM_DESC(ieee80211_debug, "Load-
78                                 (bssid)[0] |= (((id) << 2) | 0x02);     \
79                 } while (0)
80  
81 +static inline int ath_chan2mode(struct ieee80211_channel *c)
82 +{
83 +       if (IEEE80211_IS_CHAN_HALF(c))
84 +               return ATH_MODE_HALF;
85 +       else if (IEEE80211_IS_CHAN_QUARTER(c))
86 +               return ATH_MODE_QUARTER;
87 +       else
88 +               return ieee80211_chan2mode(c);
89 +}
90 +
91 +static inline int rate_hal2ieee(int dot11Rate, int f)
92 +{
93 +       int flag = dot11Rate & ~(IEEE80211_RATE_VAL);
94 +       dot11Rate &= IEEE80211_RATE_VAL;
95 +
96 +       if (f == 4) { /* Quarter */
97 +               if (dot11Rate == 4)
98 +                       return 18 | flag;
99 +       }
100 +       return (dot11Rate * f) | flag;
101 +}
102 +
103 +static inline int rate_factor(int mode)
104 +{
105 +       int f;
106 +
107 +       /*
108 +        * NB: Fix up rates. HAL returns half or quarter dot11Rates,
109 +        * while the stack deals with full rates only
110 +        */
111 +       switch(mode) {
112 +               case ATH_MODE_HALF:
113 +                       f = 2;
114 +                       break;
115 +               case ATH_MODE_QUARTER:
116 +                       f = 4;
117 +                       break;
118 +               default:
119 +                       f = 1;
120 +                       break;
121 +       }
122 +       return f;
123 +}
124 +
125  /* Initialize ath_softc structure */
126  
127  int
128 @@ -647,14 +679,6 @@ ath_attach(u_int16_t devid, struct net_d
129         for (i = 0; i < sc->sc_keymax; i++)
130                 ath_hal_keyreset(ah, i);
131  
132 -       /*
133 -        * Collect the channel list using the default country
134 -        * code and including outdoor channels.  The 802.11 layer
135 -        * is responsible for filtering this list based on settings
136 -        * like the phy mode.
137 -        */
138 -       if (countrycode != -1)
139 -               ath_countrycode = countrycode;
140         if (maxvaps != -1) {
141                 ath_maxvaps = maxvaps;
142                 if (ath_maxvaps < ATH_MAXVAPS_MIN)
143 @@ -662,17 +686,14 @@ ath_attach(u_int16_t devid, struct net_d
144                 else if (ath_maxvaps > ATH_MAXVAPS_MAX)
145                         ath_maxvaps = ATH_MAXVAPS_MAX;
146         }
147 -       if (outdoor != -1)
148 -               ath_outdoor = outdoor;
149         if (xchanmode != -1)
150                 ath_xchanmode = xchanmode;
151 -       error = ath_getchannels(dev, ath_countrycode,
152 -                       ath_outdoor, ath_xchanmode);
153 +       error = ath_getchannels(dev);
154         if (error != 0)
155                 goto bad;
156  
157 -       ic->ic_country_code = ath_countrycode;
158 -       ic->ic_country_outdoor = ath_outdoor;
159 +       ic->ic_country_code = CTRY_DEFAULT;
160 +       ic->ic_country_outdoor = 0;
161  
162         IPRINTF(sc, "Switching rfkill capability %s\n",
163                 rfkill ? "on" : "off");
164 @@ -686,9 +707,8 @@ ath_attach(u_int16_t devid, struct net_d
165         ath_rate_setup(dev, IEEE80211_MODE_11G);
166         ath_rate_setup(dev, IEEE80211_MODE_TURBO_A);
167         ath_rate_setup(dev, IEEE80211_MODE_TURBO_G);
168 -
169 -       /* Setup for half/quarter rates */
170 -       ath_setup_subrates(dev);
171 +       ath_rate_setup(dev, ATH_MODE_HALF);
172 +       ath_rate_setup(dev, ATH_MODE_QUARTER);
173  
174         /* NB: setup here so ath_rate_update is happy */
175         ath_setcurmode(sc, IEEE80211_MODE_11A);
176 @@ -908,10 +928,6 @@ ath_attach(u_int16_t devid, struct net_d
177                         IEEE80211_ATHC_COMP : 0);
178  #endif
179  
180 -#ifdef ATH_SUPERG_DYNTURBO
181 -       ic->ic_ath_cap |= (ath_hal_turboagsupported(ah, ath_countrycode) ? 
182 -                       (IEEE80211_ATHC_TURBOP | IEEE80211_ATHC_AR) : 0);
183 -#endif
184  #ifdef ATH_SUPERG_XR
185         ic->ic_ath_cap |= (ath_hal_xrsupported(ah) ? IEEE80211_ATHC_XR : 0);
186  #endif
187 @@ -4470,17 +4486,17 @@ ath_mode_init(struct net_device *dev)
188   * Set the slot time based on the current setting.
189   */
190  static void
191 -ath_setslottime(struct ath_softc *sc)
192 +ath_settiming(struct ath_softc *sc)
193  {
194 -       struct ieee80211com *ic = &sc->sc_ic;
195         struct ath_hal *ah = sc->sc_ah;
196 +       u_int offset = getTimingOffset(sc);
197  
198 -       if (sc->sc_slottimeconf > 0) /* manual override */
199 -               ath_hal_setslottime(ah, sc->sc_slottimeconf);
200 -       else if (ic->ic_flags & IEEE80211_F_SHSLOT)
201 -               ath_hal_setslottime(ah, HAL_SLOT_TIME_9);
202 -       else
203 -               ath_hal_setslottime(ah, HAL_SLOT_TIME_20);
204 +       if (sc->sc_slottimeconf > 0)
205 +               ath_hal_setslottime(ah, offset + sc->sc_slottimeconf);
206 +       if (sc->sc_acktimeconf > 0)
207 +               ath_hal_setacktimeout(ah, 2 * offset + sc->sc_acktimeconf);
208 +       if (sc->sc_ctstimeconf > 0)
209 +               ath_hal_setctstimeout(ah, 2 * offset + sc->sc_ctstimeconf);
210         sc->sc_updateslot = OK;
211  }
212  
213 @@ -4502,7 +4518,7 @@ ath_updateslot(struct net_device *dev)
214         if (ic->ic_opmode == IEEE80211_M_HOSTAP)
215                 sc->sc_updateslot = UPDATE;
216         else if (dev->flags & IFF_RUNNING)
217 -               ath_setslottime(sc);
218 +               ath_settiming(sc);
219  }
220  
221  #ifdef ATH_SUPERG_DYNTURBO
222 @@ -5346,7 +5362,7 @@ ath_beacon_send(struct ath_softc *sc, in
223                 sc->sc_updateslot = COMMIT;     /* commit next beacon */
224                 sc->sc_slotupdate = slot;
225         } else if ((sc->sc_updateslot == COMMIT) && (sc->sc_slotupdate == slot))
226 -               ath_setslottime(sc);            /* commit change to hardware */
227 +               ath_settiming(sc);              /* commit change to hardware */
228  
229         if (bfaddr != 0) {
230                 /*
231 @@ -7802,12 +7818,14 @@ ath_get_ivlen(struct ieee80211_key *k)
232   * Get transmit rate index using rate in Kbps
233   */
234  static __inline int
235 -ath_tx_findindex(const HAL_RATE_TABLE *rt, int rate)
236 +ath_tx_findindex(struct ath_softc *sc, const HAL_RATE_TABLE *rt, int rate)
237  {
238         unsigned int i, ndx = 0;
239 +       int f;
240  
241 +       f = rate_factor(sc->sc_curmode);
242         for (i = 0; i < rt->rateCount; i++) {
243 -               if (rt->info[i].rateKbps == rate) {
244 +               if ((rt->info[i].rateKbps * f) == rate) {
245                         ndx = i;
246                         break;
247                 }
248 @@ -8100,7 +8118,7 @@ ath_tx_start(struct net_device *dev, str
249                 atype = HAL_PKT_TYPE_NORMAL;            /* default */
250  
251                 if (ismcast) {
252 -                       rix = ath_tx_findindex(rt, vap->iv_mcast_rate);
253 +                       rix = ath_tx_findindex(sc, rt, vap->iv_mcast_rate);
254                         txrate = rt->info[rix].rateCode;
255                         if (shortPreamble)
256                                 txrate |= rt->info[rix].shortPreamble;
257 @@ -9067,7 +9085,7 @@ ath_chan_change(struct ath_softc *sc, st
258         struct net_device *dev = sc->sc_dev;
259         enum ieee80211_phymode mode;
260  
261 -       mode = ieee80211_chan2mode(chan);
262 +       mode = ath_chan2mode(chan);
263  
264         ath_rate_setup(dev, mode);
265         ath_setcurmode(sc, mode);
266 @@ -10124,8 +10142,7 @@ ath_newassoc(struct ieee80211_node *ni, 
267  }
268  
269  static int
270 -ath_getchannels(struct net_device *dev, u_int cc,
271 -       HAL_BOOL outdoor, HAL_BOOL xchanmode)
272 +ath_getchannels(struct net_device *dev)
273  {
274         struct ath_softc *sc = dev->priv;
275         struct ieee80211com *ic = &sc->sc_ic;
276 @@ -10139,17 +10156,31 @@ ath_getchannels(struct net_device *dev, 
277                 EPRINTF(sc, "Insufficient memory for channel table!\n");
278                 return -ENOMEM;
279         }
280 +
281 +restart:
282         if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
283             ic->ic_regclassids, IEEE80211_REGCLASSIDS_MAX, &ic->ic_nregclass,
284 -           cc, HAL_MODE_ALL, outdoor, xchanmode)) {
285 +           ic->ic_country_code, HAL_MODE_ALL, ic->ic_country_outdoor, ath_xchanmode)) {
286                 u_int32_t rd;
287  
288                 ath_hal_getregdomain(ah, &rd);
289                 EPRINTF(sc, "Unable to collect channel list from HAL; "
290 -                       "regdomain likely %u country code %u\n", rd, cc);
291 +                       "regdomain likely %u country code %u\n", rd, ic->ic_country_code);
292 +               if ((ic->ic_country_code != CTRY_DEFAULT) ||
293 +                       (ic->ic_country_outdoor != 0)) {
294 +                       EPRINTF(sc, "Reverting to defaults\n");
295 +                       ic->ic_country_code = CTRY_DEFAULT;
296 +                       ic->ic_country_outdoor = 0;
297 +                       goto restart;
298 +               }
299                 kfree(chans);
300                 return -EINVAL;
301         }
302 +#ifdef ATH_SUPERG_DYNTURBO
303 +       ic->ic_ath_cap &= ~(IEEE80211_ATHC_TURBOP | IEEE80211_ATHC_AR);
304 +       ic->ic_ath_cap |= (ath_hal_turboagsupported(ah, ic->ic_country_code) ?
305 +                       (IEEE80211_ATHC_TURBOP | IEEE80211_ATHC_AR) : 0);
306 +#endif
307         /*
308          * Convert HAL channels to ieee80211 ones.
309          */
310 @@ -10395,7 +10426,7 @@ ath_xr_rate_setup(struct net_device *dev
311         struct ieee80211com *ic = &sc->sc_ic;
312         const HAL_RATE_TABLE *rt;
313         struct ieee80211_rateset *rs;
314 -       unsigned int i, maxrates;
315 +       unsigned int i, j, maxrates;
316         sc->sc_xr_rates = ath_hal_getratetable(ah, HAL_MODE_XR);
317         rt = sc->sc_xr_rates;
318         if (rt == NULL)
319 @@ -10408,57 +10439,16 @@ ath_xr_rate_setup(struct net_device *dev
320         } else
321                 maxrates = rt->rateCount;
322         rs = &ic->ic_sup_xr_rates;
323 -       for (i = 0; i < maxrates; i++)
324 -               rs->rs_rates[i] = rt->info[i].dot11Rate;
325 -       rs->rs_nrates = maxrates;
326 +       for (j = 0, i = 0; i < maxrates; i++) {
327 +               if (!rt->info[i].valid)
328 +                       continue;
329 +               rs->rs_rates[j++] = rt->info[i].dot11Rate;
330 +       }
331 +       rs->rs_nrates = j;
332         return 1;
333  }
334  #endif
335  
336 -/* Setup half/quarter rate table support */
337 -static void
338 -ath_setup_subrates(struct net_device *dev)
339 -{
340 -       struct ath_softc *sc = dev->priv;
341 -       struct ath_hal *ah = sc->sc_ah;
342 -       struct ieee80211com *ic = &sc->sc_ic;
343 -       const HAL_RATE_TABLE *rt;
344 -       struct ieee80211_rateset *rs;
345 -       unsigned int i, maxrates;
346 -
347 -       sc->sc_half_rates = ath_hal_getratetable(ah, HAL_MODE_11A_HALF_RATE);
348 -       rt = sc->sc_half_rates;
349 -       if (rt != NULL) {
350 -               if (rt->rateCount > IEEE80211_RATE_MAXSIZE) {
351 -                       DPRINTF(sc, ATH_DEBUG_ANY,
352 -                               "The rate table is too small (%u > %u)\n",
353 -                              rt->rateCount, IEEE80211_RATE_MAXSIZE);
354 -                       maxrates = IEEE80211_RATE_MAXSIZE;
355 -               } else
356 -                       maxrates = rt->rateCount;
357 -               rs = &ic->ic_sup_half_rates;
358 -               for (i = 0; i < maxrates; i++)
359 -                       rs->rs_rates[i] = rt->info[i].dot11Rate;
360 -               rs->rs_nrates = maxrates;
361 -       }
362 -
363 -       sc->sc_quarter_rates = ath_hal_getratetable(ah, HAL_MODE_11A_QUARTER_RATE);
364 -       rt = sc->sc_quarter_rates;
365 -       if (rt != NULL) {
366 -               if (rt->rateCount > IEEE80211_RATE_MAXSIZE) {
367 -                       DPRINTF(sc, ATH_DEBUG_ANY,
368 -                               "The rate table is too small (%u > %u)\n",
369 -                              rt->rateCount, IEEE80211_RATE_MAXSIZE);
370 -                       maxrates = IEEE80211_RATE_MAXSIZE;
371 -               } else
372 -                       maxrates = rt->rateCount;
373 -               rs = &ic->ic_sup_quarter_rates;
374 -               for (i = 0; i < maxrates; i++)
375 -                       rs->rs_rates[i] = rt->info[i].dot11Rate;
376 -               rs->rs_nrates = maxrates;
377 -       }
378 -}
379 -
380  static int
381  ath_rate_setup(struct net_device *dev, u_int mode)
382  {
383 @@ -10467,7 +10457,7 @@ ath_rate_setup(struct net_device *dev, u
384         struct ieee80211com *ic = &sc->sc_ic;
385         const HAL_RATE_TABLE *rt;
386         struct ieee80211_rateset *rs;
387 -       unsigned int i, maxrates;
388 +       unsigned int i, j, maxrates, f;
389  
390         switch (mode) {
391         case IEEE80211_MODE_11A:
392 @@ -10485,6 +10475,12 @@ ath_rate_setup(struct net_device *dev, u
393         case IEEE80211_MODE_TURBO_G:
394                 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_108G);
395                 break;
396 +       case ATH_MODE_HALF:
397 +               sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11A_HALF_RATE);
398 +               break;
399 +       case ATH_MODE_QUARTER:
400 +               sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11A_QUARTER_RATE);
401 +               break;
402         default:
403                 DPRINTF(sc, ATH_DEBUG_ANY, "Invalid mode %u\n", mode);
404                 return 0;
405 @@ -10499,10 +10495,16 @@ ath_rate_setup(struct net_device *dev, u
406                 maxrates = IEEE80211_RATE_MAXSIZE;
407         } else
408                 maxrates = rt->rateCount;
409 +
410 +       /* NB: quarter/half rate channels hijack the 11A rateset */
411 +       if (mode >= IEEE80211_MODE_MAX)
412 +               return 1;
413 +
414         rs = &ic->ic_sup_rates[mode];
415         for (i = 0; i < maxrates; i++)
416                 rs->rs_rates[i] = rt->info[i].dot11Rate;
417         rs->rs_nrates = maxrates;
418 +
419         return 1;
420  }
421  
422 @@ -10531,13 +10533,18 @@ ath_setcurmode(struct ath_softc *sc, enu
423                 {   0, 500, 130 },
424         };
425         const HAL_RATE_TABLE *rt;
426 -       unsigned int i, j;
427 +       unsigned int i, j, f;
428  
429 +       /*
430 +        * NB: Fix up rixmap. HAL returns half or quarter dot11Rates,
431 +        * while the stack deals with full rates only
432 +        */
433 +       f = rate_factor(mode);
434         memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
435         rt = sc->sc_rates[mode];
436         KASSERT(rt != NULL, ("no h/w rate set for phy mode %u", mode));
437         for (i = 0; i < rt->rateCount; i++)
438 -               sc->sc_rixmap[rt->info[i].dot11Rate & IEEE80211_RATE_VAL] = i;
439 +               sc->sc_rixmap[rate_hal2ieee(rt->info[i].dot11Rate, f) & IEEE80211_RATE_VAL] = i;
440         memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap));
441         for (i = 0; i < 32; i++) {
442                 u_int8_t ix = rt->rateCodeToIndex[i];
443 @@ -10547,7 +10554,7 @@ ath_setcurmode(struct ath_softc *sc, enu
444                         continue;
445                 }
446                 sc->sc_hwmap[i].ieeerate =
447 -                       rt->info[ix].dot11Rate & IEEE80211_RATE_VAL;
448 +                       rate_hal2ieee(rt->info[ix].dot11Rate, f) & IEEE80211_RATE_VAL;
449                 if (rt->info[ix].shortPreamble ||
450                     rt->info[ix].phy == IEEE80211_T_OFDM)
451                         sc->sc_hwmap[i].flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
452 @@ -10948,9 +10955,106 @@ enum {
453         ATH_MAXVAPS             = 26,
454         ATH_INTMIT                      = 27,
455         ATH_NOISE_IMMUNITY      = 28,
456 -       ATH_OFDM_WEAK_DET       = 29
457 +       ATH_OFDM_WEAK_DET       = 29,
458 +       ATH_CHANBW              = 30,
459 +       ATH_OUTDOOR             = 31,
460  };
461  
462 +/*
463 + * perform the channel related sysctl, reload the channel list
464 + * and try to stay on the current frequency
465 + */
466 +static int ath_sysctl_setchanparam(struct ath_softc *sc, unsigned long ctl, u_int val)
467 +{
468 +       struct ieee80211com *ic = &sc->sc_ic;
469 +       struct ath_hal *ah = sc->sc_ah;
470 +       struct ieee80211_channel *c = NULL;
471 +       struct ieee80211vap *vap;
472 +       u_int16_t freq = 0;
473 +       struct ifreq ifr;
474 +
475 +       if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
476 +               freq = ic->ic_curchan->ic_freq;
477 +
478 +       switch(ctl) {
479 +       case ATH_COUNTRYCODE:
480 +               ic->ic_country_code = val;
481 +               break;
482 +       case ATH_OUTDOOR:
483 +               ic->ic_country_outdoor = val;
484 +               break;
485 +       case ATH_CHANBW:
486 +               switch(val) {
487 +               case 0:
488 +               case 5:
489 +               case 10:
490 +               case 20:
491 +               case 40:
492 +                       if (ath_hal_setcapability(ah, HAL_CAP_CHANBW, 1, val, NULL) == AH_TRUE) {
493 +                               sc->sc_chanbw = val;
494 +                               break;
495 +                       }
496 +               default:
497 +                       return -EINVAL;
498 +               }
499 +               break;
500 +       }
501 +
502 +       if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
503 +               freq = ic->ic_curchan->ic_freq;
504 +
505 +       /* clear out any old state */
506 +       TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
507 +               vap->iv_des_mode = IEEE80211_MODE_AUTO;
508 +               vap->iv_des_chan = IEEE80211_CHAN_ANYC;
509 +       }
510 +       ieee80211_scan_flush(ic);
511 +
512 +       IEEE80211_LOCK_IRQ(ic);
513 +       ath_getchannels(sc->sc_dev);
514 +       ieee80211_update_channels(ic, 0);
515 +       if (freq)
516 +               c = ieee80211_find_channel(ic, freq, IEEE80211_MODE_AUTO);
517 +       if (!c)
518 +               c = &ic->ic_channels[0];
519 +       ic->ic_curchan = c;
520 +       ic->ic_bsschan = c;
521 +       ic->ic_curmode = IEEE80211_MODE_AUTO;
522 +       IEEE80211_UNLOCK_IRQ(ic);
523 +
524 +       if (!(sc->sc_dev->flags & IFF_RUNNING)) {
525 +               ic->ic_bsschan = IEEE80211_CHAN_ANYC;
526 +               return 0;
527 +       }
528 +
529 +#ifndef ifr_media
530 +#define    ifr_media       ifr_ifru.ifru_ivalue
531 +#endif
532 +       memset(&ifr, 0, sizeof(ifr));
533 +       ifr.ifr_media = ic->ic_media.ifm_cur->ifm_media & ~IFM_MMASK;
534 +       ifr.ifr_media |= IFM_MAKEMODE(IEEE80211_MODE_AUTO);
535 +       ifmedia_ioctl(ic->ic_dev, &ifr, &ic->ic_media, SIOCSIFMEDIA);
536 +
537 +       /* apply the channel to the hw */
538 +       ath_set_channel(ic);
539 +
540 +       TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
541 +               struct net_device *dev = vap->iv_dev;
542 +
543 +               /* reactivate all active vaps */
544 +               vap->iv_state = IEEE80211_S_SCAN;
545 +               if ((vap->iv_opmode == IEEE80211_M_HOSTAP) ||
546 +                       (vap->iv_opmode == IEEE80211_M_MONITOR) ||
547 +                       (vap->iv_opmode == IEEE80211_M_WDS))
548 +                       ieee80211_new_state(vap, IEEE80211_S_RUN, 0);
549 +               else
550 +                       ieee80211_new_state(vap, IEEE80211_S_INIT, -1);
551 +       }
552 +
553 +       return 0;
554 +}
555 +
556 +
557  static int
558  ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val)
559  {
560 @@ -11029,6 +11133,7 @@ static int
561  ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
562  {
563         struct ath_softc *sc = ctl->extra1;
564 +       struct ieee80211com *ic = &sc->sc_ic;
565         struct ath_hal *ah = sc->sc_ah;
566         u_int val;
567         u_int tab_3_val[3];
568 @@ -11052,25 +11157,34 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
569                                 lenp, ppos);
570                 if (ret == 0) {
571                         switch ((long)ctl->extra2) {
572 +                       case ATH_REGDOMAIN:
573 +                               ath_hal_setregdomain(ah, val);
574 +                               break;
575 +                       case ATH_OUTDOOR:
576 +                       case ATH_COUNTRYCODE:
577 +                       case ATH_CHANBW:
578 +                               ret = ath_sysctl_setchanparam(sc, (long) ctl->extra2, val);
579 +                               break;
580                         case ATH_SLOTTIME:
581 -                               if (val > 0) {
582 -                                       if (!ath_hal_setslottime(ah, val))
583 -                                               ret = -EINVAL;
584 -                                       else
585 -                                               sc->sc_slottimeconf = val;
586 -                               } else {
587 -                                       /* disable manual override */
588 +                               if (val > 0)
589 +                                       sc->sc_slottimeconf = val;
590 +                               else
591                                         sc->sc_slottimeconf = 0;
592 -                                       ath_setslottime(sc);
593 -                               }
594 +                               ath_settiming(sc);
595                                 break;
596                         case ATH_ACKTIMEOUT:
597 -                               if (!ath_hal_setacktimeout(ah, val))
598 -                                       ret = -EINVAL;
599 +                               if (val > 0)
600 +                                       sc->sc_acktimeconf = val;
601 +                               else
602 +                                       sc->sc_acktimeconf = 0;
603 +                               ath_settiming(sc);
604                                 break;
605                         case ATH_CTSTIMEOUT:
606 -                               if (!ath_hal_setctstimeout(ah, val))
607 -                                       ret = -EINVAL;
608 +                               if (val > 0)
609 +                                       sc->sc_ctstimeconf = val;
610 +                               else
611 +                                       sc->sc_ctstimeconf = 0;
612 +                               ath_settiming(sc);
613                                 break;
614                         case ATH_SOFTLED:
615                                 if (val != sc->sc_softled) {
616 @@ -11223,6 +11337,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
617                 }
618         } else {
619                 switch ((long)ctl->extra2) {
620 +               case ATH_CHANBW:
621 +                       val = sc->sc_chanbw ?: 20;
622 +                       break;
623                 case ATH_SLOTTIME:
624                         val = ath_hal_getslottime(ah);
625                         break;
626 @@ -11241,6 +11358,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
627                 case ATH_COUNTRYCODE:
628                         ath_hal_getcountrycode(ah, &val);
629                         break;
630 +               case ATH_OUTDOOR:
631 +                       val = ic->ic_country_outdoor;
632 +                       break;
633                 case ATH_MAXVAPS:
634                         val = ath_maxvaps;
635                         break;
636 @@ -11354,11 +11474,17 @@ static const ctl_table ath_sysctl_templa
637         },
638         { .ctl_name     = CTL_AUTO,
639           .procname     = "countrycode",
640 -         .mode         = 0444,
641 +         .mode         = 0644,
642           .proc_handler = ath_sysctl_halparam,
643           .extra2       = (void *)ATH_COUNTRYCODE,
644         },
645         { .ctl_name     = CTL_AUTO,
646 +         .procname     = "outdoor",
647 +         .mode         = 0644,
648 +         .proc_handler = ath_sysctl_halparam,
649 +         .extra2       = (void *)ATH_OUTDOOR,
650 +       },
651 +       { .ctl_name     = CTL_AUTO,
652           .procname     = "maxvaps",
653           .mode         = 0444,
654           .proc_handler = ath_sysctl_halparam,
655 @@ -11366,7 +11492,7 @@ static const ctl_table ath_sysctl_templa
656         },
657         { .ctl_name     = CTL_AUTO,
658           .procname     = "regdomain",
659 -         .mode         = 0444,
660 +         .mode         = 0644,
661           .proc_handler = ath_sysctl_halparam,
662           .extra2       = (void *)ATH_REGDOMAIN,
663         },
664 @@ -11429,6 +11555,12 @@ static const ctl_table ath_sysctl_templa
665           .extra2       = (void *)ATH_ACKRATE,
666         },
667         { .ctl_name     = CTL_AUTO,
668 +         .procname     = "channelbw",
669 +         .mode         = 0644,
670 +         .proc_handler = ath_sysctl_halparam,
671 +         .extra2       = (void *)ATH_CHANBW,
672 +       },
673 +       { .ctl_name     = CTL_AUTO,
674           .procname     = "rp",
675           .mode         = 0200,
676           .proc_handler = ath_sysctl_halparam,
677 @@ -11669,13 +11801,6 @@ static ctl_table ath_static_sysctls[] = 
678         },
679  #endif
680         { .ctl_name     = CTL_AUTO,
681 -         .procname     = "countrycode",
682 -         .mode         = 0444,
683 -         .data         = &ath_countrycode,
684 -         .maxlen       = sizeof(ath_countrycode),
685 -         .proc_handler = proc_dointvec
686 -       },
687 -       { .ctl_name     = CTL_AUTO,
688           .procname     = "maxvaps",
689           .mode         = 0444,
690           .data         = &ath_maxvaps,
691 @@ -11683,13 +11808,6 @@ static ctl_table ath_static_sysctls[] = 
692           .proc_handler = proc_dointvec
693         },
694         { .ctl_name     = CTL_AUTO,
695 -         .procname     = "outdoor",
696 -         .mode         = 0444,
697 -         .data         = &ath_outdoor,
698 -         .maxlen       = sizeof(ath_outdoor),
699 -         .proc_handler = proc_dointvec
700 -       },
701 -       { .ctl_name     = CTL_AUTO,
702           .procname     = "xchanmode",
703           .mode         = 0444,
704           .data         = &ath_xchanmode,
705 --- a/ath/if_athvar.h
706 +++ b/ath/if_athvar.h
707 @@ -688,17 +688,18 @@ struct ath_softc {
708         int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */
709  
710         /* rate tables */
711 -       const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
712 +#define ATH_MODE_HALF          (IEEE80211_MODE_MAX)
713 +#define ATH_MODE_QUARTER       (IEEE80211_MODE_MAX + 1)
714 +       const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX + 2];
715         const HAL_RATE_TABLE *sc_currates;      /* current rate table */
716         const HAL_RATE_TABLE *sc_xr_rates;      /* XR rate table */
717 -       const HAL_RATE_TABLE *sc_half_rates;    /* half rate table */
718 -       const HAL_RATE_TABLE *sc_quarter_rates; /* quarter rate table */
719         HAL_OPMODE sc_opmode;                   /* current hal operating mode */
720         enum ieee80211_phymode sc_curmode;      /* current phy mode */
721         u_int sc_poweroffset;                   /* hardware power offset */
722         u_int16_t sc_curtxpow;                  /* current tx power limit */
723         u_int16_t sc_curaid;                    /* current association id */
724         HAL_CHANNEL sc_curchan;                 /* current h/w channel */
725 +       u_int8_t sc_chanbw;                             /* channel bandwidth */
726         u_int8_t sc_curbssid[IEEE80211_ADDR_LEN];
727         u_int8_t        sc_rixmap[256];                 /* IEEE to h/w rate table ix */
728         struct {
729 @@ -809,6 +810,8 @@ struct ath_softc {
730         u_int32_t sc_dturbo_bw_turbo;           /* bandwidth threshold */
731  #endif
732         u_int sc_slottimeconf;                  /* manual override for slottime */
733 +       u_int sc_acktimeconf;                   /* manual override for acktime */
734 +       u_int sc_ctstimeconf;                   /* manual override for ctstime */
735  
736         struct timer_list sc_dfs_excl_timer;    /* mark expiration timer task */
737         struct timer_list sc_dfs_cac_timer;     /* dfs wait timer */
738 @@ -827,6 +830,7 @@ struct ath_softc {
739         int sc_rp_num;
740         int sc_rp_min;
741         HAL_BOOL (*sc_rp_analyse)(struct ath_softc *sc);
742 +       struct ATH_TQ_STRUCT sc_refresh_tq;
743         struct ATH_TQ_STRUCT sc_rp_tq;
744         
745         int sc_rp_ignored;                      /* if set, we ignored all 
746 @@ -942,6 +946,48 @@ int ar_device(int devid);
747           DEV_NAME(_v->iv_ic->ic_dev))
748  
749  void ath_radar_detected(struct ath_softc *sc, const char* message);
750 +static inline u_int getTimingOffset(struct ath_softc *sc)
751 +{
752 +       struct ieee80211com *ic = &sc->sc_ic;
753 +       u_int usec = 9;
754 +       if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
755 +               usec = 20;
756 +               if (ic->ic_flags & IEEE80211_F_SHSLOT)
757 +                       usec = 9;
758 +       } else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
759 +               usec = 9;
760 +
761 +       if (IEEE80211_IS_CHAN_TURBO(ic->ic_curchan))
762 +               usec = 6;
763 +
764 +       if (IEEE80211_IS_CHAN_HALF(ic->ic_curchan))
765 +               usec = 13;
766 +       else if (IEEE80211_IS_CHAN_QUARTER(ic->ic_curchan))
767 +               usec = 21;
768 +       return usec;
769 +}
770 +
771 +static inline void ath_get_timings(struct ath_softc *sc, u_int *t_slot, u_int *t_sifs, u_int *t_difs)
772 +{
773 +       struct ieee80211_channel *c = sc->sc_ic.ic_curchan;
774 +
775 +       *t_slot = getTimingOffset(sc) + sc->sc_slottimeconf;
776 +
777 +       if (IEEE80211_IS_CHAN_HALF(c)) {
778 +               *t_sifs = 32;
779 +               *t_difs = 56;
780 +       } else if (IEEE80211_IS_CHAN_QUARTER(c)) {
781 +               *t_sifs = 64;
782 +               *t_difs = 112;
783 +       } else if (IEEE80211_IS_CHAN_TURBO(c)) {
784 +               *t_sifs = 8;
785 +               *t_difs = 28;
786 +       } else {
787 +               *t_sifs = 16;
788 +               *t_difs = 28;
789 +       }
790 +}
791 +
792  
793  struct ath_hw_detect {
794         const char *vendor_name;
795 --- a/tools/athctrl.c
796 +++ b/tools/athctrl.c
797 @@ -118,7 +118,7 @@ CMD(athctrl)(int argc, char *argv[])
798         }
799  
800         if (distance >= 0) {
801 -               int slottime = 9 + (distance / 300) + ((distance % 300) ? 1 : 0);
802 +               int slottime = (distance / 300) + ((distance % 300) ? 1 : 0);
803                 int acktimeout = slottime * 2 + 3;
804                 int ctstimeout = slottime * 2 + 3;
805  
806 --- a/net80211/ieee80211.c
807 +++ b/net80211/ieee80211.c
808 @@ -243,34 +243,17 @@ static const  struct country_code_to_str
809         {CTRY_ZIMBABWE,             "ZW"}
810  };
811  
812 -int
813 -ieee80211_ifattach(struct ieee80211com *ic)
814 +void ieee80211_update_channels(struct ieee80211com *ic, int init)
815  {
816 -       struct net_device *dev = ic->ic_dev;
817         struct ieee80211_channel *c;
818 +       struct ieee80211vap *vap;
819         struct ifmediareq imr;
820 +       int ext = 0;
821         int i;
822  
823 -       _MOD_INC_USE(THIS_MODULE, return -ENODEV);
824 -
825 -       /*
826 -        * Pick an initial operating mode until we have a vap
827 -        * created to lock it down correctly.  This is only
828 -        * drivers have something defined for configuring the
829 -        * hardware at startup.
830 -        */
831 -       ic->ic_opmode = IEEE80211_M_STA;        /* everyone supports this */
832 -
833 -       /*
834 -        * Fill in 802.11 available channel set, mark
835 -        * all available channels as active, and pick
836 -        * a default channel if not already specified.
837 -        */
838 -       KASSERT(0 < ic->ic_nchans && ic->ic_nchans < IEEE80211_CHAN_MAX,
839 -               ("invalid number of channels specified: %u", ic->ic_nchans));
840         memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
841 -       ic->ic_modecaps |= 1 << IEEE80211_MODE_AUTO;
842         ic->ic_max_txpower = IEEE80211_TXPOWER_MIN;
843 +       ic->ic_modecaps = 1 << IEEE80211_MODE_AUTO;
844  
845         for (i = 0; i < ic->ic_nchans; i++) {
846                 c = &ic->ic_channels[i];
847 @@ -298,6 +281,8 @@ ieee80211_ifattach(struct ieee80211com *
848                         ic->ic_modecaps |= 1 << IEEE80211_MODE_TURBO_A;
849                 if (IEEE80211_IS_CHAN_108G(c))
850                         ic->ic_modecaps |= 1 << IEEE80211_MODE_TURBO_G;
851 +               if (IEEE80211_IS_CHAN_HALF(c) || IEEE80211_IS_CHAN_QUARTER(c))
852 +                       ext = 1;
853         }
854         /* Initialize candidate channels to all available */
855         memcpy(ic->ic_chan_active, ic->ic_chan_avail,
856 @@ -311,11 +296,59 @@ ieee80211_ifattach(struct ieee80211com *
857          * When 11g is supported, force the rate set to
858          * include basic rates suitable for a mixed b/g bss.
859          */
860 -       if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G))
861 +       if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11G)) && !ext)
862                 ieee80211_set11gbasicrates(
863                         &ic->ic_sup_rates[IEEE80211_MODE_11G],
864                         IEEE80211_MODE_11G);
865  
866 +       if (init)
867 +               return;
868 +
869 +       ifmedia_removeall(&ic->ic_media);
870 +       ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, NULL, NULL);
871 +       ieee80211com_media_status(ic->ic_dev, &imr);
872 +       ifmedia_set(&ic->ic_media, imr.ifm_active);
873 +
874 +       TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
875 +               struct ieee80211vap *avp;
876 +               TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
877 +                       (void) ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps, NULL, NULL);
878 +                       ieee80211_media_status(vap->iv_dev, &imr);
879 +                       ifmedia_set(&vap->iv_media, imr.ifm_active);
880 +               }
881 +               (void) ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps, NULL, NULL);
882 +               ieee80211_media_status(vap->iv_dev, &imr);
883 +               ifmedia_set(&vap->iv_media, imr.ifm_active);
884 +       }
885 +}
886 +EXPORT_SYMBOL(ieee80211_update_channels);
887 +
888 +int
889 +ieee80211_ifattach(struct ieee80211com *ic)
890 +{
891 +       struct net_device *dev = ic->ic_dev;
892 +       struct ieee80211_channel *c;
893 +       struct ifmediareq imr;
894 +
895 +       _MOD_INC_USE(THIS_MODULE, return -ENODEV);
896 +
897 +       /*
898 +        * Pick an initial operating mode until we have a vap
899 +        * created to lock it down correctly.  This is only
900 +        * drivers have something defined for configuring the
901 +        * hardware at startup.
902 +        */
903 +       ic->ic_opmode = IEEE80211_M_STA;        /* everyone supports this */
904 +
905 +       /*
906 +        * Fill in 802.11 available channel set, mark
907 +        * all available channels as active, and pick
908 +        * a default channel if not already specified.
909 +        */
910 +       KASSERT(0 < ic->ic_nchans && ic->ic_nchans < IEEE80211_CHAN_MAX,
911 +               ("invalid number of channels specified: %u", ic->ic_nchans));
912 +       ieee80211_update_channels(ic, 1);
913 +
914         /* Setup initial channel settings */
915         ic->ic_bsschan = IEEE80211_CHAN_ANYC;
916         /* Arbitrarily pick the first channel */
917 @@ -327,6 +360,7 @@ ieee80211_ifattach(struct ieee80211com *
918         /* Enable WME by default, if we're capable. */
919         if (ic->ic_caps & IEEE80211_C_WME)
920                 ic->ic_flags |= IEEE80211_F_WME;
921 +
922         (void) ieee80211_setmode(ic, ic->ic_curmode);
923  
924         /* Store default beacon interval, as nec. */
925 @@ -763,7 +797,8 @@ ieee80211_media_setup(struct ieee80211co
926         struct ieee80211_rateset allrates;
927  
928         /* Fill in media characteristics. */
929 -       ifmedia_init(media, 0, media_change, media_stat);
930 +       if (media_change || media_stat)
931 +               ifmedia_init(media, 0, media_change, media_stat);
932         maxrate = 0;
933         memset(&allrates, 0, sizeof(allrates));
934  
935 @@ -793,7 +828,7 @@ ieee80211_media_setup(struct ieee80211co
936                         ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_WDS);
937                 if (mode == IEEE80211_MODE_AUTO)
938                         continue;
939 -               rs = &ic->ic_sup_rates[mode];
940 +               rs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)];
941  
942                 for (i = 0; i < rs->rs_nrates; i++) {
943                         rate = rs->rs_rates[i];
944 @@ -1207,7 +1242,7 @@ ieee80211_announce(struct ieee80211com *
945                 if ((ic->ic_modecaps & (1 << mode)) == 0)
946                         continue;
947                 if_printf(dev, "%s rates: ", ieee80211_phymode_name[mode]);
948 -               rs = &ic->ic_sup_rates[mode];
949 +               rs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)];
950                 for (i = 0; i < rs->rs_nrates; i++) {
951                         rate = rs->rs_rates[i];
952                         mword = ieee80211_rate2media(ic, rate, mode);
953 @@ -1417,7 +1452,7 @@ ieee80211com_media_change(struct net_dev
954                          * now so drivers have a consistent state.
955                          */
956                         KASSERT(vap->iv_bss != NULL, ("no bss node"));
957 -                       vap->iv_bss->ni_rates = ic->ic_sup_rates[newphymode];
958 +                       vap->iv_bss->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, newphymode)];
959                 }
960                 error = -ENETRESET;
961         }
962 @@ -1435,7 +1470,7 @@ findrate(struct ieee80211com *ic, enum i
963  {
964  #define        IEEERATE(_ic,_m,_i) \
965         ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
966 -       int i, nrates = ic->ic_sup_rates[mode].rs_nrates;
967 +       int i, nrates = ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)].rs_nrates;
968         for (i = 0; i < nrates; i++)
969                 if (IEEERATE(ic, mode, i) == rate)
970                         return i;
971 @@ -1877,11 +1912,6 @@ ieee80211_build_countryie(struct ieee802
972                         if (ieee80211_chan2mode(c) != curmode_noturbo)
973                                 continue;
974  
975 -                       /* Skip half/quarter rate channels */
976 -                       if (IEEE80211_IS_CHAN_HALF(c) ||
977 -                           IEEE80211_IS_CHAN_QUARTER(c))
978 -                               continue;
979 -
980                         if (*cur_runlen == 0) {
981                                 (*cur_runlen)++;
982                                 *cur_pow = c->ic_maxregpower;
983 @@ -1915,7 +1945,7 @@ void
984  ieee80211_build_sc_ie(struct ieee80211com *ic)
985  {
986         struct ieee80211_ie_sc *ie = &ic->ic_sc_ie;
987 -       int i, j;
988 +       int i, j, k;
989         struct ieee80211_channel *c;
990         u_int8_t prevchan;
991  
992 --- a/net80211/ieee80211_var.h
993 +++ b/net80211/ieee80211_var.h
994 @@ -336,8 +336,6 @@ struct ieee80211com {
995         u_int8_t ic_nopened;                    /* VAPs been opened */
996         struct ieee80211_rateset ic_sup_rates[IEEE80211_MODE_MAX];
997         struct ieee80211_rateset ic_sup_xr_rates;
998 -       struct ieee80211_rateset ic_sup_half_rates;
999 -       struct ieee80211_rateset ic_sup_quarter_rates;
1000         u_int16_t ic_modecaps;                  /* set of mode capabilities */
1001         u_int16_t ic_curmode;                   /* current mode */
1002         u_int16_t ic_lintval;                   /* beacon interval */
1003 @@ -714,6 +712,7 @@ MALLOC_DECLARE(M_80211_VAP);
1004  
1005  int ieee80211_ifattach(struct ieee80211com *);
1006  void ieee80211_ifdetach(struct ieee80211com *);
1007 +void ieee80211_update_channels(struct ieee80211com *ic, int);
1008  int ieee80211_vap_setup(struct ieee80211com *, struct net_device *,
1009         const char *, int, int, struct ieee80211vap *);
1010  int ieee80211_vap_attach(struct ieee80211vap *, ifm_change_cb_t, ifm_stat_cb_t);
1011 @@ -793,6 +792,23 @@ ieee80211_anyhdrspace(struct ieee80211co
1012         return size;
1013  }
1014  
1015 +static __inline int
1016 +ieee80211_chan2ratemode(struct ieee80211_channel *c, int mode)
1017 +{
1018 +       if (mode == -1)
1019 +               mode = ieee80211_chan2mode(c);
1020 +
1021 +       /*
1022 +        * Use 11a rateset for half/quarter to restrict things
1023 +        * to pure OFDM
1024 +        */
1025 +       if (IEEE80211_IS_CHAN_HALF(c) ||
1026 +               IEEE80211_IS_CHAN_QUARTER(c))
1027 +               return IEEE80211_MODE_11A;
1028 +
1029 +       return mode;
1030 +}
1031 +
1032  /* Macros to print MAC address used in 802.11 headers */
1033  
1034  #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
1035 --- a/net80211/ieee80211_node.c
1036 +++ b/net80211/ieee80211_node.c
1037 @@ -287,7 +287,7 @@ ieee80211_node_set_chan(struct ieee80211
1038                 ni->ni_rates = ic->ic_sup_xr_rates;
1039         else
1040  #endif
1041 -       ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2mode(chan)];
1042 +       ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(chan, -1)];
1043  }
1044  
1045  static __inline void
1046 @@ -387,6 +387,8 @@ ieee80211_create_ibss(struct ieee80211va
1047         ic->ic_bsschan = chan;
1048         ieee80211_node_set_chan(ic, ni);
1049         ic->ic_curmode = ieee80211_chan2mode(chan);
1050 +       ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(chan, -1)];
1051 +
1052         spin_lock_irqsave(&channel_lock, flags);
1053         ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
1054         spin_unlock_irqrestore(&channel_lock, flags);
1055 @@ -394,14 +396,8 @@ ieee80211_create_ibss(struct ieee80211va
1056         /* Update country ie information */
1057         ieee80211_build_countryie(ic);
1058  
1059 -       if (IEEE80211_IS_CHAN_HALF(chan)) {
1060 -               ni->ni_rates = ic->ic_sup_half_rates;
1061 -       } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
1062 -               ni->ni_rates = ic->ic_sup_quarter_rates;
1063 -       }
1064 -
1065 -       if ((vap->iv_flags & IEEE80211_F_PUREG) &&
1066 -               IEEE80211_IS_CHAN_ANYG(chan)) {
1067 +       if ((ieee80211_chan2ratemode(chan, -1) != IEEE80211_MODE_11A) &&
1068 +               IEEE80211_IS_CHAN_ANYG(chan) && (vap->iv_flags & IEEE80211_F_PUREG)) {
1069                 ieee80211_setpuregbasicrates(&ni->ni_rates);
1070         }
1071  
1072 --- a/net80211/ieee80211_scan_sta.c
1073 +++ b/net80211/ieee80211_scan_sta.c
1074 @@ -490,12 +490,7 @@ check_rate(struct ieee80211vap *vap, con
1075  
1076         okrate = badrate = fixedrate = 0;
1077  
1078 -       if (IEEE80211_IS_CHAN_HALF(se->se_chan))
1079 -               srs = &ic->ic_sup_half_rates;
1080 -       else if (IEEE80211_IS_CHAN_QUARTER(se->se_chan))
1081 -               srs = &ic->ic_sup_quarter_rates;
1082 -       else
1083 -               srs = &ic->ic_sup_rates[ieee80211_chan2mode(se->se_chan)];
1084 +       srs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, -1)];
1085         nrs = se->se_rates[1];
1086         rs = se->se_rates + 2;
1087         fixedrate = IEEE80211_FIXED_RATE_NONE;
1088 --- a/net80211/ieee80211_output.c
1089 +++ b/net80211/ieee80211_output.c
1090 @@ -1676,8 +1676,8 @@ ieee80211_send_probereq(struct ieee80211
1091  
1092         frm = ieee80211_add_ssid(frm, ssid, ssidlen);
1093         mode = ieee80211_chan2mode(ic->ic_curchan);
1094 -       frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]);
1095 -       frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]);
1096 +       frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)]);
1097 +       frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)]);
1098  
1099         if (optie != NULL) {
1100                 memcpy(frm, optie, optielen);
1101 --- a/net80211/ieee80211_proto.c
1102 +++ b/net80211/ieee80211_proto.c
1103 @@ -404,7 +404,7 @@ ieee80211_fix_rate(struct ieee80211_node
1104  
1105         error = 0;
1106         okrate = badrate = fixedrate = 0;
1107 -       srs = &ic->ic_sup_rates[ieee80211_chan2mode(ni->ni_chan)];
1108 +       srs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, -1)];
1109         nrs = &ni->ni_rates;
1110         fixedrate = IEEE80211_FIXED_RATE_NONE;
1111         for (i = 0; i < nrs->rs_nrates;) {
1112 @@ -1407,6 +1407,7 @@ ieee80211_new_state(struct ieee80211vap 
1113         IEEE80211_VAPS_UNLOCK_IRQ(ic);
1114         return rc;
1115  }
1116 +EXPORT_SYMBOL(ieee80211_new_state);
1117  
1118  static int
1119  __ieee80211_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1120 --- a/ath_rate/minstrel/minstrel.c
1121 +++ b/ath_rate/minstrel/minstrel.c
1122 @@ -195,31 +195,7 @@ calc_usecs_unicast_packet(struct ath_sof
1123                         return 0;
1124                 }
1125  
1126 -               /* XXX: Getting MAC/PHY level timings should be fixed for turbo
1127 -                * rates, and there is probably a way to get this from the
1128 -                * HAL... */
1129 -               switch (rt->info[rix].phy) {
1130 -               case IEEE80211_T_OFDM:
1131 -#if 0
1132 -                       t_slot = 9;
1133 -                       t_sifs = 16;
1134 -                       t_difs = 28;
1135 -                       /* fall through */
1136 -#endif
1137 -               case IEEE80211_T_TURBO:
1138 -                       t_slot = 9;
1139 -                       t_sifs = 8;
1140 -                       t_difs = 28;
1141 -                       break;
1142 -               case IEEE80211_T_DS:
1143 -                       /* Fall through to default */
1144 -               default:
1145 -                       /* pg. 205 ieee.802.11.pdf */
1146 -                       t_slot = 20;
1147 -                       t_difs = 50;
1148 -                       t_sifs = 10;
1149 -               }
1150 -
1151 +               ath_get_timings(sc, &t_slot, &t_sifs, &t_difs);
1152                 if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1153                 (rt->info[rix].phy == IEEE80211_T_OFDM)) {
1154                         if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
1155 --- a/ath_rate/sample/sample.c
1156 +++ b/ath_rate/sample/sample.c
1157 @@ -172,26 +172,7 @@ calc_usecs_unicast_packet(struct ath_sof
1158          * rates, and there is probably a way to get this from the
1159          * hal...
1160          */
1161 -       switch (rt->info[rix].phy) {
1162 -       case IEEE80211_T_OFDM:
1163 -               t_slot = 9;
1164 -               t_sifs = 16;
1165 -               t_difs = 28;
1166 -               /* fall through */
1167 -       case IEEE80211_T_TURBO:
1168 -               t_slot = 9;
1169 -               t_sifs = 8;
1170 -               t_difs = 28;
1171 -               break;
1172 -       case IEEE80211_T_DS:
1173 -               /* fall through to default */
1174 -       default:
1175 -               /* pg 205 ieee.802.11.pdf */
1176 -               t_slot = 20;
1177 -               t_difs = 50;
1178 -               t_sifs = 10;
1179 -       }
1180 -
1181 +       ath_get_timings(sc, &t_slot, &t_sifs, &t_difs);
1182         rts = cts = 0;
1183  
1184         if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1185 --- a/net80211/ieee80211_wireless.c
1186 +++ b/net80211/ieee80211_wireless.c
1187 @@ -2142,7 +2142,7 @@ ieee80211_ioctl_setmode(struct net_devic
1188  
1189                 vap->iv_des_mode = mode;
1190                 if (IS_UP_AUTO(vap))
1191 -                       ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
1192 +                       ieee80211_init(vap->iv_dev, 0);
1193  
1194                 retv = 0;
1195         }
1196 @@ -4090,46 +4090,60 @@ ieee80211_ioctl_getchanlist(struct net_d
1197         return 0;
1198  }
1199  
1200 +static int alreadyListed(struct ieee80211req_chaninfo *chans, u_int16_t mhz)
1201 +{
1202 +       int i;
1203 +       for (i = 0; i < chans->ic_nchans; i++) {
1204 +               if (chans->ic_chans[i].ic_freq == mhz)
1205 +                       return 1;
1206 +       }
1207 +       return 0;
1208 +}
1209 +
1210  static int
1211  ieee80211_ioctl_getchaninfo(struct net_device *dev,
1212 -       struct iw_request_info *info, void *w, char *extra)
1213 +                           struct iw_request_info *info, void *w, char *extra)
1214  {
1215         struct ieee80211vap *vap = dev->priv;
1216         struct ieee80211com *ic = vap->iv_ic;
1217 -       struct ieee80211req_chaninfo chans;
1218 +       struct ieee80211req_chaninfo *chans =
1219 +           (struct ieee80211req_chaninfo *)extra;
1220 +
1221         u_int8_t reported[IEEE80211_CHAN_BYTES];        /* XXX stack usage? */
1222         int i;
1223  
1224 -       memset(&chans, 0, sizeof(chans));
1225 -       memset(&reported, 0, sizeof(reported));
1226 +       memset(chans, 0, sizeof(*chans));
1227 +       memset(reported, 0, sizeof(reported));
1228         for (i = 0; i < ic->ic_nchans; i++) {
1229                 const struct ieee80211_channel *c = &ic->ic_channels[i];
1230                 const struct ieee80211_channel *c1 = c;
1231  
1232 -               if (isclr(reported, c->ic_ieee)) {
1233 +               if (!alreadyListed(chans, c->ic_freq)) {
1234                         setbit(reported, c->ic_ieee);
1235  
1236 -                       /* pick turbo channel over non-turbo channel, and
1237 -                        * 11g channel over 11b channel */
1238                         if (IEEE80211_IS_CHAN_A(c))
1239 -                               c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_A);
1240 +                               c1 = findchannel(ic, c->ic_freq,
1241 +                                                IEEE80211_MODE_TURBO_A);
1242                         if (IEEE80211_IS_CHAN_ANYG(c))
1243 -                               c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_G);
1244 +                               c1 = findchannel(ic, c->ic_freq,
1245 +                                                IEEE80211_MODE_TURBO_G);
1246                         else if (IEEE80211_IS_CHAN_B(c)) {
1247 -                               c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_G);
1248 +                               c1 = findchannel(ic, c->ic_freq,
1249 +                                                IEEE80211_MODE_TURBO_G);
1250                                 if (!c1)
1251 -                                       c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_11G);
1252 +                                       c1 = findchannel(ic, c->ic_freq,
1253 +                                                        IEEE80211_MODE_11G);
1254                         }
1255  
1256                         if (c1)
1257                                 c = c1;
1258 -                       /* Copy the entire structure, whereas it used to just copy a few fields */
1259 -                       memcpy(&chans.ic_chans[chans.ic_nchans], c, sizeof(struct ieee80211_channel));
1260 -                       if (++chans.ic_nchans >= IEEE80211_CHAN_MAX)
1261 +                       chans->ic_chans[chans->ic_nchans].ic_ieee = c->ic_ieee;
1262 +                       chans->ic_chans[chans->ic_nchans].ic_freq = c->ic_freq;
1263 +                       chans->ic_chans[chans->ic_nchans].ic_flags = c->ic_flags;
1264 +                       if (++chans->ic_nchans >= IEEE80211_CHAN_MAX)
1265                                 break;
1266                 }
1267         }
1268 -       memcpy(extra, &chans, sizeof(struct ieee80211req_chaninfo));
1269         return 0;
1270  }
1271  
1272 --- a/net80211/ieee80211_scan_ap.c
1273 +++ b/net80211/ieee80211_scan_ap.c
1274 @@ -512,12 +512,13 @@ pick_channel(struct ieee80211_scan_state
1275         int ss_last = ss->ss_last;
1276         struct ieee80211_channel *best;
1277         struct ap_state *as = ss->ss_priv;
1278 -       struct channel chans[ss_last]; /* actually ss_last-1 is required */
1279 +       struct channel *chans; /* actually ss_last-1 is required */
1280         struct channel *c = NULL;
1281         struct pc_params params = { vap, ss, flags };
1282         int benefit = 0;
1283         int sta_assoc = 0;
1284  
1285 +       chans = (struct channel *)kmalloc(ss_last*sizeof(struct channel),GFP_ATOMIC);
1286         for (i = 0; i < ss_last; i++) {
1287                 chans[i].chan = ss->ss_chans[i];
1288                 chans[i].orig = i;
1289 @@ -571,6 +572,7 @@ pick_channel(struct ieee80211_scan_state
1290                                 "%s: best: channel %u rssi %d\n",
1291                                 __func__, i, as->as_maxrssi[i]);
1292         }
1293 +       kfree(chans);
1294         return best;
1295  }
1296  
1297 @@ -609,6 +611,7 @@ ap_end(struct ieee80211_scan_state *ss, 
1298                 res = 1; /* Do NOT restart scan */
1299         } else {
1300                 struct ieee80211_scan_entry se;
1301 +               int i;
1302                 /* XXX: notify all VAPs? */
1303                 /* if this is a dynamic turbo frequency , start with normal 
1304                  * mode first */
1305 @@ -623,6 +626,11 @@ ap_end(struct ieee80211_scan_state *ss, 
1306                                 return 0;
1307                         }
1308                 }
1309 +               for (i = (bestchan - &ic->ic_channels[0])/sizeof(*bestchan) + 1; i < ic->ic_nchans; i++) {
1310 +                       if ((ic->ic_channels[i].ic_freq == bestchan->ic_freq) &&
1311 +                               IEEE80211_IS_CHAN_ANYG(&ic->ic_channels[i]))
1312 +                               bestchan = &ic->ic_channels[i];
1313 +               }
1314                 memset(&se, 0, sizeof(se));
1315                 se.se_chan = bestchan;
1316  
1317 --- a/tools/wlanconfig.c
1318 +++ b/tools/wlanconfig.c
1319 @@ -737,7 +737,7 @@ list_channels(const char *ifname, int al
1320         if (get80211priv(ifname, IEEE80211_IOCTL_GETCHANINFO, &chans, sizeof(chans)) < 0)
1321                 errx(1, "unable to get channel information");
1322         if (!allchans) {
1323 -               uint8_t active[32];
1324 +               uint8_t active[IEEE80211_CHAN_BYTES];
1325  
1326                 if (get80211priv(ifname, IEEE80211_IOCTL_GETCHANLIST, &active, sizeof(active)) < 0)
1327                         errx(1, "unable to get active channel list");
1328 --- a/net80211/ieee80211_scan.c
1329 +++ b/net80211/ieee80211_scan.c
1330 @@ -1044,6 +1044,7 @@ ieee80211_scan_assoc_fail(struct ieee802
1331                 ss->ss_ops->scan_assoc_fail(ss, mac, reason);
1332         }
1333  }
1334 +EXPORT_SYMBOL(ieee80211_scan_flush);
1335  
1336  /*
1337   * Iterate over the contents of the scan cache.
1338 --- a/ath/if_ath_hal_wrappers.h
1339 +++ b/ath/if_ath_hal_wrappers.h
1340 @@ -111,6 +111,11 @@ static inline HAL_BOOL ath_hal_getregdom
1341         return (ath_hal_getcapability(ah, HAL_CAP_REG_DMN, 0, destination) == HAL_OK);
1342  }
1343  
1344 +static inline HAL_BOOL ath_hal_setregdomain(struct ath_hal *ah, u_int32_t v)
1345 +{
1346 +       return (ath_hal_setcapability(ah, HAL_CAP_REG_DMN, 0, v, NULL));
1347 +}
1348 +
1349  static inline HAL_BOOL ath_hal_gettkipmic(struct ath_hal *ah)
1350  {
1351         return (ath_hal_getcapability(ah, HAL_CAP_TKIP_MIC, 1, NULL) == HAL_OK);