Root/package/madwifi/patches/357-bgscan_thresh.patch

1Add an optional background scanning threshold triggered by low rssi
2(useful for passing updated scan results to the supplicant ahead of
3time, before losing connectivity entirely)
4
5Signed-off-by: Felix Fietkau <nbd@openwrt.org>
6
7--- a/net80211/ieee80211_ioctl.h
8+++ b/net80211/ieee80211_ioctl.h
9@@ -646,6 +646,7 @@ enum {
10     IEEE80211_PARAM_MINRATE = 76, /* Minimum rate (by table index) */
11     IEEE80211_PARAM_PROTMODE_RSSI = 77, /* RSSI Threshold for enabling protection mode */
12     IEEE80211_PARAM_PROTMODE_TIMEOUT = 78, /* Timeout for expiring protection mode */
13+ IEEE80211_PARAM_BGSCAN_THRESH = 79, /* bg scan rssi threshold */
14 };
15 
16 #define SIOCG80211STATS (SIOCDEVPRIVATE+2)
17--- a/net80211/ieee80211_var.h
18+++ b/net80211/ieee80211_var.h
19@@ -92,6 +92,8 @@
20 #define IEEE80211_BGSCAN_IDLE_MIN 100 /* min idle time (ms) */
21 #define IEEE80211_BGSCAN_IDLE_DEFAULT 250 /* default idle time (ms) */
22 
23+#define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */
24+
25 #define IEEE80211_COVERAGE_CLASS_MAX 31 /* max coverage class */
26 #define IEEE80211_REGCLASSIDS_MAX 10 /* max regclass id list */
27 
28@@ -219,6 +221,10 @@ struct ieee80211vap {
29     u_int8_t iv_nickname[IEEE80211_NWID_LEN];
30     u_int iv_bgscanidle; /* bg scan idle threshold */
31     u_int iv_bgscanintvl; /* bg scan min interval */
32+ u_int iv_bgscanthr; /* bg scan rssi threshold */
33+ u_int iv_bgscantrintvl; /* bg scan trigger interval */
34+ unsigned long iv_bgscanthr_next; /* last trigger for bgscan */
35+ unsigned long iv_lastconnect; /* time of last connect attempt */
36     u_int iv_scanvalid; /* scan cache valid threshold */
37     struct ieee80211_roam iv_roam; /* sta-mode roaming state */
38 
39@@ -608,6 +614,7 @@ MALLOC_DECLARE(M_80211_VAP);
40 #define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: use software beacon timer */
41 #define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800 /* CONF: drop unencrypted eapol frames */
42 #define IEEE80211_FEXT_APPIE_UPDATE 0x00001000 /* STATE: beacon APP IE updated */
43+#define IEEE80211_FEXT_BGSCAN_THR 0x00002000 /* bgscan due to low rssi */
44 
45 #define IEEE80211_COM_UAPSD_ENABLE(_ic) ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD)
46 #define IEEE80211_COM_UAPSD_DISABLE(_ic) ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD)
47--- a/net80211/ieee80211_wireless.c
48+++ b/net80211/ieee80211_wireless.c
49@@ -2744,6 +2744,9 @@ ieee80211_ioctl_setparam(struct net_devi
50         else
51             retv = EINVAL;
52         break;
53+ case IEEE80211_PARAM_BGSCAN_THRESH:
54+ vap->iv_bgscanthr = value;
55+ break;
56     case IEEE80211_PARAM_MCAST_RATE:
57         /* units are in KILObits per second */
58         if (value >= 256 && value <= 54000)
59@@ -3144,6 +3147,9 @@ ieee80211_ioctl_getparam(struct net_devi
60     case IEEE80211_PARAM_BGSCAN_INTERVAL:
61         param[0] = vap->iv_bgscanintvl / HZ; /* seconds */
62         break;
63+ case IEEE80211_PARAM_BGSCAN_THRESH:
64+ param[0] = vap->iv_bgscanthr; /* rssi */
65+ break;
66     case IEEE80211_PARAM_MCAST_RATE:
67         param[0] = vap->iv_mcast_rate; /* seconds */
68         break;
69@@ -5666,6 +5672,10 @@ static const struct iw_priv_args ieee802
70       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanintvl" },
71     { IEEE80211_PARAM_BGSCAN_INTERVAL,
72       0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanintvl" },
73+ { IEEE80211_PARAM_BGSCAN_THRESH,
74+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanthr" },
75+ { IEEE80211_PARAM_BGSCAN_THRESH,
76+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanthr" },
77     { IEEE80211_PARAM_MCAST_RATE,
78       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcast_rate" },
79     { IEEE80211_PARAM_MCAST_RATE,
80--- a/net80211/ieee80211_input.c
81+++ b/net80211/ieee80211_input.c
82@@ -3013,8 +3013,10 @@ contbgscan(struct ieee80211vap *vap)
83 {
84     struct ieee80211com *ic = vap->iv_ic;
85 
86+ vap->iv_bgscantrintvl = (vap->iv_bgscantrintvl + 1) % 4;
87     return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) &&
88- time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle));
89+ (((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && !vap->iv_bgscantrintvl) ||
90+ time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle)));
91 }
92 
93 static __inline int
94@@ -3258,6 +3260,25 @@ ieee80211_recv_mgmt(struct ieee80211vap
95             /* record tsf of last beacon */
96             memcpy(ni->ni_tstamp.data, scan.tstamp,
97                 sizeof(ni->ni_tstamp));
98+
99+ /* When rssi is low, start doing bgscans more frequently to allow
100+ * the supplicant to make a better switching decision */
101+ if (!(ic->ic_flags & IEEE80211_F_SCAN) && (rssi < vap->iv_bgscanthr) &&
102+ (!vap->iv_bgscanthr_next ||
103+ !time_before(jiffies, vap->iv_bgscanthr_next)) &&
104+ (vap->iv_state == IEEE80211_S_RUN) &&
105+ time_after(jiffies, vap->iv_lastconnect +
106+ msecs_to_jiffies(IEEE80211_BGSCAN_INTVAL_MIN * 1000))) {
107+ int ret;
108+
109+ ic->ic_lastdata = 0;
110+ ic->ic_lastscan = 0;
111+ ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN_THR;
112+ ret = ieee80211_bg_scan(vap);
113+ if (ret)
114+ vap->iv_bgscanthr_next = jiffies + msecs_to_jiffies(IEEE80211_BGSCAN_TRIGGER_INTVL * 1000);
115+ }
116+
117             if (ni->ni_intval != scan.bintval) {
118                 IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
119                         "beacon interval divergence: "
120--- a/net80211/ieee80211_scan.c
121+++ b/net80211/ieee80211_scan.c
122@@ -616,6 +616,7 @@ ieee80211_cancel_scan(struct ieee80211va
123 
124         /* clear bg scan NOPICK and mark cancel request */
125         ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
126+ ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN_THR;
127         SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL;
128         ss->ss_ops->scan_cancel(ss, vap);
129         /* force it to fire asap */
130@@ -782,7 +783,7 @@ again:
131                 ieee80211_sta_pwrsave(vap, 0);
132                 if (ss->ss_next >= ss->ss_last) {
133                     ieee80211_notify_scan_done(vap);
134- ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
135+ ic->ic_flags_ext &= ~(IEEE80211_FEXT_BGSCAN|IEEE80211_FEXT_BGSCAN_THR);
136                 }
137             }
138             SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_CANCEL;
139--- a/net80211/ieee80211_proto.c
140+++ b/net80211/ieee80211_proto.c
141@@ -1450,6 +1450,7 @@ __ieee80211_newstate(struct ieee80211vap
142         }
143         break;
144     case IEEE80211_S_AUTH:
145+ vap->iv_lastconnect = jiffies;
146         /* auth frames are possible between IBSS nodes,
147          * see 802.11-1999, chapter 5.7.6 */
148         KASSERT(vap->iv_opmode == IEEE80211_M_STA ||
149--- a/net80211/ieee80211_output.c
150+++ b/net80211/ieee80211_output.c
151@@ -238,7 +238,8 @@ ieee80211_hardstart(struct sk_buff *skb,
152     }
153     
154     /* Cancel any running BG scan */
155- ieee80211_cancel_scan(vap);
156+ if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && (vap->iv_state == IEEE80211_S_RUN))
157+ ieee80211_cancel_scan(vap);
158 
159     /*
160      * Find the node for the destination so we can do
161

Archive Download this file



interactive