| 1 | --- a/net80211/ieee80211_scan_sta.c |
| 2 | +++ b/net80211/ieee80211_scan_sta.c |
| 3 | @@ -317,147 +317,6 @@ found: |
| 4 | #undef ISPROBE |
| 5 | } |
| 6 | |
| 7 | -static struct ieee80211_channel * |
| 8 | -find11gchannel(struct ieee80211com *ic, int i, int freq) |
| 9 | -{ |
| 10 | - struct ieee80211_channel *c; |
| 11 | - int j; |
| 12 | - |
| 13 | - /* |
| 14 | - * The normal ordering in the channel list is b channel |
| 15 | - * immediately followed by g so optimize the search for |
| 16 | - * this. We'll still do a full search just in case. |
| 17 | - */ |
| 18 | - for (j = i+1; j < ic->ic_nchans; j++) { |
| 19 | - c = &ic->ic_channels[j]; |
| 20 | - if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) |
| 21 | - return c; |
| 22 | - } |
| 23 | - for (j = 0; j < i; j++) { |
| 24 | - c = &ic->ic_channels[j]; |
| 25 | - if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) |
| 26 | - return c; |
| 27 | - } |
| 28 | - return NULL; |
| 29 | -} |
| 30 | -static const u_int chanflags[] = { |
| 31 | - IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ |
| 32 | - IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ |
| 33 | - IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ |
| 34 | - IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ |
| 35 | - IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ |
| 36 | - IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ |
| 37 | - IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ |
| 38 | - IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ |
| 39 | -}; |
| 40 | - |
| 41 | -static void |
| 42 | -add_channels(struct ieee80211com *ic, |
| 43 | - struct ieee80211_scan_state *ss, |
| 44 | - enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) |
| 45 | -{ |
| 46 | - struct ieee80211_channel *c, *cg; |
| 47 | - u_int modeflags; |
| 48 | - int i; |
| 49 | - |
| 50 | - KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); |
| 51 | - modeflags = chanflags[mode]; |
| 52 | - for (i = 0; i < nfreq; i++) { |
| 53 | - c = ieee80211_find_channel(ic, freq[i], modeflags); |
| 54 | - if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) |
| 55 | - continue; |
| 56 | - if (mode == IEEE80211_MODE_AUTO) { |
| 57 | - /* |
| 58 | - * XXX special-case 11b/g channels so we select |
| 59 | - * the g channel if both are present. |
| 60 | - */ |
| 61 | - if (IEEE80211_IS_CHAN_B(c) && |
| 62 | - (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) |
| 63 | - c = cg; |
| 64 | - } |
| 65 | - if (ss->ss_last >= IEEE80211_SCAN_MAX) |
| 66 | - break; |
| 67 | - ss->ss_chans[ss->ss_last++] = c; |
| 68 | - } |
| 69 | -} |
| 70 | - |
| 71 | -static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */ |
| 72 | -{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; |
| 73 | -static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ |
| 74 | -{ 5170, 5190, 5210, 5230 }; |
| 75 | -static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ |
| 76 | -{ 2412, 2437, 2462, 2442, 2472 }; |
| 77 | -static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ |
| 78 | -{ 5745, 5765, 5785, 5805, 5825 }; |
| 79 | -static const u_int16_t rcl7[] = /* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */ |
| 80 | -{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; |
| 81 | -static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ |
| 82 | -{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; |
| 83 | -static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ |
| 84 | -{ 2484 }; |
| 85 | -static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ |
| 86 | -{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; |
| 87 | -static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ |
| 88 | -{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; |
| 89 | -#ifdef ATH_TURBO_SCAN |
| 90 | -static const u_int16_t rcl5[] = /* 3 static turbo channels */ |
| 91 | -{ 5210, 5250, 5290 }; |
| 92 | -static const u_int16_t rcl6[] = /* 2 static turbo channels */ |
| 93 | -{ 5760, 5800 }; |
| 94 | -static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ |
| 95 | -{ 5540, 5580, 5620, 5660 }; |
| 96 | -static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ |
| 97 | -{ 2437 }; |
| 98 | -static const u_int16_t rcl13[] = /* dynamic Turbo channels */ |
| 99 | -{ 5200, 5240, 5280, 5765, 5805 }; |
| 100 | -#endif /* ATH_TURBO_SCAN */ |
| 101 | - |
| 102 | -struct scanlist { |
| 103 | - u_int16_t mode; |
| 104 | - u_int16_t count; |
| 105 | - const u_int16_t *list; |
| 106 | -}; |
| 107 | - |
| 108 | -#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX |
| 109 | -#define X(a) .count = sizeof(a)/sizeof(a[0]), .list = a |
| 110 | - |
| 111 | -static const struct scanlist staScanTable[] = { |
| 112 | - { IEEE80211_MODE_11B, X(rcl3) }, |
| 113 | - { IEEE80211_MODE_11A, X(rcl1) }, |
| 114 | - { IEEE80211_MODE_11A, X(rcl2) }, |
| 115 | - { IEEE80211_MODE_11B, X(rcl8) }, |
| 116 | - { IEEE80211_MODE_11B, X(rcl9) }, |
| 117 | - { IEEE80211_MODE_11A, X(rcl4) }, |
| 118 | -#ifdef ATH_TURBO_SCAN |
| 119 | - { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, |
| 120 | - { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, |
| 121 | - { IEEE80211_MODE_TURBO_A, X(rcl6x) }, |
| 122 | - { IEEE80211_MODE_TURBO_A, X(rcl13) }, |
| 123 | -#endif /* ATH_TURBO_SCAN */ |
| 124 | - { IEEE80211_MODE_11A, X(rcl7) }, |
| 125 | - { IEEE80211_MODE_11B, X(rcl10) }, |
| 126 | - { IEEE80211_MODE_11A, X(rcl11) }, |
| 127 | -#ifdef ATH_TURBO_SCAN |
| 128 | - { IEEE80211_MODE_TURBO_G, X(rcl12) }, |
| 129 | -#endif /* ATH_TURBO_SCAN */ |
| 130 | - { .list = NULL } |
| 131 | -}; |
| 132 | - |
| 133 | -#undef X |
| 134 | - |
| 135 | -static int |
| 136 | -checktable(const struct scanlist *scan, const struct ieee80211_channel *c) |
| 137 | -{ |
| 138 | - int i; |
| 139 | - |
| 140 | - for (; scan->list != NULL; scan++) { |
| 141 | - for (i = 0; i < scan->count; i++) |
| 142 | - if (scan->list[i] == c->ic_freq) |
| 143 | - return 1; |
| 144 | - } |
| 145 | - return 0; |
| 146 | -} |
| 147 | - |
| 148 | /* |
| 149 | * Start a station-mode scan by populating the channel list. |
| 150 | */ |
| 151 | @@ -466,81 +325,14 @@ sta_start(struct ieee80211_scan_state *s |
| 152 | { |
| 153 | struct ieee80211com *ic = vap->iv_ic; |
| 154 | struct sta_table *st = ss->ss_priv; |
| 155 | - const struct scanlist *scan; |
| 156 | enum ieee80211_phymode mode; |
| 157 | struct ieee80211_channel *c; |
| 158 | int i; |
| 159 | |
| 160 | ss->ss_last = 0; |
| 161 | - /* |
| 162 | - * Use the table of ordered channels to construct the list |
| 163 | - * of channels for scanning. Any channels in the ordered |
| 164 | - * list not in the master list will be discarded. |
| 165 | - */ |
| 166 | - for (scan = staScanTable; scan->list != NULL; scan++) { |
| 167 | - mode = scan->mode; |
| 168 | - if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { |
| 169 | - /* |
| 170 | - * If a desired mode was specified, scan only |
| 171 | - * channels that satisfy that constraint. |
| 172 | - */ |
| 173 | - if (vap->iv_des_mode != mode) { |
| 174 | - /* |
| 175 | - * The scan table marks 2.4Ghz channels as b |
| 176 | - * so if the desired mode is 11g, then use |
| 177 | - * the 11b channel list but upgrade the mode. |
| 178 | - */ |
| 179 | - if (vap->iv_des_mode != IEEE80211_MODE_11G || |
| 180 | - mode != IEEE80211_MODE_11B) |
| 181 | - continue; |
| 182 | - mode = IEEE80211_MODE_11G; /* upgrade */ |
| 183 | - } |
| 184 | - } else { |
| 185 | - /* |
| 186 | - * This lets ieee80211_scan_add_channels |
| 187 | - * upgrade an 11b channel to 11g if available. |
| 188 | - */ |
| 189 | - if (mode == IEEE80211_MODE_11B) |
| 190 | - mode = IEEE80211_MODE_AUTO; |
| 191 | - } |
| 192 | - /* XR does not operate on turbo channels */ |
| 193 | - if ((vap->iv_flags & IEEE80211_F_XR) && |
| 194 | - (mode == IEEE80211_MODE_TURBO_A || |
| 195 | - mode == IEEE80211_MODE_TURBO_G)) |
| 196 | - continue; |
| 197 | - /* |
| 198 | - * Add the list of the channels; any that are not |
| 199 | - * in the master channel list will be discarded. |
| 200 | - */ |
| 201 | - add_channels(ic, ss, mode, scan->list, scan->count); |
| 202 | - } |
| 203 | - |
| 204 | - /* |
| 205 | - * Add the channels from the ic (from HAL) that are not present |
| 206 | - * in the staScanTable. |
| 207 | - */ |
| 208 | - for (i = 0; i < ic->ic_nchans; i++) { |
| 209 | - c = &ic->ic_channels[i]; |
| 210 | - /* |
| 211 | - * scan dynamic turbo channels in normal mode. |
| 212 | - */ |
| 213 | - if (IEEE80211_IS_CHAN_DTURBO(c)) |
| 214 | - continue; |
| 215 | - mode = ieee80211_chan2mode(c); |
| 216 | - if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { |
| 217 | - /* |
| 218 | - * If a desired mode was specified, scan only |
| 219 | - * channels that satisfy that constraint. |
| 220 | - */ |
| 221 | - if (vap->iv_des_mode != mode) |
| 222 | - continue; |
| 223 | - |
| 224 | - } |
| 225 | - if (!checktable(staScanTable, c)) |
| 226 | - ss->ss_chans[ss->ss_last++] = c; |
| 227 | - } |
| 228 | - |
| 229 | + ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); |
| 230 | ss->ss_next = 0; |
| 231 | + |
| 232 | /* XXX tunables */ |
| 233 | /* |
| 234 | * The scanner will stay on station for ss_maxdwell ms (using a |
| 235 | @@ -749,17 +541,7 @@ match_bss(struct ieee80211vap *vap, |
| 236 | fail = 0; |
| 237 | if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, se->se_chan))) |
| 238 | fail |= 0x01; |
| 239 | - /* |
| 240 | - * NB: normally the desired mode is used to construct |
| 241 | - * the channel list, but it's possible for the scan |
| 242 | - * cache to include entries for stations outside this |
| 243 | - * list so we check the desired mode here to weed them |
| 244 | - * out. |
| 245 | - */ |
| 246 | - if (vap->iv_des_mode != IEEE80211_MODE_AUTO && |
| 247 | - (se->se_chan->ic_flags & IEEE80211_CHAN_ALLTURBO) != |
| 248 | - chanflags[vap->iv_des_mode]) |
| 249 | - fail |= 0x01; |
| 250 | + |
| 251 | if (vap->iv_opmode == IEEE80211_M_IBSS) { |
| 252 | if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0) |
| 253 | fail |= 0x02; |
| 254 | @@ -1168,78 +950,6 @@ static const struct ieee80211_scanner st |
| 255 | .scan_default = ieee80211_sta_join, |
| 256 | }; |
| 257 | |
| 258 | -/* |
| 259 | - * Start an adhoc-mode scan by populating the channel list. |
| 260 | - */ |
| 261 | -static int |
| 262 | -adhoc_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) |
| 263 | -{ |
| 264 | - struct ieee80211com *ic = vap->iv_ic; |
| 265 | - struct sta_table *st = ss->ss_priv; |
| 266 | - const struct scanlist *scan; |
| 267 | - enum ieee80211_phymode mode; |
| 268 | - |
| 269 | - ss->ss_last = 0; |
| 270 | - /* |
| 271 | - * Use the table of ordered channels to construct the list |
| 272 | - * of channels for scanning. Any channels in the ordered |
| 273 | - * list not in the master list will be discarded. |
| 274 | - */ |
| 275 | - for (scan = staScanTable; scan->list != NULL; scan++) { |
| 276 | - mode = scan->mode; |
| 277 | - if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { |
| 278 | - /* |
| 279 | - * If a desired mode was specified, scan only |
| 280 | - * channels that satisfy that constraint. |
| 281 | - */ |
| 282 | - if (vap->iv_des_mode != mode) { |
| 283 | - /* |
| 284 | - * The scan table marks 2.4Ghz channels as b |
| 285 | - * so if the desired mode is 11g, then use |
| 286 | - * the 11b channel list but upgrade the mode. |
| 287 | - */ |
| 288 | - if (vap->iv_des_mode != IEEE80211_MODE_11G || |
| 289 | - mode != IEEE80211_MODE_11B) |
| 290 | - continue; |
| 291 | - mode = IEEE80211_MODE_11G; /* upgrade */ |
| 292 | - } |
| 293 | - } else { |
| 294 | - /* |
| 295 | - * This lets ieee80211_scan_add_channels |
| 296 | - * upgrade an 11b channel to 11g if available. |
| 297 | - */ |
| 298 | - if (mode == IEEE80211_MODE_11B) |
| 299 | - mode = IEEE80211_MODE_AUTO; |
| 300 | - } |
| 301 | - /* XR does not operate on turbo channels */ |
| 302 | - if ((vap->iv_flags & IEEE80211_F_XR) && |
| 303 | - (mode == IEEE80211_MODE_TURBO_A || |
| 304 | - mode == IEEE80211_MODE_TURBO_G)) |
| 305 | - continue; |
| 306 | - /* |
| 307 | - * Add the list of the channels; any that are not |
| 308 | - * in the master channel list will be discarded. |
| 309 | - */ |
| 310 | - add_channels(ic, ss, mode, scan->list, scan->count); |
| 311 | - } |
| 312 | - ss->ss_next = 0; |
| 313 | - /* XXX tunables */ |
| 314 | - ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */ |
| 315 | - ss->ss_maxdwell = msecs_to_jiffies(200); /* 200ms */ |
| 316 | - |
| 317 | -#ifdef IEEE80211_DEBUG |
| 318 | - if (ieee80211_msg_scan(vap)) { |
| 319 | - printk("%s: scan set ", vap->iv_dev->name); |
| 320 | - ieee80211_scan_dump_channels(ss); |
| 321 | - printk(" dwell min %ld max %ld\n", |
| 322 | - ss->ss_mindwell, ss->ss_maxdwell); |
| 323 | - } |
| 324 | -#endif /* IEEE80211_DEBUG */ |
| 325 | - |
| 326 | - st->st_newscan = 1; |
| 327 | - |
| 328 | - return 0; |
| 329 | -} |
| 330 | |
| 331 | /* |
| 332 | * Select a channel to start an adhoc network on. |
| 333 | @@ -1405,7 +1115,7 @@ static const struct ieee80211_scanner ad |
| 334 | .scan_name = "default", |
| 335 | .scan_attach = sta_attach, |
| 336 | .scan_detach = sta_detach, |
| 337 | - .scan_start = adhoc_start, |
| 338 | + .scan_start = sta_start, |
| 339 | .scan_restart = sta_restart, |
| 340 | .scan_cancel = sta_cancel, |
| 341 | .scan_end = adhoc_pick_bss, |
| 342 | --- a/net80211/ieee80211.c |
| 343 | +++ b/net80211/ieee80211.c |
| 344 | @@ -278,6 +278,11 @@ ieee80211_ifattach(struct ieee80211com * |
| 345 | ("channel with bogus ieee number %u", c->ic_ieee)); |
| 346 | setbit(ic->ic_chan_avail, c->ic_ieee); |
| 347 | |
| 348 | + if (c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT) |
| 349 | + c->ic_scanflags |= IEEE80211_NOSCAN_SET; |
| 350 | + else |
| 351 | + c->ic_scanflags &= ~IEEE80211_NOSCAN_SET; |
| 352 | + |
| 353 | /* Identify mode capabilities. */ |
| 354 | if (IEEE80211_IS_CHAN_A(c)) |
| 355 | ic->ic_modecaps |= 1 << IEEE80211_MODE_11A; |
| 356 | @@ -1447,10 +1452,6 @@ ieee80211_media_change(struct net_device |
| 357 | vap->iv_fixed_rate = newrate; /* fixed TX rate */ |
| 358 | error = -ENETRESET; |
| 359 | } |
| 360 | - if (vap->iv_des_mode != newmode) { |
| 361 | - vap->iv_des_mode = newmode; /* desired PHY mode */ |
| 362 | - error = -ENETRESET; |
| 363 | - } |
| 364 | return error; |
| 365 | } |
| 366 | EXPORT_SYMBOL(ieee80211_media_change); |
| 367 | --- a/net80211/_ieee80211.h |
| 368 | +++ b/net80211/_ieee80211.h |
| 369 | @@ -132,6 +132,11 @@ enum ieee80211_scanmode { |
| 370 | IEEE80211_SCAN_FIRST = 2, /* take first suitable candidate */ |
| 371 | }; |
| 372 | |
| 373 | +enum ieee80211_scanflags { |
| 374 | + IEEE80211_NOSCAN_DEFAULT = (1 << 0), |
| 375 | + IEEE80211_NOSCAN_SET = (1 << 1), |
| 376 | +}; |
| 377 | + |
| 378 | /* |
| 379 | * Channels are specified by frequency and attributes. |
| 380 | */ |
| 381 | @@ -142,6 +147,7 @@ struct ieee80211_channel { |
| 382 | int8_t ic_maxregpower; /* maximum regulatory tx power in dBm */ |
| 383 | int8_t ic_maxpower; /* maximum tx power in dBm */ |
| 384 | int8_t ic_minpower; /* minimum tx power in dBm */ |
| 385 | + u_int8_t ic_scanflags; |
| 386 | }; |
| 387 | |
| 388 | #define IEEE80211_CHAN_MAX 255 |
| 389 | --- a/net80211/ieee80211_ioctl.h |
| 390 | +++ b/net80211/ieee80211_ioctl.h |
| 391 | @@ -555,6 +555,7 @@ struct ieee80211req_scan_result { |
| 392 | #define IEEE80211_IOCTL_WDSADDMAC (SIOCIWFIRSTPRIV+26) |
| 393 | #define IEEE80211_IOCTL_WDSDELMAC (SIOCIWFIRSTPRIV+28) |
| 394 | #define IEEE80211_IOCTL_KICKMAC (SIOCIWFIRSTPRIV+30) |
| 395 | +#define IEEE80211_IOCTL_SETSCANLIST (SIOCIWFIRSTPRIV+31) |
| 396 | |
| 397 | enum { |
| 398 | IEEE80211_WMMPARAMS_CWMIN = 1, |
| 399 | --- a/net80211/ieee80211_scan_ap.c |
| 400 | +++ b/net80211/ieee80211_scan_ap.c |
| 401 | @@ -105,11 +105,6 @@ struct scan_entry { |
| 402 | }; |
| 403 | |
| 404 | struct ap_state { |
| 405 | - unsigned int as_vap_desired_mode; /* Used for channel selection, |
| 406 | - * vap->iv_des_mode */ |
| 407 | - unsigned int as_required_mode; /* Used for channel selection, |
| 408 | - * filtered version of |
| 409 | - * as_vap_desired_mode */ |
| 410 | int as_maxrssi[IEEE80211_CHAN_MAX]; /* Used for channel selection */ |
| 411 | |
| 412 | /* These fields are just for scan caching for returning responses to |
| 413 | @@ -129,131 +124,7 @@ struct ap_state { |
| 414 | |
| 415 | static int ap_flush(struct ieee80211_scan_state *); |
| 416 | static void action_tasklet(IEEE80211_TQUEUE_ARG); |
| 417 | -static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic, |
| 418 | - int i, int freq); |
| 419 | |
| 420 | -static const u_int chanflags[] = { |
| 421 | - IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ |
| 422 | - IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ |
| 423 | - IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ |
| 424 | - IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ |
| 425 | - IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ |
| 426 | - IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode |
| 427 | - * look for AP in |
| 428 | - * normal channel |
| 429 | - */ |
| 430 | - IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ |
| 431 | - IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ |
| 432 | -}; |
| 433 | - |
| 434 | -static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, |
| 435 | - * 36, 40, 44, 48 */ |
| 436 | -{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; |
| 437 | -static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ |
| 438 | -{ 5170, 5190, 5210, 5230 }; |
| 439 | -static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ |
| 440 | -{ 2412, 2437, 2462, 2442, 2472 }; |
| 441 | -static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ |
| 442 | -{ 5745, 5765, 5785, 5805, 5825 }; |
| 443 | -static const u_int16_t rcl7[] = /* 11 ETSI channel: 100, 104, 108, 112, |
| 444 | - * 116, 120, 124, 128, |
| 445 | - * 132, 136, 140 */ |
| 446 | -{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; |
| 447 | -static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ |
| 448 | -{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; |
| 449 | -static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ |
| 450 | -{ 2484 }; |
| 451 | -static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ |
| 452 | -{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; |
| 453 | -static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ |
| 454 | -{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; |
| 455 | -#ifdef ATH_TURBO_SCAN |
| 456 | -static const u_int16_t rcl5[] = /* 3 static turbo channels */ |
| 457 | -{ 5210, 5250, 5290 }; |
| 458 | -static const u_int16_t rcl6[] = /* 2 static turbo channels */ |
| 459 | -{ 5760, 5800 }; |
| 460 | -static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ |
| 461 | -{ 5540, 5580, 5620, 5660 }; |
| 462 | -static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ |
| 463 | -{ 2437 }; |
| 464 | -static const u_int16_t rcl13[] = /* dynamic Turbo channels */ |
| 465 | -{ 5200, 5240, 5280, 5765, 5805 }; |
| 466 | -#endif /* ATH_TURBO_SCAN */ |
| 467 | - |
| 468 | -struct scanlist { |
| 469 | - u_int16_t mode; |
| 470 | - u_int16_t count; |
| 471 | - const u_int16_t *list; |
| 472 | -}; |
| 473 | - |
| 474 | -#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX |
| 475 | -#define X(a) .count = ARRAY_SIZE(a), .list = a |
| 476 | - |
| 477 | -static const struct scanlist staScanTable[] = { |
| 478 | - { IEEE80211_MODE_11B, X(rcl3) }, |
| 479 | - { IEEE80211_MODE_11A, X(rcl1) }, |
| 480 | - { IEEE80211_MODE_11A, X(rcl2) }, |
| 481 | - { IEEE80211_MODE_11B, X(rcl8) }, |
| 482 | - { IEEE80211_MODE_11B, X(rcl9) }, |
| 483 | - { IEEE80211_MODE_11A, X(rcl4) }, |
| 484 | -#ifdef ATH_TURBO_SCAN |
| 485 | - { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, |
| 486 | - { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, |
| 487 | - { IEEE80211_MODE_TURBO_A, X(rcl6x) }, |
| 488 | - { IEEE80211_MODE_TURBO_A, X(rcl13) }, |
| 489 | -#endif /* ATH_TURBO_SCAN */ |
| 490 | - { IEEE80211_MODE_11A, X(rcl7) }, |
| 491 | - { IEEE80211_MODE_11B, X(rcl10) }, |
| 492 | - { IEEE80211_MODE_11A, X(rcl11) }, |
| 493 | -#ifdef ATH_TURBO_SCAN |
| 494 | - { IEEE80211_MODE_TURBO_G, X(rcl12) }, |
| 495 | -#endif /* ATH_TURBO_SCAN */ |
| 496 | - { .list = NULL } |
| 497 | -}; |
| 498 | - |
| 499 | -#undef X |
| 500 | -/* This function must be invoked with locks acquired */ |
| 501 | -static void |
| 502 | -add_channels(struct ieee80211com *ic, |
| 503 | - struct ieee80211_scan_state *ss, |
| 504 | - enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) |
| 505 | -{ |
| 506 | - struct ieee80211_channel *c, *cg; |
| 507 | - u_int modeflags; |
| 508 | - int i; |
| 509 | - |
| 510 | - KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); |
| 511 | - modeflags = chanflags[mode]; |
| 512 | - for (i = 0; i < nfreq; i++) { |
| 513 | - c = ieee80211_find_channel(ic, freq[i], modeflags); |
| 514 | - if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee)) |
| 515 | - continue; |
| 516 | - if (mode == IEEE80211_MODE_AUTO) { |
| 517 | - /* XXX special-case 11b/g channels so we select |
| 518 | - * the g channel if both are present. */ |
| 519 | - if (IEEE80211_IS_CHAN_B(c) && |
| 520 | - (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) |
| 521 | - c = cg; |
| 522 | - } |
| 523 | - if (ss->ss_last >= IEEE80211_SCAN_MAX) |
| 524 | - break; |
| 525 | - ss->ss_chans[ss->ss_last++] = c; |
| 526 | - } |
| 527 | -} |
| 528 | - |
| 529 | -/* This function must be invoked with locks acquired */ |
| 530 | -static int |
| 531 | -checktable(const struct scanlist *scan, const struct ieee80211_channel *c) |
| 532 | -{ |
| 533 | - int i; |
| 534 | - |
| 535 | - for (; scan->list != NULL; scan++) { |
| 536 | - for (i = 0; i < scan->count; i++) |
| 537 | - if (scan->list[i] == c->ic_freq) |
| 538 | - return 1; |
| 539 | - } |
| 540 | - return 0; |
| 541 | -} |
| 542 | |
| 543 | /* |
| 544 | * Attach prior to any scanning work. |
| 545 | @@ -327,29 +198,6 @@ saveie(u_int8_t **iep, const u_int8_t *i |
| 546 | ieee80211_saveie(iep, ie); |
| 547 | } |
| 548 | |
| 549 | -/* This function must be invoked with locks acquired */ |
| 550 | -static struct ieee80211_channel * |
| 551 | -find11gchannel(struct ieee80211com *ic, int i, int freq) |
| 552 | -{ |
| 553 | - struct ieee80211_channel *c; |
| 554 | - int j; |
| 555 | - |
| 556 | - /* The normal ordering in the channel list is b channel |
| 557 | - * immediately followed by g so optimize the search for |
| 558 | - * this. We'll still do a full search just in case. */ |
| 559 | - for (j = i + 1; j < ic->ic_nchans; j++) { |
| 560 | - c = &ic->ic_channels[j]; |
| 561 | - if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c)) |
| 562 | - return c; |
| 563 | - } |
| 564 | - for (j = 0; j < i; j++) { |
| 565 | - c = &ic->ic_channels[j]; |
| 566 | - if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c)) |
| 567 | - return c; |
| 568 | - } |
| 569 | - return NULL; |
| 570 | -} |
| 571 | - |
| 572 | /* |
| 573 | * Start an ap scan by populating the channel list. |
| 574 | */ |
| 575 | @@ -358,90 +206,15 @@ ap_start(struct ieee80211_scan_state *ss |
| 576 | { |
| 577 | struct ap_state *as = ss->ss_priv; |
| 578 | struct ieee80211com *ic = NULL; |
| 579 | - const struct scanlist *sl = NULL; |
| 580 | - struct ieee80211_channel *c = NULL; |
| 581 | int i; |
| 582 | unsigned int mode = 0; |
| 583 | |
| 584 | SCAN_AP_LOCK_IRQ(as); |
| 585 | ic = vap->iv_ic; |
| 586 | /* Determine mode flags to match, or leave zero for auto mode */ |
| 587 | - as->as_vap_desired_mode = vap->iv_des_mode; |
| 588 | - as->as_required_mode = 0; |
| 589 | - if (as->as_vap_desired_mode != IEEE80211_MODE_AUTO) { |
| 590 | - as->as_required_mode = chanflags[as->as_vap_desired_mode]; |
| 591 | - if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) && |
| 592 | - (as->as_required_mode != IEEE80211_CHAN_ST)) { |
| 593 | - /* Fixup for dynamic turbo flags */ |
| 594 | - if (as->as_vap_desired_mode == IEEE80211_MODE_11G) |
| 595 | - as->as_required_mode = IEEE80211_CHAN_108G; |
| 596 | - else |
| 597 | - as->as_required_mode = IEEE80211_CHAN_108A; |
| 598 | - } |
| 599 | - } |
| 600 | - |
| 601 | ss->ss_last = 0; |
| 602 | - /* Use the table of ordered channels to construct the list |
| 603 | - * of channels for scanning. Any channels in the ordered |
| 604 | - * list not in the master list will be discarded. */ |
| 605 | - for (sl = staScanTable; sl->list != NULL; sl++) { |
| 606 | - mode = sl->mode; |
| 607 | - |
| 608 | - /* The scan table marks 2.4Ghz channels as b |
| 609 | - * so if the desired mode is 11g, then use |
| 610 | - * the 11b channel list but upgrade the mode. */ |
| 611 | - if (as->as_vap_desired_mode && |
| 612 | - (as->as_vap_desired_mode != mode) && |
| 613 | - (as->as_vap_desired_mode == IEEE80211_MODE_11G) && |
| 614 | - (mode == IEEE80211_MODE_11B)) |
| 615 | - mode = IEEE80211_MODE_11G; |
| 616 | - |
| 617 | - /* If we are in "AUTO" mode, upgrade the mode to auto. |
| 618 | - * This lets add_channels upgrade an 11b channel to |
| 619 | - * 11g if available. */ |
| 620 | - if (!as->as_vap_desired_mode && (mode == IEEE80211_MODE_11B)) |
| 621 | - mode = IEEE80211_MODE_AUTO; |
| 622 | - |
| 623 | - /* Add the list of the channels; any that are not |
| 624 | - * in the master channel list will be discarded. */ |
| 625 | - add_channels(ic, ss, mode, sl->list, sl->count); |
| 626 | - } |
| 627 | - |
| 628 | - /* Add the channels from the ic (from HAL) that are not present |
| 629 | - * in the staScanTable, assuming they pass the sanity checks... */ |
| 630 | - for (i = 0; i < ic->ic_nchans; i++) { |
| 631 | - c = &ic->ic_channels[i]; |
| 632 | - |
| 633 | - /* XR is not supported on turbo channels */ |
| 634 | - if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR) |
| 635 | - continue; |
| 636 | - |
| 637 | - /* Dynamic channels are scanned in base mode */ |
| 638 | - if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c)) |
| 639 | - continue; |
| 640 | - |
| 641 | - /* Use any 11g channel instead of 11b one. */ |
| 642 | - if (vap->iv_des_mode == IEEE80211_MODE_AUTO && |
| 643 | - IEEE80211_IS_CHAN_B(c) && |
| 644 | - find11gchannel(ic, i, c->ic_freq)) |
| 645 | - continue; |
| 646 | - |
| 647 | - /* Do not add channels already put into the scan list by the |
| 648 | - * scan table - these have already been filtered by mode |
| 649 | - * and for whether they are in the active channel list. */ |
| 650 | - if (checktable(staScanTable, c)) |
| 651 | - continue; |
| 652 | - |
| 653 | - /* Make sure the channel is active */ |
| 654 | - if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee)) |
| 655 | - continue; |
| 656 | + ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); |
| 657 | |
| 658 | - /* Don't overrun */ |
| 659 | - if (ss->ss_last >= IEEE80211_SCAN_MAX) |
| 660 | - break; |
| 661 | - |
| 662 | - ss->ss_chans[ss->ss_last++] = c; |
| 663 | - } |
| 664 | ss->ss_next = 0; |
| 665 | /* XXX tunables */ |
| 666 | ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */ |
| 667 | @@ -761,18 +534,6 @@ pick_channel(struct ieee80211_scan_state |
| 668 | if (IEEE80211_IS_CHAN_RADAR(c->chan)) |
| 669 | continue; |
| 670 | |
| 671 | - /* Do not select 802.11a ST if mode is specified and is not |
| 672 | - * 802.11a ST */ |
| 673 | - if (as->as_required_mode && |
| 674 | - IEEE80211_IS_CHAN_STURBO(c->chan) && |
| 675 | - (as->as_vap_desired_mode != IEEE80211_MODE_TURBO_STATIC_A)) |
| 676 | - continue; |
| 677 | - |
| 678 | - /* Verify mode matches any fixed mode specified */ |
| 679 | - if((c->chan->ic_flags & as->as_required_mode) != |
| 680 | - as->as_required_mode) |
| 681 | - continue; |
| 682 | - |
| 683 | if ((ic->ic_bsschan != NULL) && |
| 684 | (ic->ic_bsschan != IEEE80211_CHAN_ANYC)) { |
| 685 | |
| 686 | --- a/net80211/ieee80211_scan.c |
| 687 | +++ b/net80211/ieee80211_scan.c |
| 688 | @@ -958,6 +958,80 @@ ieee80211_scan_flush(struct ieee80211com |
| 689 | } |
| 690 | } |
| 691 | |
| 692 | +static const u_int chanflags[] = { |
| 693 | + 0, /* IEEE80211_MODE_AUTO */ |
| 694 | + IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ |
| 695 | + IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ |
| 696 | + IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ |
| 697 | + IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ |
| 698 | + IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ |
| 699 | + IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ |
| 700 | + IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ |
| 701 | +}; |
| 702 | + |
| 703 | +static struct ieee80211_channel * |
| 704 | +find11gchannel(struct ieee80211com *ic, int i, int freq) |
| 705 | +{ |
| 706 | + struct ieee80211_channel *c; |
| 707 | + int j; |
| 708 | + |
| 709 | + /* |
| 710 | + * The normal ordering in the channel list is b channel |
| 711 | + * immediately followed by g so optimize the search for |
| 712 | + * this. We'll still do a full search just in case. |
| 713 | + */ |
| 714 | + for (j = i+1; j < ic->ic_nchans; j++) { |
| 715 | + c = &ic->ic_channels[j]; |
| 716 | + if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) |
| 717 | + return c; |
| 718 | + } |
| 719 | + for (j = 0; j < i; j++) { |
| 720 | + c = &ic->ic_channels[j]; |
| 721 | + if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) |
| 722 | + return c; |
| 723 | + } |
| 724 | + return NULL; |
| 725 | +} |
| 726 | + |
| 727 | + |
| 728 | +void |
| 729 | +ieee80211_scan_add_channels(struct ieee80211com *ic, |
| 730 | + struct ieee80211_scan_state *ss, |
| 731 | + enum ieee80211_phymode mode) |
| 732 | +{ |
| 733 | + struct ieee80211_channel *c, *cg; |
| 734 | + u_int modeflags; |
| 735 | + int i; |
| 736 | + |
| 737 | + KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); |
| 738 | + modeflags = chanflags[mode]; |
| 739 | + for (i = 0; i < ic->ic_nchans; i++) { |
| 740 | + c = &ic->ic_channels[i]; |
| 741 | + if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) |
| 742 | + continue; |
| 743 | + if (c->ic_scanflags & IEEE80211_NOSCAN_SET) |
| 744 | + continue; |
| 745 | + if (modeflags && |
| 746 | + ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) != |
| 747 | + (modeflags & IEEE80211_CHAN_ALLTURBO))) |
| 748 | + continue; |
| 749 | + if (mode == IEEE80211_MODE_AUTO) { |
| 750 | + /* |
| 751 | + * XXX special-case 11b/g channels so we select |
| 752 | + * the g channel if both are present. |
| 753 | + */ |
| 754 | + if (IEEE80211_IS_CHAN_B(c) && |
| 755 | + (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) |
| 756 | + continue; |
| 757 | + } |
| 758 | + if (ss->ss_last >= IEEE80211_SCAN_MAX) |
| 759 | + break; |
| 760 | + ss->ss_chans[ss->ss_last++] = c; |
| 761 | + } |
| 762 | +} |
| 763 | +EXPORT_SYMBOL(ieee80211_scan_add_channels); |
| 764 | + |
| 765 | + |
| 766 | /* |
| 767 | * Execute radar channel change. This is called when a radar/dfs |
| 768 | * signal is detected. AP mode only. Return 1 on success, 0 on |
| 769 | --- a/net80211/ieee80211_scan.h |
| 770 | +++ b/net80211/ieee80211_scan.h |
| 771 | @@ -219,4 +219,7 @@ void ieee80211_scanner_register(enum iee |
| 772 | void ieee80211_scanner_unregister(enum ieee80211_opmode, |
| 773 | const struct ieee80211_scanner *); |
| 774 | void ieee80211_scanner_unregister_all(const struct ieee80211_scanner *); |
| 775 | +void ieee80211_scan_add_channels(struct ieee80211com *ic, |
| 776 | + struct ieee80211_scan_state *ss, |
| 777 | + enum ieee80211_phymode mode); |
| 778 | #endif /* _NET80211_IEEE80211_SCAN_H_ */ |
| 779 | --- a/net80211/ieee80211_wireless.c |
| 780 | +++ b/net80211/ieee80211_wireless.c |
| 781 | @@ -3873,6 +3873,106 @@ ieee80211_ioctl_kickmac(struct net_devic |
| 782 | return ieee80211_ioctl_setmlme(dev, info, w, (char *)&mlme); |
| 783 | } |
| 784 | |
| 785 | +static inline void setflag(struct ieee80211_channel *c, int flag) |
| 786 | +{ |
| 787 | + if (flag) |
| 788 | + c->ic_scanflags |= IEEE80211_NOSCAN_SET; |
| 789 | + else |
| 790 | + c->ic_scanflags &= ~IEEE80211_NOSCAN_SET; |
| 791 | +} |
| 792 | + |
| 793 | +static void setscanflag(struct ieee80211com *ic, int min, int max, int set) |
| 794 | +{ |
| 795 | + int i; |
| 796 | + |
| 797 | + for (i = 0; i < ic->ic_nchans; i++) { |
| 798 | + struct ieee80211_channel *c = &ic->ic_channels[i]; |
| 799 | + |
| 800 | + if (min == -1) { |
| 801 | + if (!(c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT)) |
| 802 | + setflag(c, set); |
| 803 | + } else if ((c->ic_freq >= min) && (c->ic_freq <= max)) { |
| 804 | + setflag(c, set); |
| 805 | + } |
| 806 | + } |
| 807 | +} |
| 808 | + |
| 809 | +static int |
| 810 | +ieee80211_ioctl_setscanlist(struct net_device *dev, |
| 811 | + struct iw_request_info *info, |
| 812 | + struct iw_point *data, char *extra) |
| 813 | +{ |
| 814 | + struct ieee80211vap *vap = dev->priv; |
| 815 | + struct ieee80211com *ic = vap->iv_ic; |
| 816 | + char *s, *next; |
| 817 | + int val = 1; |
| 818 | + |
| 819 | + if (data->length <= 0) |
| 820 | + return -EINVAL; |
| 821 | + |
| 822 | + s = kmalloc(data->length + 1, GFP_KERNEL); |
| 823 | + if (!s) |
| 824 | + return -ENOMEM; |
| 825 | + |
| 826 | + memset(s, 0, data->length + 1); |
| 827 | + if (copy_from_user(s, data->pointer, data->length)) |
| 828 | + return -EFAULT; |
| 829 | + |
| 830 | + s[data->length - 1] = '\0'; /* ensure null termination */ |
| 831 | + |
| 832 | + switch(*s) { |
| 833 | + case '-': |
| 834 | + val = 1; |
| 835 | + break; |
| 836 | + case '+': |
| 837 | + val = 0; |
| 838 | + break; |
| 839 | + default: |
| 840 | + goto error; |
| 841 | + } |
| 842 | + s++; |
| 843 | + next = s; |
| 844 | + do { |
| 845 | + next = strchr(s, ','); |
| 846 | + if (next) { |
| 847 | + *next = 0; |
| 848 | + next++; |
| 849 | + } |
| 850 | + if (!strcmp(s, "ALL")) { |
| 851 | + setscanflag(ic, 0, 10000, val); |
| 852 | + } else if (!strcmp(s, "REG")) { |
| 853 | + setscanflag(ic, -1, -1, val); |
| 854 | + } else { |
| 855 | + int min, max; |
| 856 | + char *n, *end = NULL; |
| 857 | + |
| 858 | + n = strchr(s, '-'); |
| 859 | + if (n) { |
| 860 | + *n = 0; |
| 861 | + n++; |
| 862 | + } |
| 863 | + min = simple_strtoul(s, &end, 10); |
| 864 | + if (end && *end) |
| 865 | + goto error; |
| 866 | + if (n) { |
| 867 | + max = simple_strtoul(n, &end, 10); |
| 868 | + if (end && *end) |
| 869 | + goto error; |
| 870 | + } else { |
| 871 | + max = min; |
| 872 | + } |
| 873 | + setscanflag(ic, min, max, val); |
| 874 | + } |
| 875 | + s = next; |
| 876 | + } while (next); |
| 877 | + return 0; |
| 878 | + |
| 879 | +error: |
| 880 | + if (s) |
| 881 | + kfree(s); |
| 882 | + return -EINVAL; |
| 883 | +} |
| 884 | + |
| 885 | static int |
| 886 | ieee80211_ioctl_addmac(struct net_device *dev, struct iw_request_info *info, |
| 887 | void *w, char *extra) |
| 888 | @@ -5656,6 +5756,8 @@ static const struct iw_priv_args ieee802 |
| 889 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"}, |
| 890 | {IEEE80211_PARAM_MINRATE, |
| 891 | 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"}, |
| 892 | + { IEEE80211_IOCTL_SETSCANLIST, |
| 893 | + IW_PRIV_TYPE_CHAR | 255, 0, "setscanlist"}, |
| 894 | |
| 895 | #ifdef ATH_REVERSE_ENGINEERING |
| 896 | /* |
| 897 | @@ -5753,6 +5855,7 @@ static const iw_handler ieee80211_priv_h |
| 898 | set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac), |
| 899 | set_priv(IEEE80211_IOCTL_WDSDELMAC, ieee80211_ioctl_wdsdelmac), |
| 900 | set_priv(IEEE80211_IOCTL_KICKMAC, ieee80211_ioctl_kickmac), |
| 901 | + set_priv(IEEE80211_IOCTL_SETSCANLIST, ieee80211_ioctl_setscanlist), |
| 902 | #ifdef ATH_REVERSE_ENGINEERING |
| 903 | set_priv(IEEE80211_IOCTL_READREG, ieee80211_ioctl_readreg), |
| 904 | set_priv(IEEE80211_IOCTL_WRITEREG, ieee80211_ioctl_writereg), |
| 905 | |