[package] madwifi: remove cruft from madwifi.sh introduced by r15954, thanks Vasilis...
[openwrt.git] / package / madwifi / patches / 357-bgscan_thresh.patch
1 Add an optional background scanning threshold triggered by low rssi
2 (useful for passing updated scan results to the supplicant ahead of
3 time, before losing connectivity entirely)
4
5 Signed-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