mac80211: Update to version 5.14.13-1
authorHauke Mehrtens <hauke@hauke-m.de>
Sun, 10 Oct 2021 19:24:14 +0000 (21:24 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 23 Oct 2021 22:08:38 +0000 (00:08 +0200)
The removed patches were applied upstream.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
22 files changed:
package/kernel/mac80211/Makefile
package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch
package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch
package/kernel/mac80211/patches/brcm/998-survey.patch
package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch
package/kernel/mac80211/patches/subsys/210-ap_scan.patch
package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch
package/kernel/mac80211/patches/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch
package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch [deleted file]
package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch [deleted file]
package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch [deleted file]
package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch [deleted file]
package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch [deleted file]
package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch [deleted file]
package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch [deleted file]
package/kernel/mac80211/patches/subsys/387-nl80211-add-support-for-BSS-coloring.patch
package/kernel/mac80211/patches/subsys/388-mac80211-add-support-for-BSS-color-change.patch
package/kernel/mac80211/patches/subsys/389-ieee80211-add-TWT-element-definitions.patch
package/kernel/mac80211/patches/subsys/390-mac80211-introduce-individual-TWT-support-in-AP-mode.patch
package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch
package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch
package/network/utils/iw/patches/001-nl80211_h_sync.patch

index b3a8960fe86263bd89b533160f1fe3f178610d5c..1fc9dc4c486d9bfa20a78e616f138016ab70e89c 100644 (file)
@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=5.13.19-1
+PKG_VERSION:=5.14.13-1
 PKG_RELEASE:=1
-PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.13.19/
-PKG_HASH:=1eb761c1664d59a0a2d52847f240c9d02fc2e56fb27d862d2949bfb275187eef
+PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.14.13/
+PKG_HASH:=042aef20caf17ef649502d5f2e744a7676abe7faed18de83c96f37bc029635fe
 
 PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
index 774656f1fdee74dd8016580969c7ed1c1e349255..2e22ec793b0ad79fdbc1ab26f21eae9a2ba39d4e 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -2961,6 +2961,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
+@@ -2966,6 +2966,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
         * preference in cfg struct to apply this to
         * FW later while initializing the dongle
         */
index 9658bda1c17806856bcf2b8ac7053db2ba5a2f76..835c870a657770a7575adaf6eebfb91ce0ce4bf7 100644 (file)
@@ -12,9 +12,9 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
-@@ -12,6 +12,36 @@
- #include "common.h"
- #include "of.h"
+@@ -58,6 +58,36 @@ static int brcmf_of_get_country_codes(st
+       return 0;
+ }
  
 +/* TODO: FIXME: Use DT */
 +static void brcmf_of_probe_cc(struct device *dev,
@@ -49,12 +49,12 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
  void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
                    struct brcmf_mp_device *settings)
  {
-@@ -43,6 +73,8 @@ void brcmf_of_probe(struct device *dev,
+@@ -90,6 +120,8 @@ void brcmf_of_probe(struct device *dev,
                of_node_put(root);
        }
  
 +      brcmf_of_probe_cc(dev, settings);
 +
-       if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
-           !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
+       if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
                return;
index 2c11ed696db2acb3762c0f3246709c5c3b485722..1479c671561a597515d8753291c67f1725858a02 100644 (file)
@@ -64,7 +64,7 @@
  brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
                            int idx, u8 *mac, struct station_info *sinfo)
  {
-@@ -3008,6 +3065,7 @@ static s32 brcmf_inform_single_bss(struc
+@@ -3013,6 +3070,7 @@ static s32 brcmf_inform_single_bss(struc
        struct brcmu_chan ch;
        u16 channel;
        u32 freq;
@@ -72,7 +72,7 @@
        u16 notify_capability;
        u16 notify_interval;
        u8 *notify_ie;
-@@ -3032,6 +3090,17 @@ static s32 brcmf_inform_single_bss(struc
+@@ -3037,6 +3095,17 @@ static s32 brcmf_inform_single_bss(struc
                band = NL80211_BAND_5GHZ;
  
        freq = ieee80211_channel_to_frequency(channel, band);
@@ -90,7 +90,7 @@
        bss_data.chan = ieee80211_get_channel(wiphy, freq);
        bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
        bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
-@@ -5560,6 +5629,7 @@ static struct cfg80211_ops brcmf_cfg8021
+@@ -5565,6 +5634,7 @@ static struct cfg80211_ops brcmf_cfg8021
        .leave_ibss = brcmf_cfg80211_leave_ibss,
        .get_station = brcmf_cfg80211_get_station,
        .dump_station = brcmf_cfg80211_dump_station,
        .add_key = brcmf_cfg80211_add_key,
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-@@ -1356,6 +1356,8 @@ int brcmf_attach(struct device *dev)
+@@ -1361,6 +1361,8 @@ int brcmf_attach(struct device *dev)
  
        /* Link to bus module */
        drvr->hdrlen = 0;
  
        /* Attach and link in the protocol */
        ret = brcmf_proto_attach(drvr);
-@@ -1438,6 +1440,12 @@ void brcmf_detach(struct device *dev)
+@@ -1443,6 +1445,12 @@ void brcmf_detach(struct device *dev)
        if (drvr == NULL)
                return;
  
index 0cd1cfdd31cf0fe0ef44399551ff273a58930824..e93efa44298065d99f53c86fa260555ecdd52b60 100644 (file)
@@ -18,7 +18,7 @@
  static int ieee80211_ifa6_changed(struct notifier_block *nb,
                                  unsigned long data, void *arg)
  {
-@@ -1319,14 +1319,14 @@ int ieee80211_register_hw(struct ieee802
+@@ -1324,14 +1324,14 @@ int ieee80211_register_hw(struct ieee802
        wiphy_unlock(hw->wiphy);
        rtnl_unlock();
  
@@ -35,7 +35,7 @@
        local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
        result = register_inet6addr_notifier(&local->ifa6_notifier);
        if (result)
-@@ -1335,13 +1335,13 @@ int ieee80211_register_hw(struct ieee802
+@@ -1340,13 +1340,13 @@ int ieee80211_register_hw(struct ieee802
  
        return 0;
  
@@ -52,7 +52,7 @@
   fail_ifa:
  #endif
        wiphy_unregister(local->hw.wiphy);
-@@ -1369,10 +1369,10 @@ void ieee80211_unregister_hw(struct ieee
+@@ -1374,10 +1374,10 @@ void ieee80211_unregister_hw(struct ieee
        tasklet_kill(&local->tx_pending_tasklet);
        tasklet_kill(&local->tasklet);
  
index 708cf7b0d5ba65212006b37c1422598850024f21..1efa336d0c29302ee03011ada76c613af7bd51dd 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2462,7 +2462,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -2487,7 +2487,7 @@ static int ieee80211_scan(struct wiphy *
                 * the  frames sent while scanning on other channel will be
                 * lost)
                 */
index c21d4446ab896dfc9238f4cd369dba2eae47d281..9c7417e5fc8fcbee3449ac6a0a0ec9d6844e99ba 100644 (file)
@@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/wireless/mac80211_hwsim.c
 +++ b/drivers/net/wireless/mac80211_hwsim.c
-@@ -2990,15 +2990,19 @@ static void mac80211_hwsim_he_capab(stru
+@@ -2992,15 +2992,19 @@ static void mac80211_hwsim_he_capab(stru
  {
        u16 n_iftype_data;
  
@@ -34,7 +34,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                return;
        }
  
-@@ -3288,6 +3292,12 @@ static int mac80211_hwsim_new_radio(stru
+@@ -3290,6 +3294,12 @@ static int mac80211_hwsim_new_radio(stru
                        sband->vht_cap.vht_mcs.tx_mcs_map =
                                sband->vht_cap.vht_mcs.rx_mcs_map;
                        break;
@@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                case NL80211_BAND_S1GHZ:
                        memcpy(&sband->s1g_cap, &hwsim_s1g_cap,
                               sizeof(sband->s1g_cap));
-@@ -3298,6 +3308,13 @@ static int mac80211_hwsim_new_radio(stru
+@@ -3300,6 +3310,13 @@ static int mac80211_hwsim_new_radio(stru
                        continue;
                }
  
@@ -61,7 +61,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                sband->ht_cap.ht_supported = true;
                sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
                                    IEEE80211_HT_CAP_GRN_FLD |
-@@ -3311,10 +3328,6 @@ static int mac80211_hwsim_new_radio(stru
+@@ -3313,10 +3330,6 @@ static int mac80211_hwsim_new_radio(stru
                sband->ht_cap.mcs.rx_mask[0] = 0xff;
                sband->ht_cap.mcs.rx_mask[1] = 0xff;
                sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
index 7cbc8c01d05ee3c2cdc56a82b88f2c60f0a82a7d..a6817bd4a6dc29dfd2503524fdbdc85ff1998e47 100644 (file)
@@ -117,7 +117,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
  }
  
-@@ -1206,7 +1169,7 @@ minstrel_ht_tx_status(void *priv, struct
+@@ -1183,7 +1146,7 @@ minstrel_ht_tx_status(void *priv, struct
        struct ieee80211_tx_info *info = st->info;
        struct minstrel_ht_sta *mi = priv_sta;
        struct ieee80211_tx_rate *ar = info->status.rates;
@@ -126,7 +126,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct minstrel_priv *mp = priv;
        u32 update_interval = mp->update_interval;
        bool last, update = false;
-@@ -1252,18 +1215,13 @@ minstrel_ht_tx_status(void *priv, struct
+@@ -1233,18 +1196,13 @@ minstrel_ht_tx_status(void *priv, struct
                /*
                 * check for sudden death of spatial multiplexing,
                 * downgrade to a lower number of streams if necessary.
diff --git a/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch b/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch
deleted file mode 100644 (file)
index dc51188..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 17 Jun 2021 17:56:54 +0200
-Subject: [PATCH] mac80211: move A-MPDU session check from minstrel_ht to
- mac80211
-
-This avoids calling back into tx handlers from within the rate control module.
-Preparation for deferring rate control until tx dequeue
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -6192,6 +6192,11 @@ enum rate_control_capabilities {
-        * otherwise the NSS difference doesn't bother us.
-        */
-       RATE_CTRL_CAPA_VHT_EXT_NSS_BW = BIT(0),
-+      /**
-+       * @RATE_CTRL_CAPA_AMPDU_TRIGGER:
-+       * mac80211 should start A-MPDU sessions on tx
-+       */
-+      RATE_CTRL_CAPA_AMPDU_TRIGGER = BIT(1),
- };
- struct rate_control_ops {
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -1140,29 +1140,6 @@ minstrel_downgrade_prob_rate(struct mins
- }
- static void
--minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb)
--{
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
--      struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
--      u16 tid;
--
--      if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
--              return;
--
--      if (unlikely(!ieee80211_is_data_qos(hdr->frame_control)))
--              return;
--
--      if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE)))
--              return;
--
--      tid = ieee80211_get_tid(hdr);
--      if (likely(sta->ampdu_mlme.tid_tx[tid]))
--              return;
--
--      ieee80211_start_tx_ba_session(pubsta, tid, 0);
--}
--
--static void
- minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
-                       void *priv_sta, struct ieee80211_tx_status *st)
- {
-@@ -1457,10 +1434,6 @@ minstrel_ht_get_rate(void *priv, struct
-       struct minstrel_priv *mp = priv;
-       u16 sample_idx;
--      if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
--          !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate)))
--              minstrel_aggr_check(sta, txrc->skb);
--
-       info->flags |= mi->tx_flags;
- #ifdef CPTCFG_MAC80211_DEBUGFS
-@@ -1866,6 +1839,7 @@ static u32 minstrel_ht_get_expected_thro
- static const struct rate_control_ops mac80211_minstrel_ht = {
-       .name = "minstrel_ht",
-+      .capa = RATE_CTRL_CAPA_AMPDU_TRIGGER,
-       .tx_status_ext = minstrel_ht_tx_status,
-       .get_rate = minstrel_ht_get_rate,
-       .rate_init = minstrel_ht_rate_init,
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3951,6 +3951,29 @@ void ieee80211_txq_schedule_start(struct
- }
- EXPORT_SYMBOL(ieee80211_txq_schedule_start);
-+static void
-+ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
-+                   struct sta_info *sta,
-+                   struct sk_buff *skb)
-+{
-+      struct rate_control_ref *ref = sdata->local->rate_ctrl;
-+      u16 tid;
-+
-+      if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER))
-+              return;
-+
-+      if (!sta || !sta->sta.ht_cap.ht_supported ||
-+          !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO ||
-+          skb->protocol == sdata->control_port_protocol)
-+              return;
-+
-+      tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
-+      if (likely(sta->ampdu_mlme.tid_tx[tid]))
-+              return;
-+
-+      ieee80211_start_tx_ba_session(&sta->sta, tid, 0);
-+}
-+
- void __ieee80211_subif_start_xmit(struct sk_buff *skb,
-                                 struct net_device *dev,
-                                 u32 info_flags,
-@@ -3981,6 +4004,8 @@ void __ieee80211_subif_start_xmit(struct
-               skb_get_hash(skb);
-       }
-+      ieee80211_aggr_check(sdata, sta, skb);
-+
-       if (sta) {
-               struct ieee80211_fast_tx *fast_tx;
-@@ -4244,6 +4269,8 @@ static void ieee80211_8023_xmit(struct i
-       memset(info, 0, sizeof(*info));
-+      ieee80211_aggr_check(sdata, sta, skb);
-+
-       tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-       tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
-       if (tid_tx) {
diff --git a/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch b/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch
deleted file mode 100644 (file)
index 346c646..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-From: Ryder Lee <ryder.lee@mediatek.com>
-Date: Fri, 28 May 2021 14:05:41 +0800
-Subject: [PATCH] mac80211: call ieee80211_tx_h_rate_ctrl() when dequeue
-
-Make ieee80211_tx_h_rate_ctrl() get called on dequeue to improve
-performance since it reduces the turnaround time for rate control.
-
-Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1768,8 +1768,6 @@ static int invoke_tx_handlers_early(stru
-       CALL_TXH(ieee80211_tx_h_ps_buf);
-       CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
-       CALL_TXH(ieee80211_tx_h_select_key);
--      if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
--              CALL_TXH(ieee80211_tx_h_rate_ctrl);
-  txh_done:
-       if (unlikely(res == TX_DROP)) {
-@@ -1802,6 +1800,9 @@ static int invoke_tx_handlers_late(struc
-               goto txh_done;
-       }
-+      if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
-+              CALL_TXH(ieee80211_tx_h_rate_ctrl);
-+
-       CALL_TXH(ieee80211_tx_h_michael_mic_add);
-       CALL_TXH(ieee80211_tx_h_sequence);
-       CALL_TXH(ieee80211_tx_h_fragment);
-@@ -3391,15 +3392,21 @@ out:
-  * Can be called while the sta lock is held. Anything that can cause packets to
-  * be generated will cause deadlock!
-  */
--static void ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
--                                     struct sta_info *sta, u8 pn_offs,
--                                     struct ieee80211_key *key,
--                                     struct sk_buff *skb)
-+static ieee80211_tx_result
-+ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
-+                         struct sta_info *sta, u8 pn_offs,
-+                         struct ieee80211_key *key,
-+                         struct ieee80211_tx_data *tx)
- {
-+      struct sk_buff *skb = tx->skb;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr = (void *)skb->data;
-       u8 tid = IEEE80211_NUM_TIDS;
-+      if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL) &&
-+          ieee80211_tx_h_rate_ctrl(tx) != TX_CONTINUE)
-+              return TX_DROP;
-+
-       if (key)
-               info->control.hw_key = &key->conf;
-@@ -3448,6 +3455,8 @@ static void ieee80211_xmit_fast_finish(s
-                       break;
-               }
-       }
-+
-+      return TX_CONTINUE;
- }
- static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
-@@ -3551,24 +3560,17 @@ static bool ieee80211_xmit_fast(struct i
-       tx.sta = sta;
-       tx.key = fast_tx->key;
--      if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
--              tx.skb = skb;
--              r = ieee80211_tx_h_rate_ctrl(&tx);
--              skb = tx.skb;
--              tx.skb = NULL;
--
--              if (r != TX_CONTINUE) {
--                      if (r != TX_QUEUED)
--                              kfree_skb(skb);
--                      return true;
--              }
--      }
--
-       if (ieee80211_queue_skb(local, sdata, sta, skb))
-               return true;
--      ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs,
--                                 fast_tx->key, skb);
-+      tx.skb = skb;
-+      r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs,
-+                                     fast_tx->key, &tx);
-+      tx.skb = NULL;
-+      if (r == TX_DROP) {
-+              kfree_skb(skb);
-+              return true;
-+      }
-       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-               sdata = container_of(sdata->bss,
-@@ -3685,8 +3687,12 @@ begin:
-                   (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
-                       pn_offs = ieee80211_hdrlen(hdr->frame_control);
--              ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
--                                         tx.key, skb);
-+              r = ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
-+                                             tx.key, &tx);
-+              if (r != TX_CONTINUE) {
-+                      ieee80211_free_txskb(&local->hw, skb);
-+                      goto begin;
-+              }
-       } else {
-               if (invoke_tx_handlers_late(&tx))
-                       goto begin;
diff --git a/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch b/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch
deleted file mode 100644 (file)
index b9f3421..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-From: Ryder Lee <ryder.lee@mediatek.com>
-Date: Fri, 28 May 2021 14:05:43 +0800
-Subject: [PATCH] mac80211: add rate control support for encap offload
-
-The software rate control cannot deal with encap offload, so fix it.
-
-Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
----
-
---- a/net/mac80211/rate.c
-+++ b/net/mac80211/rate.c
-@@ -297,15 +297,11 @@ void ieee80211_check_rate_mask(struct ie
- static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)
- {
-       struct sk_buff *skb = txrc->skb;
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--      __le16 fc;
--
--      fc = hdr->frame_control;
-       return (info->flags & (IEEE80211_TX_CTL_NO_ACK |
-                              IEEE80211_TX_CTL_USE_MINRATE)) ||
--              !ieee80211_is_data(fc);
-+              !ieee80211_is_tx_data(skb);
- }
- static void rc_send_low_basicrate(struct ieee80211_tx_rate *rate,
-@@ -870,7 +866,6 @@ void ieee80211_get_tx_rates(struct ieee8
-                           int max_rates)
- {
-       struct ieee80211_sub_if_data *sdata;
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_supported_band *sband;
-@@ -882,7 +877,7 @@ void ieee80211_get_tx_rates(struct ieee8
-       sdata = vif_to_sdata(vif);
-       sband = sdata->local->hw.wiphy->bands[info->band];
--      if (ieee80211_is_data(hdr->frame_control))
-+      if (ieee80211_is_tx_data(skb))
-               rate_control_apply_mask(sdata, sta, sband, dest, max_rates);
-       if (dest[0].idx < 0)
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -666,6 +666,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
-       u32 len;
-       struct ieee80211_tx_rate_control txrc;
-       struct ieee80211_sta_rates *ratetbl = NULL;
-+      bool encap = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
-       bool assoc = false;
-       memset(&txrc, 0, sizeof(txrc));
-@@ -707,7 +708,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
-        * just wants a probe response.
-        */
-       if (tx->sdata->vif.bss_conf.use_short_preamble &&
--          (ieee80211_is_data(hdr->frame_control) ||
-+          (ieee80211_is_tx_data(tx->skb) ||
-            (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
-               txrc.short_preamble = true;
-@@ -729,7 +730,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
-                "%s: Dropped data frame as no usable bitrate found while "
-                "scanning and associated. Target station: "
-                "%pM on %d GHz band\n",
--               tx->sdata->name, hdr->addr1,
-+               tx->sdata->name,
-+               encap ? ((struct ethhdr *)hdr)->h_dest : hdr->addr1,
-                info->band ? 5 : 2))
-               return TX_DROP;
-@@ -763,7 +765,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
-       if (txrc.reported_rate.idx < 0) {
-               txrc.reported_rate = tx->rate;
--              if (tx->sta && ieee80211_is_data(hdr->frame_control))
-+              if (tx->sta && ieee80211_is_tx_data(tx->skb))
-                       tx->sta->tx_stats.last_rate = txrc.reported_rate;
-       } else if (tx->sta)
-               tx->sta->tx_stats.last_rate = txrc.reported_rate;
-@@ -3675,8 +3677,16 @@ begin:
-       else
-               info->flags &= ~IEEE80211_TX_CTL_AMPDU;
--      if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
-+      if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
-+              if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
-+                      r = ieee80211_tx_h_rate_ctrl(&tx);
-+                      if (r != TX_CONTINUE) {
-+                              ieee80211_free_txskb(&local->hw, skb);
-+                              goto begin;
-+                      }
-+              }
-               goto encap_out;
-+      }
-       if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
-               struct sta_info *sta = container_of(txq->sta, struct sta_info,
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -6765,4 +6765,22 @@ struct sk_buff *ieee80211_get_fils_disco
- struct sk_buff *
- ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
-                                         struct ieee80211_vif *vif);
-+
-+/**
-+ * ieee80211_is_tx_data - check if frame is a data frame
-+ *
-+ * The function is used to check if a frame is a data frame. Frames with
-+ * hardware encapsulation enabled are data frames.
-+ *
-+ * @skb: the frame to be transmitted.
-+ */
-+static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
-+{
-+      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+      struct ieee80211_hdr *hdr = (void *) skb->data;
-+
-+      return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP ||
-+             ieee80211_is_data(hdr->frame_control);
-+}
-+
- #endif /* MAC80211_H */
diff --git a/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch b/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch
deleted file mode 100644 (file)
index 7494734..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 29 Jun 2021 13:25:09 +0200
-Subject: [PATCH] mac80211: fix starting aggregation sessions on mesh
- interfaces
-
-The logic for starting aggregation sessions was recently moved from minstrel_ht
-to mac80211, into the subif tx handler just after the sta lookup.
-Unfortunately this didn't work for mesh interfaces, since the sta lookup is
-deferred until a much later point in time on those.
-Fix this by also calling the aggregation check right after the deferred sta
-lookup.
-
-Fixes: 08a46c642001 ("mac80211: move A-MPDU session check from minstrel_ht to mac80211")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1146,6 +1146,29 @@ static bool ieee80211_tx_prep_agg(struct
-       return queued;
- }
-+static void
-+ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
-+                   struct sta_info *sta,
-+                   struct sk_buff *skb)
-+{
-+      struct rate_control_ref *ref = sdata->local->rate_ctrl;
-+      u16 tid;
-+
-+      if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER))
-+              return;
-+
-+      if (!sta || !sta->sta.ht_cap.ht_supported ||
-+          !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO ||
-+          skb->protocol == sdata->control_port_protocol)
-+              return;
-+
-+      tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
-+      if (likely(sta->ampdu_mlme.tid_tx[tid]))
-+              return;
-+
-+      ieee80211_start_tx_ba_session(&sta->sta, tid, 0);
-+}
-+
- /*
-  * initialises @tx
-  * pass %NULL for the station if unknown, a valid pointer if known
-@@ -1159,6 +1182,7 @@ ieee80211_tx_prepare(struct ieee80211_su
-       struct ieee80211_local *local = sdata->local;
-       struct ieee80211_hdr *hdr;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+      bool aggr_check = false;
-       int tid;
-       memset(tx, 0, sizeof(*tx));
-@@ -1187,8 +1211,10 @@ ieee80211_tx_prepare(struct ieee80211_su
-               } else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
-                       tx->sta = sta_info_get_bss(sdata, hdr->addr1);
-               }
--              if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
-+              if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) {
-                       tx->sta = sta_info_get(sdata, hdr->addr1);
-+                      aggr_check = true;
-+              }
-       }
-       if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
-@@ -1198,8 +1224,12 @@ ieee80211_tx_prepare(struct ieee80211_su
-               struct tid_ampdu_tx *tid_tx;
-               tid = ieee80211_get_tid(hdr);
--
-               tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
-+              if (!tid_tx && aggr_check) {
-+                      ieee80211_aggr_check(sdata, tx->sta, skb);
-+                      tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
-+              }
-+
-               if (tid_tx) {
-                       bool queued;
-@@ -3967,29 +3997,6 @@ void ieee80211_txq_schedule_start(struct
- }
- EXPORT_SYMBOL(ieee80211_txq_schedule_start);
--static void
--ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
--                   struct sta_info *sta,
--                   struct sk_buff *skb)
--{
--      struct rate_control_ref *ref = sdata->local->rate_ctrl;
--      u16 tid;
--
--      if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER))
--              return;
--
--      if (!sta || !sta->sta.ht_cap.ht_supported ||
--          !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO ||
--          skb->protocol == sdata->control_port_protocol)
--              return;
--
--      tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
--      if (likely(sta->ampdu_mlme.tid_tx[tid]))
--              return;
--
--      ieee80211_start_tx_ba_session(&sta->sta, tid, 0);
--}
--
- void __ieee80211_subif_start_xmit(struct sk_buff *skb,
-                                 struct net_device *dev,
-                                 u32 info_flags,
diff --git a/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch b/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch
deleted file mode 100644 (file)
index 6a561b2..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Fri, 18 Jun 2021 13:41:44 +0300
-Subject: [PATCH] mac80211: rearrange struct txq_info for fewer holes
-
-We can slightly decrease the size of struct txq_info by
-rearranging some fields for fewer holes, so do that.
-
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
-Link: https://lore.kernel.org/r/iwlwifi.20210618133832.1bf019a1fe2e.Ib54622b8d6dc1a9a7dc484e573c073119450538b@changeid
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -5,7 +5,7 @@
-  * Copyright 2006-2007        Jiri Benc <jbenc@suse.cz>
-  * Copyright 2007-2010        Johannes Berg <johannes@sipsolutions.net>
-  * Copyright 2013-2015  Intel Mobile Communications GmbH
-- * Copyright (C) 2018-2020 Intel Corporation
-+ * Copyright (C) 2018-2021 Intel Corporation
-  */
- #ifndef IEEE80211_I_H
-@@ -843,9 +843,12 @@ struct txq_info {
-       struct fq_tin tin;
-       struct codel_vars def_cvars;
-       struct codel_stats cstats;
--      struct sk_buff_head frags;
--      struct list_head schedule_order;
-+
-       u16 schedule_round;
-+      struct list_head schedule_order;
-+
-+      struct sk_buff_head frags;
-+
-       unsigned long flags;
-       /* keep last! */
diff --git a/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch b/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch
deleted file mode 100644 (file)
index 49f9349..0000000
+++ /dev/null
@@ -1,1277 +0,0 @@
-From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
-Date: Wed, 23 Jun 2021 15:47:55 +0200
-Subject: [PATCH] mac80211: Switch to a virtual time-based airtime scheduler
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This switches the airtime scheduler in mac80211 to use a virtual
-time-based scheduler instead of the round-robin scheduler used before.
-This has a couple of advantages:
-
-- No need to sync up the round-robin scheduler in firmware/hardware with
-  the round-robin airtime scheduler.
-
-- If several stations are eligible for transmission we can schedule both
-  of them; no need to hard-block the scheduling rotation until the head
-  of the queue has used up its quantum.
-
-- The check of whether a station is eligible for transmission becomes
-  simpler (in ieee80211_txq_may_transmit()).
-
-The drawback is that scheduling becomes slightly more expensive, as we
-need to maintain an rbtree of TXQs sorted by virtual time. This means
-that ieee80211_register_airtime() becomes O(logN) in the number of
-currently scheduled TXQs because it can change the order of the
-scheduled stations. We mitigate this overhead by only resorting when a
-station changes position in the tree, and hopefully N rarely grows too
-big (it's only TXQs currently backlogged, not all associated stations),
-so it shouldn't be too big of an issue.
-
-To prevent divisions in the fast path, we maintain both station sums and
-pre-computed reciprocals of the sums. This turns the fast-path operation
-into a multiplication, with divisions only happening as the number of
-active stations change (to re-compute the current sum of all active
-station weights). To prevent this re-computation of the reciprocal from
-happening too frequently, we use a time-based notion of station
-activity, instead of updating the weight every time a station gets
-scheduled or de-scheduled. As queues can oscillate between empty and
-occupied quite frequently, this can significantly cut down on the number
-of re-computations. It also has the added benefit of making the station
-airtime calculation independent on whether the queue happened to have
-drained at the time an airtime value was accounted.
-
-Co-developed-by: Yibo Zhao <yiboz@codeaurora.org>
-Signed-off-by: Yibo Zhao <yiboz@codeaurora.org>
-Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
-Link: https://lore.kernel.org/r/20210623134755.235545-1-toke@redhat.com
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -6589,9 +6589,6 @@ static inline void ieee80211_txq_schedul
- {
- }
--void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
--                            struct ieee80211_txq *txq, bool force);
--
- /**
-  * ieee80211_schedule_txq - schedule a TXQ for transmission
-  *
-@@ -6604,11 +6601,7 @@ void __ieee80211_schedule_txq(struct iee
-  * The driver may call this function if it has buffered packets for
-  * this TXQ internally.
-  */
--static inline void
--ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
--{
--      __ieee80211_schedule_txq(hw, txq, true);
--}
-+void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
- /**
-  * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
-@@ -6620,12 +6613,8 @@ ieee80211_schedule_txq(struct ieee80211_
-  * The driver may set force=true if it has buffered packets for this TXQ
-  * internally.
-  */
--static inline void
--ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
--                   bool force)
--{
--      __ieee80211_schedule_txq(hw, txq, force);
--}
-+void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
-+                        bool force);
- /**
-  * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1460,6 +1460,38 @@ static void sta_apply_mesh_params(struct
- #endif
- }
-+static void sta_apply_airtime_params(struct ieee80211_local *local,
-+                                   struct sta_info *sta,
-+                                   struct station_parameters *params)
-+{
-+      u8 ac;
-+
-+      for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-+              struct airtime_sched_info *air_sched = &local->airtime[ac];
-+              struct airtime_info *air_info = &sta->airtime[ac];
-+              struct txq_info *txqi;
-+              u8 tid;
-+
-+              spin_lock_bh(&air_sched->lock);
-+              for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
-+                      if (air_info->weight == params->airtime_weight ||
-+                          !sta->sta.txq[tid] ||
-+                          ac != ieee80211_ac_from_tid(tid))
-+                              continue;
-+
-+                      airtime_weight_set(air_info, params->airtime_weight);
-+
-+                      txqi = to_txq_info(sta->sta.txq[tid]);
-+                      if (RB_EMPTY_NODE(&txqi->schedule_order))
-+                              continue;
-+
-+                      ieee80211_update_airtime_weight(local, air_sched,
-+                                                      0, true);
-+              }
-+              spin_unlock_bh(&air_sched->lock);
-+      }
-+}
-+
- static int sta_apply_parameters(struct ieee80211_local *local,
-                               struct sta_info *sta,
-                               struct station_parameters *params)
-@@ -1647,7 +1679,8 @@ static int sta_apply_parameters(struct i
-               sta_apply_mesh_params(local, sta, params);
-       if (params->airtime_weight)
--              sta->airtime_weight = params->airtime_weight;
-+              sta_apply_airtime_params(local, sta, params);
-+
-       /* set the STA state after all sta info from usermode has been set */
-       if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) ||
---- a/net/mac80211/debugfs.c
-+++ b/net/mac80211/debugfs.c
-@@ -216,14 +216,14 @@ static ssize_t aql_txq_limit_read(struct
-                       "VI     %u              %u\n"
-                       "BE     %u              %u\n"
-                       "BK     %u              %u\n",
--                      local->aql_txq_limit_low[IEEE80211_AC_VO],
--                      local->aql_txq_limit_high[IEEE80211_AC_VO],
--                      local->aql_txq_limit_low[IEEE80211_AC_VI],
--                      local->aql_txq_limit_high[IEEE80211_AC_VI],
--                      local->aql_txq_limit_low[IEEE80211_AC_BE],
--                      local->aql_txq_limit_high[IEEE80211_AC_BE],
--                      local->aql_txq_limit_low[IEEE80211_AC_BK],
--                      local->aql_txq_limit_high[IEEE80211_AC_BK]);
-+                      local->airtime[IEEE80211_AC_VO].aql_txq_limit_low,
-+                      local->airtime[IEEE80211_AC_VO].aql_txq_limit_high,
-+                      local->airtime[IEEE80211_AC_VI].aql_txq_limit_low,
-+                      local->airtime[IEEE80211_AC_VI].aql_txq_limit_high,
-+                      local->airtime[IEEE80211_AC_BE].aql_txq_limit_low,
-+                      local->airtime[IEEE80211_AC_BE].aql_txq_limit_high,
-+                      local->airtime[IEEE80211_AC_BK].aql_txq_limit_low,
-+                      local->airtime[IEEE80211_AC_BK].aql_txq_limit_high);
-       return simple_read_from_buffer(user_buf, count, ppos,
-                                      buf, len);
- }
-@@ -255,11 +255,11 @@ static ssize_t aql_txq_limit_write(struc
-       if (ac >= IEEE80211_NUM_ACS)
-               return -EINVAL;
--      q_limit_low_old = local->aql_txq_limit_low[ac];
--      q_limit_high_old = local->aql_txq_limit_high[ac];
-+      q_limit_low_old = local->airtime[ac].aql_txq_limit_low;
-+      q_limit_high_old = local->airtime[ac].aql_txq_limit_high;
--      local->aql_txq_limit_low[ac] = q_limit_low;
--      local->aql_txq_limit_high[ac] = q_limit_high;
-+      local->airtime[ac].aql_txq_limit_low = q_limit_low;
-+      local->airtime[ac].aql_txq_limit_high = q_limit_high;
-       mutex_lock(&local->sta_mtx);
-       list_for_each_entry(sta, &local->sta_list, list) {
-@@ -382,6 +382,46 @@ static const struct file_operations forc
-       .llseek = default_llseek,
- };
-+static ssize_t airtime_read(struct file *file,
-+                          char __user *user_buf,
-+                          size_t count,
-+                          loff_t *ppos)
-+{
-+      struct ieee80211_local *local = file->private_data;
-+      char buf[200];
-+      u64 v_t[IEEE80211_NUM_ACS];
-+      u64 wt[IEEE80211_NUM_ACS];
-+      int len = 0, ac;
-+
-+      for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-+              spin_lock_bh(&local->airtime[ac].lock);
-+              v_t[ac] = local->airtime[ac].v_t;
-+              wt[ac] = local->airtime[ac].weight_sum;
-+              spin_unlock_bh(&local->airtime[ac].lock);
-+      }
-+      len = scnprintf(buf, sizeof(buf),
-+                      "\tVO         VI         BE         BK\n"
-+                      "Virt-t\t%-10llu %-10llu %-10llu %-10llu\n"
-+                      "Weight\t%-10llu %-10llu %-10llu %-10llu\n",
-+                      v_t[0],
-+                      v_t[1],
-+                      v_t[2],
-+                      v_t[3],
-+                      wt[0],
-+                      wt[1],
-+                      wt[2],
-+                      wt[3]);
-+
-+      return simple_read_from_buffer(user_buf, count, ppos,
-+                                     buf, len);
-+}
-+
-+static const struct file_operations airtime_ops = {
-+      .read = airtime_read,
-+      .open = simple_open,
-+      .llseek = default_llseek,
-+};
-+
- #ifdef CONFIG_PM
- static ssize_t reset_write(struct file *file, const char __user *user_buf,
-                          size_t count, loff_t *ppos)
-@@ -632,7 +672,11 @@ void debugfs_hw_add(struct ieee80211_loc
-       if (local->ops->wake_tx_queue)
-               DEBUGFS_ADD_MODE(aqm, 0600);
--      DEBUGFS_ADD_MODE(airtime_flags, 0600);
-+      if (wiphy_ext_feature_isset(local->hw.wiphy,
-+                                  NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) {
-+              DEBUGFS_ADD_MODE(airtime, 0600);
-+              DEBUGFS_ADD_MODE(airtime_flags, 0600);
-+      }
-       DEBUGFS_ADD(aql_txq_limit);
-       debugfs_create_u32("aql_threshold", 0600,
---- a/net/mac80211/debugfs_netdev.c
-+++ b/net/mac80211/debugfs_netdev.c
-@@ -513,6 +513,34 @@ static ssize_t ieee80211_if_fmt_aqm(
- }
- IEEE80211_IF_FILE_R(aqm);
-+static ssize_t ieee80211_if_fmt_airtime(
-+      const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-+{
-+      struct ieee80211_local *local = sdata->local;
-+      struct ieee80211_txq *txq = sdata->vif.txq;
-+      struct airtime_info *air_info;
-+      int len;
-+
-+      if (!txq)
-+              return 0;
-+
-+      spin_lock_bh(&local->airtime[txq->ac].lock);
-+      air_info = to_airtime_info(txq);
-+      len = scnprintf(buf,
-+                      buflen,
-+                      "RX: %llu us\nTX: %llu us\nWeight: %u\n"
-+                      "Virt-T: %lld us\n",
-+                      air_info->rx_airtime,
-+                      air_info->tx_airtime,
-+                      air_info->weight,
-+                      air_info->v_t);
-+      spin_unlock_bh(&local->airtime[txq->ac].lock);
-+
-+      return len;
-+}
-+
-+IEEE80211_IF_FILE_R(airtime);
-+
- IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX);
- /* IBSS attributes */
-@@ -658,8 +686,10 @@ static void add_common_files(struct ieee
-       if (sdata->local->ops->wake_tx_queue &&
-           sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
--          sdata->vif.type != NL80211_IFTYPE_NAN)
-+          sdata->vif.type != NL80211_IFTYPE_NAN) {
-               DEBUGFS_ADD(aqm);
-+              DEBUGFS_ADD(airtime);
-+      }
- }
- static void add_sta_files(struct ieee80211_sub_if_data *sdata)
---- a/net/mac80211/debugfs_sta.c
-+++ b/net/mac80211/debugfs_sta.c
-@@ -202,7 +202,7 @@ static ssize_t sta_airtime_read(struct f
-       size_t bufsz = 400;
-       char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
-       u64 rx_airtime = 0, tx_airtime = 0;
--      s64 deficit[IEEE80211_NUM_ACS];
-+      u64 v_t[IEEE80211_NUM_ACS];
-       ssize_t rv;
-       int ac;
-@@ -210,18 +210,18 @@ static ssize_t sta_airtime_read(struct f
-               return -ENOMEM;
-       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
--              spin_lock_bh(&local->active_txq_lock[ac]);
-+              spin_lock_bh(&local->airtime[ac].lock);
-               rx_airtime += sta->airtime[ac].rx_airtime;
-               tx_airtime += sta->airtime[ac].tx_airtime;
--              deficit[ac] = sta->airtime[ac].deficit;
--              spin_unlock_bh(&local->active_txq_lock[ac]);
-+              v_t[ac] = sta->airtime[ac].v_t;
-+              spin_unlock_bh(&local->airtime[ac].lock);
-       }
-       p += scnprintf(p, bufsz + buf - p,
-               "RX: %llu us\nTX: %llu us\nWeight: %u\n"
--              "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
--              rx_airtime, tx_airtime, sta->airtime_weight,
--              deficit[0], deficit[1], deficit[2], deficit[3]);
-+              "Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
-+              rx_airtime, tx_airtime, sta->airtime[0].weight,
-+              v_t[0], v_t[1], v_t[2], v_t[3]);
-       rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
-       kfree(buf);
-@@ -236,11 +236,11 @@ static ssize_t sta_airtime_write(struct
-       int ac;
-       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
--              spin_lock_bh(&local->active_txq_lock[ac]);
-+              spin_lock_bh(&local->airtime[ac].lock);
-               sta->airtime[ac].rx_airtime = 0;
-               sta->airtime[ac].tx_airtime = 0;
--              sta->airtime[ac].deficit = sta->airtime_weight;
--              spin_unlock_bh(&local->active_txq_lock[ac]);
-+              sta->airtime[ac].v_t = 0;
-+              spin_unlock_bh(&local->airtime[ac].lock);
-       }
-       return count;
-@@ -263,10 +263,10 @@ static ssize_t sta_aql_read(struct file
-               return -ENOMEM;
-       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
--              spin_lock_bh(&local->active_txq_lock[ac]);
-+              spin_lock_bh(&local->airtime[ac].lock);
-               q_limit_l[ac] = sta->airtime[ac].aql_limit_low;
-               q_limit_h[ac] = sta->airtime[ac].aql_limit_high;
--              spin_unlock_bh(&local->active_txq_lock[ac]);
-+              spin_unlock_bh(&local->airtime[ac].lock);
-               q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending);
-       }
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -835,20 +835,16 @@ enum txq_info_flags {
-  * @def_flow: used as a fallback flow when a packet destined to @tin hashes to
-  *    a fq_flow which is already owned by a different tin
-  * @def_cvars: codel vars for @def_flow
-- * @frags: used to keep fragments created after dequeue
-  * @schedule_order: used with ieee80211_local->active_txqs
-- * @schedule_round: counter to prevent infinite loops on TXQ scheduling
-+ * @frags: used to keep fragments created after dequeue
-  */
- struct txq_info {
-       struct fq_tin tin;
-       struct codel_vars def_cvars;
-       struct codel_stats cstats;
--
--      u16 schedule_round;
--      struct list_head schedule_order;
-+      struct rb_node schedule_order;
-       struct sk_buff_head frags;
--
-       unsigned long flags;
-       /* keep last! */
-@@ -925,6 +921,8 @@ struct ieee80211_sub_if_data {
-       struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
-       struct mac80211_qos_map __rcu *qos_map;
-+      struct airtime_info airtime[IEEE80211_NUM_ACS];
-+
-       struct work_struct csa_finalize_work;
-       bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
-       struct cfg80211_chan_def csa_chandef;
-@@ -1137,6 +1135,44 @@ enum mac80211_scan_state {
-       SCAN_ABORT,
- };
-+/**
-+ * struct airtime_sched_info - state used for airtime scheduling and AQL
-+ *
-+ * @lock: spinlock that protects all the fields in this struct
-+ * @active_txqs: rbtree of currently backlogged queues, sorted by virtual time
-+ * @schedule_pos: the current position maintained while a driver walks the tree
-+ *                with ieee80211_next_txq()
-+ * @active_list: list of struct airtime_info structs that were active within
-+ *               the last AIRTIME_ACTIVE_DURATION (100 ms), used to compute
-+ *               weight_sum
-+ * @last_weight_update: used for rate limiting walking active_list
-+ * @last_schedule_time: tracks the last time a transmission was scheduled; used
-+ *                      for catching up v_t if no stations are eligible for
-+ *                      transmission.
-+ * @v_t: global virtual time; queues with v_t < this are eligible for
-+ *       transmission
-+ * @weight_sum: total sum of all active stations used for dividing airtime
-+ * @weight_sum_reciprocal: reciprocal of weight_sum (to avoid divisions in fast
-+ *                         path - see comment above
-+ *                         IEEE80211_RECIPROCAL_DIVISOR_64)
-+ * @aql_txq_limit_low: AQL limit when total outstanding airtime
-+ *                     is < IEEE80211_AQL_THRESHOLD
-+ * @aql_txq_limit_high: AQL limit when total outstanding airtime
-+ *                      is > IEEE80211_AQL_THRESHOLD
-+ */
-+struct airtime_sched_info {
-+      spinlock_t lock;
-+      struct rb_root_cached active_txqs;
-+      struct rb_node *schedule_pos;
-+      struct list_head active_list;
-+      u64 last_weight_update;
-+      u64 last_schedule_activity;
-+      u64 v_t;
-+      u64 weight_sum;
-+      u64 weight_sum_reciprocal;
-+      u32 aql_txq_limit_low;
-+      u32 aql_txq_limit_high;
-+};
- DECLARE_STATIC_KEY_FALSE(aql_disable);
- struct ieee80211_local {
-@@ -1150,13 +1186,8 @@ struct ieee80211_local {
-       struct codel_params cparams;
-       /* protects active_txqs and txqi->schedule_order */
--      spinlock_t active_txq_lock[IEEE80211_NUM_ACS];
--      struct list_head active_txqs[IEEE80211_NUM_ACS];
--      u16 schedule_round[IEEE80211_NUM_ACS];
--
-+      struct airtime_sched_info airtime[IEEE80211_NUM_ACS];
-       u16 airtime_flags;
--      u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
--      u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
-       u32 aql_threshold;
-       atomic_t aql_total_pending_airtime;
-@@ -1574,6 +1605,125 @@ static inline bool txq_has_queue(struct
-       return !(skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets);
- }
-+static inline struct airtime_info *to_airtime_info(struct ieee80211_txq *txq)
-+{
-+      struct ieee80211_sub_if_data *sdata;
-+      struct sta_info *sta;
-+
-+      if (txq->sta) {
-+              sta = container_of(txq->sta, struct sta_info, sta);
-+              return &sta->airtime[txq->ac];
-+      }
-+
-+      sdata = vif_to_sdata(txq->vif);
-+      return &sdata->airtime[txq->ac];
-+}
-+
-+/* To avoid divisions in the fast path, we keep pre-computed reciprocals for
-+ * airtime weight calculations. There are two different weights to keep track
-+ * of: The per-station weight and the sum of weights per phy.
-+ *
-+ * For the per-station weights (kept in airtime_info below), we use 32-bit
-+ * reciprocals with a devisor of 2^19. This lets us keep the multiplications and
-+ * divisions for the station weights as 32-bit operations at the cost of a bit
-+ * of rounding error for high weights; but the choice of divisor keeps rounding
-+ * errors <10% for weights <2^15, assuming no more than 8ms of airtime is
-+ * reported at a time.
-+ *
-+ * For the per-phy sum of weights the values can get higher, so we use 64-bit
-+ * operations for those with a 32-bit divisor, which should avoid any
-+ * significant rounding errors.
-+ */
-+#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL
-+#define IEEE80211_RECIPROCAL_SHIFT_64 32
-+#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U
-+#define IEEE80211_RECIPROCAL_SHIFT_32 19
-+
-+static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight)
-+{
-+      if (air_info->weight == weight)
-+              return;
-+
-+      air_info->weight = weight;
-+      if (weight) {
-+              air_info->weight_reciprocal =
-+                      IEEE80211_RECIPROCAL_DIVISOR_32 / weight;
-+      } else {
-+              air_info->weight_reciprocal = 0;
-+      }
-+}
-+
-+static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched,
-+                                        int weight_sum)
-+{
-+      if (air_sched->weight_sum == weight_sum)
-+              return;
-+
-+      air_sched->weight_sum = weight_sum;
-+      if (air_sched->weight_sum) {
-+              air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64;
-+              do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum);
-+      } else {
-+              air_sched->weight_sum_reciprocal = 0;
-+      }
-+}
-+
-+/* A problem when trying to enforce airtime fairness is that we want to divide
-+ * the airtime between the currently *active* stations. However, basing this on
-+ * the instantaneous queue state of stations doesn't work, as queues tend to
-+ * oscillate very quickly between empty and occupied, leading to the scheduler
-+ * thinking only a single station is active when deciding whether to allow
-+ * transmission (and thus not throttling correctly).
-+ *
-+ * To fix this we use a timer-based notion of activity: a station is considered
-+ * active if it has been scheduled within the last 100 ms; we keep a separate
-+ * list of all the stations considered active in this manner, and lazily update
-+ * the total weight of active stations from this list (filtering the stations in
-+ * the list by their 'last active' time).
-+ *
-+ * We add one additional safeguard to guard against stations that manage to get
-+ * scheduled every 100 ms but don't transmit a lot of data, and thus don't use
-+ * up any airtime. Such stations would be able to get priority for an extended
-+ * period of time if they do start transmitting at full capacity again, and so
-+ * we add an explicit maximum for how far behind a station is allowed to fall in
-+ * the virtual airtime domain. This limit is set to a relatively high value of
-+ * 20 ms because the main mechanism for catching up idle stations is the active
-+ * state as described above; i.e., the hard limit should only be hit in
-+ * pathological cases.
-+ */
-+#define AIRTIME_ACTIVE_DURATION (100 * NSEC_PER_MSEC)
-+#define AIRTIME_MAX_BEHIND 20000 /* 20 ms */
-+
-+static inline bool airtime_is_active(struct airtime_info *air_info, u64 now)
-+{
-+      return air_info->last_scheduled >= now - AIRTIME_ACTIVE_DURATION;
-+}
-+
-+static inline void airtime_set_active(struct airtime_sched_info *air_sched,
-+                                    struct airtime_info *air_info, u64 now)
-+{
-+      air_info->last_scheduled = now;
-+      air_sched->last_schedule_activity = now;
-+      list_move_tail(&air_info->list, &air_sched->active_list);
-+}
-+
-+static inline bool airtime_catchup_v_t(struct airtime_sched_info *air_sched,
-+                                     u64 v_t, u64 now)
-+{
-+      air_sched->v_t = v_t;
-+      return true;
-+}
-+
-+static inline void init_airtime_info(struct airtime_info *air_info,
-+                                   struct airtime_sched_info *air_sched)
-+{
-+      atomic_set(&air_info->aql_tx_pending, 0);
-+      air_info->aql_limit_low = air_sched->aql_txq_limit_low;
-+      air_info->aql_limit_high = air_sched->aql_txq_limit_high;
-+      airtime_weight_set(air_info, IEEE80211_DEFAULT_AIRTIME_WEIGHT);
-+      INIT_LIST_HEAD(&air_info->list);
-+}
-+
- static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
- {
-       return ether_addr_equal(raddr, addr) ||
-@@ -1816,6 +1966,14 @@ int ieee80211_tx_control_port(struct wip
-                             u64 *cookie);
- int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
-                             const u8 *buf, size_t len);
-+void ieee80211_resort_txq(struct ieee80211_hw *hw,
-+                        struct ieee80211_txq *txq);
-+void ieee80211_unschedule_txq(struct ieee80211_hw *hw,
-+                            struct ieee80211_txq *txq,
-+                            bool purge);
-+void ieee80211_update_airtime_weight(struct ieee80211_local *local,
-+                                   struct airtime_sched_info *air_sched,
-+                                   u64 now, bool force);
- /* HT */
- void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -2041,6 +2041,9 @@ int ieee80211_if_add(struct ieee80211_lo
-               }
-       }
-+      for (i = 0; i < IEEE80211_NUM_ACS; i++)
-+              init_airtime_info(&sdata->airtime[i], &local->airtime[i]);
-+
-       ieee80211_set_default_queues(sdata);
-       sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -707,10 +707,13 @@ struct ieee80211_hw *ieee80211_alloc_hw_
-       spin_lock_init(&local->queue_stop_reason_lock);
-       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
--              INIT_LIST_HEAD(&local->active_txqs[i]);
--              spin_lock_init(&local->active_txq_lock[i]);
--              local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L;
--              local->aql_txq_limit_high[i] =
-+              struct airtime_sched_info *air_sched = &local->airtime[i];
-+
-+              air_sched->active_txqs = RB_ROOT_CACHED;
-+              INIT_LIST_HEAD(&air_sched->active_list);
-+              spin_lock_init(&air_sched->lock);
-+              air_sched->aql_txq_limit_low = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L;
-+              air_sched->aql_txq_limit_high =
-                       IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H;
-       }
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1563,12 +1563,8 @@ static void sta_ps_start(struct sta_info
-       for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) {
-               struct ieee80211_txq *txq = sta->sta.txq[tid];
--              struct txq_info *txqi = to_txq_info(txq);
--              spin_lock(&local->active_txq_lock[txq->ac]);
--              if (!list_empty(&txqi->schedule_order))
--                      list_del_init(&txqi->schedule_order);
--              spin_unlock(&local->active_txq_lock[txq->ac]);
-+              ieee80211_unschedule_txq(&local->hw, txq, false);
-               if (txq_has_queue(txq))
-                       set_bit(tid, &sta->txq_buffered_tids);
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -426,15 +426,11 @@ struct sta_info *sta_info_alloc(struct i
-       if (sta_prepare_rate_control(local, sta, gfp))
-               goto free_txq;
--      sta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT;
-       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-               skb_queue_head_init(&sta->ps_tx_buf[i]);
-               skb_queue_head_init(&sta->tx_filtered[i]);
--              sta->airtime[i].deficit = sta->airtime_weight;
--              atomic_set(&sta->airtime[i].aql_tx_pending, 0);
--              sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i];
--              sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i];
-+              init_airtime_info(&sta->airtime[i], &local->airtime[i]);
-       }
-       for (i = 0; i < IEEE80211_NUM_TIDS; i++)
-@@ -1893,24 +1889,59 @@ void ieee80211_sta_set_buffered(struct i
- }
- EXPORT_SYMBOL(ieee80211_sta_set_buffered);
--void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
--                                  u32 tx_airtime, u32 rx_airtime)
-+void ieee80211_register_airtime(struct ieee80211_txq *txq,
-+                              u32 tx_airtime, u32 rx_airtime)
- {
--      struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
--      struct ieee80211_local *local = sta->sdata->local;
--      u8 ac = ieee80211_ac_from_tid(tid);
-+      struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
-+      struct ieee80211_local *local = sdata->local;
-+      u64 weight_sum, weight_sum_reciprocal;
-+      struct airtime_sched_info *air_sched;
-+      struct airtime_info *air_info;
-       u32 airtime = 0;
--      if (sta->local->airtime_flags & AIRTIME_USE_TX)
-+      air_sched = &local->airtime[txq->ac];
-+      air_info = to_airtime_info(txq);
-+
-+      if (local->airtime_flags & AIRTIME_USE_TX)
-               airtime += tx_airtime;
--      if (sta->local->airtime_flags & AIRTIME_USE_RX)
-+      if (local->airtime_flags & AIRTIME_USE_RX)
-               airtime += rx_airtime;
--      spin_lock_bh(&local->active_txq_lock[ac]);
--      sta->airtime[ac].tx_airtime += tx_airtime;
--      sta->airtime[ac].rx_airtime += rx_airtime;
--      sta->airtime[ac].deficit -= airtime;
--      spin_unlock_bh(&local->active_txq_lock[ac]);
-+      /* Weights scale so the unit weight is 256 */
-+      airtime <<= 8;
-+
-+      spin_lock_bh(&air_sched->lock);
-+
-+      air_info->tx_airtime += tx_airtime;
-+      air_info->rx_airtime += rx_airtime;
-+
-+      if (air_sched->weight_sum) {
-+              weight_sum = air_sched->weight_sum;
-+              weight_sum_reciprocal = air_sched->weight_sum_reciprocal;
-+      } else {
-+              weight_sum = air_info->weight;
-+              weight_sum_reciprocal = air_info->weight_reciprocal;
-+      }
-+
-+      /* Round the calculation of global vt */
-+      air_sched->v_t += (u64)((airtime + (weight_sum >> 1)) *
-+                              weight_sum_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_64;
-+      air_info->v_t += (u32)((airtime + (air_info->weight >> 1)) *
-+                             air_info->weight_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_32;
-+      ieee80211_resort_txq(&local->hw, txq);
-+
-+      spin_unlock_bh(&air_sched->lock);
-+}
-+
-+void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
-+                                  u32 tx_airtime, u32 rx_airtime)
-+{
-+      struct ieee80211_txq *txq = pubsta->txq[tid];
-+
-+      if (!txq)
-+              return;
-+
-+      ieee80211_register_airtime(txq, tx_airtime, rx_airtime);
- }
- EXPORT_SYMBOL(ieee80211_sta_register_airtime);
-@@ -2354,7 +2385,7 @@ void sta_set_sinfo(struct sta_info *sta,
-       }
-       if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) {
--              sinfo->airtime_weight = sta->airtime_weight;
-+              sinfo->airtime_weight = sta->airtime[0].weight;
-               sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT);
-       }
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -135,18 +135,25 @@ enum ieee80211_agg_stop_reason {
- #define AIRTIME_USE_TX                BIT(0)
- #define AIRTIME_USE_RX                BIT(1)
-+
- struct airtime_info {
-       u64 rx_airtime;
-       u64 tx_airtime;
--      s64 deficit;
-+      u64 v_t;
-+      u64 last_scheduled;
-+      struct list_head list;
-       atomic_t aql_tx_pending; /* Estimated airtime for frames pending */
-       u32 aql_limit_low;
-       u32 aql_limit_high;
-+      u32 weight_reciprocal;
-+      u16 weight;
- };
- void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
-                                         struct sta_info *sta, u8 ac,
-                                         u16 tx_airtime, bool tx_completed);
-+void ieee80211_register_airtime(struct ieee80211_txq *txq,
-+                              u32 tx_airtime, u32 rx_airtime);
- struct sta_info;
-@@ -515,7 +522,6 @@ struct ieee80211_fragment_cache {
-  * @tid_seq: per-TID sequence numbers for sending to this STA
-  * @airtime: per-AC struct airtime_info describing airtime statistics for this
-  *    station
-- * @airtime_weight: station weight for airtime fairness calculation purposes
-  * @ampdu_mlme: A-MPDU state machine state
-  * @mesh: mesh STA information
-  * @debugfs_dir: debug filesystem directory dentry
-@@ -646,7 +652,6 @@ struct sta_info {
-       u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
-       struct airtime_info airtime[IEEE80211_NUM_ACS];
--      u16 airtime_weight;
-       /*
-        * Aggregation information, locked with lock.
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -970,6 +970,25 @@ static void __ieee80211_tx_status(struct
-               if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked)
-                       ieee80211_frame_acked(sta, skb);
-+      } else if (wiphy_ext_feature_isset(local->hw.wiphy,
-+                                         NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) {
-+              struct ieee80211_sub_if_data *sdata;
-+              struct ieee80211_txq *txq;
-+              u32 airtime;
-+
-+              /* Account airtime to multicast queue */
-+              sdata = ieee80211_sdata_from_skb(local, skb);
-+
-+              if (sdata && (txq = sdata->vif.txq)) {
-+                      airtime = info->status.tx_time ?:
-+                              ieee80211_calc_expected_tx_airtime(hw,
-+                                                                 &sdata->vif,
-+                                                                 NULL,
-+                                                                 skb->len,
-+                                                                 false);
-+
-+                      ieee80211_register_airtime(txq, airtime, 0);
-+              }
-       }
-       /* SNMP counters
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -18,6 +18,7 @@
- #include <linux/bitmap.h>
- #include <linux/rcupdate.h>
- #include <linux/export.h>
-+#include <linux/timekeeping.h>
- #include <net/net_namespace.h>
- #include <net/ieee80211_radiotap.h>
- #include <net/cfg80211.h>
-@@ -1479,7 +1480,7 @@ void ieee80211_txq_init(struct ieee80211
-       codel_vars_init(&txqi->def_cvars);
-       codel_stats_init(&txqi->cstats);
-       __skb_queue_head_init(&txqi->frags);
--      INIT_LIST_HEAD(&txqi->schedule_order);
-+      RB_CLEAR_NODE(&txqi->schedule_order);
-       txqi->txq.vif = &sdata->vif;
-@@ -1523,9 +1524,7 @@ void ieee80211_txq_purge(struct ieee8021
-       ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
-       spin_unlock_bh(&fq->lock);
--      spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
--      list_del_init(&txqi->schedule_order);
--      spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
-+      ieee80211_unschedule_txq(&local->hw, &txqi->txq, true);
- }
- void ieee80211_txq_set_params(struct ieee80211_local *local)
-@@ -3812,102 +3811,259 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue);
- struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
- {
-       struct ieee80211_local *local = hw_to_local(hw);
-+      struct airtime_sched_info *air_sched;
-+      u64 now = ktime_get_boottime_ns();
-       struct ieee80211_txq *ret = NULL;
--      struct txq_info *txqi = NULL, *head = NULL;
--      bool found_eligible_txq = false;
-+      struct airtime_info *air_info;
-+      struct txq_info *txqi = NULL;
-+      struct rb_node *node;
-+      bool first = false;
--      spin_lock_bh(&local->active_txq_lock[ac]);
-+      air_sched = &local->airtime[ac];
-+      spin_lock_bh(&air_sched->lock);
-- begin:
--      txqi = list_first_entry_or_null(&local->active_txqs[ac],
--                                      struct txq_info,
--                                      schedule_order);
--      if (!txqi)
-+      node = air_sched->schedule_pos;
-+
-+begin:
-+      if (!node) {
-+              node = rb_first_cached(&air_sched->active_txqs);
-+              first = true;
-+      } else {
-+              node = rb_next(node);
-+      }
-+
-+      if (!node)
-               goto out;
--      if (txqi == head) {
--              if (!found_eligible_txq)
--                      goto out;
--              else
--                      found_eligible_txq = false;
-+      txqi = container_of(node, struct txq_info, schedule_order);
-+      air_info = to_airtime_info(&txqi->txq);
-+
-+      if (air_info->v_t > air_sched->v_t &&
-+          (!first || !airtime_catchup_v_t(air_sched, air_info->v_t, now)))
-+              goto out;
-+
-+      if (!ieee80211_txq_airtime_check(hw, &txqi->txq)) {
-+              first = false;
-+              goto begin;
-       }
--      if (!head)
--              head = txqi;
-+      air_sched->schedule_pos = node;
-+      air_sched->last_schedule_activity = now;
-+      ret = &txqi->txq;
-+out:
-+      spin_unlock_bh(&air_sched->lock);
-+      return ret;
-+}
-+EXPORT_SYMBOL(ieee80211_next_txq);
--      if (txqi->txq.sta) {
--              struct sta_info *sta = container_of(txqi->txq.sta,
--                                                  struct sta_info, sta);
--              bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
--              s64 deficit = sta->airtime[txqi->txq.ac].deficit;
-+static void __ieee80211_insert_txq(struct rb_root_cached *root,
-+                                 struct txq_info *txqi)
-+{
-+      struct rb_node **new = &root->rb_root.rb_node;
-+      struct airtime_info *old_air, *new_air;
-+      struct rb_node *parent = NULL;
-+      struct txq_info *__txqi;
-+      bool leftmost = true;
-+
-+      while (*new) {
-+              parent = *new;
-+              __txqi = rb_entry(parent, struct txq_info, schedule_order);
-+              old_air = to_airtime_info(&__txqi->txq);
-+              new_air = to_airtime_info(&txqi->txq);
--              if (aql_check)
--                      found_eligible_txq = true;
-+              if (new_air->v_t <= old_air->v_t) {
-+                      new = &parent->rb_left;
-+              } else {
-+                      new = &parent->rb_right;
-+                      leftmost = false;
-+              }
-+      }
--              if (deficit < 0)
--                      sta->airtime[txqi->txq.ac].deficit +=
--                              sta->airtime_weight;
--
--              if (deficit < 0 || !aql_check) {
--                      list_move_tail(&txqi->schedule_order,
--                                     &local->active_txqs[txqi->txq.ac]);
--                      goto begin;
-+      rb_link_node(&txqi->schedule_order, parent, new);
-+      rb_insert_color_cached(&txqi->schedule_order, root, leftmost);
-+}
-+
-+void ieee80211_resort_txq(struct ieee80211_hw *hw,
-+                        struct ieee80211_txq *txq)
-+{
-+      struct airtime_info *air_info = to_airtime_info(txq);
-+      struct ieee80211_local *local = hw_to_local(hw);
-+      struct txq_info *txqi = to_txq_info(txq);
-+      struct airtime_sched_info *air_sched;
-+
-+      air_sched = &local->airtime[txq->ac];
-+
-+      lockdep_assert_held(&air_sched->lock);
-+
-+      if (!RB_EMPTY_NODE(&txqi->schedule_order)) {
-+              struct airtime_info *a_prev = NULL, *a_next = NULL;
-+              struct txq_info *t_prev, *t_next;
-+              struct rb_node *n_prev, *n_next;
-+
-+              /* Erasing a node can cause an expensive rebalancing operation,
-+               * so we check the previous and next nodes first and only remove
-+               * and re-insert if the current node is not already in the
-+               * correct position.
-+               */
-+              if ((n_prev = rb_prev(&txqi->schedule_order)) != NULL) {
-+                      t_prev = container_of(n_prev, struct txq_info,
-+                                            schedule_order);
-+                      a_prev = to_airtime_info(&t_prev->txq);
-+              }
-+
-+              if ((n_next = rb_next(&txqi->schedule_order)) != NULL) {
-+                      t_next = container_of(n_next, struct txq_info,
-+                                            schedule_order);
-+                      a_next = to_airtime_info(&t_next->txq);
-               }
-+
-+              if ((!a_prev || a_prev->v_t <= air_info->v_t) &&
-+                  (!a_next || a_next->v_t > air_info->v_t))
-+                      return;
-+
-+              if (air_sched->schedule_pos == &txqi->schedule_order)
-+                      air_sched->schedule_pos = n_prev;
-+
-+              rb_erase_cached(&txqi->schedule_order,
-+                              &air_sched->active_txqs);
-+              RB_CLEAR_NODE(&txqi->schedule_order);
-+              __ieee80211_insert_txq(&air_sched->active_txqs, txqi);
-       }
-+}
-+
-+void ieee80211_update_airtime_weight(struct ieee80211_local *local,
-+                                   struct airtime_sched_info *air_sched,
-+                                   u64 now, bool force)
-+{
-+      struct airtime_info *air_info, *tmp;
-+      u64 weight_sum = 0;
-+
-+      if (unlikely(!now))
-+              now = ktime_get_boottime_ns();
-+
-+      lockdep_assert_held(&air_sched->lock);
-+
-+      if (!force && (air_sched->last_weight_update <
-+                     now - AIRTIME_ACTIVE_DURATION))
-+              return;
-+
-+      list_for_each_entry_safe(air_info, tmp,
-+                               &air_sched->active_list, list) {
-+              if (airtime_is_active(air_info, now))
-+                      weight_sum += air_info->weight;
-+              else
-+                      list_del_init(&air_info->list);
-+      }
-+      airtime_weight_sum_set(air_sched, weight_sum);
-+      air_sched->last_weight_update = now;
-+}
-+void ieee80211_schedule_txq(struct ieee80211_hw *hw,
-+                          struct ieee80211_txq *txq)
-+      __acquires(txq_lock) __releases(txq_lock)
-+{
-+      struct ieee80211_local *local = hw_to_local(hw);
-+      struct txq_info *txqi = to_txq_info(txq);
-+      struct airtime_sched_info *air_sched;
-+      u64 now = ktime_get_boottime_ns();
-+      struct airtime_info *air_info;
-+      u8 ac = txq->ac;
-+      bool was_active;
--      if (txqi->schedule_round == local->schedule_round[ac])
-+      air_sched = &local->airtime[ac];
-+      air_info = to_airtime_info(txq);
-+
-+      spin_lock_bh(&air_sched->lock);
-+      was_active = airtime_is_active(air_info, now);
-+      airtime_set_active(air_sched, air_info, now);
-+
-+      if (!RB_EMPTY_NODE(&txqi->schedule_order))
-               goto out;
--      list_del_init(&txqi->schedule_order);
--      txqi->schedule_round = local->schedule_round[ac];
--      ret = &txqi->txq;
-+      /* If the station has been inactive for a while, catch up its v_t so it
-+       * doesn't get indefinite priority; see comment above the definition of
-+       * AIRTIME_MAX_BEHIND.
-+       */
-+      if ((!was_active && air_info->v_t < air_sched->v_t) ||
-+          air_info->v_t < air_sched->v_t - AIRTIME_MAX_BEHIND)
-+              air_info->v_t = air_sched->v_t;
-+
-+      ieee80211_update_airtime_weight(local, air_sched, now, !was_active);
-+      __ieee80211_insert_txq(&air_sched->active_txqs, txqi);
- out:
--      spin_unlock_bh(&local->active_txq_lock[ac]);
--      return ret;
-+      spin_unlock_bh(&air_sched->lock);
- }
--EXPORT_SYMBOL(ieee80211_next_txq);
-+EXPORT_SYMBOL(ieee80211_schedule_txq);
--void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
--                            struct ieee80211_txq *txq,
--                            bool force)
-+static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw,
-+                                     struct ieee80211_txq *txq,
-+                                     bool purge)
- {
-       struct ieee80211_local *local = hw_to_local(hw);
-       struct txq_info *txqi = to_txq_info(txq);
-+      struct airtime_sched_info *air_sched;
-+      struct airtime_info *air_info;
--      spin_lock_bh(&local->active_txq_lock[txq->ac]);
-+      air_sched = &local->airtime[txq->ac];
-+      air_info = to_airtime_info(&txqi->txq);
--      if (list_empty(&txqi->schedule_order) &&
--          (force || !skb_queue_empty(&txqi->frags) ||
--           txqi->tin.backlog_packets)) {
--              /* If airtime accounting is active, always enqueue STAs at the
--               * head of the list to ensure that they only get moved to the
--               * back by the airtime DRR scheduler once they have a negative
--               * deficit. A station that already has a negative deficit will
--               * get immediately moved to the back of the list on the next
--               * call to ieee80211_next_txq().
--               */
--              if (txqi->txq.sta && local->airtime_flags &&
--                  wiphy_ext_feature_isset(local->hw.wiphy,
--                                          NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
--                      list_add(&txqi->schedule_order,
--                               &local->active_txqs[txq->ac]);
--              else
--                      list_add_tail(&txqi->schedule_order,
--                                    &local->active_txqs[txq->ac]);
-+      lockdep_assert_held(&air_sched->lock);
-+
-+      if (purge) {
-+              list_del_init(&air_info->list);
-+              ieee80211_update_airtime_weight(local, air_sched, 0, true);
-       }
--      spin_unlock_bh(&local->active_txq_lock[txq->ac]);
-+      if (RB_EMPTY_NODE(&txqi->schedule_order))
-+              return;
-+
-+      if (air_sched->schedule_pos == &txqi->schedule_order)
-+              air_sched->schedule_pos = rb_prev(&txqi->schedule_order);
-+
-+      if (!purge)
-+              airtime_set_active(air_sched, air_info,
-+                                 ktime_get_boottime_ns());
-+
-+      rb_erase_cached(&txqi->schedule_order,
-+                      &air_sched->active_txqs);
-+      RB_CLEAR_NODE(&txqi->schedule_order);
-+}
-+
-+void ieee80211_unschedule_txq(struct ieee80211_hw *hw,
-+                            struct ieee80211_txq *txq,
-+                            bool purge)
-+      __acquires(txq_lock) __releases(txq_lock)
-+{
-+      struct ieee80211_local *local = hw_to_local(hw);
-+
-+      spin_lock_bh(&local->airtime[txq->ac].lock);
-+      __ieee80211_unschedule_txq(hw, txq, purge);
-+      spin_unlock_bh(&local->airtime[txq->ac].lock);
-+}
-+
-+void ieee80211_return_txq(struct ieee80211_hw *hw,
-+                        struct ieee80211_txq *txq, bool force)
-+{
-+      struct ieee80211_local *local = hw_to_local(hw);
-+      struct txq_info *txqi = to_txq_info(txq);
-+
-+      spin_lock_bh(&local->airtime[txq->ac].lock);
-+
-+      if (!RB_EMPTY_NODE(&txqi->schedule_order) && !force &&
-+          !txq_has_queue(txq))
-+              __ieee80211_unschedule_txq(hw, txq, false);
-+
-+      spin_unlock_bh(&local->airtime[txq->ac].lock);
- }
--EXPORT_SYMBOL(__ieee80211_schedule_txq);
-+EXPORT_SYMBOL(ieee80211_return_txq);
- DEFINE_STATIC_KEY_FALSE(aql_disable);
- bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
-                                struct ieee80211_txq *txq)
- {
--      struct sta_info *sta;
-+      struct airtime_info *air_info = to_airtime_info(txq);
-       struct ieee80211_local *local = hw_to_local(hw);
-       if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
-@@ -3922,15 +4078,12 @@ bool ieee80211_txq_airtime_check(struct
-       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)
-+      if (atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_low)
-               return true;
-       if (atomic_read(&local->aql_total_pending_airtime) <
-           local->aql_threshold &&
--          atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
--          sta->airtime[txq->ac].aql_limit_high)
-+          atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_high)
-               return true;
-       return false;
-@@ -3940,60 +4093,59 @@ EXPORT_SYMBOL(ieee80211_txq_airtime_chec
- bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
-                               struct ieee80211_txq *txq)
- {
-+      struct txq_info *first_txqi = NULL, *txqi = to_txq_info(txq);
-       struct ieee80211_local *local = hw_to_local(hw);
--      struct txq_info *iter, *tmp, *txqi = to_txq_info(txq);
--      struct sta_info *sta;
--      u8 ac = txq->ac;
-+      struct airtime_sched_info *air_sched;
-+      struct airtime_info *air_info;
-+      struct rb_node *node = NULL;
-+      bool ret = false;
-+      u64 now;
--      spin_lock_bh(&local->active_txq_lock[ac]);
--      if (!txqi->txq.sta)
--              goto out;
-+      if (!ieee80211_txq_airtime_check(hw, txq))
-+              return false;
-+
-+      air_sched = &local->airtime[txq->ac];
-+      spin_lock_bh(&air_sched->lock);
--      if (list_empty(&txqi->schedule_order))
-+      if (RB_EMPTY_NODE(&txqi->schedule_order))
-               goto out;
--      list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
--                               schedule_order) {
--              if (iter == txqi)
--                      break;
-+      now = ktime_get_boottime_ns();
--              if (!iter->txq.sta) {
--                      list_move_tail(&iter->schedule_order,
--                                     &local->active_txqs[ac]);
--                      continue;
--              }
--              sta = container_of(iter->txq.sta, struct sta_info, sta);
--              if (sta->airtime[ac].deficit < 0)
--                      sta->airtime[ac].deficit += sta->airtime_weight;
--              list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
-+      /* Like in ieee80211_next_txq(), make sure the first station in the
-+       * scheduling order is eligible for transmission to avoid starvation.
-+       */
-+      node = rb_first_cached(&air_sched->active_txqs);
-+      if (node) {
-+              first_txqi = container_of(node, struct txq_info,
-+                                        schedule_order);
-+              air_info = to_airtime_info(&first_txqi->txq);
-+
-+              if (air_sched->v_t < air_info->v_t)
-+                      airtime_catchup_v_t(air_sched, air_info->v_t, now);
-       }
--      sta = container_of(txqi->txq.sta, struct sta_info, sta);
--      if (sta->airtime[ac].deficit >= 0)
--              goto out;
--
--      sta->airtime[ac].deficit += sta->airtime_weight;
--      list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
--      spin_unlock_bh(&local->active_txq_lock[ac]);
-+      air_info = to_airtime_info(&txqi->txq);
-+      if (air_info->v_t <= air_sched->v_t) {
-+              air_sched->last_schedule_activity = now;
-+              ret = true;
-+      }
--      return false;
- out:
--      if (!list_empty(&txqi->schedule_order))
--              list_del_init(&txqi->schedule_order);
--      spin_unlock_bh(&local->active_txq_lock[ac]);
--
--      return true;
-+      spin_unlock_bh(&air_sched->lock);
-+      return ret;
- }
- EXPORT_SYMBOL(ieee80211_txq_may_transmit);
- void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
- {
-       struct ieee80211_local *local = hw_to_local(hw);
-+      struct airtime_sched_info *air_sched = &local->airtime[ac];
--      spin_lock_bh(&local->active_txq_lock[ac]);
--      local->schedule_round[ac]++;
--      spin_unlock_bh(&local->active_txq_lock[ac]);
-+      spin_lock_bh(&air_sched->lock);
-+      air_sched->schedule_pos = NULL;
-+      spin_unlock_bh(&air_sched->lock);
- }
- EXPORT_SYMBOL(ieee80211_txq_schedule_start);
diff --git a/package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch b/package/kernel/mac80211/patches/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch
deleted file mode 100644 (file)
index e195d0b..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Ryder Lee <ryder.lee@mediatek.com>
-Date: Fri, 18 Jun 2021 04:38:59 +0800
-Subject: [PATCH] mac80211: check per vif offload_flags in Tx path
-
-offload_flags has been introduced to indicate encap status of each interface.
-An interface can encap offload at runtime, or if it has some extra limitations
-it can simply override the flags, so it's more flexible to check offload_flags
-in Tx path.
-
-Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
-Link: https://lore.kernel.org/r/177785418cf407808bf3a44760302d0647076990.1623961575.git.ryder.lee@mediatek.com
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3318,6 +3318,9 @@ static bool ieee80211_amsdu_aggregate(st
-       if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
-               return false;
-+      if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
-+              return false;
-+
-       if (skb_is_gso(skb))
-               return false;
index 69893751802a3b8433f354bb320ec71f4a247ef6..f2ebede15ab0c4104c107d759cc94243b2b710b4 100644 (file)
@@ -23,8 +23,8 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -1253,6 +1253,27 @@ struct cfg80211_csa_settings {
- #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
+@@ -1258,6 +1258,27 @@ struct cfg80211_csa_settings {
+ };
  
  /**
 + * struct cfg80211_color_change_settings - color change settings
@@ -51,7 +51,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
   * struct iface_combination_params - input parameters for interface combinations
   *
   * Used to pass interface combination parameters
-@@ -3991,6 +4012,8 @@ struct mgmt_frame_regs {
+@@ -4000,6 +4021,8 @@ struct mgmt_frame_regs {
   *    given TIDs. This callback may sleep.
   *
   * @set_sar_specs: Update the SAR (TX power) settings.
@@ -60,7 +60,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
   */
  struct cfg80211_ops {
        int     (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
-@@ -4318,6 +4341,9 @@ struct cfg80211_ops {
+@@ -4327,6 +4350,9 @@ struct cfg80211_ops {
                                    const u8 *peer, u8 tids);
        int     (*set_sar_specs)(struct wiphy *wiphy,
                                 struct cfg80211_sar_specs *sar);
@@ -70,7 +70,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  };
  
  /*
-@@ -8209,4 +8235,70 @@ void cfg80211_update_owe_info_event(stru
+@@ -8226,4 +8252,70 @@ void cfg80211_update_owe_info_event(stru
   */
  void cfg80211_bss_flush(struct wiphy *wiphy);
  
@@ -210,7 +210,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        /* add attributes here, update the policy in nl80211.c */
  
        __NL80211_ATTR_AFTER_LAST,
-@@ -5950,6 +5989,9 @@ enum nl80211_feature_flags {
+@@ -5953,6 +5992,9 @@ enum nl80211_feature_flags {
   *      frame protection for all management frames exchanged during the
   *      negotiation and range measurement procedure.
   *
@@ -220,7 +220,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
   * @NUM_NL80211_EXT_FEATURES: number of extended features.
   * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
   */
-@@ -6014,6 +6056,7 @@ enum nl80211_ext_feature_index {
+@@ -6017,6 +6059,7 @@ enum nl80211_ext_feature_index {
        NL80211_EXT_FEATURE_SECURE_LTF,
        NL80211_EXT_FEATURE_SECURE_RTT,
        NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
@@ -241,7 +241,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  };
  
  /* policy for the key attributes */
-@@ -14815,6 +14819,106 @@ bad_tid_conf:
+@@ -14823,6 +14827,106 @@ bad_tid_conf:
        return ret;
  }
  
@@ -348,7 +348,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  #define NL80211_FLAG_NEED_WIPHY               0x01
  #define NL80211_FLAG_NEED_NETDEV      0x02
  #define NL80211_FLAG_NEED_RTNL                0x04
-@@ -15815,6 +15919,14 @@ static const struct genl_small_ops nl802
+@@ -15823,6 +15927,14 @@ static const struct genl_small_ops nl802
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
        },
@@ -363,7 +363,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  };
  
  static struct genl_family nl80211_fam __genl_ro_after_init = {
-@@ -17446,6 +17558,51 @@ void cfg80211_ch_switch_started_notify(s
+@@ -17454,6 +17566,51 @@ void cfg80211_ch_switch_started_notify(s
  }
  EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
  
@@ -417,7 +417,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
                     const struct cfg80211_chan_def *chandef,
 --- a/net/wireless/rdev-ops.h
 +++ b/net/wireless/rdev-ops.h
-@@ -1358,4 +1358,17 @@ static inline int rdev_set_sar_specs(str
+@@ -1368,4 +1368,17 @@ static inline int rdev_set_sar_specs(str
        return ret;
  }
  
@@ -437,7 +437,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  #endif /* __CFG80211_RDEV_OPS */
 --- a/net/wireless/trace.h
 +++ b/net/wireless/trace.h
-@@ -3565,6 +3565,52 @@ TRACE_EVENT(rdev_set_sar_specs,
+@@ -3597,6 +3597,52 @@ TRACE_EVENT(rdev_set_sar_specs,
                  WIPHY_PR_ARG, __entry->type, __entry->num)
  );
  
index 320570d0340ce8fd03aea33d429fa21d3963e8e0..196c8e10af9d38c83aa8699c664c1e9821febe80 100644 (file)
@@ -19,7 +19,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -1713,6 +1713,10 @@ enum ieee80211_offload_flags {
+@@ -1715,6 +1715,10 @@ enum ieee80211_offload_flags {
   *    protected by fq->lock.
   * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see
   *    &enum ieee80211_offload_flags.
@@ -30,7 +30,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
   */
  struct ieee80211_vif {
        enum nl80211_iftype type;
-@@ -1741,6 +1745,9 @@ struct ieee80211_vif {
+@@ -1743,6 +1747,9 @@ struct ieee80211_vif {
  
        bool txqs_stopped[IEEE80211_NUM_ACS];
  
@@ -40,7 +40,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        /* must be last */
        u8 drv_priv[] __aligned(sizeof(void *));
  };
-@@ -4992,6 +4999,16 @@ void ieee80211_csa_finish(struct ieee802
+@@ -5016,6 +5023,16 @@ void ieee80211_csa_finish(struct ieee802
  bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif);
  
  /**
@@ -57,7 +57,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
   * ieee80211_proberesp_get - retrieve a Probe Response template
   * @hw: pointer obtained from ieee80211_alloc_hw().
   * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-@@ -6756,6 +6773,18 @@ ieee80211_get_unsol_bcast_probe_resp_tmp
+@@ -6780,6 +6797,18 @@ ieee80211_get_unsol_bcast_probe_resp_tmp
                                          struct ieee80211_vif *vif);
  
  /**
@@ -161,7 +161,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        if (err < 0)
                return err;
        ieee80211_bss_info_change_notify(sdata, err);
-@@ -3163,7 +3171,7 @@ static int ieee80211_set_after_csa_beaco
+@@ -3155,7 +3163,7 @@ static int ieee80211_set_after_csa_beaco
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_AP:
                err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
@@ -170,7 +170,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
                kfree(sdata->u.ap.next_beacon);
                sdata->u.ap.next_beacon = NULL;
  
-@@ -3329,7 +3337,7 @@ static int ieee80211_set_csa_beacon(stru
+@@ -3321,7 +3329,7 @@ static int ieee80211_set_csa_beacon(stru
                csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
                csa.count = params->count;
  
@@ -179,7 +179,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
                if (err < 0) {
                        kfree(sdata->u.ap.next_beacon);
                        return err;
-@@ -3418,6 +3426,15 @@ static int ieee80211_set_csa_beacon(stru
+@@ -3410,6 +3418,15 @@ static int ieee80211_set_csa_beacon(stru
        return 0;
  }
  
@@ -195,7 +195,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  static int
  __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
                           struct cfg80211_csa_settings *params)
-@@ -3486,6 +3503,10 @@ __ieee80211_channel_switch(struct wiphy
+@@ -3478,6 +3495,10 @@ __ieee80211_channel_switch(struct wiphy
                goto out;
        }
  
@@ -206,7 +206,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        err = ieee80211_set_csa_beacon(sdata, params, &changed);
        if (err) {
                ieee80211_vif_unreserve_chanctx(sdata);
-@@ -4137,6 +4158,196 @@ static int ieee80211_set_sar_specs(struc
+@@ -4129,6 +4150,196 @@ static int ieee80211_set_sar_specs(struc
        return local->ops->set_sar_specs(&local->hw, sar);
  }
  
@@ -403,7 +403,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  const struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
-@@ -4240,4 +4451,5 @@ const struct cfg80211_ops mac80211_confi
+@@ -4232,4 +4443,5 @@ const struct cfg80211_ops mac80211_confi
        .set_tid_config = ieee80211_set_tid_config,
        .reset_tid_config = ieee80211_reset_tid_config,
        .set_sar_specs = ieee80211_set_sar_specs,
@@ -433,7 +433,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */
        struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */
  
-@@ -1895,6 +1903,9 @@ void ieee80211_csa_finalize_work(struct
+@@ -1891,6 +1899,9 @@ void ieee80211_csa_finalize_work(struct
  int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
                             struct cfg80211_csa_settings *params);
  
@@ -453,7 +453,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  
        cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
  
-@@ -1595,6 +1596,7 @@ static void ieee80211_setup_sdata(struct
+@@ -1608,6 +1609,7 @@ static void ieee80211_setup_sdata(struct
        INIT_WORK(&sdata->work, ieee80211_iface_work);
        INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
        INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
@@ -463,7 +463,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -4784,11 +4784,11 @@ static int ieee80211_beacon_add_tim(stru
+@@ -4796,11 +4796,11 @@ static int ieee80211_beacon_add_tim(stru
  static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
                                        struct beacon_data *beacon)
  {
@@ -477,7 +477,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_AP:
-@@ -4808,21 +4808,27 @@ static void ieee80211_set_beacon_cntdwn(
+@@ -4820,21 +4820,27 @@ static void ieee80211_set_beacon_cntdwn(
        }
  
        rcu_read_lock();
@@ -514,7 +514,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        }
        rcu_read_unlock();
  }
-@@ -5032,6 +5038,7 @@ __ieee80211_beacon_get(struct ieee80211_
+@@ -5044,6 +5050,7 @@ __ieee80211_beacon_get(struct ieee80211_
                        if (offs) {
                                offs->tim_offset = beacon->head_len;
                                offs->tim_length = skb->len - beacon->head_len;
index cf45c6d072217fa5171183f8b31abee6884471e0..6bb7dd7df4db32a32c01da13476f3bfe7e93d6e0 100644 (file)
@@ -73,7 +73,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
                        } u;
                } __packed action;
        } u;
-@@ -2879,6 +2925,7 @@ enum ieee80211_eid {
+@@ -2881,6 +2927,7 @@ enum ieee80211_eid {
        WLAN_EID_AID_RESPONSE = 211,
        WLAN_EID_S1G_BCN_COMPAT = 213,
        WLAN_EID_S1G_SHORT_BCN_INTERVAL = 214,
@@ -81,7 +81,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        WLAN_EID_S1G_CAPABILITIES = 217,
        WLAN_EID_VENDOR_SPECIFIC = 221,
        WLAN_EID_QOS_PARAMETER = 222,
-@@ -2947,6 +2994,7 @@ enum ieee80211_category {
+@@ -2950,6 +2997,7 @@ enum ieee80211_category {
        WLAN_CATEGORY_FST = 18,
        WLAN_CATEGORY_UNPROT_DMG = 20,
        WLAN_CATEGORY_VHT = 21,
@@ -89,7 +89,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
        WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
  };
-@@ -3020,6 +3068,20 @@ enum ieee80211_key_len {
+@@ -3023,6 +3071,20 @@ enum ieee80211_key_len {
        WLAN_KEY_LEN_BIP_GMAC_256 = 32,
  };
  
index 2b7bdabfe3d99936043478b8489ab9e67179396a..f0f864c7e7b9e883891a0d415a2f602b081f1888 100644 (file)
@@ -1,3 +1,4 @@
+From f5a4c24e689f54e66201f04d343bdd2e8a1d7923 Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
 Date: Mon, 23 Aug 2021 20:02:39 +0200
 Subject: [PATCH] mac80211: introduce individual TWT support in AP mode
@@ -24,10 +25,33 @@ Link: https://lore.kernel.org/r/257512f2e22ba42b9f2624942a128dd8f141de4b.1629741
  fix to use ieee80211_get_he_iftype_cap() correctly]
 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 ---
+ include/net/mac80211.h     |  12 +++
+ net/mac80211/driver-ops.h  |  36 ++++++++
+ net/mac80211/ieee80211_i.h |   6 ++
+ net/mac80211/iface.c       |  41 +++++++++
+ net/mac80211/rx.c          |  73 +++++++++++++++
+ net/mac80211/s1g.c         | 180 +++++++++++++++++++++++++++++++++++++
+ net/mac80211/status.c      |  17 +++-
+ net/mac80211/trace.h       |  67 ++++++++++++++
+ 8 files changed, 430 insertions(+), 2 deletions(-)
 
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -4229,6 +4229,11 @@ struct ieee80211_ops {
+@@ -3930,6 +3930,13 @@ struct ieee80211_prep_tx_info {
+  * @set_sar_specs: Update the SAR (TX power) settings.
+  * @sta_set_decap_offload: Called to notify the driver when a station is allowed
+  *    to use rx decapsulation offload
++ * @add_twt_setup: Update hw with TWT agreement parameters received from the peer.
++ *    This callback allows the hw to check if requested parameters
++ *    are supported and if there is enough room for a new agreement.
++ *    The hw is expected to set agreement result in the req_type field of
++ *    twt structure.
++ * @twt_teardown_request: Update the hw with TWT teardown request received
++ *    from the peer.
+  */
+ struct ieee80211_ops {
+       void (*tx)(struct ieee80211_hw *hw,
+@@ -4253,6 +4260,11 @@ struct ieee80211_ops {
        void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
                                      struct ieee80211_vif *vif,
                                      struct ieee80211_sta *sta, bool enabled);
@@ -41,7 +65,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  /**
 --- a/net/mac80211/driver-ops.h
 +++ b/net/mac80211/driver-ops.h
-@@ -1429,4 +1429,40 @@ static inline void drv_sta_set_decap_off
+@@ -1447,4 +1447,40 @@ static inline void drv_sta_set_decap_off
        trace_drv_return_void(local);
  }
  
@@ -92,7 +116,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  
        u8 needed_rx_chains;
        enum ieee80211_smps_mode smps_mode;
-@@ -2088,6 +2089,11 @@ ieee80211_he_op_ie_to_bss_conf(struct ie
+@@ -2083,6 +2084,11 @@ ieee80211_he_op_ie_to_bss_conf(struct ie
  
  /* S1G */
  void ieee80211_s1g_sta_rate_init(struct sta_info *sta);
@@ -122,8 +146,25 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        INIT_WORK(&sdata->work, ieee80211_iface_work);
  
        return 0;
-@@ -1396,6 +1398,24 @@ static void ieee80211_if_setup_no_queue(
-       dev->priv_flags |= IFF_NO_QUEUE;
+@@ -1459,6 +1461,16 @@ static void ieee80211_iface_process_skb(
+                       WARN_ON(1);
+                       break;
+               }
++      } else if (ieee80211_is_action(mgmt->frame_control) &&
++                 mgmt->u.action.category == WLAN_CATEGORY_S1G) {
++              switch (mgmt->u.action.u.s1g.action_code) {
++              case WLAN_S1G_TWT_TEARDOWN:
++              case WLAN_S1G_TWT_SETUP:
++                      ieee80211_s1g_rx_twt_action(sdata, skb);
++                      break;
++              default:
++                      break;
++              }
+       } else if (ieee80211_is_ext(mgmt->frame_control)) {
+               if (sdata->vif.type == NL80211_IFTYPE_STATION)
+                       ieee80211_sta_rx_queued_ext(sdata, skb);
+@@ -1514,6 +1526,24 @@ static void ieee80211_iface_process_skb(
+       }
  }
  
 +static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
@@ -147,37 +188,24 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  static void ieee80211_iface_work(struct work_struct *work)
  {
        struct ieee80211_sub_if_data *sdata =
-@@ -1474,6 +1494,16 @@ static void ieee80211_iface_work(struct
-                               WARN_ON(1);
-                               break;
-                       }
-+              } else if (ieee80211_is_action(mgmt->frame_control) &&
-+                         mgmt->u.action.category == WLAN_CATEGORY_S1G) {
-+                      switch (mgmt->u.action.u.s1g.action_code) {
-+                      case WLAN_S1G_TWT_TEARDOWN:
-+                      case WLAN_S1G_TWT_SETUP:
-+                              ieee80211_s1g_rx_twt_action(sdata, skb);
-+                              break;
-+                      default:
-+                              break;
-+                      }
-               } else if (ieee80211_is_ext(mgmt->frame_control)) {
-                       if (sdata->vif.type == NL80211_IFTYPE_STATION)
-                               ieee80211_sta_rx_queued_ext(sdata, skb);
-@@ -1530,6 +1560,12 @@ static void ieee80211_iface_work(struct
+@@ -1543,6 +1573,16 @@ static void ieee80211_iface_work(struct
                kcov_remote_stop();
        }
  
 +      /* process status queue */
 +      while ((skb = skb_dequeue(&sdata->status_queue))) {
++              kcov_remote_start_common(skb_get_kcov_handle(skb));
++
 +              ieee80211_iface_process_status(sdata, skb);
 +              kfree_skb(skb);
++
++              kcov_remote_stop();
 +      }
 +
        /* then other type-dependent work */
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_STATION:
-@@ -1593,6 +1629,7 @@ static void ieee80211_setup_sdata(struct
+@@ -1606,6 +1646,7 @@ static void ieee80211_setup_sdata(struct
        }
  
        skb_queue_head_init(&sdata->skb_queue);
@@ -187,7 +215,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
        INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3198,6 +3198,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802
+@@ -3211,6 +3211,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802
        return RX_CONTINUE;
  }
  
@@ -256,7 +284,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  static ieee80211_rx_result debug_noinline
  ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
  {
-@@ -3477,6 +3539,17 @@ ieee80211_rx_h_action(struct ieee80211_r
+@@ -3490,6 +3552,17 @@ ieee80211_rx_h_action(struct ieee80211_r
                    !mesh_path_sel_is_hwmp(sdata))
                        break;
                goto queue;
@@ -500,7 +528,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
                rcu_read_unlock();
 --- a/net/mac80211/trace.h
 +++ b/net/mac80211/trace.h
-@@ -2804,6 +2804,73 @@ DEFINE_EVENT(sta_flag_evt, drv_sta_set_d
+@@ -2825,6 +2825,73 @@ DEFINE_EVENT(sta_flag_evt, drv_sta_set_d
        TP_ARGS(local, sdata, sta, enabled)
  );
  
index 870d6283b7a1b7d01ce8bbfc0ad7b60810279709..b9fd8e3ea221f360683167dabd4c1c17a3e4ab1f 100644 (file)
@@ -5,7 +5,7 @@ and we should ignore this.
 
 --- a/net/wireless/core.c
 +++ b/net/wireless/core.c
-@@ -637,21 +637,6 @@ static int wiphy_verify_combinations(str
+@@ -629,21 +629,6 @@ static int wiphy_verify_combinations(str
                                    c->limits[j].max > 1))
                                return -EINVAL;
  
index 6d4a9c21a57c14f3a374702d2e5e815eb65de0e6..1775dc44b161c6bbf3268c4ebe8fe727755b67d9 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -3826,6 +3826,7 @@ struct mgmt_frame_regs {
+@@ -3835,6 +3835,7 @@ struct mgmt_frame_regs {
   *    (as advertised by the nl80211 feature flag.)
   * @get_tx_power: store the current TX power into the dbm variable;
   *    return 0 if successful
@@ -8,7 +8,7 @@
   *
   * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
   *    functions to adjust rfkill hw state
-@@ -4150,6 +4151,7 @@ struct cfg80211_ops {
+@@ -4159,6 +4160,7 @@ struct cfg80211_ops {
                                enum nl80211_tx_power_setting type, int mbm);
        int     (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
                                int *dbm);
@@ -18,7 +18,7 @@
  
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -1564,6 +1564,7 @@ enum ieee80211_smps_mode {
+@@ -1566,6 +1566,7 @@ enum ieee80211_smps_mode {
   *
   * @power_level: requested transmit power (in dBm), backward compatibility
   *    value only that is set to the minimum of all interfaces
@@ -26,7 +26,7 @@
   *
   * @chandef: the channel definition to tune to
   * @radar_enabled: whether radar detection is enabled
-@@ -1584,6 +1585,7 @@ enum ieee80211_smps_mode {
+@@ -1586,6 +1587,7 @@ enum ieee80211_smps_mode {
  struct ieee80211_conf {
        u32 flags;
        int power_level, dynamic_ps_timeout;
@@ -57,7 +57,7 @@
        __NL80211_ATTR_AFTER_LAST,
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2768,6 +2768,19 @@ static int ieee80211_get_tx_power(struct
+@@ -2760,6 +2760,19 @@ static int ieee80211_get_tx_power(struct
        return 0;
  }
  
@@ -77,7 +77,7 @@
  static void ieee80211_rfkill_poll(struct wiphy *wiphy)
  {
        struct ieee80211_local *local = wiphy_priv(wiphy);
-@@ -4403,6 +4416,7 @@ const struct cfg80211_ops mac80211_confi
+@@ -4395,6 +4408,7 @@ const struct cfg80211_ops mac80211_confi
        .set_wiphy_params = ieee80211_set_wiphy_params,
        .set_tx_power = ieee80211_set_tx_power,
        .get_tx_power = ieee80211_get_tx_power,
  };
  
  /* policy for the key attributes */
-@@ -3317,6 +3318,20 @@ static int nl80211_set_wiphy(struct sk_b
+@@ -3325,6 +3326,20 @@ static int nl80211_set_wiphy(struct sk_b
                        goto out;
        }
  
index 2f724b61ff7717d4bad88331092d185e2a76590c..f788e6915f963c7ae5afa8f776d4c525d929e27d 100644 (file)
@@ -1,5 +1,14 @@
 --- a/nl80211.h
 +++ b/nl80211.h
+@@ -11,7 +11,7 @@
+  * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
+  * Copyright 2008 Colin McCabe <colin@cozybit.com>
+  * Copyright 2015-2017        Intel Deutschland GmbH
+- * Copyright (C) 2018-2020 Intel Corporation
++ * Copyright (C) 2018-2021 Intel Corporation
+  *
+  * Permission to use, copy, modify, and/or distribute this software for any
+  * purpose with or without fee is hereby granted, provided that the above
 @@ -655,6 +655,9 @@
   *    When a security association was established on an 802.1X network using
   *    fast transition, this event should be followed by an
        /* add attributes here, update the policy in nl80211.c */
  
        __NL80211_ATTR_AFTER_LAST,
-@@ -5896,6 +5981,22 @@ enum nl80211_feature_flags {
+@@ -3613,6 +3698,8 @@ enum nl80211_mpath_info {
+  *     defined
+  * @NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA: HE 6GHz band capabilities (__le16),
+  *    given for all 6 GHz band channels
++ * @NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS: vendor element capabilities that are
++ *    advertised on this band/for this iftype (binary)
+  * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
+  */
+ enum nl80211_band_iftype_attr {
+@@ -3624,6 +3711,7 @@ enum nl80211_band_iftype_attr {
+       NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
+       NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
+       NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
++      NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
+       /* keep last */
+       __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
+@@ -5896,6 +5984,22 @@ enum nl80211_feature_flags {
   * @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports
   *    unsolicited broadcast probe response transmission
   *
   * @NUM_NL80211_EXT_FEATURES: number of extended features.
   * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
   */
-@@ -5956,6 +6057,11 @@ enum nl80211_ext_feature_index {
+@@ -5956,6 +6060,11 @@ enum nl80211_ext_feature_index {
        NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
        NL80211_EXT_FEATURE_FILS_DISCOVERY,
        NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
  
        /* add new features before the definition below */
        NUM_NL80211_EXT_FEATURES,
-@@ -6253,11 +6359,13 @@ struct nl80211_vendor_cmd_info {
+@@ -6253,11 +6362,13 @@ struct nl80211_vendor_cmd_info {
   * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
   * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
   * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
  };
  
  /**
-@@ -6849,6 +6957,9 @@ enum nl80211_peer_measurement_ftm_capa {
+@@ -6849,6 +6960,12 @@ enum nl80211_peer_measurement_ftm_capa {
   *      if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
   *    %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
   *    ranging will be used.
 + * @NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK: negotiate for LMR feedback. Only
 + *    valid if either %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED or
 + *    %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
++ * @NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR: optional. The BSS color of the
++ *    responder. Only valid if %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED
++ *    or %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED is set.
   *
   * @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal
   * @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number
-@@ -6867,6 +6978,7 @@ enum nl80211_peer_measurement_ftm_req {
+@@ -6867,6 +6984,8 @@ enum nl80211_peer_measurement_ftm_req {
        NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
        NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
        NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
 +      NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK,
++      NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR,
  
        /* keep last */
        NUM_NL80211_PMSR_FTM_REQ_ATTR,
-@@ -7124,4 +7236,115 @@ enum nl80211_unsol_bcast_probe_resp_attr
+@@ -7124,4 +7243,115 @@ enum nl80211_unsol_bcast_probe_resp_attr
        NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX =
                __NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST - 1
  };