+++ /dev/null
-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
-@@ -3369,12 +3369,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
-@@ -1213,6 +1213,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");
-@@ -1225,6 +1227,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
- /*
-@@ -1621,14 +1646,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
-@@ -292,6 +292,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 */