Root/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);
1352

Archive Download this file



interactive