diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6bcf0faa4a89dbf38ee125099ad8c328f378331f..ed4c8e66b44a9edd9188634996f641dbb2200ab5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -256,6 +256,11 @@ static void ieee80211_restart_work(struct work_struct *work) list_for_each_entry(sdata, &local->interfaces, list) flush_delayed_work(&sdata->dec_tailroom_needed_wk); ieee80211_scan_cancel(local); + + /* make sure any new ROC will consider local->in_reconfig */ + flush_delayed_work(&local->roc_work); + flush_work(&local->hw_roc_done); + ieee80211_reconfig(local); rtnl_unlock(); } diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index fbc34e9088deda0dfd2daa12fed1720eacf499d1..55a9c5b94ce128d06ffb3154173fa2ea62a53f9b 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -408,6 +408,10 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) return; } + /* defer roc if driver is not started (i.e. during reconfig) */ + if (local->in_reconfig) + return; + roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, list); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 3943d4bf289c29b436765d82dd0f241c8b7f5530..4f6e0b79ef69c673f307219cd77536d9c6bf38e8 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2051,8 +2051,15 @@ int ieee80211_reconfig(struct ieee80211_local *local) cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy); wake_up: - local->in_reconfig = false; - barrier(); + if (local->in_reconfig) { + local->in_reconfig = false; + barrier(); + + /* Restart deferred ROCs */ + mutex_lock(&local->mtx); + ieee80211_start_next_roc(local); + mutex_unlock(&local->mtx); + } if (local->monitors == local->open_count && local->monitors > 0) ieee80211_add_virtual_monitor(local);