mac80211: station state transition error handling

In the future, when we start notifying drivers,
state transitions could potentially fail. To make
it easier to distinguish between programming bugs
and driver failures:
 * rename sta_info_move_state() to
   sta_info_pre_move_state() which can only be
   called before the station is inserted (and
   check this with a new station flag).
 * rename sta_info_move_state_checked() to just
   plain sta_info_move_state(), as it will be
   the regular function that can fail for more
   than just one reason (bad transition or an
   error from the driver)

This makes the programming model easier -- one of
the functions can only be called before insertion
and can't fail, the other can fail.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index f28fa02..df8f0a2 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -403,6 +403,8 @@
 		sta_info_hash_add(local, sta);
 
 		list_add(&sta->list, &local->sta_list);
+
+		set_sta_flag(sta, WLAN_STA_INSERTED);
 	} else {
 		sta->dummy = false;
 	}
@@ -707,7 +709,7 @@
 	return have_buffered;
 }
 
-static int __must_check __sta_info_destroy(struct sta_info *sta)
+int __must_check __sta_info_destroy(struct sta_info *sta)
 {
 	struct ieee80211_local *local;
 	struct ieee80211_sub_if_data *sdata;
@@ -722,6 +724,8 @@
 	local = sta->local;
 	sdata = sta->sdata;
 
+	lockdep_assert_held(&local->sta_mtx);
+
 	/*
 	 * Before removing the station from the driver and
 	 * rate control, it might still start new aggregation
@@ -763,8 +767,13 @@
 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
 		RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
 
-	while (sta->sta_state > IEEE80211_STA_NONE)
-		sta_info_move_state(sta, sta->sta_state - 1);
+	while (sta->sta_state > IEEE80211_STA_NONE) {
+		int err = sta_info_move_state(sta, sta->sta_state - 1);
+		if (err) {
+			WARN_ON_ONCE(1);
+			break;
+		}
+	}
 
 	if (sta->uploaded) {
 		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -1391,8 +1400,8 @@
 }
 EXPORT_SYMBOL(ieee80211_sta_set_buffered);
 
-int sta_info_move_state_checked(struct sta_info *sta,
-				enum ieee80211_sta_state new_state)
+int sta_info_move_state(struct sta_info *sta,
+			enum ieee80211_sta_state new_state)
 {
 	might_sleep();