mac80211: rework MLME for multiple authentications

Sit tight. This shakes up the world as you know
it. Let go of your spaghetti tongs, they will no
longer be required, the horrible statemachine in
net/mac80211/mlme.c is no more...

With the cfg80211 SME mac80211 now has much less
to keep track of, but, on the other hand, for FT
it needs to be able to keep track of at least one
authentication being in progress while associated.
So convert from a single state machine to having
small ones for all the different things we need to
do. For real FT it will still need work wrt. PS,
but this should be a good step.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b87bf42..4839a2d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -233,9 +233,6 @@
 		ieee80211_configure_filter(local);
 		netif_addr_unlock_bh(local->mdev);
 		break;
-	case NL80211_IFTYPE_STATION:
-		sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
-		/* fall through */
 	default:
 		conf.vif = &sdata->vif;
 		conf.type = sdata->vif.type;
@@ -366,18 +363,6 @@
 	rcu_read_unlock();
 
 	/*
-	 * Announce that we are leaving the network, in case we are a
-	 * station interface type. This must be done before removing
-	 * all stations associated with sta_info_flush, otherwise STA
-	 * information will be gone and no announce being done.
-	 */
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED)
-			ieee80211_sta_deauthenticate(sdata,
-				WLAN_REASON_DEAUTH_LEAVING);
-	}
-
-	/*
 	 * Remove all stations associated with this interface.
 	 *
 	 * This must be done before calling ops->remove_interface()
@@ -462,7 +447,6 @@
 		netif_addr_unlock_bh(local->mdev);
 		break;
 	case NL80211_IFTYPE_STATION:
-		memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
 		del_timer_sync(&sdata->u.mgd.chswitch_timer);
 		del_timer_sync(&sdata->u.mgd.timer);
 		/*
@@ -485,10 +469,6 @@
 		 */
 		synchronize_rcu();
 		skb_queue_purge(&sdata->u.mgd.skb_queue);
-
-		kfree(sdata->u.mgd.extra_ie);
-		sdata->u.mgd.extra_ie = NULL;
-		sdata->u.mgd.extra_ie_len = 0;
 		/* fall through */
 	case NL80211_IFTYPE_ADHOC:
 		if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
@@ -650,11 +630,6 @@
 			kfree_skb(sdata->u.ibss.presp);
 		break;
 	case NL80211_IFTYPE_STATION:
-		kfree(sdata->u.mgd.extra_ie);
-		kfree(sdata->u.mgd.assocreq_ies);
-		kfree(sdata->u.mgd.assocresp_ies);
-		kfree(sdata->u.mgd.sme_auth_ie);
-		break;
 	case NL80211_IFTYPE_WDS:
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_MONITOR:
@@ -937,7 +912,8 @@
 			continue;
 		/* do not count disabled managed interfaces */
 		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-		    sdata->u.mgd.state == IEEE80211_STA_MLME_DISABLED)
+		    !sdata->u.mgd.associated &&
+		    list_empty(&sdata->u.mgd.work_list))
 			continue;
 		/* do not count unused IBSS interfaces */
 		if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&