aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-03-26 17:23:20 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-04-08 05:06:28 -0400
commit2b730daacee6c318bce7b6373c19909e36a74590 (patch)
tree9fd2b28079afae8672cd5bfb695e74abdba0cddf /net/mac80211/iface.c
parenta23108248a9d41400e686becddb5584b3a3fec1e (diff)
mac80211: don't start new netdev queues if driver stopped
If a new netdev (e.g. an AP VLAN) is created while the driver has queues stopped, the new netdev queues will be started even though they shouldn't. This will lead to frames accumulating on the internal mac80211 pending queues instead of properly being held on the netdev queues. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 63b63675aa6d..b6abaaa3676f 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -639,8 +639,28 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
639 639
640 ieee80211_recalc_ps(local, -1); 640 ieee80211_recalc_ps(local, -1);
641 641
642 if (dev) 642 if (dev) {
643 netif_tx_start_all_queues(dev); 643 unsigned long flags;
644 int n_acs = IEEE80211_NUM_ACS;
645 int ac;
646
647 if (local->hw.queues < IEEE80211_NUM_ACS)
648 n_acs = 1;
649
650 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
651 if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE ||
652 (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 &&
653 skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) {
654 for (ac = 0; ac < n_acs; ac++) {
655 int ac_queue = sdata->vif.hw_queue[ac];
656
657 if (local->queue_stop_reasons[ac_queue] == 0 &&
658 skb_queue_empty(&local->pending[ac_queue]))
659 netif_start_subqueue(dev, ac);
660 }
661 }
662 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
663 }
644 664
645 return 0; 665 return 0;
646 err_del_interface: 666 err_del_interface: