Merge tag 'pm-urgent-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[cascardo/linux.git] / net / mac80211 / iface.c
index c59af3e..b123a9e 100644 (file)
@@ -779,6 +779,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                              bool going_down)
 {
        struct ieee80211_local *local = sdata->local;
+       struct fq *fq = &local->fq;
        unsigned long flags;
        struct sk_buff *skb, *tmp;
        u32 hw_reconf_flags = 0;
@@ -977,12 +978,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        if (sdata->vif.txq) {
                struct txq_info *txqi = to_txq_info(sdata->vif.txq);
 
-               spin_lock_bh(&txqi->queue.lock);
-               ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
-               txqi->byte_cnt = 0;
-               spin_unlock_bh(&txqi->queue.lock);
-
-               atomic_set(&sdata->txqs_len[txqi->txq.ac], 0);
+               spin_lock_bh(&fq->lock);
+               ieee80211_txq_purge(local, txqi);
+               spin_unlock_bh(&fq->lock);
        }
 
        if (local->open_count == 0)
@@ -1198,6 +1196,12 @@ static void ieee80211_if_setup(struct net_device *dev)
        dev->destructor = ieee80211_if_free;
 }
 
+static void ieee80211_if_setup_no_queue(struct net_device *dev)
+{
+       ieee80211_if_setup(dev);
+       dev->priv_flags |= IFF_NO_QUEUE;
+}
+
 static void ieee80211_iface_work(struct work_struct *work)
 {
        struct ieee80211_sub_if_data *sdata =
@@ -1707,6 +1711,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
        struct net_device *ndev = NULL;
        struct ieee80211_sub_if_data *sdata = NULL;
        struct txq_info *txqi;
+       void (*if_setup)(struct net_device *dev);
        int ret, i;
        int txqs = 1;
 
@@ -1734,12 +1739,17 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
                        txq_size += sizeof(struct txq_info) +
                                    local->hw.txq_data_size;
 
+               if (local->ops->wake_tx_queue)
+                       if_setup = ieee80211_if_setup_no_queue;
+               else
+                       if_setup = ieee80211_if_setup;
+
                if (local->hw.queues >= IEEE80211_NUM_ACS)
                        txqs = IEEE80211_NUM_ACS;
 
                ndev = alloc_netdev_mqs(size + txq_size,
                                        name, name_assign_type,
-                                       ieee80211_if_setup, txqs, 1);
+                                       if_setup, txqs, 1);
                if (!ndev)
                        return -ENOMEM;
                dev_net_set(ndev, wiphy_net(local->hw.wiphy));
@@ -1780,7 +1790,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 
                if (txq_size) {
                        txqi = netdev_priv(ndev) + size;
-                       ieee80211_init_tx_queue(sdata, NULL, txqi, 0);
+                       ieee80211_txq_init(sdata, NULL, txqi, 0);
                }
 
                sdata->dev = ndev;