diff options
-rw-r--r-- | package/madwifi/patches/361-bmiss_handling.patch | 102 |
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..814a916dd --- /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 +@@ -3398,12 +3398,17 @@ + } + + /* 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 @@ + } + /* 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 @@ + 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 + /* +@@ -1617,14 +1642,14 @@ + } + + /* 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 +@@ -282,6 +282,7 @@ + + 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 */ |