Merge tag 'devicetree-fixes-for-5.13-1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / net / mac80211 / tx.c
index 3b3bcef..0b719f3 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
  *
  * Transmit and frame generation functions.
  */
@@ -1388,8 +1388,20 @@ static void ieee80211_txq_enqueue(struct ieee80211_local *local,
        ieee80211_set_skb_enqueue_time(skb);
 
        spin_lock_bh(&fq->lock);
-       fq_tin_enqueue(fq, tin, flow_idx, skb,
-                      fq_skb_free_func);
+       /*
+        * For management frames, don't really apply codel etc.,
+        * we don't want to apply any shaping or anything we just
+        * want to simplify the driver API by having them on the
+        * txqi.
+        */
+       if (unlikely(txqi->txq.tid == IEEE80211_NUM_TIDS)) {
+               IEEE80211_SKB_CB(skb)->control.flags |=
+                       IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
+               __skb_queue_tail(&txqi->frags, skb);
+       } else {
+               fq_tin_enqueue(fq, tin, flow_idx, skb,
+                              fq_skb_free_func);
+       }
        spin_unlock_bh(&fq->lock);
 }
 
@@ -1684,7 +1696,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_vif *vif;
        struct sk_buff *skb;
-       bool result = true;
+       bool result;
        __le16 fc;
 
        if (WARN_ON(skb_queue_empty(skbs)))
@@ -2267,17 +2279,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
                                                    payload[7]);
        }
 
-       /* Initialize skb->priority for QoS frames. If the DONT_REORDER flag
-        * is set, stick to the default value for skb->priority to assure
-        * frames injected with this flag are not reordered relative to each
-        * other.
-        */
-       if (ieee80211_is_data_qos(hdr->frame_control) &&
-           !(info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER)) {
-               u8 *p = ieee80211_get_qos_ctl(hdr);
-               skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
-       }
-
        rcu_read_lock();
 
        /*
@@ -2341,6 +2342,15 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
 
        info->band = chandef->chan->band;
 
+       /* Initialize skb->priority according to frame type and TID class,
+        * with respect to the sub interface that the frame will actually
+        * be transmitted on. If the DONT_REORDER flag is set, the original
+        * skb-priority is preserved to assure frames injected with this
+        * flag are not reordered relative to each other.
+        */
+       ieee80211_select_queue_80211(sdata, skb, hdr);
+       skb_set_queue_mapping(skb, ieee80211_ac_from_tid(skb->priority));
+
        /* remove the injection radiotap header */
        skb_pull(skb, len_rthdr);
 
@@ -3580,10 +3590,16 @@ begin:
 
        /* Make sure fragments stay together. */
        skb = __skb_dequeue(&txqi->frags);
-       if (skb)
-               goto out;
+       if (unlikely(skb)) {
+               if (!(IEEE80211_SKB_CB(skb)->control.flags &
+                               IEEE80211_TX_INTCFL_NEED_TXPROCESSING))
+                       goto out;
+               IEEE80211_SKB_CB(skb)->control.flags &=
+                       ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
+       } else {
+               skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func);
+       }
 
-       skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func);
        if (!skb)
                goto out;
 
@@ -3835,6 +3851,9 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
        if (!txq->sta)
                return true;
 
+       if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
+               return true;
+
        sta = container_of(txq->sta, struct sta_info, sta);
        if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
            sta->airtime[txq->ac].aql_limit_low)
@@ -4150,6 +4169,9 @@ static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
        unsigned long flags;
        int q = info->hw_queue;
 
+       if (sta)
+               sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift);
+
        if (ieee80211_queue_skb(local, sdata, sta, skb))
                return true;