diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 4fb2709cb527..513627896204 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -256,8 +256,27 @@ static void ieee80211_restart_work(struct work_struct *work) | |||
256 | 256 | ||
257 | flush_work(&local->radar_detected_work); | 257 | flush_work(&local->radar_detected_work); |
258 | rtnl_lock(); | 258 | rtnl_lock(); |
259 | list_for_each_entry(sdata, &local->interfaces, list) | 259 | list_for_each_entry(sdata, &local->interfaces, list) { |
260 | /* | ||
261 | * XXX: there may be more work for other vif types and even | ||
262 | * for station mode: a good thing would be to run most of | ||
263 | * the iface type's dependent _stop (ieee80211_mg_stop, | ||
264 | * ieee80211_ibss_stop) etc... | ||
265 | * For now, fix only the specific bug that was seen: race | ||
266 | * between csa_connection_drop_work and us. | ||
267 | */ | ||
268 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
269 | /* | ||
270 | * This worker is scheduled from the iface worker that | ||
271 | * runs on mac80211's workqueue, so we can't be | ||
272 | * scheduling this worker after the cancel right here. | ||
273 | * The exception is ieee80211_chswitch_done. | ||
274 | * Then we can have a race... | ||
275 | */ | ||
276 | cancel_work_sync(&sdata->u.mgd.csa_connection_drop_work); | ||
277 | } | ||
260 | flush_delayed_work(&sdata->dec_tailroom_needed_wk); | 278 | flush_delayed_work(&sdata->dec_tailroom_needed_wk); |
279 | } | ||
261 | ieee80211_scan_cancel(local); | 280 | ieee80211_scan_cancel(local); |
262 | 281 | ||
263 | /* make sure any new ROC will consider local->in_reconfig */ | 282 | /* make sure any new ROC will consider local->in_reconfig */ |
@@ -471,10 +490,7 @@ static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = { | |||
471 | cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC | | 490 | cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC | |
472 | IEEE80211_VHT_CAP_SHORT_GI_80 | | 491 | IEEE80211_VHT_CAP_SHORT_GI_80 | |
473 | IEEE80211_VHT_CAP_SHORT_GI_160 | | 492 | IEEE80211_VHT_CAP_SHORT_GI_160 | |
474 | IEEE80211_VHT_CAP_RXSTBC_1 | | 493 | IEEE80211_VHT_CAP_RXSTBC_MASK | |
475 | IEEE80211_VHT_CAP_RXSTBC_2 | | ||
476 | IEEE80211_VHT_CAP_RXSTBC_3 | | ||
477 | IEEE80211_VHT_CAP_RXSTBC_4 | | ||
478 | IEEE80211_VHT_CAP_TXSTBC | | 494 | IEEE80211_VHT_CAP_TXSTBC | |
479 | IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | | 495 | IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | |
480 | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | | 496 | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | |
@@ -1208,6 +1224,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1208 | #if IS_ENABLED(CONFIG_IPV6) | 1224 | #if IS_ENABLED(CONFIG_IPV6) |
1209 | unregister_inet6addr_notifier(&local->ifa6_notifier); | 1225 | unregister_inet6addr_notifier(&local->ifa6_notifier); |
1210 | #endif | 1226 | #endif |
1227 | ieee80211_txq_teardown_flows(local); | ||
1211 | 1228 | ||
1212 | rtnl_lock(); | 1229 | rtnl_lock(); |
1213 | 1230 | ||
@@ -1236,7 +1253,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1236 | skb_queue_purge(&local->skb_queue); | 1253 | skb_queue_purge(&local->skb_queue); |
1237 | skb_queue_purge(&local->skb_queue_unreliable); | 1254 | skb_queue_purge(&local->skb_queue_unreliable); |
1238 | skb_queue_purge(&local->skb_queue_tdls_chsw); | 1255 | skb_queue_purge(&local->skb_queue_tdls_chsw); |
1239 | ieee80211_txq_teardown_flows(local); | ||
1240 | 1256 | ||
1241 | destroy_workqueue(local->workqueue); | 1257 | destroy_workqueue(local->workqueue); |
1242 | wiphy_unregister(local->hw.wiphy); | 1258 | wiphy_unregister(local->hw.wiphy); |