diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-07-25 22:36:33 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-07-25 22:36:33 +0000 | 
| commit | 5bcfda23beadcf7322a79198affca58f94982d37 (patch) | |
| tree | 747f64b6d305d5d677a12d596cdef291baaf8bac | |
| parent | c3e464ad094b6c2862cdde82adf3c67b548ad3b3 (diff) | |
rewrite madwifi sta mode link up/down notifications (mostly used by wpa_supplicant),
fixes some stale node or reconnect loop issues
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@11926 3c298f89-4303-0410-b956-a3cf2f4a3e73
| -rw-r--r-- | package/madwifi/patches/360-sta_nodes.patch | 202 | 
1 files changed, 197 insertions, 5 deletions
| diff --git a/package/madwifi/patches/360-sta_nodes.patch b/package/madwifi/patches/360-sta_nodes.patch index 4f70b5712..e701f9069 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 <nbd@openwrt.org>   				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 <nbd@openwrt.org>   		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 <nbd@openwrt.org>   		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 <nbd@openwrt.org>   				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 <nbd@openwrt.org>   				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 <nbd@openwrt.org>   			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; | 
