madwifi: improve beacon miss handling to increase the reliability of STA mode links

SVN-Revision: 11798
owl
Felix Fietkau 2008-07-12 22:24:36 +00:00
parent a466930858
commit 09bcffddf1
1 changed files with 102 additions and 0 deletions

View File

@ -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 */