diff options
-rw-r--r-- | Documentation/DocBook/80211.tmpl | 2 | ||||
-rw-r--r-- | include/net/cfg80211.h | 51 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 4 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 10 | ||||
-rw-r--r-- | net/mac80211/ht.c | 4 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 39 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 25 | ||||
-rw-r--r-- | net/mac80211/main.c | 4 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 32 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 7 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 341 | ||||
-rw-r--r-- | net/mac80211/util.c | 4 | ||||
-rw-r--r-- | net/wireless/mlme.c | 48 | ||||
-rw-r--r-- | net/wireless/trace.h | 4 |
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 | */ |
3429 | void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); | 3441 | void 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 | */ |
3438 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr); | 3451 | void 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 | */ |
3453 | void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, | 3467 | void 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 | */ |
3463 | void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); | 3477 | void 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 | */ |
3475 | void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); | 3490 | void 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 | */ | ||
3485 | void __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 | */ |
3497 | void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); | 3503 | void 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 | */ | ||
3507 | void __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 | ||
437 | void ieee80211_request_smps(struct ieee80211_vif *vif, | 437 | void 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 | ||
963 | void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) | 963 | void 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 | ||
1007 | static void ieee80211_ibss_timer(unsigned long data) | 1007 | static 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 { | |||
488 | struct ieee80211_if_ibss { | 487 | struct 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 | ||
776 | static 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 | |||
783 | static 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 | |||
790 | static inline void | ||
791 | sdata_assert_lock(struct ieee80211_sub_if_data *sdata) | ||
792 | { | ||
793 | lockdep_assert_held(&sdata->wdev.mtx); | ||
794 | } | ||
795 | |||
781 | static inline enum ieee80211_band | 796 | static inline enum ieee80211_band |
782 | ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata) | 797 | ieee80211_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 | ||
168 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) | 171 | int 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 | ||
699 | static int | 704 | static int |
700 | ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) | 705 | ieee80211_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); |
716 | out: | 719 | return 0; |
717 | mutex_unlock(&ifmsh->mtx); | ||
718 | return ret; | ||
719 | } | 720 | } |
720 | 721 | ||
721 | void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 722 | void 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); |
518 | out: | 518 | out: |
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 | ||
523 | static void mesh_plink_timer(unsigned long data) | 525 | static 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 | */ | ||
99 | enum 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 */ | ||
123 | static 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 | */ |
138 | static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout) | 103 | static 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 | ||
147 | void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) | 113 | void 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 | ||
991 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) | 957 | void 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 | ||
2128 | struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | 2094 | struct 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 | ||
2196 | static void ieee80211_beacon_connection_loss_work(struct work_struct *work) | 2158 | static 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 | ||
2301 | static enum rx_mgmt_action __must_check | 2263 | static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, |
2302 | ieee80211_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 | ||
2398 | static enum rx_mgmt_action __must_check | 2361 | static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, |
2399 | ieee80211_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 | ||
2428 | static enum rx_mgmt_action __must_check | 2390 | static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, |
2429 | ieee80211_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 | ||
2454 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, | 2415 | static 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 | ||
2682 | static enum rx_mgmt_action __must_check | 2643 | static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, |
2683 | ieee80211_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 | ||
2764 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 2726 | static 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 | ||
2884 | static enum rx_mgmt_action | 2846 | static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, |
2885 | ieee80211_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 | ||
3175 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 3137 | void 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 | ||
3289 | static void ieee80211_sta_timer(unsigned long data) | 3219 | static void ieee80211_sta_timer(unsigned long data) |
@@ -3297,20 +3227,12 @@ static void ieee80211_sta_timer(unsigned long data) | |||
3297 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | 3227 | static 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 | ||
3316 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | 3238 | static 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 | ||
3593 | static void ieee80211_sta_bcn_mon_timer(unsigned long data) | 3511 | static 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 | ||
4474 | void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | 4369 | void 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 | } |
35 | EXPORT_SYMBOL(cfg80211_send_rx_auth); | 32 | EXPORT_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 | } |
93 | EXPORT_SYMBOL(cfg80211_send_rx_assoc); | 87 | EXPORT_SYMBOL(cfg80211_send_rx_assoc); |
94 | 88 | ||
95 | void __cfg80211_send_deauth(struct net_device *dev, | 89 | void 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 | } |
132 | EXPORT_SYMBOL(__cfg80211_send_deauth); | ||
133 | |||
134 | void 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 | } | ||
142 | EXPORT_SYMBOL(cfg80211_send_deauth); | 126 | EXPORT_SYMBOL(cfg80211_send_deauth); |
143 | 127 | ||
144 | void __cfg80211_send_disassoc(struct net_device *dev, | 128 | void 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 | } |
178 | EXPORT_SYMBOL(__cfg80211_send_disassoc); | ||
179 | |||
180 | void 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 | } | ||
188 | EXPORT_SYMBOL(cfg80211_send_disassoc); | 162 | EXPORT_SYMBOL(cfg80211_send_disassoc); |
189 | 163 | ||
190 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) | 164 | void 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 | } |
207 | EXPORT_SYMBOL(cfg80211_send_auth_timeout); | 178 | EXPORT_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 | } |
226 | EXPORT_SYMBOL(cfg80211_send_assoc_timeout); | 194 | EXPORT_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 | ||
1914 | DEFINE_EVENT(netdev_evt_only, __cfg80211_send_deauth, | 1914 | DEFINE_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 | ||
1919 | DEFINE_EVENT(netdev_evt_only, __cfg80211_send_disassoc, | 1919 | DEFINE_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 | ); |