diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-01-12 03:31:10 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-01-30 15:41:25 -0500 |
commit | 83d5cc012441531ab0bf6f99881958e964e9cf11 (patch) | |
tree | b36a127cd4d735f5b4a0b7fbfbdd3714bceca44f /net/mac80211/sta_info.c | |
parent | c037b8367c7e2b775a99d74037f5df014d2fbf06 (diff) |
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>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index f28fa02b6e54..df8f0a2f0dee 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -403,6 +403,8 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
403 | sta_info_hash_add(local, sta); | 403 | sta_info_hash_add(local, sta); |
404 | 404 | ||
405 | list_add(&sta->list, &local->sta_list); | 405 | list_add(&sta->list, &local->sta_list); |
406 | |||
407 | set_sta_flag(sta, WLAN_STA_INSERTED); | ||
406 | } else { | 408 | } else { |
407 | sta->dummy = false; | 409 | sta->dummy = false; |
408 | } | 410 | } |
@@ -707,7 +709,7 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
707 | return have_buffered; | 709 | return have_buffered; |
708 | } | 710 | } |
709 | 711 | ||
710 | static int __must_check __sta_info_destroy(struct sta_info *sta) | 712 | int __must_check __sta_info_destroy(struct sta_info *sta) |
711 | { | 713 | { |
712 | struct ieee80211_local *local; | 714 | struct ieee80211_local *local; |
713 | struct ieee80211_sub_if_data *sdata; | 715 | struct ieee80211_sub_if_data *sdata; |
@@ -722,6 +724,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
722 | local = sta->local; | 724 | local = sta->local; |
723 | sdata = sta->sdata; | 725 | sdata = sta->sdata; |
724 | 726 | ||
727 | lockdep_assert_held(&local->sta_mtx); | ||
728 | |||
725 | /* | 729 | /* |
726 | * Before removing the station from the driver and | 730 | * Before removing the station from the driver and |
727 | * rate control, it might still start new aggregation | 731 | * rate control, it might still start new aggregation |
@@ -763,8 +767,13 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
763 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 767 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
764 | RCU_INIT_POINTER(sdata->u.vlan.sta, NULL); | 768 | RCU_INIT_POINTER(sdata->u.vlan.sta, NULL); |
765 | 769 | ||
766 | while (sta->sta_state > IEEE80211_STA_NONE) | 770 | while (sta->sta_state > IEEE80211_STA_NONE) { |
767 | sta_info_move_state(sta, sta->sta_state - 1); | 771 | int err = sta_info_move_state(sta, sta->sta_state - 1); |
772 | if (err) { | ||
773 | WARN_ON_ONCE(1); | ||
774 | break; | ||
775 | } | ||
776 | } | ||
768 | 777 | ||
769 | if (sta->uploaded) { | 778 | if (sta->uploaded) { |
770 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 779 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
@@ -1391,8 +1400,8 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, | |||
1391 | } | 1400 | } |
1392 | EXPORT_SYMBOL(ieee80211_sta_set_buffered); | 1401 | EXPORT_SYMBOL(ieee80211_sta_set_buffered); |
1393 | 1402 | ||
1394 | int sta_info_move_state_checked(struct sta_info *sta, | 1403 | int sta_info_move_state(struct sta_info *sta, |
1395 | enum ieee80211_sta_state new_state) | 1404 | enum ieee80211_sta_state new_state) |
1396 | { | 1405 | { |
1397 | might_sleep(); | 1406 | might_sleep(); |
1398 | 1407 | ||