From c0dc50fb550a7e5ceaeacd48fca27069958832c9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 25 Jul 2008 22:36:33 +0000 Subject: [PATCH] rewrite madwifi sta mode link up/down notifications (mostly used by wpa_supplicant), fixes some stale node or reconnect loop issues SVN-Revision: 11926 --- package/madwifi/patches/360-sta_nodes.patch | 202 +++++++++++++++++++- 1 file changed, 197 insertions(+), 5 deletions(-) diff --git a/package/madwifi/patches/360-sta_nodes.patch b/package/madwifi/patches/360-sta_nodes.patch index 4f70b5712d..e701f9069b 100644 --- a/package/madwifi/patches/360-sta_nodes.patch +++ b/package/madwifi/patches/360-sta_nodes.patch @@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau break; case IEEE80211_M_HOSTAP: ieee80211_iterate_nodes(&ic->ic_sta, -@@ -1358,6 +1358,7 @@ +@@ -1358,12 +1358,14 @@ break; } goto reset; @@ -22,7 +22,14 @@ Signed-off-by: Felix Fietkau case IEEE80211_S_ASSOC: switch (vap->iv_opmode) { case IEEE80211_M_STA: -@@ -1376,7 +1377,6 @@ + IEEE80211_SEND_MGMT(ni, + IEEE80211_FC0_SUBTYPE_DEAUTH, + IEEE80211_REASON_AUTH_LEAVE); ++ ieee80211_node_leave(ni); + break; + case IEEE80211_M_HOSTAP: + ieee80211_iterate_nodes(&ic->ic_sta, +@@ -1376,7 +1378,6 @@ case IEEE80211_S_SCAN: ieee80211_cancel_scan(vap); goto reset; @@ -30,7 +37,12 @@ Signed-off-by: Felix Fietkau reset: ieee80211_reset_bss(vap); break; -@@ -1432,7 +1432,7 @@ +@@ -1429,10 +1430,12 @@ + IEEE80211_SCAN_FOREVER, + vap->iv_des_nssid, vap->iv_des_ssid, + NULL); ++ else ++ ieee80211_node_leave(vap->iv_bss); break; case IEEE80211_S_RUN: /* beacon miss */ if (vap->iv_opmode == IEEE80211_M_STA) { @@ -39,7 +51,7 @@ Signed-off-by: Felix Fietkau vap->iv_flags &= ~IEEE80211_F_SIBSS; /* XXX */ if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) ieee80211_check_scan(vap, -@@ -1483,7 +1483,7 @@ +@@ -1484,7 +1487,7 @@ vap->iv_state = ostate; /* stay RUN */ break; case IEEE80211_FC0_SUBTYPE_DEAUTH: @@ -48,7 +60,7 @@ Signed-off-by: Felix Fietkau if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { /* try to reauth */ IEEE80211_SEND_MGMT(ni, -@@ -1510,7 +1510,7 @@ +@@ -1511,7 +1514,7 @@ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0); break; case IEEE80211_S_RUN: @@ -57,3 +69,183 @@ Signed-off-by: Felix Fietkau if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { /* NB: caller specifies ASSOC/REASSOC by arg */ IEEE80211_SEND_MGMT(ni, arg ? +@@ -1779,6 +1782,7 @@ + ieee80211_state_name[nstate], + ieee80211_state_name[dstate]); + ++ ieee80211_update_link_status(vap, nstate, ostate); + switch (nstate) { + case IEEE80211_S_AUTH: + case IEEE80211_S_ASSOC: +--- a/net80211/ieee80211_linux.c ++++ b/net80211/ieee80211_linux.c +@@ -233,33 +233,59 @@ + } + + void +-ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc) ++ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate) + { +- struct ieee80211vap *vap = ni->ni_vap; + struct net_device *dev = vap->iv_dev; + union iwreq_data wreq; ++ int active; ++ ++ if (vap->iv_opmode != IEEE80211_M_STA) ++ return; ++ ++ if (ostate == nstate) ++ return; ++ ++ if (nstate == IEEE80211_S_RUN) ++ active = 1; ++ else if ((ostate >= IEEE80211_S_AUTH) && (nstate < ostate)) ++ active = 0; ++ else ++ return; ++ ++ if (active && !vap->iv_bss) ++ return; ++ ++ memset(&wreq, 0, sizeof(wreq)); ++ wreq.ap_addr.sa_family = ARPHRD_ETHER; + +- if (ni == vap->iv_bss) { +- if (newassoc) +- netif_carrier_on(dev); +- memset(&wreq, 0, sizeof(wreq)); ++ if (active) { ++ //netif_carrier_on(vap->iv_dev); + IEEE80211_ADDR_COPY(wreq.addr.sa_data, vap->iv_bssid); +- wreq.addr.sa_family = ARPHRD_ETHER; +-#ifdef ATH_SUPERG_XR +- if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR) +- dev = vap->iv_xrvap->iv_dev; +-#endif +- wireless_send_event(dev, SIOCGIWAP, &wreq, NULL); + } else { +- memset(&wreq, 0, sizeof(wreq)); +- IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr); +- wreq.addr.sa_family = ARPHRD_ETHER; ++ //netif_carrier_off(vap->iv_dev); ++ memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN); ++ } ++ wireless_send_event(dev, SIOCGIWAP, &wreq, NULL); ++} ++ ++void ++ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc) ++{ ++ struct ieee80211vap *vap = ni->ni_vap; ++ struct net_device *dev = vap->iv_dev; ++ union iwreq_data wreq; ++ ++ if (ni == vap->iv_bss) ++ return; ++ ++ memset(&wreq, 0, sizeof(wreq)); ++ IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr); ++ wreq.addr.sa_family = ARPHRD_ETHER; + #ifdef ATH_SUPERG_XR +- if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR) +- dev = vap->iv_xrvap->iv_dev; ++ if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR) ++ dev = vap->iv_xrvap->iv_dev; + #endif +- wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL); +- } ++ wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL); + } + + void +@@ -269,18 +295,14 @@ + struct net_device *dev = vap->iv_dev; + union iwreq_data wreq; + +- if (ni == vap->iv_bss) { +- netif_carrier_off(dev); +- memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN); +- wreq.ap_addr.sa_family = ARPHRD_ETHER; +- wireless_send_event(dev, SIOCGIWAP, &wreq, NULL); +- } else { +- /* fire off wireless event station leaving */ +- memset(&wreq, 0, sizeof(wreq)); +- IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr); +- wreq.addr.sa_family = ARPHRD_ETHER; +- wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL); +- } ++ if (ni == vap->iv_bss) ++ return; ++ ++ /* fire off wireless event station leaving */ ++ memset(&wreq, 0, sizeof(wreq)); ++ IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr); ++ wreq.addr.sa_family = ARPHRD_ETHER; ++ wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL); + } + + void +--- a/net80211/ieee80211_node.c ++++ b/net80211/ieee80211_node.c +@@ -2332,6 +2332,7 @@ + count_suppchans(ic, ni, -1); + IEEE80211_UNLOCK_IRQ(ic); + ++done: + /* + * Cleanup station state. In particular clear various + * state that might otherwise be reused if the node +@@ -2339,7 +2340,7 @@ + * (and memory is reclaimed). + */ + ieee80211_sta_leave(ni); +-done: ++ + /* Run a cleanup */ + #ifdef IEEE80211_DEBUG_REFCNT + ic->ic_node_cleanup_debug(ni, __func__, __LINE__); +--- a/net80211/ieee80211_node.h ++++ b/net80211/ieee80211_node.h +@@ -60,7 +60,7 @@ + #define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */ + #define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */ + +-#define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */ ++#define IEEE80211_TRANS_WAIT 300 /* mgt frame tx timer (msecs) */ + + #define IEEE80211_NODE_HASHSIZE 32 + /* simple hash is enough for variation of macaddr */ +--- a/net80211/ieee80211_output.c ++++ b/net80211/ieee80211_output.c +@@ -2140,7 +2140,7 @@ + + ieee80211_mgmt_output(ieee80211_ref_node(ni), skb, type); + if (timer) +- mod_timer(&vap->iv_mgtsend, jiffies + timer * HZ); ++ mod_timer(&vap->iv_mgtsend, jiffies + msecs_to_jiffies(timer)); + return 0; + bad: + return ret; +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -514,8 +514,9 @@ + vap->iv_flags |= IEEE80211_F_DESBSSID; + + IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data); +- if (IS_UP_AUTO(vap)) ++ if (IS_UP(vap->iv_dev)) { + ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); ++ } + } + return 0; + } +--- a/net80211/ieee80211_linux.h ++++ b/net80211/ieee80211_linux.h +@@ -643,6 +643,7 @@ + #define free_netdev(dev) kfree(dev) + #endif + ++void ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate); + void ieee80211_ioctl_vattach(struct ieee80211vap *); + void ieee80211_ioctl_vdetach(struct ieee80211vap *); + struct ifreq; -- 2.25.1