diff options
Diffstat (limited to 'package/madwifi/patches/411-autochannel_multi.patch')
-rw-r--r-- | package/madwifi/patches/411-autochannel_multi.patch | 347 |
1 files changed, 0 insertions, 347 deletions
diff --git a/package/madwifi/patches/411-autochannel_multi.patch b/package/madwifi/patches/411-autochannel_multi.patch deleted file mode 100644 index d05c447f7b..0000000000 --- a/package/madwifi/patches/411-autochannel_multi.patch +++ /dev/null @@ -1,347 +0,0 @@ ---- a/net80211/ieee80211_scan.c -+++ b/net80211/ieee80211_scan.c -@@ -97,6 +97,123 @@ struct scan_state { - static void scan_restart_pwrsav(unsigned long); - static void scan_next(unsigned long); - -+spinlock_t channel_lock = SPIN_LOCK_UNLOCKED; -+static LIST_HEAD(channels_inuse); -+ -+struct channel_inuse { -+ struct list_head list; -+ struct ieee80211com *ic; -+ u16 freq; -+ u8 bw; -+}; -+ -+static inline u32 -+get_signal(u8 bw, u8 distance) -+{ -+ u32 v; -+ -+ /* signal = 1 - (distance / bw)^2 [scale: 100] */ -+ v = 100 * distance / bw; -+ v = (100 - ((v * v) / 100)); -+ return v; -+} -+ -+static u32 -+get_overlap(u16 f1, u16 f2, u8 b1, u8 b2) -+{ -+ u32 v; -+ u16 d, c; -+ -+ /* add offsets for sidechannel interference */ -+ b1 += (b1 / 5); -+ b2 += (b2 / 5); -+ -+ /* use only one direction */ -+ b1 /= 2; -+ b2 /= 2; -+ -+ if (f1 + b1 < f2 - b2) -+ return 0; -+ -+ d = f2 - f1; -+ c = d * b1 / (b1 + b2); -+ v = get_signal(b1, c); -+ -+ return v * v / 100; -+} -+ -+static u8 -+get_channel_bw(struct ieee80211_channel *c) -+{ -+ switch(c->ic_flags & ( -+ IEEE80211_CHAN_HALF | -+ IEEE80211_CHAN_QUARTER | -+ IEEE80211_CHAN_TURBO | -+ IEEE80211_CHAN_STURBO)) { -+ case IEEE80211_CHAN_QUARTER: -+ return 5; -+ case IEEE80211_CHAN_HALF: -+ return 10; -+ case IEEE80211_CHAN_TURBO: -+ case IEEE80211_CHAN_STURBO: -+ return 40; -+ default: -+ return 20; -+ } -+} -+ -+/* must be called with channel_lock held */ -+u32 -+ieee80211_scan_get_bias(struct ieee80211_channel *c) -+{ -+ struct channel_inuse *ch; -+ u8 bw = get_channel_bw(c); -+ u32 bias = 0; -+ -+ list_for_each_entry(ch, &channels_inuse, list) { -+ if (ch->freq == c->ic_freq) { -+ bias += 50; -+ continue; -+ } -+ if (c->ic_freq < ch->freq) -+ bias += get_overlap(c->ic_freq, ch->freq, bw, ch->bw); -+ else -+ bias += get_overlap(ch->freq, c->ic_freq, ch->bw, bw); -+ } -+ return bias; -+} -+EXPORT_SYMBOL(ieee80211_scan_get_bias); -+ -+/* must be called with channel_lock held */ -+void -+ieee80211_scan_set_bss_channel(struct ieee80211com *ic, struct ieee80211_channel *c) -+{ -+ unsigned long flags; -+ struct channel_inuse *ch; -+ -+ list_for_each_entry(ch, &channels_inuse, list) { -+ if (ch->ic == ic) -+ goto found; -+ } -+ ch = NULL; -+found: -+ if (c && (c != IEEE80211_CHAN_ANYC)) { -+ if (!ch) { -+ ch = kmalloc(sizeof(struct channel_inuse), GFP_ATOMIC); -+ ch->ic = ic; -+ INIT_LIST_HEAD(&ch->list); -+ list_add(&ch->list, &channels_inuse); -+ } -+ ch->freq = c->ic_freq; -+ ch->bw = get_channel_bw(c); -+ } else if (ch) { -+ list_del(&ch->list); -+ kfree(ch); -+ } -+} -+EXPORT_SYMBOL(ieee80211_scan_set_bss_channel); -+ -+ - void - ieee80211_scan_attach(struct ieee80211com *ic) - { -@@ -1169,7 +1286,7 @@ ieee80211_scan_dfs_action(struct ieee802 - IEEE80211_RADAR_CHANCHANGE_TBTT_COUNT; - ic->ic_flags |= IEEE80211_F_CHANSWITCH; - } else { -- -+ unsigned long flags; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH, - "%s: directly switching to channel " - "%3d (%4d MHz)\n", __func__, -@@ -1180,6 +1297,9 @@ ieee80211_scan_dfs_action(struct ieee802 - * change the channel here. */ - change_channel(ic, new_channel); - ic->ic_bsschan = new_channel; -+ spin_lock_irqsave(&channel_lock, flags); -+ ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan); -+ spin_unlock_irqrestore(&channel_lock, flags); - if (vap->iv_bss) - vap->iv_bss->ni_chan = new_channel; - } ---- a/net80211/ieee80211_scan.h -+++ b/net80211/ieee80211_scan.h -@@ -35,6 +35,7 @@ - - #define IEEE80211_SCAN_MAX IEEE80211_CHAN_MAX - -+extern spinlock_t channel_lock; - struct ieee80211_scanner; - struct ieee80211_scan_entry; - -@@ -116,6 +117,8 @@ void ieee80211_scan_flush(struct ieee802 - struct ieee80211_scan_entry; - typedef int ieee80211_scan_iter_func(void *, const struct ieee80211_scan_entry *); - int ieee80211_scan_iterate(struct ieee80211com *, ieee80211_scan_iter_func *, void *); -+u32 ieee80211_scan_get_bias(struct ieee80211_channel *c); -+void ieee80211_scan_set_bss_channel(struct ieee80211com *ic, struct ieee80211_channel *c); - - /* - * Parameters supplied when adding/updating an entry in a ---- a/net80211/ieee80211.c -+++ b/net80211/ieee80211.c -@@ -373,8 +373,16 @@ void - ieee80211_ifdetach(struct ieee80211com *ic) - { - struct ieee80211vap *vap; -+ unsigned long flags; - int count; - -+ /* mark the channel as no longer in use */ -+ ic->ic_bsschan = IEEE80211_CHAN_ANYC; -+ spin_lock_irqsave(&channel_lock, flags); -+ ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan); -+ spin_unlock_irqrestore(&channel_lock, flags); -+ -+ - /* bring down all vaps */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - ieee80211_stop(vap->iv_dev); ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -2775,6 +2775,7 @@ static void - ieee80211_doth_switch_channel(struct ieee80211vap *vap) - { - struct ieee80211com *ic = vap->iv_ic; -+ unsigned long flags; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH, - "%s: Channel switch to %3d (%4d MHz) NOW!\n", -@@ -2797,6 +2798,9 @@ ieee80211_doth_switch_channel(struct iee - - ic->ic_curchan = ic->ic_bsschan = vap->iv_csa_chan; - ic->ic_set_channel(ic); -+ spin_lock_irqsave(&channel_lock, flags); -+ ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan); -+ spin_unlock_irqrestore(&channel_lock, flags); - } - - static void ---- a/net80211/ieee80211_node.c -+++ b/net80211/ieee80211_node.c -@@ -308,6 +308,7 @@ ieee80211_create_ibss(struct ieee80211va - { - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; -+ unsigned long flags; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: creating ibss on channel %u\n", __func__, -@@ -386,6 +387,9 @@ ieee80211_create_ibss(struct ieee80211va - ic->ic_bsschan = chan; - ieee80211_node_set_chan(ic, ni); - ic->ic_curmode = ieee80211_chan2mode(chan); -+ spin_lock_irqsave(&channel_lock, flags); -+ ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan); -+ spin_unlock_irqrestore(&channel_lock, flags); - - /* Update country ie information */ - ieee80211_build_countryie(ic); -@@ -622,6 +626,7 @@ ieee80211_sta_join1(struct ieee80211_nod - struct ieee80211vap *vap = selbs->ni_vap; - struct ieee80211com *ic = selbs->ni_ic; - struct ieee80211_node *obss; -+ unsigned long flags; - int canreassoc; - - if (vap->iv_opmode == IEEE80211_M_IBSS) { -@@ -650,6 +655,9 @@ ieee80211_sta_join1(struct ieee80211_nod - ic->ic_curchan = ic->ic_bsschan; - ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan); - ic->ic_set_channel(ic); -+ spin_lock_irqsave(&channel_lock, flags); -+ ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan); -+ spin_unlock_irqrestore(&channel_lock, flags); - /* - * Set the erp state (mostly the slot time) to deal with - * the auto-select case; this should be redundant if the ---- a/net80211/ieee80211_proto.c -+++ b/net80211/ieee80211_proto.c -@@ -1231,6 +1231,7 @@ ieee80211_dturbo_switch(struct ieee80211 - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - #endif - struct ieee80211_channel *chan; -+ unsigned long flags; - - chan = ieee80211_find_channel(ic, ic->ic_bsschan->ic_freq, newflags); - if (chan == NULL) { /* XXX should not happen */ -@@ -1249,6 +1250,9 @@ ieee80211_dturbo_switch(struct ieee80211 - ic->ic_bsschan = chan; - ic->ic_curchan = chan; - ic->ic_set_channel(ic); -+ spin_lock_irqsave(&channel_lock, flags); -+ ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan); -+ spin_unlock_irqrestore(&channel_lock, flags); - /* NB: do not need to reset ERP state because in sta mode */ - } - EXPORT_SYMBOL(ieee80211_dturbo_switch); ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -4076,8 +4076,13 @@ ieee80211_ioctl_setchanlist(struct net_d - if (nchan == 0) /* no valid channels, disallow */ - return -EINVAL; - if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */ -- isclr(chanlist, ic->ic_bsschan->ic_ieee)) -+ isclr(chanlist, ic->ic_bsschan->ic_ieee)) { -+ unsigned long flags; - ic->ic_bsschan = IEEE80211_CHAN_ANYC; /* invalidate */ -+ spin_lock_irqsave(&channel_lock, flags); -+ ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan); -+ spin_unlock_irqrestore(&channel_lock, flags); -+ } - - memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active)); - /* update Supported Channels information element */ ---- a/net80211/ieee80211_scan_ap.c -+++ b/net80211/ieee80211_scan_ap.c -@@ -208,9 +208,15 @@ ap_start(struct ieee80211_scan_state *ss - struct ieee80211com *ic = NULL; - int i; - unsigned int mode = 0; -+ unsigned long sflags; - - SCAN_AP_LOCK_IRQ(as); - ic = vap->iv_ic; -+ -+ spin_lock_irqsave(&channel_lock, sflags); -+ ieee80211_scan_set_bss_channel(ic, NULL); -+ spin_unlock_irqrestore(&channel_lock, sflags); -+ - /* Determine mode flags to match, or leave zero for auto mode */ - ss->ss_last = 0; - ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); -@@ -423,8 +429,10 @@ pc_cmp_idletime(struct ieee80211_channel - if (!a->ic_idletime || !b->ic_idletime) - return 0; - -- /* a is better than b (return < 0) when a has more idle time than b */ -- return b->ic_idletime - a->ic_idletime; -+ /* a is better than b (return < 0) when a has more idle and less bias time than b */ -+ return -+ ((100 - (u32) a->ic_idletime) + ieee80211_scan_get_bias(a)) - -+ ((100 - (u32) b->ic_idletime) + ieee80211_scan_get_bias(b)); - } - - -@@ -575,6 +583,7 @@ ap_end(struct ieee80211_scan_state *ss, - struct ap_state *as = ss->ss_priv; - struct ieee80211_channel *bestchan = NULL; - struct ieee80211com *ic = NULL; -+ unsigned long sflags; - int res = 1; - - SCAN_AP_LOCK_IRQ(as); -@@ -586,8 +595,11 @@ ap_end(struct ieee80211_scan_state *ss, - - /* record stats for the channel that was scanned last */ - ic->ic_set_channel(ic); -+ spin_lock_irqsave(&channel_lock, sflags); -+ ieee80211_scan_set_bss_channel(ic, NULL); - bestchan = pick_channel(ss, vap, flags); - if (bestchan == NULL) { -+ spin_unlock_irqrestore(&channel_lock, sflags); - if (ss->ss_last > 0) { - /* no suitable channel, should not happen */ - printk(KERN_ERR "%s: %s: no suitable channel! " -@@ -606,6 +618,7 @@ ap_end(struct ieee80211_scan_state *ss, - bestchan->ic_freq, bestchan->ic_flags & - ~IEEE80211_CHAN_TURBO)) == NULL) { - /* should never happen ?? */ -+ spin_unlock_irqrestore(&channel_lock, sflags); - SCAN_AP_UNLOCK_IRQ_EARLY(as); - return 0; - } -@@ -618,6 +631,9 @@ ap_end(struct ieee80211_scan_state *ss, - as->as_action = action; - as->as_selbss = se; - -+ ieee80211_scan_set_bss_channel(ic, bestchan); -+ spin_unlock_irqrestore(&channel_lock, sflags); -+ - /* Must defer action to avoid possible recursive call through - * 80211 state machine, which would result in recursive - * locking. */ |