aboutsummaryrefslogtreecommitdiffstats
path: root/package/madwifi/patches/361-bmiss_handling.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/madwifi/patches/361-bmiss_handling.patch')
-rw-r--r--package/madwifi/patches/361-bmiss_handling.patch102
1 files changed, 102 insertions, 0 deletions
diff --git a/package/madwifi/patches/361-bmiss_handling.patch b/package/madwifi/patches/361-bmiss_handling.patch
new file mode 100644
index 000000000..15d238f7b
--- /dev/null
+++ b/package/madwifi/patches/361-bmiss_handling.patch
@@ -0,0 +1,102 @@
+Improve the beacon miss handling. Instead of just dropping the connection,
+send a directed probe request to the AP to see if it's still responding.
+Schedule a software beacon miss timer in this case, which adds a timeout
+for the APs probe response.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+
+--- a/net80211/ieee80211_input.c
++++ b/net80211/ieee80211_input.c
+@@ -3400,12 +3400,17 @@ ieee80211_recv_mgmt(struct ieee80211vap
+ }
+
+ /* WDS/Repeater: re-schedule software beacon timer for
+- * STA. */
+- if ((vap->iv_state == IEEE80211_S_RUN) &&
+- (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {
+- mod_timer(&vap->iv_swbmiss,
++ * STA. Reset consecutive bmiss counter as well */
++ IEEE80211_LOCK_IRQ(ic);
++ if (vap->iv_state == IEEE80211_S_RUN) {
++ vap->iv_bmiss_count = 0;
++ if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)
++ mod_timer(&vap->iv_swbmiss,
+ jiffies + vap->iv_swbmiss_period);
++ else
++ del_timer(&vap->iv_swbmiss);
+ }
++ IEEE80211_UNLOCK_IRQ(ic);
+
+ /* If scanning, pass the info to the scan module.
+ * Otherwise, check if it's the right time to do
+--- a/net80211/ieee80211_proto.c
++++ b/net80211/ieee80211_proto.c
+@@ -1209,6 +1209,8 @@ ieee80211_beacon_miss(struct ieee80211co
+ }
+ /* XXX locking */
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
++ int count;
++
+ IEEE80211_DPRINTF(vap,
+ IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
+ "%s\n", "beacon miss");
+@@ -1221,6 +1223,29 @@ ieee80211_beacon_miss(struct ieee80211co
+ if (vap->iv_opmode != IEEE80211_M_STA ||
+ vap->iv_state != IEEE80211_S_RUN)
+ continue;
++
++ IEEE80211_LOCK_IRQ(ic);
++ count = vap->iv_bmiss_count++;
++ if (count) {
++ /* if the counter was already above zero, reset it
++ * here, since we're going to do the bmiss handling
++ * in any case */
++ vap->iv_bmiss_count = 0;
++ } else {
++ /* schedule the software beacon miss timer, it will be
++ * cancelled, if the probe request is acked */
++ mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);
++ }
++ IEEE80211_UNLOCK_IRQ(ic);
++
++ if (!count) {
++ ieee80211_send_probereq(vap->iv_bss, vap->iv_myaddr,
++ vap->iv_bss->ni_bssid, vap->iv_bss->ni_bssid,
++ vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen,
++ NULL, 0);
++ continue;
++ }
++
+ if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
+ #ifdef ATH_SUPERG_DYNTURBO
+ /*
+@@ -1621,14 +1646,14 @@ __ieee80211_newstate(struct ieee80211vap
+ }
+
+ /* WDS/Repeater: Start software beacon timer for STA */
++ vap->iv_swbmiss.function = ieee80211_sta_swbmiss;
++ vap->iv_swbmiss.data = (unsigned long) vap;
++ vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES(
++ vap->iv_ic->ic_bmissthreshold * ni->ni_intval);
++
+ if (ostate != IEEE80211_S_RUN &&
+ (vap->iv_opmode == IEEE80211_M_STA &&
+ vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {
+- vap->iv_swbmiss.function = ieee80211_sta_swbmiss;
+- vap->iv_swbmiss.data = (unsigned long) vap;
+- vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES(
+- vap->iv_ic->ic_bmissthreshold * ni->ni_intval);
+-
+ mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);
+ }
+
+--- a/net80211/ieee80211_var.h
++++ b/net80211/ieee80211_var.h
+@@ -283,6 +283,7 @@ struct ieee80211vap {
+
+ struct timer_list iv_swbmiss; /* software beacon miss timer */
+ u_int16_t iv_swbmiss_period; /* software beacon miss timer period */
++ u_int16_t iv_bmiss_count; /* consecutive beacon miss counter */
+ struct ieee80211_nsparams iv_nsparams; /* new state parameters for tasklet for stajoin1 */
+ struct IEEE80211_TQ_STRUCT iv_stajoin1tq; /* tasklet for newstate action called from stajoin1tq */
+ unsigned int iv_nsdone; /* Done with scheduled newstate tasklet */