aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/80211.tmpl2
-rw-r--r--include/net/cfg80211.h51
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/debugfs_netdev.c10
-rw-r--r--net/mac80211/ht.c4
-rw-r--r--net/mac80211/ibss.c39
-rw-r--r--net/mac80211/ieee80211_i.h25
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mesh.c32
-rw-r--r--net/mac80211/mesh_plink.c7
-rw-r--r--net/mac80211/mlme.c341
-rw-r--r--net/mac80211/util.c4
-rw-r--r--net/wireless/mlme.c48
-rw-r--r--net/wireless/trace.h4
14 files changed, 220 insertions, 355 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 0f6a3edcd44b..ebe89694cf81 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -132,9 +132,7 @@
132!Finclude/net/cfg80211.h cfg80211_send_rx_assoc 132!Finclude/net/cfg80211.h cfg80211_send_rx_assoc
133!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout 133!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
134!Finclude/net/cfg80211.h cfg80211_send_deauth 134!Finclude/net/cfg80211.h cfg80211_send_deauth
135!Finclude/net/cfg80211.h __cfg80211_send_deauth
136!Finclude/net/cfg80211.h cfg80211_send_disassoc 135!Finclude/net/cfg80211.h cfg80211_send_disassoc
137!Finclude/net/cfg80211.h __cfg80211_send_disassoc
138!Finclude/net/cfg80211.h cfg80211_ibss_joined 136!Finclude/net/cfg80211.h cfg80211_ibss_joined
139!Finclude/net/cfg80211.h cfg80211_connect_result 137!Finclude/net/cfg80211.h cfg80211_connect_result
140!Finclude/net/cfg80211.h cfg80211_roamed 138!Finclude/net/cfg80211.h cfg80211_roamed
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5430f70c63b3..9f45d74ce3c2 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1867,7 +1867,9 @@ struct cfg80211_update_ft_ies_params {
1867 * @get_mpath: get a mesh path for the given parameters 1867 * @get_mpath: get a mesh path for the given parameters
1868 * @dump_mpath: dump mesh path callback -- resume dump at index @idx 1868 * @dump_mpath: dump mesh path callback -- resume dump at index @idx
1869 * @join_mesh: join the mesh network with the specified parameters 1869 * @join_mesh: join the mesh network with the specified parameters
1870 * (invoked with the wireless_dev mutex held)
1870 * @leave_mesh: leave the current mesh network 1871 * @leave_mesh: leave the current mesh network
1872 * (invoked with the wireless_dev mutex held)
1871 * 1873 *
1872 * @get_mesh_config: Get the current mesh configuration 1874 * @get_mesh_config: Get the current mesh configuration
1873 * 1875 *
@@ -1894,20 +1896,28 @@ struct cfg80211_update_ft_ies_params {
1894 * the scan/scan_done bracket too. 1896 * the scan/scan_done bracket too.
1895 * 1897 *
1896 * @auth: Request to authenticate with the specified peer 1898 * @auth: Request to authenticate with the specified peer
1899 * (invoked with the wireless_dev mutex held)
1897 * @assoc: Request to (re)associate with the specified peer 1900 * @assoc: Request to (re)associate with the specified peer
1901 * (invoked with the wireless_dev mutex held)
1898 * @deauth: Request to deauthenticate from the specified peer 1902 * @deauth: Request to deauthenticate from the specified peer
1903 * (invoked with the wireless_dev mutex held)
1899 * @disassoc: Request to disassociate from the specified peer 1904 * @disassoc: Request to disassociate from the specified peer
1905 * (invoked with the wireless_dev mutex held)
1900 * 1906 *
1901 * @connect: Connect to the ESS with the specified parameters. When connected, 1907 * @connect: Connect to the ESS with the specified parameters. When connected,
1902 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. 1908 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
1903 * If the connection fails for some reason, call cfg80211_connect_result() 1909 * If the connection fails for some reason, call cfg80211_connect_result()
1904 * with the status from the AP. 1910 * with the status from the AP.
1911 * (invoked with the wireless_dev mutex held)
1905 * @disconnect: Disconnect from the BSS/ESS. 1912 * @disconnect: Disconnect from the BSS/ESS.
1913 * (invoked with the wireless_dev mutex held)
1906 * 1914 *
1907 * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call 1915 * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
1908 * cfg80211_ibss_joined(), also call that function when changing BSSID due 1916 * cfg80211_ibss_joined(), also call that function when changing BSSID due
1909 * to a merge. 1917 * to a merge.
1918 * (invoked with the wireless_dev mutex held)
1910 * @leave_ibss: Leave the IBSS. 1919 * @leave_ibss: Leave the IBSS.
1920 * (invoked with the wireless_dev mutex held)
1911 * 1921 *
1912 * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or 1922 * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or
1913 * MESH mode) 1923 * MESH mode)
@@ -2851,7 +2861,8 @@ struct cfg80211_cached_keys;
2851 * by cfg80211 on change_interface 2861 * by cfg80211 on change_interface
2852 * @mgmt_registrations: list of registrations for management frames 2862 * @mgmt_registrations: list of registrations for management frames
2853 * @mgmt_registrations_lock: lock for the list 2863 * @mgmt_registrations_lock: lock for the list
2854 * @mtx: mutex used to lock data in this struct 2864 * @mtx: mutex used to lock data in this struct, may be used by drivers
2865 * and some API functions require it held
2855 * @cleanup_work: work struct used for cleanup that can't be done directly 2866 * @cleanup_work: work struct used for cleanup that can't be done directly
2856 * @beacon_interval: beacon interval used on this device for transmitting 2867 * @beacon_interval: beacon interval used on this device for transmitting
2857 * beacons, 0 when not valid 2868 * beacons, 0 when not valid
@@ -3424,7 +3435,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
3424 * This function is called whenever an authentication has been processed in 3435 * This function is called whenever an authentication has been processed in
3425 * station mode. The driver is required to call either this function or 3436 * station mode. The driver is required to call either this function or
3426 * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth() 3437 * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth()
3427 * call. This function may sleep. 3438 * call. This function may sleep. The caller must hold the corresponding wdev's
3439 * mutex.
3428 */ 3440 */
3429void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); 3441void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
3430 3442
@@ -3433,7 +3445,8 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
3433 * @dev: network device 3445 * @dev: network device
3434 * @addr: The MAC address of the device with which the authentication timed out 3446 * @addr: The MAC address of the device with which the authentication timed out
3435 * 3447 *
3436 * This function may sleep. 3448 * This function may sleep. The caller must hold the corresponding wdev's
3449 * mutex.
3437 */ 3450 */
3438void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr); 3451void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
3439 3452
@@ -3448,7 +3461,8 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
3448 * This function is called whenever a (re)association response has been 3461 * This function is called whenever a (re)association response has been
3449 * processed in station mode. The driver is required to call either this 3462 * processed in station mode. The driver is required to call either this
3450 * function or cfg80211_send_assoc_timeout() to indicate the result of 3463 * function or cfg80211_send_assoc_timeout() to indicate the result of
3451 * cfg80211_ops::assoc() call. This function may sleep. 3464 * cfg80211_ops::assoc() call. This function may sleep. The caller must hold
3465 * the corresponding wdev's mutex.
3452 */ 3466 */
3453void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, 3467void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
3454 const u8 *buf, size_t len); 3468 const u8 *buf, size_t len);
@@ -3458,7 +3472,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
3458 * @dev: network device 3472 * @dev: network device
3459 * @addr: The MAC address of the device with which the association timed out 3473 * @addr: The MAC address of the device with which the association timed out
3460 * 3474 *
3461 * This function may sleep. 3475 * This function may sleep. The caller must hold the corresponding wdev's mutex.
3462 */ 3476 */
3463void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); 3477void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
3464 3478
@@ -3470,21 +3484,12 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
3470 * 3484 *
3471 * This function is called whenever deauthentication has been processed in 3485 * This function is called whenever deauthentication has been processed in
3472 * station mode. This includes both received deauthentication frames and 3486 * station mode. This includes both received deauthentication frames and
3473 * locally generated ones. This function may sleep. 3487 * locally generated ones. This function may sleep. The caller must hold the
3488 * corresponding wdev's mutex.
3474 */ 3489 */
3475void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); 3490void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
3476 3491
3477/** 3492/**
3478 * __cfg80211_send_deauth - notification of processed deauthentication
3479 * @dev: network device
3480 * @buf: deauthentication frame (header + body)
3481 * @len: length of the frame data
3482 *
3483 * Like cfg80211_send_deauth(), but doesn't take the wdev lock.
3484 */
3485void __cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
3486
3487/**
3488 * cfg80211_send_disassoc - notification of processed disassociation 3493 * cfg80211_send_disassoc - notification of processed disassociation
3489 * @dev: network device 3494 * @dev: network device
3490 * @buf: disassociation response frame (header + body) 3495 * @buf: disassociation response frame (header + body)
@@ -3492,22 +3497,12 @@ void __cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
3492 * 3497 *
3493 * This function is called whenever disassociation has been processed in 3498 * This function is called whenever disassociation has been processed in
3494 * station mode. This includes both received disassociation frames and locally 3499 * station mode. This includes both received disassociation frames and locally
3495 * generated ones. This function may sleep. 3500 * generated ones. This function may sleep. The caller must hold the
3501 * corresponding wdev's mutex.
3496 */ 3502 */
3497void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); 3503void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len);
3498 3504
3499/** 3505/**
3500 * __cfg80211_send_disassoc - notification of processed disassociation
3501 * @dev: network device
3502 * @buf: disassociation response frame (header + body)
3503 * @len: length of the frame data
3504 *
3505 * Like cfg80211_send_disassoc(), but doesn't take the wdev lock.
3506 */
3507void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf,
3508 size_t len);
3509
3510/**
3511 * cfg80211_send_unprot_deauth - notification of unprotected deauthentication 3506 * cfg80211_send_unprot_deauth - notification of unprotected deauthentication
3512 * @dev: network device 3507 * @dev: network device
3513 * @buf: deauthentication frame (header + body) 3508 * @buf: deauthentication frame (header + body)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index eb4219051043..232edf78d5a9 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2318,7 +2318,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
2318 enum ieee80211_smps_mode old_req; 2318 enum ieee80211_smps_mode old_req;
2319 int err; 2319 int err;
2320 2320
2321 lockdep_assert_held(&sdata->u.mgd.mtx); 2321 lockdep_assert_held(&sdata->wdev.mtx);
2322 2322
2323 old_req = sdata->u.mgd.req_smps; 2323 old_req = sdata->u.mgd.req_smps;
2324 sdata->u.mgd.req_smps = smps_mode; 2324 sdata->u.mgd.req_smps = smps_mode;
@@ -2375,9 +2375,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2375 local->dynamic_ps_forced_timeout = timeout; 2375 local->dynamic_ps_forced_timeout = timeout;
2376 2376
2377 /* no change, but if automatic follow powersave */ 2377 /* no change, but if automatic follow powersave */
2378 mutex_lock(&sdata->u.mgd.mtx);
2379 __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps); 2378 __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
2380 mutex_unlock(&sdata->u.mgd.mtx);
2381 2379
2382 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 2380 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
2383 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 2381 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index f83074fe6670..cafe614ef93d 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -228,9 +228,9 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
228 if (sdata->vif.type != NL80211_IFTYPE_STATION) 228 if (sdata->vif.type != NL80211_IFTYPE_STATION)
229 return -EOPNOTSUPP; 229 return -EOPNOTSUPP;
230 230
231 mutex_lock(&sdata->u.mgd.mtx); 231 sdata_lock(sdata);
232 err = __ieee80211_request_smps(sdata, smps_mode); 232 err = __ieee80211_request_smps(sdata, smps_mode);
233 mutex_unlock(&sdata->u.mgd.mtx); 233 sdata_unlock(sdata);
234 234
235 return err; 235 return err;
236} 236}
@@ -313,16 +313,16 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
313 case NL80211_IFTYPE_STATION: 313 case NL80211_IFTYPE_STATION:
314 fc |= cpu_to_le16(IEEE80211_FCTL_TODS); 314 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
315 /* BSSID SA DA */ 315 /* BSSID SA DA */
316 mutex_lock(&sdata->u.mgd.mtx); 316 sdata_lock(sdata);
317 if (!sdata->u.mgd.associated) { 317 if (!sdata->u.mgd.associated) {
318 mutex_unlock(&sdata->u.mgd.mtx); 318 sdata_unlock(sdata);
319 dev_kfree_skb(skb); 319 dev_kfree_skb(skb);
320 return -ENOTCONN; 320 return -ENOTCONN;
321 } 321 }
322 memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN); 322 memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN);
323 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); 323 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
324 memcpy(hdr->addr3, addr, ETH_ALEN); 324 memcpy(hdr->addr3, addr, ETH_ALEN);
325 mutex_unlock(&sdata->u.mgd.mtx); 325 sdata_unlock(sdata);
326 break; 326 break;
327 default: 327 default:
328 dev_kfree_skb(skb); 328 dev_kfree_skb(skb);
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index af8cee06e4f3..75dff338f581 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -429,9 +429,9 @@ void ieee80211_request_smps_work(struct work_struct *work)
429 container_of(work, struct ieee80211_sub_if_data, 429 container_of(work, struct ieee80211_sub_if_data,
430 u.mgd.request_smps_work); 430 u.mgd.request_smps_work);
431 431
432 mutex_lock(&sdata->u.mgd.mtx); 432 sdata_lock(sdata);
433 __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); 433 __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode);
434 mutex_unlock(&sdata->u.mgd.mtx); 434 sdata_unlock(sdata);
435} 435}
436 436
437void ieee80211_request_smps(struct ieee80211_vif *vif, 437void ieee80211_request_smps(struct ieee80211_vif *vif,
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 956ba6316da5..caa4b4f7f6e4 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -54,7 +54,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
54 struct beacon_data *presp; 54 struct beacon_data *presp;
55 int frame_len; 55 int frame_len;
56 56
57 lockdep_assert_held(&ifibss->mtx); 57 sdata_assert_lock(sdata);
58 58
59 /* Reset own TSF to allow time synchronization work. */ 59 /* Reset own TSF to allow time synchronization work. */
60 drv_reset_tsf(local, sdata); 60 drv_reset_tsf(local, sdata);
@@ -74,7 +74,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
74 } 74 }
75 75
76 presp = rcu_dereference_protected(ifibss->presp, 76 presp = rcu_dereference_protected(ifibss->presp,
77 lockdep_is_held(&ifibss->mtx)); 77 lockdep_is_held(&sdata->wdev.mtx));
78 rcu_assign_pointer(ifibss->presp, NULL); 78 rcu_assign_pointer(ifibss->presp, NULL);
79 if (presp) 79 if (presp)
80 kfree_rcu(presp, rcu_head); 80 kfree_rcu(presp, rcu_head);
@@ -263,7 +263,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
263 const struct cfg80211_bss_ies *ies; 263 const struct cfg80211_bss_ies *ies;
264 u64 tsf; 264 u64 tsf;
265 265
266 lockdep_assert_held(&sdata->u.ibss.mtx); 266 sdata_assert_lock(sdata);
267 267
268 if (beacon_int < 10) 268 if (beacon_int < 10)
269 beacon_int = 10; 269 beacon_int = 10;
@@ -410,7 +410,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
410 struct sta_info *sta; 410 struct sta_info *sta;
411 u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 411 u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
412 412
413 lockdep_assert_held(&sdata->u.ibss.mtx); 413 sdata_assert_lock(sdata);
414 414
415 if (len < 24 + 6) 415 if (len < 24 + 6)
416 return; 416 return;
@@ -677,7 +677,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
677 int active = 0; 677 int active = 0;
678 struct sta_info *sta; 678 struct sta_info *sta;
679 679
680 lockdep_assert_held(&sdata->u.ibss.mtx); 680 sdata_assert_lock(sdata);
681 681
682 rcu_read_lock(); 682 rcu_read_lock();
683 683
@@ -703,7 +703,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
703{ 703{
704 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 704 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
705 705
706 lockdep_assert_held(&ifibss->mtx); 706 sdata_assert_lock(sdata);
707 707
708 mod_timer(&ifibss->timer, 708 mod_timer(&ifibss->timer,
709 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); 709 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
@@ -734,7 +734,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
734 u16 capability; 734 u16 capability;
735 int i; 735 int i;
736 736
737 lockdep_assert_held(&ifibss->mtx); 737 sdata_assert_lock(sdata);
738 738
739 if (ifibss->fixed_bssid) { 739 if (ifibss->fixed_bssid) {
740 memcpy(bssid, ifibss->bssid, ETH_ALEN); 740 memcpy(bssid, ifibss->bssid, ETH_ALEN);
@@ -777,7 +777,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
777 int active_ibss; 777 int active_ibss;
778 u16 capability; 778 u16 capability;
779 779
780 lockdep_assert_held(&ifibss->mtx); 780 sdata_assert_lock(sdata);
781 781
782 active_ibss = ieee80211_sta_active_ibss(sdata); 782 active_ibss = ieee80211_sta_active_ibss(sdata);
783 ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss); 783 ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss);
@@ -847,10 +847,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
847 struct beacon_data *presp; 847 struct beacon_data *presp;
848 u8 *pos, *end; 848 u8 *pos, *end;
849 849
850 lockdep_assert_held(&ifibss->mtx); 850 sdata_assert_lock(sdata);
851 851
852 presp = rcu_dereference_protected(ifibss->presp, 852 presp = rcu_dereference_protected(ifibss->presp,
853 lockdep_is_held(&ifibss->mtx)); 853 lockdep_is_held(&sdata->wdev.mtx));
854 854
855 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || 855 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
856 len < 24 + 2 || !presp) 856 len < 24 + 2 || !presp)
@@ -934,7 +934,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
934 mgmt = (struct ieee80211_mgmt *) skb->data; 934 mgmt = (struct ieee80211_mgmt *) skb->data;
935 fc = le16_to_cpu(mgmt->frame_control); 935 fc = le16_to_cpu(mgmt->frame_control);
936 936
937 mutex_lock(&sdata->u.ibss.mtx); 937 sdata_lock(sdata);
938 938
939 if (!sdata->u.ibss.ssid_len) 939 if (!sdata->u.ibss.ssid_len)
940 goto mgmt_out; /* not ready to merge yet */ 940 goto mgmt_out; /* not ready to merge yet */
@@ -957,7 +957,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
957 } 957 }
958 958
959 mgmt_out: 959 mgmt_out:
960 mutex_unlock(&sdata->u.ibss.mtx); 960 sdata_unlock(sdata);
961} 961}
962 962
963void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) 963void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
@@ -965,7 +965,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
965 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 965 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
966 struct sta_info *sta; 966 struct sta_info *sta;
967 967
968 mutex_lock(&ifibss->mtx); 968 sdata_lock(sdata);
969 969
970 /* 970 /*
971 * Work could be scheduled after scan or similar 971 * Work could be scheduled after scan or similar
@@ -1001,7 +1001,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
1001 } 1001 }
1002 1002
1003 out: 1003 out:
1004 mutex_unlock(&ifibss->mtx); 1004 sdata_unlock(sdata);
1005} 1005}
1006 1006
1007static void ieee80211_ibss_timer(unsigned long data) 1007static void ieee80211_ibss_timer(unsigned long data)
@@ -1018,7 +1018,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
1018 1018
1019 setup_timer(&ifibss->timer, ieee80211_ibss_timer, 1019 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
1020 (unsigned long) sdata); 1020 (unsigned long) sdata);
1021 mutex_init(&ifibss->mtx);
1022 INIT_LIST_HEAD(&ifibss->incomplete_stations); 1021 INIT_LIST_HEAD(&ifibss->incomplete_stations);
1023 spin_lock_init(&ifibss->incomplete_lock); 1022 spin_lock_init(&ifibss->incomplete_lock);
1024} 1023}
@@ -1045,8 +1044,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1045{ 1044{
1046 u32 changed = 0; 1045 u32 changed = 0;
1047 1046
1048 mutex_lock(&sdata->u.ibss.mtx);
1049
1050 if (params->bssid) { 1047 if (params->bssid) {
1051 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); 1048 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
1052 sdata->u.ibss.fixed_bssid = true; 1049 sdata->u.ibss.fixed_bssid = true;
@@ -1079,8 +1076,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1079 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); 1076 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
1080 sdata->u.ibss.ssid_len = params->ssid_len; 1077 sdata->u.ibss.ssid_len = params->ssid_len;
1081 1078
1082 mutex_unlock(&sdata->u.ibss.mtx);
1083
1084 /* 1079 /*
1085 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is 1080 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is
1086 * reserved, but an HT STA shall protect HT transmissions as though 1081 * reserved, but an HT STA shall protect HT transmissions as though
@@ -1116,8 +1111,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1116 struct sta_info *sta; 1111 struct sta_info *sta;
1117 struct beacon_data *presp; 1112 struct beacon_data *presp;
1118 1113
1119 mutex_lock(&sdata->u.ibss.mtx);
1120
1121 active_ibss = ieee80211_sta_active_ibss(sdata); 1114 active_ibss = ieee80211_sta_active_ibss(sdata);
1122 1115
1123 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { 1116 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
@@ -1161,7 +1154,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1161 /* remove beacon */ 1154 /* remove beacon */
1162 kfree(sdata->u.ibss.ie); 1155 kfree(sdata->u.ibss.ie);
1163 presp = rcu_dereference_protected(ifibss->presp, 1156 presp = rcu_dereference_protected(ifibss->presp,
1164 lockdep_is_held(&sdata->u.ibss.mtx)); 1157 lockdep_is_held(&sdata->wdev.mtx));
1165 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); 1158 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
1166 sdata->vif.bss_conf.ibss_joined = false; 1159 sdata->vif.bss_conf.ibss_joined = false;
1167 sdata->vif.bss_conf.ibss_creator = false; 1160 sdata->vif.bss_conf.ibss_creator = false;
@@ -1177,7 +1170,5 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1177 1170
1178 del_timer_sync(&sdata->u.ibss.timer); 1171 del_timer_sync(&sdata->u.ibss.timer);
1179 1172
1180 mutex_unlock(&sdata->u.ibss.mtx);
1181
1182 return 0; 1173 return 0;
1183} 1174}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ba3cd284d104..9eed6f1d1614 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -394,7 +394,6 @@ struct ieee80211_if_managed {
394 bool nullfunc_failed; 394 bool nullfunc_failed;
395 bool connection_loss; 395 bool connection_loss;
396 396
397 struct mutex mtx;
398 struct cfg80211_bss *associated; 397 struct cfg80211_bss *associated;
399 struct ieee80211_mgd_auth_data *auth_data; 398 struct ieee80211_mgd_auth_data *auth_data;
400 struct ieee80211_mgd_assoc_data *assoc_data; 399 struct ieee80211_mgd_assoc_data *assoc_data;
@@ -488,8 +487,6 @@ struct ieee80211_if_managed {
488struct ieee80211_if_ibss { 487struct ieee80211_if_ibss {
489 struct timer_list timer; 488 struct timer_list timer;
490 489
491 struct mutex mtx;
492
493 unsigned long last_scan_completed; 490 unsigned long last_scan_completed;
494 491
495 u32 basic_rates; 492 u32 basic_rates;
@@ -580,8 +577,6 @@ struct ieee80211_if_mesh {
580 bool accepting_plinks; 577 bool accepting_plinks;
581 int num_gates; 578 int num_gates;
582 struct beacon_data __rcu *beacon; 579 struct beacon_data __rcu *beacon;
583 /* just protects beacon updates for now */
584 struct mutex mtx;
585 const u8 *ie; 580 const u8 *ie;
586 u8 ie_len; 581 u8 ie_len;
587 enum { 582 enum {
@@ -778,6 +773,26 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
778 return container_of(p, struct ieee80211_sub_if_data, vif); 773 return container_of(p, struct ieee80211_sub_if_data, vif);
779} 774}
780 775
776static inline void sdata_lock(struct ieee80211_sub_if_data *sdata)
777 __acquires(&sdata->wdev.mtx)
778{
779 mutex_lock(&sdata->wdev.mtx);
780 __acquire(&sdata->wdev.mtx);
781}
782
783static inline void sdata_unlock(struct ieee80211_sub_if_data *sdata)
784 __releases(&sdata->wdev.mtx)
785{
786 mutex_unlock(&sdata->wdev.mtx);
787 __release(&sdata->wdev.mtx);
788}
789
790static inline void
791sdata_assert_lock(struct ieee80211_sub_if_data *sdata)
792{
793 lockdep_assert_held(&sdata->wdev.mtx);
794}
795
781static inline enum ieee80211_band 796static inline enum ieee80211_band
782ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata) 797ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
783{ 798{
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 8a7bfc47d577..1998f1475267 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -331,7 +331,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
331 return NOTIFY_DONE; 331 return NOTIFY_DONE;
332 332
333 ifmgd = &sdata->u.mgd; 333 ifmgd = &sdata->u.mgd;
334 mutex_lock(&ifmgd->mtx); 334 sdata_lock(sdata);
335 335
336 /* Copy the addresses to the bss_conf list */ 336 /* Copy the addresses to the bss_conf list */
337 ifa = idev->ifa_list; 337 ifa = idev->ifa_list;
@@ -349,7 +349,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
349 ieee80211_bss_info_change_notify(sdata, 349 ieee80211_bss_info_change_notify(sdata,
350 BSS_CHANGED_ARP_FILTER); 350 BSS_CHANGED_ARP_FILTER);
351 351
352 mutex_unlock(&ifmgd->mtx); 352 sdata_unlock(sdata);
353 353
354 return NOTIFY_DONE; 354 return NOTIFY_DONE;
355} 355}
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c14bb816c6a3..b3d1fdd46368 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -161,8 +161,11 @@ void mesh_sta_cleanup(struct sta_info *sta)
161 del_timer_sync(&sta->plink_timer); 161 del_timer_sync(&sta->plink_timer);
162 } 162 }
163 163
164 if (changed) 164 if (changed) {
165 sdata_lock(sdata);
165 ieee80211_mbss_info_change_notify(sdata, changed); 166 ieee80211_mbss_info_change_notify(sdata, changed);
167 sdata_unlock(sdata);
168 }
166} 169}
167 170
168int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 171int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -577,7 +580,9 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
577 mesh_path_expire(sdata); 580 mesh_path_expire(sdata);
578 581
579 changed = mesh_accept_plinks_update(sdata); 582 changed = mesh_accept_plinks_update(sdata);
583 sdata_lock(sdata);
580 ieee80211_mbss_info_change_notify(sdata, changed); 584 ieee80211_mbss_info_change_notify(sdata, changed);
585 sdata_unlock(sdata);
581 586
582 mod_timer(&ifmsh->housekeeping_timer, 587 mod_timer(&ifmsh->housekeeping_timer,
583 round_jiffies(jiffies + 588 round_jiffies(jiffies +
@@ -697,25 +702,21 @@ out_free:
697} 702}
698 703
699static int 704static int
700ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) 705ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata)
701{ 706{
702 struct beacon_data *old_bcn; 707 struct beacon_data *old_bcn;
703 int ret; 708 int ret;
704 709
705 mutex_lock(&ifmsh->mtx); 710 old_bcn = rcu_dereference_protected(sdata->u.mesh.beacon,
706 711 lockdep_is_held(&sdata->wdev.mtx));
707 old_bcn = rcu_dereference_protected(ifmsh->beacon, 712 ret = ieee80211_mesh_build_beacon(&sdata->u.mesh);
708 lockdep_is_held(&ifmsh->mtx));
709 ret = ieee80211_mesh_build_beacon(ifmsh);
710 if (ret) 713 if (ret)
711 /* just reuse old beacon */ 714 /* just reuse old beacon */
712 goto out; 715 return ret;
713 716
714 if (old_bcn) 717 if (old_bcn)
715 kfree_rcu(old_bcn, rcu_head); 718 kfree_rcu(old_bcn, rcu_head);
716out: 719 return 0;
717 mutex_unlock(&ifmsh->mtx);
718 return ret;
719} 720}
720 721
721void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, 722void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
@@ -726,7 +727,7 @@ void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
726 BSS_CHANGED_HT | 727 BSS_CHANGED_HT |
727 BSS_CHANGED_BASIC_RATES | 728 BSS_CHANGED_BASIC_RATES |
728 BSS_CHANGED_BEACON_INT))) 729 BSS_CHANGED_BEACON_INT)))
729 if (ieee80211_mesh_rebuild_beacon(&sdata->u.mesh)) 730 if (ieee80211_mesh_rebuild_beacon(sdata))
730 return; 731 return;
731 ieee80211_bss_info_change_notify(sdata, changed); 732 ieee80211_bss_info_change_notify(sdata, changed);
732} 733}
@@ -788,12 +789,12 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
788 sdata->vif.bss_conf.enable_beacon = false; 789 sdata->vif.bss_conf.enable_beacon = false;
789 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 790 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
790 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 791 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
791 mutex_lock(&ifmsh->mtx); 792 sdata_lock(sdata);
792 bcn = rcu_dereference_protected(ifmsh->beacon, 793 bcn = rcu_dereference_protected(ifmsh->beacon,
793 lockdep_is_held(&ifmsh->mtx)); 794 lockdep_is_held(&sdata->wdev.mtx));
794 rcu_assign_pointer(ifmsh->beacon, NULL); 795 rcu_assign_pointer(ifmsh->beacon, NULL);
795 kfree_rcu(bcn, rcu_head); 796 kfree_rcu(bcn, rcu_head);
796 mutex_unlock(&ifmsh->mtx); 797 sdata_unlock(sdata);
797 798
798 /* flush STAs and mpaths on this iface */ 799 /* flush STAs and mpaths on this iface */
799 sta_info_flush(sdata); 800 sta_info_flush(sdata);
@@ -1041,7 +1042,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
1041 spin_lock_init(&ifmsh->mesh_preq_queue_lock); 1042 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
1042 spin_lock_init(&ifmsh->sync_offset_lock); 1043 spin_lock_init(&ifmsh->sync_offset_lock);
1043 RCU_INIT_POINTER(ifmsh->beacon, NULL); 1044 RCU_INIT_POINTER(ifmsh->beacon, NULL);
1044 mutex_init(&ifmsh->mtx);
1045 1045
1046 sdata->vif.bss_conf.bssid = zero_addr; 1046 sdata->vif.bss_conf.bssid = zero_addr;
1047} 1047}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 09bebed99416..6c4da99bc4fb 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -517,7 +517,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
517 ieee80211_mps_frame_release(sta, elems); 517 ieee80211_mps_frame_release(sta, elems);
518out: 518out:
519 rcu_read_unlock(); 519 rcu_read_unlock();
520 sdata_lock(sdata);
520 ieee80211_mbss_info_change_notify(sdata, changed); 521 ieee80211_mbss_info_change_notify(sdata, changed);
522 sdata_unlock(sdata);
521} 523}
522 524
523static void mesh_plink_timer(unsigned long data) 525static void mesh_plink_timer(unsigned long data)
@@ -1068,6 +1070,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
1068 1070
1069 rcu_read_unlock(); 1071 rcu_read_unlock();
1070 1072
1071 if (changed) 1073 if (changed) {
1074 sdata_lock(sdata);
1072 ieee80211_mbss_info_change_notify(sdata, changed); 1075 ieee80211_mbss_info_change_notify(sdata, changed);
1076 sdata_unlock(sdata);
1077 }
1073} 1078}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1da3d6be8e11..f44f4caa69ee 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -91,41 +91,6 @@ MODULE_PARM_DESC(probe_wait_ms,
91#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 91#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
92 92
93/* 93/*
94 * All cfg80211 functions have to be called outside a locked
95 * section so that they can acquire a lock themselves... This
96 * is much simpler than queuing up things in cfg80211, but we
97 * do need some indirection for that here.
98 */
99enum rx_mgmt_action {
100 /* no action required */
101 RX_MGMT_NONE,
102
103 /* caller must call cfg80211_send_deauth() */
104 RX_MGMT_CFG80211_DEAUTH,
105
106 /* caller must call cfg80211_send_disassoc() */
107 RX_MGMT_CFG80211_DISASSOC,
108
109 /* caller must call cfg80211_send_rx_auth() */
110 RX_MGMT_CFG80211_RX_AUTH,
111
112 /* caller must call cfg80211_send_rx_assoc() */
113 RX_MGMT_CFG80211_RX_ASSOC,
114
115 /* caller must call cfg80211_send_assoc_timeout() */
116 RX_MGMT_CFG80211_ASSOC_TIMEOUT,
117
118 /* used when a processed beacon causes a deauth */
119 RX_MGMT_CFG80211_TX_DEAUTH,
120};
121
122/* utils */
123static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
124{
125 lockdep_assert_held(&ifmgd->mtx);
126}
127
128/*
129 * We can have multiple work items (and connection probing) 94 * We can have multiple work items (and connection probing)
130 * scheduling this timer, but we need to take care to only 95 * scheduling this timer, but we need to take care to only
131 * reschedule it when it should fire _earlier_ than it was 96 * reschedule it when it should fire _earlier_ than it was
@@ -135,13 +100,14 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
135 * has happened -- the work that runs from this timer will 100 * has happened -- the work that runs from this timer will
136 * do that. 101 * do that.
137 */ 102 */
138static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout) 103static void run_again(struct ieee80211_sub_if_data *sdata,
104 unsigned long timeout)
139{ 105{
140 ASSERT_MGD_MTX(ifmgd); 106 sdata_assert_lock(sdata);
141 107
142 if (!timer_pending(&ifmgd->timer) || 108 if (!timer_pending(&sdata->u.mgd.timer) ||
143 time_before(timeout, ifmgd->timer.expires)) 109 time_before(timeout, sdata->u.mgd.timer.expires))
144 mod_timer(&ifmgd->timer, timeout); 110 mod_timer(&sdata->u.mgd.timer, timeout);
145} 111}
146 112
147void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) 113void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
@@ -652,7 +618,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
652 struct ieee80211_channel *chan; 618 struct ieee80211_channel *chan;
653 u32 rates = 0; 619 u32 rates = 0;
654 620
655 lockdep_assert_held(&ifmgd->mtx); 621 sdata_assert_lock(sdata);
656 622
657 rcu_read_lock(); 623 rcu_read_lock();
658 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 624 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
@@ -962,7 +928,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
962 if (!ieee80211_sdata_running(sdata)) 928 if (!ieee80211_sdata_running(sdata))
963 return; 929 return;
964 930
965 mutex_lock(&ifmgd->mtx); 931 sdata_lock(sdata);
966 if (!ifmgd->associated) 932 if (!ifmgd->associated)
967 goto out; 933 goto out;
968 934
@@ -985,7 +951,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
985 IEEE80211_QUEUE_STOP_REASON_CSA); 951 IEEE80211_QUEUE_STOP_REASON_CSA);
986 out: 952 out:
987 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 953 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
988 mutex_unlock(&ifmgd->mtx); 954 sdata_unlock(sdata);
989} 955}
990 956
991void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) 957void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
@@ -1036,7 +1002,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1036 const struct ieee80211_ht_operation *ht_oper; 1002 const struct ieee80211_ht_operation *ht_oper;
1037 int secondary_channel_offset = -1; 1003 int secondary_channel_offset = -1;
1038 1004
1039 ASSERT_MGD_MTX(ifmgd); 1005 sdata_assert_lock(sdata);
1040 1006
1041 if (!cbss) 1007 if (!cbss)
1042 return; 1008 return;
@@ -1845,7 +1811,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1845 struct ieee80211_local *local = sdata->local; 1811 struct ieee80211_local *local = sdata->local;
1846 u32 changed = 0; 1812 u32 changed = 0;
1847 1813
1848 ASSERT_MGD_MTX(ifmgd); 1814 sdata_assert_lock(sdata);
1849 1815
1850 if (WARN_ON_ONCE(tx && !frame_buf)) 1816 if (WARN_ON_ONCE(tx && !frame_buf))
1851 return; 1817 return;
@@ -2054,7 +2020,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
2054 } 2020 }
2055 2021
2056 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 2022 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
2057 run_again(ifmgd, ifmgd->probe_timeout); 2023 run_again(sdata, ifmgd->probe_timeout);
2058 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 2024 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
2059 ieee80211_flush_queues(sdata->local, sdata); 2025 ieee80211_flush_queues(sdata->local, sdata);
2060} 2026}
@@ -2068,7 +2034,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
2068 if (!ieee80211_sdata_running(sdata)) 2034 if (!ieee80211_sdata_running(sdata))
2069 return; 2035 return;
2070 2036
2071 mutex_lock(&ifmgd->mtx); 2037 sdata_lock(sdata);
2072 2038
2073 if (!ifmgd->associated) 2039 if (!ifmgd->associated)
2074 goto out; 2040 goto out;
@@ -2122,7 +2088,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
2122 ifmgd->probe_send_count = 0; 2088 ifmgd->probe_send_count = 0;
2123 ieee80211_mgd_probe_ap_send(sdata); 2089 ieee80211_mgd_probe_ap_send(sdata);
2124 out: 2090 out:
2125 mutex_unlock(&ifmgd->mtx); 2091 sdata_unlock(sdata);
2126} 2092}
2127 2093
2128struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, 2094struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
@@ -2138,7 +2104,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
2138 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) 2104 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
2139 return NULL; 2105 return NULL;
2140 2106
2141 ASSERT_MGD_MTX(ifmgd); 2107 sdata_assert_lock(sdata);
2142 2108
2143 if (ifmgd->associated) 2109 if (ifmgd->associated)
2144 cbss = ifmgd->associated; 2110 cbss = ifmgd->associated;
@@ -2171,9 +2137,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2171 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2137 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2172 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 2138 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
2173 2139
2174 mutex_lock(&ifmgd->mtx); 2140 sdata_lock(sdata);
2175 if (!ifmgd->associated) { 2141 if (!ifmgd->associated) {
2176 mutex_unlock(&ifmgd->mtx); 2142 sdata_unlock(sdata);
2177 return; 2143 return;
2178 } 2144 }
2179 2145
@@ -2184,13 +2150,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2184 ieee80211_wake_queues_by_reason(&sdata->local->hw, 2150 ieee80211_wake_queues_by_reason(&sdata->local->hw,
2185 IEEE80211_MAX_QUEUE_MAP, 2151 IEEE80211_MAX_QUEUE_MAP,
2186 IEEE80211_QUEUE_STOP_REASON_CSA); 2152 IEEE80211_QUEUE_STOP_REASON_CSA);
2187 mutex_unlock(&ifmgd->mtx);
2188 2153
2189 /*
2190 * must be outside lock due to cfg80211,
2191 * but that's not a problem.
2192 */
2193 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 2154 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
2155 sdata_unlock(sdata);
2194} 2156}
2195 2157
2196static void ieee80211_beacon_connection_loss_work(struct work_struct *work) 2158static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
@@ -2257,7 +2219,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
2257{ 2219{
2258 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data; 2220 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
2259 2221
2260 lockdep_assert_held(&sdata->u.mgd.mtx); 2222 sdata_assert_lock(sdata);
2261 2223
2262 if (!assoc) { 2224 if (!assoc) {
2263 sta_info_destroy_addr(sdata, auth_data->bss->bssid); 2225 sta_info_destroy_addr(sdata, auth_data->bss->bssid);
@@ -2298,27 +2260,26 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
2298 auth_data->key_idx, tx_flags); 2260 auth_data->key_idx, tx_flags);
2299} 2261}
2300 2262
2301static enum rx_mgmt_action __must_check 2263static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2302ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, 2264 struct ieee80211_mgmt *mgmt, size_t len)
2303 struct ieee80211_mgmt *mgmt, size_t len)
2304{ 2265{
2305 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2266 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2306 u8 bssid[ETH_ALEN]; 2267 u8 bssid[ETH_ALEN];
2307 u16 auth_alg, auth_transaction, status_code; 2268 u16 auth_alg, auth_transaction, status_code;
2308 struct sta_info *sta; 2269 struct sta_info *sta;
2309 2270
2310 lockdep_assert_held(&ifmgd->mtx); 2271 sdata_assert_lock(sdata);
2311 2272
2312 if (len < 24 + 6) 2273 if (len < 24 + 6)
2313 return RX_MGMT_NONE; 2274 return;
2314 2275
2315 if (!ifmgd->auth_data || ifmgd->auth_data->done) 2276 if (!ifmgd->auth_data || ifmgd->auth_data->done)
2316 return RX_MGMT_NONE; 2277 return;
2317 2278
2318 memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); 2279 memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
2319 2280
2320 if (!ether_addr_equal(bssid, mgmt->bssid)) 2281 if (!ether_addr_equal(bssid, mgmt->bssid))
2321 return RX_MGMT_NONE; 2282 return;
2322 2283
2323 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); 2284 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
2324 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 2285 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
@@ -2330,14 +2291,15 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2330 mgmt->sa, auth_alg, ifmgd->auth_data->algorithm, 2291 mgmt->sa, auth_alg, ifmgd->auth_data->algorithm,
2331 auth_transaction, 2292 auth_transaction,
2332 ifmgd->auth_data->expected_transaction); 2293 ifmgd->auth_data->expected_transaction);
2333 return RX_MGMT_NONE; 2294 return;
2334 } 2295 }
2335 2296
2336 if (status_code != WLAN_STATUS_SUCCESS) { 2297 if (status_code != WLAN_STATUS_SUCCESS) {
2337 sdata_info(sdata, "%pM denied authentication (status %d)\n", 2298 sdata_info(sdata, "%pM denied authentication (status %d)\n",
2338 mgmt->sa, status_code); 2299 mgmt->sa, status_code);
2339 ieee80211_destroy_auth_data(sdata, false); 2300 ieee80211_destroy_auth_data(sdata, false);
2340 return RX_MGMT_CFG80211_RX_AUTH; 2301 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
2302 return;
2341 } 2303 }
2342 2304
2343 switch (ifmgd->auth_data->algorithm) { 2305 switch (ifmgd->auth_data->algorithm) {
@@ -2350,20 +2312,20 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2350 if (ifmgd->auth_data->expected_transaction != 4) { 2312 if (ifmgd->auth_data->expected_transaction != 4) {
2351 ieee80211_auth_challenge(sdata, mgmt, len); 2313 ieee80211_auth_challenge(sdata, mgmt, len);
2352 /* need another frame */ 2314 /* need another frame */
2353 return RX_MGMT_NONE; 2315 return;
2354 } 2316 }
2355 break; 2317 break;
2356 default: 2318 default:
2357 WARN_ONCE(1, "invalid auth alg %d", 2319 WARN_ONCE(1, "invalid auth alg %d",
2358 ifmgd->auth_data->algorithm); 2320 ifmgd->auth_data->algorithm);
2359 return RX_MGMT_NONE; 2321 return;
2360 } 2322 }
2361 2323
2362 sdata_info(sdata, "authenticated\n"); 2324 sdata_info(sdata, "authenticated\n");
2363 ifmgd->auth_data->done = true; 2325 ifmgd->auth_data->done = true;
2364 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; 2326 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
2365 ifmgd->auth_data->timeout_started = true; 2327 ifmgd->auth_data->timeout_started = true;
2366 run_again(ifmgd, ifmgd->auth_data->timeout); 2328 run_again(sdata, ifmgd->auth_data->timeout);
2367 2329
2368 if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && 2330 if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
2369 ifmgd->auth_data->expected_transaction != 2) { 2331 ifmgd->auth_data->expected_transaction != 2) {
@@ -2371,7 +2333,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2371 * Report auth frame to user space for processing since another 2333 * Report auth frame to user space for processing since another
2372 * round of Authentication frames is still needed. 2334 * round of Authentication frames is still needed.
2373 */ 2335 */
2374 return RX_MGMT_CFG80211_RX_AUTH; 2336 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
2337 return;
2375 } 2338 }
2376 2339
2377 /* move station state to auth */ 2340 /* move station state to auth */
@@ -2387,30 +2350,29 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2387 } 2350 }
2388 mutex_unlock(&sdata->local->sta_mtx); 2351 mutex_unlock(&sdata->local->sta_mtx);
2389 2352
2390 return RX_MGMT_CFG80211_RX_AUTH; 2353 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
2354 return;
2391 out_err: 2355 out_err:
2392 mutex_unlock(&sdata->local->sta_mtx); 2356 mutex_unlock(&sdata->local->sta_mtx);
2393 /* ignore frame -- wait for timeout */ 2357 /* ignore frame -- wait for timeout */
2394 return RX_MGMT_NONE;
2395} 2358}
2396 2359
2397 2360
2398static enum rx_mgmt_action __must_check 2361static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2399ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 2362 struct ieee80211_mgmt *mgmt, size_t len)
2400 struct ieee80211_mgmt *mgmt, size_t len)
2401{ 2363{
2402 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2364 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2403 const u8 *bssid = NULL; 2365 const u8 *bssid = NULL;
2404 u16 reason_code; 2366 u16 reason_code;
2405 2367
2406 lockdep_assert_held(&ifmgd->mtx); 2368 sdata_assert_lock(sdata);
2407 2369
2408 if (len < 24 + 2) 2370 if (len < 24 + 2)
2409 return RX_MGMT_NONE; 2371 return;
2410 2372
2411 if (!ifmgd->associated || 2373 if (!ifmgd->associated ||
2412 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) 2374 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
2413 return RX_MGMT_NONE; 2375 return;
2414 2376
2415 bssid = ifmgd->associated->bssid; 2377 bssid = ifmgd->associated->bssid;
2416 2378
@@ -2421,25 +2383,24 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2421 2383
2422 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2384 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2423 2385
2424 return RX_MGMT_CFG80211_DEAUTH; 2386 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, len);
2425} 2387}
2426 2388
2427 2389
2428static enum rx_mgmt_action __must_check 2390static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
2429ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, 2391 struct ieee80211_mgmt *mgmt, size_t len)
2430 struct ieee80211_mgmt *mgmt, size_t len)
2431{ 2392{
2432 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2393 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2433 u16 reason_code; 2394 u16 reason_code;
2434 2395
2435 lockdep_assert_held(&ifmgd->mtx); 2396 sdata_assert_lock(sdata);
2436 2397
2437 if (len < 24 + 2) 2398 if (len < 24 + 2)
2438 return RX_MGMT_NONE; 2399 return;
2439 2400
2440 if (!ifmgd->associated || 2401 if (!ifmgd->associated ||
2441 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) 2402 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
2442 return RX_MGMT_NONE; 2403 return;
2443 2404
2444 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 2405 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
2445 2406
@@ -2448,7 +2409,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
2448 2409
2449 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2410 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2450 2411
2451 return RX_MGMT_CFG80211_DISASSOC; 2412 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, len);
2452} 2413}
2453 2414
2454static void ieee80211_get_rates(struct ieee80211_supported_band *sband, 2415static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
@@ -2498,7 +2459,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
2498{ 2459{
2499 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data; 2460 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
2500 2461
2501 lockdep_assert_held(&sdata->u.mgd.mtx); 2462 sdata_assert_lock(sdata);
2502 2463
2503 if (!assoc) { 2464 if (!assoc) {
2504 sta_info_destroy_addr(sdata, assoc_data->bss->bssid); 2465 sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
@@ -2679,10 +2640,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2679 return true; 2640 return true;
2680} 2641}
2681 2642
2682static enum rx_mgmt_action __must_check 2643static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2683ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, 2644 struct ieee80211_mgmt *mgmt,
2684 struct ieee80211_mgmt *mgmt, size_t len, 2645 size_t len)
2685 struct cfg80211_bss **bss)
2686{ 2646{
2687 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2647 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2688 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; 2648 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
@@ -2690,13 +2650,14 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2690 struct ieee802_11_elems elems; 2650 struct ieee802_11_elems elems;
2691 u8 *pos; 2651 u8 *pos;
2692 bool reassoc; 2652 bool reassoc;
2653 struct cfg80211_bss *bss;
2693 2654
2694 lockdep_assert_held(&ifmgd->mtx); 2655 sdata_assert_lock(sdata);
2695 2656
2696 if (!assoc_data) 2657 if (!assoc_data)
2697 return RX_MGMT_NONE; 2658 return;
2698 if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid)) 2659 if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid))
2699 return RX_MGMT_NONE; 2660 return;
2700 2661
2701 /* 2662 /*
2702 * AssocResp and ReassocResp have identical structure, so process both 2663 * AssocResp and ReassocResp have identical structure, so process both
@@ -2704,7 +2665,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2704 */ 2665 */
2705 2666
2706 if (len < 24 + 6) 2667 if (len < 24 + 6)
2707 return RX_MGMT_NONE; 2668 return;
2708 2669
2709 reassoc = ieee80211_is_reassoc_req(mgmt->frame_control); 2670 reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
2710 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); 2671 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
@@ -2731,22 +2692,23 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2731 assoc_data->timeout = jiffies + msecs_to_jiffies(ms); 2692 assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
2732 assoc_data->timeout_started = true; 2693 assoc_data->timeout_started = true;
2733 if (ms > IEEE80211_ASSOC_TIMEOUT) 2694 if (ms > IEEE80211_ASSOC_TIMEOUT)
2734 run_again(ifmgd, assoc_data->timeout); 2695 run_again(sdata, assoc_data->timeout);
2735 return RX_MGMT_NONE; 2696 return;
2736 } 2697 }
2737 2698
2738 *bss = assoc_data->bss; 2699 bss = assoc_data->bss;
2739 2700
2740 if (status_code != WLAN_STATUS_SUCCESS) { 2701 if (status_code != WLAN_STATUS_SUCCESS) {
2741 sdata_info(sdata, "%pM denied association (code=%d)\n", 2702 sdata_info(sdata, "%pM denied association (code=%d)\n",
2742 mgmt->sa, status_code); 2703 mgmt->sa, status_code);
2743 ieee80211_destroy_assoc_data(sdata, false); 2704 ieee80211_destroy_assoc_data(sdata, false);
2744 } else { 2705 } else {
2745 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { 2706 if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
2746 /* oops -- internal error -- send timeout for now */ 2707 /* oops -- internal error -- send timeout for now */
2747 ieee80211_destroy_assoc_data(sdata, false); 2708 ieee80211_destroy_assoc_data(sdata, false);
2748 cfg80211_put_bss(sdata->local->hw.wiphy, *bss); 2709 cfg80211_put_bss(sdata->local->hw.wiphy, bss);
2749 return RX_MGMT_CFG80211_ASSOC_TIMEOUT; 2710 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
2711 return;
2750 } 2712 }
2751 sdata_info(sdata, "associated\n"); 2713 sdata_info(sdata, "associated\n");
2752 2714
@@ -2758,7 +2720,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2758 ieee80211_destroy_assoc_data(sdata, true); 2720 ieee80211_destroy_assoc_data(sdata, true);
2759 } 2721 }
2760 2722
2761 return RX_MGMT_CFG80211_RX_ASSOC; 2723 cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, len);
2762} 2724}
2763 2725
2764static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 2726static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -2772,7 +2734,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2772 struct ieee80211_channel *channel; 2734 struct ieee80211_channel *channel;
2773 bool need_ps = false; 2735 bool need_ps = false;
2774 2736
2775 lockdep_assert_held(&sdata->u.mgd.mtx); 2737 sdata_assert_lock(sdata);
2776 2738
2777 if ((sdata->u.mgd.associated && 2739 if ((sdata->u.mgd.associated &&
2778 ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || 2740 ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) ||
@@ -2831,7 +2793,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2831 2793
2832 ifmgd = &sdata->u.mgd; 2794 ifmgd = &sdata->u.mgd;
2833 2795
2834 ASSERT_MGD_MTX(ifmgd); 2796 sdata_assert_lock(sdata);
2835 2797
2836 if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) 2798 if (!ether_addr_equal(mgmt->da, sdata->vif.addr))
2837 return; /* ignore ProbeResp to foreign address */ 2799 return; /* ignore ProbeResp to foreign address */
@@ -2856,7 +2818,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2856 ifmgd->auth_data->tries = 0; 2818 ifmgd->auth_data->tries = 0;
2857 ifmgd->auth_data->timeout = jiffies; 2819 ifmgd->auth_data->timeout = jiffies;
2858 ifmgd->auth_data->timeout_started = true; 2820 ifmgd->auth_data->timeout_started = true;
2859 run_again(ifmgd, ifmgd->auth_data->timeout); 2821 run_again(sdata, ifmgd->auth_data->timeout);
2860 } 2822 }
2861} 2823}
2862 2824
@@ -2881,10 +2843,9 @@ static const u64 care_about_ies =
2881 (1ULL << WLAN_EID_HT_CAPABILITY) | 2843 (1ULL << WLAN_EID_HT_CAPABILITY) |
2882 (1ULL << WLAN_EID_HT_OPERATION); 2844 (1ULL << WLAN_EID_HT_OPERATION);
2883 2845
2884static enum rx_mgmt_action 2846static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2885ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, 2847 struct ieee80211_mgmt *mgmt, size_t len,
2886 struct ieee80211_mgmt *mgmt, size_t len, 2848 struct ieee80211_rx_status *rx_status)
2887 u8 *deauth_buf, struct ieee80211_rx_status *rx_status)
2888{ 2849{
2889 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2850 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2890 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 2851 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
@@ -2899,24 +2860,25 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2899 u8 erp_value = 0; 2860 u8 erp_value = 0;
2900 u32 ncrc; 2861 u32 ncrc;
2901 u8 *bssid; 2862 u8 *bssid;
2863 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
2902 2864
2903 lockdep_assert_held(&ifmgd->mtx); 2865 sdata_assert_lock(sdata);
2904 2866
2905 /* Process beacon from the current BSS */ 2867 /* Process beacon from the current BSS */
2906 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 2868 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
2907 if (baselen > len) 2869 if (baselen > len)
2908 return RX_MGMT_NONE; 2870 return;
2909 2871
2910 rcu_read_lock(); 2872 rcu_read_lock();
2911 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2873 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2912 if (!chanctx_conf) { 2874 if (!chanctx_conf) {
2913 rcu_read_unlock(); 2875 rcu_read_unlock();
2914 return RX_MGMT_NONE; 2876 return;
2915 } 2877 }
2916 2878
2917 if (rx_status->freq != chanctx_conf->def.chan->center_freq) { 2879 if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
2918 rcu_read_unlock(); 2880 rcu_read_unlock();
2919 return RX_MGMT_NONE; 2881 return;
2920 } 2882 }
2921 chan = chanctx_conf->def.chan; 2883 chan = chanctx_conf->def.chan;
2922 rcu_read_unlock(); 2884 rcu_read_unlock();
@@ -2943,13 +2905,13 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2943 /* continue assoc process */ 2905 /* continue assoc process */
2944 ifmgd->assoc_data->timeout = jiffies; 2906 ifmgd->assoc_data->timeout = jiffies;
2945 ifmgd->assoc_data->timeout_started = true; 2907 ifmgd->assoc_data->timeout_started = true;
2946 run_again(ifmgd, ifmgd->assoc_data->timeout); 2908 run_again(sdata, ifmgd->assoc_data->timeout);
2947 return RX_MGMT_NONE; 2909 return;
2948 } 2910 }
2949 2911
2950 if (!ifmgd->associated || 2912 if (!ifmgd->associated ||
2951 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) 2913 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
2952 return RX_MGMT_NONE; 2914 return;
2953 bssid = ifmgd->associated->bssid; 2915 bssid = ifmgd->associated->bssid;
2954 2916
2955 /* Track average RSSI from the Beacon frames of the current AP */ 2917 /* Track average RSSI from the Beacon frames of the current AP */
@@ -3095,7 +3057,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3095 } 3057 }
3096 3058
3097 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) 3059 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
3098 return RX_MGMT_NONE; 3060 return;
3099 ifmgd->beacon_crc = ncrc; 3061 ifmgd->beacon_crc = ncrc;
3100 ifmgd->beacon_crc_valid = true; 3062 ifmgd->beacon_crc_valid = true;
3101 3063
@@ -3151,7 +3113,9 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3151 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 3113 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
3152 WLAN_REASON_DEAUTH_LEAVING, 3114 WLAN_REASON_DEAUTH_LEAVING,
3153 true, deauth_buf); 3115 true, deauth_buf);
3154 return RX_MGMT_CFG80211_TX_DEAUTH; 3116 cfg80211_send_deauth(sdata->dev, deauth_buf,
3117 sizeof(deauth_buf));
3118 return;
3155 } 3119 }
3156 3120
3157 if (sta && elems.opmode_notif) 3121 if (sta && elems.opmode_notif)
@@ -3168,19 +3132,13 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3168 elems.pwr_constr_elem); 3132 elems.pwr_constr_elem);
3169 3133
3170 ieee80211_bss_info_change_notify(sdata, changed); 3134 ieee80211_bss_info_change_notify(sdata, changed);
3171
3172 return RX_MGMT_NONE;
3173} 3135}
3174 3136
3175void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 3137void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3176 struct sk_buff *skb) 3138 struct sk_buff *skb)
3177{ 3139{
3178 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3179 struct ieee80211_rx_status *rx_status; 3140 struct ieee80211_rx_status *rx_status;
3180 struct ieee80211_mgmt *mgmt; 3141 struct ieee80211_mgmt *mgmt;
3181 struct cfg80211_bss *bss = NULL;
3182 enum rx_mgmt_action rma = RX_MGMT_NONE;
3183 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
3184 u16 fc; 3142 u16 fc;
3185 struct ieee802_11_elems elems; 3143 struct ieee802_11_elems elems;
3186 int ies_len; 3144 int ies_len;
@@ -3189,28 +3147,27 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3189 mgmt = (struct ieee80211_mgmt *) skb->data; 3147 mgmt = (struct ieee80211_mgmt *) skb->data;
3190 fc = le16_to_cpu(mgmt->frame_control); 3148 fc = le16_to_cpu(mgmt->frame_control);
3191 3149
3192 mutex_lock(&ifmgd->mtx); 3150 sdata_lock(sdata);
3193 3151
3194 switch (fc & IEEE80211_FCTL_STYPE) { 3152 switch (fc & IEEE80211_FCTL_STYPE) {
3195 case IEEE80211_STYPE_BEACON: 3153 case IEEE80211_STYPE_BEACON:
3196 rma = ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, 3154 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
3197 deauth_buf, rx_status);
3198 break; 3155 break;
3199 case IEEE80211_STYPE_PROBE_RESP: 3156 case IEEE80211_STYPE_PROBE_RESP:
3200 ieee80211_rx_mgmt_probe_resp(sdata, skb); 3157 ieee80211_rx_mgmt_probe_resp(sdata, skb);
3201 break; 3158 break;
3202 case IEEE80211_STYPE_AUTH: 3159 case IEEE80211_STYPE_AUTH:
3203 rma = ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len); 3160 ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
3204 break; 3161 break;
3205 case IEEE80211_STYPE_DEAUTH: 3162 case IEEE80211_STYPE_DEAUTH:
3206 rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len); 3163 ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
3207 break; 3164 break;
3208 case IEEE80211_STYPE_DISASSOC: 3165 case IEEE80211_STYPE_DISASSOC:
3209 rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); 3166 ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
3210 break; 3167 break;
3211 case IEEE80211_STYPE_ASSOC_RESP: 3168 case IEEE80211_STYPE_ASSOC_RESP:
3212 case IEEE80211_STYPE_REASSOC_RESP: 3169 case IEEE80211_STYPE_REASSOC_RESP:
3213 rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss); 3170 ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len);
3214 break; 3171 break;
3215 case IEEE80211_STYPE_ACTION: 3172 case IEEE80211_STYPE_ACTION:
3216 if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { 3173 if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
@@ -3256,34 +3213,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3256 } 3213 }
3257 break; 3214 break;
3258 } 3215 }
3259 mutex_unlock(&ifmgd->mtx); 3216 sdata_unlock(sdata);
3260
3261 switch (rma) {
3262 case RX_MGMT_NONE:
3263 /* no action */
3264 break;
3265 case RX_MGMT_CFG80211_DEAUTH:
3266 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
3267 break;
3268 case RX_MGMT_CFG80211_DISASSOC:
3269 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
3270 break;
3271 case RX_MGMT_CFG80211_RX_AUTH:
3272 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, skb->len);
3273 break;
3274 case RX_MGMT_CFG80211_RX_ASSOC:
3275 cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, skb->len);
3276 break;
3277 case RX_MGMT_CFG80211_ASSOC_TIMEOUT:
3278 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
3279 break;
3280 case RX_MGMT_CFG80211_TX_DEAUTH:
3281 cfg80211_send_deauth(sdata->dev, deauth_buf,
3282 sizeof(deauth_buf));
3283 break;
3284 default:
3285 WARN(1, "unexpected: %d", rma);
3286 }
3287} 3217}
3288 3218
3289static void ieee80211_sta_timer(unsigned long data) 3219static void ieee80211_sta_timer(unsigned long data)
@@ -3297,20 +3227,12 @@ static void ieee80211_sta_timer(unsigned long data)
3297static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, 3227static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
3298 u8 *bssid, u8 reason, bool tx) 3228 u8 *bssid, u8 reason, bool tx)
3299{ 3229{
3300 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3301 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 3230 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
3302 3231
3303 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, 3232 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
3304 tx, frame_buf); 3233 tx, frame_buf);
3305 mutex_unlock(&ifmgd->mtx);
3306 3234
3307 /*
3308 * must be outside lock due to cfg80211,
3309 * but that's not a problem.
3310 */
3311 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 3235 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
3312
3313 mutex_lock(&ifmgd->mtx);
3314} 3236}
3315 3237
3316static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) 3238static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
@@ -3320,7 +3242,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
3320 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data; 3242 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
3321 u32 tx_flags = 0; 3243 u32 tx_flags = 0;
3322 3244
3323 lockdep_assert_held(&ifmgd->mtx); 3245 sdata_assert_lock(sdata);
3324 3246
3325 if (WARN_ON_ONCE(!auth_data)) 3247 if (WARN_ON_ONCE(!auth_data))
3326 return -EINVAL; 3248 return -EINVAL;
@@ -3393,7 +3315,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
3393 if (tx_flags == 0) { 3315 if (tx_flags == 0) {
3394 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 3316 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
3395 ifmgd->auth_data->timeout_started = true; 3317 ifmgd->auth_data->timeout_started = true;
3396 run_again(ifmgd, auth_data->timeout); 3318 run_again(sdata, auth_data->timeout);
3397 } else { 3319 } else {
3398 auth_data->timeout_started = false; 3320 auth_data->timeout_started = false;
3399 } 3321 }
@@ -3406,7 +3328,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
3406 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data; 3328 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
3407 struct ieee80211_local *local = sdata->local; 3329 struct ieee80211_local *local = sdata->local;
3408 3330
3409 lockdep_assert_held(&sdata->u.mgd.mtx); 3331 sdata_assert_lock(sdata);
3410 3332
3411 assoc_data->tries++; 3333 assoc_data->tries++;
3412 if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { 3334 if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
@@ -3430,7 +3352,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
3430 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { 3352 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
3431 assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; 3353 assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
3432 assoc_data->timeout_started = true; 3354 assoc_data->timeout_started = true;
3433 run_again(&sdata->u.mgd, assoc_data->timeout); 3355 run_again(sdata, assoc_data->timeout);
3434 } else { 3356 } else {
3435 assoc_data->timeout_started = false; 3357 assoc_data->timeout_started = false;
3436 } 3358 }
@@ -3455,7 +3377,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3455 struct ieee80211_local *local = sdata->local; 3377 struct ieee80211_local *local = sdata->local;
3456 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3378 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3457 3379
3458 mutex_lock(&ifmgd->mtx); 3380 sdata_lock(sdata);
3459 3381
3460 if (ifmgd->status_received) { 3382 if (ifmgd->status_received) {
3461 __le16 fc = ifmgd->status_fc; 3383 __le16 fc = ifmgd->status_fc;
@@ -3467,7 +3389,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3467 if (status_acked) { 3389 if (status_acked) {
3468 ifmgd->auth_data->timeout = 3390 ifmgd->auth_data->timeout =
3469 jiffies + IEEE80211_AUTH_TIMEOUT_SHORT; 3391 jiffies + IEEE80211_AUTH_TIMEOUT_SHORT;
3470 run_again(ifmgd, ifmgd->auth_data->timeout); 3392 run_again(sdata, ifmgd->auth_data->timeout);
3471 } else { 3393 } else {
3472 ifmgd->auth_data->timeout = jiffies - 1; 3394 ifmgd->auth_data->timeout = jiffies - 1;
3473 } 3395 }
@@ -3478,7 +3400,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3478 if (status_acked) { 3400 if (status_acked) {
3479 ifmgd->assoc_data->timeout = 3401 ifmgd->assoc_data->timeout =
3480 jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT; 3402 jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT;
3481 run_again(ifmgd, ifmgd->assoc_data->timeout); 3403 run_again(sdata, ifmgd->assoc_data->timeout);
3482 } else { 3404 } else {
3483 ifmgd->assoc_data->timeout = jiffies - 1; 3405 ifmgd->assoc_data->timeout = jiffies - 1;
3484 } 3406 }
@@ -3501,12 +3423,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3501 3423
3502 ieee80211_destroy_auth_data(sdata, false); 3424 ieee80211_destroy_auth_data(sdata, false);
3503 3425
3504 mutex_unlock(&ifmgd->mtx);
3505 cfg80211_send_auth_timeout(sdata->dev, bssid); 3426 cfg80211_send_auth_timeout(sdata->dev, bssid);
3506 mutex_lock(&ifmgd->mtx);
3507 } 3427 }
3508 } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) 3428 } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started)
3509 run_again(ifmgd, ifmgd->auth_data->timeout); 3429 run_again(sdata, ifmgd->auth_data->timeout);
3510 3430
3511 if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && 3431 if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started &&
3512 time_after(jiffies, ifmgd->assoc_data->timeout)) { 3432 time_after(jiffies, ifmgd->assoc_data->timeout)) {
@@ -3519,12 +3439,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3519 3439
3520 ieee80211_destroy_assoc_data(sdata, false); 3440 ieee80211_destroy_assoc_data(sdata, false);
3521 3441
3522 mutex_unlock(&ifmgd->mtx);
3523 cfg80211_send_assoc_timeout(sdata->dev, bssid); 3442 cfg80211_send_assoc_timeout(sdata->dev, bssid);
3524 mutex_lock(&ifmgd->mtx);
3525 } 3443 }
3526 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) 3444 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
3527 run_again(ifmgd, ifmgd->assoc_data->timeout); 3445 run_again(sdata, ifmgd->assoc_data->timeout);
3528 3446
3529 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 3447 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
3530 IEEE80211_STA_CONNECTION_POLL) && 3448 IEEE80211_STA_CONNECTION_POLL) &&
@@ -3558,7 +3476,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3558 false); 3476 false);
3559 } 3477 }
3560 } else if (time_is_after_jiffies(ifmgd->probe_timeout)) 3478 } else if (time_is_after_jiffies(ifmgd->probe_timeout))
3561 run_again(ifmgd, ifmgd->probe_timeout); 3479 run_again(sdata, ifmgd->probe_timeout);
3562 else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { 3480 else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
3563 mlme_dbg(sdata, 3481 mlme_dbg(sdata,
3564 "Failed to send nullfunc to AP %pM after %dms, disconnecting\n", 3482 "Failed to send nullfunc to AP %pM after %dms, disconnecting\n",
@@ -3587,7 +3505,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3587 } 3505 }
3588 } 3506 }
3589 3507
3590 mutex_unlock(&ifmgd->mtx); 3508 sdata_unlock(sdata);
3591} 3509}
3592 3510
3593static void ieee80211_sta_bcn_mon_timer(unsigned long data) 3511static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -3648,9 +3566,9 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
3648{ 3566{
3649 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3567 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3650 3568
3651 mutex_lock(&ifmgd->mtx); 3569 sdata_lock(sdata);
3652 if (!ifmgd->associated) { 3570 if (!ifmgd->associated) {
3653 mutex_unlock(&ifmgd->mtx); 3571 sdata_unlock(sdata);
3654 return; 3572 return;
3655 } 3573 }
3656 3574
@@ -3661,10 +3579,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
3661 ifmgd->associated->bssid, 3579 ifmgd->associated->bssid,
3662 WLAN_REASON_UNSPECIFIED, 3580 WLAN_REASON_UNSPECIFIED,
3663 true); 3581 true);
3664 mutex_unlock(&ifmgd->mtx); 3582 sdata_unlock(sdata);
3665 return; 3583 return;
3666 } 3584 }
3667 mutex_unlock(&ifmgd->mtx); 3585 sdata_unlock(sdata);
3668} 3586}
3669#endif 3587#endif
3670 3588
@@ -3696,8 +3614,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3696 ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len; 3614 ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len;
3697 ifmgd->p2p_noa_index = -1; 3615 ifmgd->p2p_noa_index = -1;
3698 3616
3699 mutex_init(&ifmgd->mtx);
3700
3701 if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) 3617 if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
3702 ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC; 3618 ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
3703 else 3619 else
@@ -4053,8 +3969,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4053 3969
4054 /* try to authenticate/probe */ 3970 /* try to authenticate/probe */
4055 3971
4056 mutex_lock(&ifmgd->mtx);
4057
4058 if ((ifmgd->auth_data && !ifmgd->auth_data->done) || 3972 if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
4059 ifmgd->assoc_data) { 3973 ifmgd->assoc_data) {
4060 err = -EBUSY; 3974 err = -EBUSY;
@@ -4074,8 +3988,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4074 WLAN_REASON_UNSPECIFIED, 3988 WLAN_REASON_UNSPECIFIED,
4075 false, frame_buf); 3989 false, frame_buf);
4076 3990
4077 __cfg80211_send_deauth(sdata->dev, frame_buf, 3991 cfg80211_send_deauth(sdata->dev, frame_buf,
4078 sizeof(frame_buf)); 3992 sizeof(frame_buf));
4079 } 3993 }
4080 3994
4081 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); 3995 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
@@ -4092,8 +4006,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4092 4006
4093 /* hold our own reference */ 4007 /* hold our own reference */
4094 cfg80211_ref_bss(local->hw.wiphy, auth_data->bss); 4008 cfg80211_ref_bss(local->hw.wiphy, auth_data->bss);
4095 err = 0; 4009 return 0;
4096 goto out_unlock;
4097 4010
4098 err_clear: 4011 err_clear:
4099 memset(ifmgd->bssid, 0, ETH_ALEN); 4012 memset(ifmgd->bssid, 0, ETH_ALEN);
@@ -4101,9 +4014,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4101 ifmgd->auth_data = NULL; 4014 ifmgd->auth_data = NULL;
4102 err_free: 4015 err_free:
4103 kfree(auth_data); 4016 kfree(auth_data);
4104 out_unlock:
4105 mutex_unlock(&ifmgd->mtx);
4106
4107 return err; 4017 return err;
4108} 4018}
4109 4019
@@ -4134,8 +4044,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4134 assoc_data->ssid_len = ssidie[1]; 4044 assoc_data->ssid_len = ssidie[1];
4135 rcu_read_unlock(); 4045 rcu_read_unlock();
4136 4046
4137 mutex_lock(&ifmgd->mtx);
4138
4139 if (ifmgd->associated) { 4047 if (ifmgd->associated) {
4140 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 4048 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
4141 4049
@@ -4143,8 +4051,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4143 WLAN_REASON_UNSPECIFIED, 4051 WLAN_REASON_UNSPECIFIED,
4144 false, frame_buf); 4052 false, frame_buf);
4145 4053
4146 __cfg80211_send_deauth(sdata->dev, frame_buf, 4054 cfg80211_send_deauth(sdata->dev, frame_buf,
4147 sizeof(frame_buf)); 4055 sizeof(frame_buf));
4148 } 4056 }
4149 4057
4150 if (ifmgd->auth_data && !ifmgd->auth_data->done) { 4058 if (ifmgd->auth_data && !ifmgd->auth_data->done) {
@@ -4338,7 +4246,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4338 } 4246 }
4339 rcu_read_unlock(); 4247 rcu_read_unlock();
4340 4248
4341 run_again(ifmgd, assoc_data->timeout); 4249 run_again(sdata, assoc_data->timeout);
4342 4250
4343 if (bss->corrupt_data) { 4251 if (bss->corrupt_data) {
4344 char *corrupt_type = "data"; 4252 char *corrupt_type = "data";
@@ -4354,17 +4262,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4354 corrupt_type); 4262 corrupt_type);
4355 } 4263 }
4356 4264
4357 err = 0; 4265 return 0;
4358 goto out;
4359 err_clear: 4266 err_clear:
4360 memset(ifmgd->bssid, 0, ETH_ALEN); 4267 memset(ifmgd->bssid, 0, ETH_ALEN);
4361 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 4268 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
4362 ifmgd->assoc_data = NULL; 4269 ifmgd->assoc_data = NULL;
4363 err_free: 4270 err_free:
4364 kfree(assoc_data); 4271 kfree(assoc_data);
4365 out:
4366 mutex_unlock(&ifmgd->mtx);
4367
4368 return err; 4272 return err;
4369} 4273}
4370 4274
@@ -4376,8 +4280,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4376 bool tx = !req->local_state_change; 4280 bool tx = !req->local_state_change;
4377 bool report_frame = false; 4281 bool report_frame = false;
4378 4282
4379 mutex_lock(&ifmgd->mtx);
4380
4381 sdata_info(sdata, 4283 sdata_info(sdata,
4382 "deauthenticating from %pM by local choice (reason=%d)\n", 4284 "deauthenticating from %pM by local choice (reason=%d)\n",
4383 req->bssid, req->reason_code); 4285 req->bssid, req->reason_code);
@@ -4389,7 +4291,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4389 req->reason_code, tx, 4291 req->reason_code, tx,
4390 frame_buf); 4292 frame_buf);
4391 ieee80211_destroy_auth_data(sdata, false); 4293 ieee80211_destroy_auth_data(sdata, false);
4392 mutex_unlock(&ifmgd->mtx);
4393 4294
4394 report_frame = true; 4295 report_frame = true;
4395 goto out; 4296 goto out;
@@ -4401,12 +4302,11 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4401 req->reason_code, tx, frame_buf); 4302 req->reason_code, tx, frame_buf);
4402 report_frame = true; 4303 report_frame = true;
4403 } 4304 }
4404 mutex_unlock(&ifmgd->mtx);
4405 4305
4406 out: 4306 out:
4407 if (report_frame) 4307 if (report_frame)
4408 __cfg80211_send_deauth(sdata->dev, frame_buf, 4308 cfg80211_send_deauth(sdata->dev, frame_buf,
4409 IEEE80211_DEAUTH_FRAME_LEN); 4309 IEEE80211_DEAUTH_FRAME_LEN);
4410 4310
4411 return 0; 4311 return 0;
4412} 4312}
@@ -4418,18 +4318,14 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4418 u8 bssid[ETH_ALEN]; 4318 u8 bssid[ETH_ALEN];
4419 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 4319 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
4420 4320
4421 mutex_lock(&ifmgd->mtx);
4422
4423 /* 4321 /*
4424 * cfg80211 should catch this ... but it's racy since 4322 * cfg80211 should catch this ... but it's racy since
4425 * we can receive a disassoc frame, process it, hand it 4323 * we can receive a disassoc frame, process it, hand it
4426 * to cfg80211 while that's in a locked section already 4324 * to cfg80211 while that's in a locked section already
4427 * trying to tell us that the user wants to disconnect. 4325 * trying to tell us that the user wants to disconnect.
4428 */ 4326 */
4429 if (ifmgd->associated != req->bss) { 4327 if (ifmgd->associated != req->bss)
4430 mutex_unlock(&ifmgd->mtx);
4431 return -ENOLINK; 4328 return -ENOLINK;
4432 }
4433 4329
4434 sdata_info(sdata, 4330 sdata_info(sdata,
4435 "disassociating from %pM by local choice (reason=%d)\n", 4331 "disassociating from %pM by local choice (reason=%d)\n",
@@ -4439,10 +4335,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4439 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, 4335 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
4440 req->reason_code, !req->local_state_change, 4336 req->reason_code, !req->local_state_change,
4441 frame_buf); 4337 frame_buf);
4442 mutex_unlock(&ifmgd->mtx);
4443 4338
4444 __cfg80211_send_disassoc(sdata->dev, frame_buf, 4339 cfg80211_send_disassoc(sdata->dev, frame_buf,
4445 IEEE80211_DEAUTH_FRAME_LEN); 4340 IEEE80211_DEAUTH_FRAME_LEN);
4446 4341
4447 return 0; 4342 return 0;
4448} 4343}
@@ -4462,13 +4357,13 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
4462 cancel_work_sync(&ifmgd->csa_connection_drop_work); 4357 cancel_work_sync(&ifmgd->csa_connection_drop_work);
4463 cancel_work_sync(&ifmgd->chswitch_work); 4358 cancel_work_sync(&ifmgd->chswitch_work);
4464 4359
4465 mutex_lock(&ifmgd->mtx); 4360 sdata_lock(sdata);
4466 if (ifmgd->assoc_data) 4361 if (ifmgd->assoc_data)
4467 ieee80211_destroy_assoc_data(sdata, false); 4362 ieee80211_destroy_assoc_data(sdata, false);
4468 if (ifmgd->auth_data) 4363 if (ifmgd->auth_data)
4469 ieee80211_destroy_auth_data(sdata, false); 4364 ieee80211_destroy_auth_data(sdata, false);
4470 del_timer_sync(&ifmgd->timer); 4365 del_timer_sync(&ifmgd->timer);
4471 mutex_unlock(&ifmgd->mtx); 4366 sdata_unlock(sdata);
4472} 4367}
4473 4368
4474void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, 4369void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ffdfe4bc89ad..2a8d759324c2 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1581,9 +1581,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1581 if (sdata->u.mgd.dtim_period) 1581 if (sdata->u.mgd.dtim_period)
1582 changed |= BSS_CHANGED_DTIM_PERIOD; 1582 changed |= BSS_CHANGED_DTIM_PERIOD;
1583 1583
1584 mutex_lock(&sdata->u.mgd.mtx); 1584 sdata_lock(sdata);
1585 ieee80211_bss_info_change_notify(sdata, changed); 1585 ieee80211_bss_info_change_notify(sdata, changed);
1586 mutex_unlock(&sdata->u.mgd.mtx); 1586 sdata_unlock(sdata);
1587 break; 1587 break;
1588 case NL80211_IFTYPE_ADHOC: 1588 case NL80211_IFTYPE_ADHOC:
1589 changed |= BSS_CHANGED_IBSS; 1589 changed |= BSS_CHANGED_IBSS;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 68b40f21bc38..80ffb0138919 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -25,12 +25,9 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
26 26
27 trace_cfg80211_send_rx_auth(dev); 27 trace_cfg80211_send_rx_auth(dev);
28 wdev_lock(wdev);
29 28
30 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL); 29 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
31 cfg80211_sme_rx_auth(dev, buf, len); 30 cfg80211_sme_rx_auth(dev, buf, len);
32
33 wdev_unlock(wdev);
34} 31}
35EXPORT_SYMBOL(cfg80211_send_rx_auth); 32EXPORT_SYMBOL(cfg80211_send_rx_auth);
36 33
@@ -46,7 +43,6 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
46 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 43 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
47 44
48 trace_cfg80211_send_rx_assoc(dev, bss); 45 trace_cfg80211_send_rx_assoc(dev, bss);
49 wdev_lock(wdev);
50 46
51 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 47 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
52 48
@@ -59,7 +55,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
59 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 55 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
60 cfg80211_sme_failed_reassoc(wdev)) { 56 cfg80211_sme_failed_reassoc(wdev)) {
61 cfg80211_put_bss(wiphy, bss); 57 cfg80211_put_bss(wiphy, bss);
62 goto out; 58 return;
63 } 59 }
64 60
65 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 61 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
@@ -71,7 +67,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
71 * sme will schedule work that does it later. 67 * sme will schedule work that does it later.
72 */ 68 */
73 cfg80211_put_bss(wiphy, bss); 69 cfg80211_put_bss(wiphy, bss);
74 goto out; 70 return;
75 } 71 }
76 72
77 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { 73 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
@@ -87,13 +83,11 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
87 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 83 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
88 status_code, 84 status_code,
89 status_code == WLAN_STATUS_SUCCESS, bss); 85 status_code == WLAN_STATUS_SUCCESS, bss);
90 out:
91 wdev_unlock(wdev);
92} 86}
93EXPORT_SYMBOL(cfg80211_send_rx_assoc); 87EXPORT_SYMBOL(cfg80211_send_rx_assoc);
94 88
95void __cfg80211_send_deauth(struct net_device *dev, 89void cfg80211_send_deauth(struct net_device *dev,
96 const u8 *buf, size_t len) 90 const u8 *buf, size_t len)
97{ 91{
98 struct wireless_dev *wdev = dev->ieee80211_ptr; 92 struct wireless_dev *wdev = dev->ieee80211_ptr;
99 struct wiphy *wiphy = wdev->wiphy; 93 struct wiphy *wiphy = wdev->wiphy;
@@ -102,7 +96,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
102 const u8 *bssid = mgmt->bssid; 96 const u8 *bssid = mgmt->bssid;
103 bool was_current = false; 97 bool was_current = false;
104 98
105 trace___cfg80211_send_deauth(dev); 99 trace_cfg80211_send_deauth(dev);
106 ASSERT_WDEV_LOCK(wdev); 100 ASSERT_WDEV_LOCK(wdev);
107 101
108 if (wdev->current_bss && 102 if (wdev->current_bss &&
@@ -129,20 +123,10 @@ void __cfg80211_send_deauth(struct net_device *dev,
129 false, NULL); 123 false, NULL);
130 } 124 }
131} 125}
132EXPORT_SYMBOL(__cfg80211_send_deauth);
133
134void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
135{
136 struct wireless_dev *wdev = dev->ieee80211_ptr;
137
138 wdev_lock(wdev);
139 __cfg80211_send_deauth(dev, buf, len);
140 wdev_unlock(wdev);
141}
142EXPORT_SYMBOL(cfg80211_send_deauth); 126EXPORT_SYMBOL(cfg80211_send_deauth);
143 127
144void __cfg80211_send_disassoc(struct net_device *dev, 128void cfg80211_send_disassoc(struct net_device *dev,
145 const u8 *buf, size_t len) 129 const u8 *buf, size_t len)
146{ 130{
147 struct wireless_dev *wdev = dev->ieee80211_ptr; 131 struct wireless_dev *wdev = dev->ieee80211_ptr;
148 struct wiphy *wiphy = wdev->wiphy; 132 struct wiphy *wiphy = wdev->wiphy;
@@ -152,7 +136,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
152 u16 reason_code; 136 u16 reason_code;
153 bool from_ap; 137 bool from_ap;
154 138
155 trace___cfg80211_send_disassoc(dev); 139 trace_cfg80211_send_disassoc(dev);
156 ASSERT_WDEV_LOCK(wdev); 140 ASSERT_WDEV_LOCK(wdev);
157 141
158 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); 142 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
@@ -175,16 +159,6 @@ void __cfg80211_send_disassoc(struct net_device *dev,
175 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); 159 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
176 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 160 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
177} 161}
178EXPORT_SYMBOL(__cfg80211_send_disassoc);
179
180void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
181{
182 struct wireless_dev *wdev = dev->ieee80211_ptr;
183
184 wdev_lock(wdev);
185 __cfg80211_send_disassoc(dev, buf, len);
186 wdev_unlock(wdev);
187}
188EXPORT_SYMBOL(cfg80211_send_disassoc); 162EXPORT_SYMBOL(cfg80211_send_disassoc);
189 163
190void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 164void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
@@ -194,15 +168,12 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
194 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 168 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
195 169
196 trace_cfg80211_send_auth_timeout(dev, addr); 170 trace_cfg80211_send_auth_timeout(dev, addr);
197 wdev_lock(wdev);
198 171
199 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); 172 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
200 if (wdev->sme_state == CFG80211_SME_CONNECTING) 173 if (wdev->sme_state == CFG80211_SME_CONNECTING)
201 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 174 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
202 WLAN_STATUS_UNSPECIFIED_FAILURE, 175 WLAN_STATUS_UNSPECIFIED_FAILURE,
203 false, NULL); 176 false, NULL);
204
205 wdev_unlock(wdev);
206} 177}
207EXPORT_SYMBOL(cfg80211_send_auth_timeout); 178EXPORT_SYMBOL(cfg80211_send_auth_timeout);
208 179
@@ -213,15 +184,12 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
213 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 184 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
214 185
215 trace_cfg80211_send_assoc_timeout(dev, addr); 186 trace_cfg80211_send_assoc_timeout(dev, addr);
216 wdev_lock(wdev);
217 187
218 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 188 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
219 if (wdev->sme_state == CFG80211_SME_CONNECTING) 189 if (wdev->sme_state == CFG80211_SME_CONNECTING)
220 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 190 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
221 WLAN_STATUS_UNSPECIFIED_FAILURE, 191 WLAN_STATUS_UNSPECIFIED_FAILURE,
222 false, NULL); 192 false, NULL);
223
224 wdev_unlock(wdev);
225} 193}
226EXPORT_SYMBOL(cfg80211_send_assoc_timeout); 194EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
227 195
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 5755bc14abbd..23fafeae8a10 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1911,12 +1911,12 @@ TRACE_EVENT(cfg80211_send_rx_assoc,
1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) 1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
1912); 1912);
1913 1913
1914DEFINE_EVENT(netdev_evt_only, __cfg80211_send_deauth, 1914DEFINE_EVENT(netdev_evt_only, cfg80211_send_deauth,
1915 TP_PROTO(struct net_device *netdev), 1915 TP_PROTO(struct net_device *netdev),
1916 TP_ARGS(netdev) 1916 TP_ARGS(netdev)
1917); 1917);
1918 1918
1919DEFINE_EVENT(netdev_evt_only, __cfg80211_send_disassoc, 1919DEFINE_EVENT(netdev_evt_only, cfg80211_send_disassoc,
1920 TP_PROTO(struct net_device *netdev), 1920 TP_PROTO(struct net_device *netdev),
1921 TP_ARGS(netdev) 1921 TP_ARGS(netdev)
1922); 1922);