move a few unmaintained packages from trunk to /packages
[openwrt/openwrt.git] / package / madwifi / patches / 411-autochannel_multi.patch
diff --git a/package/madwifi/patches/411-autochannel_multi.patch b/package/madwifi/patches/411-autochannel_multi.patch
deleted file mode 100644 (file)
index d05c447..0000000
+++ /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. */