mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2024-11-19 06:54:58 +01:00
103 lines
3.4 KiB
Diff
103 lines
3.4 KiB
Diff
|
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 */
|