aboutsummaryrefslogtreecommitdiffstats
path: root/package/madwifi/patches/361-bmiss_handling.patch
blob: b33cc3f73e97022b363c42a8ec01c1059c829326 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff
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 */
endif # check prerequisites before starting to build prereq: $(target/stamp-prereq) tmp/.prereq_packages @if [ ! -f "$(INCLUDE_DIR)/site/$(REAL_GNU_TARGET_NAME)" ]; then \ echo 'ERROR: Missing site config for target "$(REAL_GNU_TARGET_NAME)" !'; \ echo ' The missing file will cause configure scripts to fail during compilation.'; \ echo ' Please provide a "$(INCLUDE_DIR)/site/$(REAL_GNU_TARGET_NAME)" file and restart the build.'; \ exit 1; \ fi prepare: .config $(tools/stamp-install) $(toolchain/stamp-install) world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-install) $(target/stamp-install) FORCE $(_SINGLE)$(SUBMAKE) -r package/index # update all feeds, re-create index files, install symlinks package/symlinks: $(SCRIPT_DIR)/feeds update -a $(SCRIPT_DIR)/feeds install -a # re-create index files, install symlinks package/symlinks-install: $(SCRIPT_DIR)/feeds update -i $(SCRIPT_DIR)/feeds install -a # remove all symlinks, don't touch ./feeds package/symlinks-clean: $(SCRIPT_DIR)/feeds uninstall -a .PHONY: clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean endif