aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/debugfs_sta.c5
-rw-r--r--net/mac80211/ibss.c6
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac80211/mesh_plink.c6
-rw-r--r--net/mac80211/mlme.c17
-rw-r--r--net/mac80211/sta_info.c19
-rw-r--r--net/mac80211/sta_info.h17
8 files changed, 59 insertions, 39 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 98460783c2d3..dc7420441574 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -776,12 +776,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
776 776
777 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED) && 777 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED) &&
778 !test_sta_flag(sta, WLAN_STA_AUTH)) { 778 !test_sta_flag(sta, WLAN_STA_AUTH)) {
779 ret = sta_info_move_state_checked(sta, 779 ret = sta_info_move_state(sta, IEEE80211_STA_AUTH);
780 IEEE80211_STA_AUTH);
781 if (ret) 780 if (ret)
782 return ret; 781 return ret;
783 ret = sta_info_move_state_checked(sta, 782 ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
784 IEEE80211_STA_ASSOC);
785 if (ret) 783 if (ret)
786 return ret; 784 return ret;
787 } 785 }
@@ -789,11 +787,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
789 787
790 if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { 788 if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
791 if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) 789 if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
792 ret = sta_info_move_state_checked(sta, 790 ret = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
793 IEEE80211_STA_AUTHORIZED);
794 else if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) 791 else if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
795 ret = sta_info_move_state_checked(sta, 792 ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
796 IEEE80211_STA_ASSOC);
797 if (ret) 793 if (ret)
798 return ret; 794 return ret;
799 } 795 }
@@ -805,12 +801,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
805 801
806 if (!(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) && 802 if (!(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) &&
807 test_sta_flag(sta, WLAN_STA_AUTH)) { 803 test_sta_flag(sta, WLAN_STA_AUTH)) {
808 ret = sta_info_move_state_checked(sta, 804 ret = sta_info_move_state(sta, IEEE80211_STA_AUTH);
809 IEEE80211_STA_AUTH);
810 if (ret) 805 if (ret)
811 return ret; 806 return ret;
812 ret = sta_info_move_state_checked(sta, 807 ret = sta_info_move_state(sta, IEEE80211_STA_NONE);
813 IEEE80211_STA_NONE);
814 if (ret) 808 if (ret)
815 return ret; 809 return ret;
816 } 810 }
@@ -944,8 +938,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
944 if (!sta) 938 if (!sta)
945 return -ENOMEM; 939 return -ENOMEM;
946 940
947 sta_info_move_state(sta, IEEE80211_STA_AUTH); 941 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
948 sta_info_move_state(sta, IEEE80211_STA_ASSOC); 942 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
949 943
950 err = sta_apply_parameters(local, sta, params); 944 err = sta_apply_parameters(local, sta, params);
951 if (err) { 945 if (err) {
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 2406b3e7393f..c8383712fdec 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -63,14 +63,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
63 test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" 63 test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
64 64
65 int res = scnprintf(buf, sizeof(buf), 65 int res = scnprintf(buf, sizeof(buf),
66 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 66 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
67 TEST(AUTH), TEST(ASSOC), TEST(PS_STA), 67 TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
68 TEST(PS_DRIVER), TEST(AUTHORIZED), 68 TEST(PS_DRIVER), TEST(AUTHORIZED),
69 TEST(SHORT_PREAMBLE), 69 TEST(SHORT_PREAMBLE),
70 TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), 70 TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
71 TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), 71 TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
72 TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), 72 TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
73 TEST(TDLS_PEER_AUTH)); 73 TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
74 TEST(INSERTED));
74#undef TEST 75#undef TEST
75 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 76 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
76} 77}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index d38baa41cf6c..a98d370b56f6 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -265,9 +265,9 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
265 addr, sdata->name); 265 addr, sdata->name);
266#endif 266#endif
267 267
268 sta_info_move_state(sta, IEEE80211_STA_AUTH); 268 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
269 sta_info_move_state(sta, IEEE80211_STA_ASSOC); 269 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
270 sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); 270 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
271 271
272 rate_control_rate_init(sta); 272 rate_control_rate_init(sta);
273 273
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index e47768cb8cb3..6b0d70e960d4 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -318,9 +318,9 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
318 goto err_del_interface; 318 goto err_del_interface;
319 } 319 }
320 320
321 sta_info_move_state(sta, IEEE80211_STA_AUTH); 321 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
322 sta_info_move_state(sta, IEEE80211_STA_ASSOC); 322 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
323 sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); 323 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
324 324
325 res = sta_info_insert(sta); 325 res = sta_info_insert(sta);
326 if (res) { 326 if (res) {
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 41ef1b476442..bf92e2878fe6 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -96,9 +96,9 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
96 if (!sta) 96 if (!sta)
97 return NULL; 97 return NULL;
98 98
99 sta_info_move_state(sta, IEEE80211_STA_AUTH); 99 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
100 sta_info_move_state(sta, IEEE80211_STA_ASSOC); 100 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
101 sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); 101 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
102 102
103 set_sta_flag(sta, WLAN_STA_WME); 103 set_sta_flag(sta, WLAN_STA_WME);
104 104
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index de3268c7be1e..acc11b5c16fa 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1587,10 +1587,19 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1587 return false; 1587 return false;
1588 } 1588 }
1589 1589
1590 sta_info_move_state(sta, IEEE80211_STA_AUTH); 1590 err = sta_info_move_state(sta, IEEE80211_STA_AUTH);
1591 sta_info_move_state(sta, IEEE80211_STA_ASSOC); 1591 if (!err)
1592 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) 1592 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
1593 sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); 1593 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
1594 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
1595 if (err) {
1596 printk(KERN_DEBUG
1597 "%s: failed to move station %pM to desired state\n",
1598 sdata->name, sta->sta.addr);
1599 WARN_ON(__sta_info_destroy(sta));
1600 mutex_unlock(&sdata->local->sta_mtx);
1601 return false;
1602 }
1594 1603
1595 rates = 0; 1604 rates = 0;
1596 basic_rates = 0; 1605 basic_rates = 0;
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
710static int __must_check __sta_info_destroy(struct sta_info *sta) 712int __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}
1392EXPORT_SYMBOL(ieee80211_sta_set_buffered); 1401EXPORT_SYMBOL(ieee80211_sta_set_buffered);
1393 1402
1394int sta_info_move_state_checked(struct sta_info *sta, 1403int 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
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6f77f12dc3fc..381de37d2478 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -52,6 +52,7 @@
52 * @WLAN_STA_SP: Station is in a service period, so don't try to 52 * @WLAN_STA_SP: Station is in a service period, so don't try to
53 * reply to other uAPSD trigger frames or PS-Poll. 53 * reply to other uAPSD trigger frames or PS-Poll.
54 * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame. 54 * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
55 * @WLAN_STA_INSERTED: This station is inserted into the hash table.
55 */ 56 */
56enum ieee80211_sta_info_flags { 57enum ieee80211_sta_info_flags {
57 WLAN_STA_AUTH, 58 WLAN_STA_AUTH,
@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags {
71 WLAN_STA_UAPSD, 72 WLAN_STA_UAPSD,
72 WLAN_STA_SP, 73 WLAN_STA_SP,
73 WLAN_STA_4ADDR_EVENT, 74 WLAN_STA_4ADDR_EVENT,
75 WLAN_STA_INSERTED,
74}; 76};
75 77
76enum ieee80211_sta_state { 78enum ieee80211_sta_state {
@@ -427,13 +429,17 @@ static inline int test_and_set_sta_flag(struct sta_info *sta,
427 return test_and_set_bit(flag, &sta->_flags); 429 return test_and_set_bit(flag, &sta->_flags);
428} 430}
429 431
430int sta_info_move_state_checked(struct sta_info *sta, 432int sta_info_move_state(struct sta_info *sta,
431 enum ieee80211_sta_state new_state); 433 enum ieee80211_sta_state new_state);
432 434
433static inline void sta_info_move_state(struct sta_info *sta, 435static inline void sta_info_pre_move_state(struct sta_info *sta,
434 enum ieee80211_sta_state new_state) 436 enum ieee80211_sta_state new_state)
435{ 437{
436 int ret = sta_info_move_state_checked(sta, new_state); 438 int ret;
439
440 WARN_ON_ONCE(test_sta_flag(sta, WLAN_STA_INSERTED));
441
442 ret = sta_info_move_state(sta, new_state);
437 WARN_ON_ONCE(ret); 443 WARN_ON_ONCE(ret);
438} 444}
439 445
@@ -544,6 +550,7 @@ int sta_info_insert(struct sta_info *sta);
544int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU); 550int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
545int sta_info_reinsert(struct sta_info *sta); 551int sta_info_reinsert(struct sta_info *sta);
546 552
553int __must_check __sta_info_destroy(struct sta_info *sta);
547int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, 554int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,
548 const u8 *addr); 555 const u8 *addr);
549int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata, 556int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,