aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 906fc2be0cfb..56167a3d872d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -465,21 +465,11 @@ static int ieee80211_stop(struct net_device *dev)
465 cancel_work_sync(&sdata->u.mgd.monitor_work); 465 cancel_work_sync(&sdata->u.mgd.monitor_work);
466 cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work); 466 cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work);
467 467
468 /*
469 * When we get here, the interface is marked down.
470 * Call synchronize_rcu() to wait for the RX path
471 * should it be using the interface and enqueuing
472 * frames at this very time on another CPU.
473 */
474 synchronize_rcu();
475 skb_queue_purge(&sdata->u.mgd.skb_queue);
476 /* fall through */ 468 /* fall through */
477 case NL80211_IFTYPE_ADHOC: 469 case NL80211_IFTYPE_ADHOC:
478 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 470 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
479 del_timer_sync(&sdata->u.ibss.timer); 471 del_timer_sync(&sdata->u.ibss.timer);
480 cancel_work_sync(&sdata->u.ibss.work); 472 cancel_work_sync(&sdata->u.ibss.work);
481 synchronize_rcu();
482 skb_queue_purge(&sdata->u.ibss.skb_queue);
483 } 473 }
484 /* fall through */ 474 /* fall through */
485 case NL80211_IFTYPE_MESH_POINT: 475 case NL80211_IFTYPE_MESH_POINT:
@@ -495,6 +485,15 @@ static int ieee80211_stop(struct net_device *dev)
495 } 485 }
496 /* fall through */ 486 /* fall through */
497 default: 487 default:
488 /*
489 * When we get here, the interface is marked down.
490 * Call synchronize_rcu() to wait for the RX path
491 * should it be using the interface and enqueuing
492 * frames at this very time on another CPU.
493 */
494 synchronize_rcu();
495 skb_queue_purge(&sdata->skb_queue);
496
498 if (local->scan_sdata == sdata) 497 if (local->scan_sdata == sdata)
499 ieee80211_scan_cancel(local); 498 ieee80211_scan_cancel(local);
500 499
@@ -721,6 +720,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
721 /* only monitor differs */ 720 /* only monitor differs */
722 sdata->dev->type = ARPHRD_ETHER; 721 sdata->dev->type = ARPHRD_ETHER;
723 722
723 skb_queue_head_init(&sdata->skb_queue);
724
724 switch (type) { 725 switch (type) {
725 case NL80211_IFTYPE_AP: 726 case NL80211_IFTYPE_AP:
726 skb_queue_head_init(&sdata->u.ap.ps_bc_buf); 727 skb_queue_head_init(&sdata->u.ap.ps_bc_buf);