diff options
Diffstat (limited to 'net/mac80211/iface.c')
| -rw-r--r-- | net/mac80211/iface.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 3dfd20a453ab..d6d1f1df9119 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -418,20 +418,24 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
| 418 | return ret; | 418 | return ret; |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | mutex_lock(&local->iflist_mtx); | ||
| 422 | rcu_assign_pointer(local->monitor_sdata, sdata); | ||
| 423 | mutex_unlock(&local->iflist_mtx); | ||
| 424 | |||
| 421 | mutex_lock(&local->mtx); | 425 | mutex_lock(&local->mtx); |
| 422 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, | 426 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, |
| 423 | IEEE80211_CHANCTX_EXCLUSIVE); | 427 | IEEE80211_CHANCTX_EXCLUSIVE); |
| 424 | mutex_unlock(&local->mtx); | 428 | mutex_unlock(&local->mtx); |
| 425 | if (ret) { | 429 | if (ret) { |
| 430 | mutex_lock(&local->iflist_mtx); | ||
| 431 | rcu_assign_pointer(local->monitor_sdata, NULL); | ||
| 432 | mutex_unlock(&local->iflist_mtx); | ||
| 433 | synchronize_net(); | ||
| 426 | drv_remove_interface(local, sdata); | 434 | drv_remove_interface(local, sdata); |
| 427 | kfree(sdata); | 435 | kfree(sdata); |
| 428 | return ret; | 436 | return ret; |
| 429 | } | 437 | } |
| 430 | 438 | ||
| 431 | mutex_lock(&local->iflist_mtx); | ||
| 432 | rcu_assign_pointer(local->monitor_sdata, sdata); | ||
| 433 | mutex_unlock(&local->iflist_mtx); | ||
| 434 | |||
| 435 | return 0; | 439 | return 0; |
| 436 | } | 440 | } |
| 437 | 441 | ||
| @@ -770,12 +774,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 770 | 774 | ||
| 771 | ieee80211_roc_purge(local, sdata); | 775 | ieee80211_roc_purge(local, sdata); |
| 772 | 776 | ||
| 773 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 777 | switch (sdata->vif.type) { |
| 778 | case NL80211_IFTYPE_STATION: | ||
| 774 | ieee80211_mgd_stop(sdata); | 779 | ieee80211_mgd_stop(sdata); |
| 775 | 780 | break; | |
| 776 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 781 | case NL80211_IFTYPE_ADHOC: |
| 777 | ieee80211_ibss_stop(sdata); | 782 | ieee80211_ibss_stop(sdata); |
| 778 | 783 | break; | |
| 784 | case NL80211_IFTYPE_AP: | ||
| 785 | cancel_work_sync(&sdata->u.ap.request_smps_work); | ||
| 786 | break; | ||
| 787 | default: | ||
| 788 | break; | ||
| 789 | } | ||
| 779 | 790 | ||
| 780 | /* | 791 | /* |
| 781 | * Remove all stations associated with this interface. | 792 | * Remove all stations associated with this interface. |
