aboutsummaryrefslogtreecommitdiffstats
path: root/package/madwifi/patches-r3776/319-eap_auth_disassoc.patch
blob: a1d9b0ba4edd7cd932a0fc228c9028cefc4791be (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
This patch causes STA mode interfaces to disassociate if transmission of assoc/auth
critical packets failed.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

--- a/ath/if_ath.c
+++ b/ath/if_ath.c
@@ -8273,6 +8273,18 @@
 #endif
 				if (ts->ts_status & HAL_TXERR_XRETRY) {
 					sc->sc_stats.ast_tx_xretries++;
+					if (SKB_CB(bf->bf_skb)->auth_pkt && (ni->ni_vap->iv_opmode == IEEE80211_M_STA)) {
+						struct ieee80211com *ic = &sc->sc_ic;
+
+						/* if roaming is enabled, try reassociating, otherwise
+						 * disassociate and go back to the scan state */
+						IEEE80211_VAPS_LOCK_BH(ic);
+						if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
+							ni->ni_vap->iv_newstate(ni->ni_vap, IEEE80211_S_ASSOC, 1);
+						else
+							ni->ni_vap->iv_newstate(ni->ni_vap, IEEE80211_S_SCAN, 0);
+						IEEE80211_VAPS_UNLOCK_BH(ic);
+					}
 					if (ni->ni_flags & IEEE80211_NODE_UAPSD_TRIG) {
 						ni->ni_stats.ns_tx_eosplost++;
 						DPRINTF(sc, ATH_DEBUG_UAPSD,
--- a/net80211/ieee80211_linux.c
+++ b/net80211/ieee80211_linux.c
@@ -158,6 +158,7 @@
 
 		SKB_NI(skb) = NULL;
 		SKB_CB(skb)->flags = 0;
+		SKB_CB(skb)->auth_pkt = 0;
 
 		skb_reserve(skb, sizeof(struct ieee80211_frame));
 		*frm = skb_put(skb, pktlen);
--- a/net80211/ieee80211_linux.h
+++ b/net80211/ieee80211_linux.h
@@ -411,6 +411,7 @@
 #define M_SKB_TRACKED	0x20
 	void		(*next_destructor)(struct sk_buff *skb);
 #endif
+	u_int8_t auth_pkt;
 };
 
 struct __assert {
--- a/net80211/ieee80211_output.c
+++ b/net80211/ieee80211_output.c
@@ -773,6 +773,8 @@
 	else
 		hdrsize = sizeof(struct ieee80211_frame);
 
+	SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE));
+
 	switch (vap->iv_opmode) {
 	case IEEE80211_M_IBSS:
 	case IEEE80211_M_AHDEMO:
@@ -1617,6 +1619,7 @@
 	ie->param_len = frm - &ie->param_oui[0];
 	return frm;
 }
+
 #endif
 /*
  * Send a probe request frame with the specified ssid
@@ -1881,6 +1884,7 @@
 				sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0));
 		if (skb == NULL)
 			senderr(ENOMEM, is_tx_nobuf);
+		SKB_CB(skb)->auth_pkt = 1;
 
 		((__le16 *)frm)[0] =
 			(is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED)
@@ -1955,6 +1959,7 @@
 			vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length);
 		if (skb == NULL)
 			senderr(ENOMEM, is_tx_nobuf);
+		SKB_CB(skb)->auth_pkt = 1;
 
 		capinfo = 0;
 		if (vap->iv_opmode == IEEE80211_M_IBSS)