diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 26 | ||||
-rw-r--r-- | net/mac80211/chan.c | 21 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 7 | ||||
-rw-r--r-- | net/mac80211/iface.c | 6 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 25 | ||||
-rw-r--r-- | net/mac80211/util.c | 8 |
6 files changed, 73 insertions, 20 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bfe54daab4b1..aab3c2f29de3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -828,6 +828,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | |||
828 | if (cfg80211_chandef_identical(&local->monitor_chandef, chandef)) | 828 | if (cfg80211_chandef_identical(&local->monitor_chandef, chandef)) |
829 | return 0; | 829 | return 0; |
830 | 830 | ||
831 | mutex_lock(&local->mtx); | ||
831 | mutex_lock(&local->iflist_mtx); | 832 | mutex_lock(&local->iflist_mtx); |
832 | if (local->use_chanctx) { | 833 | if (local->use_chanctx) { |
833 | sdata = rcu_dereference_protected( | 834 | sdata = rcu_dereference_protected( |
@@ -846,6 +847,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | |||
846 | if (ret == 0) | 847 | if (ret == 0) |
847 | local->monitor_chandef = *chandef; | 848 | local->monitor_chandef = *chandef; |
848 | mutex_unlock(&local->iflist_mtx); | 849 | mutex_unlock(&local->iflist_mtx); |
850 | mutex_unlock(&local->mtx); | ||
849 | 851 | ||
850 | return ret; | 852 | return ret; |
851 | } | 853 | } |
@@ -951,6 +953,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
951 | struct cfg80211_ap_settings *params) | 953 | struct cfg80211_ap_settings *params) |
952 | { | 954 | { |
953 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 955 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
956 | struct ieee80211_local *local = sdata->local; | ||
954 | struct beacon_data *old; | 957 | struct beacon_data *old; |
955 | struct ieee80211_sub_if_data *vlan; | 958 | struct ieee80211_sub_if_data *vlan; |
956 | u32 changed = BSS_CHANGED_BEACON_INT | | 959 | u32 changed = BSS_CHANGED_BEACON_INT | |
@@ -969,8 +972,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
969 | sdata->needed_rx_chains = sdata->local->rx_chains; | 972 | sdata->needed_rx_chains = sdata->local->rx_chains; |
970 | sdata->radar_required = params->radar_required; | 973 | sdata->radar_required = params->radar_required; |
971 | 974 | ||
975 | mutex_lock(&local->mtx); | ||
972 | err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, | 976 | err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, |
973 | IEEE80211_CHANCTX_SHARED); | 977 | IEEE80211_CHANCTX_SHARED); |
978 | mutex_unlock(&local->mtx); | ||
974 | if (err) | 979 | if (err) |
975 | return err; | 980 | return err; |
976 | ieee80211_vif_copy_chanctx_to_vlans(sdata, false); | 981 | ieee80211_vif_copy_chanctx_to_vlans(sdata, false); |
@@ -1121,7 +1126,9 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1121 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); | 1126 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); |
1122 | 1127 | ||
1123 | ieee80211_vif_copy_chanctx_to_vlans(sdata, true); | 1128 | ieee80211_vif_copy_chanctx_to_vlans(sdata, true); |
1129 | mutex_lock(&local->mtx); | ||
1124 | ieee80211_vif_release_channel(sdata); | 1130 | ieee80211_vif_release_channel(sdata); |
1131 | mutex_unlock(&local->mtx); | ||
1125 | 1132 | ||
1126 | return 0; | 1133 | return 0; |
1127 | } | 1134 | } |
@@ -1944,8 +1951,10 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, | |||
1944 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 1951 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
1945 | sdata->needed_rx_chains = sdata->local->rx_chains; | 1952 | sdata->needed_rx_chains = sdata->local->rx_chains; |
1946 | 1953 | ||
1954 | mutex_lock(&sdata->local->mtx); | ||
1947 | err = ieee80211_vif_use_channel(sdata, &setup->chandef, | 1955 | err = ieee80211_vif_use_channel(sdata, &setup->chandef, |
1948 | IEEE80211_CHANCTX_SHARED); | 1956 | IEEE80211_CHANCTX_SHARED); |
1957 | mutex_unlock(&sdata->local->mtx); | ||
1949 | if (err) | 1958 | if (err) |
1950 | return err; | 1959 | return err; |
1951 | 1960 | ||
@@ -1957,7 +1966,9 @@ static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) | |||
1957 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1966 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1958 | 1967 | ||
1959 | ieee80211_stop_mesh(sdata); | 1968 | ieee80211_stop_mesh(sdata); |
1969 | mutex_lock(&sdata->local->mtx); | ||
1960 | ieee80211_vif_release_channel(sdata); | 1970 | ieee80211_vif_release_channel(sdata); |
1971 | mutex_unlock(&sdata->local->mtx); | ||
1961 | 1972 | ||
1962 | return 0; | 1973 | return 0; |
1963 | } | 1974 | } |
@@ -2895,8 +2906,11 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy, | |||
2895 | unsigned long timeout; | 2906 | unsigned long timeout; |
2896 | int err; | 2907 | int err; |
2897 | 2908 | ||
2898 | if (!list_empty(&local->roc_list) || local->scanning) | 2909 | mutex_lock(&local->mtx); |
2899 | return -EBUSY; | 2910 | if (!list_empty(&local->roc_list) || local->scanning) { |
2911 | err = -EBUSY; | ||
2912 | goto out_unlock; | ||
2913 | } | ||
2900 | 2914 | ||
2901 | /* whatever, but channel contexts should not complain about that one */ | 2915 | /* whatever, but channel contexts should not complain about that one */ |
2902 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 2916 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
@@ -2906,13 +2920,15 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy, | |||
2906 | err = ieee80211_vif_use_channel(sdata, chandef, | 2920 | err = ieee80211_vif_use_channel(sdata, chandef, |
2907 | IEEE80211_CHANCTX_SHARED); | 2921 | IEEE80211_CHANCTX_SHARED); |
2908 | if (err) | 2922 | if (err) |
2909 | return err; | 2923 | goto out_unlock; |
2910 | 2924 | ||
2911 | timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); | 2925 | timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); |
2912 | ieee80211_queue_delayed_work(&sdata->local->hw, | 2926 | ieee80211_queue_delayed_work(&sdata->local->hw, |
2913 | &sdata->dfs_cac_timer_work, timeout); | 2927 | &sdata->dfs_cac_timer_work, timeout); |
2914 | 2928 | ||
2915 | return 0; | 2929 | out_unlock: |
2930 | mutex_unlock(&local->mtx); | ||
2931 | return err; | ||
2916 | } | 2932 | } |
2917 | 2933 | ||
2918 | static struct cfg80211_beacon_data * | 2934 | static struct cfg80211_beacon_data * |
@@ -2988,7 +3004,9 @@ void ieee80211_csa_finalize_work(struct work_struct *work) | |||
2988 | goto unlock; | 3004 | goto unlock; |
2989 | 3005 | ||
2990 | sdata->radar_required = sdata->csa_radar_required; | 3006 | sdata->radar_required = sdata->csa_radar_required; |
3007 | mutex_lock(&local->mtx); | ||
2991 | err = ieee80211_vif_change_channel(sdata, &changed); | 3008 | err = ieee80211_vif_change_channel(sdata, &changed); |
3009 | mutex_unlock(&local->mtx); | ||
2992 | if (WARN_ON(err < 0)) | 3010 | if (WARN_ON(err < 0)) |
2993 | goto unlock; | 3011 | goto unlock; |
2994 | 3012 | ||
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index f20a98a70cc0..f43613a97dd6 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -232,8 +232,8 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
232 | if (!local->use_chanctx) | 232 | if (!local->use_chanctx) |
233 | local->hw.conf.radar_enabled = ctx->conf.radar_enabled; | 233 | local->hw.conf.radar_enabled = ctx->conf.radar_enabled; |
234 | 234 | ||
235 | /* acquire mutex to prevent idle from changing */ | 235 | /* we hold the mutex to prevent idle from changing */ |
236 | mutex_lock(&local->mtx); | 236 | lockdep_assert_held(&local->mtx); |
237 | /* turn idle off *before* setting channel -- some drivers need that */ | 237 | /* turn idle off *before* setting channel -- some drivers need that */ |
238 | changed = ieee80211_idle_off(local); | 238 | changed = ieee80211_idle_off(local); |
239 | if (changed) | 239 | if (changed) |
@@ -246,19 +246,14 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
246 | err = drv_add_chanctx(local, ctx); | 246 | err = drv_add_chanctx(local, ctx); |
247 | if (err) { | 247 | if (err) { |
248 | kfree(ctx); | 248 | kfree(ctx); |
249 | ctx = ERR_PTR(err); | ||
250 | |||
251 | ieee80211_recalc_idle(local); | 249 | ieee80211_recalc_idle(local); |
252 | goto out; | 250 | return ERR_PTR(err); |
253 | } | 251 | } |
254 | } | 252 | } |
255 | 253 | ||
256 | /* and keep the mutex held until the new chanctx is on the list */ | 254 | /* and keep the mutex held until the new chanctx is on the list */ |
257 | list_add_rcu(&ctx->list, &local->chanctx_list); | 255 | list_add_rcu(&ctx->list, &local->chanctx_list); |
258 | 256 | ||
259 | out: | ||
260 | mutex_unlock(&local->mtx); | ||
261 | |||
262 | return ctx; | 257 | return ctx; |
263 | } | 258 | } |
264 | 259 | ||
@@ -294,9 +289,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local, | |||
294 | /* throw a warning if this wasn't the only channel context. */ | 289 | /* throw a warning if this wasn't the only channel context. */ |
295 | WARN_ON(check_single_channel && !list_empty(&local->chanctx_list)); | 290 | WARN_ON(check_single_channel && !list_empty(&local->chanctx_list)); |
296 | 291 | ||
297 | mutex_lock(&local->mtx); | ||
298 | ieee80211_recalc_idle(local); | 292 | ieee80211_recalc_idle(local); |
299 | mutex_unlock(&local->mtx); | ||
300 | } | 293 | } |
301 | 294 | ||
302 | static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | 295 | static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, |
@@ -364,6 +357,8 @@ static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, | |||
364 | bool radar_enabled; | 357 | bool radar_enabled; |
365 | 358 | ||
366 | lockdep_assert_held(&local->chanctx_mtx); | 359 | lockdep_assert_held(&local->chanctx_mtx); |
360 | /* for setting local->radar_detect_enabled */ | ||
361 | lockdep_assert_held(&local->mtx); | ||
367 | 362 | ||
368 | radar_enabled = ieee80211_is_radar_required(local); | 363 | radar_enabled = ieee80211_is_radar_required(local); |
369 | 364 | ||
@@ -518,6 +513,8 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | |||
518 | struct ieee80211_chanctx *ctx; | 513 | struct ieee80211_chanctx *ctx; |
519 | int ret; | 514 | int ret; |
520 | 515 | ||
516 | lockdep_assert_held(&local->mtx); | ||
517 | |||
521 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | 518 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); |
522 | 519 | ||
523 | mutex_lock(&local->chanctx_mtx); | 520 | mutex_lock(&local->chanctx_mtx); |
@@ -558,6 +555,8 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, | |||
558 | int ret; | 555 | int ret; |
559 | u32 chanctx_changed = 0; | 556 | u32 chanctx_changed = 0; |
560 | 557 | ||
558 | lockdep_assert_held(&local->mtx); | ||
559 | |||
561 | /* should never be called if not performing a channel switch. */ | 560 | /* should never be called if not performing a channel switch. */ |
562 | if (WARN_ON(!sdata->vif.csa_active)) | 561 | if (WARN_ON(!sdata->vif.csa_active)) |
563 | return -EINVAL; | 562 | return -EINVAL; |
@@ -655,6 +654,8 @@ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | |||
655 | { | 654 | { |
656 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | 655 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); |
657 | 656 | ||
657 | lockdep_assert_held(&sdata->local->mtx); | ||
658 | |||
658 | mutex_lock(&sdata->local->chanctx_mtx); | 659 | mutex_lock(&sdata->local->chanctx_mtx); |
659 | __ieee80211_vif_release_channel(sdata); | 660 | __ieee80211_vif_release_channel(sdata); |
660 | mutex_unlock(&sdata->local->chanctx_mtx); | 661 | mutex_unlock(&sdata->local->chanctx_mtx); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index d6ba841437b6..771080ec7212 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -293,14 +293,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
293 | radar_required = true; | 293 | radar_required = true; |
294 | } | 294 | } |
295 | 295 | ||
296 | mutex_lock(&local->mtx); | ||
296 | ieee80211_vif_release_channel(sdata); | 297 | ieee80211_vif_release_channel(sdata); |
297 | if (ieee80211_vif_use_channel(sdata, &chandef, | 298 | if (ieee80211_vif_use_channel(sdata, &chandef, |
298 | ifibss->fixed_channel ? | 299 | ifibss->fixed_channel ? |
299 | IEEE80211_CHANCTX_SHARED : | 300 | IEEE80211_CHANCTX_SHARED : |
300 | IEEE80211_CHANCTX_EXCLUSIVE)) { | 301 | IEEE80211_CHANCTX_EXCLUSIVE)) { |
301 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); | 302 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); |
303 | mutex_unlock(&local->mtx); | ||
302 | return; | 304 | return; |
303 | } | 305 | } |
306 | mutex_unlock(&local->mtx); | ||
304 | 307 | ||
305 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | 308 | memcpy(ifibss->bssid, bssid, ETH_ALEN); |
306 | 309 | ||
@@ -363,7 +366,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
363 | sdata->vif.bss_conf.ssid_len = 0; | 366 | sdata->vif.bss_conf.ssid_len = 0; |
364 | RCU_INIT_POINTER(ifibss->presp, NULL); | 367 | RCU_INIT_POINTER(ifibss->presp, NULL); |
365 | kfree_rcu(presp, rcu_head); | 368 | kfree_rcu(presp, rcu_head); |
369 | mutex_lock(&local->mtx); | ||
366 | ieee80211_vif_release_channel(sdata); | 370 | ieee80211_vif_release_channel(sdata); |
371 | mutex_unlock(&local->mtx); | ||
367 | sdata_info(sdata, "Failed to join IBSS, driver failure: %d\n", | 372 | sdata_info(sdata, "Failed to join IBSS, driver failure: %d\n", |
368 | err); | 373 | err); |
369 | return; | 374 | return; |
@@ -747,7 +752,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata) | |||
747 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 752 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | |
748 | BSS_CHANGED_IBSS); | 753 | BSS_CHANGED_IBSS); |
749 | drv_leave_ibss(local, sdata); | 754 | drv_leave_ibss(local, sdata); |
755 | mutex_lock(&local->mtx); | ||
750 | ieee80211_vif_release_channel(sdata); | 756 | ieee80211_vif_release_channel(sdata); |
757 | mutex_unlock(&local->mtx); | ||
751 | } | 758 | } |
752 | 759 | ||
753 | static void ieee80211_csa_connection_drop_work(struct work_struct *work) | 760 | static void ieee80211_csa_connection_drop_work(struct work_struct *work) |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 0c0be9097664..0aa9675319ef 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -418,8 +418,10 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
418 | return ret; | 418 | return ret; |
419 | } | 419 | } |
420 | 420 | ||
421 | mutex_lock(&local->mtx); | ||
421 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, | 422 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, |
422 | IEEE80211_CHANCTX_EXCLUSIVE); | 423 | IEEE80211_CHANCTX_EXCLUSIVE); |
424 | mutex_unlock(&local->mtx); | ||
423 | if (ret) { | 425 | if (ret) { |
424 | drv_remove_interface(local, sdata); | 426 | drv_remove_interface(local, sdata); |
425 | kfree(sdata); | 427 | kfree(sdata); |
@@ -456,7 +458,9 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
456 | 458 | ||
457 | synchronize_net(); | 459 | synchronize_net(); |
458 | 460 | ||
461 | mutex_lock(&local->mtx); | ||
459 | ieee80211_vif_release_channel(sdata); | 462 | ieee80211_vif_release_channel(sdata); |
463 | mutex_unlock(&local->mtx); | ||
460 | 464 | ||
461 | drv_remove_interface(local, sdata); | 465 | drv_remove_interface(local, sdata); |
462 | 466 | ||
@@ -826,7 +830,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
826 | if (sdata->wdev.cac_started) { | 830 | if (sdata->wdev.cac_started) { |
827 | chandef = sdata->vif.bss_conf.chandef; | 831 | chandef = sdata->vif.bss_conf.chandef; |
828 | WARN_ON(local->suspended); | 832 | WARN_ON(local->suspended); |
833 | mutex_lock(&local->mtx); | ||
829 | ieee80211_vif_release_channel(sdata); | 834 | ieee80211_vif_release_channel(sdata); |
835 | mutex_unlock(&local->mtx); | ||
830 | cfg80211_cac_event(sdata->dev, &chandef, | 836 | cfg80211_cac_event(sdata->dev, &chandef, |
831 | NL80211_RADAR_CAC_ABORTED, | 837 | NL80211_RADAR_CAC_ABORTED, |
832 | GFP_KERNEL); | 838 | GFP_KERNEL); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9c2c7ee2cc30..fc1d82465b3c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -888,7 +888,9 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
888 | if (!ifmgd->associated) | 888 | if (!ifmgd->associated) |
889 | goto out; | 889 | goto out; |
890 | 890 | ||
891 | mutex_lock(&local->mtx); | ||
891 | ret = ieee80211_vif_change_channel(sdata, &changed); | 892 | ret = ieee80211_vif_change_channel(sdata, &changed); |
893 | mutex_unlock(&local->mtx); | ||
892 | if (ret) { | 894 | if (ret) { |
893 | sdata_info(sdata, | 895 | sdata_info(sdata, |
894 | "vif channel switch failed, disconnecting\n"); | 896 | "vif channel switch failed, disconnecting\n"); |
@@ -1401,10 +1403,14 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work) | |||
1401 | dfs_cac_timer_work); | 1403 | dfs_cac_timer_work); |
1402 | struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef; | 1404 | struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef; |
1403 | 1405 | ||
1404 | ieee80211_vif_release_channel(sdata); | 1406 | mutex_lock(&sdata->local->mtx); |
1405 | cfg80211_cac_event(sdata->dev, &chandef, | 1407 | if (sdata->wdev.cac_started) { |
1406 | NL80211_RADAR_CAC_FINISHED, | 1408 | ieee80211_vif_release_channel(sdata); |
1407 | GFP_KERNEL); | 1409 | cfg80211_cac_event(sdata->dev, &chandef, |
1410 | NL80211_RADAR_CAC_FINISHED, | ||
1411 | GFP_KERNEL); | ||
1412 | } | ||
1413 | mutex_unlock(&sdata->local->mtx); | ||
1408 | } | 1414 | } |
1409 | 1415 | ||
1410 | /* MLME */ | 1416 | /* MLME */ |
@@ -1747,7 +1753,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1747 | ifmgd->have_beacon = false; | 1753 | ifmgd->have_beacon = false; |
1748 | 1754 | ||
1749 | ifmgd->flags = 0; | 1755 | ifmgd->flags = 0; |
1756 | mutex_lock(&local->mtx); | ||
1750 | ieee80211_vif_release_channel(sdata); | 1757 | ieee80211_vif_release_channel(sdata); |
1758 | mutex_unlock(&local->mtx); | ||
1751 | 1759 | ||
1752 | sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; | 1760 | sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; |
1753 | } | 1761 | } |
@@ -2070,7 +2078,9 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, | |||
2070 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 2078 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
2071 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | 2079 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); |
2072 | sdata->u.mgd.flags = 0; | 2080 | sdata->u.mgd.flags = 0; |
2081 | mutex_lock(&sdata->local->mtx); | ||
2073 | ieee80211_vif_release_channel(sdata); | 2082 | ieee80211_vif_release_channel(sdata); |
2083 | mutex_unlock(&sdata->local->mtx); | ||
2074 | } | 2084 | } |
2075 | 2085 | ||
2076 | cfg80211_put_bss(sdata->local->hw.wiphy, auth_data->bss); | 2086 | cfg80211_put_bss(sdata->local->hw.wiphy, auth_data->bss); |
@@ -2319,7 +2329,9 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, | |||
2319 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 2329 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
2320 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | 2330 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); |
2321 | sdata->u.mgd.flags = 0; | 2331 | sdata->u.mgd.flags = 0; |
2332 | mutex_lock(&sdata->local->mtx); | ||
2322 | ieee80211_vif_release_channel(sdata); | 2333 | ieee80211_vif_release_channel(sdata); |
2334 | mutex_unlock(&sdata->local->mtx); | ||
2323 | } | 2335 | } |
2324 | 2336 | ||
2325 | kfree(assoc_data); | 2337 | kfree(assoc_data); |
@@ -3670,6 +3682,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3670 | /* will change later if needed */ | 3682 | /* will change later if needed */ |
3671 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 3683 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
3672 | 3684 | ||
3685 | mutex_lock(&local->mtx); | ||
3673 | /* | 3686 | /* |
3674 | * If this fails (possibly due to channel context sharing | 3687 | * If this fails (possibly due to channel context sharing |
3675 | * on incompatible channels, e.g. 80+80 and 160 sharing the | 3688 | * on incompatible channels, e.g. 80+80 and 160 sharing the |
@@ -3681,13 +3694,15 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3681 | /* don't downgrade for 5 and 10 MHz channels, though. */ | 3694 | /* don't downgrade for 5 and 10 MHz channels, though. */ |
3682 | if (chandef.width == NL80211_CHAN_WIDTH_5 || | 3695 | if (chandef.width == NL80211_CHAN_WIDTH_5 || |
3683 | chandef.width == NL80211_CHAN_WIDTH_10) | 3696 | chandef.width == NL80211_CHAN_WIDTH_10) |
3684 | return ret; | 3697 | goto out; |
3685 | 3698 | ||
3686 | while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { | 3699 | while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { |
3687 | ifmgd->flags |= ieee80211_chandef_downgrade(&chandef); | 3700 | ifmgd->flags |= ieee80211_chandef_downgrade(&chandef); |
3688 | ret = ieee80211_vif_use_channel(sdata, &chandef, | 3701 | ret = ieee80211_vif_use_channel(sdata, &chandef, |
3689 | IEEE80211_CHANCTX_SHARED); | 3702 | IEEE80211_CHANCTX_SHARED); |
3690 | } | 3703 | } |
3704 | out: | ||
3705 | mutex_unlock(&local->mtx); | ||
3691 | return ret; | 3706 | return ret; |
3692 | } | 3707 | } |
3693 | 3708 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 656648b9b9d3..ed93504d24b8 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2315,9 +2315,14 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) | |||
2315 | struct ieee80211_sub_if_data *sdata; | 2315 | struct ieee80211_sub_if_data *sdata; |
2316 | struct cfg80211_chan_def chandef; | 2316 | struct cfg80211_chan_def chandef; |
2317 | 2317 | ||
2318 | mutex_lock(&local->mtx); | ||
2318 | mutex_lock(&local->iflist_mtx); | 2319 | mutex_lock(&local->iflist_mtx); |
2319 | list_for_each_entry(sdata, &local->interfaces, list) { | 2320 | list_for_each_entry(sdata, &local->interfaces, list) { |
2320 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); | 2321 | /* it might be waiting for the local->mtx, but then |
2322 | * by the time it gets it, sdata->wdev.cac_started | ||
2323 | * will no longer be true | ||
2324 | */ | ||
2325 | cancel_delayed_work(&sdata->dfs_cac_timer_work); | ||
2321 | 2326 | ||
2322 | if (sdata->wdev.cac_started) { | 2327 | if (sdata->wdev.cac_started) { |
2323 | chandef = sdata->vif.bss_conf.chandef; | 2328 | chandef = sdata->vif.bss_conf.chandef; |
@@ -2329,6 +2334,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) | |||
2329 | } | 2334 | } |
2330 | } | 2335 | } |
2331 | mutex_unlock(&local->iflist_mtx); | 2336 | mutex_unlock(&local->iflist_mtx); |
2337 | mutex_unlock(&local->mtx); | ||
2332 | } | 2338 | } |
2333 | 2339 | ||
2334 | void ieee80211_dfs_radar_detected_work(struct work_struct *work) | 2340 | void ieee80211_dfs_radar_detected_work(struct work_struct *work) |