diff options
Diffstat (limited to 'package/madwifi/patches-testing/315-scanlist.patch')
-rw-r--r-- | package/madwifi/patches-testing/315-scanlist.patch | 876 |
1 files changed, 0 insertions, 876 deletions
diff --git a/package/madwifi/patches-testing/315-scanlist.patch b/package/madwifi/patches-testing/315-scanlist.patch deleted file mode 100644 index 0ae0ed010a..0000000000 --- a/package/madwifi/patches-testing/315-scanlist.patch +++ /dev/null @@ -1,876 +0,0 @@ ---- a/net80211/ieee80211_scan_sta.c -+++ b/net80211/ieee80211_scan_sta.c -@@ -318,147 +318,6 @@ - #undef ISPROBE - } - --static struct ieee80211_channel * --find11gchannel(struct ieee80211com *ic, int i, int freq) --{ -- struct ieee80211_channel *c; -- int j; -- -- /* -- * The normal ordering in the channel list is b channel -- * immediately followed by g so optimize the search for -- * this. We'll still do a full search just in case. -- */ -- for (j = i+1; j < ic->ic_nchans; j++) { -- c = &ic->ic_channels[j]; -- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) -- return c; -- } -- for (j = 0; j < i; j++) { -- c = &ic->ic_channels[j]; -- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) -- return c; -- } -- return NULL; --} --static const u_int chanflags[] = { -- IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ -- IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ -- IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ -- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ -- IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ -- IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ -- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ -- IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ --}; -- --static void --add_channels(struct ieee80211com *ic, -- struct ieee80211_scan_state *ss, -- enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) --{ -- struct ieee80211_channel *c, *cg; -- u_int modeflags; -- int i; -- -- KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); -- modeflags = chanflags[mode]; -- for (i = 0; i < nfreq; i++) { -- c = ieee80211_find_channel(ic, freq[i], modeflags); -- if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) -- continue; -- if (mode == IEEE80211_MODE_AUTO) { -- /* -- * XXX special-case 11b/g channels so we select -- * the g channel if both are present. -- */ -- if (IEEE80211_IS_CHAN_B(c) && -- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) -- c = cg; -- } -- if (ss->ss_last >= IEEE80211_SCAN_MAX) -- break; -- ss->ss_chans[ss->ss_last++] = c; -- } --} -- --static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */ --{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; --static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ --{ 5170, 5190, 5210, 5230 }; --static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ --{ 2412, 2437, 2462, 2442, 2472 }; --static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ --{ 5745, 5765, 5785, 5805, 5825 }; --static const u_int16_t rcl7[] = /* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */ --{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; --static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ --{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; --static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ --{ 2484 }; --static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ --{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; --static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ --{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; --#ifdef ATH_TURBO_SCAN --static const u_int16_t rcl5[] = /* 3 static turbo channels */ --{ 5210, 5250, 5290 }; --static const u_int16_t rcl6[] = /* 2 static turbo channels */ --{ 5760, 5800 }; --static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ --{ 5540, 5580, 5620, 5660 }; --static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ --{ 2437 }; --static const u_int16_t rcl13[] = /* dynamic Turbo channels */ --{ 5200, 5240, 5280, 5765, 5805 }; --#endif /* ATH_TURBO_SCAN */ -- --struct scanlist { -- u_int16_t mode; -- u_int16_t count; -- const u_int16_t *list; --}; -- --#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX --#define X(a) .count = sizeof(a)/sizeof(a[0]), .list = a -- --static const struct scanlist staScanTable[] = { -- { IEEE80211_MODE_11B, X(rcl3) }, -- { IEEE80211_MODE_11A, X(rcl1) }, -- { IEEE80211_MODE_11A, X(rcl2) }, -- { IEEE80211_MODE_11B, X(rcl8) }, -- { IEEE80211_MODE_11B, X(rcl9) }, -- { IEEE80211_MODE_11A, X(rcl4) }, --#ifdef ATH_TURBO_SCAN -- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, -- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, -- { IEEE80211_MODE_TURBO_A, X(rcl6x) }, -- { IEEE80211_MODE_TURBO_A, X(rcl13) }, --#endif /* ATH_TURBO_SCAN */ -- { IEEE80211_MODE_11A, X(rcl7) }, -- { IEEE80211_MODE_11B, X(rcl10) }, -- { IEEE80211_MODE_11A, X(rcl11) }, --#ifdef ATH_TURBO_SCAN -- { IEEE80211_MODE_TURBO_G, X(rcl12) }, --#endif /* ATH_TURBO_SCAN */ -- { .list = NULL } --}; -- --#undef X -- --static int --checktable(const struct scanlist *scan, const struct ieee80211_channel *c) --{ -- int i; -- -- for (; scan->list != NULL; scan++) { -- for (i = 0; i < scan->count; i++) -- if (scan->list[i] == c->ic_freq) -- return 1; -- } -- return 0; --} -- - /* - * Start a station-mode scan by populating the channel list. - */ -@@ -467,81 +326,11 @@ - { - struct ieee80211com *ic = vap->iv_ic; - struct sta_table *st = ss->ss_priv; -- const struct scanlist *scan; -- enum ieee80211_phymode mode; -- struct ieee80211_channel *c; -- int i; - - ss->ss_last = 0; -- /* -- * Use the table of ordered channels to construct the list -- * of channels for scanning. Any channels in the ordered -- * list not in the master list will be discarded. -- */ -- for (scan = staScanTable; scan->list != NULL; scan++) { -- mode = scan->mode; -- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { -- /* -- * If a desired mode was specified, scan only -- * channels that satisfy that constraint. -- */ -- if (vap->iv_des_mode != mode) { -- /* -- * The scan table marks 2.4Ghz channels as b -- * so if the desired mode is 11g, then use -- * the 11b channel list but upgrade the mode. -- */ -- if (vap->iv_des_mode != IEEE80211_MODE_11G || -- mode != IEEE80211_MODE_11B) -- continue; -- mode = IEEE80211_MODE_11G; /* upgrade */ -- } -- } else { -- /* -- * This lets ieee80211_scan_add_channels -- * upgrade an 11b channel to 11g if available. -- */ -- if (mode == IEEE80211_MODE_11B) -- mode = IEEE80211_MODE_AUTO; -- } -- /* XR does not operate on turbo channels */ -- if ((vap->iv_flags & IEEE80211_F_XR) && -- (mode == IEEE80211_MODE_TURBO_A || -- mode == IEEE80211_MODE_TURBO_G)) -- continue; -- /* -- * Add the list of the channels; any that are not -- * in the master channel list will be discarded. -- */ -- add_channels(ic, ss, mode, scan->list, scan->count); -- } -- -- /* -- * Add the channels from the ic (from HAL) that are not present -- * in the staScanTable. -- */ -- for (i = 0; i < ic->ic_nchans; i++) { -- c = &ic->ic_channels[i]; -- /* -- * scan dynamic turbo channels in normal mode. -- */ -- if (IEEE80211_IS_CHAN_DTURBO(c)) -- continue; -- mode = ieee80211_chan2mode(c); -- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { -- /* -- * If a desired mode was specified, scan only -- * channels that satisfy that constraint. -- */ -- if (vap->iv_des_mode != mode) -- continue; -- -- } -- if (!checktable(staScanTable, c)) -- ss->ss_chans[ss->ss_last++] = c; -- } -- -+ ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); - ss->ss_next = 0; -+ - /* XXX tunables */ - /* - * The scanner will stay on station for ss_maxdwell ms (using a -@@ -750,17 +539,7 @@ - fail = 0; - if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, se->se_chan))) - fail |= 0x01; -- /* -- * NB: normally the desired mode is used to construct -- * the channel list, but it's possible for the scan -- * cache to include entries for stations outside this -- * list so we check the desired mode here to weed them -- * out. -- */ -- if (vap->iv_des_mode != IEEE80211_MODE_AUTO && -- (se->se_chan->ic_flags & IEEE80211_CHAN_ALLTURBO) != -- chanflags[vap->iv_des_mode]) -- fail |= 0x01; -+ - if (vap->iv_opmode == IEEE80211_M_IBSS) { - if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0) - fail |= 0x02; -@@ -1175,78 +954,6 @@ - .scan_default = ieee80211_sta_join, - }; - --/* -- * Start an adhoc-mode scan by populating the channel list. -- */ --static int --adhoc_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) --{ -- struct ieee80211com *ic = vap->iv_ic; -- struct sta_table *st = ss->ss_priv; -- const struct scanlist *scan; -- enum ieee80211_phymode mode; -- -- ss->ss_last = 0; -- /* -- * Use the table of ordered channels to construct the list -- * of channels for scanning. Any channels in the ordered -- * list not in the master list will be discarded. -- */ -- for (scan = staScanTable; scan->list != NULL; scan++) { -- mode = scan->mode; -- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { -- /* -- * If a desired mode was specified, scan only -- * channels that satisfy that constraint. -- */ -- if (vap->iv_des_mode != mode) { -- /* -- * The scan table marks 2.4Ghz channels as b -- * so if the desired mode is 11g, then use -- * the 11b channel list but upgrade the mode. -- */ -- if (vap->iv_des_mode != IEEE80211_MODE_11G || -- mode != IEEE80211_MODE_11B) -- continue; -- mode = IEEE80211_MODE_11G; /* upgrade */ -- } -- } else { -- /* -- * This lets ieee80211_scan_add_channels -- * upgrade an 11b channel to 11g if available. -- */ -- if (mode == IEEE80211_MODE_11B) -- mode = IEEE80211_MODE_AUTO; -- } -- /* XR does not operate on turbo channels */ -- if ((vap->iv_flags & IEEE80211_F_XR) && -- (mode == IEEE80211_MODE_TURBO_A || -- mode == IEEE80211_MODE_TURBO_G)) -- continue; -- /* -- * Add the list of the channels; any that are not -- * in the master channel list will be discarded. -- */ -- add_channels(ic, ss, mode, scan->list, scan->count); -- } -- ss->ss_next = 0; -- /* XXX tunables */ -- ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */ -- ss->ss_maxdwell = msecs_to_jiffies(200); /* 200ms */ -- --#ifdef IEEE80211_DEBUG -- if (ieee80211_msg_scan(vap)) { -- printk("%s: scan set ", vap->iv_dev->name); -- ieee80211_scan_dump_channels(ss); -- printk(" dwell min %ld max %ld\n", -- ss->ss_mindwell, ss->ss_maxdwell); -- } --#endif /* IEEE80211_DEBUG */ -- -- st->st_newscan = 1; -- -- return 0; --} - - /* - * Select a channel to start an adhoc network on. -@@ -1412,7 +1119,7 @@ - .scan_name = "default", - .scan_attach = sta_attach, - .scan_detach = sta_detach, -- .scan_start = adhoc_start, -+ .scan_start = sta_start, - .scan_restart = sta_restart, - .scan_cancel = sta_cancel, - .scan_end = adhoc_pick_bss, ---- a/net80211/ieee80211.c -+++ b/net80211/ieee80211.c -@@ -292,6 +292,11 @@ - ("channel with bogus ieee number %u", c->ic_ieee)); - setbit(ic->ic_chan_avail, c->ic_ieee); - -+ if (c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT) -+ c->ic_scanflags |= IEEE80211_NOSCAN_SET; -+ else -+ c->ic_scanflags &= ~IEEE80211_NOSCAN_SET; -+ - /* Identify mode capabilities. */ - if (IEEE80211_IS_CHAN_A(c)) - ic->ic_modecaps |= 1 << IEEE80211_MODE_11A; ---- a/net80211/_ieee80211.h -+++ b/net80211/_ieee80211.h -@@ -132,6 +132,11 @@ - IEEE80211_SCAN_FIRST = 2, /* take first suitable candidate */ - }; - -+enum ieee80211_scanflags { -+ IEEE80211_NOSCAN_DEFAULT = (1 << 0), -+ IEEE80211_NOSCAN_SET = (1 << 1), -+}; -+ - /* - * Channels are specified by frequency and attributes. - */ -@@ -142,6 +147,7 @@ - int8_t ic_maxregpower; /* maximum regulatory tx power in dBm */ - int8_t ic_maxpower; /* maximum tx power in dBm */ - int8_t ic_minpower; /* minimum tx power in dBm */ -+ u_int8_t ic_scanflags; - }; - - #define IEEE80211_CHAN_MAX 255 ---- a/net80211/ieee80211_ioctl.h -+++ b/net80211/ieee80211_ioctl.h -@@ -556,6 +556,7 @@ - #define IEEE80211_IOCTL_WDSADDMAC (SIOCIWFIRSTPRIV+26) - #define IEEE80211_IOCTL_WDSDELMAC (SIOCIWFIRSTPRIV+28) - #define IEEE80211_IOCTL_KICKMAC (SIOCIWFIRSTPRIV+30) -+#define IEEE80211_IOCTL_SETSCANLIST (SIOCIWFIRSTPRIV+31) - - enum { - IEEE80211_WMMPARAMS_CWMIN = 1, ---- a/net80211/ieee80211_scan_ap.c -+++ b/net80211/ieee80211_scan_ap.c -@@ -200,131 +200,7 @@ - - static int ap_flush(struct ieee80211_scan_state *); - static void action_tasklet(IEEE80211_TQUEUE_ARG); --static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic, -- int i, int freq); - --static const u_int chanflags[] = { -- IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ -- IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ -- IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ -- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ -- IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ -- IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode -- * look for AP in -- * normal channel -- */ -- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ -- IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ --}; -- --static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, -- * 36, 40, 44, 48 */ --{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; --static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ --{ 5170, 5190, 5210, 5230 }; --static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ --{ 2412, 2437, 2462, 2442, 2472 }; --static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ --{ 5745, 5765, 5785, 5805, 5825 }; --static const u_int16_t rcl7[] = /* 11 ETSI channel: 100, 104, 108, 112, -- * 116, 120, 124, 128, -- * 132, 136, 140 */ --{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; --static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ --{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; --static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ --{ 2484 }; --static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ --{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; --static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ --{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; --#ifdef ATH_TURBO_SCAN --static const u_int16_t rcl5[] = /* 3 static turbo channels */ --{ 5210, 5250, 5290 }; --static const u_int16_t rcl6[] = /* 2 static turbo channels */ --{ 5760, 5800 }; --static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ --{ 5540, 5580, 5620, 5660 }; --static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ --{ 2437 }; --static const u_int16_t rcl13[] = /* dynamic Turbo channels */ --{ 5200, 5240, 5280, 5765, 5805 }; --#endif /* ATH_TURBO_SCAN */ -- --struct scanlist { -- u_int16_t mode; -- u_int16_t count; -- const u_int16_t *list; --}; -- --#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX --#define X(a) .count = ARRAY_SIZE(a), .list = a -- --static const struct scanlist staScanTable[] = { -- { IEEE80211_MODE_11B, X(rcl3) }, -- { IEEE80211_MODE_11A, X(rcl1) }, -- { IEEE80211_MODE_11A, X(rcl2) }, -- { IEEE80211_MODE_11B, X(rcl8) }, -- { IEEE80211_MODE_11B, X(rcl9) }, -- { IEEE80211_MODE_11A, X(rcl4) }, --#ifdef ATH_TURBO_SCAN -- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, -- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, -- { IEEE80211_MODE_TURBO_A, X(rcl6x) }, -- { IEEE80211_MODE_TURBO_A, X(rcl13) }, --#endif /* ATH_TURBO_SCAN */ -- { IEEE80211_MODE_11A, X(rcl7) }, -- { IEEE80211_MODE_11B, X(rcl10) }, -- { IEEE80211_MODE_11A, X(rcl11) }, --#ifdef ATH_TURBO_SCAN -- { IEEE80211_MODE_TURBO_G, X(rcl12) }, --#endif /* ATH_TURBO_SCAN */ -- { .list = NULL } --}; -- --#undef X --/* This function must be invoked with locks acquired */ --static void --add_channels(struct ieee80211com *ic, -- struct ieee80211_scan_state *ss, -- enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) --{ -- struct ieee80211_channel *c, *cg; -- u_int modeflags; -- int i; -- -- KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); -- modeflags = chanflags[mode]; -- for (i = 0; i < nfreq; i++) { -- c = ieee80211_find_channel(ic, freq[i], modeflags); -- if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee)) -- continue; -- if (mode == IEEE80211_MODE_AUTO) { -- /* XXX special-case 11b/g channels so we select -- * the g channel if both are present. */ -- if (IEEE80211_IS_CHAN_B(c) && -- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) -- c = cg; -- } -- if (ss->ss_last >= IEEE80211_SCAN_MAX) -- break; -- ss->ss_chans[ss->ss_last++] = c; -- } --} -- --/* This function must be invoked with locks acquired */ --static int --checktable(const struct scanlist *scan, const struct ieee80211_channel *c) --{ -- int i; -- -- for (; scan->list != NULL; scan++) { -- for (i = 0; i < scan->count; i++) -- if (scan->list[i] == c->ic_freq) -- return 1; -- } -- return 0; --} - - /* - * Attach prior to any scanning work. -@@ -398,29 +274,6 @@ - ieee80211_saveie(iep, ie); - } - --/* This function must be invoked with locks acquired */ --static struct ieee80211_channel * --find11gchannel(struct ieee80211com *ic, int i, int freq) --{ -- struct ieee80211_channel *c; -- int j; -- -- /* The normal ordering in the channel list is b channel -- * immediately followed by g so optimize the search for -- * this. We'll still do a full search just in case. */ -- for (j = i + 1; j < ic->ic_nchans; j++) { -- c = &ic->ic_channels[j]; -- if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c)) -- return c; -- } -- for (j = 0; j < i; j++) { -- c = &ic->ic_channels[j]; -- if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c)) -- return c; -- } -- return NULL; --} -- - /* - * Start an ap scan by populating the channel list. - */ -@@ -429,90 +282,14 @@ - { - struct ap_state *as = ss->ss_priv; - struct ieee80211com *ic = NULL; -- const struct scanlist *sl = NULL; -- struct ieee80211_channel *c = NULL; -- int i; -- unsigned int mode = 0; - - SCAN_AP_LOCK_IRQ(as); - ic = vap->iv_ic; - /* Determine mode flags to match, or leave zero for auto mode */ - as->as_vap_desired_mode = vap->iv_des_mode; - as->as_required_mode = 0; -- if (as->as_vap_desired_mode != IEEE80211_MODE_AUTO) { -- as->as_required_mode = chanflags[as->as_vap_desired_mode]; -- if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) && -- (as->as_required_mode != IEEE80211_CHAN_ST)) { -- /* Fixup for dynamic turbo flags */ -- if (as->as_vap_desired_mode == IEEE80211_MODE_11G) -- as->as_required_mode = IEEE80211_CHAN_108G; -- else -- as->as_required_mode = IEEE80211_CHAN_108A; -- } -- } -- -- ss->ss_last = 0; -- /* Use the table of ordered channels to construct the list -- * of channels for scanning. Any channels in the ordered -- * list not in the master list will be discarded. */ -- for (sl = staScanTable; sl->list != NULL; sl++) { -- mode = sl->mode; -- -- /* The scan table marks 2.4Ghz channels as b -- * so if the desired mode is 11g, then use -- * the 11b channel list but upgrade the mode. */ -- if (as->as_vap_desired_mode && -- (as->as_vap_desired_mode != mode) && -- (as->as_vap_desired_mode == IEEE80211_MODE_11G) && -- (mode == IEEE80211_MODE_11B)) -- mode = IEEE80211_MODE_11G; -- -- /* If we are in "AUTO" mode, upgrade the mode to auto. -- * This lets add_channels upgrade an 11b channel to -- * 11g if available. */ -- if (!as->as_vap_desired_mode && (mode == IEEE80211_MODE_11B)) -- mode = IEEE80211_MODE_AUTO; -- -- /* Add the list of the channels; any that are not -- * in the master channel list will be discarded. */ -- add_channels(ic, ss, mode, sl->list, sl->count); -- } -- -- /* Add the channels from the ic (from HAL) that are not present -- * in the staScanTable, assuming they pass the sanity checks... */ -- for (i = 0; i < ic->ic_nchans; i++) { -- c = &ic->ic_channels[i]; -- -- /* XR is not supported on turbo channels */ -- if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR) -- continue; -+ ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); - -- /* Dynamic channels are scanned in base mode */ -- if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c)) -- continue; -- -- /* Use any 11g channel instead of 11b one. */ -- if (vap->iv_des_mode == IEEE80211_MODE_AUTO && -- IEEE80211_IS_CHAN_B(c) && -- find11gchannel(ic, i, c->ic_freq)) -- continue; -- -- /* Do not add channels already put into the scan list by the -- * scan table - these have already been filtered by mode -- * and for whether they are in the active channel list. */ -- if (checktable(staScanTable, c)) -- continue; -- -- /* Make sure the channel is active */ -- if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee)) -- continue; -- -- /* Don't overrun */ -- if (ss->ss_last >= IEEE80211_SCAN_MAX) -- break; -- -- ss->ss_chans[ss->ss_last++] = c; -- } - ss->ss_next = 0; - /* XXX tunables */ - ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */ -@@ -831,13 +608,6 @@ - if (IEEE80211_IS_CHAN_RADAR(c->chan)) - continue; - -- /* Do not select 802.11a ST if mode is specified and is not -- * 802.11a ST */ -- if (as->as_required_mode && -- IEEE80211_IS_CHAN_STURBO(c->chan) && -- (as->as_vap_desired_mode != IEEE80211_MODE_TURBO_STATIC_A)) -- continue; -- - /* Verify mode matches any fixed mode specified */ - if ((c->chan->ic_flags & as->as_required_mode) != - as->as_required_mode) ---- a/net80211/ieee80211_scan.c -+++ b/net80211/ieee80211_scan.c -@@ -969,6 +969,80 @@ - } - } - -+static const u_int chanflags[] = { -+ 0, /* IEEE80211_MODE_AUTO */ -+ IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ -+ IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ -+ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ -+ IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ -+ IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ -+ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ -+ IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ -+}; -+ -+static struct ieee80211_channel * -+find11gchannel(struct ieee80211com *ic, int i, int freq) -+{ -+ struct ieee80211_channel *c; -+ int j; -+ -+ /* -+ * The normal ordering in the channel list is b channel -+ * immediately followed by g so optimize the search for -+ * this. We'll still do a full search just in case. -+ */ -+ for (j = i+1; j < ic->ic_nchans; j++) { -+ c = &ic->ic_channels[j]; -+ if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) -+ return c; -+ } -+ for (j = 0; j < i; j++) { -+ c = &ic->ic_channels[j]; -+ if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) -+ return c; -+ } -+ return NULL; -+} -+ -+ -+void -+ieee80211_scan_add_channels(struct ieee80211com *ic, -+ struct ieee80211_scan_state *ss, -+ enum ieee80211_phymode mode) -+{ -+ struct ieee80211_channel *c, *cg; -+ u_int modeflags; -+ int i; -+ -+ KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); -+ modeflags = chanflags[mode]; -+ for (i = 0; i < ic->ic_nchans; i++) { -+ c = &ic->ic_channels[i]; -+ if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) -+ continue; -+ if (c->ic_scanflags & IEEE80211_NOSCAN_SET) -+ continue; -+ if (modeflags && -+ ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) != -+ (modeflags & IEEE80211_CHAN_ALLTURBO))) -+ continue; -+ if (mode == IEEE80211_MODE_AUTO) { -+ /* -+ * XXX special-case 11b/g channels so we select -+ * the g channel if both are present. -+ */ -+ if (IEEE80211_IS_CHAN_B(c) && -+ (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) -+ continue; -+ } -+ if (ss->ss_last >= IEEE80211_SCAN_MAX) -+ break; -+ ss->ss_chans[ss->ss_last++] = c; -+ } -+} -+EXPORT_SYMBOL(ieee80211_scan_add_channels); -+ -+ - /* - * Execute radar channel change. This is called when a radar/dfs - * signal is detected. AP mode only. Return 1 on success, 0 on ---- a/net80211/ieee80211_scan.h -+++ b/net80211/ieee80211_scan.h -@@ -219,4 +219,7 @@ - void ieee80211_scanner_unregister(enum ieee80211_opmode, - const struct ieee80211_scanner *); - void ieee80211_scanner_unregister_all(const struct ieee80211_scanner *); -+void ieee80211_scan_add_channels(struct ieee80211com *ic, -+ struct ieee80211_scan_state *ss, -+ enum ieee80211_phymode mode); - #endif /* _NET80211_IEEE80211_SCAN_H_ */ ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -3911,6 +3911,106 @@ - return ieee80211_ioctl_setmlme(dev, info, w, (char *)&mlme); - } - -+static inline void setflag(struct ieee80211_channel *c, int flag) -+{ -+ if (flag) -+ c->ic_scanflags |= IEEE80211_NOSCAN_SET; -+ else -+ c->ic_scanflags &= ~IEEE80211_NOSCAN_SET; -+} -+ -+static void setscanflag(struct ieee80211com *ic, int min, int max, int set) -+{ -+ int i; -+ -+ for (i = 0; i < ic->ic_nchans; i++) { -+ struct ieee80211_channel *c = &ic->ic_channels[i]; -+ -+ if (min == -1) { -+ if (!(c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT)) -+ setflag(c, set); -+ } else if ((c->ic_freq >= min) && (c->ic_freq <= max)) { -+ setflag(c, set); -+ } -+ } -+} -+ -+static int -+ieee80211_ioctl_setscanlist(struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *data, char *extra) -+{ -+ struct ieee80211vap *vap = dev->priv; -+ struct ieee80211com *ic = vap->iv_ic; -+ char *s, *next; -+ int val = 1; -+ -+ if (data->length <= 0) -+ return -EINVAL; -+ -+ s = kmalloc(data->length + 1, GFP_KERNEL); -+ if (!s) -+ return -ENOMEM; -+ -+ memset(s, 0, data->length + 1); -+ if (copy_from_user(s, data->pointer, data->length)) -+ return -EFAULT; -+ -+ s[data->length - 1] = '\0'; /* ensure null termination */ -+ -+ switch(*s) { -+ case '-': -+ val = 1; -+ break; -+ case '+': -+ val = 0; -+ break; -+ default: -+ goto error; -+ } -+ s++; -+ next = s; -+ do { -+ next = strchr(s, ','); -+ if (next) { -+ *next = 0; -+ next++; -+ } -+ if (!strcmp(s, "ALL")) { -+ setscanflag(ic, 0, 10000, val); -+ } else if (!strcmp(s, "REG")) { -+ setscanflag(ic, -1, -1, val); -+ } else { -+ int min, max; -+ char *n, *end = NULL; -+ -+ n = strchr(s, '-'); -+ if (n) { -+ *n = 0; -+ n++; -+ } -+ min = simple_strtoul(s, &end, 10); -+ if (end && *end) -+ goto error; -+ if (n) { -+ max = simple_strtoul(n, &end, 10); -+ if (end && *end) -+ goto error; -+ } else { -+ max = min; -+ } -+ setscanflag(ic, min, max, val); -+ } -+ s = next; -+ } while (next); -+ return 0; -+ -+error: -+ if (s) -+ kfree(s); -+ return -EINVAL; -+} -+ - static int - ieee80211_ioctl_addmac(struct net_device *dev, struct iw_request_info *info, - void *w, char *extra) -@@ -5712,6 +5812,8 @@ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"}, - {IEEE80211_PARAM_MINRATE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"}, -+ { IEEE80211_IOCTL_SETSCANLIST, -+ IW_PRIV_TYPE_CHAR | 255, 0, "setscanlist"}, - - #ifdef ATH_REVERSE_ENGINEERING - /* -@@ -5809,6 +5911,7 @@ - set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac), - set_priv(IEEE80211_IOCTL_WDSDELMAC, ieee80211_ioctl_wdsdelmac), - set_priv(IEEE80211_IOCTL_KICKMAC, ieee80211_ioctl_kickmac), -+ set_priv(IEEE80211_IOCTL_SETSCANLIST, ieee80211_ioctl_setscanlist), - #ifdef ATH_REVERSE_ENGINEERING - set_priv(IEEE80211_IOCTL_READREG, ieee80211_ioctl_readreg), - set_priv(IEEE80211_IOCTL_WRITEREG, ieee80211_ioctl_writereg), |