madwifi: ignore the eeprom fast framing supported flag, as it is an arbitrary restric...
[openwrt/svn-archive/archive.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 @@ -4469,17 +4485,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 @@ -4501,7 +4517,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 @@ -5345,7 +5361,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 @@ -7798,12 +7814,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 @@ -8096,7 +8114,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 @@ -9063,7 +9081,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 @@ -10120,8 +10138,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 @@ -10135,17 +10152,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 @@ -10389,7 +10420,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 @@ -10402,57 +10433,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 @@ -10461,7 +10451,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 @@ -10479,6 +10469,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 @@ -10493,10 +10489,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 @@ -10525,13 +10527,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 @@ -10541,7 +10548,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 @@ -10942,9 +10949,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 @@ -11023,6 +11127,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 @@ -11046,25 +11151,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 @@ -11217,6 +11331,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 @@ -11235,6 +11352,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 @@ -11348,11 +11468,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 @@ -11360,7 +11486,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 @@ -11423,6 +11549,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 @@ -11663,13 +11795,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 @@ -11677,13 +11802,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,16 +688,17 @@ 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_int16_t sc_curtxpow; /* current tx power limit */
722 u_int16_t sc_curaid; /* current association id */
723 HAL_CHANNEL sc_curchan; /* current h/w channel */
724 + u_int8_t sc_chanbw; /* channel bandwidth */
725 u_int8_t sc_curbssid[IEEE80211_ADDR_LEN];
726 u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */
727 struct {
728 @@ -808,6 +809,8 @@ struct ath_softc {
729 u_int32_t sc_dturbo_bw_turbo; /* bandwidth threshold */
730 #endif
731 u_int sc_slottimeconf; /* manual override for slottime */
732 + u_int sc_acktimeconf; /* manual override for acktime */
733 + u_int sc_ctstimeconf; /* manual override for ctstime */
734
735 struct timer_list sc_dfs_excl_timer; /* mark expiration timer task */
736 struct timer_list sc_dfs_cac_timer; /* dfs wait timer */
737 @@ -826,6 +829,7 @@ struct ath_softc {
738 int sc_rp_num;
739 int sc_rp_min;
740 HAL_BOOL (*sc_rp_analyse)(struct ath_softc *sc);
741 + struct ATH_TQ_STRUCT sc_refresh_tq;
742 struct ATH_TQ_STRUCT sc_rp_tq;
743
744 int sc_rp_ignored; /* if set, we ignored all
745 @@ -941,6 +945,48 @@ int ar_device(int devid);
746 DEV_NAME(_v->iv_ic->ic_dev))
747
748 void ath_radar_detected(struct ath_softc *sc, const char* message);
749 +static inline u_int getTimingOffset(struct ath_softc *sc)
750 +{
751 + struct ieee80211com *ic = &sc->sc_ic;
752 + u_int usec = 9;
753 + if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
754 + usec = 20;
755 + if (ic->ic_flags & IEEE80211_F_SHSLOT)
756 + usec = 9;
757 + } else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
758 + usec = 9;
759 +
760 + if (IEEE80211_IS_CHAN_TURBO(ic->ic_curchan))
761 + usec = 6;
762 +
763 + if (IEEE80211_IS_CHAN_HALF(ic->ic_curchan))
764 + usec = 13;
765 + else if (IEEE80211_IS_CHAN_QUARTER(ic->ic_curchan))
766 + usec = 21;
767 + return usec;
768 +}
769 +
770 +static inline void ath_get_timings(struct ath_softc *sc, u_int *t_slot, u_int *t_sifs, u_int *t_difs)
771 +{
772 + struct ieee80211_channel *c = sc->sc_ic.ic_curchan;
773 +
774 + *t_slot = getTimingOffset(sc) + sc->sc_slottimeconf;
775 +
776 + if (IEEE80211_IS_CHAN_HALF(c)) {
777 + *t_sifs = 32;
778 + *t_difs = 56;
779 + } else if (IEEE80211_IS_CHAN_QUARTER(c)) {
780 + *t_sifs = 64;
781 + *t_difs = 112;
782 + } else if (IEEE80211_IS_CHAN_TURBO(c)) {
783 + *t_sifs = 8;
784 + *t_difs = 28;
785 + } else {
786 + *t_sifs = 16;
787 + *t_difs = 28;
788 + }
789 +}
790 +
791
792 struct ath_hw_detect {
793 const char *vendor_name;
794 --- a/tools/athctrl.c
795 +++ b/tools/athctrl.c
796 @@ -118,7 +118,7 @@ CMD(athctrl)(int argc, char *argv[])
797 }
798
799 if (distance >= 0) {
800 - int slottime = 9 + (distance / 300) + ((distance % 300) ? 1 : 0);
801 + int slottime = (distance / 300) + ((distance % 300) ? 1 : 0);
802 int acktimeout = slottime * 2 + 3;
803 int ctstimeout = slottime * 2 + 3;
804
805 --- a/net80211/ieee80211.c
806 +++ b/net80211/ieee80211.c
807 @@ -243,34 +243,17 @@ static const struct country_code_to_str
808 {CTRY_ZIMBABWE, "ZW"}
809 };
810
811 -int
812 -ieee80211_ifattach(struct ieee80211com *ic)
813 +void ieee80211_update_channels(struct ieee80211com *ic, int init)
814 {
815 - struct net_device *dev = ic->ic_dev;
816 struct ieee80211_channel *c;
817 + struct ieee80211vap *vap;
818 struct ifmediareq imr;
819 + int ext = 0;
820 int i;
821
822 - _MOD_INC_USE(THIS_MODULE, return -ENODEV);
823 -
824 - /*
825 - * Pick an initial operating mode until we have a vap
826 - * created to lock it down correctly. This is only
827 - * drivers have something defined for configuring the
828 - * hardware at startup.
829 - */
830 - ic->ic_opmode = IEEE80211_M_STA; /* everyone supports this */
831 -
832 - /*
833 - * Fill in 802.11 available channel set, mark
834 - * all available channels as active, and pick
835 - * a default channel if not already specified.
836 - */
837 - KASSERT(0 < ic->ic_nchans && ic->ic_nchans < IEEE80211_CHAN_MAX,
838 - ("invalid number of channels specified: %u", ic->ic_nchans));
839 memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
840 - ic->ic_modecaps |= 1 << IEEE80211_MODE_AUTO;
841 ic->ic_max_txpower = IEEE80211_TXPOWER_MIN;
842 + ic->ic_modecaps = 1 << IEEE80211_MODE_AUTO;
843
844 for (i = 0; i < ic->ic_nchans; i++) {
845 c = &ic->ic_channels[i];
846 @@ -298,6 +281,8 @@ ieee80211_ifattach(struct ieee80211com *
847 ic->ic_modecaps |= 1 << IEEE80211_MODE_TURBO_A;
848 if (IEEE80211_IS_CHAN_108G(c))
849 ic->ic_modecaps |= 1 << IEEE80211_MODE_TURBO_G;
850 + if (IEEE80211_IS_CHAN_HALF(c) || IEEE80211_IS_CHAN_QUARTER(c))
851 + ext = 1;
852 }
853 /* Initialize candidate channels to all available */
854 memcpy(ic->ic_chan_active, ic->ic_chan_avail,
855 @@ -311,11 +296,58 @@ ieee80211_ifattach(struct ieee80211com *
856 * When 11g is supported, force the rate set to
857 * include basic rates suitable for a mixed b/g bss.
858 */
859 - if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G))
860 + if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11G)) && !ext)
861 ieee80211_set11gbasicrates(
862 &ic->ic_sup_rates[IEEE80211_MODE_11G],
863 IEEE80211_MODE_11G);
864
865 + if (init)
866 + return;
867 +
868 + ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, NULL, NULL);
869 + ieee80211com_media_status(ic->ic_dev, &imr);
870 + ifmedia_set(&ic->ic_media, imr.ifm_active);
871 +
872 + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
873 + struct ieee80211vap *avp;
874 + TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
875 + (void) ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps, NULL, NULL);
876 + ieee80211_media_status(vap->iv_dev, &imr);
877 + ifmedia_set(&vap->iv_media, imr.ifm_active);
878 + }
879 + (void) ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps, NULL, NULL);
880 + ieee80211_media_status(vap->iv_dev, &imr);
881 + ifmedia_set(&vap->iv_media, imr.ifm_active);
882 + }
883 +}
884 +EXPORT_SYMBOL(ieee80211_update_channels);
885 +
886 +int
887 +ieee80211_ifattach(struct ieee80211com *ic)
888 +{
889 + struct net_device *dev = ic->ic_dev;
890 + struct ieee80211_channel *c;
891 + struct ifmediareq imr;
892 +
893 + _MOD_INC_USE(THIS_MODULE, return -ENODEV);
894 +
895 + /*
896 + * Pick an initial operating mode until we have a vap
897 + * created to lock it down correctly. This is only
898 + * drivers have something defined for configuring the
899 + * hardware at startup.
900 + */
901 + ic->ic_opmode = IEEE80211_M_STA; /* everyone supports this */
902 +
903 + /*
904 + * Fill in 802.11 available channel set, mark
905 + * all available channels as active, and pick
906 + * a default channel if not already specified.
907 + */
908 + KASSERT(0 < ic->ic_nchans && ic->ic_nchans < IEEE80211_CHAN_MAX,
909 + ("invalid number of channels specified: %u", ic->ic_nchans));
910 + ieee80211_update_channels(ic, 1);
911 +
912 /* Setup initial channel settings */
913 ic->ic_bsschan = IEEE80211_CHAN_ANYC;
914 /* Arbitrarily pick the first channel */
915 @@ -327,6 +359,7 @@ ieee80211_ifattach(struct ieee80211com *
916 /* Enable WME by default, if we're capable. */
917 if (ic->ic_caps & IEEE80211_C_WME)
918 ic->ic_flags |= IEEE80211_F_WME;
919 +
920 (void) ieee80211_setmode(ic, ic->ic_curmode);
921
922 /* Store default beacon interval, as nec. */
923 @@ -763,7 +796,8 @@ ieee80211_media_setup(struct ieee80211co
924 struct ieee80211_rateset allrates;
925
926 /* Fill in media characteristics. */
927 - ifmedia_init(media, 0, media_change, media_stat);
928 + if (media_change || media_stat)
929 + ifmedia_init(media, 0, media_change, media_stat);
930 maxrate = 0;
931 memset(&allrates, 0, sizeof(allrates));
932
933 @@ -793,7 +827,7 @@ ieee80211_media_setup(struct ieee80211co
934 ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_WDS);
935 if (mode == IEEE80211_MODE_AUTO)
936 continue;
937 - rs = &ic->ic_sup_rates[mode];
938 + rs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)];
939
940 for (i = 0; i < rs->rs_nrates; i++) {
941 rate = rs->rs_rates[i];
942 @@ -1207,7 +1241,7 @@ ieee80211_announce(struct ieee80211com *
943 if ((ic->ic_modecaps & (1 << mode)) == 0)
944 continue;
945 if_printf(dev, "%s rates: ", ieee80211_phymode_name[mode]);
946 - rs = &ic->ic_sup_rates[mode];
947 + rs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)];
948 for (i = 0; i < rs->rs_nrates; i++) {
949 rate = rs->rs_rates[i];
950 mword = ieee80211_rate2media(ic, rate, mode);
951 @@ -1417,7 +1451,7 @@ ieee80211com_media_change(struct net_dev
952 * now so drivers have a consistent state.
953 */
954 KASSERT(vap->iv_bss != NULL, ("no bss node"));
955 - vap->iv_bss->ni_rates = ic->ic_sup_rates[newphymode];
956 + vap->iv_bss->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, newphymode)];
957 }
958 error = -ENETRESET;
959 }
960 @@ -1435,7 +1469,7 @@ findrate(struct ieee80211com *ic, enum i
961 {
962 #define IEEERATE(_ic,_m,_i) \
963 ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
964 - int i, nrates = ic->ic_sup_rates[mode].rs_nrates;
965 + int i, nrates = ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)].rs_nrates;
966 for (i = 0; i < nrates; i++)
967 if (IEEERATE(ic, mode, i) == rate)
968 return i;
969 @@ -1877,11 +1911,6 @@ ieee80211_build_countryie(struct ieee802
970 if (ieee80211_chan2mode(c) != curmode_noturbo)
971 continue;
972
973 - /* Skip half/quarter rate channels */
974 - if (IEEE80211_IS_CHAN_HALF(c) ||
975 - IEEE80211_IS_CHAN_QUARTER(c))
976 - continue;
977 -
978 if (*cur_runlen == 0) {
979 (*cur_runlen)++;
980 *cur_pow = c->ic_maxregpower;
981 @@ -1915,7 +1944,7 @@ void
982 ieee80211_build_sc_ie(struct ieee80211com *ic)
983 {
984 struct ieee80211_ie_sc *ie = &ic->ic_sc_ie;
985 - int i, j;
986 + int i, j, k;
987 struct ieee80211_channel *c;
988 u_int8_t prevchan;
989
990 --- a/net80211/ieee80211_var.h
991 +++ b/net80211/ieee80211_var.h
992 @@ -336,8 +336,6 @@ struct ieee80211com {
993 u_int8_t ic_nopened; /* VAPs been opened */
994 struct ieee80211_rateset ic_sup_rates[IEEE80211_MODE_MAX];
995 struct ieee80211_rateset ic_sup_xr_rates;
996 - struct ieee80211_rateset ic_sup_half_rates;
997 - struct ieee80211_rateset ic_sup_quarter_rates;
998 u_int16_t ic_modecaps; /* set of mode capabilities */
999 u_int16_t ic_curmode; /* current mode */
1000 u_int16_t ic_lintval; /* beacon interval */
1001 @@ -715,6 +713,7 @@ MALLOC_DECLARE(M_80211_VAP);
1002
1003 int ieee80211_ifattach(struct ieee80211com *);
1004 void ieee80211_ifdetach(struct ieee80211com *);
1005 +void ieee80211_update_channels(struct ieee80211com *ic, int);
1006 int ieee80211_vap_setup(struct ieee80211com *, struct net_device *,
1007 const char *, int, int, struct ieee80211vap *);
1008 int ieee80211_vap_attach(struct ieee80211vap *, ifm_change_cb_t, ifm_stat_cb_t);
1009 @@ -794,6 +793,23 @@ ieee80211_anyhdrspace(struct ieee80211co
1010 return size;
1011 }
1012
1013 +static __inline int
1014 +ieee80211_chan2ratemode(struct ieee80211_channel *c, int mode)
1015 +{
1016 + if (mode == -1)
1017 + mode = ieee80211_chan2mode(c);
1018 +
1019 + /*
1020 + * Use 11a rateset for half/quarter to restrict things
1021 + * to pure OFDM
1022 + */
1023 + if (IEEE80211_IS_CHAN_HALF(c) ||
1024 + IEEE80211_IS_CHAN_QUARTER(c))
1025 + return IEEE80211_MODE_11A;
1026 +
1027 + return mode;
1028 +}
1029 +
1030 /* Macros to print MAC address used in 802.11 headers */
1031
1032 #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
1033 --- a/net80211/ieee80211_node.c
1034 +++ b/net80211/ieee80211_node.c
1035 @@ -287,7 +287,7 @@ ieee80211_node_set_chan(struct ieee80211
1036 ni->ni_rates = ic->ic_sup_xr_rates;
1037 else
1038 #endif
1039 - ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2mode(chan)];
1040 + ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(chan, -1)];
1041 }
1042
1043 static __inline void
1044 @@ -387,6 +387,8 @@ ieee80211_create_ibss(struct ieee80211va
1045 ic->ic_bsschan = chan;
1046 ieee80211_node_set_chan(ic, ni);
1047 ic->ic_curmode = ieee80211_chan2mode(chan);
1048 + ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(chan, -1)];
1049 +
1050 spin_lock_irqsave(&channel_lock, flags);
1051 ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
1052 spin_unlock_irqrestore(&channel_lock, flags);
1053 @@ -394,14 +396,8 @@ ieee80211_create_ibss(struct ieee80211va
1054 /* Update country ie information */
1055 ieee80211_build_countryie(ic);
1056
1057 - if (IEEE80211_IS_CHAN_HALF(chan)) {
1058 - ni->ni_rates = ic->ic_sup_half_rates;
1059 - } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
1060 - ni->ni_rates = ic->ic_sup_quarter_rates;
1061 - }
1062 -
1063 - if ((vap->iv_flags & IEEE80211_F_PUREG) &&
1064 - IEEE80211_IS_CHAN_ANYG(chan)) {
1065 + if ((ieee80211_chan2ratemode(chan, -1) != IEEE80211_MODE_11A) &&
1066 + IEEE80211_IS_CHAN_ANYG(chan) && (vap->iv_flags & IEEE80211_F_PUREG)) {
1067 ieee80211_setpuregbasicrates(&ni->ni_rates);
1068 }
1069
1070 --- a/net80211/ieee80211_scan_sta.c
1071 +++ b/net80211/ieee80211_scan_sta.c
1072 @@ -490,12 +490,7 @@ check_rate(struct ieee80211vap *vap, con
1073
1074 okrate = badrate = fixedrate = 0;
1075
1076 - if (IEEE80211_IS_CHAN_HALF(se->se_chan))
1077 - srs = &ic->ic_sup_half_rates;
1078 - else if (IEEE80211_IS_CHAN_QUARTER(se->se_chan))
1079 - srs = &ic->ic_sup_quarter_rates;
1080 - else
1081 - srs = &ic->ic_sup_rates[ieee80211_chan2mode(se->se_chan)];
1082 + srs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, -1)];
1083 nrs = se->se_rates[1];
1084 rs = se->se_rates + 2;
1085 fixedrate = IEEE80211_FIXED_RATE_NONE;
1086 --- a/net80211/ieee80211_output.c
1087 +++ b/net80211/ieee80211_output.c
1088 @@ -1676,8 +1676,8 @@ ieee80211_send_probereq(struct ieee80211
1089
1090 frm = ieee80211_add_ssid(frm, ssid, ssidlen);
1091 mode = ieee80211_chan2mode(ic->ic_curchan);
1092 - frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]);
1093 - frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]);
1094 + frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)]);
1095 + frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)]);
1096
1097 if (optie != NULL) {
1098 memcpy(frm, optie, optielen);
1099 --- a/net80211/ieee80211_proto.c
1100 +++ b/net80211/ieee80211_proto.c
1101 @@ -404,7 +404,7 @@ ieee80211_fix_rate(struct ieee80211_node
1102
1103 error = 0;
1104 okrate = badrate = fixedrate = 0;
1105 - srs = &ic->ic_sup_rates[ieee80211_chan2mode(ni->ni_chan)];
1106 + srs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, -1)];
1107 nrs = &ni->ni_rates;
1108 fixedrate = IEEE80211_FIXED_RATE_NONE;
1109 for (i = 0; i < nrs->rs_nrates;) {
1110 @@ -1401,6 +1401,7 @@ ieee80211_new_state(struct ieee80211vap
1111 IEEE80211_VAPS_UNLOCK_IRQ(ic);
1112 return rc;
1113 }
1114 +EXPORT_SYMBOL(ieee80211_new_state);
1115
1116 static int
1117 __ieee80211_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1118 --- a/ath_rate/minstrel/minstrel.c
1119 +++ b/ath_rate/minstrel/minstrel.c
1120 @@ -195,31 +195,7 @@ calc_usecs_unicast_packet(struct ath_sof
1121 return 0;
1122 }
1123
1124 - /* XXX: Getting MAC/PHY level timings should be fixed for turbo
1125 - * rates, and there is probably a way to get this from the
1126 - * HAL... */
1127 - switch (rt->info[rix].phy) {
1128 - case IEEE80211_T_OFDM:
1129 -#if 0
1130 - t_slot = 9;
1131 - t_sifs = 16;
1132 - t_difs = 28;
1133 - /* fall through */
1134 -#endif
1135 - case IEEE80211_T_TURBO:
1136 - t_slot = 9;
1137 - t_sifs = 8;
1138 - t_difs = 28;
1139 - break;
1140 - case IEEE80211_T_DS:
1141 - /* Fall through to default */
1142 - default:
1143 - /* pg. 205 ieee.802.11.pdf */
1144 - t_slot = 20;
1145 - t_difs = 50;
1146 - t_sifs = 10;
1147 - }
1148 -
1149 + ath_get_timings(sc, &t_slot, &t_sifs, &t_difs);
1150 if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1151 (rt->info[rix].phy == IEEE80211_T_OFDM)) {
1152 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
1153 --- a/ath_rate/sample/sample.c
1154 +++ b/ath_rate/sample/sample.c
1155 @@ -172,26 +172,7 @@ calc_usecs_unicast_packet(struct ath_sof
1156 * rates, and there is probably a way to get this from the
1157 * hal...
1158 */
1159 - switch (rt->info[rix].phy) {
1160 - case IEEE80211_T_OFDM:
1161 - t_slot = 9;
1162 - t_sifs = 16;
1163 - t_difs = 28;
1164 - /* fall through */
1165 - case IEEE80211_T_TURBO:
1166 - t_slot = 9;
1167 - t_sifs = 8;
1168 - t_difs = 28;
1169 - break;
1170 - case IEEE80211_T_DS:
1171 - /* fall through to default */
1172 - default:
1173 - /* pg 205 ieee.802.11.pdf */
1174 - t_slot = 20;
1175 - t_difs = 50;
1176 - t_sifs = 10;
1177 - }
1178 -
1179 + ath_get_timings(sc, &t_slot, &t_sifs, &t_difs);
1180 rts = cts = 0;
1181
1182 if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1183 --- a/net80211/ieee80211_wireless.c
1184 +++ b/net80211/ieee80211_wireless.c
1185 @@ -2133,7 +2133,7 @@ ieee80211_ioctl_setmode(struct net_devic
1186
1187 vap->iv_des_mode = mode;
1188 if (IS_UP_AUTO(vap))
1189 - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
1190 + ieee80211_init(vap->iv_dev, 0);
1191
1192 retv = 0;
1193 }
1194 @@ -4081,46 +4081,60 @@ ieee80211_ioctl_getchanlist(struct net_d
1195 return 0;
1196 }
1197
1198 +static int alreadyListed(struct ieee80211req_chaninfo *chans, u_int16_t mhz)
1199 +{
1200 + int i;
1201 + for (i = 0; i < chans->ic_nchans; i++) {
1202 + if (chans->ic_chans[i].ic_freq == mhz)
1203 + return 1;
1204 + }
1205 + return 0;
1206 +}
1207 +
1208 static int
1209 ieee80211_ioctl_getchaninfo(struct net_device *dev,
1210 - struct iw_request_info *info, void *w, char *extra)
1211 + struct iw_request_info *info, void *w, char *extra)
1212 {
1213 struct ieee80211vap *vap = dev->priv;
1214 struct ieee80211com *ic = vap->iv_ic;
1215 - struct ieee80211req_chaninfo chans;
1216 + struct ieee80211req_chaninfo *chans =
1217 + (struct ieee80211req_chaninfo *)extra;
1218 +
1219 u_int8_t reported[IEEE80211_CHAN_BYTES]; /* XXX stack usage? */
1220 int i;
1221
1222 - memset(&chans, 0, sizeof(chans));
1223 - memset(&reported, 0, sizeof(reported));
1224 + memset(chans, 0, sizeof(*chans));
1225 + memset(reported, 0, sizeof(reported));
1226 for (i = 0; i < ic->ic_nchans; i++) {
1227 const struct ieee80211_channel *c = &ic->ic_channels[i];
1228 const struct ieee80211_channel *c1 = c;
1229
1230 - if (isclr(reported, c->ic_ieee)) {
1231 + if (!alreadyListed(chans, c->ic_freq)) {
1232 setbit(reported, c->ic_ieee);
1233
1234 - /* pick turbo channel over non-turbo channel, and
1235 - * 11g channel over 11b channel */
1236 if (IEEE80211_IS_CHAN_A(c))
1237 - c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_A);
1238 + c1 = findchannel(ic, c->ic_freq,
1239 + IEEE80211_MODE_TURBO_A);
1240 if (IEEE80211_IS_CHAN_ANYG(c))
1241 - c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_G);
1242 + c1 = findchannel(ic, c->ic_freq,
1243 + IEEE80211_MODE_TURBO_G);
1244 else if (IEEE80211_IS_CHAN_B(c)) {
1245 - c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_G);
1246 + c1 = findchannel(ic, c->ic_freq,
1247 + IEEE80211_MODE_TURBO_G);
1248 if (!c1)
1249 - c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_11G);
1250 + c1 = findchannel(ic, c->ic_freq,
1251 + IEEE80211_MODE_11G);
1252 }
1253
1254 if (c1)
1255 c = c1;
1256 - /* Copy the entire structure, whereas it used to just copy a few fields */
1257 - memcpy(&chans.ic_chans[chans.ic_nchans], c, sizeof(struct ieee80211_channel));
1258 - if (++chans.ic_nchans >= IEEE80211_CHAN_MAX)
1259 + chans->ic_chans[chans->ic_nchans].ic_ieee = c->ic_ieee;
1260 + chans->ic_chans[chans->ic_nchans].ic_freq = c->ic_freq;
1261 + chans->ic_chans[chans->ic_nchans].ic_flags = c->ic_flags;
1262 + if (++chans->ic_nchans >= IEEE80211_CHAN_MAX)
1263 break;
1264 }
1265 }
1266 - memcpy(extra, &chans, sizeof(struct ieee80211req_chaninfo));
1267 return 0;
1268 }
1269
1270 --- a/net80211/ieee80211_scan_ap.c
1271 +++ b/net80211/ieee80211_scan_ap.c
1272 @@ -512,12 +512,13 @@ pick_channel(struct ieee80211_scan_state
1273 int ss_last = ss->ss_last;
1274 struct ieee80211_channel *best;
1275 struct ap_state *as = ss->ss_priv;
1276 - struct channel chans[ss_last]; /* actually ss_last-1 is required */
1277 + struct channel *chans; /* actually ss_last-1 is required */
1278 struct channel *c = NULL;
1279 struct pc_params params = { vap, ss, flags };
1280 int benefit = 0;
1281 int sta_assoc = 0;
1282
1283 + chans = (struct channel *)kmalloc(ss_last*sizeof(struct channel),GFP_ATOMIC);
1284 for (i = 0; i < ss_last; i++) {
1285 chans[i].chan = ss->ss_chans[i];
1286 chans[i].orig = i;
1287 @@ -571,6 +572,7 @@ pick_channel(struct ieee80211_scan_state
1288 "%s: best: channel %u rssi %d\n",
1289 __func__, i, as->as_maxrssi[i]);
1290 }
1291 + kfree(chans);
1292 return best;
1293 }
1294
1295 @@ -609,6 +611,7 @@ ap_end(struct ieee80211_scan_state *ss,
1296 res = 1; /* Do NOT restart scan */
1297 } else {
1298 struct ieee80211_scan_entry se;
1299 + int i;
1300 /* XXX: notify all VAPs? */
1301 /* if this is a dynamic turbo frequency , start with normal
1302 * mode first */
1303 @@ -623,6 +626,11 @@ ap_end(struct ieee80211_scan_state *ss,
1304 return 0;
1305 }
1306 }
1307 + for (i = (bestchan - &ic->ic_channels[0])/sizeof(*bestchan) + 1; i < ic->ic_nchans; i++) {
1308 + if ((ic->ic_channels[i].ic_freq == bestchan->ic_freq) &&
1309 + IEEE80211_IS_CHAN_ANYG(&ic->ic_channels[i]))
1310 + bestchan = &ic->ic_channels[i];
1311 + }
1312 memset(&se, 0, sizeof(se));
1313 se.se_chan = bestchan;
1314
1315 --- a/tools/wlanconfig.c
1316 +++ b/tools/wlanconfig.c
1317 @@ -737,7 +737,7 @@ list_channels(const char *ifname, int al
1318 if (get80211priv(ifname, IEEE80211_IOCTL_GETCHANINFO, &chans, sizeof(chans)) < 0)
1319 errx(1, "unable to get channel information");
1320 if (!allchans) {
1321 - uint8_t active[32];
1322 + uint8_t active[IEEE80211_CHAN_BYTES];
1323
1324 if (get80211priv(ifname, IEEE80211_IOCTL_GETCHANLIST, &active, sizeof(active)) < 0)
1325 errx(1, "unable to get active channel list");
1326 --- a/net80211/ieee80211_scan.c
1327 +++ b/net80211/ieee80211_scan.c
1328 @@ -1044,6 +1044,7 @@ ieee80211_scan_assoc_fail(struct ieee802
1329 ss->ss_ops->scan_assoc_fail(ss, mac, reason);
1330 }
1331 }
1332 +EXPORT_SYMBOL(ieee80211_scan_flush);
1333
1334 /*
1335 * Iterate over the contents of the scan cache.
1336 --- a/ath/if_ath_hal_wrappers.h
1337 +++ b/ath/if_ath_hal_wrappers.h
1338 @@ -111,6 +111,11 @@ static inline HAL_BOOL ath_hal_getregdom
1339 return (ath_hal_getcapability(ah, HAL_CAP_REG_DMN, 0, destination) == HAL_OK);
1340 }
1341
1342 +static inline HAL_BOOL ath_hal_setregdomain(struct ath_hal *ah, u_int32_t v)
1343 +{
1344 + return (ath_hal_setcapability(ah, HAL_CAP_REG_DMN, 0, v, NULL));
1345 +}
1346 +
1347 static inline HAL_BOOL ath_hal_gettkipmic(struct ath_hal *ah)
1348 {
1349 return (ath_hal_getcapability(ah, HAL_CAP_TKIP_MIC, 1, NULL) == HAL_OK);