madwifi: add an optional background scanning threshold triggered by low rssi
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Sat, 12 Jul 2008 22:23:55 +0000 (22:23 +0000)
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Sat, 12 Jul 2008 22:23:55 +0000 (22:23 +0000)
(useful for passing updated scan results to the wpa_supplicant ahead of
time, before losing connectivity entirely)

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@11794 3c298f89-4303-0410-b956-a3cf2f4a3e73

package/madwifi/patches/357-bgscan_thresh.patch [new file with mode: 0644]

diff --git a/package/madwifi/patches/357-bgscan_thresh.patch b/package/madwifi/patches/357-bgscan_thresh.patch
new file mode 100644 (file)
index 0000000..e0d5752
--- /dev/null
@@ -0,0 +1,127 @@
+Add an optional background scanning threshold triggered by low rssi
+(useful for passing updated scan results to the supplicant ahead of
+time, before losing connectivity entirely)
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+
+--- a/net80211/ieee80211_ioctl.h
++++ b/net80211/ieee80211_ioctl.h
+@@ -646,6 +646,7 @@
+       IEEE80211_PARAM_MINRATE                 = 76,   /* Maximum rate (by table index) */
+       IEEE80211_PARAM_PROTMODE_RSSI           = 77,   /* RSSI Threshold for enabling protection mode */
+       IEEE80211_PARAM_PROTMODE_TIMEOUT        = 78,   /* Timeout for expiring protection mode */
++      IEEE80211_PARAM_BGSCAN_THRESH           = 79,   /* bg scan rssi threshold */
+ };
+ #define       SIOCG80211STATS                 (SIOCDEVPRIVATE+2)
+--- a/net80211/ieee80211_var.h
++++ b/net80211/ieee80211_var.h
+@@ -92,6 +92,8 @@
+ #define       IEEE80211_BGSCAN_IDLE_MIN       100     /* min idle time (ms) */
+ #define       IEEE80211_BGSCAN_IDLE_DEFAULT   250     /* default idle time (ms) */
++#define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */
++
+ #define IEEE80211_COVERAGE_CLASS_MAX  31      /* max coverage class */
+ #define IEEE80211_REGCLASSIDS_MAX     10      /* max regclass id list */
+@@ -219,6 +221,9 @@
+       u_int8_t iv_nickname[IEEE80211_NWID_LEN];
+       u_int iv_bgscanidle;                            /* bg scan idle threshold */
+       u_int iv_bgscanintvl;                           /* bg scan min interval */
++      u_int iv_bgscanthr;                                     /* bg scan rssi threshold */
++      u_int iv_bgscantrintvl;                         /* bg scan trigger interval */
++      unsigned long iv_bgscanthr_next;                /* last trigger for bgscan */
+       u_int iv_scanvalid;                             /* scan cache valid threshold */
+       struct ieee80211_roam iv_roam;                  /* sta-mode roaming state */
+@@ -608,6 +613,7 @@
+ #define IEEE80211_FEXT_SWBMISS                0x00000400      /* CONF: use software beacon timer */
+ #define IEEE80211_FEXT_DROPUNENC_EAPOL        0x00000800      /* CONF: drop unencrypted eapol frames */
+ #define IEEE80211_FEXT_APPIE_UPDATE   0x00001000      /* STATE: beacon APP IE updated */
++#define IEEE80211_FEXT_BGSCAN_THR     0x00002000      /* bgscan due to low rssi */
+ #define IEEE80211_COM_UAPSD_ENABLE(_ic)               ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD)
+ #define IEEE80211_COM_UAPSD_DISABLE(_ic)      ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD)
+--- a/net80211/ieee80211_wireless.c
++++ b/net80211/ieee80211_wireless.c
+@@ -2744,6 +2744,9 @@
+               else
+                       retv = EINVAL;
+               break;
++      case IEEE80211_PARAM_BGSCAN_THRESH:
++              vap->iv_bgscanthr = value;
++              break;
+       case IEEE80211_PARAM_MCAST_RATE:
+               /* units are in KILObits per second */
+               if (value >= 256 && value <= 54000)
+@@ -3144,6 +3147,9 @@
+       case IEEE80211_PARAM_BGSCAN_INTERVAL:
+               param[0] = vap->iv_bgscanintvl / HZ;    /* seconds */
+               break;
++      case IEEE80211_PARAM_BGSCAN_THRESH:
++              param[0] = vap->iv_bgscanthr;   /* rssi */
++              break;
+       case IEEE80211_PARAM_MCAST_RATE:
+               param[0] = vap->iv_mcast_rate;  /* seconds */
+               break;
+@@ -5666,6 +5672,10 @@
+         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanintvl" },
+       { IEEE80211_PARAM_BGSCAN_INTERVAL,
+         0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanintvl" },
++      { IEEE80211_PARAM_BGSCAN_THRESH,
++        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanthr" },
++      { IEEE80211_PARAM_BGSCAN_THRESH,
++        0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanthr" },
+       { IEEE80211_PARAM_MCAST_RATE,
+         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcast_rate" },
+       { IEEE80211_PARAM_MCAST_RATE,
+--- a/net80211/ieee80211_input.c
++++ b/net80211/ieee80211_input.c
+@@ -3013,8 +3013,10 @@
+ {
+       struct ieee80211com *ic = vap->iv_ic;
++      vap->iv_bgscantrintvl = (vap->iv_bgscantrintvl + 1) % 4;
+       return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) &&
+-              time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle));
++              (((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && !vap->iv_bgscantrintvl) ||
++                      time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle)));
+ }
+ static __inline int
+@@ -3258,6 +3260,23 @@
+                       /* record tsf of last beacon */
+                       memcpy(ni->ni_tstamp.data, scan.tstamp,
+                               sizeof(ni->ni_tstamp));
++
++                      /* When rssi is low, start doing bgscans more frequently to allow
++                       * the supplicant to make a better switching decision */
++                      if ((rssi < vap->iv_bgscanthr) &&
++                                      (!vap->iv_bgscanthr_next ||
++                                              !time_before(jiffies, vap->iv_bgscanthr_next)) &&
++                                      !(ic->ic_flags & IEEE80211_F_SCAN)) {
++                              int ret;
++
++                              ic->ic_lastdata = 0;
++                              ic->ic_lastscan = 0;
++                              ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN_THR;
++                              ret = ieee80211_bg_scan(vap);
++                              if (ret)
++                                      vap->iv_bgscanthr_next = jiffies + msecs_to_jiffies(IEEE80211_BGSCAN_TRIGGER_INTVL * 1000);
++                      }
++
+                       if (ni->ni_intval != scan.bintval) {
+                               IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
+                                               "beacon interval divergence: "
+--- a/net80211/ieee80211_scan.c
++++ b/net80211/ieee80211_scan.c
+@@ -782,7 +782,7 @@
+                               ieee80211_sta_pwrsave(vap, 0);
+                               if (ss->ss_next >= ss->ss_last) {
+                                       ieee80211_notify_scan_done(vap);
+-                                      ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
++                                      ic->ic_flags_ext &= ~(IEEE80211_FEXT_BGSCAN|IEEE80211_FEXT_BGSCAN_THR);
+                               }
+                       }
+                       SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_CANCEL;