aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/subsys')
-rw-r--r--package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch49
-rw-r--r--package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch4
-rw-r--r--package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch2
-rw-r--r--package/kernel/mac80211/patches/subsys/130-disable-fils.patch4
-rw-r--r--package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch6
-rw-r--r--package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch2
-rw-r--r--package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch2
-rw-r--r--package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch10
-rw-r--r--package/kernel/mac80211/patches/subsys/210-ap_scan.patch2
-rw-r--r--package/kernel/mac80211/patches/subsys/300-mac80211-add-stop-start-logic-for-software-TXQs.patch272
-rw-r--r--package/kernel/mac80211/patches/subsys/301-mac80211-do-not-call-driver-wake_tx_queue-op-during-.patch33
-rw-r--r--package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch82
-rw-r--r--package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch150
-rw-r--r--package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch575
-rw-r--r--package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch368
-rw-r--r--package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch31
-rw-r--r--package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch20
-rw-r--r--package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch58
-rw-r--r--package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch40
-rw-r--r--package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch58
-rw-r--r--package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch122
-rw-r--r--package/kernel/mac80211/patches/subsys/313-mac80211-fix-unaligned-access-in-mesh-table-hash-fun.patch21
-rw-r--r--package/kernel/mac80211/patches/subsys/320-mac80211-Add-TXQ-scheduling-API.patch292
-rw-r--r--package/kernel/mac80211/patches/subsys/321-cfg80211-Add-airtime-statistics-and-settings.patch202
-rw-r--r--package/kernel/mac80211/patches/subsys/322-mac80211-Add-airtime-accounting-and-scheduling-to-TX.patch522
-rw-r--r--package/kernel/mac80211/patches/subsys/323-mac80211-Expose-ieee80211_schedule_txq-function.patch73
-rw-r--r--package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch44
-rw-r--r--package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch60
-rw-r--r--package/kernel/mac80211/patches/subsys/352-mac80211-rework-locking-for-txq-scheduling-airtime-f.patch214
-rw-r--r--package/kernel/mac80211/patches/subsys/353-mac80211-mesh-drop-redundant-rcu_read_lock-unlock-ca.patch96
-rw-r--r--package/kernel/mac80211/patches/subsys/354-mac80211-calculate-hash-for-fq-without-holding-fq-lo.patch124
-rw-r--r--package/kernel/mac80211/patches/subsys/355-mac80211-run-late-dequeue-late-tx-handlers-without-h.patch55
-rw-r--r--package/kernel/mac80211/patches/subsys/356-mac80211-set-NETIF_F_LLTX-when-using-intermediate-tx.patch22
-rw-r--r--package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch18
-rw-r--r--package/kernel/mac80211/patches/subsys/358-mac80211-make-ieee80211_schedule_txq-schedule-empty-.patch105
-rw-r--r--package/kernel/mac80211/patches/subsys/359-mac80211-un-schedule-TXQs-on-powersave-start.patch31
-rw-r--r--package/kernel/mac80211/patches/subsys/360-mac80211-when-using-iTXQ-select-the-queue-in-ieee802.patch183
-rw-r--r--package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-add-support-for-rates-with-4-sp.patch78
-rw-r--r--package/kernel/mac80211/patches/subsys/362-mac80211-minstrel_ht-automatically-calculate-rate-du.patch189
-rw-r--r--package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch103
-rw-r--r--package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch40
41 files changed, 118 insertions, 4244 deletions
diff --git a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch
index 0fe6ee196c..1a13fdc56f 100644
--- a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch
+++ b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch
@@ -20,17 +20,14 @@
ethtool.o \
--- a/net/mac80211/aead_api.c
+++ /dev/null
-@@ -1,115 +0,0 @@
+@@ -1,112 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright 2003-2004, Instant802 Networks, Inc.
- * Copyright 2005-2006, Devicescape Software, Inc.
- * Copyright 2014-2015, Qualcomm Atheros, Inc.
- *
- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
@@ -138,12 +135,8 @@
-}
--- a/net/mac80211/aead_api.h
+++ /dev/null
-@@ -1,27 +0,0 @@
--/*
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- */
+@@ -1,23 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef _AEAD_API_H
-#define _AEAD_API_H
@@ -168,7 +161,7 @@
-#endif /* _AEAD_API_H */
--- a/net/mac80211/aes_ccm.h
+++ b/net/mac80211/aes_ccm.h
-@@ -10,39 +10,17 @@
+@@ -7,39 +7,17 @@
#ifndef AES_CCM_H
#define AES_CCM_H
@@ -333,7 +326,7 @@
+}
--- a/net/mac80211/aes_gcm.h
+++ b/net/mac80211/aes_gcm.h
-@@ -9,38 +9,30 @@
+@@ -6,38 +6,30 @@
#ifndef AES_GCM_H
#define AES_GCM_H
@@ -385,7 +378,7 @@
#endif /* AES_GCM_H */
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
-@@ -314,7 +314,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
+@@ -311,7 +311,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
}
@@ -395,7 +388,7 @@
{
__le16 mask_fc;
int a4_included, mgmt;
-@@ -344,14 +345,8 @@ static void ccmp_special_blocks(struct s
+@@ -341,14 +342,8 @@ static void ccmp_special_blocks(struct s
else
qos_tid = 0;
@@ -412,7 +405,7 @@
/* Nonce: Nonce Flags | A2 | PN
* Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
-@@ -359,6 +354,8 @@ static void ccmp_special_blocks(struct s
+@@ -356,6 +351,8 @@ static void ccmp_special_blocks(struct s
b_0[1] = qos_tid | (mgmt << 4);
memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
@@ -421,7 +414,7 @@
/* AAD (extra authenticate-only data) / masked 802.11 header
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
-@@ -415,7 +412,7 @@ static int ccmp_encrypt_skb(struct ieee8
+@@ -412,7 +409,7 @@ static int ccmp_encrypt_skb(struct ieee8
u8 *pos;
u8 pn[6];
u64 pn64;
@@ -430,7 +423,7 @@
u8 b_0[AES_BLOCK_SIZE];
if (info->control.hw_key &&
-@@ -470,9 +467,11 @@ static int ccmp_encrypt_skb(struct ieee8
+@@ -467,9 +464,11 @@ static int ccmp_encrypt_skb(struct ieee8
return 0;
pos += IEEE80211_CCMP_HDR_LEN;
@@ -445,7 +438,7 @@
}
-@@ -545,13 +544,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+@@ -542,13 +541,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee
u8 aad[2 * AES_BLOCK_SIZE];
u8 b_0[AES_BLOCK_SIZE];
/* hardware didn't decrypt/verify MIC */
@@ -461,7 +454,7 @@
return RX_DROP_UNUSABLE;
}
-@@ -646,7 +645,7 @@ static int gcmp_encrypt_skb(struct ieee8
+@@ -643,7 +642,7 @@ static int gcmp_encrypt_skb(struct ieee8
u8 *pos;
u8 pn[6];
u64 pn64;
@@ -470,7 +463,7 @@
u8 j_0[AES_BLOCK_SIZE];
if (info->control.hw_key &&
-@@ -703,8 +702,10 @@ static int gcmp_encrypt_skb(struct ieee8
+@@ -700,8 +699,10 @@ static int gcmp_encrypt_skb(struct ieee8
pos += IEEE80211_GCMP_HDR_LEN;
gcmp_special_blocks(skb, pn, j_0, aad);
@@ -483,7 +476,7 @@
}
ieee80211_tx_result
-@@ -1127,9 +1128,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct
+@@ -1124,9 +1125,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct
struct ieee80211_key *key = tx->key;
struct ieee80211_mmie_16 *mmie;
struct ieee80211_hdr *hdr;
@@ -495,12 +488,12 @@
if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
return TX_DROP;
-@@ -1175,7 +1176,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct
+@@ -1172,7 +1173,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_key *key = rx->key;
struct ieee80211_mmie_16 *mmie;
-- u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN];
-+ u8 aad[20], mic[16], ipn[6], nonce[12];
+- u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN];
++ u8 aad[20], *mic, ipn[6], nonce[12];
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
if (!ieee80211_is_mgmt(hdr->frame_control))
@@ -653,7 +646,7 @@
+}
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
-@@ -5,8 +5,6 @@ config MAC80211
+@@ -6,8 +6,6 @@ config MAC80211
depends on CRYPTO
depends on CRYPTO_ARC4
depends on CRYPTO_AES
@@ -664,7 +657,7 @@
---help---
--- a/net/mac80211/aes_gmac.h
+++ b/net/mac80211/aes_gmac.h
-@@ -15,10 +15,22 @@
+@@ -12,10 +12,22 @@
#define GMAC_MIC_LEN 16
#define GMAC_NONCE_LEN 12
@@ -694,7 +687,7 @@
#endif /* AES_GMAC_H */
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
-@@ -88,7 +88,7 @@ struct ieee80211_key {
+@@ -86,7 +86,7 @@ struct ieee80211_key {
* Management frames.
*/
u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
diff --git a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch
index 6775884a34..59144f7310 100644
--- a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch
+++ b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch
@@ -2,8 +2,8 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -1067,7 +1067,6 @@ static int ieee80211_stop_ap(struct wiph
- sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
+@@ -1162,7 +1162,6 @@ static int ieee80211_stop_ap(struct wiph
+ sdata->vif.bss_conf.ftmr_params = NULL;
__sta_info_flush(sdata, true);
- ieee80211_free_keys(sdata, true);
diff --git a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch
index ffd8807ccc..172e5b04fd 100644
--- a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch
+++ b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch
@@ -1,6 +1,6 @@
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
-@@ -24,18 +24,35 @@ static inline struct cfg80211_registered
+@@ -23,18 +23,35 @@ static inline struct cfg80211_registered
return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
}
diff --git a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch b/package/kernel/mac80211/patches/subsys/130-disable-fils.patch
index f1163764a0..dd1ccc8597 100644
--- a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch
+++ b/package/kernel/mac80211/patches/subsys/130-disable-fils.patch
@@ -2,7 +2,7 @@ Disable FILS support, since it pulls in crypto hash support
--- a/net/mac80211/fils_aead.h
+++ b/net/mac80211/fils_aead.h
-@@ -10,7 +10,7 @@
+@@ -7,7 +7,7 @@
#ifndef FILS_AEAD_H
#define FILS_AEAD_H
@@ -16,9 +16,9 @@ Disable FILS support, since it pulls in crypto hash support
@@ -1,4 +1,4 @@
-#if LINUX_VERSION_IS_GEQ(4,3,0)
+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */
+ // SPDX-License-Identifier: GPL-2.0-only
/*
* FILS AEAD for (Re)Association Request/Response frames
- * Copyright 2016, Qualcomm Atheros, Inc.
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -570,7 +570,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
diff --git a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch
index d138b2c5ac..0c5f85236e 100644
--- a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch
+++ b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch
@@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
-@@ -22,50 +22,126 @@
+@@ -19,50 +19,126 @@
#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
#define AAD_LEN 20
@@ -166,7 +166,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
--- a/net/mac80211/aes_cmac.h
+++ b/net/mac80211/aes_cmac.h
-@@ -10,14 +10,13 @@
+@@ -7,14 +7,13 @@
#define AES_CMAC_H
#include <linux/crypto.h>
@@ -188,7 +188,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#endif /* AES_CMAC_H */
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
-@@ -93,7 +93,7 @@ struct ieee80211_key {
+@@ -91,7 +91,7 @@ struct ieee80211_key {
} ccmp;
struct {
u8 rx_pn[IEEE80211_CMAC_PN_LEN];
diff --git a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch b/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch
index 9d185e61e7..a259d5816b 100644
--- a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch
+++ b/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch
@@ -1,6 +1,6 @@
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
-@@ -5,7 +5,6 @@ config MAC80211
+@@ -6,7 +6,6 @@ config MAC80211
depends on CRYPTO
depends on CRYPTO_ARC4
depends on CRYPTO_AES
diff --git a/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch b/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch
index 42a6382209..449179a962 100644
--- a/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch
+++ b/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch
@@ -1,6 +1,6 @@
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3797,6 +3797,12 @@ out:
+@@ -4012,6 +4012,12 @@ out:
netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
diff --git a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch
index 1581b3400b..39000e4f05 100644
--- a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch
+++ b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch
@@ -1,6 +1,6 @@
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
-@@ -315,7 +315,7 @@ void ieee80211_restart_hw(struct ieee802
+@@ -313,7 +313,7 @@ void ieee80211_restart_hw(struct ieee802
}
EXPORT_SYMBOL(ieee80211_restart_hw);
@@ -9,7 +9,7 @@
static int ieee80211_ifa_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
-@@ -374,7 +374,7 @@ static int ieee80211_ifa_changed(struct
+@@ -372,7 +372,7 @@ static int ieee80211_ifa_changed(struct
}
#endif
@@ -18,7 +18,7 @@
static int ieee80211_ifa6_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
-@@ -1168,14 +1168,14 @@ int ieee80211_register_hw(struct ieee802
+@@ -1269,14 +1269,14 @@ int ieee80211_register_hw(struct ieee802
rtnl_unlock();
@@ -35,7 +35,7 @@
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
result = register_inet6addr_notifier(&local->ifa6_notifier);
if (result)
-@@ -1184,13 +1184,13 @@ int ieee80211_register_hw(struct ieee802
+@@ -1285,13 +1285,13 @@ int ieee80211_register_hw(struct ieee802
return 0;
@@ -52,7 +52,7 @@
fail_ifa:
#endif
rtnl_lock();
-@@ -1219,10 +1219,10 @@ void ieee80211_unregister_hw(struct ieee
+@@ -1320,10 +1320,10 @@ void ieee80211_unregister_hw(struct ieee
tasklet_kill(&local->tx_pending_tasklet);
tasklet_kill(&local->tasklet);
diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch
index fcc173da69..7e237a443e 100644
--- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch
+++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch
@@ -1,6 +1,6 @@
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -2237,7 +2237,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -2312,7 +2312,7 @@ static int ieee80211_scan(struct wiphy *
* the frames sent while scanning on other channel will be
* lost)
*/
diff --git a/package/kernel/mac80211/patches/subsys/300-mac80211-add-stop-start-logic-for-software-TXQs.patch b/package/kernel/mac80211/patches/subsys/300-mac80211-add-stop-start-logic-for-software-TXQs.patch
deleted file mode 100644
index 422e9c2977..0000000000
--- a/package/kernel/mac80211/patches/subsys/300-mac80211-add-stop-start-logic-for-software-TXQs.patch
+++ /dev/null
@@ -1,272 +0,0 @@
-From: Manikanta Pubbisetty <mpubbise@codeaurora.org>
-Date: Wed, 11 Jul 2018 00:12:53 +0530
-Subject: [PATCH] mac80211: add stop/start logic for software TXQs
-
-Sometimes, it is required to stop the transmissions momentarily and
-resume it later; stopping the txqs becomes very critical in scenarios where
-the packet transmission has to be ceased completely. For example, during
-the hardware restart, during off channel operations,
-when initiating CSA(upon detecting a radar on the DFS channel), etc.
-
-The TX queue stop/start logic in mac80211 works well in stopping the TX
-when drivers make use of netdev queues, i.e, when Qdiscs in network layer
-take care of traffic scheduling. Since the devices implementing
-wake_tx_queue can run without Qdiscs, packets will be handed to mac80211
-directly without queueing them in the netdev queues.
-
-Also, mac80211 does not invoke any of the
-netif_stop_*/netif_wake_* APIs if wake_tx_queue is implemented.
-Since the queues are not stopped in this case, transmissions can continue
-and this will impact negatively on the operation of the wireless device.
-
-For example,
-During hardware restart, we stop the netdev queues so that packets are
-not sent to the driver. Since ath10k implements wake_tx_queue,
-TX queues will not be stopped and packets might reach the hardware while
-it is restarting; this can make hardware unresponsive and the only
-possible option for recovery is to reboot the entire system.
-
-There is another problem to this, it is observed that the packets
-were sent on the DFS channel for a prolonged duration after radar
-detection impacting the channel closing time.
-
-We can still invoke netif stop/wake APIs when wake_tx_queue is implemented
-but this could lead to packet drops in network layer; adding stop/start
-logic for software TXQs in mac80211 instead makes more sense; the change
-proposed adds the same in mac80211.
-
-Signed-off-by: Manikanta Pubbisetty <mpubbise@codeaurora.org>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1504,6 +1504,8 @@ enum ieee80211_vif_flags {
- * @drv_priv: data area for driver use, will always be aligned to
- * sizeof(void \*).
- * @txq: the multicast data TX queue (if driver uses the TXQ abstraction)
-+ * @txqs_stopped: per AC flag to indicate that intermediate TXQs are stopped,
-+ * protected by fq->lock.
- */
- struct ieee80211_vif {
- enum nl80211_iftype type;
-@@ -1528,6 +1530,8 @@ struct ieee80211_vif {
-
- unsigned int probe_req_reg;
-
-+ bool txqs_stopped[IEEE80211_NUM_ACS];
-+
- /* must be last */
- u8 drv_priv[0] __aligned(sizeof(void *));
- };
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -818,6 +818,7 @@ enum txq_info_flags {
- IEEE80211_TXQ_STOP,
- IEEE80211_TXQ_AMPDU,
- IEEE80211_TXQ_NO_AMSDU,
-+ IEEE80211_TXQ_STOP_NETIF_TX,
- };
-
- /**
-@@ -1226,6 +1227,7 @@ struct ieee80211_local {
-
- struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
- struct tasklet_struct tx_pending_tasklet;
-+ struct tasklet_struct wake_txqs_tasklet;
-
- atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES];
-
-@@ -2039,6 +2041,7 @@ void ieee80211_txq_remove_vlan(struct ie
- struct ieee80211_sub_if_data *sdata);
- void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats,
- struct txq_info *txqi);
-+void ieee80211_wake_txqs(unsigned long data);
- void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
- u16 transaction, u16 auth_alg, u16 status,
- const u8 *extra, size_t extra_len, const u8 *bssid,
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -686,6 +686,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_
- tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
- (unsigned long)local);
-
-+ if (ops->wake_tx_queue)
-+ tasklet_init(&local->wake_txqs_tasklet, ieee80211_wake_txqs,
-+ (unsigned long)local);
-+
- tasklet_init(&local->tasklet,
- ieee80211_tasklet_handler,
- (unsigned long) local);
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3482,13 +3482,19 @@ struct sk_buff *ieee80211_tx_dequeue(str
- struct ieee80211_tx_info *info;
- struct ieee80211_tx_data tx;
- ieee80211_tx_result r;
-- struct ieee80211_vif *vif;
-+ struct ieee80211_vif *vif = txq->vif;
-
- spin_lock_bh(&fq->lock);
-
-- if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags))
-+ if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ||
-+ test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags))
- goto out;
-
-+ if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) {
-+ set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags);
-+ goto out;
-+ }
-+
- /* Make sure fragments stay together. */
- skb = __skb_dequeue(&txqi->frags);
- if (skb)
-@@ -3583,6 +3589,7 @@ begin:
- }
-
- IEEE80211_SKB_CB(skb)->control.vif = vif;
-+
- out:
- spin_unlock_bh(&fq->lock);
-
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -240,6 +240,99 @@ __le16 ieee80211_ctstoself_duration(stru
- }
- EXPORT_SYMBOL(ieee80211_ctstoself_duration);
-
-+static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
-+{
-+ struct ieee80211_local *local = sdata->local;
-+ struct ieee80211_vif *vif = &sdata->vif;
-+ struct fq *fq = &local->fq;
-+ struct ps_data *ps = NULL;
-+ struct txq_info *txqi;
-+ struct sta_info *sta;
-+ int i;
-+
-+ spin_lock_bh(&fq->lock);
-+
-+ if (sdata->vif.type == NL80211_IFTYPE_AP)
-+ ps = &sdata->bss->ps;
-+
-+ sdata->vif.txqs_stopped[ac] = false;
-+
-+ list_for_each_entry_rcu(sta, &local->sta_list, list) {
-+ if (sdata != sta->sdata)
-+ continue;
-+
-+ for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
-+ struct ieee80211_txq *txq = sta->sta.txq[i];
-+
-+ txqi = to_txq_info(txq);
-+
-+ if (ac != txq->ac)
-+ continue;
-+
-+ if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX,
-+ &txqi->flags))
-+ continue;
-+
-+ spin_unlock_bh(&fq->lock);
-+ drv_wake_tx_queue(local, txqi);
-+ spin_lock_bh(&fq->lock);
-+ }
-+ }
-+
-+ if (!vif->txq)
-+ goto out;
-+
-+ txqi = to_txq_info(vif->txq);
-+
-+ if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags) ||
-+ (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac)
-+ goto out;
-+
-+ spin_unlock_bh(&fq->lock);
-+
-+ drv_wake_tx_queue(local, txqi);
-+ return;
-+out:
-+ spin_unlock_bh(&fq->lock);
-+}
-+
-+void ieee80211_wake_txqs(unsigned long data)
-+{
-+ struct ieee80211_local *local = (struct ieee80211_local *)data;
-+ struct ieee80211_sub_if_data *sdata;
-+ int n_acs = IEEE80211_NUM_ACS;
-+ unsigned long flags;
-+ int i;
-+
-+ rcu_read_lock();
-+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-+
-+ if (local->hw.queues < IEEE80211_NUM_ACS)
-+ n_acs = 1;
-+
-+ for (i = 0; i < local->hw.queues; i++) {
-+ if (local->queue_stop_reasons[i])
-+ continue;
-+
-+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-+ int ac;
-+
-+ for (ac = 0; ac < n_acs; ac++) {
-+ int ac_queue = sdata->vif.hw_queue[ac];
-+
-+ if (ac_queue == i ||
-+ sdata->vif.cab_queue == i)
-+ __ieee80211_wake_txqs(sdata, ac);
-+ }
-+ }
-+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-+ }
-+
-+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-+ rcu_read_unlock();
-+}
-+
- void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
- {
- struct ieee80211_sub_if_data *sdata;
-@@ -308,6 +401,9 @@ static void __ieee80211_wake_queue(struc
- rcu_read_unlock();
- } else
- tasklet_schedule(&local->tx_pending_tasklet);
-+
-+ if (local->ops->wake_tx_queue)
-+ tasklet_schedule(&local->wake_txqs_tasklet);
- }
-
- void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
-@@ -351,9 +447,6 @@ static void __ieee80211_stop_queue(struc
- if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue]))
- return;
-
-- if (local->ops->wake_tx_queue)
-- return;
--
- if (local->hw.queues < IEEE80211_NUM_ACS)
- n_acs = 1;
-
-@@ -366,8 +459,15 @@ static void __ieee80211_stop_queue(struc
-
- for (ac = 0; ac < n_acs; ac++) {
- if (sdata->vif.hw_queue[ac] == queue ||
-- sdata->vif.cab_queue == queue)
-- netif_stop_subqueue(sdata->dev, ac);
-+ sdata->vif.cab_queue == queue) {
-+ if (!local->ops->wake_tx_queue) {
-+ netif_stop_subqueue(sdata->dev, ac);
-+ continue;
-+ }
-+ spin_lock(&local->fq.lock);
-+ sdata->vif.txqs_stopped[ac] = true;
-+ spin_unlock(&local->fq.lock);
-+ }
- }
- }
- rcu_read_unlock();
diff --git a/package/kernel/mac80211/patches/subsys/301-mac80211-do-not-call-driver-wake_tx_queue-op-during-.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-do-not-call-driver-wake_tx_queue-op-during-.patch
deleted file mode 100644
index 5bbf4db23b..0000000000
--- a/package/kernel/mac80211/patches/subsys/301-mac80211-do-not-call-driver-wake_tx_queue-op-during-.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 1 Mar 2019 14:42:56 +0100
-Subject: [PATCH] mac80211: do not call driver wake_tx_queue op during reconfig
-
-There are several scenarios in which mac80211 can call drv_wake_tx_queue
-after ieee80211_restart_hw has been called and has not yet completed.
-Driver private structs are considered uninitialized until mac80211 has
-uploaded the vifs, stations and keys again, so using private tx queue
-data during that time is not safe.
-
-The driver can also not rely on drv_reconfig_complete to figure out when
-it is safe to accept drv_wake_tx_queue calls again, because it is only
-called after all tx queues are woken again.
-
-To fix this, bail out early in drv_wake_tx_queue if local->in_reconfig
-is set.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -1166,6 +1166,9 @@ static inline void drv_wake_tx_queue(str
- {
- struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
-
-+ if (local->in_reconfig)
-+ return;
-+
- if (!check_sdata_in_driver(sdata))
- return;
-
diff --git a/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch
deleted file mode 100644
index 661fb46ea4..0000000000
--- a/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From: Chaitanya T K <chaitanya.mgit@gmail.com>
-Date: Mon, 27 Jun 2016 15:23:26 +0530
-Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates
-
-If peer support reception of STBC and LDPC, enable them for better
-performance.
-
-Signed-off-by: Chaitanya TK <chaitanya.mgit@gmail.com>
----
-
---- a/include/linux/ieee80211.h
-+++ b/include/linux/ieee80211.h
-@@ -1659,6 +1659,7 @@ struct ieee80211_mu_edca_param_set {
- #define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300
- #define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400
- #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700
-+#define IEEE80211_VHT_CAP_RXSTBC_SHIFT 8
- #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800
- #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000
- #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -1130,7 +1130,7 @@ minstrel_ht_update_caps(void *priv, stru
- struct minstrel_ht_sta_priv *msp = priv_sta;
- struct minstrel_ht_sta *mi = &msp->ht;
- struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
-- u16 sta_cap = sta->ht_cap.cap;
-+ u16 ht_cap = sta->ht_cap.cap;
- struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
- struct sta_info *sinfo = container_of(sta, struct sta_info, sta);
- int use_vht;
-@@ -1138,6 +1138,7 @@ minstrel_ht_update_caps(void *priv, stru
- int ack_dur;
- int stbc;
- int i;
-+ bool ldpc = false;
-
- /* fall back to the old minstrel for legacy stations */
- if (!sta->ht_cap.ht_supported)
-@@ -1175,16 +1176,24 @@ minstrel_ht_update_caps(void *priv, stru
- }
- mi->sample_tries = 4;
-
-- /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */
- if (!use_vht) {
-- stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
-+ stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >>
- IEEE80211_HT_CAP_RX_STBC_SHIFT;
-- mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
-
-- if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
-- mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
-+ if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING)
-+ ldpc = true;
-+ } else {
-+ stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >>
-+ IEEE80211_VHT_CAP_RXSTBC_SHIFT;
-+
-+ if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)
-+ ldpc = true;
- }
-
-+ mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
-+ if (ldpc)
-+ mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
-+
- for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
- u32 gflags = minstrel_mcs_groups[i].flags;
- int bw, nss;
-@@ -1197,10 +1206,10 @@ minstrel_ht_update_caps(void *priv, stru
-
- if (gflags & IEEE80211_TX_RC_SHORT_GI) {
- if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
-- if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
-+ if (!(ht_cap & IEEE80211_HT_CAP_SGI_40))
- continue;
- } else {
-- if (!(sta_cap & IEEE80211_HT_CAP_SGI_20))
-+ if (!(ht_cap & IEEE80211_HT_CAP_SGI_20))
- continue;
- }
- }
diff --git a/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch
deleted file mode 100644
index 95d4f294aa..0000000000
--- a/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 10 Feb 2018 12:41:51 +0100
-Subject: [PATCH] mac80211: minstrel: remove unnecessary debugfs cleanup
- code
-
-debugfs entries are cleaned up by debugfs_remove_recursive already.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel.c
-+++ b/net/mac80211/rc80211_minstrel.c
-@@ -689,8 +689,8 @@ minstrel_alloc(struct ieee80211_hw *hw,
-
- #ifdef CPTCFG_MAC80211_DEBUGFS
- mp->fixed_rate_idx = (u32) -1;
-- mp->dbg_fixed_rate = debugfs_create_u32("fixed_rate_idx",
-- 0666, debugfsdir, &mp->fixed_rate_idx);
-+ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
-+ &mp->fixed_rate_idx);
- #endif
-
- minstrel_init_cck_rates(mp);
-@@ -701,9 +701,6 @@ minstrel_alloc(struct ieee80211_hw *hw,
- static void
- minstrel_free(void *priv)
- {
--#ifdef CPTCFG_MAC80211_DEBUGFS
-- debugfs_remove(((struct minstrel_priv *)priv)->dbg_fixed_rate);
--#endif
- kfree(priv);
- }
-
-@@ -735,7 +732,6 @@ const struct rate_control_ops mac80211_m
- .free_sta = minstrel_free_sta,
- #ifdef CPTCFG_MAC80211_DEBUGFS
- .add_sta_debugfs = minstrel_add_sta_debugfs,
-- .remove_sta_debugfs = minstrel_remove_sta_debugfs,
- #endif
- .get_expected_throughput = minstrel_get_expected_throughput,
- };
---- a/net/mac80211/rc80211_minstrel.h
-+++ b/net/mac80211/rc80211_minstrel.h
-@@ -109,11 +109,6 @@ struct minstrel_sta_info {
-
- /* sampling table */
- u8 *sample_table;
--
--#ifdef CPTCFG_MAC80211_DEBUGFS
-- struct dentry *dbg_stats;
-- struct dentry *dbg_stats_csv;
--#endif
- };
-
- struct minstrel_priv {
-@@ -137,7 +132,6 @@ struct minstrel_priv {
- * - setting will be applied on next update
- */
- u32 fixed_rate_idx;
-- struct dentry *dbg_fixed_rate;
- #endif
- };
-
-@@ -156,7 +150,6 @@ minstrel_get_ewmsd10(struct minstrel_rat
-
- extern const struct rate_control_ops mac80211_minstrel;
- void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
--void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
-
- /* Recalculate success probabilities and counters for a given rate using EWMA */
- void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs);
---- a/net/mac80211/rc80211_minstrel_debugfs.c
-+++ b/net/mac80211/rc80211_minstrel_debugfs.c
-@@ -214,19 +214,7 @@ minstrel_add_sta_debugfs(void *priv, voi
- {
- struct minstrel_sta_info *mi = priv_sta;
-
-- mi->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, mi,
-- &minstrel_stat_fops);
--
-- mi->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, mi,
-- &minstrel_stat_csv_fops);
--}
--
--void
--minstrel_remove_sta_debugfs(void *priv, void *priv_sta)
--{
-- struct minstrel_sta_info *mi = priv_sta;
--
-- debugfs_remove(mi->dbg_stats);
--
-- debugfs_remove(mi->dbg_stats_csv);
-+ debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops);
-+ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi,
-+ &minstrel_stat_csv_fops);
- }
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -1393,7 +1393,6 @@ static const struct rate_control_ops mac
- .free = minstrel_ht_free,
- #ifdef CPTCFG_MAC80211_DEBUGFS
- .add_sta_debugfs = minstrel_ht_add_sta_debugfs,
-- .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs,
- #endif
- .get_expected_throughput = minstrel_ht_get_expected_throughput,
- };
---- a/net/mac80211/rc80211_minstrel_ht.h
-+++ b/net/mac80211/rc80211_minstrel_ht.h
-@@ -110,17 +110,12 @@ struct minstrel_ht_sta_priv {
- struct minstrel_ht_sta ht;
- struct minstrel_sta_info legacy;
- };
--#ifdef CPTCFG_MAC80211_DEBUGFS
-- struct dentry *dbg_stats;
-- struct dentry *dbg_stats_csv;
--#endif
- void *ratelist;
- void *sample_table;
- bool is_ht;
- };
-
- void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
--void minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta);
- int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
- int prob_ewma);
-
---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
-+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
-@@ -303,17 +303,8 @@ minstrel_ht_add_sta_debugfs(void *priv,
- {
- struct minstrel_ht_sta_priv *msp = priv_sta;
-
-- msp->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, msp,
-- &minstrel_ht_stat_fops);
-- msp->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, msp,
-- &minstrel_ht_stat_csv_fops);
--}
--
--void
--minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta)
--{
-- struct minstrel_ht_sta_priv *msp = priv_sta;
--
-- debugfs_remove(msp->dbg_stats);
-- debugfs_remove(msp->dbg_stats_csv);
-+ debugfs_create_file("rc_stats", S_IRUGO, dir, msp,
-+ &minstrel_ht_stat_fops);
-+ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, msp,
-+ &minstrel_ht_stat_csv_fops);
- }
diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch
deleted file mode 100644
index 9a233753ad..0000000000
--- a/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch
+++ /dev/null
@@ -1,575 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 10 Feb 2018 12:43:30 +0100
-Subject: [PATCH] mac80211: minstrel: merge with minstrel_ht, always enable
- VHT support
-
-Legacy-only devices are not very common and the overhead of the extra
-code for HT and VHT rates is not big enough to justify all those extra
-lines of code to make it optional.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/Kconfig
-+++ b/net/mac80211/Kconfig
-@@ -25,20 +25,6 @@ config MAC80211_RC_MINSTREL
- ---help---
- This option enables the 'minstrel' TX rate control algorithm
-
--config MAC80211_RC_MINSTREL_HT
-- bool "Minstrel 802.11n support" if EXPERT
-- depends on MAC80211_RC_MINSTREL
-- default y
-- ---help---
-- This option enables the 'minstrel_ht' TX rate control algorithm
--
--config MAC80211_RC_MINSTREL_VHT
-- bool "Minstrel 802.11ac support" if EXPERT
-- depends on MAC80211_RC_MINSTREL_HT
-- default n
-- ---help---
-- This option enables VHT in the 'minstrel_ht' TX rate control algorithm
--
- choice
- prompt "Default rate control algorithm"
- depends on MAC80211_HAS_RC
-@@ -60,8 +46,7 @@ endchoice
-
- config MAC80211_RC_DEFAULT
- string
-- default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT
-- default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL
-+ default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL
- default ""
-
- endif
---- a/net/mac80211/Makefile
-+++ b/net/mac80211/Makefile
-@@ -52,13 +52,14 @@ mac80211-$(CONFIG_PM) += pm.o
-
- CFLAGS_trace.o := -I$(src)
-
--rc80211_minstrel-y := rc80211_minstrel.o
--rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o
-+rc80211_minstrel-y := \
-+ rc80211_minstrel.o \
-+ rc80211_minstrel_ht.o
-
--rc80211_minstrel_ht-y := rc80211_minstrel_ht.o
--rc80211_minstrel_ht-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_ht_debugfs.o
-+rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += \
-+ rc80211_minstrel_debugfs.o \
-+ rc80211_minstrel_ht_debugfs.o
-
- mac80211-$(CPTCFG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
--mac80211-$(CPTCFG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y)
-
- ccflags-y += -DDEBUG
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -1308,18 +1308,12 @@ static int __init ieee80211_init(void)
- if (ret)
- return ret;
-
-- ret = rc80211_minstrel_ht_init();
-- if (ret)
-- goto err_minstrel;
--
- ret = ieee80211_iface_init();
- if (ret)
- goto err_netdev;
-
- return 0;
- err_netdev:
-- rc80211_minstrel_ht_exit();
-- err_minstrel:
- rc80211_minstrel_exit();
-
- return ret;
-@@ -1327,7 +1321,6 @@ static int __init ieee80211_init(void)
-
- static void __exit ieee80211_exit(void)
- {
-- rc80211_minstrel_ht_exit();
- rc80211_minstrel_exit();
-
- ieee80211s_stop();
---- a/net/mac80211/rate.h
-+++ b/net/mac80211/rate.h
-@@ -95,18 +95,5 @@ static inline void rc80211_minstrel_exit
- }
- #endif
-
--#ifdef CPTCFG_MAC80211_RC_MINSTREL_HT
--int rc80211_minstrel_ht_init(void);
--void rc80211_minstrel_ht_exit(void);
--#else
--static inline int rc80211_minstrel_ht_init(void)
--{
-- return 0;
--}
--static inline void rc80211_minstrel_ht_exit(void)
--{
--}
--#endif
--
-
- #endif /* IEEE80211_RATE_H */
---- a/net/mac80211/rc80211_minstrel.c
-+++ b/net/mac80211/rc80211_minstrel.c
-@@ -572,138 +572,6 @@ minstrel_rate_init(void *priv, struct ie
- minstrel_update_rates(mp, mi);
- }
-
--static void *
--minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
--{
-- struct ieee80211_supported_band *sband;
-- struct minstrel_sta_info *mi;
-- struct minstrel_priv *mp = priv;
-- struct ieee80211_hw *hw = mp->hw;
-- int max_rates = 0;
-- int i;
--
-- mi = kzalloc(sizeof(struct minstrel_sta_info), gfp);
-- if (!mi)
-- return NULL;
--
-- for (i = 0; i < NUM_NL80211_BANDS; i++) {
-- sband = hw->wiphy->bands[i];
-- if (sband && sband->n_bitrates > max_rates)
-- max_rates = sband->n_bitrates;
-- }
--
-- mi->r = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp);
-- if (!mi->r)
-- goto error;
--
-- mi->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp);
-- if (!mi->sample_table)
-- goto error1;
--
-- mi->last_stats_update = jiffies;
-- return mi;
--
--error1:
-- kfree(mi->r);
--error:
-- kfree(mi);
-- return NULL;
--}
--
--static void
--minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta)
--{
-- struct minstrel_sta_info *mi = priv_sta;
--
-- kfree(mi->sample_table);
-- kfree(mi->r);
-- kfree(mi);
--}
--
--static void
--minstrel_init_cck_rates(struct minstrel_priv *mp)
--{
-- static const int bitrates[4] = { 10, 20, 55, 110 };
-- struct ieee80211_supported_band *sband;
-- u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
-- int i, j;
--
-- sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ];
-- if (!sband)
-- return;
--
-- for (i = 0, j = 0; i < sband->n_bitrates; i++) {
-- struct ieee80211_rate *rate = &sband->bitrates[i];
--
-- if (rate->flags & IEEE80211_RATE_ERP_G)
-- continue;
--
-- if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
-- continue;
--
-- for (j = 0; j < ARRAY_SIZE(bitrates); j++) {
-- if (rate->bitrate != bitrates[j])
-- continue;
--
-- mp->cck_rates[j] = i;
-- break;
-- }
-- }
--}
--
--static void *
--minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
--{
-- struct minstrel_priv *mp;
--
-- mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC);
-- if (!mp)
-- return NULL;
--
-- /* contention window settings
-- * Just an approximation. Using the per-queue values would complicate
-- * the calculations and is probably unnecessary */
-- mp->cw_min = 15;
-- mp->cw_max = 1023;
--
-- /* number of packets (in %) to use for sampling other rates
-- * sample less often for non-mrr packets, because the overhead
-- * is much higher than with mrr */
-- mp->lookaround_rate = 5;
-- mp->lookaround_rate_mrr = 10;
--
-- /* maximum time that the hw is allowed to stay in one MRR segment */
-- mp->segment_size = 6000;
--
-- if (hw->max_rate_tries > 0)
-- mp->max_retry = hw->max_rate_tries;
-- else
-- /* safe default, does not necessarily have to match hw properties */
-- mp->max_retry = 7;
--
-- if (hw->max_rates >= 4)
-- mp->has_mrr = true;
--
-- mp->hw = hw;
-- mp->update_interval = 100;
--
--#ifdef CPTCFG_MAC80211_DEBUGFS
-- mp->fixed_rate_idx = (u32) -1;
-- debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
-- &mp->fixed_rate_idx);
--#endif
--
-- minstrel_init_cck_rates(mp);
--
-- return mp;
--}
--
--static void
--minstrel_free(void *priv)
--{
-- kfree(priv);
--}
--
- static u32 minstrel_get_expected_throughput(void *priv_sta)
- {
- struct minstrel_sta_info *mi = priv_sta;
-@@ -722,28 +590,8 @@ static u32 minstrel_get_expected_through
- }
-
- const struct rate_control_ops mac80211_minstrel = {
-- .name = "minstrel",
- .tx_status_ext = minstrel_tx_status,
- .get_rate = minstrel_get_rate,
- .rate_init = minstrel_rate_init,
-- .alloc = minstrel_alloc,
-- .free = minstrel_free,
-- .alloc_sta = minstrel_alloc_sta,
-- .free_sta = minstrel_free_sta,
--#ifdef CPTCFG_MAC80211_DEBUGFS
-- .add_sta_debugfs = minstrel_add_sta_debugfs,
--#endif
- .get_expected_throughput = minstrel_get_expected_throughput,
- };
--
--int __init
--rc80211_minstrel_init(void)
--{
-- return ieee80211_rate_control_register(&mac80211_minstrel);
--}
--
--void
--rc80211_minstrel_exit(void)
--{
-- ieee80211_rate_control_unregister(&mac80211_minstrel);
--}
---- a/net/mac80211/rc80211_minstrel.h
-+++ b/net/mac80211/rc80211_minstrel.h
-@@ -158,7 +158,5 @@ int minstrel_get_tp_avg(struct minstrel_
- /* debugfs */
- int minstrel_stats_open(struct inode *inode, struct file *file);
- int minstrel_stats_csv_open(struct inode *inode, struct file *file);
--ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos);
--int minstrel_stats_release(struct inode *inode, struct file *file);
-
- #endif
---- a/net/mac80211/rc80211_minstrel_debugfs.c
-+++ b/net/mac80211/rc80211_minstrel_debugfs.c
-@@ -54,22 +54,6 @@
- #include <net/mac80211.h>
- #include "rc80211_minstrel.h"
-
--ssize_t
--minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos)
--{
-- struct minstrel_debugfs_info *ms;
--
-- ms = file->private_data;
-- return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len);
--}
--
--int
--minstrel_stats_release(struct inode *inode, struct file *file)
--{
-- kfree(file->private_data);
-- return 0;
--}
--
- int
- minstrel_stats_open(struct inode *inode, struct file *file)
- {
-@@ -135,14 +119,6 @@ minstrel_stats_open(struct inode *inode,
- return 0;
- }
-
--static const struct file_operations minstrel_stat_fops = {
-- .owner = THIS_MODULE,
-- .open = minstrel_stats_open,
-- .read = minstrel_stats_read,
-- .release = minstrel_stats_release,
-- .llseek = default_llseek,
--};
--
- int
- minstrel_stats_csv_open(struct inode *inode, struct file *file)
- {
-@@ -200,21 +176,3 @@ minstrel_stats_csv_open(struct inode *in
-
- return 0;
- }
--
--static const struct file_operations minstrel_stat_csv_fops = {
-- .owner = THIS_MODULE,
-- .open = minstrel_stats_csv_open,
-- .read = minstrel_stats_read,
-- .release = minstrel_stats_release,
-- .llseek = default_llseek,
--};
--
--void
--minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir)
--{
-- struct minstrel_sta_info *mi = priv_sta;
--
-- debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops);
-- debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi,
-- &minstrel_stat_csv_fops);
--}
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -137,12 +137,10 @@
- } \
- }
-
--#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT
- static bool minstrel_vht_only = true;
- module_param(minstrel_vht_only, bool, 0644);
- MODULE_PARM_DESC(minstrel_vht_only,
- "Use only VHT rates when VHT is supported by sta.");
--#endif
-
- /*
- * To enable sufficiently targeted rate sampling, MCS rates are divided into
-@@ -171,7 +169,6 @@ const struct mcs_group minstrel_mcs_grou
-
- CCK_GROUP,
-
--#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT
- VHT_GROUP(1, 0, BW_20),
- VHT_GROUP(2, 0, BW_20),
- VHT_GROUP(3, 0, BW_20),
-@@ -195,7 +192,6 @@ const struct mcs_group minstrel_mcs_grou
- VHT_GROUP(1, 1, BW_80),
- VHT_GROUP(2, 1, BW_80),
- VHT_GROUP(3, 1, BW_80),
--#endif
- };
-
- static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
-@@ -1146,12 +1142,10 @@ minstrel_ht_update_caps(void *priv, stru
-
- BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB);
-
--#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT
- if (vht_cap->vht_supported)
- use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0);
- else
--#endif
-- use_vht = 0;
-+ use_vht = 0;
-
- msp->is_ht = true;
- memset(mi, 0, sizeof(*mi));
-@@ -1226,10 +1220,9 @@ minstrel_ht_update_caps(void *priv, stru
-
- /* HT rate */
- if (gflags & IEEE80211_TX_RC_MCS) {
--#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT
- if (use_vht && minstrel_vht_only)
- continue;
--#endif
-+
- mi->supported[i] = mcs->rx_mask[nss - 1];
- if (mi->supported[i])
- n_supported++;
-@@ -1349,16 +1342,88 @@ minstrel_ht_free_sta(void *priv, struct
- kfree(msp);
- }
-
-+static void
-+minstrel_ht_init_cck_rates(struct minstrel_priv *mp)
-+{
-+ static const int bitrates[4] = { 10, 20, 55, 110 };
-+ struct ieee80211_supported_band *sband;
-+ u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
-+ int i, j;
-+
-+ sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ];
-+ if (!sband)
-+ return;
-+
-+ for (i = 0, j = 0; i < sband->n_bitrates; i++) {
-+ struct ieee80211_rate *rate = &sband->bitrates[i];
-+
-+ if (rate->flags & IEEE80211_RATE_ERP_G)
-+ continue;
-+
-+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
-+ continue;
-+
-+ for (j = 0; j < ARRAY_SIZE(bitrates); j++) {
-+ if (rate->bitrate != bitrates[j])
-+ continue;
-+
-+ mp->cck_rates[j] = i;
-+ break;
-+ }
-+ }
-+}
-+
- static void *
- minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
- {
-- return mac80211_minstrel.alloc(hw, debugfsdir);
-+ struct minstrel_priv *mp;
-+
-+ mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC);
-+ if (!mp)
-+ return NULL;
-+
-+ /* contention window settings
-+ * Just an approximation. Using the per-queue values would complicate
-+ * the calculations and is probably unnecessary */
-+ mp->cw_min = 15;
-+ mp->cw_max = 1023;
-+
-+ /* number of packets (in %) to use for sampling other rates
-+ * sample less often for non-mrr packets, because the overhead
-+ * is much higher than with mrr */
-+ mp->lookaround_rate = 5;
-+ mp->lookaround_rate_mrr = 10;
-+
-+ /* maximum time that the hw is allowed to stay in one MRR segment */
-+ mp->segment_size = 6000;
-+
-+ if (hw->max_rate_tries > 0)
-+ mp->max_retry = hw->max_rate_tries;
-+ else
-+ /* safe default, does not necessarily have to match hw properties */
-+ mp->max_retry = 7;
-+
-+ if (hw->max_rates >= 4)
-+ mp->has_mrr = true;
-+
-+ mp->hw = hw;
-+ mp->update_interval = 100;
-+
-+#ifdef CPTCFG_MAC80211_DEBUGFS
-+ mp->fixed_rate_idx = (u32) -1;
-+ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
-+ &mp->fixed_rate_idx);
-+#endif
-+
-+ minstrel_ht_init_cck_rates(mp);
-+
-+ return mp;
- }
-
- static void
- minstrel_ht_free(void *priv)
- {
-- mac80211_minstrel.free(priv);
-+ kfree(priv);
- }
-
- static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
-@@ -1417,14 +1482,14 @@ static void __init init_sample_table(voi
- }
-
- int __init
--rc80211_minstrel_ht_init(void)
-+rc80211_minstrel_init(void)
- {
- init_sample_table();
- return ieee80211_rate_control_register(&mac80211_minstrel_ht);
- }
-
- void
--rc80211_minstrel_ht_exit(void)
-+rc80211_minstrel_exit(void)
- {
- ieee80211_rate_control_unregister(&mac80211_minstrel_ht);
- }
---- a/net/mac80211/rc80211_minstrel_ht.h
-+++ b/net/mac80211/rc80211_minstrel_ht.h
-@@ -15,11 +15,7 @@
- */
- #define MINSTREL_MAX_STREAMS 3
- #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */
--#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT
- #define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */
--#else
--#define MINSTREL_VHT_STREAM_GROUPS 0
--#endif
-
- #define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \
- MINSTREL_HT_STREAM_GROUPS)
-@@ -34,11 +30,7 @@
- #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB)
- #define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1)
-
--#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT
- #define MCS_GROUP_RATES 10
--#else
--#define MCS_GROUP_RATES 8
--#endif
-
- struct mcs_group {
- u32 flags;
---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
-+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
-@@ -15,6 +15,22 @@
- #include "rc80211_minstrel.h"
- #include "rc80211_minstrel_ht.h"
-
-+static ssize_t
-+minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos)
-+{
-+ struct minstrel_debugfs_info *ms;
-+
-+ ms = file->private_data;
-+ return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len);
-+}
-+
-+static int
-+minstrel_stats_release(struct inode *inode, struct file *file)
-+{
-+ kfree(file->private_data);
-+ return 0;
-+}
-+
- static char *
- minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
- {
diff --git a/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch b/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch
deleted file mode 100644
index 02a0ca0a52..0000000000
--- a/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch
+++ /dev/null
@@ -1,368 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 10 Feb 2018 12:45:47 +0100
-Subject: [PATCH] mac80211: minstrel: reduce minstrel_mcs_groups size
-
-By storing a shift value for all duration values of a group, we can
-reduce precision by a neglegible amount to make it fit into a u16 value.
-This improves cache footprint and reduces size:
-
-Before:
- text data bss dec hex filename
- 10024 116 0 10140 279c rc80211_minstrel_ht.o
-
-After:
- text data bss dec hex filename
- 9368 116 0 9484 250c rc80211_minstrel_ht.o
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -52,22 +52,23 @@
- _streams - 1
-
- /* MCS rate information for an MCS group */
--#define MCS_GROUP(_streams, _sgi, _ht40) \
-+#define MCS_GROUP(_streams, _sgi, _ht40, _s) \
- [GROUP_IDX(_streams, _sgi, _ht40)] = { \
- .streams = _streams, \
-+ .shift = _s, \
- .flags = \
- IEEE80211_TX_RC_MCS | \
- (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
- (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
- .duration = { \
-- MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26), \
-- MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \
-- MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \
-- MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104), \
-- MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156), \
-- MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \
-- MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \
-- MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \
-+ MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s, \
-+ MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s, \
-+ MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s, \
-+ MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s, \
-+ MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s, \
-+ MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s, \
-+ MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s, \
-+ MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s \
- } \
- }
-
-@@ -80,9 +81,10 @@
- #define BW2VBPS(_bw, r3, r2, r1) \
- (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
-
--#define VHT_GROUP(_streams, _sgi, _bw) \
-+#define VHT_GROUP(_streams, _sgi, _bw, _s) \
- [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \
- .streams = _streams, \
-+ .shift = _s, \
- .flags = \
- IEEE80211_TX_RC_VHT_MCS | \
- (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
-@@ -90,25 +92,25 @@
- _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
- .duration = { \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 117, 54, 26)), \
-+ BW2VBPS(_bw, 117, 54, 26)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 234, 108, 52)), \
-+ BW2VBPS(_bw, 234, 108, 52)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 351, 162, 78)), \
-+ BW2VBPS(_bw, 351, 162, 78)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 468, 216, 104)), \
-+ BW2VBPS(_bw, 468, 216, 104)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 702, 324, 156)), \
-+ BW2VBPS(_bw, 702, 324, 156)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 936, 432, 208)), \
-+ BW2VBPS(_bw, 936, 432, 208)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 1053, 486, 234)), \
-+ BW2VBPS(_bw, 1053, 486, 234)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 1170, 540, 260)), \
-+ BW2VBPS(_bw, 1170, 540, 260)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 1404, 648, 312)), \
-+ BW2VBPS(_bw, 1404, 648, 312)) >> _s, \
- MCS_DURATION(_streams, _sgi, \
-- BW2VBPS(_bw, 1560, 720, 346)) \
-+ BW2VBPS(_bw, 1560, 720, 346)) >> _s \
- } \
- }
-
-@@ -121,19 +123,20 @@
- (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \
- CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE))
-
--#define CCK_DURATION_LIST(_short) \
-- CCK_ACK_DURATION(10, _short), \
-- CCK_ACK_DURATION(20, _short), \
-- CCK_ACK_DURATION(55, _short), \
-- CCK_ACK_DURATION(110, _short)
-+#define CCK_DURATION_LIST(_short, _s) \
-+ CCK_ACK_DURATION(10, _short) >> _s, \
-+ CCK_ACK_DURATION(20, _short) >> _s, \
-+ CCK_ACK_DURATION(55, _short) >> _s, \
-+ CCK_ACK_DURATION(110, _short) >> _s
-
--#define CCK_GROUP \
-+#define CCK_GROUP(_s) \
- [MINSTREL_CCK_GROUP] = { \
- .streams = 0, \
- .flags = 0, \
-+ .shift = _s, \
- .duration = { \
-- CCK_DURATION_LIST(false), \
-- CCK_DURATION_LIST(true) \
-+ CCK_DURATION_LIST(false, _s), \
-+ CCK_DURATION_LIST(true, _s) \
- } \
- }
-
-@@ -151,47 +154,47 @@ MODULE_PARM_DESC(minstrel_vht_only,
- * BW -> SGI -> #streams
- */
- const struct mcs_group minstrel_mcs_groups[] = {
-- MCS_GROUP(1, 0, BW_20),
-- MCS_GROUP(2, 0, BW_20),
-- MCS_GROUP(3, 0, BW_20),
--
-- MCS_GROUP(1, 1, BW_20),
-- MCS_GROUP(2, 1, BW_20),
-- MCS_GROUP(3, 1, BW_20),
--
-- MCS_GROUP(1, 0, BW_40),
-- MCS_GROUP(2, 0, BW_40),
-- MCS_GROUP(3, 0, BW_40),
--
-- MCS_GROUP(1, 1, BW_40),
-- MCS_GROUP(2, 1, BW_40),
-- MCS_GROUP(3, 1, BW_40),
--
-- CCK_GROUP,
--
-- VHT_GROUP(1, 0, BW_20),
-- VHT_GROUP(2, 0, BW_20),
-- VHT_GROUP(3, 0, BW_20),
--
-- VHT_GROUP(1, 1, BW_20),
-- VHT_GROUP(2, 1, BW_20),
-- VHT_GROUP(3, 1, BW_20),
--
-- VHT_GROUP(1, 0, BW_40),
-- VHT_GROUP(2, 0, BW_40),
-- VHT_GROUP(3, 0, BW_40),
--
-- VHT_GROUP(1, 1, BW_40),
-- VHT_GROUP(2, 1, BW_40),
-- VHT_GROUP(3, 1, BW_40),
--
-- VHT_GROUP(1, 0, BW_80),
-- VHT_GROUP(2, 0, BW_80),
-- VHT_GROUP(3, 0, BW_80),
--
-- VHT_GROUP(1, 1, BW_80),
-- VHT_GROUP(2, 1, BW_80),
-- VHT_GROUP(3, 1, BW_80),
-+ MCS_GROUP(1, 0, BW_20, 5),
-+ MCS_GROUP(2, 0, BW_20, 4),
-+ MCS_GROUP(3, 0, BW_20, 4),
-+
-+ MCS_GROUP(1, 1, BW_20, 5),
-+ MCS_GROUP(2, 1, BW_20, 4),
-+ MCS_GROUP(3, 1, BW_20, 4),
-+
-+ MCS_GROUP(1, 0, BW_40, 4),
-+ MCS_GROUP(2, 0, BW_40, 4),
-+ MCS_GROUP(3, 0, BW_40, 4),
-+
-+ MCS_GROUP(1, 1, BW_40, 4),
-+ MCS_GROUP(2, 1, BW_40, 4),
-+ MCS_GROUP(3, 1, BW_40, 4),
-+
-+ CCK_GROUP(8),
-+
-+ VHT_GROUP(1, 0, BW_20, 5),
-+ VHT_GROUP(2, 0, BW_20, 4),
-+ VHT_GROUP(3, 0, BW_20, 4),
-+
-+ VHT_GROUP(1, 1, BW_20, 5),
-+ VHT_GROUP(2, 1, BW_20, 4),
-+ VHT_GROUP(3, 1, BW_20, 4),
-+
-+ VHT_GROUP(1, 0, BW_40, 4),
-+ VHT_GROUP(2, 0, BW_40, 4),
-+ VHT_GROUP(3, 0, BW_40, 4),
-+
-+ VHT_GROUP(1, 1, BW_40, 4),
-+ VHT_GROUP(2, 1, BW_40, 4),
-+ VHT_GROUP(3, 1, BW_40, 4),
-+
-+ VHT_GROUP(1, 0, BW_80, 4),
-+ VHT_GROUP(2, 0, BW_80, 4),
-+ VHT_GROUP(3, 0, BW_80, 4),
-+
-+ VHT_GROUP(1, 1, BW_80, 4),
-+ VHT_GROUP(2, 1, BW_80, 4),
-+ VHT_GROUP(3, 1, BW_80, 4),
- };
-
- static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
-@@ -307,7 +310,8 @@ minstrel_ht_get_tp_avg(struct minstrel_h
- if (group != MINSTREL_CCK_GROUP)
- nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
-
-- nsecs += minstrel_mcs_groups[group].duration[rate];
-+ nsecs += minstrel_mcs_groups[group].duration[rate] <<
-+ minstrel_mcs_groups[group].shift;
-
- /*
- * For the throughput calculation, limit the probability value to 90% to
-@@ -755,12 +759,19 @@ minstrel_ht_tx_status(void *priv, struct
- minstrel_ht_update_rates(mp, mi);
- }
-
-+static inline int
-+minstrel_get_duration(int index)
-+{
-+ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
-+ unsigned int duration = group->duration[index % MCS_GROUP_RATES];
-+ return duration << group->shift;
-+}
-+
- static void
- minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
- int index)
- {
- struct minstrel_rate_stats *mrs;
-- const struct mcs_group *group;
- unsigned int tx_time, tx_time_rtscts, tx_time_data;
- unsigned int cw = mp->cw_min;
- unsigned int ctime = 0;
-@@ -779,8 +790,7 @@ minstrel_calc_retransmit(struct minstrel
- mrs->retry_count_rtscts = 2;
- mrs->retry_updated = true;
-
-- group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
-- tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000;
-+ tx_time_data = minstrel_get_duration(index) * ampdu_len / 1000;
-
- /* Contention time for first 2 tries */
- ctime = (t_slot * cw) >> 1;
-@@ -874,20 +884,24 @@ minstrel_ht_get_max_amsdu_len(struct min
- int group = mi->max_prob_rate / MCS_GROUP_RATES;
- const struct mcs_group *g = &minstrel_mcs_groups[group];
- int rate = mi->max_prob_rate % MCS_GROUP_RATES;
-+ unsigned int duration;
-
- /* Disable A-MSDU if max_prob_rate is bad */
- if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100))
- return 1;
-
-+ duration = g->duration[rate];
-+ duration <<= g->shift;
-+
- /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */
-- if (g->duration[rate] > MCS_DURATION(1, 0, 52))
-+ if (duration > MCS_DURATION(1, 0, 52))
- return 500;
-
- /*
- * If the rate is slower than single-stream MCS4, limit A-MSDU to usual
- * data packet size
- */
-- if (g->duration[rate] > MCS_DURATION(1, 0, 104))
-+ if (duration > MCS_DURATION(1, 0, 104))
- return 1600;
-
- /*
-@@ -895,7 +909,7 @@ minstrel_ht_get_max_amsdu_len(struct min
- * rate success probability is less than 75%, limit A-MSDU to twice the usual
- * data packet size
- */
-- if (g->duration[rate] > MCS_DURATION(1, 0, 260) ||
-+ if (duration > MCS_DURATION(1, 0, 260) ||
- (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) <
- MINSTREL_FRAC(75, 100)))
- return 3200;
-@@ -942,13 +956,6 @@ minstrel_ht_update_rates(struct minstrel
- rate_control_set_rates(mp->hw, mi->sta, rates);
- }
-
--static inline int
--minstrel_get_duration(int index)
--{
-- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
-- return group->duration[index % MCS_GROUP_RATES];
--}
--
- static int
- minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
- {
---- a/net/mac80211/rc80211_minstrel_ht.h
-+++ b/net/mac80211/rc80211_minstrel_ht.h
-@@ -33,9 +33,10 @@
- #define MCS_GROUP_RATES 10
-
- struct mcs_group {
-- u32 flags;
-- unsigned int streams;
-- unsigned int duration[MCS_GROUP_RATES];
-+ u16 flags;
-+ u8 streams;
-+ u8 shift;
-+ u16 duration[MCS_GROUP_RATES];
- };
-
- extern const struct mcs_group minstrel_mcs_groups[];
---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
-+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
-@@ -58,6 +58,7 @@ minstrel_ht_stats_dump(struct minstrel_h
- static const int bitrates[4] = { 10, 20, 55, 110 };
- int idx = i * MCS_GROUP_RATES + j;
- unsigned int prob_ewmsd;
-+ unsigned int duration;
-
- if (!(mi->supported[i] & BIT(j)))
- continue;
-@@ -95,7 +96,9 @@ minstrel_ht_stats_dump(struct minstrel_h
- p += sprintf(p, " %3u ", idx);
-
- /* tx_time[rate(i)] in usec */
-- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000);
-+ duration = mg->duration[j];
-+ duration <<= mg->shift;
-+ tx_time = DIV_ROUND_CLOSEST(duration, 1000);
- p += sprintf(p, "%6u ", tx_time);
-
- tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
-@@ -204,6 +207,7 @@ minstrel_ht_stats_csv_dump(struct minstr
- static const int bitrates[4] = { 10, 20, 55, 110 };
- int idx = i * MCS_GROUP_RATES + j;
- unsigned int prob_ewmsd;
-+ unsigned int duration;
-
- if (!(mi->supported[i] & BIT(j)))
- continue;
-@@ -238,7 +242,10 @@ minstrel_ht_stats_csv_dump(struct minstr
- }
-
- p += sprintf(p, "%u,", idx);
-- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000);
-+
-+ duration = mg->duration[j];
-+ duration <<= mg->shift;
-+ tx_time = DIV_ROUND_CLOSEST(duration, 1000);
- p += sprintf(p, "%u,", tx_time);
-
- tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
diff --git a/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch b/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch
deleted file mode 100644
index 502d8c7768..0000000000
--- a/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 10 Feb 2018 13:43:07 +0100
-Subject: [PATCH] mac80211: minstrel: fix using short preamble CCK rates on
- HT clients
-
-mi->supported[MINSTREL_CCK_GROUP] needs to be updated
-
-Fixes: 782dda00ab8e ("mac80211: minstrel_ht: move short preamble check out of get_rate")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -1135,7 +1135,6 @@ minstrel_ht_update_caps(void *priv, stru
- struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
- u16 ht_cap = sta->ht_cap.cap;
- struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
-- struct sta_info *sinfo = container_of(sta, struct sta_info, sta);
- int use_vht;
- int n_supported = 0;
- int ack_dur;
-@@ -1267,8 +1266,7 @@ minstrel_ht_update_caps(void *priv, stru
- if (!n_supported)
- goto use_legacy;
-
-- if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE))
-- mi->cck_supported_short |= mi->cck_supported_short << 4;
-+ mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4;
-
- /* create an initial rate table with the lowest supported rates */
- minstrel_ht_update_stats(mp, mi);
diff --git a/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch b/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch
deleted file mode 100644
index f0ffcd9655..0000000000
--- a/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 1 Mar 2018 13:27:54 +0100
-Subject: [PATCH] mac80211: minstrel: fix CCK rate group streams value
-
-Fixes a harmless underflow issue when CCK rates are actively being used
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -131,7 +131,7 @@
-
- #define CCK_GROUP(_s) \
- [MINSTREL_CCK_GROUP] = { \
-- .streams = 0, \
-+ .streams = 1, \
- .flags = 0, \
- .shift = _s, \
- .duration = { \
diff --git a/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch b/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch
deleted file mode 100644
index e0049c36eb..0000000000
--- a/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 1 Mar 2018 13:28:48 +0100
-Subject: [PATCH] mac80211: minstrel: fix sampling/reporting of CCK rates
- in HT mode
-
-Long/short preamble selection cannot be sampled separately, since it
-depends on the BSS state. Because of that, sampling attempts to
-currently not used preamble modes are not counted in the statistics,
-which leads to CCK rates being sampled too often.
-
-Fix statistics accounting for long/short preamble by increasing the
-index where necessary.
-Fix excessive CCK rate sampling by dropping unsupported sample attempts.
-
-This improves throughput on 2.4 GHz channels
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -281,7 +281,8 @@ minstrel_ht_get_stats(struct minstrel_pr
- break;
-
- /* short preamble */
-- if (!(mi->supported[group] & BIT(idx)))
-+ if ((mi->supported[group] & BIT(idx + 4)) &&
-+ (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
- idx += 4;
- }
- return &mi->groups[group].rates[idx];
-@@ -1080,18 +1081,23 @@ minstrel_ht_get_rate(void *priv, struct
- return;
-
- sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
-+ sample_idx %= MCS_GROUP_RATES;
-+
-+ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] &&
-+ (sample_idx >= 4) != txrc->short_preamble)
-+ return;
-+
- info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
- rate->count = 1;
-
-- if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
-+ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP]) {
- int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
- rate->idx = mp->cck_rates[idx];
- } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) {
- ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES,
- sample_group->streams);
- } else {
-- rate->idx = sample_idx % MCS_GROUP_RATES +
-- (sample_group->streams - 1) * 8;
-+ rate->idx = sample_idx + (sample_group->streams - 1) * 8;
- }
-
- rate->flags = sample_group->flags;
diff --git a/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch
deleted file mode 100644
index 414cb137de..0000000000
--- a/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 3 Mar 2018 18:48:58 +0100
-Subject: [PATCH] mac80211: minstrel: do not sample rates 3 times slower than
- max_prob_rate
-
-These rates are highly unlikely to be used quickly, even if the link
-deteriorates rapidly. This improves throughput in cases where CCK rates
-are not reliable enough to be skipped entirely during sampling.
-Sampling these rates regularly can cost a lot of airtime.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -1004,10 +1004,13 @@ minstrel_get_sample_rate(struct minstrel
- return -1;
-
- /*
-- * Do not sample if the probability is already higher than 95%
-- * to avoid wasting airtime.
-+ * Do not sample if the probability is already higher than 95%,
-+ * or if the rate is 3 times slower than the current max probability
-+ * rate, to avoid wasting airtime.
- */
-- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100))
-+ sample_dur = minstrel_get_duration(sample_idx);
-+ if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
-+ minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur)
- return -1;
-
- /*
-@@ -1017,7 +1020,6 @@ minstrel_get_sample_rate(struct minstrel
-
- cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 /
- MCS_GROUP_RATES].streams;
-- sample_dur = minstrel_get_duration(sample_idx);
- if (sample_dur >= minstrel_get_duration(tp_rate2) &&
- (cur_max_tp_streams - 1 <
- minstrel_mcs_groups[sample_group].streams ||
diff --git a/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch
deleted file mode 100644
index 1fd2b25271..0000000000
--- a/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 8 Mar 2018 21:00:56 +0100
-Subject: [PATCH] mac80211: fix memory accounting with A-MSDU aggregation
-
-fq uses skb->truesize for memory usage tracking. Increments/decrements
-are done on enqueue/dequeue.
-When A-MSDU aggregation is performed on tx side, the packet is
-aggregated with the last packet in the queue belonging to the same flow.
-There are multiple bugs here:
-- The truesize field of the aggregated packet isn't updated, so memory
-usage is underestimated
-- fq->memory_usage isn't adjusted.
-
-Because of the combination of both bugs, this only causes tx issues in
-rare cases, mainly when the A-MSDU head needs to be reallocated.
-
-Fix this by adjusting both truesize of the A-MSDU head and adding the
-truesize delta to fq->memory_usage.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3185,6 +3185,7 @@ static bool ieee80211_amsdu_aggregate(st
- u8 max_subframes = sta->sta.max_amsdu_subframes;
- int max_frags = local->hw.max_tx_fragments;
- int max_amsdu_len = sta->sta.max_amsdu_len;
-+ int orig_truesize;
- __be16 len;
- void *data;
- bool ret = false;
-@@ -3216,12 +3217,13 @@ static bool ieee80211_amsdu_aggregate(st
- flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func);
- head = skb_peek_tail(&flow->queue);
- if (!head)
-- goto out;
-+ goto unlock;
-
-+ orig_truesize = head->truesize;
- orig_len = head->len;
-
- if (skb->len + head->len > max_amsdu_len)
-- goto out;
-+ goto unlock;
-
- nfrags = 1 + skb_shinfo(skb)->nr_frags;
- nfrags += 1 + skb_shinfo(head)->nr_frags;
-@@ -3279,6 +3281,9 @@ out_recalc:
- fq_recalc_backlog(fq, tin, flow);
- }
- out:
-+ fq->memory_usage += head->truesize - orig_truesize;
-+
-+unlock:
- spin_unlock_bh(&fq->lock);
-
- return ret;
diff --git a/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch b/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch
deleted file mode 100644
index f221d36bf8..0000000000
--- a/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 16 Jan 2019 22:32:12 +0100
-Subject: [PATCH] mac80211: minstrel_ht: add flag to indicate
- missing/inaccurate tx A-MPDU length
-
-Some hardware (e.g. MediaTek MT7603) cannot report A-MPDU length in tx status
-information. Add support for a flag to indicate that, to allow minstrel_ht
-to use a fixed value in its internal calculation (which gives better results
-than just defaulting to 1).
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -2131,6 +2131,9 @@ struct ieee80211_txq {
- * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't
- * support QoS NDP for AP probing - that's most likely a driver bug.
- *
-+ * @IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN: Driver does not report accurate A-MPDU
-+ * length in tx status information
-+ *
- * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
- */
- enum ieee80211_hw_flags {
-@@ -2176,6 +2179,7 @@ enum ieee80211_hw_flags {
- IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
- IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP,
- IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP,
-+ IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
-
- /* keep last, obviously */
- NUM_IEEE80211_HW_FLAGS
---- a/net/mac80211/debugfs.c
-+++ b/net/mac80211/debugfs.c
-@@ -214,6 +214,7 @@ static const char *hw_flag_names[] = {
- FLAG(SUPPORTS_TDLS_BUFFER_STA),
- FLAG(DEAUTH_NEED_MGD_TX_PREP),
- FLAG(DOESNT_SUPPORT_QOS_NDP),
-+ FLAG(TX_STATUS_NO_AMPDU_LEN),
- #undef FLAG
- };
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -294,6 +294,15 @@ minstrel_get_ratestats(struct minstrel_h
- return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES];
- }
-
-+static unsigned int
-+minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi)
-+{
-+ if (!mi->avg_ampdu_len)
-+ return AVG_AMPDU_SIZE;
-+
-+ return MINSTREL_TRUNC(mi->avg_ampdu_len);
-+}
-+
- /*
- * Return current throughput based on the average A-MPDU length, taking into
- * account the expected number of retransmissions and their expected length
-@@ -309,7 +318,7 @@ minstrel_ht_get_tp_avg(struct minstrel_h
- return 0;
-
- if (group != MINSTREL_CCK_GROUP)
-- nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
-+ nsecs = 1000 * mi->overhead / minstrel_ht_avg_ampdu_len(mi);
-
- nsecs += minstrel_mcs_groups[group].duration[rate] <<
- minstrel_mcs_groups[group].shift;
-@@ -503,8 +512,12 @@ minstrel_ht_update_stats(struct minstrel
- u16 tmp_cck_tp_rate[MAX_THR_RATES], index;
-
- if (mi->ampdu_packets > 0) {
-- mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
-- MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), EWMA_LEVEL);
-+ if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN))
-+ mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
-+ MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets),
-+ EWMA_LEVEL);
-+ else
-+ mi->avg_ampdu_len = 0;
- mi->ampdu_len = 0;
- mi->ampdu_packets = 0;
- }
-@@ -709,7 +722,9 @@ minstrel_ht_tx_status(void *priv, struct
- mi->ampdu_len += info->status.ampdu_len;
-
- if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
-- mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
-+ int avg_ampdu_len = minstrel_ht_avg_ampdu_len(mi);
-+
-+ mi->sample_wait = 16 + 2 * avg_ampdu_len;
- mi->sample_tries = 1;
- mi->sample_count--;
- }
-@@ -777,7 +792,7 @@ minstrel_calc_retransmit(struct minstrel
- unsigned int cw = mp->cw_min;
- unsigned int ctime = 0;
- unsigned int t_slot = 9; /* FIXME */
-- unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
-+ unsigned int ampdu_len = minstrel_ht_avg_ampdu_len(mi);
- unsigned int overhead = 0, overhead_rtscts = 0;
-
- mrs = minstrel_get_ratestats(mi, index);
---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
-+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
-@@ -163,9 +163,10 @@ minstrel_ht_stats_open(struct inode *ino
- "lookaround %d\n",
- max(0, (int) mi->total_packets - (int) mi->sample_packets),
- mi->sample_packets);
-- p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d\n",
-- MINSTREL_TRUNC(mi->avg_ampdu_len),
-- MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10);
-+ if (mi->avg_ampdu_len)
-+ p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d\n",
-+ MINSTREL_TRUNC(mi->avg_ampdu_len),
-+ MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10);
- ms->len = p - ms->buf;
- WARN_ON(ms->len + sizeof(*ms) > 32768);
-
diff --git a/package/kernel/mac80211/patches/subsys/313-mac80211-fix-unaligned-access-in-mesh-table-hash-fun.patch b/package/kernel/mac80211/patches/subsys/313-mac80211-fix-unaligned-access-in-mesh-table-hash-fun.patch
deleted file mode 100644
index 2ce23586ca..0000000000
--- a/package/kernel/mac80211/patches/subsys/313-mac80211-fix-unaligned-access-in-mesh-table-hash-fun.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 13 Mar 2019 18:52:56 +0100
-Subject: [PATCH] mac80211: fix unaligned access in mesh table hash function
-
-The pointer to the last four bytes of the address is not guaranteed to be
-aligned, so we need to use __get_unaligned_cpu32 here
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/mesh_pathtbl.c
-+++ b/net/mac80211/mesh_pathtbl.c
-@@ -23,7 +23,7 @@ static void mesh_path_free_rcu(struct me
- static u32 mesh_table_hash(const void *addr, u32 len, u32 seed)
- {
- /* Use last four bytes of hw addr as hash index */
-- return jhash_1word(*(u32 *)(addr+2), seed);
-+ return jhash_1word(__get_unaligned_cpu32(addr+2), seed);
- }
-
- static const struct rhashtable_params mesh_rht_params = {
diff --git a/package/kernel/mac80211/patches/subsys/320-mac80211-Add-TXQ-scheduling-API.patch b/package/kernel/mac80211/patches/subsys/320-mac80211-Add-TXQ-scheduling-API.patch
deleted file mode 100644
index 0f7d9e1506..0000000000
--- a/package/kernel/mac80211/patches/subsys/320-mac80211-Add-TXQ-scheduling-API.patch
+++ /dev/null
@@ -1,292 +0,0 @@
-From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@toke.dk>
-Date: Tue, 18 Dec 2018 17:02:06 -0800
-Subject: [PATCH] mac80211: Add TXQ scheduling API
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds an API to mac80211 to handle scheduling of TXQs. The interface
-between driver and mac80211 for TXQ handling is changed by adding two new
-functions: ieee80211_next_txq(), which will return the next TXQ to schedule
-in the current round-robin rotation, and ieee80211_return_txq(), which the
-driver uses to indicate that it has finished scheduling a TXQ (which will
-then be put back in the scheduling rotation if it isn't empty).
-
-The driver must call ieee80211_txq_schedule_start() at the start of each
-scheduling session, and ieee80211_txq_schedule_end() at the end. The API
-then guarantees that the same TXQ is not returned twice in the same
-session (so a driver can loop on ieee80211_next_txq() without worrying
-about breaking the loop.
-
-Usage of the new API is optional, so drivers can be ported one at a time.
-In this patch, the actual scheduling performed by mac80211 is simple
-round-robin, but a subsequent commit adds airtime fairness awareness to the
-scheduler.
-
-Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
-[minor kernel-doc fix, propagate sparse locking checks out]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -107,9 +107,15 @@
- * The driver is expected to initialize its private per-queue data for stations
- * and interfaces in the .add_interface and .sta_add ops.
- *
-- * The driver can't access the queue directly. To dequeue a frame, it calls
-- * ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a queue, it
-- * calls the .wake_tx_queue driver op.
-+ * The driver can't access the queue directly. To dequeue a frame from a
-+ * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a
-+ * queue, it calls the .wake_tx_queue driver op.
-+ *
-+ * Drivers can optionally delegate responsibility for scheduling queues to
-+ * mac80211, to take advantage of airtime fairness accounting. In this case, to
-+ * obtain the next queue to pull frames from, the driver calls
-+ * ieee80211_next_txq(). The driver is then expected to return the txq using
-+ * ieee80211_return_txq().
- *
- * For AP powersave TIM handling, the driver only needs to indicate if it has
- * buffered packets in the driver specific data structures by calling
-@@ -5979,7 +5985,8 @@ void ieee80211_unreserve_tid(struct ieee
- * ieee80211_tx_dequeue - dequeue a packet from a software tx queue
- *
- * @hw: pointer as obtained from ieee80211_alloc_hw()
-- * @txq: pointer obtained from station or virtual interface
-+ * @txq: pointer obtained from station or virtual interface, or from
-+ * ieee80211_next_txq()
- *
- * Returns the skb if successful, %NULL if no frame was available.
- */
-@@ -5987,6 +5994,54 @@ struct sk_buff *ieee80211_tx_dequeue(str
- struct ieee80211_txq *txq);
-
- /**
-+ * ieee80211_next_txq - get next tx queue to pull packets from
-+ *
-+ * @hw: pointer as obtained from ieee80211_alloc_hw()
-+ * @ac: AC number to return packets from.
-+ *
-+ * Should only be called between calls to ieee80211_txq_schedule_start()
-+ * and ieee80211_txq_schedule_end().
-+ * Returns the next txq if successful, %NULL if no queue is eligible. If a txq
-+ * is returned, it should be returned with ieee80211_return_txq() after the
-+ * driver has finished scheduling it.
-+ */
-+struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac);
-+
-+/**
-+ * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
-+ *
-+ * @hw: pointer as obtained from ieee80211_alloc_hw()
-+ * @txq: pointer obtained from station or virtual interface
-+ *
-+ * Should only be called between calls to ieee80211_txq_schedule_start()
-+ * and ieee80211_txq_schedule_end().
-+ */
-+void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
-+
-+/**
-+ * ieee80211_txq_schedule_start - acquire locks for safe scheduling of an AC
-+ *
-+ * @hw: pointer as obtained from ieee80211_alloc_hw()
-+ * @ac: AC number to acquire locks for
-+ *
-+ * Acquire locks needed to schedule TXQs from the given AC. Should be called
-+ * before ieee80211_next_txq() or ieee80211_return_txq().
-+ */
-+void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
-+ __acquires(txq_lock);
-+
-+/**
-+ * ieee80211_txq_schedule_end - release locks for safe scheduling of an AC
-+ *
-+ * @hw: pointer as obtained from ieee80211_alloc_hw()
-+ * @ac: AC number to acquire locks for
-+ *
-+ * Release locks previously acquired by ieee80211_txq_schedule_end().
-+ */
-+void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
-+ __releases(txq_lock);
-+
-+/**
- * ieee80211_txq_get_depth - get pending frame/byte count of given txq
- *
- * The values are not guaranteed to be coherent with regard to each other, i.e.
---- a/net/mac80211/agg-tx.c
-+++ b/net/mac80211/agg-tx.c
-@@ -229,7 +229,7 @@ ieee80211_agg_start_txq(struct sta_info
- clear_bit(IEEE80211_TXQ_STOP, &txqi->flags);
- local_bh_disable();
- rcu_read_lock();
-- drv_wake_tx_queue(sta->sdata->local, txqi);
-+ schedule_and_wake_txq(sta->sdata->local, txqi);
- rcu_read_unlock();
- local_bh_enable();
- }
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -1176,6 +1176,15 @@ static inline void drv_wake_tx_queue(str
- local->ops->wake_tx_queue(&local->hw, &txq->txq);
- }
-
-+static inline void schedule_and_wake_txq(struct ieee80211_local *local,
-+ struct txq_info *txqi)
-+{
-+ spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
-+ ieee80211_return_txq(&local->hw, &txqi->txq);
-+ spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
-+ drv_wake_tx_queue(local, txqi);
-+}
-+
- static inline int drv_start_nan(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- struct cfg80211_nan_conf *conf)
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -829,6 +829,8 @@ enum txq_info_flags {
- * 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
- */
- struct txq_info {
- struct fq_tin tin;
-@@ -836,6 +838,8 @@ struct txq_info {
- struct codel_vars def_cvars;
- struct codel_stats cstats;
- struct sk_buff_head frags;
-+ struct list_head schedule_order;
-+ u16 schedule_round;
- unsigned long flags;
-
- /* keep last! */
-@@ -1127,6 +1131,11 @@ struct ieee80211_local {
- struct codel_vars *cvars;
- 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];
-+
- const struct ieee80211_ops *ops;
-
- /*
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -652,6 +652,11 @@ struct ieee80211_hw *ieee80211_alloc_hw_
- spin_lock_init(&local->rx_path_lock);
- 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]);
-+ }
-+
- INIT_LIST_HEAD(&local->chanctx_list);
- mutex_init(&local->chanctx_mtx);
-
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -1244,7 +1244,7 @@ void ieee80211_sta_ps_deliver_wakeup(str
- if (!txq_has_queue(sta->sta.txq[i]))
- continue;
-
-- drv_wake_tx_queue(local, to_txq_info(sta->sta.txq[i]));
-+ schedule_and_wake_txq(local, to_txq_info(sta->sta.txq[i]));
- }
- }
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1441,6 +1441,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);
-
- txqi->txq.vif = &sdata->vif;
-
-@@ -1464,6 +1465,9 @@ void ieee80211_txq_purge(struct ieee8021
-
- fq_tin_reset(fq, tin, fq_skb_free_func);
- ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
-+ 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]);
- }
-
- void ieee80211_txq_set_params(struct ieee80211_local *local)
-@@ -1580,7 +1584,7 @@ static bool ieee80211_queue_skb(struct i
- ieee80211_txq_enqueue(local, txqi, skb);
- spin_unlock_bh(&fq->lock);
-
-- drv_wake_tx_queue(local, txqi);
-+ schedule_and_wake_txq(local, txqi);
-
- return true;
- }
-@@ -3602,6 +3606,60 @@ out:
- }
- 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 txq_info *txqi = NULL;
-+
-+ lockdep_assert_held(&local->active_txq_lock[ac]);
-+
-+ txqi = list_first_entry_or_null(&local->active_txqs[ac],
-+ struct txq_info,
-+ schedule_order);
-+
-+ if (!txqi || txqi->schedule_round == local->schedule_round[ac])
-+ return NULL;
-+
-+ list_del_init(&txqi->schedule_order);
-+ txqi->schedule_round = local->schedule_round[ac];
-+ return &txqi->txq;
-+}
-+EXPORT_SYMBOL(ieee80211_next_txq);
-+
-+void ieee80211_return_txq(struct ieee80211_hw *hw,
-+ struct ieee80211_txq *txq)
-+{
-+ struct ieee80211_local *local = hw_to_local(hw);
-+ struct txq_info *txqi = to_txq_info(txq);
-+
-+ lockdep_assert_held(&local->active_txq_lock[txq->ac]);
-+
-+ if (list_empty(&txqi->schedule_order) &&
-+ (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets))
-+ list_add_tail(&txqi->schedule_order,
-+ &local->active_txqs[txq->ac]);
-+}
-+EXPORT_SYMBOL(ieee80211_return_txq);
-+
-+void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
-+ __acquires(txq_lock)
-+{
-+ struct ieee80211_local *local = hw_to_local(hw);
-+
-+ spin_lock_bh(&local->active_txq_lock[ac]);
-+ local->schedule_round[ac]++;
-+}
-+EXPORT_SYMBOL(ieee80211_txq_schedule_start);
-+
-+void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
-+ __releases(txq_lock)
-+{
-+ struct ieee80211_local *local = hw_to_local(hw);
-+
-+ spin_unlock_bh(&local->active_txq_lock[ac]);
-+}
-+EXPORT_SYMBOL(ieee80211_txq_schedule_end);
-+
- void __ieee80211_subif_start_xmit(struct sk_buff *skb,
- struct net_device *dev,
- u32 info_flags)
diff --git a/package/kernel/mac80211/patches/subsys/321-cfg80211-Add-airtime-statistics-and-settings.patch b/package/kernel/mac80211/patches/subsys/321-cfg80211-Add-airtime-statistics-and-settings.patch
deleted file mode 100644
index 7eb64c4251..0000000000
--- a/package/kernel/mac80211/patches/subsys/321-cfg80211-Add-airtime-statistics-and-settings.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@toke.dk>
-Date: Tue, 18 Dec 2018 17:02:07 -0800
-Subject: [PATCH] cfg80211: Add airtime statistics and settings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds TX airtime statistics to the cfg80211 station dump (to go along
-with the RX info already present), and adds a new parameter to set the
-airtime weight of each station. The latter allows userspace to implement
-policies for different stations by varying their weights.
-
-Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
-[rmanohar@codeaurora.org: fixed checkpatch warnings]
-Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org>
-[move airtime weight != 0 check into policy]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -988,6 +988,7 @@ enum station_parameters_apply_mask {
- * @support_p2p_ps: information if station supports P2P PS mechanism
- * @he_capa: HE capabilities of station
- * @he_capa_len: the length of the HE capabilities
-+ * @airtime_weight: airtime scheduler weight for this station
- */
- struct station_parameters {
- const u8 *supported_rates;
-@@ -1017,6 +1018,7 @@ struct station_parameters {
- int support_p2p_ps;
- const struct ieee80211_he_cap_elem *he_capa;
- u8 he_capa_len;
-+ u16 airtime_weight;
- };
-
- /**
-@@ -1284,6 +1286,8 @@ struct cfg80211_tid_stats {
- * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received
- * from this peer
- * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer
-+ * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer
-+ * @airtime_weight: current airtime scheduling weight
- * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last
- * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs.
- * Note that this doesn't use the @filled bit, but is used if non-NULL.
-@@ -1330,12 +1334,15 @@ struct station_info {
-
- u32 expected_throughput;
-
-- u64 rx_beacon;
-+ u64 tx_duration;
- u64 rx_duration;
-+ u64 rx_beacon;
- u8 rx_beacon_signal_avg;
- struct cfg80211_tid_stats *pertid;
- s8 ack_signal;
- s8 avg_ack_signal;
-+
-+ u16 airtime_weight;
- };
-
- #if IS_ENABLED(CPTCFG_CFG80211)
-@@ -2361,6 +2368,8 @@ enum wiphy_params_flags {
- WIPHY_PARAM_TXQ_QUANTUM = 1 << 8,
- };
-
-+#define IEEE80211_DEFAULT_AIRTIME_WEIGHT 256
-+
- /**
- * struct cfg80211_pmksa - PMK Security Association
- *
---- a/include/uapi/linux/nl80211.h
-+++ b/include/uapi/linux/nl80211.h
-@@ -2241,6 +2241,9 @@ enum nl80211_commands {
- * association request when used with NL80211_CMD_NEW_STATION). Can be set
- * only if %NL80211_STA_FLAG_WME is set.
- *
-+ * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime
-+ * scheduler.
-+ *
- * @NUM_NL80211_ATTR: total number of nl80211_attrs available
- * @NL80211_ATTR_MAX: highest attribute number currently defined
- * @__NL80211_ATTR_AFTER_LAST: internal use
-@@ -2682,6 +2685,14 @@ enum nl80211_attrs {
-
- NL80211_ATTR_HE_CAPABILITY,
-
-+ /* not backported yet */
-+ NL80211_ATTR_FTM_RESPONDER,
-+ NL80211_ATTR_FTM_RESPONDER_STATS,
-+ NL80211_ATTR_TIMEOUT,
-+ NL80211_ATTR_PEER_MEASUREMENTS,
-+
-+ NL80211_ATTR_AIRTIME_WEIGHT,
-+
- /* add attributes here, update the policy in nl80211.c */
-
- __NL80211_ATTR_AFTER_LAST,
-@@ -3052,6 +3063,9 @@ enum nl80211_sta_bss_param {
- * @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK frame(u8, dBm)
- * @NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG: avg signal strength of (data)
- * ACK frame (s8, dBm)
-+ * @NL80211_STA_INFO_TX_DURATION: aggregate PPDU duration for all frames
-+ * sent to the station (u64, usec)
-+ * @NL80211_STA_INFO_AIRTIME_WEIGHT: current airtime weight for station (u16)
- * @__NL80211_STA_INFO_AFTER_LAST: internal
- * @NL80211_STA_INFO_MAX: highest possible station info attribute
- */
-@@ -3093,6 +3107,14 @@ enum nl80211_sta_info {
- NL80211_STA_INFO_ACK_SIGNAL,
- NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG,
-
-+ /* not backported yet */
-+ NL80211_STA_INFO_RX_MPDUS,
-+ NL80211_STA_INFO_FCS_ERROR_COUNT,
-+ NL80211_STA_INFO_CONNECTED_TO_GATE,
-+
-+ NL80211_STA_INFO_TX_DURATION,
-+ NL80211_STA_INFO_AIRTIME_WEIGHT,
-+
- /* keep last */
- __NL80211_STA_INFO_AFTER_LAST,
- NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1
-@@ -5224,6 +5246,10 @@ enum nl80211_feature_flags {
- * except for supported rates from the probe request content if requested
- * by the %NL80211_SCAN_FLAG_MIN_PREQ_CONTENT flag.
- *
-+ * @NL80211_EXT_FEATURE_AIRTIME_FAIRNESS: Driver supports getting airtime
-+ * fairness for transmitted packets and has enabled airtime fairness
-+ * scheduling.
-+ *
- * @NUM_NL80211_EXT_FEATURES: number of extended features.
- * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
- */
-@@ -5260,6 +5286,12 @@ enum nl80211_ext_feature_index {
- NL80211_EXT_FEATURE_SCAN_RANDOM_SN,
- NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
-
-+ /* --- not backported yet --- */
-+ NL80211_EXT_FEATURE_CAN_REPLACE_PTK0,
-+ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
-+
-+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
-+
- /* add new features before the definition below */
- NUM_NL80211_EXT_FEATURES,
- MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -430,6 +430,7 @@ static const struct nla_policy nl80211_p
- [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
- [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
- .len = NL80211_HE_MAX_CAPABILITY_LEN },
-+ [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
- };
-
- /* policy for the key attributes */
-@@ -4658,6 +4659,11 @@ static int nl80211_send_station(struct s
- PUT_SINFO(PLID, plid, u16);
- PUT_SINFO(PLINK_STATE, plink_state, u8);
- PUT_SINFO_U64(RX_DURATION, rx_duration);
-+ PUT_SINFO_U64(TX_DURATION, tx_duration);
-+
-+ if (wiphy_ext_feature_isset(&rdev->wiphy,
-+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
-+ PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
-
- switch (rdev->wiphy.signal_type) {
- case CFG80211_SIGNAL_TYPE_MBM:
-@@ -5294,6 +5300,15 @@ static int nl80211_set_station(struct sk
- nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
- }
-
-+ if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
-+ params.airtime_weight =
-+ nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
-+
-+ if (params.airtime_weight &&
-+ !wiphy_ext_feature_isset(&rdev->wiphy,
-+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
-+ return -EOPNOTSUPP;
-+
- /* Include parameters for TDLS peer (will check later) */
- err = nl80211_set_station_tdls(info, &params);
- if (err)
-@@ -5432,6 +5447,15 @@ static int nl80211_new_station(struct sk
- return -EINVAL;
- }
-
-+ if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
-+ params.airtime_weight =
-+ nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
-+
-+ if (params.airtime_weight &&
-+ !wiphy_ext_feature_isset(&rdev->wiphy,
-+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
-+ return -EOPNOTSUPP;
-+
- err = nl80211_parse_sta_channel_info(info, &params);
- if (err)
- return err;
diff --git a/package/kernel/mac80211/patches/subsys/322-mac80211-Add-airtime-accounting-and-scheduling-to-TX.patch b/package/kernel/mac80211/patches/subsys/322-mac80211-Add-airtime-accounting-and-scheduling-to-TX.patch
deleted file mode 100644
index d4176eb491..0000000000
--- a/package/kernel/mac80211/patches/subsys/322-mac80211-Add-airtime-accounting-and-scheduling-to-TX.patch
+++ /dev/null
@@ -1,522 +0,0 @@
-From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@toke.dk>
-Date: Tue, 18 Dec 2018 17:02:08 -0800
-Subject: [PATCH] mac80211: Add airtime accounting and scheduling to TXQs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds airtime accounting and scheduling to the mac80211 TXQ
-scheduler. A new callback, ieee80211_sta_register_airtime(), is added
-that drivers can call to report airtime usage for stations.
-
-When airtime information is present, mac80211 will schedule TXQs
-(through ieee80211_next_txq()) in a way that enforces airtime fairness
-between active stations. This scheduling works the same way as the ath9k
-in-driver airtime fairness scheduling. If no airtime usage is reported
-by the driver, the scheduler will default to round-robin scheduling.
-
-For drivers that don't control TXQ scheduling in software, a new API
-function, ieee80211_txq_may_transmit(), is added which the driver can use
-to check if the TXQ is eligible for transmission, or should be throttled to
-enforce fairness. Calls to this function must also be enclosed in
-ieee80211_txq_schedule_{start,end}() calls to ensure proper locking.
-
-The API ieee80211_txq_may_transmit() also ensures that TXQ list will be
-aligned aginst driver's own round-robin scheduler list. i.e it rotates
-the TXQ list till it makes the requested node becomes the first entry
-in TXQ list. Thus both the TXQ list and driver's list are in sync.
-
-Co-developed-by: Rajkumar Manoharan <rmanohar@codeaurora.org>
-Signed-off-by: Louie Lu <git@louie.lu>
-[added debugfs write op to reset airtime counter]
-Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
-Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -2304,6 +2304,9 @@ enum ieee80211_hw_flags {
- * supported by HW.
- * @max_nan_de_entries: maximum number of NAN DE functions supported by the
- * device.
-+ *
-+ * @weight_multipler: Driver specific airtime weight multiplier used while
-+ * refilling deficit of each TXQ.
- */
- struct ieee80211_hw {
- struct ieee80211_conf conf;
-@@ -2339,6 +2342,7 @@ struct ieee80211_hw {
- u8 n_cipher_schemes;
- const struct ieee80211_cipher_scheme *cipher_schemes;
- u8 max_nan_de_entries;
-+ u8 weight_multiplier;
- };
-
- static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw,
-@@ -5299,6 +5303,34 @@ void ieee80211_sta_eosp(struct ieee80211
- void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid);
-
- /**
-+ * ieee80211_sta_register_airtime - register airtime usage for a sta/tid
-+ *
-+ * Register airtime usage for a given sta on a given tid. The driver can call
-+ * this function to notify mac80211 that a station used a certain amount of
-+ * airtime. This information will be used by the TXQ scheduler to schedule
-+ * stations in a way that ensures airtime fairness.
-+ *
-+ * The reported airtime should as a minimum include all time that is spent
-+ * transmitting to the remote station, including overhead and padding, but not
-+ * including time spent waiting for a TXOP. If the time is not reported by the
-+ * hardware it can in some cases be calculated from the rate and known frame
-+ * composition. When possible, the time should include any failed transmission
-+ * attempts.
-+ *
-+ * The driver can either call this function synchronously for every packet or
-+ * aggregate, or asynchronously as airtime usage information becomes available.
-+ * TX and RX airtime can be reported together, or separately by setting one of
-+ * them to 0.
-+ *
-+ * @pubsta: the station
-+ * @tid: the TID to register airtime for
-+ * @tx_airtime: airtime used during TX (in usec)
-+ * @rx_airtime: airtime used during RX (in usec)
-+ */
-+void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
-+ u32 tx_airtime, u32 rx_airtime);
-+
-+/**
- * ieee80211_iter_keys - iterate keys programmed into the device
- * @hw: pointer obtained from ieee80211_alloc_hw()
- * @vif: virtual interface to iterate, may be %NULL for all
-@@ -6042,6 +6074,33 @@ void ieee80211_txq_schedule_end(struct i
- __releases(txq_lock);
-
- /**
-+ * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
-+ *
-+ * This function is used to check whether given txq is allowed to transmit by
-+ * the airtime scheduler, and can be used by drivers to access the airtime
-+ * fairness accounting without going using the scheduling order enfored by
-+ * next_txq().
-+ *
-+ * Returns %true if the airtime scheduler thinks the TXQ should be allowed to
-+ * transmit, and %false if it should be throttled. This function can also have
-+ * the side effect of rotating the TXQ in the scheduler rotation, which will
-+ * eventually bring the deficit to positive and allow the station to transmit
-+ * again.
-+ *
-+ * The API ieee80211_txq_may_transmit() also ensures that TXQ list will be
-+ * aligned aginst driver's own round-robin scheduler list. i.e it rotates
-+ * the TXQ list till it makes the requested node becomes the first entry
-+ * in TXQ list. Thus both the TXQ list and driver's list are in sync. If this
-+ * function returns %true, the driver is expected to schedule packets
-+ * for transmission, and then return the TXQ through ieee80211_return_txq().
-+ *
-+ * @hw: pointer as obtained from ieee80211_alloc_hw()
-+ * @txq: pointer obtained from station or virtual interface
-+ */
-+bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
-+ struct ieee80211_txq *txq);
-+
-+/**
- * ieee80211_txq_get_depth - get pending frame/byte count of given txq
- *
- * The values are not guaranteed to be coherent with regard to each other, i.e.
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1434,6 +1434,9 @@ static int sta_apply_parameters(struct i
- if (ieee80211_vif_is_mesh(&sdata->vif))
- sta_apply_mesh_params(local, sta, params);
-
-+ if (params->airtime_weight)
-+ sta->airtime_weight = params->airtime_weight;
-+
- /* set the STA state after all sta info from usermode has been set */
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) ||
- set & BIT(NL80211_STA_FLAG_ASSOCIATED)) {
---- a/net/mac80211/debugfs.c
-+++ b/net/mac80211/debugfs.c
-@@ -380,6 +380,9 @@ void debugfs_hw_add(struct ieee80211_loc
- if (local->ops->wake_tx_queue)
- DEBUGFS_ADD_MODE(aqm, 0600);
-
-+ debugfs_create_u16("airtime_flags", 0600,
-+ phyd, &local->airtime_flags);
-+
- statsd = debugfs_create_dir("statistics", phyd);
-
- /* if the dir failed, don't put all the other things into the root! */
---- a/net/mac80211/debugfs_sta.c
-+++ b/net/mac80211/debugfs_sta.c
-@@ -178,9 +178,9 @@ static ssize_t sta_aqm_read(struct file
- txqi->tin.tx_bytes,
- txqi->tin.tx_packets,
- txqi->flags,
-- txqi->flags & (1<<IEEE80211_TXQ_STOP) ? "STOP" : "RUN",
-- txqi->flags & (1<<IEEE80211_TXQ_AMPDU) ? " AMPDU" : "",
-- txqi->flags & (1<<IEEE80211_TXQ_NO_AMSDU) ? " NO-AMSDU" : "");
-+ test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ? "STOP" : "RUN",
-+ test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags) ? " AMPDU" : "",
-+ test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags) ? " NO-AMSDU" : "");
- }
-
- rcu_read_unlock();
-@@ -192,6 +192,64 @@ static ssize_t sta_aqm_read(struct file
- }
- STA_OPS(aqm);
-
-+static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct sta_info *sta = file->private_data;
-+ struct ieee80211_local *local = sta->sdata->local;
-+ size_t bufsz = 200;
-+ char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
-+ u64 rx_airtime = 0, tx_airtime = 0;
-+ s64 deficit[IEEE80211_NUM_ACS];
-+ ssize_t rv;
-+ int ac;
-+
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-+ spin_lock_bh(&local->active_txq_lock[ac]);
-+ 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]);
-+ }
-+
-+ 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]);
-+
-+ rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
-+ kfree(buf);
-+ return rv;
-+}
-+
-+static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct sta_info *sta = file->private_data;
-+ struct ieee80211_local *local = sta->sdata->local;
-+ int ac;
-+
-+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-+ spin_lock_bh(&local->active_txq_lock[ac]);
-+ 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]);
-+ }
-+
-+ return count;
-+}
-+STA_OPS_RW(airtime);
-+
- static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
- {
-@@ -546,6 +604,10 @@ void ieee80211_sta_debugfs_add(struct st
- if (local->ops->wake_tx_queue)
- DEBUGFS_ADD(aqm);
-
-+ if (wiphy_ext_feature_isset(local->hw.wiphy,
-+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
-+ DEBUGFS_ADD(airtime);
-+
- if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
- debugfs_create_x32("driver_buffered_tids", 0400,
- sta->debugfs_dir,
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1136,6 +1136,8 @@ struct ieee80211_local {
- struct list_head active_txqs[IEEE80211_NUM_ACS];
- u16 schedule_round[IEEE80211_NUM_ACS];
-
-+ u16 airtime_flags;
-+
- const struct ieee80211_ops *ops;
-
- /*
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -656,6 +656,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
- INIT_LIST_HEAD(&local->active_txqs[i]);
- spin_lock_init(&local->active_txq_lock[i]);
- }
-+ local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
-
- INIT_LIST_HEAD(&local->chanctx_list);
- mutex_init(&local->chanctx_mtx);
-@@ -1142,6 +1143,9 @@ int ieee80211_register_hw(struct ieee802
- if (!local->hw.max_nan_de_entries)
- local->hw.max_nan_de_entries = IEEE80211_MAX_NAN_INSTANCE_ID;
-
-+ if (!local->hw.weight_multiplier)
-+ local->hw.weight_multiplier = 1;
-+
- result = ieee80211_wep_init(local);
- if (result < 0)
- wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -90,7 +90,6 @@ static void __cleanup_single_sta(struct
- struct tid_ampdu_tx *tid_tx;
- struct ieee80211_sub_if_data *sdata = sta->sdata;
- struct ieee80211_local *local = sdata->local;
-- struct fq *fq = &local->fq;
- struct ps_data *ps;
-
- if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
-@@ -115,9 +114,7 @@ static void __cleanup_single_sta(struct
- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
- struct txq_info *txqi = to_txq_info(sta->sta.txq[i]);
-
-- spin_lock_bh(&fq->lock);
- ieee80211_txq_purge(local, txqi);
-- spin_unlock_bh(&fq->lock);
- }
- }
-
-@@ -381,9 +378,12 @@ 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;
- }
-
- for (i = 0; i < IEEE80211_NUM_TIDS; i++)
-@@ -1821,6 +1821,27 @@ 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)
-+{
-+ 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);
-+ u32 airtime = 0;
-+
-+ if (sta->local->airtime_flags & AIRTIME_USE_TX)
-+ airtime += tx_airtime;
-+ if (sta->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]);
-+}
-+EXPORT_SYMBOL(ieee80211_sta_register_airtime);
-+
- int sta_info_move_state(struct sta_info *sta,
- enum ieee80211_sta_state new_state)
- {
-@@ -2183,6 +2204,23 @@ void sta_set_sinfo(struct sta_info *sta,
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
- }
-
-+ if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_DURATION))) {
-+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
-+ sinfo->rx_duration += sta->airtime[ac].rx_airtime;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);
-+ }
-+
-+ if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_DURATION))) {
-+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
-+ sinfo->tx_duration += sta->airtime[ac].tx_airtime;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION);
-+ }
-+
-+ if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) {
-+ sinfo->airtime_weight = sta->airtime_weight;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT);
-+ }
-+
- sinfo->rx_dropped_misc = sta->rx_stats.dropped;
- if (sta->pcpu_rx_stats) {
- for_each_possible_cpu(cpu) {
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -127,6 +127,16 @@ enum ieee80211_agg_stop_reason {
- AGG_STOP_DESTROY_STA,
- };
-
-+/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
-+#define AIRTIME_USE_TX BIT(0)
-+#define AIRTIME_USE_RX BIT(1)
-+
-+struct airtime_info {
-+ u64 rx_airtime;
-+ u64 tx_airtime;
-+ s64 deficit;
-+};
-+
- struct sta_info;
-
- /**
-@@ -563,6 +573,9 @@ struct sta_info {
- } tx_stats;
- 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
-@@ -825,6 +825,12 @@ static void __ieee80211_tx_status(struct
- ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
- acked, info->status.tx_time);
-
-+ if (info->status.tx_time &&
-+ wiphy_ext_feature_isset(local->hw.wiphy,
-+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
-+ ieee80211_sta_register_airtime(&sta->sta, tid,
-+ info->status.tx_time, 0);
-+
- if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
- if (info->flags & IEEE80211_TX_STAT_ACK) {
- if (sta->status_stats.lost_packets)
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1463,8 +1463,11 @@ void ieee80211_txq_purge(struct ieee8021
- struct fq *fq = &local->fq;
- struct fq_tin *tin = &txqi->tin;
-
-+ spin_lock_bh(&fq->lock);
- fq_tin_reset(fq, tin, fq_skb_free_func);
- 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]);
-@@ -3613,11 +3616,28 @@ struct ieee80211_txq *ieee80211_next_txq
-
- lockdep_assert_held(&local->active_txq_lock[ac]);
-
-+ begin:
- txqi = list_first_entry_or_null(&local->active_txqs[ac],
- struct txq_info,
- schedule_order);
-+ if (!txqi)
-+ return NULL;
-+
-+ if (txqi->txq.sta) {
-+ struct sta_info *sta = container_of(txqi->txq.sta,
-+ struct sta_info, sta);
-+
-+ if (sta->airtime[txqi->txq.ac].deficit < 0) {
-+ sta->airtime[txqi->txq.ac].deficit +=
-+ sta->airtime_weight;
-+ list_move_tail(&txqi->schedule_order,
-+ &local->active_txqs[txqi->txq.ac]);
-+ goto begin;
-+ }
-+ }
-+
-
-- if (!txqi || txqi->schedule_round == local->schedule_round[ac])
-+ if (txqi->schedule_round == local->schedule_round[ac])
- return NULL;
-
- list_del_init(&txqi->schedule_order);
-@@ -3635,12 +3655,74 @@ void ieee80211_return_txq(struct ieee802
- lockdep_assert_held(&local->active_txq_lock[txq->ac]);
-
- if (list_empty(&txqi->schedule_order) &&
-- (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets))
-- list_add_tail(&txqi->schedule_order,
-- &local->active_txqs[txq->ac]);
-+ (!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 &&
-+ 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]);
-+ }
- }
- EXPORT_SYMBOL(ieee80211_return_txq);
-
-+bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
-+ struct ieee80211_txq *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;
-+
-+ lockdep_assert_held(&local->active_txq_lock[ac]);
-+
-+ if (!txqi->txq.sta)
-+ goto out;
-+
-+ if (list_empty(&txqi->schedule_order))
-+ goto out;
-+
-+ list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
-+ schedule_order) {
-+ if (iter == txqi)
-+ break;
-+
-+ 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]);
-+ }
-+
-+ 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]);
-+
-+ return false;
-+out:
-+ if (!list_empty(&txqi->schedule_order))
-+ list_del_init(&txqi->schedule_order);
-+
-+ return true;
-+}
-+EXPORT_SYMBOL(ieee80211_txq_may_transmit);
-+
- void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
- __acquires(txq_lock)
- {
diff --git a/package/kernel/mac80211/patches/subsys/323-mac80211-Expose-ieee80211_schedule_txq-function.patch b/package/kernel/mac80211/patches/subsys/323-mac80211-Expose-ieee80211_schedule_txq-function.patch
deleted file mode 100644
index 573f9bd135..0000000000
--- a/package/kernel/mac80211/patches/subsys/323-mac80211-Expose-ieee80211_schedule_txq-function.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
-Date: Tue, 22 Jan 2019 15:20:16 +0100
-Subject: [PATCH] mac80211: Expose ieee80211_schedule_txq() function
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Since we reworked ieee80211_return_txq() so it assumes that the caller
-takes care of logging, we need another function that can be called without
-holding any locks. Introduce ieee80211_schedule_txq() which serves this
-purpose.
-
-Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -6074,6 +6074,19 @@ void ieee80211_txq_schedule_end(struct i
- __releases(txq_lock);
-
- /**
-+ * ieee80211_schedule_txq - schedule a TXQ for transmission
-+ *
-+ * @hw: pointer as obtained from ieee80211_alloc_hw()
-+ * @txq: pointer obtained from station or virtual interface
-+ *
-+ * Schedules a TXQ for transmission if it is not already scheduled. Takes a
-+ * lock, which means it must *not* be called between
-+ * ieee80211_txq_schedule_start() and ieee80211_txq_schedule_end()
-+ */
-+void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
-+ __acquires(txq_lock) __releases(txq_lock);
-+
-+/**
- * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
- *
- * This function is used to check whether given txq is allowed to transmit by
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -1179,9 +1179,7 @@ static inline void drv_wake_tx_queue(str
- static inline void schedule_and_wake_txq(struct ieee80211_local *local,
- struct txq_info *txqi)
- {
-- spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
-- ieee80211_return_txq(&local->hw, &txqi->txq);
-- spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
-+ ieee80211_schedule_txq(&local->hw, &txqi->txq);
- drv_wake_tx_queue(local, txqi);
- }
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3675,6 +3675,19 @@ void ieee80211_return_txq(struct ieee802
- }
- EXPORT_SYMBOL(ieee80211_return_txq);
-
-+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);
-+
-+ spin_lock_bh(&local->active_txq_lock[txq->ac]);
-+ ieee80211_return_txq(hw, txq);
-+ spin_unlock_bh(&local->active_txq_lock[txq->ac]);
-+}
-+EXPORT_SYMBOL(ieee80211_schedule_txq);
-+
- bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
- struct ieee80211_txq *txq)
- {
diff --git a/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch
index 2759895c98..e88163eb5d 100644
--- a/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch
+++ b/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch
@@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -179,6 +179,7 @@ struct ieee80211_tx_data {
+@@ -176,6 +176,7 @@ struct ieee80211_tx_data {
struct ieee80211_tx_rate rate;
unsigned int flags;
@@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -925,7 +925,7 @@ ieee80211_tx_h_fragment(struct ieee80211
+@@ -921,7 +921,7 @@ ieee80211_tx_h_fragment(struct ieee80211
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (void *)skb->data;
int frag_threshold = tx->local->hw.wiphy->frag_threshold;
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
int fragnum;
/* no matter what happens, tx->skb moves to tx->skbs */
-@@ -946,8 +946,6 @@ ieee80211_tx_h_fragment(struct ieee80211
+@@ -942,8 +942,6 @@ ieee80211_tx_h_fragment(struct ieee80211
if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
return TX_DROP;
@@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* internal error, why isn't DONTFRAG set? */
if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
return TX_DROP;
-@@ -1178,6 +1176,8 @@ ieee80211_tx_prepare(struct ieee80211_su
+@@ -1174,6 +1172,8 @@ ieee80211_tx_prepare(struct ieee80211_su
hdr = (struct ieee80211_hdr *) skb->data;
@@ -48,7 +48,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (likely(sta)) {
if (!IS_ERR(sta))
tx->sta = sta;
-@@ -3525,6 +3525,7 @@ begin:
+@@ -3577,6 +3577,7 @@ begin:
tx.local = local;
tx.skb = skb;
tx.sdata = vif_to_sdata(info->control.vif);
@@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (txq->sta)
tx.sta = container_of(txq->sta, struct sta_info, sta);
-@@ -3551,7 +3552,7 @@ begin:
+@@ -3603,7 +3604,7 @@ begin:
if (tx.key &&
(tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
@@ -65,7 +65,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
tx.key, skb);
-@@ -4008,6 +4009,7 @@ ieee80211_build_data_template(struct iee
+@@ -4058,6 +4059,7 @@ ieee80211_build_data_template(struct iee
hdr = (void *)skb->data;
tx.sta = sta_info_get(sdata, hdr->addr1);
tx.skb = skb;
@@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
rcu_read_unlock();
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
-@@ -1390,6 +1390,7 @@ void ieee80211_send_auth(struct ieee8021
+@@ -1538,6 +1538,7 @@ void ieee80211_send_auth(struct ieee8021
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
@@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
int err;
/* 24 + 6 = header + auth_algo + auth_transaction + status_code */
-@@ -1413,8 +1414,10 @@ void ieee80211_send_auth(struct ieee8021
+@@ -1561,8 +1562,10 @@ void ieee80211_send_auth(struct ieee8021
skb_put_data(skb, extra, extra_len);
if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
@@ -97,7 +97,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
-@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct
+@@ -86,11 +86,11 @@ static void ieee80211_wep_get_iv(struct
static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
struct sk_buff *skb,
@@ -110,7 +110,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
u8 *newhdr;
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i
+@@ -98,7 +98,6 @@ static u8 *ieee80211_wep_add_iv(struct i
if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
return NULL;
@@ -118,7 +118,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN);
memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen);
-@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr
+@@ -157,6 +156,7 @@ int ieee80211_wep_encrypt_data(struct cr
*/
int ieee80211_wep_encrypt(struct ieee80211_local *local,
struct sk_buff *skb,
@@ -126,7 +126,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
const u8 *key, int keylen, int keyidx)
{
u8 *iv;
-@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802
+@@ -166,7 +166,7 @@ int ieee80211_wep_encrypt(struct ieee802
if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN))
return -1;
@@ -135,7 +135,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!iv)
return -1;
-@@ -307,13 +307,14 @@ static int wep_encrypt_skb(struct ieee80
+@@ -304,13 +304,14 @@ static int wep_encrypt_skb(struct ieee80
struct ieee80211_key_conf *hw_key = info->control.hw_key;
if (!hw_key) {
@@ -154,7 +154,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
return -1;
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
-@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr
+@@ -19,6 +19,7 @@ int ieee80211_wep_encrypt_data(struct cr
size_t klen, u8 *data, size_t data_len);
int ieee80211_wep_encrypt(struct ieee80211_local *local,
struct sk_buff *skb,
@@ -164,7 +164,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
size_t klen, u8 *data, size_t data_len);
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
-@@ -44,7 +44,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
+@@ -41,7 +41,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control))
return TX_CONTINUE;
@@ -173,7 +173,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (skb->len < hdrlen)
return TX_DROP;
-@@ -195,7 +195,6 @@ mic_fail_no_key:
+@@ -192,7 +192,6 @@ mic_fail_no_key:
static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
{
@@ -181,7 +181,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct ieee80211_key *key = tx->key;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
unsigned int hdrlen;
-@@ -210,7 +209,7 @@ static int tkip_encrypt_skb(struct ieee8
+@@ -207,7 +206,7 @@ static int tkip_encrypt_skb(struct ieee8
return 0;
}
@@ -190,7 +190,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
len = skb->len - hdrlen;
if (info->control.hw_key)
-@@ -428,7 +427,7 @@ static int ccmp_encrypt_skb(struct ieee8
+@@ -425,7 +424,7 @@ static int ccmp_encrypt_skb(struct ieee8
return 0;
}
@@ -199,7 +199,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
len = skb->len - hdrlen;
if (info->control.hw_key)
-@@ -660,7 +659,7 @@ static int gcmp_encrypt_skb(struct ieee8
+@@ -657,7 +656,7 @@ static int gcmp_encrypt_skb(struct ieee8
return 0;
}
@@ -208,7 +208,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
len = skb->len - hdrlen;
if (info->control.hw_key)
-@@ -800,7 +799,6 @@ static ieee80211_tx_result
+@@ -797,7 +796,6 @@ static ieee80211_tx_result
ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
struct sk_buff *skb)
{
@@ -216,7 +216,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct ieee80211_key *key = tx->key;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int hdrlen;
-@@ -816,8 +814,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8
+@@ -813,8 +811,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8
pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC)))
return TX_DROP;
diff --git a/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch
index d8dbecca1b..8d9b6e7de9 100644
--- a/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch
+++ b/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch
@@ -20,9 +20,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -2140,6 +2140,9 @@ struct ieee80211_txq {
- * @IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN: Driver does not report accurate A-MPDU
- * length in tx status information
+@@ -2266,6 +2266,9 @@ struct ieee80211_txq {
+ * @IEEE80211_HW_EXT_KEY_ID_NATIVE: Driver and hardware are supporting Extended
+ * Key ID and can handle two unicast keys per station for Rx and Tx.
*
+ * @IEEE80211_HW_TX_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte.
+ * Padding will be added after ieee80211_hdr, before IV/LLC.
@@ -30,15 +30,15 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
-@@ -2186,6 +2189,7 @@ enum ieee80211_hw_flags {
- IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP,
- IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP,
- IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
+@@ -2318,6 +2321,7 @@ enum ieee80211_hw_flags {
+ IEEE80211_HW_SUPPORTS_MULTI_BSSID,
+ IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
+ IEEE80211_HW_EXT_KEY_ID_NATIVE,
+ IEEE80211_HW_TX_NEEDS_ALIGNED4_SKBS,
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
-@@ -2472,6 +2476,40 @@ ieee80211_get_alt_retry_rate(const struc
+@@ -2611,6 +2615,40 @@ ieee80211_get_alt_retry_rate(const struc
void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
/**
@@ -81,7 +81,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
* mac80211 is capable of taking advantage of many hardware
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
-@@ -1871,6 +1871,10 @@ int ieee80211_if_add(struct ieee80211_lo
+@@ -1877,6 +1877,10 @@ int ieee80211_if_add(struct ieee80211_lo
+ 8 /* rfc1042/bridge tunnel */
- ETH_HLEN /* ethernet hard_header_len */
+ IEEE80211_ENCRYPT_HEADROOM;
@@ -94,7 +94,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
ret = dev_alloc_name(ndev, ndev->name);
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
-@@ -105,13 +105,15 @@ void mesh_path_assign_nexthop(struct mes
+@@ -102,13 +102,15 @@ void mesh_path_assign_nexthop(struct mes
static void prepare_for_gate(struct sk_buff *skb, char *dst_addr,
struct mesh_path *gate_mpath)
{
@@ -113,7 +113,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!(mshdr->flags & MESH_FLAGS_AE)) {
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2597,7 +2597,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
+@@ -2673,7 +2673,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -122,7 +122,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
int tailroom = 0;
hdr = (struct ieee80211_hdr *) skb->data;
-@@ -2690,7 +2690,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
+@@ -2766,7 +2766,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
if (sdata->crypto_tx_tailroom_needed_cnt)
tailroom = IEEE80211_ENCRYPT_TAILROOM;
@@ -133,7 +133,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
sdata->encrypt_headroom,
tailroom, GFP_ATOMIC);
if (!fwd_skb)
-@@ -2722,6 +2724,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
+@@ -2798,6 +2800,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
return RX_DROP_MONITOR;
}
@@ -148,7 +148,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
out:
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
-@@ -311,7 +311,7 @@ struct ieee80211_fast_tx {
+@@ -308,7 +308,7 @@ struct ieee80211_fast_tx {
u8 hdr_len;
u8 sa_offs, da_offs, pn_offs;
u8 band;
@@ -159,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct rcu_head rcu_head;
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
-@@ -515,6 +515,7 @@ static void ieee80211_report_used_skb(st
+@@ -512,6 +512,7 @@ static void ieee80211_report_used_skb(st
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (void *)skb->data;
@@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
bool acked = info->flags & IEEE80211_TX_STAT_ACK;
if (dropped)
-@@ -531,7 +532,7 @@ static void ieee80211_report_used_skb(st
+@@ -528,7 +529,7 @@ static void ieee80211_report_used_skb(st
skb->dev = NULL;
} else {
unsigned int hdr_size =
@@ -176,7 +176,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* Check to see if packet is a TDLS teardown packet */
if (ieee80211_is_data(hdr->frame_control) &&
-@@ -655,9 +656,22 @@ void ieee80211_tx_monitor(struct ieee802
+@@ -652,9 +653,22 @@ void ieee80211_tx_monitor(struct ieee802
struct sk_buff *skb2;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_sub_if_data *sdata;
@@ -201,7 +201,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
-@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8
+@@ -198,10 +198,12 @@ void ieee80211_get_tkip_p2k(struct ieee8
{
struct ieee80211_key *key = (struct ieee80211_key *)
container_of(keyconf, struct ieee80211_key, conf);
@@ -217,7 +217,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -1175,8 +1175,7 @@ ieee80211_tx_prepare(struct ieee80211_su
+@@ -1171,8 +1171,7 @@ ieee80211_tx_prepare(struct ieee80211_su
info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING;
hdr = (struct ieee80211_hdr *) skb->data;
@@ -227,7 +227,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (likely(sta)) {
if (!IS_ERR(sta))
-@@ -2222,7 +2221,7 @@ netdev_tx_t ieee80211_monitor_start_xmit
+@@ -2244,7 +2243,7 @@ netdev_tx_t ieee80211_monitor_start_xmit
goto fail;
hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
@@ -236,7 +236,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (skb->len < len_rthdr + hdrlen)
goto fail;
-@@ -2440,7 +2439,7 @@ static struct sk_buff *ieee80211_build_h
+@@ -2463,7 +2462,7 @@ static struct sk_buff *ieee80211_build_h
struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_sub_if_data *ap_sdata;
enum nl80211_band band;
@@ -245,7 +245,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (IS_ERR(sta))
sta = NULL;
-@@ -2739,7 +2738,9 @@ static struct sk_buff *ieee80211_build_h
+@@ -2774,7 +2773,9 @@ static struct sk_buff *ieee80211_build_h
}
skb_pull(skb, skip_header_bytes);
@@ -255,7 +255,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/*
* So we need to modify the skb header and hence need a copy of
-@@ -2772,6 +2773,9 @@ static struct sk_buff *ieee80211_build_h
+@@ -2807,6 +2808,9 @@ static struct sk_buff *ieee80211_build_h
memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
#endif
@@ -265,7 +265,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (ieee80211_is_data_qos(fc)) {
__le16 *qos_control;
-@@ -2947,6 +2951,8 @@ void ieee80211_check_fast_xmit(struct st
+@@ -2983,6 +2987,8 @@ void ieee80211_check_fast_xmit(struct st
fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
}
@@ -274,7 +274,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* We store the key here so there's no point in using rcu_dereference()
* but that's fine because the code that changes the pointers will call
* this function after doing so. For a single CPU that would be enough,
-@@ -3525,7 +3531,7 @@ begin:
+@@ -3577,7 +3583,7 @@ begin:
tx.local = local;
tx.skb = skb;
tx.sdata = vif_to_sdata(info->control.vif);
@@ -283,7 +283,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (txq->sta)
tx.sta = container_of(txq->sta, struct sta_info, sta);
-@@ -4009,7 +4015,7 @@ ieee80211_build_data_template(struct iee
+@@ -4059,7 +4065,7 @@ ieee80211_build_data_template(struct iee
hdr = (void *)skb->data;
tx.sta = sta_info_get(sdata, hdr->addr1);
tx.skb = skb;
@@ -294,10 +294,10 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
rcu_read_unlock();
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
-@@ -215,6 +215,7 @@ static const char *hw_flag_names[] = {
- FLAG(DEAUTH_NEED_MGD_TX_PREP),
- FLAG(DOESNT_SUPPORT_QOS_NDP),
- FLAG(TX_STATUS_NO_AMPDU_LEN),
+@@ -272,6 +272,7 @@ static const char *hw_flag_names[] = {
+ FLAG(SUPPORTS_MULTI_BSSID),
+ FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
+ FLAG(EXT_KEY_ID_NATIVE),
+ FLAG(TX_NEEDS_ALIGNED4_SKBS),
#undef FLAG
};
diff --git a/package/kernel/mac80211/patches/subsys/352-mac80211-rework-locking-for-txq-scheduling-airtime-f.patch b/package/kernel/mac80211/patches/subsys/352-mac80211-rework-locking-for-txq-scheduling-airtime-f.patch
deleted file mode 100644
index ef67dd1977..0000000000
--- a/package/kernel/mac80211/patches/subsys/352-mac80211-rework-locking-for-txq-scheduling-airtime-f.patch
+++ /dev/null
@@ -1,214 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 13 Mar 2019 19:09:22 +0100
-Subject: [PATCH] mac80211: rework locking for txq scheduling / airtime
- fairness
-
-Holding the lock around the entire duration of tx scheduling can create
-some nasty lock contention, especially when processing airtime information
-from the tx status or the rx path.
-Improve locking by only holding the active_txq_lock for lookups / scheduling
-list modifications.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -6069,8 +6069,6 @@ struct sk_buff *ieee80211_tx_dequeue(str
- * @hw: pointer as obtained from ieee80211_alloc_hw()
- * @ac: AC number to return packets from.
- *
-- * Should only be called between calls to ieee80211_txq_schedule_start()
-- * and ieee80211_txq_schedule_end().
- * Returns the next txq if successful, %NULL if no queue is eligible. If a txq
- * is returned, it should be returned with ieee80211_return_txq() after the
- * driver has finished scheduling it.
-@@ -6078,51 +6076,41 @@ struct sk_buff *ieee80211_tx_dequeue(str
- struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac);
-
- /**
-- * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
-- *
-- * @hw: pointer as obtained from ieee80211_alloc_hw()
-- * @txq: pointer obtained from station or virtual interface
-- *
-- * Should only be called between calls to ieee80211_txq_schedule_start()
-- * and ieee80211_txq_schedule_end().
-- */
--void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
--
--/**
-- * ieee80211_txq_schedule_start - acquire locks for safe scheduling of an AC
-+ * ieee80211_txq_schedule_start - start new scheduling round for TXQs
- *
- * @hw: pointer as obtained from ieee80211_alloc_hw()
- * @ac: AC number to acquire locks for
- *
-- * Acquire locks needed to schedule TXQs from the given AC. Should be called
-- * before ieee80211_next_txq() or ieee80211_return_txq().
-+ * Should be called before ieee80211_next_txq() or ieee80211_return_txq().
- */
--void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
-- __acquires(txq_lock);
-+void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac);
-+
-+/* (deprecated) */
-+static inline void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
-+{
-+}
-
- /**
-- * ieee80211_txq_schedule_end - release locks for safe scheduling of an AC
-+ * ieee80211_schedule_txq - schedule a TXQ for transmission
- *
- * @hw: pointer as obtained from ieee80211_alloc_hw()
-- * @ac: AC number to acquire locks for
-+ * @txq: pointer obtained from station or virtual interface
- *
-- * Release locks previously acquired by ieee80211_txq_schedule_end().
-+ * Schedules a TXQ for transmission if it is not already scheduled.
- */
--void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
-- __releases(txq_lock);
-+void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
-
- /**
-- * ieee80211_schedule_txq - schedule a TXQ for transmission
-+ * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
- *
- * @hw: pointer as obtained from ieee80211_alloc_hw()
- * @txq: pointer obtained from station or virtual interface
-- *
-- * Schedules a TXQ for transmission if it is not already scheduled. Takes a
-- * lock, which means it must *not* be called between
-- * ieee80211_txq_schedule_start() and ieee80211_txq_schedule_end()
- */
--void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
-- __acquires(txq_lock) __releases(txq_lock);
-+static inline void
-+ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
-+{
-+ ieee80211_schedule_txq(hw, txq);
-+}
-
- /**
- * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3619,16 +3619,17 @@ 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 ieee80211_txq *ret = NULL;
- struct txq_info *txqi = NULL;
-
-- lockdep_assert_held(&local->active_txq_lock[ac]);
-+ spin_lock_bh(&local->active_txq_lock[ac]);
-
- begin:
- txqi = list_first_entry_or_null(&local->active_txqs[ac],
- struct txq_info,
- schedule_order);
- if (!txqi)
-- return NULL;
-+ goto out;
-
- if (txqi->txq.sta) {
- struct sta_info *sta = container_of(txqi->txq.sta,
-@@ -3645,21 +3646,25 @@ struct ieee80211_txq *ieee80211_next_txq
-
-
- if (txqi->schedule_round == local->schedule_round[ac])
-- return NULL;
-+ goto out;
-
- list_del_init(&txqi->schedule_order);
- txqi->schedule_round = local->schedule_round[ac];
-- return &txqi->txq;
-+ ret = &txqi->txq;
-+
-+out:
-+ spin_unlock_bh(&local->active_txq_lock[ac]);
-+ return ret;
- }
- EXPORT_SYMBOL(ieee80211_next_txq);
-
--void ieee80211_return_txq(struct ieee80211_hw *hw,
-- struct ieee80211_txq *txq)
-+void ieee80211_schedule_txq(struct ieee80211_hw *hw,
-+ struct ieee80211_txq *txq)
- {
- struct ieee80211_local *local = hw_to_local(hw);
- struct txq_info *txqi = to_txq_info(txq);
-
-- lockdep_assert_held(&local->active_txq_lock[txq->ac]);
-+ spin_lock_bh(&local->active_txq_lock[txq->ac]);
-
- if (list_empty(&txqi->schedule_order) &&
- (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
-@@ -3679,18 +3684,7 @@ void ieee80211_return_txq(struct ieee802
- list_add_tail(&txqi->schedule_order,
- &local->active_txqs[txq->ac]);
- }
--}
--EXPORT_SYMBOL(ieee80211_return_txq);
-
--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);
--
-- spin_lock_bh(&local->active_txq_lock[txq->ac]);
-- ieee80211_return_txq(hw, txq);
- spin_unlock_bh(&local->active_txq_lock[txq->ac]);
- }
- EXPORT_SYMBOL(ieee80211_schedule_txq);
-@@ -3703,7 +3697,7 @@ bool ieee80211_txq_may_transmit(struct i
- struct sta_info *sta;
- u8 ac = txq->ac;
-
-- lockdep_assert_held(&local->active_txq_lock[ac]);
-+ spin_lock_bh(&local->active_txq_lock[ac]);
-
- if (!txqi->txq.sta)
- goto out;
-@@ -3733,34 +3727,27 @@ bool ieee80211_txq_may_transmit(struct i
-
- 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]);
-
- 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;
- }
- EXPORT_SYMBOL(ieee80211_txq_may_transmit);
-
- void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
-- __acquires(txq_lock)
- {
- struct ieee80211_local *local = hw_to_local(hw);
-
- spin_lock_bh(&local->active_txq_lock[ac]);
- local->schedule_round[ac]++;
--}
--EXPORT_SYMBOL(ieee80211_txq_schedule_start);
--
--void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
-- __releases(txq_lock)
--{
-- struct ieee80211_local *local = hw_to_local(hw);
--
- spin_unlock_bh(&local->active_txq_lock[ac]);
- }
--EXPORT_SYMBOL(ieee80211_txq_schedule_end);
-+EXPORT_SYMBOL(ieee80211_txq_schedule_start);
-
- void __ieee80211_subif_start_xmit(struct sk_buff *skb,
- struct net_device *dev,
diff --git a/package/kernel/mac80211/patches/subsys/353-mac80211-mesh-drop-redundant-rcu_read_lock-unlock-ca.patch b/package/kernel/mac80211/patches/subsys/353-mac80211-mesh-drop-redundant-rcu_read_lock-unlock-ca.patch
deleted file mode 100644
index 86300be4ed..0000000000
--- a/package/kernel/mac80211/patches/subsys/353-mac80211-mesh-drop-redundant-rcu_read_lock-unlock-ca.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 16 Mar 2019 17:43:58 +0100
-Subject: [PATCH] mac80211: mesh: drop redundant rcu_read_lock/unlock calls
-
-The callers of these functions are all within RCU locked sections
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/mesh_hwmp.c
-+++ b/net/mac80211/mesh_hwmp.c
-@@ -1112,16 +1112,13 @@ int mesh_nexthop_resolve(struct ieee8021
- struct mesh_path *mpath;
- struct sk_buff *skb_to_free = NULL;
- u8 *target_addr = hdr->addr3;
-- int err = 0;
-
- /* Nulls are only sent to peers for PS and should be pre-addressed */
- if (ieee80211_is_qos_nullfunc(hdr->frame_control))
- return 0;
-
-- rcu_read_lock();
-- err = mesh_nexthop_lookup(sdata, skb);
-- if (!err)
-- goto endlookup;
-+ if (!mesh_nexthop_lookup(sdata, skb))
-+ return 0;
-
- /* no nexthop found, start resolving */
- mpath = mesh_path_lookup(sdata, target_addr);
-@@ -1129,8 +1126,7 @@ int mesh_nexthop_resolve(struct ieee8021
- mpath = mesh_path_add(sdata, target_addr);
- if (IS_ERR(mpath)) {
- mesh_path_discard_frame(sdata, skb);
-- err = PTR_ERR(mpath);
-- goto endlookup;
-+ return PTR_ERR(mpath);
- }
- }
-
-@@ -1143,13 +1139,10 @@ int mesh_nexthop_resolve(struct ieee8021
- info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
- ieee80211_set_qos_hdr(sdata, skb);
- skb_queue_tail(&mpath->frame_queue, skb);
-- err = -ENOENT;
- if (skb_to_free)
- mesh_path_discard_frame(sdata, skb_to_free);
-
--endlookup:
-- rcu_read_unlock();
-- return err;
-+ return -ENOENT;
- }
-
- /**
-@@ -1169,13 +1162,10 @@ int mesh_nexthop_lookup(struct ieee80211
- struct sta_info *next_hop;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *target_addr = hdr->addr3;
-- int err = -ENOENT;
-
-- rcu_read_lock();
- mpath = mesh_path_lookup(sdata, target_addr);
--
- if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE))
-- goto endlookup;
-+ return -ENOENT;
-
- if (time_after(jiffies,
- mpath->exp_time -
-@@ -1190,12 +1180,10 @@ int mesh_nexthop_lookup(struct ieee80211
- memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
- memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
- ieee80211_mps_set_frame_flags(sdata, next_hop, hdr);
-- err = 0;
-+ return 0;
- }
-
--endlookup:
-- rcu_read_unlock();
-- return err;
-+ return -ENOENT;
- }
-
- void mesh_path_timer(struct timer_list *t)
---- a/net/mac80211/mesh_pathtbl.c
-+++ b/net/mac80211/mesh_pathtbl.c
-@@ -219,7 +219,7 @@ static struct mesh_path *mpath_lookup(st
- {
- struct mesh_path *mpath;
-
-- mpath = rhashtable_lookup_fast(&tbl->rhead, dst, mesh_rht_params);
-+ mpath = rhashtable_lookup(&tbl->rhead, dst, mesh_rht_params);
-
- if (mpath && mpath_expired(mpath)) {
- spin_lock_bh(&mpath->state_lock);
diff --git a/package/kernel/mac80211/patches/subsys/354-mac80211-calculate-hash-for-fq-without-holding-fq-lo.patch b/package/kernel/mac80211/patches/subsys/354-mac80211-calculate-hash-for-fq-without-holding-fq-lo.patch
deleted file mode 100644
index 2b6d8ab525..0000000000
--- a/package/kernel/mac80211/patches/subsys/354-mac80211-calculate-hash-for-fq-without-holding-fq-lo.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 16 Mar 2019 17:57:38 +0100
-Subject: [PATCH] mac80211: calculate hash for fq without holding fq->lock
- in itxq enqueue
-
-Reduces lock contention on enqueue/dequeue of iTXQ packets
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/fq_impl.h
-+++ b/include/net/fq_impl.h
-@@ -107,21 +107,23 @@ begin:
- return skb;
- }
-
-+static u32 fq_flow_idx(struct fq *fq, struct sk_buff *skb)
-+{
-+ u32 hash = skb_get_hash_perturb(skb, fq->perturbation);
-+
-+ return reciprocal_scale(hash, fq->flows_cnt);
-+}
-+
- static struct fq_flow *fq_flow_classify(struct fq *fq,
-- struct fq_tin *tin,
-+ struct fq_tin *tin, u32 idx,
- struct sk_buff *skb,
- fq_flow_get_default_t get_default_func)
- {
- struct fq_flow *flow;
-- u32 hash;
-- u32 idx;
-
- lockdep_assert_held(&fq->lock);
-
-- hash = skb_get_hash_perturb(skb, fq->perturbation);
-- idx = reciprocal_scale(hash, fq->flows_cnt);
- flow = &fq->flows[idx];
--
- if (flow->tin && flow->tin != tin) {
- flow = get_default_func(fq, tin, idx, skb);
- tin->collisions++;
-@@ -153,7 +155,7 @@ static void fq_recalc_backlog(struct fq
- }
-
- static void fq_tin_enqueue(struct fq *fq,
-- struct fq_tin *tin,
-+ struct fq_tin *tin, u32 idx,
- struct sk_buff *skb,
- fq_skb_free_t free_func,
- fq_flow_get_default_t get_default_func)
-@@ -163,7 +165,7 @@ static void fq_tin_enqueue(struct fq *fq
-
- lockdep_assert_held(&fq->lock);
-
-- flow = fq_flow_classify(fq, tin, skb, get_default_func);
-+ flow = fq_flow_classify(fq, tin, idx, skb, get_default_func);
-
- flow->tin = tin;
- flow->backlog += skb->len;
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1390,11 +1390,15 @@ static void ieee80211_txq_enqueue(struct
- {
- struct fq *fq = &local->fq;
- struct fq_tin *tin = &txqi->tin;
-+ u32 flow_idx = fq_flow_idx(fq, skb);
-
- ieee80211_set_skb_enqueue_time(skb);
-- fq_tin_enqueue(fq, tin, skb,
-+
-+ spin_lock_bh(&fq->lock);
-+ fq_tin_enqueue(fq, tin, flow_idx, skb,
- fq_skb_free_func,
- fq_flow_get_default_func);
-+ spin_unlock_bh(&fq->lock);
- }
-
- static bool fq_vlan_filter_func(struct fq *fq, struct fq_tin *tin,
-@@ -1564,7 +1568,6 @@ static bool ieee80211_queue_skb(struct i
- struct sta_info *sta,
- struct sk_buff *skb)
- {
-- struct fq *fq = &local->fq;
- struct ieee80211_vif *vif;
- struct txq_info *txqi;
-
-@@ -1582,9 +1585,7 @@ static bool ieee80211_queue_skb(struct i
- if (!txqi)
- return false;
-
-- spin_lock_bh(&fq->lock);
- ieee80211_txq_enqueue(local, txqi, skb);
-- spin_unlock_bh(&fq->lock);
-
- schedule_and_wake_txq(local, txqi);
-
-@@ -3198,6 +3199,7 @@ static bool ieee80211_amsdu_aggregate(st
- u8 max_subframes = sta->sta.max_amsdu_subframes;
- int max_frags = local->hw.max_tx_fragments;
- int max_amsdu_len = sta->sta.max_amsdu_len;
-+ u32 flow_idx;
- int orig_truesize;
- __be16 len;
- void *data;
-@@ -3220,6 +3222,8 @@ static bool ieee80211_amsdu_aggregate(st
- max_amsdu_len = min_t(int, max_amsdu_len,
- sta->sta.max_rc_amsdu_len);
-
-+ flow_idx = fq_flow_idx(fq, skb);
-+
- spin_lock_bh(&fq->lock);
-
- /* TODO: Ideally aggregation should be done on dequeue to remain
-@@ -3227,7 +3231,8 @@ static bool ieee80211_amsdu_aggregate(st
- */
-
- tin = &txqi->tin;
-- flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func);
-+ flow = fq_flow_classify(fq, tin, flow_idx, skb,
-+ fq_flow_get_default_func);
- head = skb_peek_tail(&flow->queue);
- if (!head)
- goto unlock;
diff --git a/package/kernel/mac80211/patches/subsys/355-mac80211-run-late-dequeue-late-tx-handlers-without-h.patch b/package/kernel/mac80211/patches/subsys/355-mac80211-run-late-dequeue-late-tx-handlers-without-h.patch
deleted file mode 100644
index 3127c86822..0000000000
--- a/package/kernel/mac80211/patches/subsys/355-mac80211-run-late-dequeue-late-tx-handlers-without-h.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 16 Mar 2019 18:00:12 +0100
-Subject: [PATCH] mac80211: run late dequeue late tx handlers without
- holding fq->lock
-
-Reduces lock contention on enqueue/dequeue of iTXQ packets
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3507,6 +3507,7 @@ struct sk_buff *ieee80211_tx_dequeue(str
- ieee80211_tx_result r;
- struct ieee80211_vif *vif = txq->vif;
-
-+begin:
- spin_lock_bh(&fq->lock);
-
- if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ||
-@@ -3523,11 +3524,12 @@ struct sk_buff *ieee80211_tx_dequeue(str
- if (skb)
- goto out;
-
--begin:
- skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func);
- if (!skb)
- goto out;
-
-+ spin_unlock_bh(&fq->lock);
-+
- hdr = (struct ieee80211_hdr *)skb->data;
- info = IEEE80211_SKB_CB(skb);
-
-@@ -3573,8 +3575,11 @@ begin:
-
- skb = __skb_dequeue(&tx.skbs);
-
-- if (!skb_queue_empty(&tx.skbs))
-+ if (!skb_queue_empty(&tx.skbs)) {
-+ spin_lock_bh(&fq->lock);
- skb_queue_splice_tail(&tx.skbs, &txqi->frags);
-+ spin_unlock_bh(&fq->lock);
-+ }
- }
-
- if (skb && skb_has_frag_list(skb) &&
-@@ -3613,6 +3618,7 @@ begin:
- }
-
- IEEE80211_SKB_CB(skb)->control.vif = vif;
-+ return skb;
-
- out:
- spin_unlock_bh(&fq->lock);
diff --git a/package/kernel/mac80211/patches/subsys/356-mac80211-set-NETIF_F_LLTX-when-using-intermediate-tx.patch b/package/kernel/mac80211/patches/subsys/356-mac80211-set-NETIF_F_LLTX-when-using-intermediate-tx.patch
deleted file mode 100644
index 95ab3ab9fb..0000000000
--- a/package/kernel/mac80211/patches/subsys/356-mac80211-set-NETIF_F_LLTX-when-using-intermediate-tx.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 16 Mar 2019 18:01:53 +0100
-Subject: [PATCH] mac80211: set NETIF_F_LLTX when using intermediate tx
- queues
-
-When using iTXQ, tx sequence number allocation and statistics are run at
-dequeue time. Because of that, it is safe to enable NETIF_F_LLTX, which
-allows tx handlers to run on multiple CPUs in parallel.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -1301,6 +1301,7 @@ static void ieee80211_if_setup(struct ne
- static void ieee80211_if_setup_no_queue(struct net_device *dev)
- {
- ieee80211_if_setup(dev);
-+ dev->features |= NETIF_F_LLTX;
- #if LINUX_VERSION_IS_GEQ(4,3,0)
- dev->priv_flags |= IFF_NO_QUEUE;
- #else
diff --git a/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch b/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch
index 82ed1723c0..6ed2884d5e 100644
--- a/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch
+++ b/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch
@@ -24,10 +24,10 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1761,6 +1761,9 @@ void ieee80211_clear_fast_xmit(struct st
- int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
- const u8 *buf, size_t len,
+@@ -1780,6 +1780,9 @@ int ieee80211_tx_control_port(struct wip
const u8 *dest, __be16 proto, bool unencrypted);
+ int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *buf, size_t len);
+int ieee80211_skb_resize(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, int hdrlen, int hdr_add);
@@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
-@@ -672,6 +672,11 @@ void ieee80211_tx_monitor(struct ieee802
+@@ -669,6 +669,11 @@ void ieee80211_tx_monitor(struct ieee802
}
}
@@ -50,7 +50,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -1914,37 +1914,53 @@ static bool ieee80211_tx(struct ieee8021
+@@ -1935,37 +1935,53 @@ static bool ieee80211_tx(struct ieee8021
}
/* device xmit handlers */
@@ -123,7 +123,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
wiphy_debug(local->hw.wiphy,
"failed to reallocate TX buffer\n");
return -ENOMEM;
-@@ -1960,18 +1976,8 @@ void ieee80211_xmit(struct ieee80211_sub
+@@ -1981,18 +1997,8 @@ void ieee80211_xmit(struct ieee80211_sub
struct ieee80211_local *local = sdata->local;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr;
@@ -143,7 +143,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
ieee80211_free_txskb(&local->hw, skb);
return;
}
-@@ -2740,30 +2746,14 @@ static struct sk_buff *ieee80211_build_h
+@@ -2774,30 +2780,14 @@ static struct sk_buff *ieee80211_build_h
skb_pull(skb, skip_header_bytes);
padsize = ieee80211_hdr_padsize(&local->hw, hdrlen);
@@ -180,7 +180,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
if (encaps_data)
-@@ -3377,7 +3367,6 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3417,7 +3407,6 @@ static bool ieee80211_xmit_fast(struct i
struct ieee80211_local *local = sdata->local;
u16 ethertype = (skb->data[12] << 8) | skb->data[13];
int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
@@ -188,7 +188,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct ethhdr eth;
struct ieee80211_tx_info *info;
struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
-@@ -3429,10 +3418,7 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3469,10 +3458,7 @@ static bool ieee80211_xmit_fast(struct i
* as the may-encrypt argument for the resize to not account for
* more room than we already have in 'extra_head'
*/
diff --git a/package/kernel/mac80211/patches/subsys/358-mac80211-make-ieee80211_schedule_txq-schedule-empty-.patch b/package/kernel/mac80211/patches/subsys/358-mac80211-make-ieee80211_schedule_txq-schedule-empty-.patch
deleted file mode 100644
index a0a65f35a8..0000000000
--- a/package/kernel/mac80211/patches/subsys/358-mac80211-make-ieee80211_schedule_txq-schedule-empty-.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 17 Mar 2019 14:26:59 +0100
-Subject: [PATCH] mac80211: make ieee80211_schedule_txq schedule empty TXQs
-
-Currently there is no way for the driver to signal to mac80211 that it should
-schedule a TXQ even if there are no packets on the mac80211 part of that queue.
-This is problematic if the driver has an internal retry queue to deal with
-software A-MPDU retry.
-
-This patch changes the behavior of ieee80211_schedule_txq to always schedule
-the queue, as its only user (ath9k) seems to expect such behavior already:
-it calls this function on tx status and on powersave wakeup whenever its
-internal retry queue is not empty.
-
-Also add an extra argument to ieee80211_return_txq to get the same behavior.
-
-This fixes an issue on ath9k where tx queues with packets to retry (and no
-new packets in mac80211) would not get serviced.
-
-Fixes: 89cea7493a346 ("ath9k: Switch to mac80211 TXQ scheduling and airtime APIs")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -6090,26 +6090,42 @@ 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
- *
- * @hw: pointer as obtained from ieee80211_alloc_hw()
- * @txq: pointer obtained from station or virtual interface
- *
-- * Schedules a TXQ for transmission if it is not already scheduled.
-+ * Schedules a TXQ for transmission if it is not already scheduled,
-+ * even if mac80211 does not have any packets buffered.
-+ *
-+ * The driver may call this function if it has buffered packets for
-+ * this TXQ internally.
- */
--void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
-+static inline void
-+ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
-+{
-+ __ieee80211_schedule_txq(hw, txq, true);
-+}
-
- /**
- * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
- *
- * @hw: pointer as obtained from ieee80211_alloc_hw()
- * @txq: pointer obtained from station or virtual interface
-+ * @force: schedule txq even if mac80211 does not have any buffered packets.
-+ *
-+ * 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)
-+ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
-+ bool force)
- {
-- ieee80211_schedule_txq(hw, txq);
-+ __ieee80211_schedule_txq(hw, txq, force);
- }
-
- /**
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3655,8 +3655,9 @@ out:
- }
- EXPORT_SYMBOL(ieee80211_next_txq);
-
--void ieee80211_schedule_txq(struct ieee80211_hw *hw,
-- struct ieee80211_txq *txq)
-+void __ieee80211_schedule_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);
-@@ -3664,7 +3665,8 @@ void ieee80211_schedule_txq(struct ieee8
- spin_lock_bh(&local->active_txq_lock[txq->ac]);
-
- if (list_empty(&txqi->schedule_order) &&
-- (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
-+ (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
-@@ -3684,7 +3686,7 @@ void ieee80211_schedule_txq(struct ieee8
-
- spin_unlock_bh(&local->active_txq_lock[txq->ac]);
- }
--EXPORT_SYMBOL(ieee80211_schedule_txq);
-+EXPORT_SYMBOL(__ieee80211_schedule_txq);
-
- bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
- struct ieee80211_txq *txq)
diff --git a/package/kernel/mac80211/patches/subsys/359-mac80211-un-schedule-TXQs-on-powersave-start.patch b/package/kernel/mac80211/patches/subsys/359-mac80211-un-schedule-TXQs-on-powersave-start.patch
deleted file mode 100644
index 1abb2db7c2..0000000000
--- a/package/kernel/mac80211/patches/subsys/359-mac80211-un-schedule-TXQs-on-powersave-start.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 19 Mar 2019 11:36:12 +0100
-Subject: [PATCH] mac80211: un-schedule TXQs on powersave start
-
-Once a station enters powersave, its queues should not be returned by
-ieee80211_next_txq() anymore. They will be re-scheduled again after the
-station has woken up again
-
-Fixes: 1866760096bf4 ("mac80211: Add TXQ scheduling API")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1508,7 +1508,15 @@ static void sta_ps_start(struct sta_info
- return;
-
- for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
-- if (txq_has_queue(sta->sta.txq[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]);
-+
-+ if (txq_has_queue(txq))
- set_bit(tid, &sta->txq_buffered_tids);
- else
- clear_bit(tid, &sta->txq_buffered_tids);
diff --git a/package/kernel/mac80211/patches/subsys/360-mac80211-when-using-iTXQ-select-the-queue-in-ieee802.patch b/package/kernel/mac80211/patches/subsys/360-mac80211-when-using-iTXQ-select-the-queue-in-ieee802.patch
deleted file mode 100644
index bb3af7317a..0000000000
--- a/package/kernel/mac80211/patches/subsys/360-mac80211-when-using-iTXQ-select-the-queue-in-ieee802.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 22 Mar 2019 18:06:03 +0100
-Subject: [PATCH] mac80211: when using iTXQ, select the queue in
- ieee80211_subif_start_xmit
-
-When using iTXQ, the network stack does not need the real queue number, since
-mac80211 is using its internal queues anyway. In that case we can defer
-selecting the queue and remove a redundant station lookup in the tx path to save
-some CPU cycles.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3753,6 +3753,7 @@ void __ieee80211_subif_start_xmit(struct
- u32 info_flags)
- {
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+ struct ieee80211_local *local = sdata->local;
- struct sta_info *sta;
- struct sk_buff *next;
-
-@@ -3766,7 +3767,15 @@ void __ieee80211_subif_start_xmit(struct
- if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
- goto out_free;
-
-- if (!IS_ERR_OR_NULL(sta)) {
-+ if (IS_ERR(sta))
-+ sta = NULL;
-+
-+ if (local->ops->wake_tx_queue) {
-+ u16 queue = __ieee80211_select_queue(sdata, sta, skb);
-+ skb_set_queue_mapping(skb, queue);
-+ }
-+
-+ if (sta) {
- struct ieee80211_fast_tx *fast_tx;
-
- /* We need a bit of data queued to build aggregates properly, so
---- a/net/mac80211/wme.c
-+++ b/net/mac80211/wme.c
-@@ -141,6 +141,42 @@ u16 ieee80211_select_queue_80211(struct
- return ieee80211_downgrade_queue(sdata, NULL, skb);
- }
-
-+u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
-+ struct sta_info *sta, struct sk_buff *skb)
-+{
-+ struct mac80211_qos_map *qos_map;
-+ bool qos;
-+
-+ /* all mesh/ocb stations are required to support WME */
-+ if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
-+ sdata->vif.type == NL80211_IFTYPE_OCB)
-+ qos = true;
-+ else if (sta)
-+ qos = sta->sta.wme;
-+ else
-+ qos = false;
-+
-+ if (!qos) {
-+ skb->priority = 0; /* required for correct WPA/11i MIC */
-+ return IEEE80211_AC_BE;
-+ }
-+
-+ if (skb->protocol == sdata->control_port_protocol) {
-+ skb->priority = 7;
-+ goto downgrade;
-+ }
-+
-+ /* use the data classifier to determine what 802.1d tag the
-+ * data frame has */
-+ qos_map = rcu_dereference(sdata->qos_map);
-+ skb->priority = cfg80211_classify8021d(skb, qos_map ?
-+ &qos_map->qos_map : NULL);
-+
-+ downgrade:
-+ return ieee80211_downgrade_queue(sdata, sta, skb);
-+}
-+
-+
- /* Indicate which queue to use. */
- u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb)
-@@ -148,10 +184,12 @@ u16 ieee80211_select_queue(struct ieee80
- struct ieee80211_local *local = sdata->local;
- struct sta_info *sta = NULL;
- const u8 *ra = NULL;
-- bool qos = false;
-- struct mac80211_qos_map *qos_map;
- u16 ret;
-
-+ /* when using iTXQ, we can do this later */
-+ if (local->ops->wake_tx_queue)
-+ return 0;
-+
- if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
- skb->priority = 0; /* required for correct WPA/11i MIC */
- return 0;
-@@ -161,10 +199,8 @@ u16 ieee80211_select_queue(struct ieee80
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_AP_VLAN:
- sta = rcu_dereference(sdata->u.vlan.sta);
-- if (sta) {
-- qos = sta->sta.wme;
-+ if (sta)
- break;
-- }
- /* fall through */
- case NL80211_IFTYPE_AP:
- ra = skb->data;
-@@ -172,56 +208,26 @@ u16 ieee80211_select_queue(struct ieee80
- case NL80211_IFTYPE_WDS:
- ra = sdata->u.wds.remote_addr;
- break;
--#ifdef CPTCFG_MAC80211_MESH
-- case NL80211_IFTYPE_MESH_POINT:
-- qos = true;
-- break;
--#endif
- case NL80211_IFTYPE_STATION:
- /* might be a TDLS station */
- sta = sta_info_get(sdata, skb->data);
- if (sta)
-- qos = sta->sta.wme;
-+ break;
-
- ra = sdata->u.mgd.bssid;
- break;
- case NL80211_IFTYPE_ADHOC:
- ra = skb->data;
- break;
-- case NL80211_IFTYPE_OCB:
-- /* all stations are required to support WME */
-- qos = true;
-- break;
- default:
- break;
- }
-
-- if (!sta && ra && !is_multicast_ether_addr(ra)) {
-+ if (!sta && ra && !is_multicast_ether_addr(ra))
- sta = sta_info_get(sdata, ra);
-- if (sta)
-- qos = sta->sta.wme;
-- }
-
-- if (!qos) {
-- skb->priority = 0; /* required for correct WPA/11i MIC */
-- ret = IEEE80211_AC_BE;
-- goto out;
-- }
-+ ret = __ieee80211_select_queue(sdata, sta, skb);
-
-- if (skb->protocol == sdata->control_port_protocol) {
-- skb->priority = 7;
-- goto downgrade;
-- }
--
-- /* use the data classifier to determine what 802.1d tag the
-- * data frame has */
-- qos_map = rcu_dereference(sdata->qos_map);
-- skb->priority = cfg80211_classify8021d(skb, qos_map ?
-- &qos_map->qos_map : NULL);
--
-- downgrade:
-- ret = ieee80211_downgrade_queue(sdata, sta, skb);
-- out:
- rcu_read_unlock();
- return ret;
- }
---- a/net/mac80211/wme.h
-+++ b/net/mac80211/wme.h
-@@ -16,6 +16,8 @@
- u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb,
- struct ieee80211_hdr *hdr);
-+u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
-+ struct sta_info *sta, struct sk_buff *skb);
- u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb);
- void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
diff --git a/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-add-support-for-rates-with-4-sp.patch b/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-add-support-for-rates-with-4-sp.patch
deleted file mode 100644
index 07b30dfbf7..0000000000
--- a/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-add-support-for-rates-with-4-sp.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 25 Mar 2019 09:02:13 +0100
-Subject: [PATCH] mac80211: minstrel_ht: add support for rates with 4
- spatial streams
-
-This is needed for the upcoming driver for MT7615 4x4 802.11ac chipsets
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -157,44 +157,54 @@ const struct mcs_group minstrel_mcs_grou
- MCS_GROUP(1, 0, BW_20, 5),
- MCS_GROUP(2, 0, BW_20, 4),
- MCS_GROUP(3, 0, BW_20, 4),
-+ MCS_GROUP(4, 0, BW_20, 4),
-
- MCS_GROUP(1, 1, BW_20, 5),
- MCS_GROUP(2, 1, BW_20, 4),
- MCS_GROUP(3, 1, BW_20, 4),
-+ MCS_GROUP(4, 1, BW_20, 4),
-
- MCS_GROUP(1, 0, BW_40, 4),
- MCS_GROUP(2, 0, BW_40, 4),
- MCS_GROUP(3, 0, BW_40, 4),
-+ MCS_GROUP(4, 0, BW_40, 4),
-
- MCS_GROUP(1, 1, BW_40, 4),
- MCS_GROUP(2, 1, BW_40, 4),
- MCS_GROUP(3, 1, BW_40, 4),
-+ MCS_GROUP(4, 1, BW_40, 4),
-
- CCK_GROUP(8),
-
- VHT_GROUP(1, 0, BW_20, 5),
- VHT_GROUP(2, 0, BW_20, 4),
- VHT_GROUP(3, 0, BW_20, 4),
-+ VHT_GROUP(4, 0, BW_20, 4),
-
- VHT_GROUP(1, 1, BW_20, 5),
- VHT_GROUP(2, 1, BW_20, 4),
- VHT_GROUP(3, 1, BW_20, 4),
-+ VHT_GROUP(4, 1, BW_20, 4),
-
- VHT_GROUP(1, 0, BW_40, 4),
- VHT_GROUP(2, 0, BW_40, 4),
- VHT_GROUP(3, 0, BW_40, 4),
-+ VHT_GROUP(4, 0, BW_40, 3),
-
- VHT_GROUP(1, 1, BW_40, 4),
- VHT_GROUP(2, 1, BW_40, 4),
- VHT_GROUP(3, 1, BW_40, 4),
-+ VHT_GROUP(4, 1, BW_40, 3),
-
- VHT_GROUP(1, 0, BW_80, 4),
- VHT_GROUP(2, 0, BW_80, 4),
- VHT_GROUP(3, 0, BW_80, 4),
-+ VHT_GROUP(4, 0, BW_80, 2),
-
- VHT_GROUP(1, 1, BW_80, 4),
- VHT_GROUP(2, 1, BW_80, 4),
- VHT_GROUP(3, 1, BW_80, 4),
-+ VHT_GROUP(4, 1, BW_80, 2),
- };
-
- static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
---- a/net/mac80211/rc80211_minstrel_ht.h
-+++ b/net/mac80211/rc80211_minstrel_ht.h
-@@ -13,7 +13,7 @@
- * The number of streams can be changed to 2 to reduce code
- * size and memory footprint.
- */
--#define MINSTREL_MAX_STREAMS 3
-+#define MINSTREL_MAX_STREAMS 4
- #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */
- #define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */
-
diff --git a/package/kernel/mac80211/patches/subsys/362-mac80211-minstrel_ht-automatically-calculate-rate-du.patch b/package/kernel/mac80211/patches/subsys/362-mac80211-minstrel_ht-automatically-calculate-rate-du.patch
deleted file mode 100644
index 81d14966f7..0000000000
--- a/package/kernel/mac80211/patches/subsys/362-mac80211-minstrel_ht-automatically-calculate-rate-du.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 25 Mar 2019 09:02:52 +0100
-Subject: [PATCH] mac80211: minstrel_ht: automatically calculate rate
- duration shift
-
-A per-group shift was added to reduce the size of the per-rate transmit
-duration field to u16 without sacrificing a lot of precision
-This patch changes the macros to automatically calculate the best value for
-this shift based on the lowest rate within the group.
-This simplifies adding more groups and slightly improves accuracy for some of
-the existing groups.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -51,8 +51,11 @@
- MINSTREL_MAX_STREAMS * _sgi + \
- _streams - 1
-
-+#define GROUP_SHIFT(duration) \
-+ (16 - __builtin_clz(duration))
-+
- /* MCS rate information for an MCS group */
--#define MCS_GROUP(_streams, _sgi, _ht40, _s) \
-+#define __MCS_GROUP(_streams, _sgi, _ht40, _s) \
- [GROUP_IDX(_streams, _sgi, _ht40)] = { \
- .streams = _streams, \
- .shift = _s, \
-@@ -72,6 +75,13 @@
- } \
- }
-
-+#define MCS_GROUP_SHIFT(_streams, _sgi, _ht40) \
-+ GROUP_SHIFT(MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26))
-+
-+#define MCS_GROUP(_streams, _sgi, _ht40) \
-+ __MCS_GROUP(_streams, _sgi, _ht40, \
-+ MCS_GROUP_SHIFT(_streams, _sgi, _ht40))
-+
- #define VHT_GROUP_IDX(_streams, _sgi, _bw) \
- (MINSTREL_VHT_GROUP_0 + \
- MINSTREL_MAX_STREAMS * 2 * (_bw) + \
-@@ -81,7 +91,7 @@
- #define BW2VBPS(_bw, r3, r2, r1) \
- (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
-
--#define VHT_GROUP(_streams, _sgi, _bw, _s) \
-+#define __VHT_GROUP(_streams, _sgi, _bw, _s) \
- [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \
- .streams = _streams, \
- .shift = _s, \
-@@ -114,6 +124,14 @@
- } \
- }
-
-+#define VHT_GROUP_SHIFT(_streams, _sgi, _bw) \
-+ GROUP_SHIFT(MCS_DURATION(_streams, _sgi, \
-+ BW2VBPS(_bw, 117, 54, 26)))
-+
-+#define VHT_GROUP(_streams, _sgi, _bw) \
-+ __VHT_GROUP(_streams, _sgi, _bw, \
-+ VHT_GROUP_SHIFT(_streams, _sgi, _bw))
-+
- #define CCK_DURATION(_bitrate, _short, _len) \
- (1000 * (10 /* SIFS */ + \
- (_short ? 72 + 24 : 144 + 48) + \
-@@ -129,7 +147,7 @@
- CCK_ACK_DURATION(55, _short) >> _s, \
- CCK_ACK_DURATION(110, _short) >> _s
-
--#define CCK_GROUP(_s) \
-+#define __CCK_GROUP(_s) \
- [MINSTREL_CCK_GROUP] = { \
- .streams = 1, \
- .flags = 0, \
-@@ -140,6 +158,12 @@
- } \
- }
-
-+#define CCK_GROUP_SHIFT \
-+ GROUP_SHIFT(CCK_ACK_DURATION(10, false))
-+
-+#define CCK_GROUP __CCK_GROUP(CCK_GROUP_SHIFT)
-+
-+
- static bool minstrel_vht_only = true;
- module_param(minstrel_vht_only, bool, 0644);
- MODULE_PARM_DESC(minstrel_vht_only,
-@@ -154,57 +178,57 @@ MODULE_PARM_DESC(minstrel_vht_only,
- * BW -> SGI -> #streams
- */
- const struct mcs_group minstrel_mcs_groups[] = {
-- MCS_GROUP(1, 0, BW_20, 5),
-- MCS_GROUP(2, 0, BW_20, 4),
-- MCS_GROUP(3, 0, BW_20, 4),
-- MCS_GROUP(4, 0, BW_20, 4),
-+ MCS_GROUP(1, 0, BW_20),
-+ MCS_GROUP(2, 0, BW_20),
-+ MCS_GROUP(3, 0, BW_20),
-+ MCS_GROUP(4, 0, BW_20),
-
-- MCS_GROUP(1, 1, BW_20, 5),
-- MCS_GROUP(2, 1, BW_20, 4),
-- MCS_GROUP(3, 1, BW_20, 4),
-- MCS_GROUP(4, 1, BW_20, 4),
-+ MCS_GROUP(1, 1, BW_20),
-+ MCS_GROUP(2, 1, BW_20),
-+ MCS_GROUP(3, 1, BW_20),
-+ MCS_GROUP(4, 1, BW_20),
-
-- MCS_GROUP(1, 0, BW_40, 4),
-- MCS_GROUP(2, 0, BW_40, 4),
-- MCS_GROUP(3, 0, BW_40, 4),
-- MCS_GROUP(4, 0, BW_40, 4),
-+ MCS_GROUP(1, 0, BW_40),
-+ MCS_GROUP(2, 0, BW_40),
-+ MCS_GROUP(3, 0, BW_40),
-+ MCS_GROUP(4, 0, BW_40),
-
-- MCS_GROUP(1, 1, BW_40, 4),
-- MCS_GROUP(2, 1, BW_40, 4),
-- MCS_GROUP(3, 1, BW_40, 4),
-- MCS_GROUP(4, 1, BW_40, 4),
-+ MCS_GROUP(1, 1, BW_40),
-+ MCS_GROUP(2, 1, BW_40),
-+ MCS_GROUP(3, 1, BW_40),
-+ MCS_GROUP(4, 1, BW_40),
-
-- CCK_GROUP(8),
-+ CCK_GROUP,
-
-- VHT_GROUP(1, 0, BW_20, 5),
-- VHT_GROUP(2, 0, BW_20, 4),
-- VHT_GROUP(3, 0, BW_20, 4),
-- VHT_GROUP(4, 0, BW_20, 4),
-+ VHT_GROUP(1, 0, BW_20),
-+ VHT_GROUP(2, 0, BW_20),
-+ VHT_GROUP(3, 0, BW_20),
-+ VHT_GROUP(4, 0, BW_20),
-
-- VHT_GROUP(1, 1, BW_20, 5),
-- VHT_GROUP(2, 1, BW_20, 4),
-- VHT_GROUP(3, 1, BW_20, 4),
-- VHT_GROUP(4, 1, BW_20, 4),
-+ VHT_GROUP(1, 1, BW_20),
-+ VHT_GROUP(2, 1, BW_20),
-+ VHT_GROUP(3, 1, BW_20),
-+ VHT_GROUP(4, 1, BW_20),
-
-- VHT_GROUP(1, 0, BW_40, 4),
-- VHT_GROUP(2, 0, BW_40, 4),
-- VHT_GROUP(3, 0, BW_40, 4),
-- VHT_GROUP(4, 0, BW_40, 3),
-+ VHT_GROUP(1, 0, BW_40),
-+ VHT_GROUP(2, 0, BW_40),
-+ VHT_GROUP(3, 0, BW_40),
-+ VHT_GROUP(4, 0, BW_40),
-
-- VHT_GROUP(1, 1, BW_40, 4),
-- VHT_GROUP(2, 1, BW_40, 4),
-- VHT_GROUP(3, 1, BW_40, 4),
-- VHT_GROUP(4, 1, BW_40, 3),
-+ VHT_GROUP(1, 1, BW_40),
-+ VHT_GROUP(2, 1, BW_40),
-+ VHT_GROUP(3, 1, BW_40),
-+ VHT_GROUP(4, 1, BW_40),
-
-- VHT_GROUP(1, 0, BW_80, 4),
-- VHT_GROUP(2, 0, BW_80, 4),
-- VHT_GROUP(3, 0, BW_80, 4),
-- VHT_GROUP(4, 0, BW_80, 2),
-+ VHT_GROUP(1, 0, BW_80),
-+ VHT_GROUP(2, 0, BW_80),
-+ VHT_GROUP(3, 0, BW_80),
-+ VHT_GROUP(4, 0, BW_80),
-
-- VHT_GROUP(1, 1, BW_80, 4),
-- VHT_GROUP(2, 1, BW_80, 4),
-- VHT_GROUP(3, 1, BW_80, 4),
-- VHT_GROUP(4, 1, BW_80, 2),
-+ VHT_GROUP(1, 1, BW_80),
-+ VHT_GROUP(2, 1, BW_80),
-+ VHT_GROUP(3, 1, BW_80),
-+ VHT_GROUP(4, 1, BW_80),
- };
-
- static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
diff --git a/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch b/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch
deleted file mode 100644
index d5b08b4410..0000000000
--- a/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 33d915d9e8ce811d8958915ccd18d71a66c7c495 Mon Sep 17 00:00:00 2001
-From: Manikanta Pubbisetty <mpubbise@codeaurora.org>
-Date: Wed, 8 May 2019 14:55:33 +0530
-Subject: [PATCH] {nl,mac}80211: allow 4addr AP operation on crypto controlled
- devices
-
-As per the current design, in the case of sw crypto controlled devices,
-it is the device which advertises the support for AP/VLAN iftype based
-on it's ability to tranmsit packets encrypted in software
-(In VLAN functionality, group traffic generated for a specific
-VLAN group is always encrypted in software). Commit db3bdcb9c3ff
-("mac80211: allow AP_VLAN operation on crypto controlled devices")
-has introduced this change.
-
-Since 4addr AP operation also uses AP/VLAN iftype, this conditional
-way of advertising AP/VLAN support has broken 4addr AP mode operation on
-crypto controlled devices which do not support VLAN functionality.
-
-In the case of ath10k driver, not all firmwares have support for VLAN
-functionality but all can support 4addr AP operation. Because AP/VLAN
-support is not advertised for these devices, 4addr AP operations are
-also blocked.
-
-Fix this by allowing 4addr operation on devices which do not support
-AP/VLAN iftype but can support 4addr AP operation (decision is based on
-the wiphy flag WIPHY_FLAG_4ADDR_AP).
-
-Cc: stable@vger.kernel.org
-Fixes: db3bdcb9c3ff ("mac80211: allow AP_VLAN operation on crypto controlled devices")
-Signed-off-by: Manikanta Pubbisetty <mpubbise@codeaurora.org>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/cfg80211.h | 3 ++-
- net/mac80211/util.c | 4 +++-
- net/wireless/core.c | 6 +++++-
- net/wireless/nl80211.c | 8 ++++++--
- 4 files changed, 16 insertions(+), 5 deletions(-)
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -3457,7 +3457,8 @@ struct cfg80211_ops {
- * on wiphy_new(), but can be changed by the driver if it has a good
- * reason to override the default
- * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station
-- * on a VLAN interface)
-+ * on a VLAN interface). This flag also serves an extra purpose of
-+ * supporting 4ADDR AP mode on devices which do not support AP/VLAN iftype.
- * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station
- * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the
- * control port protocol ethertype. The device also honours the
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -3626,7 +3626,9 @@ int ieee80211_check_combinations(struct
- }
-
- /* Always allow software iftypes */
-- if (local->hw.wiphy->software_iftypes & BIT(iftype)) {
-+ if (local->hw.wiphy->software_iftypes & BIT(iftype) ||
-+ (iftype == NL80211_IFTYPE_AP_VLAN &&
-+ local->hw.wiphy->flags & WIPHY_FLAG_4ADDR_AP)) {
- if (radar_detect)
- return -EINVAL;
- return 0;
---- a/net/wireless/core.c
-+++ b/net/wireless/core.c
-@@ -1351,8 +1351,12 @@ static int cfg80211_netdev_notifier_call
- }
- break;
- case NETDEV_PRE_UP:
-- if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
-+ if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)) &&
-+ !(wdev->iftype == NL80211_IFTYPE_AP_VLAN &&
-+ rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP &&
-+ wdev->use_4addr))
- return notifier_from_errno(-EOPNOTSUPP);
-+
- if (rfkill_blocked(rdev->rfkill))
- return notifier_from_errno(-ERFKILL);
- break;
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -3194,8 +3194,7 @@ static int nl80211_new_interface(struct
- return -EINVAL;
- }
-
-- if (!rdev->ops->add_virtual_intf ||
-- !(rdev->wiphy.interface_modes & (1 << type)))
-+ if (!rdev->ops->add_virtual_intf)
- return -EOPNOTSUPP;
-
- if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
-@@ -3214,6 +3213,11 @@ static int nl80211_new_interface(struct
- return err;
- }
-
-+ if (!(rdev->wiphy.interface_modes & (1 << type)) &&
-+ !(type == NL80211_IFTYPE_AP_VLAN && params.use_4addr &&
-+ rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP))
-+ return -EOPNOTSUPP;
-+
- err = nl80211_parse_mon_options(rdev, type, info, &params);
- if (err < 0)
- return err;
diff --git a/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch
index 4dcd7b5fcc..7960039fd7 100644
--- a/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch
+++ b/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch
@@ -1,6 +1,6 @@
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
-@@ -2968,6 +2968,7 @@ struct cfg80211_external_auth_params {
+@@ -3322,6 +3322,7 @@ struct cfg80211_update_owe_info {
* (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 @@
*
* @set_wds_peer: set the WDS peer for a WDS interface
*
-@@ -3268,6 +3269,7 @@ struct cfg80211_ops {
+@@ -3634,6 +3635,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 @@
const u8 *addr);
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -1395,6 +1395,7 @@ enum ieee80211_smps_mode {
+@@ -1471,6 +1471,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
-@@ -1415,6 +1416,7 @@ enum ieee80211_smps_mode {
+@@ -1491,6 +1492,7 @@ enum ieee80211_smps_mode {
struct ieee80211_conf {
u32 flags;
int power_level, dynamic_ps_timeout;
@@ -36,9 +36,9 @@
u8 ps_dtim_period;
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
-@@ -2244,6 +2244,9 @@ enum nl80211_commands {
- * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime
- * scheduler.
+@@ -2341,6 +2341,9 @@ enum nl80211_commands {
+ * should be picking up the lowest tx power, either tx power per-interface
+ * or per-station.
*
+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
+ * transmit power to stay within regulatory limits. u32, dBi.
@@ -46,9 +46,9 @@
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
-@@ -2693,6 +2696,8 @@ enum nl80211_attrs {
-
- NL80211_ATTR_AIRTIME_WEIGHT,
+@@ -2794,6 +2797,8 @@ enum nl80211_attrs {
+ NL80211_ATTR_STA_TX_POWER_SETTING,
+ NL80211_ATTR_STA_TX_POWER,
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
+
@@ -57,7 +57,7 @@
__NL80211_ATTR_AFTER_LAST,
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
-@@ -2505,6 +2505,19 @@ static int ieee80211_get_tx_power(struct
+@@ -2577,6 +2577,19 @@ static int ieee80211_get_tx_power(struct
return 0;
}
@@ -77,7 +77,7 @@
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
const u8 *addr)
{
-@@ -3872,6 +3885,7 @@ const struct cfg80211_ops mac80211_confi
+@@ -3990,6 +4003,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,
@@ -87,7 +87,7 @@
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1365,6 +1365,7 @@ struct ieee80211_local {
+@@ -1373,6 +1373,7 @@ struct ieee80211_local {
int dynamic_ps_forced_timeout;
int user_power_level; /* in dBm, for all interfaces */
@@ -97,7 +97,7 @@
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
-@@ -94,7 +94,7 @@ static u32 ieee80211_hw_conf_chan(struct
+@@ -92,7 +92,7 @@ static u32 ieee80211_hw_conf_chan(struct
struct ieee80211_sub_if_data *sdata;
struct cfg80211_chan_def chandef = {};
u32 changed = 0;
@@ -106,7 +106,7 @@
u32 offchannel_flag;
offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
-@@ -151,6 +151,12 @@ static u32 ieee80211_hw_conf_chan(struct
+@@ -149,6 +149,12 @@ static u32 ieee80211_hw_conf_chan(struct
}
rcu_read_unlock();
@@ -119,7 +119,7 @@
if (local->hw.conf.power_level != power) {
changed |= IEEE80211_CONF_CHANGE_POWER;
local->hw.conf.power_level = power;
-@@ -626,6 +632,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
+@@ -638,6 +644,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
IEEE80211_RADIOTAP_MCS_HAVE_BW;
local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
@@ -129,15 +129,15 @@
local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
-@@ -431,6 +431,7 @@ static const struct nla_policy nl80211_p
- [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
- .len = NL80211_HE_MAX_CAPABILITY_LEN },
+@@ -571,6 +571,7 @@ const struct nla_policy nl80211_policy[N
+ [NL80211_ATTR_PEER_MEASUREMENTS] =
+ NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
[NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
+ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
};
/* policy for the key attributes */
-@@ -2588,6 +2589,20 @@ static int nl80211_set_wiphy(struct sk_b
+@@ -2866,6 +2867,20 @@ static int nl80211_set_wiphy(struct sk_b
if (result)
return result;
}