[openwrt/openwrt] mac80211: Update to version 5.10-rc6-1

LEDE Commits lede-commits at lists.infradead.org
Sun Feb 14 09:54:32 EST 2021


hauke pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/12424edff53590b989761c61aefc4ae36184447e

commit 12424edff53590b989761c61aefc4ae36184447e
Author: Hauke Mehrtens <hauke at hauke-m.de>
AuthorDate: Fri Nov 13 20:14:09 2020 +0100

    mac80211: Update to version 5.10-rc6-1
    
    The removed patches were applied upstream.
    
    This adapts ath10k-ct and mt76 to changed APIs.
    nl80211.h in iw is updated to match the version from backports.
    
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../ath10k-ct/patches/300-mac80211-5.10.patch      |   24 +
 package/kernel/mac80211/Makefile                   |    6 +-
 .../patches/ath/404-regd_no_assoc_hints.patch      |    4 +-
 .../patches/ath/410-ath9k_allow_adhoc_and_ap.patch |    2 +-
 .../patches/ath/440-ath5k_channel_bw_debugfs.patch |    4 +-
 ...9k-enabled-MFP-capability-unconditionally.patch |    4 +-
 .../patches/ath/542-ath9k_debugfs_diag.patch       |    2 +-
 .../patches/ath/543-ath9k_entropy_from_adc.patch   |    8 +-
 .../patches/ath/545-ath9k_ani_ws_detect.patch      |    2 +-
 .../patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch  |    8 +-
 .../patches/ath/553-ath9k_of_gpio_mask.patch       |    2 +-
 .../921-ath10k_init_devices_synchronously.patch    |    2 +-
 .../ath/930-ath10k_add_tpt_led_trigger.patch       |    4 +-
 ...-controlling-support-for-various-chipsets.patch |   38 +-
 .../975-ath10k-use-tpt-trigger-by-default.patch    |    4 +-
 .../ath/980-ath10k-fix-max-antenna-gain-unit.patch |    2 +-
 ...st-tx-power-reduction-for-US-regulatory-d.patch |    2 +-
 .../brcm/810-b43-gpio-mask-module-option.patch     |    2 +-
 .../mac80211/patches/brcm/811-b43_no_pio.patch     |    2 +-
 .../patches/brcm/812-b43-add-antenna-control.patch |   16 +-
 .../brcm/814-b43-only-use-gpio-0-1-for-led.patch   |    2 +-
 ...mfmac-register-wiphy-s-during-module_init.patch |    2 +-
 ...rkaround-bug-with-some-inconsistent-BSSes.patch |    2 +-
 .../862-brcmfmac-Disable-power-management.patch    |    2 +-
 .../kernel/mac80211/patches/brcm/998-survey.patch  |   12 +-
 .../mac80211/patches/build/015-ipw200-mtu.patch    |    4 +-
 .../patches/build/060-no_local_ssb_bcma.patch      |   12 +-
 .../rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch |    6 +-
 .../rt2x00/611-rt2x00-add-AP+STA-support.patch     |    2 +-
 .../612-rt2x00-led-tpt-trigger-support.patch       |    2 +-
 .../subsys/100-remove-cryptoapi-dependencies.patch |    2 +-
 .../subsys/110-mac80211_keep_keys_on_stop_ap.patch |    2 +-
 .../mac80211/patches/subsys/210-ap_scan.patch      |    2 +-
 ...eck-and-refresh-aggregation-session-in-en.patch |   45 -
 ...ip-encap-offload-for-tx-multicast-control.patch |  136 ---
 ...t-info-control.hw_key-for-encap-offload-p.patch |   31 -
 ...80211-rework-tx-encapsulation-offload-API.patch |  613 -----------
 ...reduce-duplication-in-tx-status-functions.patch |  197 ----
 ...move-tx-status-call-to-ieee80211_sta_regi.patch |   26 -
 ...80211-optimize-station-connection-monitor.patch |  174 ---
 ...ap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch |  227 ----
 ...ify-802.3-offload-and-802.11-tx-status-co.patch |  159 ---
 ...pport-using-ieee80211_tx_status_ext-to-fr.patch |   63 --
 ...tend-ieee80211_tx_status_ext-to-support-b.patch |   53 -
 ...tify-the-driver-when-a-sta-uses-4-address.patch |  109 --
 ...organize-code-to-remove-a-forward-declara.patch | 1124 --------------------
 ...low-bigger-A-MSDU-sizes-in-VHT-even-if-HT.patch |   26 -
 ...-fix-regression-in-sta-connection-monitor.patch |   70 --
 ...x-memory-leak-on-filtered-powersave-frame.patch |   55 -
 ...-not-drop-tx-nulldata-packets-on-encrypte.patch |    2 +-
 ...80211-remove-legacy-minstrel-rate-control.patch |    2 +-
 ...1-fix-station-rate-table-updates-on-assoc.patch |    2 +-
 .../patches/subsys/400-allow-ibss-mixed.patch      |    2 +-
 .../500-mac80211_configure_antenna_gain.patch      |   36 +-
 .../kernel/mt76/patches/100-mac80211-5.10.patch    |   82 ++
 .../utils/iw/patches/001-nl80211_h_sync.patch      |  346 +++++-
 56 files changed, 555 insertions(+), 3215 deletions(-)

diff --git a/package/kernel/ath10k-ct/patches/300-mac80211-5.10.patch b/package/kernel/ath10k-ct/patches/300-mac80211-5.10.patch
new file mode 100644
index 0000000000..52d639291b
--- /dev/null
+++ b/package/kernel/ath10k-ct/patches/300-mac80211-5.10.patch
@@ -0,0 +1,24 @@
+--- a/ath10k-5.8/wmi.c
++++ b/ath10k-5.8/wmi.c
+@@ -4254,7 +4254,7 @@ void ath10k_wmi_event_host_swba(struct a
+ 		 * actual channel switch is done
+ 		 */
+ 		if (arvif->vif->csa_active &&
+-		    ieee80211_csa_is_complete(arvif->vif)) {
++		    ieee80211_beacon_cntdwn_is_complete(arvif->vif)) {
+ 			ieee80211_csa_finish(arvif->vif);
+ 			continue;
+ 		}
+--- a/ath10k-5.8/mac.c
++++ b/ath10k-5.8/mac.c
+@@ -2295,8 +2295,8 @@ static void ath10k_mac_vif_ap_csa_count_
+ 	if (!arvif->is_up)
+ 		return;
+ 
+-	if (!ieee80211_csa_is_complete(vif)) {
+-		ieee80211_csa_update_counter(vif);
++	if (!ieee80211_beacon_cntdwn_is_complete(vif)) {
++		ieee80211_beacon_update_cntdwn(vif);
+ 
+ 		ret = ath10k_mac_setup_bcn_tmpl(arvif);
+ 		if (ret)
diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
index 283e1798b2..06fe948fa2 100644
--- a/package/kernel/mac80211/Makefile
+++ b/package/kernel/mac80211/Makefile
@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=5.9.12-1
+PKG_VERSION:=5.10-rc6-1
 PKG_RELEASE:=1
-PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.9.12/
-PKG_HASH:=8cf3f23152a787eeec2df1d7b38a559b0d89bdc823d9ac99175a4eb76d2b619e
+PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10-rc6/
+PKG_HASH:=24c1e84dc1e7bb52d4f67ce481c242f29212a4ceb7833af30e3c279a3f710832
 
 PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
diff --git a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch
index 646389a353..c6dc184e28 100644
--- a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch
+++ b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch
@@ -1,6 +1,6 @@
 --- a/net/wireless/reg.c
 +++ b/net/wireless/reg.c
-@@ -3047,6 +3047,8 @@ void regulatory_hint_country_ie(struct w
+@@ -3252,6 +3252,8 @@ void regulatory_hint_country_ie(struct w
  	enum environment_cap env = ENVIRON_ANY;
  	struct regulatory_request *request = NULL, *lr;
  
@@ -9,7 +9,7 @@
  	/* IE len must be evenly divisible by 2 */
  	if (country_ie_len & 0x01)
  		return;
-@@ -3298,6 +3300,7 @@ static bool is_wiphy_all_set_reg_flag(en
+@@ -3503,6 +3505,7 @@ static bool is_wiphy_all_set_reg_flag(en
  
  void regulatory_hint_disconnect(void)
  {
diff --git a/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch
index bdf784968f..17dd8f6597 100644
--- a/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch
+++ b/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -831,6 +831,7 @@ static const struct ieee80211_iface_limi
+@@ -830,6 +830,7 @@ static const struct ieee80211_iface_limi
  				 BIT(NL80211_IFTYPE_AP) },
  	{ .max = 1,	.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
  				 BIT(NL80211_IFTYPE_P2P_GO) },
diff --git a/package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch
index 57d3363274..92fb90c165 100644
--- a/package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch
+++ b/package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch
@@ -11,7 +11,7 @@ drivers/net/wireless/ath/ath5k/debug.c |   86 ++++++++++++++++++++++++++++++++
 
 --- a/drivers/net/wireless/ath/ath5k/debug.c
 +++ b/drivers/net/wireless/ath/ath5k/debug.c
-@@ -822,6 +822,97 @@ static const struct file_operations fops
+@@ -803,6 +803,97 @@ static const struct file_operations fops
  	.llseek = default_llseek,
  };
  
@@ -109,7 +109,7 @@ drivers/net/wireless/ath/ath5k/debug.c |   86 ++++++++++++++++++++++++++++++++
  
  /* debugfs: queues etc */
  
-@@ -1016,6 +1107,8 @@ ath5k_debug_init_device(struct ath5k_hw
+@@ -997,6 +1088,8 @@ ath5k_debug_init_device(struct ath5k_hw
  	debugfs_create_file("queue", 0600, phydir, ah, &fops_queue);
  	debugfs_create_bool("32khz_clock", 0600, phydir,
  			    &ah->ah_use_32khz_clock);
diff --git a/package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch b/package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch
index c75d6c7982..ea94b52385 100644
--- a/package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch
+++ b/package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch
@@ -14,7 +14,7 @@ Signed-off-by: David Bauer <mail at david-bauer.net>
 
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -928,6 +928,7 @@ static void ath9k_set_hw_capab(struct at
+@@ -927,6 +927,7 @@ static void ath9k_set_hw_capab(struct at
  	ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
  	ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
  	ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
@@ -22,7 +22,7 @@ Signed-off-by: David Bauer <mail at david-bauer.net>
  
  	if (ath9k_ps_enable)
  		ieee80211_hw_set(hw, SUPPORTS_PS);
-@@ -940,9 +941,6 @@ static void ath9k_set_hw_capab(struct at
+@@ -939,9 +940,6 @@ static void ath9k_set_hw_capab(struct at
  				IEEE80211_RADIOTAP_MCS_HAVE_STBC;
  	}
  
diff --git a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch
index 5220157de6..76cb63a5c8 100644
--- a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch
+++ b/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch
@@ -125,7 +125,7 @@
  		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -528,6 +528,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -531,6 +531,11 @@ irqreturn_t ath_isr(int irq, void *dev)
  	if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
  		return IRQ_HANDLED;
  
diff --git a/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch
index f59654e414..0d938a3730 100644
--- a/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch
+++ b/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch
@@ -55,7 +55,7 @@
  	ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -819,7 +819,8 @@ static void ath9k_init_txpower_limits(st
+@@ -818,7 +818,8 @@ static void ath9k_init_txpower_limits(st
  	if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
  		ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ);
  
@@ -66,7 +66,7 @@
  
  static const struct ieee80211_iface_limit if_limits[] = {
 @@ -1015,6 +1016,18 @@ static void ath9k_set_hw_capab(struct at
- 			      NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS);
+ 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
  }
  
 +static void ath_get_initial_entropy(struct ath_softc *sc)
@@ -110,7 +110,7 @@
  static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
 +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -1320,9 +1320,30 @@ void ar5008_hw_init_rate_txpower(struct
+@@ -1349,9 +1349,30 @@ void ar5008_hw_init_rate_txpower(struct
  	}
  }
  
@@ -141,7 +141,7 @@
  	static const u32 ar5416_cca_regs[6] = {
  		AR_PHY_CCA,
  		AR_PHY_CH1_CCA,
-@@ -1337,6 +1358,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
+@@ -1366,6 +1387,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
  	if (ret)
  	    return ret;
  
diff --git a/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch
index 48cc171134..466767adb9 100644
--- a/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch
+++ b/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
 +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -949,55 +949,6 @@ static bool ar5008_hw_ani_control_new(st
+@@ -978,55 +978,6 @@ static bool ar5008_hw_ani_control_new(st
  		 * on == 0 means more noise imm
  		 */
  		u32 on = param ? 1 : 0;
diff --git a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch
index bc5c1ab4ef..7e3e1236f7 100644
--- a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch
+++ b/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch
@@ -337,9 +337,9 @@
  #include "btcoex.h"
 +#include "hsr.h"
  
- u8 ath9k_parse_mpdudensity(u8 mpdudensity)
- {
-@@ -649,6 +650,7 @@ void ath_reset_work(struct work_struct *
+ static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			u32 queues, bool drop);
+@@ -652,6 +653,7 @@ void ath_reset_work(struct work_struct *
  static int ath9k_start(struct ieee80211_hw *hw)
  {
  	struct ath_softc *sc = hw->priv;
@@ -347,7 +347,7 @@
  	struct ath_hw *ah = sc->sc_ah;
  	struct ath_common *common = ath9k_hw_common(ah);
  	struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
-@@ -727,6 +729,11 @@ static int ath9k_start(struct ieee80211_
+@@ -730,6 +732,11 @@ static int ath9k_start(struct ieee80211_
  					  AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
  	}
  
diff --git a/package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch
index 72b99050c4..8e0041e3ef 100644
--- a/package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch
+++ b/package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch
@@ -13,7 +13,7 @@
  static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
  			    const struct ath_bus_ops *bus_ops)
  {
-@@ -758,6 +764,9 @@ static int ath9k_init_softc(u16 devid, s
+@@ -757,6 +763,9 @@ static int ath9k_init_softc(u16 devid, s
  	if (ret)
  		goto err_hw;
  
diff --git a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch
index 4e59bb00e9..e004acc340 100644
--- a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch
+++ b/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch
@@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven at open-mesh.com>
 
 --- a/drivers/net/wireless/ath/ath10k/core.c
 +++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -3172,6 +3172,16 @@ int ath10k_core_register(struct ath10k *
+@@ -3189,6 +3189,16 @@ int ath10k_core_register(struct ath10k *
  
  	queue_work(ar->workqueue, &ar->register_work);
  
diff --git a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch
index 0abd66f85e..1fedd337ac 100644
--- a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch
+++ b/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath10k/mac.c
 +++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -9049,6 +9049,21 @@ static int ath10k_mac_init_rd(struct ath
+@@ -9713,6 +9713,21 @@ static int ath10k_mac_init_rd(struct ath
  	return 0;
  }
  
@@ -22,7 +22,7 @@
  int ath10k_mac_register(struct ath10k *ar)
  {
  	static const u32 cipher_suites[] = {
-@@ -9376,6 +9391,12 @@ int ath10k_mac_register(struct ath10k *a
+@@ -10062,6 +10077,12 @@ int ath10k_mac_register(struct ath10k *a
  
  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
  
diff --git a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
index 74a3028a8a..403d1e5035 100644
--- a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
+++ b/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
@@ -140,7 +140,7 @@ v13:
  		.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
-@@ -131,6 +133,7 @@ static const struct ath10k_hw_params ath
+@@ -130,6 +132,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA9887_1_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca9887 hw1.0",
@@ -148,7 +148,7 @@ v13:
  		.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
-@@ -340,6 +343,7 @@ static const struct ath10k_hw_params ath
+@@ -335,6 +338,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA99X0_2_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca99x0 hw2.0",
@@ -156,7 +156,7 @@ v13:
  		.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.otp_exe_param = 0x00000700,
-@@ -381,6 +385,7 @@ static const struct ath10k_hw_params ath
+@@ -375,6 +379,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA9984_1_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca9984/qca9994 hw1.0",
@@ -164,7 +164,7 @@ v13:
  		.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
-@@ -429,6 +434,7 @@ static const struct ath10k_hw_params ath
+@@ -422,6 +427,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA9888_2_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca9888 hw2.0",
@@ -172,7 +172,7 @@ v13:
  		.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
-@@ -2887,6 +2893,10 @@ int ath10k_core_start(struct ath10k *ar,
+@@ -2904,6 +2910,10 @@ int ath10k_core_start(struct ath10k *ar,
  		goto err_hif_stop;
  	}
  
@@ -183,7 +183,7 @@ v13:
  	return 0;
  
  err_hif_stop:
-@@ -3145,9 +3155,18 @@ static void ath10k_core_register_work(st
+@@ -3162,9 +3172,18 @@ static void ath10k_core_register_work(st
  		goto err_spectral_destroy;
  	}
  
@@ -202,7 +202,7 @@ v13:
  err_spectral_destroy:
  	ath10k_spectral_destroy(ar);
  err_debug_destroy:
-@@ -3193,6 +3212,8 @@ void ath10k_core_unregister(struct ath10
+@@ -3210,6 +3229,8 @@ void ath10k_core_unregister(struct ath10
  	if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
  		return;
  
@@ -221,7 +221,7 @@ v13:
  
  #include "htt.h"
  #include "htc.h"
-@@ -1216,6 +1217,13 @@ struct ath10k {
+@@ -1237,6 +1238,13 @@ struct ath10k {
  	} testmode;
  
  	struct {
@@ -407,10 +407,10 @@ v13:
  /* Rates */
 --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
 +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
-@@ -224,7 +224,10 @@ struct wmi_ops {
- 	struct sk_buff *(*gen_bb_timing)
- 			(struct ath10k *ar,
+@@ -226,7 +226,10 @@ struct wmi_ops {
  			 const struct wmi_bb_timing_cfg_arg *arg);
+ 	struct sk_buff *(*gen_per_peer_per_tid_cfg)(struct ath10k *ar,
+ 						    const struct wmi_per_peer_per_tid_cfg_arg *arg);
 +	struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num,
 +					   u32 input, u32 pull_type, u32 intr_mode);
  
@@ -418,7 +418,7 @@ v13:
  };
  
  int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
-@@ -1120,6 +1123,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *
+@@ -1122,6 +1125,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *
  	return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
  }
  
@@ -467,7 +467,7 @@ v13:
  static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
 --- a/drivers/net/wireless/ath/ath10k/wmi.c
 +++ b/drivers/net/wireless/ath/ath10k/wmi.c
-@@ -7471,6 +7471,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
+@@ -7463,6 +7463,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
  	return skb;
  }
  
@@ -517,7 +517,7 @@ v13:
  static struct sk_buff *
  ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
  			     enum wmi_sta_ps_mode psmode)
-@@ -9129,6 +9172,9 @@ static const struct wmi_ops wmi_ops = {
+@@ -9151,6 +9194,9 @@ static const struct wmi_ops wmi_ops = {
  	.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
  	.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
  	.gen_echo = ath10k_wmi_op_gen_echo,
@@ -527,7 +527,7 @@ v13:
  	/* .gen_bcn_tmpl not implemented */
  	/* .gen_prb_tmpl not implemented */
  	/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9199,6 +9245,8 @@ static const struct wmi_ops wmi_10_1_ops
+@@ -9221,6 +9267,8 @@ static const struct wmi_ops wmi_10_1_ops
  	.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
  	.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
  	.gen_echo = ath10k_wmi_op_gen_echo,
@@ -536,7 +536,7 @@ v13:
  	/* .gen_bcn_tmpl not implemented */
  	/* .gen_prb_tmpl not implemented */
  	/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9271,6 +9319,8 @@ static const struct wmi_ops wmi_10_2_ops
+@@ -9293,6 +9341,8 @@ static const struct wmi_ops wmi_10_2_ops
  	.gen_delba_send = ath10k_wmi_op_gen_delba_send,
  	.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
  	.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
@@ -545,7 +545,7 @@ v13:
  	/* .gen_pdev_enable_adaptive_cca not implemented */
  };
  
-@@ -9342,6 +9392,8 @@ static const struct wmi_ops wmi_10_2_4_o
+@@ -9364,6 +9414,8 @@ static const struct wmi_ops wmi_10_2_4_o
  		ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
  	.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
  	.gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing,
@@ -554,7 +554,7 @@ v13:
  	/* .gen_bcn_tmpl not implemented */
  	/* .gen_prb_tmpl not implemented */
  	/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9422,6 +9474,8 @@ static const struct wmi_ops wmi_10_4_ops
+@@ -9445,6 +9497,8 @@ static const struct wmi_ops wmi_10_4_ops
  	.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
  	.gen_echo = ath10k_wmi_op_gen_echo,
  	.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
@@ -565,7 +565,7 @@ v13:
  int ath10k_wmi_attach(struct ath10k *ar)
 --- a/drivers/net/wireless/ath/ath10k/wmi.h
 +++ b/drivers/net/wireless/ath/ath10k/wmi.h
-@@ -3016,6 +3016,41 @@ enum wmi_10_4_feature_mask {
+@@ -3027,6 +3027,41 @@ enum wmi_10_4_feature_mask {
  
  };
  
diff --git a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch
index dbd3be79e1..f7569df33c 100644
--- a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch
+++ b/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch
@@ -16,7 +16,7 @@ Signed-off-by: Mathias Kresin <dev at kresin.me>
 
 --- a/drivers/net/wireless/ath/ath10k/core.h
 +++ b/drivers/net/wireless/ath/ath10k/core.h
-@@ -1269,6 +1269,10 @@ struct ath10k {
+@@ -1290,6 +1290,10 @@ struct ath10k {
  	bool coex_support;
  	int coex_gpio_pin;
  
@@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin <dev at kresin.me>
  	if (ret)
 --- a/drivers/net/wireless/ath/ath10k/mac.c
 +++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -9393,7 +9393,7 @@ int ath10k_mac_register(struct ath10k *a
+@@ -10079,7 +10079,7 @@ int ath10k_mac_register(struct ath10k *a
  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
  
  #ifdef CPTCFG_MAC80211_LEDS
diff --git a/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch b/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch
index 4c1963b828..e951e011e6 100644
--- a/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch
+++ b/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch
@@ -38,7 +38,7 @@ Forwarded: https://patchwork.kernel.org/patch/10986723/
  
  	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
  		arg.ssid = arvif->u.ap.ssid;
-@@ -3189,7 +3189,7 @@ static int ath10k_update_channel_list(st
+@@ -3255,7 +3255,7 @@ static int ath10k_update_channel_list(st
  			ch->min_power = 0;
  			ch->max_power = channel->max_power * 2;
  			ch->max_reg_power = channel->max_reg_power * 2;
diff --git a/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch b/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch
index ace2fd5481..a149ce1216 100644
--- a/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch
+++ b/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch
@@ -89,7 +89,7 @@ Forwarded: no
  
  	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
  		arg.ssid = arvif->u.ap.ssid;
-@@ -3189,7 +3225,8 @@ static int ath10k_update_channel_list(st
+@@ -3255,7 +3291,8 @@ static int ath10k_update_channel_list(st
  			ch->min_power = 0;
  			ch->max_power = channel->max_power * 2;
  			ch->max_reg_power = channel->max_reg_power * 2;
diff --git a/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch b/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch
index b3f30943ab..09ef50526f 100644
--- a/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch
+++ b/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch
@@ -22,7 +22,7 @@
  static int modparam_bad_frames_preempt;
  module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
  MODULE_PARM_DESC(bad_frames_preempt,
-@@ -2867,10 +2872,10 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2869,10 +2874,10 @@ static int b43_gpio_init(struct b43_wlde
  	u32 mask, set;
  
  	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
diff --git a/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch b/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch
index a8dbefb5d9..e395d48202 100644
--- a/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch
+++ b/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch
@@ -11,7 +11,7 @@
  b43-$(CPTCFG_B43_LEDS)		+= leds.o
 --- a/drivers/net/wireless/broadcom/b43/main.c
 +++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -2000,10 +2000,12 @@ static void b43_do_interrupt_thread(stru
+@@ -2001,10 +2001,12 @@ static void b43_do_interrupt_thread(stru
  			dma_reason[0], dma_reason[1],
  			dma_reason[2], dma_reason[3],
  			dma_reason[4], dma_reason[5]);
diff --git a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch
index cd7b7583c9..52ae7a8eba 100644
--- a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch
+++ b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/broadcom/b43/main.c
 +++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -1642,7 +1642,7 @@ static void b43_write_beacon_template(st
+@@ -1643,7 +1643,7 @@ static void b43_write_beacon_template(st
  				  len, ram_offset, shm_size_offset, rate);
  
  	/* Write the PHY TX control parameters. */
@@ -9,7 +9,7 @@
  	antenna = b43_antenna_to_phyctl(antenna);
  	ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
  	/* We can't send beacons with short preamble. Would get PHY errors. */
-@@ -3282,8 +3282,8 @@ static int b43_chip_init(struct b43_wlde
+@@ -3284,8 +3284,8 @@ static int b43_chip_init(struct b43_wlde
  
  	/* Select the antennae */
  	if (phy->ops->set_rx_antenna)
@@ -20,7 +20,7 @@
  
  	if (phy->type == B43_PHYTYPE_B) {
  		value16 = b43_read16(dev, 0x005E);
-@@ -3983,7 +3983,6 @@ static int b43_op_config(struct ieee8021
+@@ -3985,7 +3985,6 @@ static int b43_op_config(struct ieee8021
  	struct b43_wldev *dev = wl->current_dev;
  	struct b43_phy *phy = &dev->phy;
  	struct ieee80211_conf *conf = &hw->conf;
@@ -28,7 +28,7 @@
  	int err = 0;
  
  	mutex_lock(&wl->mutex);
-@@ -4026,11 +4025,9 @@ static int b43_op_config(struct ieee8021
+@@ -4028,11 +4027,9 @@ static int b43_op_config(struct ieee8021
  	}
  
  	/* Antennas for RX and management frame TX. */
@@ -42,7 +42,7 @@
  
  	if (wl->radio_enabled != phy->radio_on) {
  		if (wl->radio_enabled) {
-@@ -5174,6 +5171,47 @@ static int b43_op_get_survey(struct ieee
+@@ -5176,6 +5173,47 @@ static int b43_op_get_survey(struct ieee
  	return 0;
  }
  
@@ -90,7 +90,7 @@
  static const struct ieee80211_ops b43_hw_ops = {
  	.tx			= b43_op_tx,
  	.conf_tx		= b43_op_conf_tx,
-@@ -5195,6 +5233,8 @@ static const struct ieee80211_ops b43_hw
+@@ -5197,6 +5235,8 @@ static const struct ieee80211_ops b43_hw
  	.sw_scan_complete	= b43_op_sw_scan_complete_notifier,
  	.get_survey		= b43_op_get_survey,
  	.rfkill_poll		= b43_rfkill_poll,
@@ -99,7 +99,7 @@
  };
  
  /* Hard-reset the chip. Do not call this directly.
-@@ -5496,6 +5536,8 @@ static int b43_one_core_attach(struct b4
+@@ -5498,6 +5538,8 @@ static int b43_one_core_attach(struct b4
  	if (!wldev)
  		goto out;
  
@@ -108,7 +108,7 @@
  	wldev->use_pio = b43_modparam_pio;
  	wldev->dev = dev;
  	wldev->wl = wl;
-@@ -5590,6 +5632,9 @@ static struct b43_wl *b43_wireless_init(
+@@ -5592,6 +5634,9 @@ static struct b43_wl *b43_wireless_init(
  
  	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
  
diff --git a/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch b/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch
index 2aa7612878..9cb0a32fd4 100644
--- a/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch
+++ b/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/broadcom/b43/main.c
 +++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -2884,6 +2884,14 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2886,6 +2886,14 @@ static int b43_gpio_init(struct b43_wlde
  	} else if (dev->dev->chip_id == 0x5354) {
  		/* Don't allow overtaking buttons GPIOs */
  		set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
diff --git a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch
index c18a5bfa4a..dc2295db1b 100644
--- a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch
+++ b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch
@@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-@@ -1554,6 +1554,7 @@ int __init brcmf_core_init(void)
+@@ -1557,6 +1557,7 @@ int __init brcmf_core_init(void)
  {
  	if (!schedule_work(&brcmf_driver_work))
  		return -EBUSY;
diff --git a/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
index 4e79111377..7b4cb250f9 100644
--- a/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
+++ b/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
@@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -714,8 +714,36 @@ static struct wireless_dev *brcmf_cfg802
+@@ -715,8 +715,36 @@ static struct wireless_dev *brcmf_cfg802
  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
  	struct brcmf_pub *drvr = cfg->pub;
  	struct wireless_dev *wdev;
diff --git a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch
index bf8343790d..b5112bd682 100644
--- a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch
+++ b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch
@@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil at raspberrypi.org>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -2956,6 +2956,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
+@@ -2957,6 +2957,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
  	 * preference in cfg struct to apply this to
  	 * FW later while initializing the dongle
  	 */
diff --git a/package/kernel/mac80211/patches/brcm/998-survey.patch b/package/kernel/mac80211/patches/brcm/998-survey.patch
index 1c5255cce0..cf70644e1d 100644
--- a/package/kernel/mac80211/patches/brcm/998-survey.patch
+++ b/package/kernel/mac80211/patches/brcm/998-survey.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -2908,6 +2908,63 @@ done:
+@@ -2909,6 +2909,63 @@ done:
  }
  
  static int
@@ -64,7 +64,7 @@
  brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
  			    int idx, u8 *mac, struct station_info *sinfo)
  {
-@@ -3003,6 +3060,7 @@ static s32 brcmf_inform_single_bss(struc
+@@ -3004,6 +3061,7 @@ static s32 brcmf_inform_single_bss(struc
  	struct brcmu_chan ch;
  	u16 channel;
  	u32 freq;
@@ -72,7 +72,7 @@
  	u16 notify_capability;
  	u16 notify_interval;
  	u8 *notify_ie;
-@@ -3027,6 +3085,17 @@ static s32 brcmf_inform_single_bss(struc
+@@ -3028,6 +3086,17 @@ static s32 brcmf_inform_single_bss(struc
  		band = NL80211_BAND_5GHZ;
  
  	freq = ieee80211_channel_to_frequency(channel, band);
@@ -90,7 +90,7 @@
  	bss_data.chan = ieee80211_get_channel(wiphy, freq);
  	bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
  	bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
-@@ -5481,6 +5550,7 @@ static struct cfg80211_ops brcmf_cfg8021
+@@ -5514,6 +5583,7 @@ static struct cfg80211_ops brcmf_cfg8021
  	.leave_ibss = brcmf_cfg80211_leave_ibss,
  	.get_station = brcmf_cfg80211_get_station,
  	.dump_station = brcmf_cfg80211_dump_station,
@@ -100,7 +100,7 @@
  	.add_key = brcmf_cfg80211_add_key,
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-@@ -1352,6 +1352,8 @@ int brcmf_attach(struct device *dev)
+@@ -1356,6 +1356,8 @@ int brcmf_attach(struct device *dev)
  
  	/* Link to bus module */
  	drvr->hdrlen = 0;
@@ -109,7 +109,7 @@
  
  	/* Attach and link in the protocol */
  	ret = brcmf_proto_attach(drvr);
-@@ -1434,6 +1436,12 @@ void brcmf_detach(struct device *dev)
+@@ -1438,6 +1440,12 @@ void brcmf_detach(struct device *dev)
  	if (drvr == NULL)
  		return;
  
diff --git a/package/kernel/mac80211/patches/build/015-ipw200-mtu.patch b/package/kernel/mac80211/patches/build/015-ipw200-mtu.patch
index f80fda4360..68db4f72d3 100644
--- a/package/kernel/mac80211/patches/build/015-ipw200-mtu.patch
+++ b/package/kernel/mac80211/patches/build/015-ipw200-mtu.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
 +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
-@@ -11472,6 +11472,15 @@ static const struct attribute_group ipw_
+@@ -11470,6 +11470,15 @@ static const struct attribute_group ipw_
  	.attrs = ipw_sysfs_entries,
  };
  
@@ -16,7 +16,7 @@
  #ifdef CPTCFG_IPW2200_PROMISCUOUS
  static int ipw_prom_open(struct net_device *dev)
  {
-@@ -11520,15 +11529,6 @@ static netdev_tx_t ipw_prom_hard_start_x
+@@ -11518,15 +11527,6 @@ static netdev_tx_t ipw_prom_hard_start_x
  	return NETDEV_TX_OK;
  }
  
diff --git a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch
index 1958ddad7d..ff2ce2071f 100644
--- a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch
+++ b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch
@@ -1,6 +1,6 @@
 --- a/local-symbols
 +++ b/local-symbols
-@@ -435,43 +435,6 @@ USB_SIERRA_NET=
+@@ -437,43 +437,6 @@ USB_SIERRA_NET=
  USB_VL600=
  USB_NET_CH9200=
  USB_NET_AQC111=
@@ -90,7 +90,7 @@
  config B43_PHY_G
 --- a/drivers/net/wireless/broadcom/b43/main.c
 +++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -2851,7 +2851,7 @@ static struct ssb_device *b43_ssb_gpio_d
+@@ -2853,7 +2853,7 @@ static struct ssb_device *b43_ssb_gpio_d
  {
  	struct ssb_bus *bus = dev->dev->sdev->bus;
  
@@ -99,7 +99,7 @@
  	return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
  #else
  	return bus->chipco.dev;
-@@ -4868,7 +4868,7 @@ static int b43_wireless_core_init(struct
+@@ -4870,7 +4870,7 @@ static int b43_wireless_core_init(struct
  	}
  	if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
  		hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
@@ -140,7 +140,7 @@
  # LED support
 --- a/drivers/net/wireless/broadcom/b43legacy/main.c
 +++ b/drivers/net/wireless/broadcom/b43legacy/main.c
-@@ -1906,7 +1906,7 @@ static int b43legacy_gpio_init(struct b4
+@@ -1907,7 +1907,7 @@ static int b43legacy_gpio_init(struct b4
  	if (dev->dev->id.revision >= 2)
  		mask  |= 0x0010; /* FIXME: This is redundant. */
  
@@ -149,7 +149,7 @@
  	pcidev = bus->pcicore.dev;
  #endif
  	gpiodev = bus->chipco.dev ? : pcidev;
-@@ -1925,7 +1925,7 @@ static void b43legacy_gpio_cleanup(struc
+@@ -1926,7 +1926,7 @@ static void b43legacy_gpio_cleanup(struc
  	struct ssb_bus *bus = dev->dev->bus;
  	struct ssb_device *gpiodev, *pcidev = NULL;
  
@@ -192,7 +192,7 @@
  	select BRCMUTIL
 --- a/Kconfig.local
 +++ b/Kconfig.local
-@@ -1309,117 +1309,6 @@ config BACKPORTED_USB_NET_CH9200
+@@ -1315,117 +1315,6 @@ config BACKPORTED_USB_NET_CH9200
  config BACKPORTED_USB_NET_AQC111
  	tristate
  	default USB_NET_AQC111
diff --git a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch
index b6934d3954..e74d9a9aa0 100644
--- a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch
+++ b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch
@@ -1,6 +1,6 @@
 --- a/local-symbols
 +++ b/local-symbols
-@@ -330,6 +330,7 @@ RT2X00_LIB_FIRMWARE=
+@@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE=
  RT2X00_LIB_CRYPTO=
  RT2X00_LIB_LEDS=
  RT2X00_LIB_DEBUGFS=
@@ -127,7 +127,7 @@
  	DECLARE_KFIFO_PTR(txstatus_fifo, u32);
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1407,6 +1407,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+@@ -1406,6 +1406,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
  	INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
  	INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
  
@@ -138,7 +138,7 @@
  	/*
  	 * Let the driver probe the device to detect the capabilities.
  	 */
-@@ -1550,6 +1554,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+@@ -1549,6 +1553,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
  	 * Free the driver data.
  	 */
  	kfree(rt2x00dev->drv_data);
diff --git a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch
index 15f46fc98a..88d6dd559b 100644
--- a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch
+++ b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1345,7 +1345,7 @@ static inline void rt2x00lib_set_if_comb
+@@ -1344,7 +1344,7 @@ static inline void rt2x00lib_set_if_comb
  	 */
  	if_limit = &rt2x00dev->if_limits_ap;
  	if_limit->max = rt2x00dev->ops->max_ap_intf;
diff --git a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch
index 70f8d06e24..fca1fb2cd4 100644
--- a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch
+++ b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch
@@ -31,7 +31,7 @@ Tested-by: Christoph Krapp <achterin at googlemail.com>
  static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
  {
  	struct hw_mode_spec *spec = &rt2x00dev->spec;
-@@ -1211,6 +1224,10 @@ static int rt2x00lib_probe_hw(struct rt2
+@@ -1210,6 +1223,10 @@ static int rt2x00lib_probe_hw(struct rt2
  
  #undef RT2X00_TASKLET_INIT
  
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 3c699dc648..7b036e4e4c 100644
--- a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch
+++ b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch
@@ -8,7 +8,7 @@
  	wpa.o \
  	scan.o offchannel.o \
  	ht.o agg-tx.o agg-rx.o \
-@@ -18,8 +17,8 @@ mac80211-y := \
+@@ -19,8 +18,8 @@ mac80211-y := \
  	rate.o \
  	michael.o \
  	tkip.o \
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 0033837ce7..665231a040 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,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
 
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1200,7 +1200,6 @@ static int ieee80211_stop_ap(struct wiph
+@@ -1288,7 +1288,6 @@ static int ieee80211_stop_ap(struct wiph
  	sdata->vif.bss_conf.ftmr_params = NULL;
  
  	__sta_info_flush(sdata, true);
diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch
index c7da15fffc..80f995737b 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
-@@ -2353,7 +2353,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -2442,7 +2442,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/315-mac80211-check-and-refresh-aggregation-session-in-en.patch b/package/kernel/mac80211/patches/subsys/315-mac80211-check-and-refresh-aggregation-session-in-en.patch
deleted file mode 100644
index d121eec88e..0000000000
--- a/package/kernel/mac80211/patches/subsys/315-mac80211-check-and-refresh-aggregation-session-in-en.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Mon, 17 Aug 2020 21:11:25 +0200
-Subject: [PATCH] mac80211: check and refresh aggregation session in
- encap offload tx
-
-Update the last_tx timestamp to avoid tearing down the aggregation session
-early. Fall back to the slow path if the session setup is still running
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -4186,6 +4186,8 @@ static void ieee80211_8023_xmit(struct i
- 	bool authorized = false;
- 	bool multicast;
- 	unsigned char *ra = ehdr->h_dest;
-+	struct tid_ampdu_tx *tid_tx;
-+	u8 tid;
- 
- 	if (IS_ERR(sta) || (sta && !sta->uploaded))
- 		sta = NULL;
-@@ -4223,6 +4225,22 @@ static void ieee80211_8023_xmit(struct i
- 
- 	memset(info, 0, sizeof(*info));
- 
-+	if (sta) {
-+		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-+		tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
-+		if (tid_tx) {
-+			if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
-+				/* fall back to non-offload slow path */
-+				__ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL);
-+				return;
-+			}
-+
-+			info->flags |= IEEE80211_TX_CTL_AMPDU;
-+			if (tid_tx->timeout)
-+				tid_tx->last_tx = jiffies;
-+		}
-+	}
-+
- 	if (unlikely(!multicast && skb->sk &&
- 		     skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS))
- 		info->ack_frame_id = ieee80211_store_ack_skb(local, skb,
diff --git a/package/kernel/mac80211/patches/subsys/316-mac80211-skip-encap-offload-for-tx-multicast-control.patch b/package/kernel/mac80211/patches/subsys/316-mac80211-skip-encap-offload-for-tx-multicast-control.patch
deleted file mode 100644
index e8763e6237..0000000000
--- a/package/kernel/mac80211/patches/subsys/316-mac80211-skip-encap-offload-for-tx-multicast-control.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Fri, 21 Aug 2020 05:54:10 +0200
-Subject: [PATCH] mac80211: skip encap offload for tx multicast/control
- packets
-
-This simplifies the checks in the encap offload tx handler and allows using
-it in cases where software crypto is used for multicast packets, e.g. when
-using an AP_VLAN.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -4181,88 +4181,47 @@ static void ieee80211_8023_xmit(struct i
- 				struct sk_buff *skb)
- {
- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--	struct ethhdr *ehdr = (struct ethhdr *)skb->data;
- 	struct ieee80211_local *local = sdata->local;
--	bool authorized = false;
--	bool multicast;
--	unsigned char *ra = ehdr->h_dest;
- 	struct tid_ampdu_tx *tid_tx;
- 	u8 tid;
- 
--	if (IS_ERR(sta) || (sta && !sta->uploaded))
--		sta = NULL;
--
--	if (sdata->vif.type == NL80211_IFTYPE_STATION &&
--	    (!sta || !test_sta_flag(sta, WLAN_STA_TDLS_PEER)))
--		ra = sdata->u.mgd.bssid;
--
--	if (is_zero_ether_addr(ra))
--		goto out_free;
--
- 	if (local->ops->wake_tx_queue) {
- 		u16 queue = __ieee80211_select_queue(sdata, sta, skb);
- 		skb_set_queue_mapping(skb, queue);
- 		skb_get_hash(skb);
- 	}
- 
--	multicast = is_multicast_ether_addr(ra);
--
--	if (sta)
--		authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
--
--	if (!multicast && !authorized &&
--	    (ehdr->h_proto != sdata->control_port_protocol ||
--	     !ether_addr_equal(sdata->vif.addr, ehdr->h_source)))
--		goto out_free;
--
--	if (multicast && sdata->vif.type == NL80211_IFTYPE_AP &&
--	    !atomic_read(&sdata->u.ap.num_mcast_sta))
--		goto out_free;
--
- 	if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) &&
- 	    test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
- 		goto out_free;
- 
- 	memset(info, 0, sizeof(*info));
- 
--	if (sta) {
--		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
--		tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
--		if (tid_tx) {
--			if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
--				/* fall back to non-offload slow path */
--				__ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL);
--				return;
--			}
--
--			info->flags |= IEEE80211_TX_CTL_AMPDU;
--			if (tid_tx->timeout)
--				tid_tx->last_tx = jiffies;
-+	tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-+	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
-+	if (tid_tx) {
-+		if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
-+			/* fall back to non-offload slow path */
-+			__ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL);
-+			return;
- 		}
-+
-+		info->flags |= IEEE80211_TX_CTL_AMPDU;
-+		if (tid_tx->timeout)
-+			tid_tx->last_tx = jiffies;
- 	}
- 
--	if (unlikely(!multicast && skb->sk &&
-+	if (unlikely(skb->sk &&
- 		     skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS))
- 		info->ack_frame_id = ieee80211_store_ack_skb(local, skb,
- 							     &info->flags, NULL);
- 
--	if (unlikely(sdata->control_port_protocol == ehdr->h_proto)) {
--		if (sdata->control_port_no_encrypt)
--			info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
--		info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
--	}
--
--	if (multicast)
--		info->flags |= IEEE80211_TX_CTL_NO_ACK;
--
- 	info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
- 
- 	ieee80211_tx_stats(dev, skb->len);
- 
--	if (sta) {
--		sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
--		sta->tx_stats.packets[skb_get_queue_mapping(skb)]++;
--	}
-+	sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
-+	sta->tx_stats.packets[skb_get_queue_mapping(skb)]++;
- 
- 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- 		sdata = container_of(sdata->bss,
-@@ -4283,6 +4242,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8
- 					    struct net_device *dev)
- {
- 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	struct ethhdr *ehdr = (struct ethhdr *)skb->data;
- 	struct sta_info *sta;
- 
- 	if (WARN_ON(!sdata->hw_80211_encap)) {
-@@ -4299,6 +4259,10 @@ netdev_tx_t ieee80211_subif_start_xmit_8
- 
- 	if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
- 		kfree_skb(skb);
-+	else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded ||
-+			  !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
-+			  sdata->control_port_protocol == ehdr->h_proto))
-+		ieee80211_subif_start_xmit(skb, dev);
- 	else
- 		ieee80211_8023_xmit(sdata, dev, sta, skb);
- 
diff --git a/package/kernel/mac80211/patches/subsys/317-mac80211-set-info-control.hw_key-for-encap-offload-p.patch b/package/kernel/mac80211/patches/subsys/317-mac80211-set-info-control.hw_key-for-encap-offload-p.patch
deleted file mode 100644
index 077a82d5ee..0000000000
--- a/package/kernel/mac80211/patches/subsys/317-mac80211-set-info-control.hw_key-for-encap-offload-p.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Fri, 21 Aug 2020 06:03:45 +0200
-Subject: [PATCH] mac80211: set info->control.hw_key for encap offload
- packets
-
-This is needed for drivers that don't do the key lookup themselves
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -4182,6 +4182,7 @@ static void ieee80211_8023_xmit(struct i
- {
- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- 	struct ieee80211_local *local = sdata->local;
-+	struct ieee80211_key *key;
- 	struct tid_ampdu_tx *tid_tx;
- 	u8 tid;
- 
-@@ -4230,6 +4231,10 @@ static void ieee80211_8023_xmit(struct i
- 	info->control.flags |= IEEE80211_TX_CTRL_HW_80211_ENCAP;
- 	info->control.vif = &sdata->vif;
- 
-+	key = rcu_dereference(sta->ptk[sta->ptk_idx]);
-+	if (key)
-+		info->control.hw_key = &key->conf;
-+
- 	ieee80211_tx_8023(sdata, skb, skb->len, sta, false);
- 
- 	return;
diff --git a/package/kernel/mac80211/patches/subsys/318-mac80211-rework-tx-encapsulation-offload-API.patch b/package/kernel/mac80211/patches/subsys/318-mac80211-rework-tx-encapsulation-offload-API.patch
deleted file mode 100644
index 811c66499b..0000000000
--- a/package/kernel/mac80211/patches/subsys/318-mac80211-rework-tx-encapsulation-offload-API.patch
+++ /dev/null
@@ -1,613 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Thu, 13 Aug 2020 15:37:11 +0200
-Subject: [PATCH] mac80211: rework tx encapsulation offload API
-
-The current API (which lets the driver turn on/off per vif directly) has a
-number of limitations:
-- it does not deal with AP_VLAN
-- conditions for enabling (no tkip, no monitor) are only checked at
-  add_interface time
-- no way to indicate 4-addr support
-
-In order to address this, store offload flags in struct ieee80211_vif
-(easy to extend for decap offload later). mac80211 initially sets the enable
-flag, but gives the driver a chance to modify it before its settings are
-applied. In addition to the .add_interface op, a .update_vif_offload op is
-introduced, which can be used for runtime changes.
-
-If a driver can't disable encap offload at runtime, or if it has some extra
-limitations, it can simply override the flags within those ops.
-
-Support for encap offload with 4-address mode interfaces can be enabled
-by setting a flag from .add_interface or .update_vif_offload.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -4304,6 +4304,35 @@ static int ath11k_set_he_mu_sounding_mod
- 	return ret;
- }
- 
-+static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
-+					    struct ieee80211_vif *vif)
-+{
-+	struct ath11k *ar = hw->priv;
-+	struct ath11k_base *ab = ar->ab;
-+	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
-+	u32 param_id, param_value;
-+	int ret;
-+
-+	param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
-+	if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET ||
-+	    (vif->type != NL80211_IFTYPE_STATION &&
-+	     vif->type != NL80211_IFTYPE_AP))
-+		vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+
-+	if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
-+		param_value = ATH11K_HW_TXRX_ETHERNET;
-+	else
-+		param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
-+
-+	ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
-+					    param_id, param_value);
-+	if (ret) {
-+		ath11k_warn(ab, "failed to set vdev %d tx encap mode: %d\n",
-+			    arvif->vdev_id, ret);
-+		vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+	}
-+}
-+
- static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
- 				       struct ieee80211_vif *vif)
- {
-@@ -4313,7 +4342,6 @@ static int ath11k_mac_op_add_interface(s
- 	struct vdev_create_params vdev_param = {0};
- 	struct peer_create_params peer_param;
- 	u32 param_id, param_value;
--	int hw_encap = 0;
- 	u16 nss;
- 	int i;
- 	int ret;
-@@ -4407,30 +4435,7 @@ static int ath11k_mac_op_add_interface(s
- 	list_add(&arvif->list, &ar->arvifs);
- 	spin_unlock_bh(&ar->data_lock);
- 
--	param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
--	if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET)
--		switch (vif->type) {
--		case NL80211_IFTYPE_STATION:
--		case NL80211_IFTYPE_AP_VLAN:
--		case NL80211_IFTYPE_AP:
--			hw_encap = 1;
--			break;
--		default:
--			break;
--		}
--
--	if (ieee80211_set_hw_80211_encap(vif, hw_encap))
--		param_value = ATH11K_HW_TXRX_ETHERNET;
--	else
--		param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
--
--	ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
--					    param_id, param_value);
--	if (ret) {
--		ath11k_warn(ab, "failed to set vdev %d tx encap mode: %d\n",
--			    arvif->vdev_id, ret);
--		goto err_vdev_del;
--	}
-+	ath11k_mac_op_update_vif_offload(hw, vif);
- 
- 	nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1;
- 	ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
-@@ -5753,6 +5758,7 @@ static const struct ieee80211_ops ath11k
- 	.reconfig_complete              = ath11k_mac_op_reconfig_complete,
- 	.add_interface                  = ath11k_mac_op_add_interface,
- 	.remove_interface		= ath11k_mac_op_remove_interface,
-+	.update_vif_offload		= ath11k_mac_op_update_vif_offload,
- 	.config                         = ath11k_mac_op_config,
- 	.bss_info_changed               = ath11k_mac_op_bss_info_changed,
- 	.configure_filter		= ath11k_mac_op_configure_filter,
-@@ -6034,6 +6040,7 @@ static int __ath11k_mac_register(struct
- 	ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
- 	ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
- 	ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
-+	ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
- 	if (ht_cap & WMI_HT_CAP_ENABLED) {
- 		ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
- 		ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1606,6 +1606,21 @@ enum ieee80211_vif_flags {
- 	IEEE80211_VIF_GET_NOA_UPDATE		= BIT(3),
- };
- 
-+
-+/**
-+ * enum ieee80211_offload_flags - virtual interface offload flags
-+ *
-+ * @IEEE80211_OFFLOAD_ENCAP_ENABLED: tx encapsulation offload is enabled
-+ *	The driver supports sending frames passed as 802.3 frames by mac80211.
-+ *	It must also support sending 802.11 packets for the same interface.
-+ * @IEEE80211_OFFLOAD_ENCAP_4ADDR: support 4-address mode encapsulation offload
-+ */
-+
-+enum ieee80211_offload_flags {
-+	IEEE80211_OFFLOAD_ENCAP_ENABLED		= BIT(0),
-+	IEEE80211_OFFLOAD_ENCAP_4ADDR		= BIT(1),
-+};
-+
- /**
-  * struct ieee80211_vif - per-interface data
-  *
-@@ -1626,6 +1641,11 @@ enum ieee80211_vif_flags {
-  *	these need to be set (or cleared) when the interface is added
-  *	or, if supported by the driver, the interface type is changed
-  *	at runtime, mac80211 will never touch this field
-+ * @offloaad_flags: hardware offload capabilities/flags for this interface.
-+ *	These are initialized by mac80211 before calling .add_interface,
-+ *	.change_interface or .update_vif_offload and updated by the driver
-+ *	within these ops, based on supported features or runtime change
-+ *	restrictions.
-  * @hw_queue: hardware queue for each AC
-  * @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only
-  * @chanctx_conf: The channel context this interface is assigned to, or %NULL
-@@ -1662,6 +1682,7 @@ struct ieee80211_vif {
- 	struct ieee80211_chanctx_conf __rcu *chanctx_conf;
- 
- 	u32 driver_flags;
-+	u32 offload_flags;
- 
- #ifdef CPTCFG_MAC80211_DEBUGFS
- 	struct dentry *debugfs_dir;
-@@ -2328,6 +2349,9 @@ struct ieee80211_txq {
-  *	aggregating MPDUs with the same keyid, allowing mac80211 to keep Tx
-  *	A-MPDU sessions active while rekeying with Extended Key ID.
-  *
-+ * @IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD: Hardware supports tx encapsulation
-+ *	offload
-+ *
-  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
-  */
- enum ieee80211_hw_flags {
-@@ -2380,6 +2404,7 @@ enum ieee80211_hw_flags {
- 	IEEE80211_HW_SUPPORTS_MULTI_BSSID,
- 	IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
- 	IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
-+	IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
- 
- 	/* keep last, obviously */
- 	NUM_IEEE80211_HW_FLAGS
-@@ -3814,6 +3839,8 @@ enum ieee80211_reconfig_type {
-  * @set_tid_config: Apply TID specific configurations. This callback may sleep.
-  * @reset_tid_config: Reset TID specific configuration for the peer.
-  *	This callback may sleep.
-+ * @update_vif_config: Update virtual interface offload flags
-+ *	This callback may sleep.
-  */
- struct ieee80211_ops {
- 	void (*tx)(struct ieee80211_hw *hw,
-@@ -4125,6 +4152,8 @@ struct ieee80211_ops {
- 	int (*reset_tid_config)(struct ieee80211_hw *hw,
- 				struct ieee80211_vif *vif,
- 				struct ieee80211_sta *sta, u8 tids);
-+	void (*update_vif_offload)(struct ieee80211_hw *hw,
-+				   struct ieee80211_vif *vif);
- };
- 
- /**
---- a/net/mac80211/debugfs.c
-+++ b/net/mac80211/debugfs.c
-@@ -408,6 +408,7 @@ static const char *hw_flag_names[] = {
- 	FLAG(SUPPORTS_MULTI_BSSID),
- 	FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
- 	FLAG(AMPDU_KEYBORDER_SUPPORT),
-+	FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
- #undef FLAG
- };
- 
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -1384,4 +1384,19 @@ static inline int drv_reset_tid_config(s
- 
- 	return ret;
- }
-+
-+static inline void drv_update_vif_offload(struct ieee80211_local *local,
-+					  struct ieee80211_sub_if_data *sdata)
-+{
-+	might_sleep();
-+	check_sdata_in_driver(sdata);
-+
-+	if (!local->ops->update_vif_offload)
-+		return;
-+
-+	trace_drv_update_vif_offload(local, sdata);
-+	local->ops->update_vif_offload(&local->hw, &sdata->vif);
-+	trace_drv_return_void(local);
-+}
-+
- #endif /* __MAC80211_DRIVER_OPS */
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -993,8 +993,6 @@ struct ieee80211_sub_if_data {
- 	} debugfs;
- #endif
- 
--	bool hw_80211_encap;
--
- 	/* must be last, dynamically sized area in this! */
- 	struct ieee80211_vif vif;
- };
-@@ -1772,6 +1770,7 @@ void ieee80211_del_virtual_monitor(struc
- bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
- void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
- 			      bool update_bss);
-+void ieee80211_recalc_offload(struct ieee80211_local *local);
- 
- static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
- {
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -43,6 +43,7 @@
-  */
- 
- static void ieee80211_iface_work(struct work_struct *work);
-+static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata);
- 
- bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
- {
-@@ -348,6 +349,85 @@ static int ieee80211_check_queues(struct
- 	return 0;
- }
- 
-+static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype)
-+{
-+	switch (iftype) {
-+	/* P2P GO and client are mapped to AP/STATION types */
-+	case NL80211_IFTYPE_AP:
-+	case NL80211_IFTYPE_STATION:
-+		return true;
-+	default:
-+		return false;
-+	}
-+}
-+
-+static bool ieee80211_set_sdata_offload_flags(struct ieee80211_sub_if_data *sdata)
-+{
-+	struct ieee80211_local *local = sdata->local;
-+	u32 flags;
-+
-+	flags = sdata->vif.offload_flags;
-+
-+	if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) &&
-+	    ieee80211_iftype_supports_encap_offload(sdata->vif.type)) {
-+		flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+
-+		if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
-+		    local->hw.wiphy->frag_threshold != (u32)-1)
-+			flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+
-+		if (local->monitors)
-+			flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+	} else {
-+		flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+	}
-+
-+	if (sdata->vif.offload_flags == flags)
-+		return false;
-+
-+	sdata->vif.offload_flags = flags;
-+	return true;
-+}
-+
-+
-+static void ieee80211_recalc_sdata_offload(struct ieee80211_sub_if_data *sdata)
-+{
-+	struct ieee80211_local *local = sdata->local;
-+	struct ieee80211_sub_if_data *vsdata;
-+
-+	if (ieee80211_set_sdata_offload_flags(sdata)) {
-+		drv_update_vif_offload(local, sdata);
-+		ieee80211_set_vif_encap_ops(sdata);
-+	}
-+
-+	list_for_each_entry(vsdata, &local->interfaces, list) {
-+		if (vsdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
-+		    vsdata->bss != &sdata->u.ap)
-+			continue;
-+
-+		ieee80211_set_vif_encap_ops(vsdata);
-+	}
-+}
-+
-+void ieee80211_recalc_offload(struct ieee80211_local *local)
-+{
-+	struct ieee80211_sub_if_data *sdata;
-+
-+	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD))
-+		return;
-+
-+	mutex_lock(&local->iflist_mtx);
-+
-+	list_for_each_entry(sdata, &local->interfaces, list) {
-+		if (!ieee80211_sdata_running(sdata))
-+			continue;
-+
-+		ieee80211_recalc_sdata_offload(sdata);
-+	}
-+
-+	mutex_unlock(&local->iflist_mtx);
-+}
-+
- void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
- 				    const int offset)
- {
-@@ -587,6 +667,7 @@ int ieee80211_do_open(struct wireless_de
- 		if (rtnl_dereference(sdata->bss->beacon)) {
- 			ieee80211_vif_vlan_copy_chanctx(sdata);
- 			netif_carrier_on(dev);
-+			ieee80211_set_vif_encap_ops(sdata);
- 		} else {
- 			netif_carrier_off(dev);
- 		}
-@@ -616,6 +697,7 @@ int ieee80211_do_open(struct wireless_de
- 
- 		ieee80211_adjust_monitor_flags(sdata, 1);
- 		ieee80211_configure_filter(local);
-+		ieee80211_recalc_offload(local);
- 		mutex_lock(&local->mtx);
- 		ieee80211_recalc_idle(local);
- 		mutex_unlock(&local->mtx);
-@@ -625,10 +707,13 @@ int ieee80211_do_open(struct wireless_de
- 	default:
- 		if (coming_up) {
- 			ieee80211_del_virtual_monitor(local);
-+			ieee80211_set_sdata_offload_flags(sdata);
- 
- 			res = drv_add_interface(local, sdata);
- 			if (res)
- 				goto err_stop;
-+
-+			ieee80211_set_vif_encap_ops(sdata);
- 			res = ieee80211_check_queues(sdata,
- 				ieee80211_vif_type_p2p(&sdata->vif));
- 			if (res)
-@@ -1293,61 +1378,6 @@ static const struct net_device_ops ieee8
- 
- };
- 
--static void __ieee80211_set_hw_80211_encap(struct ieee80211_sub_if_data *sdata,
--					   bool enable)
--{
--	sdata->dev->netdev_ops = enable ? &ieee80211_dataif_8023_ops :
--					  &ieee80211_dataif_ops;
--	sdata->hw_80211_encap = enable;
--}
--
--bool ieee80211_set_hw_80211_encap(struct ieee80211_vif *vif, bool enable)
--{
--	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
--	struct ieee80211_local *local = sdata->local;
--	struct ieee80211_sub_if_data *iter;
--	struct ieee80211_key *key;
--
--	mutex_lock(&local->iflist_mtx);
--	list_for_each_entry(iter, &local->interfaces, list) {
--		struct ieee80211_sub_if_data *disable = NULL;
--
--		if (vif->type == NL80211_IFTYPE_MONITOR) {
--			disable = iter;
--			__ieee80211_set_hw_80211_encap(iter, false);
--		} else if (iter->vif.type == NL80211_IFTYPE_MONITOR) {
--			disable = sdata;
--			enable = false;
--		}
--		if (disable)
--			sdata_dbg(disable,
--				  "disable hw 80211 encap due to mon co-exist\n");
--	}
--	mutex_unlock(&local->iflist_mtx);
--
--	if (enable == sdata->hw_80211_encap)
--		return enable;
--
--	if (!sdata->dev)
--		return false;
--
--	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
--	    (local->hw.wiphy->frag_threshold != (u32)-1))
--		enable = false;
--
--	mutex_lock(&sdata->local->key_mtx);
--	list_for_each_entry(key, &sdata->key_list, list) {
--		if (key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)
--			enable = false;
--	}
--	mutex_unlock(&sdata->local->key_mtx);
--
--	__ieee80211_set_hw_80211_encap(sdata, enable);
--
--	return enable;
--}
--EXPORT_SYMBOL(ieee80211_set_hw_80211_encap);
--
- static void ieee80211_if_free(struct net_device *dev)
- {
- 	free_percpu(netdev_tstats(dev));
-@@ -1378,6 +1408,32 @@ static void ieee80211_if_setup_no_queue(
- #endif
- }
- 
-+static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata)
-+{
-+	struct ieee80211_local *local = sdata->local;
-+	struct ieee80211_sub_if_data *bss = sdata;
-+	bool enabled;
-+
-+	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
-+		if (!sdata->bss)
-+			return;
-+
-+		bss = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
-+	}
-+
-+	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
-+	    !ieee80211_iftype_supports_encap_offload(bss->vif.type))
-+		return;
-+
-+	enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+	if (sdata->wdev.use_4addr &&
-+	    !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR))
-+		enabled = false;
-+
-+	sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops :
-+					   &ieee80211_dataif_ops;
-+}
-+
- static void ieee80211_iface_work(struct work_struct *work)
- {
- 	struct ieee80211_sub_if_data *sdata =
-@@ -1560,7 +1616,6 @@ static void ieee80211_setup_sdata(struct
- 	sdata->vif.bss_conf.txpower = INT_MIN; /* unset */
- 
- 	sdata->noack_map = 0;
--	sdata->hw_80211_encap = false;
- 
- 	/* only monitor/p2p-device differ */
- 	if (sdata->dev) {
-@@ -1695,6 +1750,7 @@ static int ieee80211_runtime_change_ifty
- 
- 	ieee80211_teardown_sdata(sdata);
- 
-+	ieee80211_set_sdata_offload_flags(sdata);
- 	ret = drv_change_interface(local, sdata, internal_type, p2p);
- 	if (ret)
- 		type = ieee80211_vif_type_p2p(&sdata->vif);
-@@ -1707,6 +1763,7 @@ static int ieee80211_runtime_change_ifty
- 	ieee80211_check_queues(sdata, type);
- 
- 	ieee80211_setup_sdata(sdata, type);
-+	ieee80211_set_vif_encap_ops(sdata);
- 
- 	err = ieee80211_do_open(&sdata->wdev, false);
- 	WARN(err, "type change: do_open returned %d", err);
---- a/net/mac80211/key.c
-+++ b/net/mac80211/key.c
-@@ -177,13 +177,6 @@ static int ieee80211_key_enable_hw_accel
- 		}
- 	}
- 
--	/* TKIP countermeasures don't work in encap offload mode */
--	if (key->conf.cipher == WLAN_CIPHER_SUITE_TKIP &&
--	    sdata->hw_80211_encap) {
--		sdata_dbg(sdata, "TKIP is not allowed in hw 80211 encap mode\n");
--		return -EINVAL;
--	}
--
- 	ret = drv_set_key(key->local, SET_KEY, sdata,
- 			  sta ? &sta->sta : NULL, &key->conf);
- 
-@@ -219,14 +212,6 @@ static int ieee80211_key_enable_hw_accel
- 	case WLAN_CIPHER_SUITE_CCMP_256:
- 	case WLAN_CIPHER_SUITE_GCMP:
- 	case WLAN_CIPHER_SUITE_GCMP_256:
--		/* We cannot do software crypto of data frames with
--		 * encapsulation offload enabled. However for 802.11w to
--		 * function properly we need cmac/gmac keys.
--		 */
--		if (sdata->hw_80211_encap)
--			return -EINVAL;
--		fallthrough;
--
- 	case WLAN_CIPHER_SUITE_AES_CMAC:
- 	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
- 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---- a/net/mac80211/trace.h
-+++ b/net/mac80211/trace.h
-@@ -2734,6 +2734,12 @@ TRACE_EVENT(drv_get_ftm_responder_stats,
- 	)
- );
- 
-+DEFINE_EVENT(local_sdata_addr_evt, drv_update_vif_offload,
-+	TP_PROTO(struct ieee80211_local *local,
-+		 struct ieee80211_sub_if_data *sdata),
-+	TP_ARGS(local, sdata)
-+);
-+
- #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
- 
- #undef TRACE_INCLUDE_PATH
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -4178,11 +4178,10 @@ static bool ieee80211_tx_8023(struct iee
- 
- static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
- 				struct net_device *dev, struct sta_info *sta,
--				struct sk_buff *skb)
-+				struct ieee80211_key *key, struct sk_buff *skb)
- {
- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- 	struct ieee80211_local *local = sdata->local;
--	struct ieee80211_key *key;
- 	struct tid_ampdu_tx *tid_tx;
- 	u8 tid;
- 
-@@ -4231,7 +4230,6 @@ static void ieee80211_8023_xmit(struct i
- 	info->control.flags |= IEEE80211_TX_CTRL_HW_80211_ENCAP;
- 	info->control.vif = &sdata->vif;
- 
--	key = rcu_dereference(sta->ptk[sta->ptk_idx]);
- 	if (key)
- 		info->control.hw_key = &key->conf;
- 
-@@ -4248,12 +4246,9 @@ netdev_tx_t ieee80211_subif_start_xmit_8
- {
- 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- 	struct ethhdr *ehdr = (struct ethhdr *)skb->data;
-+	struct ieee80211_key *key;
- 	struct sta_info *sta;
--
--	if (WARN_ON(!sdata->hw_80211_encap)) {
--		kfree_skb(skb);
--		return NETDEV_TX_OK;
--	}
-+	bool offload = true;
- 
- 	if (unlikely(skb->len < ETH_HLEN)) {
- 		kfree_skb(skb);
-@@ -4262,15 +4257,26 @@ netdev_tx_t ieee80211_subif_start_xmit_8
- 
- 	rcu_read_lock();
- 
--	if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
-+	if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) {
- 		kfree_skb(skb);
--	else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded ||
--			  !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
--			  sdata->control_port_protocol == ehdr->h_proto))
--		ieee80211_subif_start_xmit(skb, dev);
-+		goto out;
-+	}
-+
-+	if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded ||
-+	    !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
-+		sdata->control_port_protocol == ehdr->h_proto))
-+		offload = false;
-+	else if ((key = rcu_dereference(sta->ptk[sta->ptk_idx])) &&
-+		 (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) ||
-+		  key->conf.cipher == WLAN_CIPHER_SUITE_TKIP))
-+		offload = false;
-+
-+	if (offload)
-+		ieee80211_8023_xmit(sdata, dev, sta, key, skb);
- 	else
--		ieee80211_8023_xmit(sdata, dev, sta, skb);
-+		ieee80211_subif_start_xmit(skb, dev);
- 
-+out:
- 	rcu_read_unlock();
- 
- 	return NETDEV_TX_OK;
diff --git a/package/kernel/mac80211/patches/subsys/319-mac80211-reduce-duplication-in-tx-status-functions.patch b/package/kernel/mac80211/patches/subsys/319-mac80211-reduce-duplication-in-tx-status-functions.patch
deleted file mode 100644
index 83522a7541..0000000000
--- a/package/kernel/mac80211/patches/subsys/319-mac80211-reduce-duplication-in-tx-status-functions.patch
+++ /dev/null
@@ -1,197 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Mon, 17 Aug 2020 13:16:59 +0200
-Subject: [PATCH] mac80211: reduce duplication in tx status functions
-
-Move redundant functionality from __ieee80211_tx_status into
-ieee80211_tx_status_ext. Preparation for unifying with the 802.3 tx status
-codepath.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -184,18 +184,6 @@ static void ieee80211_frame_acked(struct
- 	struct ieee80211_mgmt *mgmt = (void *) skb->data;
- 	struct ieee80211_local *local = sta->local;
- 	struct ieee80211_sub_if_data *sdata = sta->sdata;
--	struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
--
--	if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
--		sta->status_stats.last_ack = jiffies;
--		if (txinfo->status.is_valid_ack_signal) {
--			sta->status_stats.last_ack_signal =
--					 (s8)txinfo->status.ack_signal;
--			sta->status_stats.ack_signal_filled = true;
--			ewma_avg_signal_add(&sta->status_stats.avg_ack_signal,
--					    -txinfo->status.ack_signal);
--		}
--	}
- 
- 	if (ieee80211_is_data_qos(mgmt->frame_control)) {
- 		struct ieee80211_hdr *hdr = (void *) skb->data;
-@@ -897,7 +885,8 @@ void ieee80211_tx_monitor(struct ieee802
- }
- 
- static void __ieee80211_tx_status(struct ieee80211_hw *hw,
--				  struct ieee80211_tx_status *status)
-+				  struct ieee80211_tx_status *status,
-+				  int rates_idx, int retry_count)
- {
- 	struct sk_buff *skb = status->skb;
- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-@@ -906,8 +895,6 @@ static void __ieee80211_tx_status(struct
- 	struct sta_info *sta;
- 	__le16 fc;
- 	struct ieee80211_supported_band *sband;
--	int retry_count;
--	int rates_idx;
- 	bool send_to_cooked;
- 	bool acked;
- 	bool noack_success;
-@@ -916,8 +903,6 @@ static void __ieee80211_tx_status(struct
- 	int tid = IEEE80211_NUM_TIDS;
- 	u16 tx_time_est;
- 
--	rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
--
- 	sband = local->hw.wiphy->bands[info->band];
- 	fc = hdr->frame_control;
- 
-@@ -994,24 +979,14 @@ static void __ieee80211_tx_status(struct
- 		if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
- 			ieee80211_handle_filtered_frame(local, sta, skb);
- 			return;
--		} else {
-+		} else if (ieee80211_is_data_present(fc)) {
- 			if (!acked && !noack_success)
--				sta->status_stats.retry_failed++;
--			sta->status_stats.retry_count += retry_count;
-+				sta->status_stats.msdu_failed[tid]++;
- 
--			if (ieee80211_is_data_present(fc)) {
--				if (!acked && !noack_success)
--					sta->status_stats.msdu_failed[tid]++;
--
--				sta->status_stats.msdu_retries[tid] +=
--					retry_count;
--			}
-+			sta->status_stats.msdu_retries[tid] +=
-+				retry_count;
- 		}
- 
--		rate_control_tx_status(local, sband, status);
--		if (ieee80211_vif_is_mesh(&sta->sdata->vif))
--			ieee80211s_update_metric(local, sta, status);
--
- 		if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked)
- 			ieee80211_frame_acked(sta, skb);
- 
-@@ -1036,20 +1011,6 @@ static void __ieee80211_tx_status(struct
- 							     true);
- 			ieee80211_info_set_tx_time_est(info, 0);
- 		}
--
--		if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
--			if (acked) {
--				if (sta->status_stats.lost_packets)
--					sta->status_stats.lost_packets = 0;
--
--				/* Track when last TDLS packet was ACKed */
--				sta->status_stats.last_pkt_time = jiffies;
--			} else if (noack_success) {
--				/* nothing to do here, do not account as lost */
--			} else {
--				ieee80211_lost_packet(sta, info);
--			}
--		}
- 	}
- 
- 	/* SNMP counters
-@@ -1133,7 +1094,7 @@ void ieee80211_tx_status(struct ieee8021
- 	if (sta)
- 		status.sta = &sta->sta;
- 
--	__ieee80211_tx_status(hw, &status);
-+	ieee80211_tx_status_ext(hw, &status);
- 	rcu_read_unlock();
- }
- EXPORT_SYMBOL(ieee80211_tx_status);
-@@ -1146,7 +1107,7 @@ void ieee80211_tx_status_ext(struct ieee
- 	struct ieee80211_sta *pubsta = status->sta;
- 	struct ieee80211_supported_band *sband;
- 	struct sta_info *sta;
--	int retry_count;
-+	int rates_idx, retry_count;
- 	bool acked, noack_success;
- 
- 	if (pubsta) {
-@@ -1156,13 +1117,7 @@ void ieee80211_tx_status_ext(struct ieee
- 			sta->tx_stats.last_rate_info = *status->rate;
- 	}
- 
--	if (status->skb)
--		return __ieee80211_tx_status(hw, status);
--
--	if (!status->sta)
--		return;
--
--	ieee80211_tx_get_rates(hw, info, &retry_count);
-+	rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
- 
- 	sband = hw->wiphy->bands[info->band];
- 
-@@ -1174,20 +1129,30 @@ void ieee80211_tx_status_ext(struct ieee
- 			sta->status_stats.retry_failed++;
- 		sta->status_stats.retry_count += retry_count;
- 
--		if (acked) {
--			sta->status_stats.last_ack = jiffies;
-+		if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
-+			if (acked) {
-+				sta->status_stats.last_ack = jiffies;
- 
--			if (sta->status_stats.lost_packets)
--				sta->status_stats.lost_packets = 0;
-+				if (sta->status_stats.lost_packets)
-+					sta->status_stats.lost_packets = 0;
- 
--			/* Track when last packet was ACKed */
--			sta->status_stats.last_pkt_time = jiffies;
--		} else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
--			return;
--		} else if (noack_success) {
--			/* nothing to do here, do not account as lost */
--		} else {
--			ieee80211_lost_packet(sta, info);
-+				/* Track when last packet was ACKed */
-+				sta->status_stats.last_pkt_time = jiffies;
-+
-+				if (info->status.is_valid_ack_signal) {
-+					sta->status_stats.last_ack_signal =
-+							 (s8)info->status.ack_signal;
-+					sta->status_stats.ack_signal_filled = true;
-+					ewma_avg_signal_add(&sta->status_stats.avg_ack_signal,
-+							    -info->status.ack_signal);
-+				}
-+			} else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
-+				return;
-+			} else if (noack_success) {
-+				/* nothing to do here, do not account as lost */
-+			} else {
-+				ieee80211_lost_packet(sta, info);
-+			}
- 		}
- 
- 		rate_control_tx_status(local, sband, status);
-@@ -1195,6 +1160,10 @@ void ieee80211_tx_status_ext(struct ieee
- 			ieee80211s_update_metric(local, sta, status);
- 	}
- 
-+	if (status->skb)
-+		return __ieee80211_tx_status(hw, status, rates_idx,
-+					     retry_count);
-+
- 	if (acked || noack_success) {
- 		I802_DEBUG_INC(local->dot11TransmittedFrameCount);
- 		if (!pubsta)
diff --git a/package/kernel/mac80211/patches/subsys/320-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch b/package/kernel/mac80211/patches/subsys/320-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch
deleted file mode 100644
index 9bd1765b16..0000000000
--- a/package/kernel/mac80211/patches/subsys/320-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Mon, 17 Aug 2020 13:29:12 +0200
-Subject: [PATCH] mac80211: remove tx status call to
- ieee80211_sta_register_airtime
-
-All drivers using airtime fairness are calling ieee80211_sta_register_airtime
-directly
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -995,12 +995,6 @@ 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 ((tx_time_est = ieee80211_info_get_tx_time_est(info)) > 0) {
- 			/* Do this here to avoid the expensive lookup of the sta
- 			 * in ieee80211_report_used_skb().
diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch b/package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch
deleted file mode 100644
index 48d7686863..0000000000
--- a/package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Mon, 17 Aug 2020 13:29:56 +0200
-Subject: [PATCH] mac80211: optimize station connection monitor
-
-Calling mod_timer for every rx/tx packet can be quite expensive.
-Instead of constantly updating the timer, we can simply let it run out
-and check the timestamp of the last ACK or rx packet to re-arm it.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -2047,8 +2047,6 @@ void ieee80211_dynamic_ps_timer(struct t
- void ieee80211_send_nullfunc(struct ieee80211_local *local,
- 			     struct ieee80211_sub_if_data *sdata,
- 			     bool powersave);
--void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
--			     struct ieee80211_hdr *hdr);
- void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
- 			     struct ieee80211_hdr *hdr, bool ack, u16 tx_time);
- 
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -2432,23 +2432,6 @@ static void ieee80211_set_disassoc(struc
- 	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
- }
- 
--void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
--			     struct ieee80211_hdr *hdr)
--{
--	/*
--	 * We can postpone the mgd.timer whenever receiving unicast frames
--	 * from AP because we know that the connection is working both ways
--	 * at that time. But multicast frames (and hence also beacons) must
--	 * be ignored here, because we need to trigger the timer during
--	 * data idle periods for sending the periodic probe request to the
--	 * AP we're connected to.
--	 */
--	if (is_multicast_ether_addr(hdr->addr1))
--		return;
--
--	ieee80211_sta_reset_conn_monitor(sdata);
--}
--
- static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
- {
- 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-@@ -2521,21 +2504,13 @@ void ieee80211_sta_tx_notify(struct ieee
- {
- 	ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time);
- 
--	if (!ieee80211_is_data(hdr->frame_control))
--	    return;
--
--	if (ieee80211_is_any_nullfunc(hdr->frame_control) &&
--	    sdata->u.mgd.probe_send_count > 0) {
--		if (ack)
--			ieee80211_sta_reset_conn_monitor(sdata);
--		else
--			sdata->u.mgd.nullfunc_failed = true;
--		ieee80211_queue_work(&sdata->local->hw, &sdata->work);
-+	if (!ieee80211_is_any_nullfunc(hdr->frame_control) ||
-+	    !sdata->u.mgd.probe_send_count)
- 		return;
--	}
- 
--	if (ack)
--		ieee80211_sta_reset_conn_monitor(sdata);
-+	if (!ack)
-+		sdata->u.mgd.nullfunc_failed = true;
-+	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
- }
- 
- static void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata,
-@@ -3605,8 +3580,8 @@ static bool ieee80211_assoc_success(stru
- 	 * Start timer to probe the connection to the AP now.
- 	 * Also start the timer that will detect beacon loss.
- 	 */
--	ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
- 	ieee80211_sta_reset_beacon_monitor(sdata);
-+	ieee80211_sta_reset_conn_monitor(sdata);
- 
- 	ret = true;
-  out:
-@@ -4577,10 +4552,26 @@ static void ieee80211_sta_conn_mon_timer
- 		from_timer(sdata, t, u.mgd.conn_mon_timer);
- 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- 	struct ieee80211_local *local = sdata->local;
-+	struct sta_info *sta;
-+	unsigned long timeout;
- 
- 	if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
- 		return;
- 
-+	sta = sta_info_get(sdata, ifmgd->bssid);
-+	if (!sta)
-+		return;
-+
-+	timeout = sta->status_stats.last_ack;
-+	if (time_before(sta->status_stats.last_ack, sta->rx_stats.last_rx))
-+		timeout = sta->rx_stats.last_rx;
-+	timeout += IEEE80211_CONNECTION_IDLE_TIME;
-+
-+	if (time_is_before_jiffies(timeout)) {
-+		mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout));
-+		return;
-+	}
-+
- 	ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
- }
- 
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1812,9 +1812,6 @@ ieee80211_rx_h_sta_process(struct ieee80
- 			sta->rx_stats.last_rate = sta_stats_encode_rate(status);
- 	}
- 
--	if (rx->sdata->vif.type == NL80211_IFTYPE_STATION)
--		ieee80211_sta_rx_notify(rx->sdata, hdr);
--
- 	sta->rx_stats.fragments++;
- 
- 	u64_stats_update_begin(&rx->sta->rx_stats.syncp);
-@@ -4153,7 +4150,6 @@ void ieee80211_check_fast_rx(struct sta_
- 			fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
- 			fastrx.expected_ds_bits = 0;
- 		} else {
--			fastrx.sta_notify = sdata->u.mgd.probe_send_count > 0;
- 			fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
- 			fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr3);
- 			fastrx.expected_ds_bits =
-@@ -4383,11 +4379,6 @@ static bool ieee80211_invoke_fast_rx(str
- 	    pskb_trim(skb, skb->len - fast_rx->icv_len))
- 		goto drop;
- 
--	if (unlikely(fast_rx->sta_notify)) {
--		ieee80211_sta_rx_notify(rx->sdata, hdr);
--		fast_rx->sta_notify = false;
--	}
--
- 	/* statistics part of ieee80211_rx_h_sta_process() */
- 	if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
- 		stats->last_signal = status->signal;
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -336,7 +336,6 @@ struct ieee80211_fast_tx {
-  * @expected_ds_bits: from/to DS bits expected
-  * @icv_len: length of the MIC if present
-  * @key: bool indicating encryption is expected (key is set)
-- * @sta_notify: notify the MLME code (once)
-  * @internal_forward: forward froms internally on AP/VLAN type interfaces
-  * @uses_rss: copy of USES_RSS hw flag
-  * @da_offs: offset of the DA in the header (for header conversion)
-@@ -352,7 +351,6 @@ struct ieee80211_fast_rx {
- 	__le16 expected_ds_bits;
- 	u8 icv_len;
- 	u8 key:1,
--	   sta_notify:1,
- 	   internal_forward:1,
- 	   uses_rss:1;
- 	u8 da_offs, sa_offs;
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -1225,9 +1225,6 @@ void ieee80211_tx_status_8023(struct iee
- 	sta->status_stats.retry_count += retry_count;
- 
- 	if (ieee80211_hw_check(hw, REPORTS_TX_ACK_STATUS)) {
--		if (acked && vif->type == NL80211_IFTYPE_STATION)
--			ieee80211_sta_reset_conn_monitor(sdata);
--
- 		sta->status_stats.last_ack = jiffies;
- 		if (info->flags & IEEE80211_TX_STAT_ACK) {
- 			if (sta->status_stats.lost_packets)
diff --git a/package/kernel/mac80211/patches/subsys/322-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch b/package/kernel/mac80211/patches/subsys/322-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch
deleted file mode 100644
index d62621ca77..0000000000
--- a/package/kernel/mac80211/patches/subsys/322-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Mon, 17 Aug 2020 13:35:32 +0200
-Subject: [PATCH] mac80211: swap NEED_TXPROCESSING and HW_80211_ENCAP tx
- flags
-
-In order to unify the tx status path, the hw 802.11 encapsulation flag
-needs to survive the trip to the tx status call.
-Since we don't have any free bits in info->flags, we need to move one.
-IEEE80211_TX_INTFL_NEED_TXPROCESSING is only used internally in mac80211,
-and only before the call into the driver.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath11k/dp_tx.c
-+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
-@@ -14,7 +14,7 @@ ath11k_dp_tx_get_encap_type(struct ath11
- {
- 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- 
--	if (tx_info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)
-+	if (tx_info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
- 		return HAL_TCL_ENCAP_TYPE_ETHERNET;
- 
- 	return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI;
-@@ -93,7 +93,7 @@ int ath11k_dp_tx(struct ath11k *ar, stru
- 	if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
- 		return -ESHUTDOWN;
- 
--	if (!(info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP) &&
-+	if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
- 	    !ieee80211_is_data(hdr->frame_control))
- 		return -ENOTSUPP;
- 
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -3898,7 +3898,7 @@ static int ath11k_mac_mgmt_tx_wmi(struct
- 		return -ENOSPC;
- 
- 	info = IEEE80211_SKB_CB(skb);
--	if (!(info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)) {
-+	if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
- 		if ((ieee80211_is_action(hdr->frame_control) ||
- 		     ieee80211_is_deauth(hdr->frame_control) ||
- 		     ieee80211_is_disassoc(hdr->frame_control)) &&
-@@ -4025,7 +4025,7 @@ static void ath11k_mac_op_tx(struct ieee
- 	bool is_prb_rsp;
- 	int ret;
- 
--	if (info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP) {
-+	if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
- 		skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP;
- 	} else if (ieee80211_is_mgmt(hdr->frame_control)) {
- 		is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -720,9 +720,8 @@ struct ieee80211_bss_conf {
-  * @IEEE80211_TX_INTFL_OFFCHAN_TX_OK: Internal to mac80211. Used to indicate
-  *	that a frame can be transmitted while the queues are stopped for
-  *	off-channel operation.
-- * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211,
-- *	used to indicate that a pending frame requires TX processing before
-- *	it can be sent out.
-+ * @IEEE80211_TX_CTL_HW_80211_ENCAP: This frame uses hardware encapsulation
-+ *	(header conversion)
-  * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211,
-  *	used to indicate that a frame was already retried due to PS
-  * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
-@@ -791,7 +790,7 @@ enum mac80211_tx_info_flags {
- 	IEEE80211_TX_STAT_AMPDU_NO_BACK		= BIT(11),
- 	IEEE80211_TX_CTL_RATE_CTRL_PROBE	= BIT(12),
- 	IEEE80211_TX_INTFL_OFFCHAN_TX_OK	= BIT(13),
--	IEEE80211_TX_INTFL_NEED_TXPROCESSING	= BIT(14),
-+	IEEE80211_TX_CTL_HW_80211_ENCAP		= BIT(14),
- 	IEEE80211_TX_INTFL_RETRIED		= BIT(15),
- 	IEEE80211_TX_INTFL_DONT_ENCRYPT		= BIT(16),
- 	IEEE80211_TX_CTL_NO_PS_BUFFER		= BIT(17),
-@@ -823,8 +822,9 @@ enum mac80211_tx_info_flags {
-  * @IEEE80211_TX_CTRL_AMSDU: This frame is an A-MSDU frame
-  * @IEEE80211_TX_CTRL_FAST_XMIT: This frame is going through the fast_xmit path
-  * @IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP: This frame skips mesh path lookup
-- * @IEEE80211_TX_CTRL_HW_80211_ENCAP: This frame uses hardware encapsulation
-- *	(header conversion)
-+ * @IEEE80211_TX_INTCFL_NEED_TXPROCESSING: completely internal to mac80211,
-+ *	used to indicate that a pending frame requires TX processing before
-+ *	it can be sent out.
-  * @IEEE80211_TX_CTRL_NO_SEQNO: Do not overwrite the sequence number that
-  *	has already been assigned to this frame.
-  *
-@@ -837,7 +837,7 @@ enum mac80211_tx_control_flags {
- 	IEEE80211_TX_CTRL_AMSDU			= BIT(3),
- 	IEEE80211_TX_CTRL_FAST_XMIT		= BIT(4),
- 	IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP	= BIT(5),
--	IEEE80211_TX_CTRL_HW_80211_ENCAP	= BIT(6),
-+	IEEE80211_TX_INTCFL_NEED_TXPROCESSING	= BIT(6),
- 	IEEE80211_TX_CTRL_NO_SEQNO		= BIT(7),
- };
- 
---- a/net/mac80211/mesh_hwmp.c
-+++ b/net/mac80211/mesh_hwmp.c
-@@ -212,7 +212,7 @@ static void prepare_frame_for_deferred_t
- 	skb->priority = 7;
- 
- 	info->control.vif = &sdata->vif;
--	info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-+	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- 	ieee80211_set_qos_hdr(sdata, skb);
- 	ieee80211_mps_set_frame_flags(sdata, NULL, hdr);
- }
-@@ -1163,7 +1163,7 @@ int mesh_nexthop_resolve(struct ieee8021
- 	if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN)
- 		skb_to_free = skb_dequeue(&mpath->frame_queue);
- 
--	info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-+	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- 	ieee80211_set_qos_hdr(sdata, skb);
- 	skb_queue_tail(&mpath->frame_queue, skb);
- 	if (skb_to_free)
---- a/net/mac80211/mesh_ps.c
-+++ b/net/mac80211/mesh_ps.c
-@@ -432,7 +432,7 @@ static void mpsp_qos_null_append(struct
- 
- 	info = IEEE80211_SKB_CB(new_skb);
- 	info->control.vif = &sdata->vif;
--	info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-+	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- 
- 	__skb_queue_tail(frames, new_skb);
- }
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2901,7 +2901,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
- 	fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
- 	info = IEEE80211_SKB_CB(fwd_skb);
- 	memset(info, 0, sizeof(*info));
--	info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-+	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- 	info->control.vif = &rx->sdata->vif;
- 	info->control.jiffies = jiffies;
- 	if (is_multicast_ether_addr(fwd_hdr->addr1)) {
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -66,8 +66,8 @@ static void ieee80211_handle_filtered_fr
- 
- 	info->control.jiffies = jiffies;
- 	info->control.vif = &sta->sdata->vif;
--	info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING |
--		       IEEE80211_TX_INTFL_RETRANSMISSION;
-+	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
-+	info->flags |= IEEE80211_TX_INTFL_RETRANSMISSION;
- 	info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
- 
- 	sta->status_stats.filtered++;
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -531,7 +531,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- 
- 		info->control.jiffies = jiffies;
- 		info->control.vif = &tx->sdata->vif;
--		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-+		info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- 		info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
- 		skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
- 		spin_unlock(&sta->ps_lock);
-@@ -1134,7 +1134,7 @@ static bool ieee80211_tx_prep_agg(struct
- 				       tx->sta->sta.addr, tx->sta->sta.aid);
- 			}
- 			info->control.vif = &tx->sdata->vif;
--			info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-+			info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- 			info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
- 			__skb_queue_tail(&tid_tx->pending, skb);
- 			if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER)
-@@ -1179,7 +1179,7 @@ ieee80211_tx_prepare(struct ieee80211_su
- 	 * we are doing the needed processing, so remove the flag
- 	 * now.
- 	 */
--	info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-+	info->control.flags &= ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- 
- 	hdr = (struct ieee80211_hdr *) skb->data;
- 
-@@ -1258,7 +1258,7 @@ static struct txq_info *ieee80211_get_tx
- 	    (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
- 		return NULL;
- 
--	if (!(info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP) &&
-+	if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
- 	    unlikely(!ieee80211_is_data_present(hdr->frame_control))) {
- 		if ((!ieee80211_is_mgmt(hdr->frame_control) ||
- 		     ieee80211_is_bufferable_mmpdu(hdr->frame_control) ||
-@@ -3637,7 +3637,7 @@ begin:
- 	else
- 		info->flags &= ~IEEE80211_TX_CTL_AMPDU;
- 
--	if (info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)
-+	if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
- 		goto encap_out;
- 
- 	if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
-@@ -4227,7 +4227,7 @@ static void ieee80211_8023_xmit(struct i
- 		sdata = container_of(sdata->bss,
- 				     struct ieee80211_sub_if_data, u.ap);
- 
--	info->control.flags |= IEEE80211_TX_CTRL_HW_80211_ENCAP;
-+	info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP;
- 	info->control.vif = &sdata->vif;
- 
- 	if (key)
-@@ -4352,7 +4352,7 @@ static bool ieee80211_tx_pending_skb(str
- 
- 	sdata = vif_to_sdata(info->control.vif);
- 
--	if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) {
-+	if (info->control.flags & IEEE80211_TX_INTCFL_NEED_TXPROCESSING) {
- 		chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
- 		if (unlikely(!chanctx_conf)) {
- 			dev_kfree_skb(skb);
-@@ -4360,7 +4360,7 @@ static bool ieee80211_tx_pending_skb(str
- 		}
- 		info->band = chanctx_conf->def.chan->band;
- 		result = ieee80211_tx(sdata, NULL, skb, true);
--	} else if (info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP) {
-+	} else if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
- 		if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) {
- 			dev_kfree_skb(skb);
- 			return true;
diff --git a/package/kernel/mac80211/patches/subsys/323-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch b/package/kernel/mac80211/patches/subsys/323-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch
deleted file mode 100644
index 62bb917184..0000000000
--- a/package/kernel/mac80211/patches/subsys/323-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch
+++ /dev/null
@@ -1,159 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Mon, 17 Aug 2020 13:54:19 +0200
-Subject: [PATCH] mac80211: unify 802.3 (offload) and 802.11 tx status
- codepath
-
-Make ieee80211_tx_status_8023 call ieee80211_tx_status_ext, similar to
-ieee80211_tx_status.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -901,7 +901,6 @@ static void __ieee80211_tx_status(struct
- 	struct ieee80211_bar *bar;
- 	int shift = 0;
- 	int tid = IEEE80211_NUM_TIDS;
--	u16 tx_time_est;
- 
- 	sband = local->hw.wiphy->bands[info->band];
- 	fc = hdr->frame_control;
-@@ -994,17 +993,6 @@ static void __ieee80211_tx_status(struct
- 		    ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
- 			ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
- 						acked, info->status.tx_time);
--
--		if ((tx_time_est = ieee80211_info_get_tx_time_est(info)) > 0) {
--			/* Do this here to avoid the expensive lookup of the sta
--			 * in ieee80211_report_used_skb().
--			 */
--			ieee80211_sta_update_pending_airtime(local, sta,
--							     skb_get_queue_mapping(skb),
--							     tx_time_est,
--							     true);
--			ieee80211_info_set_tx_time_est(info, 0);
--		}
- 	}
- 
- 	/* SNMP counters
-@@ -1100,9 +1088,11 @@ void ieee80211_tx_status_ext(struct ieee
- 	struct ieee80211_tx_info *info = status->info;
- 	struct ieee80211_sta *pubsta = status->sta;
- 	struct ieee80211_supported_band *sband;
--	struct sta_info *sta;
-+	struct sk_buff *skb = status->skb;
-+	struct sta_info *sta = NULL;
- 	int rates_idx, retry_count;
- 	bool acked, noack_success;
-+	u16 tx_time_est;
- 
- 	if (pubsta) {
- 		sta = container_of(pubsta, struct sta_info, sta);
-@@ -1154,7 +1144,18 @@ void ieee80211_tx_status_ext(struct ieee
- 			ieee80211s_update_metric(local, sta, status);
- 	}
- 
--	if (status->skb)
-+	if (skb && (tx_time_est = ieee80211_info_get_tx_time_est(info)) > 0) {
-+		/* Do this here to avoid the expensive lookup of the sta
-+		 * in ieee80211_report_used_skb().
-+		 */
-+		ieee80211_sta_update_pending_airtime(local, sta,
-+						     skb_get_queue_mapping(skb),
-+						     tx_time_est,
-+						     true);
-+		ieee80211_info_set_tx_time_est(info, 0);
-+	}
-+
-+	if (skb && !(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
- 		return __ieee80211_tx_status(hw, status, rates_idx,
- 					     retry_count);
- 
-@@ -1169,6 +1170,12 @@ void ieee80211_tx_status_ext(struct ieee
- 	} else {
- 		I802_DEBUG_INC(local->dot11FailedCount);
- 	}
-+
-+	if (!skb)
-+		return;
-+
-+	ieee80211_report_used_skb(local, skb, false);
-+	dev_kfree_skb(skb);
- }
- EXPORT_SYMBOL(ieee80211_tx_status_ext);
- 
-@@ -1195,66 +1202,23 @@ void ieee80211_tx_status_8023(struct iee
- 			      struct ieee80211_vif *vif,
- 			      struct sk_buff *skb)
- {
--	struct ieee80211_local *local = hw_to_local(hw);
- 	struct ieee80211_sub_if_data *sdata;
--	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+	struct ieee80211_tx_status status = {
-+		.skb = skb,
-+		.info = IEEE80211_SKB_CB(skb),
-+	};
- 	struct sta_info *sta;
--	int retry_count;
--	int rates_idx;
--	bool acked;
- 
- 	sdata = vif_to_sdata(vif);
- 
--	acked = info->flags & IEEE80211_TX_STAT_ACK;
--	rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
--
- 	rcu_read_lock();
- 
--	if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
--		goto counters_update;
--
--	if (IS_ERR(sta))
--		goto counters_update;
--
--	if (!acked)
--		sta->status_stats.retry_failed++;
--
--	if (rates_idx != -1)
--		sta->tx_stats.last_rate = info->status.rates[rates_idx];
--
--	sta->status_stats.retry_count += retry_count;
--
--	if (ieee80211_hw_check(hw, REPORTS_TX_ACK_STATUS)) {
--		sta->status_stats.last_ack = jiffies;
--		if (info->flags & IEEE80211_TX_STAT_ACK) {
--			if (sta->status_stats.lost_packets)
--				sta->status_stats.lost_packets = 0;
-+	if (!ieee80211_lookup_ra_sta(sdata, skb, &sta) && !IS_ERR(sta))
-+		status.sta = &sta->sta;
- 
--			sta->status_stats.last_pkt_time = jiffies;
--		} else {
--			ieee80211_lost_packet(sta, info);
--		}
--	}
-+	ieee80211_tx_status_ext(hw, &status);
- 
--counters_update:
- 	rcu_read_unlock();
--	ieee80211_led_tx(local);
--
--	if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
--	    !(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED))
--		goto skip_stats_update;
--
--	I802_DEBUG_INC(local->dot11TransmittedFrameCount);
--	if (is_multicast_ether_addr(skb->data))
--		I802_DEBUG_INC(local->dot11MulticastTransmittedFrameCount);
--	if (retry_count > 0)
--		I802_DEBUG_INC(local->dot11RetryCount);
--	if (retry_count > 1)
--		I802_DEBUG_INC(local->dot11MultipleRetryCount);
--
--skip_stats_update:
--	ieee80211_report_used_skb(local, skb, false);
--	dev_kfree_skb(skb);
- }
- EXPORT_SYMBOL(ieee80211_tx_status_8023);
- 
diff --git a/package/kernel/mac80211/patches/subsys/324-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch b/package/kernel/mac80211/patches/subsys/324-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch
deleted file mode 100644
index ffb89a4d4a..0000000000
--- a/package/kernel/mac80211/patches/subsys/324-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Thu, 20 Aug 2020 17:27:00 +0200
-Subject: [PATCH] mac80211: support using ieee80211_tx_status_ext to free
- skbs without status info
-
-For encap-offloaded packets, ieee80211_free_txskb cannot be used, since it
-does not have the vif pointer.
-Using ieee80211_tx_status_ext for this purpose has the advantage of being able
-avoid an extra station lookup for AQL
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -1101,6 +1101,21 @@ void ieee80211_tx_status_ext(struct ieee
- 			sta->tx_stats.last_rate_info = *status->rate;
- 	}
- 
-+	if (skb && (tx_time_est =
-+		    ieee80211_info_get_tx_time_est(IEEE80211_SKB_CB(skb))) > 0) {
-+		/* Do this here to avoid the expensive lookup of the sta
-+		 * in ieee80211_report_used_skb().
-+		 */
-+		ieee80211_sta_update_pending_airtime(local, sta,
-+						     skb_get_queue_mapping(skb),
-+						     tx_time_est,
-+						     true);
-+		ieee80211_info_set_tx_time_est(IEEE80211_SKB_CB(skb), 0);
-+	}
-+
-+	if (!status->info)
-+		goto free;
-+
- 	rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
- 
- 	sband = hw->wiphy->bands[info->band];
-@@ -1144,17 +1159,6 @@ void ieee80211_tx_status_ext(struct ieee
- 			ieee80211s_update_metric(local, sta, status);
- 	}
- 
--	if (skb && (tx_time_est = ieee80211_info_get_tx_time_est(info)) > 0) {
--		/* Do this here to avoid the expensive lookup of the sta
--		 * in ieee80211_report_used_skb().
--		 */
--		ieee80211_sta_update_pending_airtime(local, sta,
--						     skb_get_queue_mapping(skb),
--						     tx_time_est,
--						     true);
--		ieee80211_info_set_tx_time_est(info, 0);
--	}
--
- 	if (skb && !(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
- 		return __ieee80211_tx_status(hw, status, rates_idx,
- 					     retry_count);
-@@ -1171,6 +1175,7 @@ void ieee80211_tx_status_ext(struct ieee
- 		I802_DEBUG_INC(local->dot11FailedCount);
- 	}
- 
-+free:
- 	if (!skb)
- 		return;
- 
diff --git a/package/kernel/mac80211/patches/subsys/325-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch b/package/kernel/mac80211/patches/subsys/325-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch
deleted file mode 100644
index b5dcb0b013..0000000000
--- a/package/kernel/mac80211/patches/subsys/325-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Fri, 21 Aug 2020 05:49:07 +0200
-Subject: [PATCH] mac80211: extend ieee80211_tx_status_ext to support
- bulk free
-
-Store processed skbs ready to be freed in a list so the driver bulk free them
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1095,12 +1095,14 @@ ieee80211_info_get_tx_time_est(struct ie
-  * @info: Basic tx status information
-  * @skb: Packet skb (can be NULL if not provided by the driver)
-  * @rate: The TX rate that was used when sending the packet
-+ * @free_list: list where processed skbs are stored to be free'd by the driver
-  */
- struct ieee80211_tx_status {
- 	struct ieee80211_sta *sta;
- 	struct ieee80211_tx_info *info;
- 	struct sk_buff *skb;
- 	struct rate_info *rate;
-+	struct list_head *free_list;
- };
- 
- /**
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -1051,7 +1051,10 @@ static void __ieee80211_tx_status(struct
- 	 * with this test...
- 	 */
- 	if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
--		dev_kfree_skb(skb);
-+		if (status->free_list)
-+			list_add_tail(&skb->list, status->free_list);
-+		else
-+			dev_kfree_skb(skb);
- 		return;
- 	}
- 
-@@ -1180,7 +1183,10 @@ free:
- 		return;
- 
- 	ieee80211_report_used_skb(local, skb, false);
--	dev_kfree_skb(skb);
-+	if (status->free_list)
-+		list_add_tail(&skb->list, status->free_list);
-+	else
-+		dev_kfree_skb(skb);
- }
- EXPORT_SYMBOL(ieee80211_tx_status_ext);
- 
diff --git a/package/kernel/mac80211/patches/subsys/326-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch b/package/kernel/mac80211/patches/subsys/326-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch
deleted file mode 100644
index f38afc7912..0000000000
--- a/package/kernel/mac80211/patches/subsys/326-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Fri, 21 Aug 2020 05:51:58 +0200
-Subject: [PATCH] mac80211: notify the driver when a sta uses 4-address
- mode
-
-This is needed for encapsulation offload of 4-address mode packets
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -3843,6 +3843,8 @@ enum ieee80211_reconfig_type {
-  *	This callback may sleep.
-  * @update_vif_config: Update virtual interface offload flags
-  *	This callback may sleep.
-+ * @sta_set_4addr: Called to notify the driver when a station starts/stops using
-+ *	4-address mode
-  */
- struct ieee80211_ops {
- 	void (*tx)(struct ieee80211_hw *hw,
-@@ -4156,6 +4158,8 @@ struct ieee80211_ops {
- 				struct ieee80211_sta *sta, u8 tids);
- 	void (*update_vif_offload)(struct ieee80211_hw *hw,
- 				   struct ieee80211_vif *vif);
-+	void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+			      struct ieee80211_sta *sta, bool enabled);
- };
- 
- /**
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1696,6 +1696,7 @@ static int ieee80211_change_station(stru
- 
- 			rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
- 			__ieee80211_check_fast_rx_iface(vlansdata);
-+			drv_sta_set_4addr(local, sta->sdata, &sta->sta, true);
- 		}
- 
- 		if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -1399,4 +1399,18 @@ static inline void drv_update_vif_offloa
- 	trace_drv_return_void(local);
- }
- 
-+static inline void drv_sta_set_4addr(struct ieee80211_local *local,
-+				     struct ieee80211_sub_if_data *sdata,
-+				     struct ieee80211_sta *sta, bool enabled)
-+{
-+	sdata = get_bss_sdata(sdata);
-+	if (!check_sdata_in_driver(sdata))
-+		return;
-+
-+	trace_drv_sta_set_4addr(local, sdata, sta, enabled);
-+	if (local->ops->sta_set_4addr)
-+		local->ops->sta_set_4addr(&local->hw, &sdata->vif, sta, enabled);
-+	trace_drv_return_void(local);
-+}
-+
- #endif /* __MAC80211_DRIVER_OPS */
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -3523,6 +3523,9 @@ static bool ieee80211_assoc_success(stru
- 		goto out;
- 	}
- 
-+	if (sdata->wdev.use_4addr)
-+		drv_sta_set_4addr(local, sdata, &sta->sta, true);
-+
- 	mutex_unlock(&sdata->local->sta_mtx);
- 
- 	/*
---- a/net/mac80211/trace.h
-+++ b/net/mac80211/trace.h
-@@ -2740,6 +2740,33 @@ DEFINE_EVENT(local_sdata_addr_evt, drv_u
- 	TP_ARGS(local, sdata)
- );
- 
-+TRACE_EVENT(drv_sta_set_4addr,
-+	TP_PROTO(struct ieee80211_local *local,
-+		 struct ieee80211_sub_if_data *sdata,
-+		 struct ieee80211_sta *sta, bool enabled),
-+
-+	TP_ARGS(local, sdata, sta, enabled),
-+
-+	TP_STRUCT__entry(
-+		LOCAL_ENTRY
-+		VIF_ENTRY
-+		STA_ENTRY
-+		__field(bool, enabled)
-+	),
-+
-+	TP_fast_assign(
-+		LOCAL_ASSIGN;
-+		VIF_ASSIGN;
-+		STA_ASSIGN;
-+		__entry->enabled = enabled;
-+	),
-+
-+	TP_printk(
-+		LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " enabled:%d",
-+		LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->enabled
-+	)
-+);
-+
- #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
- 
- #undef TRACE_INCLUDE_PATH
diff --git a/package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch b/package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch
deleted file mode 100644
index 0bfb10cdb0..0000000000
--- a/package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch
+++ /dev/null
@@ -1,1124 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Tue, 8 Sep 2020 12:16:26 +0200
-Subject: [PATCH] mac80211: reorganize code to remove a forward
- declaration
-
-Remove the newly added ieee80211_set_vif_encap_ops declaration.
-No further code changes
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -43,7 +43,6 @@
-  */
- 
- static void ieee80211_iface_work(struct work_struct *work);
--static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata);
- 
- bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
- {
-@@ -349,6 +348,518 @@ static int ieee80211_check_queues(struct
- 	return 0;
- }
- 
-+static int ieee80211_open(struct net_device *dev)
-+{
-+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	int err;
-+
-+	/* fail early if user set an invalid address */
-+	if (!is_valid_ether_addr(dev->dev_addr))
-+		return -EADDRNOTAVAIL;
-+
-+	err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type);
-+	if (err)
-+		return err;
-+
-+	return ieee80211_do_open(&sdata->wdev, true);
-+}
-+
-+static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
-+			      bool going_down)
-+{
-+	struct ieee80211_local *local = sdata->local;
-+	unsigned long flags;
-+	struct sk_buff *skb, *tmp;
-+	u32 hw_reconf_flags = 0;
-+	int i, flushed;
-+	struct ps_data *ps;
-+	struct cfg80211_chan_def chandef;
-+	bool cancel_scan;
-+	struct cfg80211_nan_func *func;
-+
-+	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
-+
-+	cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata;
-+	if (cancel_scan)
-+		ieee80211_scan_cancel(local);
-+
-+	/*
-+	 * Stop TX on this interface first.
-+	 */
-+	if (sdata->dev)
-+		netif_tx_stop_all_queues(sdata->dev);
-+
-+	ieee80211_roc_purge(local, sdata);
-+
-+	switch (sdata->vif.type) {
-+	case NL80211_IFTYPE_STATION:
-+		ieee80211_mgd_stop(sdata);
-+		break;
-+	case NL80211_IFTYPE_ADHOC:
-+		ieee80211_ibss_stop(sdata);
-+		break;
-+	case NL80211_IFTYPE_MONITOR:
-+		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
-+			break;
-+		list_del_rcu(&sdata->u.mntr.list);
-+		break;
-+	default:
-+		break;
-+	}
-+
-+	/*
-+	 * Remove all stations associated with this interface.
-+	 *
-+	 * This must be done before calling ops->remove_interface()
-+	 * because otherwise we can later invoke ops->sta_notify()
-+	 * whenever the STAs are removed, and that invalidates driver
-+	 * assumptions about always getting a vif pointer that is valid
-+	 * (because if we remove a STA after ops->remove_interface()
-+	 * the driver will have removed the vif info already!)
-+	 *
-+	 * In WDS mode a station must exist here and be flushed, for
-+	 * AP_VLANs stations may exist since there's nothing else that
-+	 * would have removed them, but in other modes there shouldn't
-+	 * be any stations.
-+	 */
-+	flushed = sta_info_flush(sdata);
-+	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
-+		     ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
-+		      (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)));
-+
-+	/* don't count this interface for allmulti while it is down */
-+	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
-+		atomic_dec(&local->iff_allmultis);
-+
-+	if (sdata->vif.type == NL80211_IFTYPE_AP) {
-+		local->fif_pspoll--;
-+		local->fif_probe_req--;
-+	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
-+		local->fif_probe_req--;
-+	}
-+
-+	if (sdata->dev) {
-+		netif_addr_lock_bh(sdata->dev);
-+		spin_lock_bh(&local->filter_lock);
-+		__hw_addr_unsync(&local->mc_list, &sdata->dev->mc,
-+				 sdata->dev->addr_len);
-+		spin_unlock_bh(&local->filter_lock);
-+		netif_addr_unlock_bh(sdata->dev);
-+	}
-+
-+	del_timer_sync(&local->dynamic_ps_timer);
-+	cancel_work_sync(&local->dynamic_ps_enable_work);
-+
-+	cancel_work_sync(&sdata->recalc_smps);
-+	sdata_lock(sdata);
-+	mutex_lock(&local->mtx);
-+	sdata->vif.csa_active = false;
-+	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-+		sdata->u.mgd.csa_waiting_bcn = false;
-+	if (sdata->csa_block_tx) {
-+		ieee80211_wake_vif_queues(local, sdata,
-+					  IEEE80211_QUEUE_STOP_REASON_CSA);
-+		sdata->csa_block_tx = false;
-+	}
-+	mutex_unlock(&local->mtx);
-+	sdata_unlock(sdata);
-+
-+	cancel_work_sync(&sdata->csa_finalize_work);
-+
-+	cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
-+
-+	if (sdata->wdev.cac_started) {
-+		chandef = sdata->vif.bss_conf.chandef;
-+		WARN_ON(local->suspended);
-+		mutex_lock(&local->mtx);
-+		ieee80211_vif_release_channel(sdata);
-+		mutex_unlock(&local->mtx);
-+		cfg80211_cac_event(sdata->dev, &chandef,
-+				   NL80211_RADAR_CAC_ABORTED,
-+				   GFP_KERNEL);
-+	}
-+
-+	/* APs need special treatment */
-+	if (sdata->vif.type == NL80211_IFTYPE_AP) {
-+		struct ieee80211_sub_if_data *vlan, *tmpsdata;
-+
-+		/* down all dependent devices, that is VLANs */
-+		list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
-+					 u.vlan.list)
-+			dev_close(vlan->dev);
-+		WARN_ON(!list_empty(&sdata->u.ap.vlans));
-+	} else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
-+		/* remove all packets in parent bc_buf pointing to this dev */
-+		ps = &sdata->bss->ps;
-+
-+		spin_lock_irqsave(&ps->bc_buf.lock, flags);
-+		skb_queue_walk_safe(&ps->bc_buf, skb, tmp) {
-+			if (skb->dev == sdata->dev) {
-+				__skb_unlink(skb, &ps->bc_buf);
-+				local->total_ps_buffered--;
-+				ieee80211_free_txskb(&local->hw, skb);
-+			}
-+		}
-+		spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
-+	}
-+
-+	if (going_down)
-+		local->open_count--;
-+
-+	switch (sdata->vif.type) {
-+	case NL80211_IFTYPE_AP_VLAN:
-+		mutex_lock(&local->mtx);
-+		list_del(&sdata->u.vlan.list);
-+		mutex_unlock(&local->mtx);
-+		RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL);
-+		/* see comment in the default case below */
-+		ieee80211_free_keys(sdata, true);
-+		/* no need to tell driver */
-+		break;
-+	case NL80211_IFTYPE_MONITOR:
-+		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
-+			local->cooked_mntrs--;
-+			break;
-+		}
-+
-+		local->monitors--;
-+		if (local->monitors == 0) {
-+			local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
-+			hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
-+		}
-+
-+		ieee80211_adjust_monitor_flags(sdata, -1);
-+		break;
-+	case NL80211_IFTYPE_NAN:
-+		/* clean all the functions */
-+		spin_lock_bh(&sdata->u.nan.func_lock);
-+
-+		idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) {
-+			idr_remove(&sdata->u.nan.function_inst_ids, i);
-+			cfg80211_free_nan_func(func);
-+		}
-+		idr_destroy(&sdata->u.nan.function_inst_ids);
-+
-+		spin_unlock_bh(&sdata->u.nan.func_lock);
-+		break;
-+	case NL80211_IFTYPE_P2P_DEVICE:
-+		/* relies on synchronize_rcu() below */
-+		RCU_INIT_POINTER(local->p2p_sdata, NULL);
-+		fallthrough;
-+	default:
-+		cancel_work_sync(&sdata->work);
-+		/*
-+		 * When we get here, the interface is marked down.
-+		 * Free the remaining keys, if there are any
-+		 * (which can happen in AP mode if userspace sets
-+		 * keys before the interface is operating, and maybe
-+		 * also in WDS mode)
-+		 *
-+		 * Force the key freeing to always synchronize_net()
-+		 * to wait for the RX path in case it is using this
-+		 * interface enqueuing frames at this very time on
-+		 * another CPU.
-+		 */
-+		ieee80211_free_keys(sdata, true);
-+		skb_queue_purge(&sdata->skb_queue);
-+	}
-+
-+	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-+	for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
-+		skb_queue_walk_safe(&local->pending[i], skb, tmp) {
-+			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+			if (info->control.vif == &sdata->vif) {
-+				__skb_unlink(skb, &local->pending[i]);
-+				ieee80211_free_txskb(&local->hw, skb);
-+			}
-+		}
-+	}
-+	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-+
-+	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+		ieee80211_txq_remove_vlan(local, sdata);
-+
-+	sdata->bss = NULL;
-+
-+	if (local->open_count == 0)
-+		ieee80211_clear_tx_pending(local);
-+
-+	sdata->vif.bss_conf.beacon_int = 0;
-+
-+	/*
-+	 * If the interface goes down while suspended, presumably because
-+	 * the device was unplugged and that happens before our resume,
-+	 * then the driver is already unconfigured and the remainder of
-+	 * this function isn't needed.
-+	 * XXX: what about WoWLAN? If the device has software state, e.g.
-+	 *	memory allocated, it might expect teardown commands from
-+	 *	mac80211 here?
-+	 */
-+	if (local->suspended) {
-+		WARN_ON(local->wowlan);
-+		WARN_ON(rtnl_dereference(local->monitor_sdata));
-+		return;
-+	}
-+
-+	switch (sdata->vif.type) {
-+	case NL80211_IFTYPE_AP_VLAN:
-+		break;
-+	case NL80211_IFTYPE_MONITOR:
-+		if (local->monitors == 0)
-+			ieee80211_del_virtual_monitor(local);
-+
-+		mutex_lock(&local->mtx);
-+		ieee80211_recalc_idle(local);
-+		mutex_unlock(&local->mtx);
-+
-+		if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
-+			break;
-+
-+		fallthrough;
-+	default:
-+		if (going_down)
-+			drv_remove_interface(local, sdata);
-+	}
-+
-+	ieee80211_recalc_ps(local);
-+
-+	if (cancel_scan)
-+		flush_delayed_work(&local->scan_work);
-+
-+	if (local->open_count == 0) {
-+		ieee80211_stop_device(local);
-+
-+		/* no reconfiguring after stop! */
-+		return;
-+	}
-+
-+	/* do after stop to avoid reconfiguring when we stop anyway */
-+	ieee80211_configure_filter(local);
-+	ieee80211_hw_config(local, hw_reconf_flags);
-+
-+	if (local->monitors == local->open_count)
-+		ieee80211_add_virtual_monitor(local);
-+}
-+
-+static int ieee80211_stop(struct net_device *dev)
-+{
-+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+
-+	ieee80211_do_stop(sdata, true);
-+
-+	return 0;
-+}
-+
-+static void ieee80211_set_multicast_list(struct net_device *dev)
-+{
-+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	struct ieee80211_local *local = sdata->local;
-+	int allmulti, sdata_allmulti;
-+
-+	allmulti = !!(dev->flags & IFF_ALLMULTI);
-+	sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI);
-+
-+	if (allmulti != sdata_allmulti) {
-+		if (dev->flags & IFF_ALLMULTI)
-+			atomic_inc(&local->iff_allmultis);
-+		else
-+			atomic_dec(&local->iff_allmultis);
-+		sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
-+	}
-+
-+	spin_lock_bh(&local->filter_lock);
-+	__hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
-+	spin_unlock_bh(&local->filter_lock);
-+	ieee80211_queue_work(&local->hw, &local->reconfig_filter);
-+}
-+
-+/*
-+ * Called when the netdev is removed or, by the code below, before
-+ * the interface type changes.
-+ */
-+static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
-+{
-+	int i;
-+
-+	/* free extra data */
-+	ieee80211_free_keys(sdata, false);
-+
-+	ieee80211_debugfs_remove_netdev(sdata);
-+
-+	for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
-+		__skb_queue_purge(&sdata->fragments[i].skb_list);
-+	sdata->fragment_next = 0;
-+
-+	if (ieee80211_vif_is_mesh(&sdata->vif))
-+		ieee80211_mesh_teardown_sdata(sdata);
-+}
-+
-+static void ieee80211_uninit(struct net_device *dev)
-+{
-+	ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
-+}
-+
-+#if LINUX_VERSION_IS_GEQ(5,2,0)
-+static u16 ieee80211_netdev_select_queue(struct net_device *dev,
-+					 struct sk_buff *skb,
-+					 struct net_device *sb_dev)
-+#elif LINUX_VERSION_IS_GEQ(4,19,0)
-+static u16 ieee80211_netdev_select_queue(struct net_device *dev,
-+					 struct sk_buff *skb,
-+					 struct net_device *sb_dev,
-+					 select_queue_fallback_t fallback)
-+#elif LINUX_VERSION_IS_GEQ(3,14,0) || \
-+    (LINUX_VERSION_CODE == KERNEL_VERSION(3,13,11) && UTS_UBUNTU_RELEASE_ABI > 30)
-+static u16 ieee80211_netdev_select_queue(struct net_device *dev,
-+					 struct sk_buff *skb,
-+					 void *accel_priv,
-+					 select_queue_fallback_t fallback)
-+#elif LINUX_VERSION_IS_GEQ(3,13,0)
-+static u16 ieee80211_netdev_select_queue(struct net_device *dev,
-+					 struct sk_buff *skb,
-+					 void *accel_priv)
-+#else
-+static u16 ieee80211_netdev_select_queue(struct net_device *dev,
-+					 struct sk_buff *skb)
-+#endif
-+{
-+	return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
-+}
-+
-+static void
-+ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
-+{
-+	int i;
-+
-+	for_each_possible_cpu(i) {
-+		const struct pcpu_sw_netstats *tstats;
-+		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
-+		unsigned int start;
-+
-+		tstats = per_cpu_ptr(netdev_tstats(dev), i);
-+
-+		do {
-+			start = u64_stats_fetch_begin_irq(&tstats->syncp);
-+			rx_packets = tstats->rx_packets;
-+			tx_packets = tstats->tx_packets;
-+			rx_bytes = tstats->rx_bytes;
-+			tx_bytes = tstats->tx_bytes;
-+		} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
-+
-+		stats->rx_packets += rx_packets;
-+		stats->tx_packets += tx_packets;
-+		stats->rx_bytes   += rx_bytes;
-+		stats->tx_bytes   += tx_bytes;
-+	}
-+}
-+#if LINUX_VERSION_IS_LESS(4,11,0)
-+/* Just declare it here to keep sparse happy */
-+struct rtnl_link_stats64 *bp_ieee80211_get_stats64(struct net_device *dev,
-+						   struct rtnl_link_stats64 *stats);
-+struct rtnl_link_stats64 *
-+bp_ieee80211_get_stats64(struct net_device *dev,
-+			 struct rtnl_link_stats64 *stats){
-+	ieee80211_get_stats64(dev, stats);
-+	return stats;
-+}
-+#endif
-+
-+static const struct net_device_ops ieee80211_dataif_ops = {
-+	.ndo_open		= ieee80211_open,
-+	.ndo_stop		= ieee80211_stop,
-+	.ndo_uninit		= ieee80211_uninit,
-+	.ndo_start_xmit		= ieee80211_subif_start_xmit,
-+	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
-+	.ndo_set_mac_address 	= ieee80211_change_mac,
-+	.ndo_select_queue	= ieee80211_netdev_select_queue,
-+#if LINUX_VERSION_IS_GEQ(4,11,0)
-+	.ndo_get_stats64	= ieee80211_get_stats64,
-+#else
-+	.ndo_get_stats64 = bp_ieee80211_get_stats64,
-+#endif
-+
-+};
-+
-+#if LINUX_VERSION_IS_GEQ(5,2,0)
-+static u16 ieee80211_monitor_select_queue(struct net_device *dev,
-+					  struct sk_buff *skb,
-+					  struct net_device *sb_dev)
-+#elif LINUX_VERSION_IS_GEQ(4,19,0)
-+static u16 ieee80211_monitor_select_queue(struct net_device *dev,
-+					  struct sk_buff *skb,
-+					  struct net_device *sb_dev,
-+					  select_queue_fallback_t fallback)
-+#elif LINUX_VERSION_IS_GEQ(3,14,0) || \
-+    (LINUX_VERSION_CODE == KERNEL_VERSION(3,13,11) && UTS_UBUNTU_RELEASE_ABI > 30)
-+static u16 ieee80211_monitor_select_queue(struct net_device *dev,
-+					  struct sk_buff *skb,
-+					  void *accel_priv,
-+					  select_queue_fallback_t fallback)
-+#elif LINUX_VERSION_IS_GEQ(3,13,0)
-+static u16 ieee80211_monitor_select_queue(struct net_device *dev,
-+					  struct sk_buff *skb,
-+					  void *accel_priv)
-+#else
-+static u16 ieee80211_monitor_select_queue(struct net_device *dev,
-+					  struct sk_buff *skb)
-+#endif
-+{
-+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	struct ieee80211_local *local = sdata->local;
-+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+	struct ieee80211_hdr *hdr;
-+	int len_rthdr;
-+
-+	if (local->hw.queues < IEEE80211_NUM_ACS)
-+		return 0;
-+
-+	/* reset flags and info before parsing radiotap header */
-+	memset(info, 0, sizeof(*info));
-+
-+	if (!ieee80211_parse_tx_radiotap(skb, dev))
-+		return 0; /* doesn't matter, frame will be dropped */
-+
-+	len_rthdr = ieee80211_get_radiotap_len(skb->data);
-+	hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
-+	if (skb->len < len_rthdr + 2 ||
-+	    skb->len < len_rthdr + ieee80211_hdrlen(hdr->frame_control))
-+		return 0; /* doesn't matter, frame will be dropped */
-+
-+	return ieee80211_select_queue_80211(sdata, skb, hdr);
-+}
-+
-+static const struct net_device_ops ieee80211_monitorif_ops = {
-+	.ndo_open		= ieee80211_open,
-+	.ndo_stop		= ieee80211_stop,
-+	.ndo_uninit		= ieee80211_uninit,
-+	.ndo_start_xmit		= ieee80211_monitor_start_xmit,
-+	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
-+	.ndo_set_mac_address 	= ieee80211_change_mac,
-+	.ndo_select_queue	= ieee80211_monitor_select_queue,
-+#if LINUX_VERSION_IS_GEQ(4,11,0)
-+	.ndo_get_stats64	= ieee80211_get_stats64,
-+#else
-+	.ndo_get_stats64 = bp_ieee80211_get_stats64,
-+#endif
-+
-+};
-+
-+static const struct net_device_ops ieee80211_dataif_8023_ops = {
-+	.ndo_open		= ieee80211_open,
-+	.ndo_stop		= ieee80211_stop,
-+	.ndo_uninit		= ieee80211_uninit,
-+	.ndo_start_xmit		= ieee80211_subif_start_xmit_8023,
-+	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
-+	.ndo_set_mac_address	= ieee80211_change_mac,
-+	.ndo_select_queue	= ieee80211_netdev_select_queue,
-+#if LINUX_VERSION_IS_GEQ(4,11,0)
-+	.ndo_get_stats64	= ieee80211_get_stats64,
-+#else
-+	.ndo_get_stats64 = bp_ieee80211_get_stats64,
-+#endif
-+
-+};
-+
- static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype)
- {
- 	switch (iftype) {
-@@ -389,6 +900,31 @@ static bool ieee80211_set_sdata_offload_
- 	return true;
- }
- 
-+static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata)
-+{
-+	struct ieee80211_local *local = sdata->local;
-+	struct ieee80211_sub_if_data *bss = sdata;
-+	bool enabled;
-+
-+	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
-+		if (!sdata->bss)
-+			return;
-+
-+		bss = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
-+	}
-+
-+	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
-+	    !ieee80211_iftype_supports_encap_offload(bss->vif.type))
-+		return;
-+
-+	enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+	if (sdata->wdev.use_4addr &&
-+	    !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR))
-+		enabled = false;
-+
-+	sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops :
-+					   &ieee80211_dataif_ops;
-+}
- 
- static void ieee80211_recalc_sdata_offload(struct ieee80211_sub_if_data *sdata)
- {
-@@ -866,518 +1402,6 @@ int ieee80211_do_open(struct wireless_de
- 	return res;
- }
- 
--static int ieee80211_open(struct net_device *dev)
--{
--	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
--	int err;
--
--	/* fail early if user set an invalid address */
--	if (!is_valid_ether_addr(dev->dev_addr))
--		return -EADDRNOTAVAIL;
--
--	err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type);
--	if (err)
--		return err;
--
--	return ieee80211_do_open(&sdata->wdev, true);
--}
--
--static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
--			      bool going_down)
--{
--	struct ieee80211_local *local = sdata->local;
--	unsigned long flags;
--	struct sk_buff *skb, *tmp;
--	u32 hw_reconf_flags = 0;
--	int i, flushed;
--	struct ps_data *ps;
--	struct cfg80211_chan_def chandef;
--	bool cancel_scan;
--	struct cfg80211_nan_func *func;
--
--	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
--
--	cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata;
--	if (cancel_scan)
--		ieee80211_scan_cancel(local);
--
--	/*
--	 * Stop TX on this interface first.
--	 */
--	if (sdata->dev)
--		netif_tx_stop_all_queues(sdata->dev);
--
--	ieee80211_roc_purge(local, sdata);
--
--	switch (sdata->vif.type) {
--	case NL80211_IFTYPE_STATION:
--		ieee80211_mgd_stop(sdata);
--		break;
--	case NL80211_IFTYPE_ADHOC:
--		ieee80211_ibss_stop(sdata);
--		break;
--	case NL80211_IFTYPE_MONITOR:
--		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
--			break;
--		list_del_rcu(&sdata->u.mntr.list);
--		break;
--	default:
--		break;
--	}
--
--	/*
--	 * Remove all stations associated with this interface.
--	 *
--	 * This must be done before calling ops->remove_interface()
--	 * because otherwise we can later invoke ops->sta_notify()
--	 * whenever the STAs are removed, and that invalidates driver
--	 * assumptions about always getting a vif pointer that is valid
--	 * (because if we remove a STA after ops->remove_interface()
--	 * the driver will have removed the vif info already!)
--	 *
--	 * In WDS mode a station must exist here and be flushed, for
--	 * AP_VLANs stations may exist since there's nothing else that
--	 * would have removed them, but in other modes there shouldn't
--	 * be any stations.
--	 */
--	flushed = sta_info_flush(sdata);
--	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
--		     ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
--		      (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)));
--
--	/* don't count this interface for allmulti while it is down */
--	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
--		atomic_dec(&local->iff_allmultis);
--
--	if (sdata->vif.type == NL80211_IFTYPE_AP) {
--		local->fif_pspoll--;
--		local->fif_probe_req--;
--	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
--		local->fif_probe_req--;
--	}
--
--	if (sdata->dev) {
--		netif_addr_lock_bh(sdata->dev);
--		spin_lock_bh(&local->filter_lock);
--		__hw_addr_unsync(&local->mc_list, &sdata->dev->mc,
--				 sdata->dev->addr_len);
--		spin_unlock_bh(&local->filter_lock);
--		netif_addr_unlock_bh(sdata->dev);
--	}
--
--	del_timer_sync(&local->dynamic_ps_timer);
--	cancel_work_sync(&local->dynamic_ps_enable_work);
--
--	cancel_work_sync(&sdata->recalc_smps);
--	sdata_lock(sdata);
--	mutex_lock(&local->mtx);
--	sdata->vif.csa_active = false;
--	if (sdata->vif.type == NL80211_IFTYPE_STATION)
--		sdata->u.mgd.csa_waiting_bcn = false;
--	if (sdata->csa_block_tx) {
--		ieee80211_wake_vif_queues(local, sdata,
--					  IEEE80211_QUEUE_STOP_REASON_CSA);
--		sdata->csa_block_tx = false;
--	}
--	mutex_unlock(&local->mtx);
--	sdata_unlock(sdata);
--
--	cancel_work_sync(&sdata->csa_finalize_work);
--
--	cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
--
--	if (sdata->wdev.cac_started) {
--		chandef = sdata->vif.bss_conf.chandef;
--		WARN_ON(local->suspended);
--		mutex_lock(&local->mtx);
--		ieee80211_vif_release_channel(sdata);
--		mutex_unlock(&local->mtx);
--		cfg80211_cac_event(sdata->dev, &chandef,
--				   NL80211_RADAR_CAC_ABORTED,
--				   GFP_KERNEL);
--	}
--
--	/* APs need special treatment */
--	if (sdata->vif.type == NL80211_IFTYPE_AP) {
--		struct ieee80211_sub_if_data *vlan, *tmpsdata;
--
--		/* down all dependent devices, that is VLANs */
--		list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
--					 u.vlan.list)
--			dev_close(vlan->dev);
--		WARN_ON(!list_empty(&sdata->u.ap.vlans));
--	} else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
--		/* remove all packets in parent bc_buf pointing to this dev */
--		ps = &sdata->bss->ps;
--
--		spin_lock_irqsave(&ps->bc_buf.lock, flags);
--		skb_queue_walk_safe(&ps->bc_buf, skb, tmp) {
--			if (skb->dev == sdata->dev) {
--				__skb_unlink(skb, &ps->bc_buf);
--				local->total_ps_buffered--;
--				ieee80211_free_txskb(&local->hw, skb);
--			}
--		}
--		spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
--	}
--
--	if (going_down)
--		local->open_count--;
--
--	switch (sdata->vif.type) {
--	case NL80211_IFTYPE_AP_VLAN:
--		mutex_lock(&local->mtx);
--		list_del(&sdata->u.vlan.list);
--		mutex_unlock(&local->mtx);
--		RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL);
--		/* see comment in the default case below */
--		ieee80211_free_keys(sdata, true);
--		/* no need to tell driver */
--		break;
--	case NL80211_IFTYPE_MONITOR:
--		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
--			local->cooked_mntrs--;
--			break;
--		}
--
--		local->monitors--;
--		if (local->monitors == 0) {
--			local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
--			hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
--		}
--
--		ieee80211_adjust_monitor_flags(sdata, -1);
--		break;
--	case NL80211_IFTYPE_NAN:
--		/* clean all the functions */
--		spin_lock_bh(&sdata->u.nan.func_lock);
--
--		idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) {
--			idr_remove(&sdata->u.nan.function_inst_ids, i);
--			cfg80211_free_nan_func(func);
--		}
--		idr_destroy(&sdata->u.nan.function_inst_ids);
--
--		spin_unlock_bh(&sdata->u.nan.func_lock);
--		break;
--	case NL80211_IFTYPE_P2P_DEVICE:
--		/* relies on synchronize_rcu() below */
--		RCU_INIT_POINTER(local->p2p_sdata, NULL);
--		fallthrough;
--	default:
--		cancel_work_sync(&sdata->work);
--		/*
--		 * When we get here, the interface is marked down.
--		 * Free the remaining keys, if there are any
--		 * (which can happen in AP mode if userspace sets
--		 * keys before the interface is operating, and maybe
--		 * also in WDS mode)
--		 *
--		 * Force the key freeing to always synchronize_net()
--		 * to wait for the RX path in case it is using this
--		 * interface enqueuing frames at this very time on
--		 * another CPU.
--		 */
--		ieee80211_free_keys(sdata, true);
--		skb_queue_purge(&sdata->skb_queue);
--	}
--
--	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
--	for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
--		skb_queue_walk_safe(&local->pending[i], skb, tmp) {
--			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--			if (info->control.vif == &sdata->vif) {
--				__skb_unlink(skb, &local->pending[i]);
--				ieee80211_free_txskb(&local->hw, skb);
--			}
--		}
--	}
--	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
--
--	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
--		ieee80211_txq_remove_vlan(local, sdata);
--
--	sdata->bss = NULL;
--
--	if (local->open_count == 0)
--		ieee80211_clear_tx_pending(local);
--
--	sdata->vif.bss_conf.beacon_int = 0;
--
--	/*
--	 * If the interface goes down while suspended, presumably because
--	 * the device was unplugged and that happens before our resume,
--	 * then the driver is already unconfigured and the remainder of
--	 * this function isn't needed.
--	 * XXX: what about WoWLAN? If the device has software state, e.g.
--	 *	memory allocated, it might expect teardown commands from
--	 *	mac80211 here?
--	 */
--	if (local->suspended) {
--		WARN_ON(local->wowlan);
--		WARN_ON(rtnl_dereference(local->monitor_sdata));
--		return;
--	}
--
--	switch (sdata->vif.type) {
--	case NL80211_IFTYPE_AP_VLAN:
--		break;
--	case NL80211_IFTYPE_MONITOR:
--		if (local->monitors == 0)
--			ieee80211_del_virtual_monitor(local);
--
--		mutex_lock(&local->mtx);
--		ieee80211_recalc_idle(local);
--		mutex_unlock(&local->mtx);
--
--		if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
--			break;
--
--		fallthrough;
--	default:
--		if (going_down)
--			drv_remove_interface(local, sdata);
--	}
--
--	ieee80211_recalc_ps(local);
--
--	if (cancel_scan)
--		flush_delayed_work(&local->scan_work);
--
--	if (local->open_count == 0) {
--		ieee80211_stop_device(local);
--
--		/* no reconfiguring after stop! */
--		return;
--	}
--
--	/* do after stop to avoid reconfiguring when we stop anyway */
--	ieee80211_configure_filter(local);
--	ieee80211_hw_config(local, hw_reconf_flags);
--
--	if (local->monitors == local->open_count)
--		ieee80211_add_virtual_monitor(local);
--}
--
--static int ieee80211_stop(struct net_device *dev)
--{
--	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
--
--	ieee80211_do_stop(sdata, true);
--
--	return 0;
--}
--
--static void ieee80211_set_multicast_list(struct net_device *dev)
--{
--	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
--	struct ieee80211_local *local = sdata->local;
--	int allmulti, sdata_allmulti;
--
--	allmulti = !!(dev->flags & IFF_ALLMULTI);
--	sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI);
--
--	if (allmulti != sdata_allmulti) {
--		if (dev->flags & IFF_ALLMULTI)
--			atomic_inc(&local->iff_allmultis);
--		else
--			atomic_dec(&local->iff_allmultis);
--		sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
--	}
--
--	spin_lock_bh(&local->filter_lock);
--	__hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
--	spin_unlock_bh(&local->filter_lock);
--	ieee80211_queue_work(&local->hw, &local->reconfig_filter);
--}
--
--/*
-- * Called when the netdev is removed or, by the code below, before
-- * the interface type changes.
-- */
--static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
--{
--	int i;
--
--	/* free extra data */
--	ieee80211_free_keys(sdata, false);
--
--	ieee80211_debugfs_remove_netdev(sdata);
--
--	for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
--		__skb_queue_purge(&sdata->fragments[i].skb_list);
--	sdata->fragment_next = 0;
--
--	if (ieee80211_vif_is_mesh(&sdata->vif))
--		ieee80211_mesh_teardown_sdata(sdata);
--}
--
--static void ieee80211_uninit(struct net_device *dev)
--{
--	ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
--}
--
--#if LINUX_VERSION_IS_GEQ(5,2,0)
--static u16 ieee80211_netdev_select_queue(struct net_device *dev,
--					 struct sk_buff *skb,
--					 struct net_device *sb_dev)
--#elif LINUX_VERSION_IS_GEQ(4,19,0)
--static u16 ieee80211_netdev_select_queue(struct net_device *dev,
--					 struct sk_buff *skb,
--					 struct net_device *sb_dev,
--					 select_queue_fallback_t fallback)
--#elif LINUX_VERSION_IS_GEQ(3,14,0) || \
--    (LINUX_VERSION_CODE == KERNEL_VERSION(3,13,11) && UTS_UBUNTU_RELEASE_ABI > 30)
--static u16 ieee80211_netdev_select_queue(struct net_device *dev,
--					 struct sk_buff *skb,
--					 void *accel_priv,
--					 select_queue_fallback_t fallback)
--#elif LINUX_VERSION_IS_GEQ(3,13,0)
--static u16 ieee80211_netdev_select_queue(struct net_device *dev,
--					 struct sk_buff *skb,
--					 void *accel_priv)
--#else
--static u16 ieee80211_netdev_select_queue(struct net_device *dev,
--					 struct sk_buff *skb)
--#endif
--{
--	return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
--}
--
--static void
--ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
--{
--	int i;
--
--	for_each_possible_cpu(i) {
--		const struct pcpu_sw_netstats *tstats;
--		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
--		unsigned int start;
--
--		tstats = per_cpu_ptr(netdev_tstats(dev), i);
--
--		do {
--			start = u64_stats_fetch_begin_irq(&tstats->syncp);
--			rx_packets = tstats->rx_packets;
--			tx_packets = tstats->tx_packets;
--			rx_bytes = tstats->rx_bytes;
--			tx_bytes = tstats->tx_bytes;
--		} while (u64_stats_fetch_retry_irq(&tstats->syncp, start));
--
--		stats->rx_packets += rx_packets;
--		stats->tx_packets += tx_packets;
--		stats->rx_bytes   += rx_bytes;
--		stats->tx_bytes   += tx_bytes;
--	}
--}
--#if LINUX_VERSION_IS_LESS(4,11,0)
--/* Just declare it here to keep sparse happy */
--struct rtnl_link_stats64 *bp_ieee80211_get_stats64(struct net_device *dev,
--						   struct rtnl_link_stats64 *stats);
--struct rtnl_link_stats64 *
--bp_ieee80211_get_stats64(struct net_device *dev,
--			 struct rtnl_link_stats64 *stats){
--	ieee80211_get_stats64(dev, stats);
--	return stats;
--}
--#endif
--
--static const struct net_device_ops ieee80211_dataif_ops = {
--	.ndo_open		= ieee80211_open,
--	.ndo_stop		= ieee80211_stop,
--	.ndo_uninit		= ieee80211_uninit,
--	.ndo_start_xmit		= ieee80211_subif_start_xmit,
--	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
--	.ndo_set_mac_address 	= ieee80211_change_mac,
--	.ndo_select_queue	= ieee80211_netdev_select_queue,
--#if LINUX_VERSION_IS_GEQ(4,11,0)
--	.ndo_get_stats64	= ieee80211_get_stats64,
--#else
--	.ndo_get_stats64 = bp_ieee80211_get_stats64,
--#endif
--
--};
--
--#if LINUX_VERSION_IS_GEQ(5,2,0)
--static u16 ieee80211_monitor_select_queue(struct net_device *dev,
--					  struct sk_buff *skb,
--					  struct net_device *sb_dev)
--#elif LINUX_VERSION_IS_GEQ(4,19,0)
--static u16 ieee80211_monitor_select_queue(struct net_device *dev,
--					  struct sk_buff *skb,
--					  struct net_device *sb_dev,
--					  select_queue_fallback_t fallback)
--#elif LINUX_VERSION_IS_GEQ(3,14,0) || \
--    (LINUX_VERSION_CODE == KERNEL_VERSION(3,13,11) && UTS_UBUNTU_RELEASE_ABI > 30)
--static u16 ieee80211_monitor_select_queue(struct net_device *dev,
--					  struct sk_buff *skb,
--					  void *accel_priv,
--					  select_queue_fallback_t fallback)
--#elif LINUX_VERSION_IS_GEQ(3,13,0)
--static u16 ieee80211_monitor_select_queue(struct net_device *dev,
--					  struct sk_buff *skb,
--					  void *accel_priv)
--#else
--static u16 ieee80211_monitor_select_queue(struct net_device *dev,
--					  struct sk_buff *skb)
--#endif
--{
--	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
--	struct ieee80211_local *local = sdata->local;
--	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--	struct ieee80211_hdr *hdr;
--	int len_rthdr;
--
--	if (local->hw.queues < IEEE80211_NUM_ACS)
--		return 0;
--
--	/* reset flags and info before parsing radiotap header */
--	memset(info, 0, sizeof(*info));
--
--	if (!ieee80211_parse_tx_radiotap(skb, dev))
--		return 0; /* doesn't matter, frame will be dropped */
--
--	len_rthdr = ieee80211_get_radiotap_len(skb->data);
--	hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
--	if (skb->len < len_rthdr + 2 ||
--	    skb->len < len_rthdr + ieee80211_hdrlen(hdr->frame_control))
--		return 0; /* doesn't matter, frame will be dropped */
--
--	return ieee80211_select_queue_80211(sdata, skb, hdr);
--}
--
--static const struct net_device_ops ieee80211_monitorif_ops = {
--	.ndo_open		= ieee80211_open,
--	.ndo_stop		= ieee80211_stop,
--	.ndo_uninit		= ieee80211_uninit,
--	.ndo_start_xmit		= ieee80211_monitor_start_xmit,
--	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
--	.ndo_set_mac_address 	= ieee80211_change_mac,
--	.ndo_select_queue	= ieee80211_monitor_select_queue,
--#if LINUX_VERSION_IS_GEQ(4,11,0)
--	.ndo_get_stats64	= ieee80211_get_stats64,
--#else
--	.ndo_get_stats64 = bp_ieee80211_get_stats64,
--#endif
--
--};
--
--static const struct net_device_ops ieee80211_dataif_8023_ops = {
--	.ndo_open		= ieee80211_open,
--	.ndo_stop		= ieee80211_stop,
--	.ndo_uninit		= ieee80211_uninit,
--	.ndo_start_xmit		= ieee80211_subif_start_xmit_8023,
--	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
--	.ndo_set_mac_address	= ieee80211_change_mac,
--	.ndo_select_queue	= ieee80211_netdev_select_queue,
--#if LINUX_VERSION_IS_GEQ(4,11,0)
--	.ndo_get_stats64	= ieee80211_get_stats64,
--#else
--	.ndo_get_stats64 = bp_ieee80211_get_stats64,
--#endif
--
--};
--
- static void ieee80211_if_free(struct net_device *dev)
- {
- 	free_percpu(netdev_tstats(dev));
-@@ -1408,32 +1432,6 @@ static void ieee80211_if_setup_no_queue(
- #endif
- }
- 
--static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata)
--{
--	struct ieee80211_local *local = sdata->local;
--	struct ieee80211_sub_if_data *bss = sdata;
--	bool enabled;
--
--	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
--		if (!sdata->bss)
--			return;
--
--		bss = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
--	}
--
--	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
--	    !ieee80211_iftype_supports_encap_offload(bss->vif.type))
--		return;
--
--	enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
--	if (sdata->wdev.use_4addr &&
--	    !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR))
--		enabled = false;
--
--	sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops :
--					   &ieee80211_dataif_ops;
--}
--
- static void ieee80211_iface_work(struct work_struct *work)
- {
- 	struct ieee80211_sub_if_data *sdata =
diff --git a/package/kernel/mac80211/patches/subsys/330-mac80211-allow-bigger-A-MSDU-sizes-in-VHT-even-if-HT.patch b/package/kernel/mac80211/patches/subsys/330-mac80211-allow-bigger-A-MSDU-sizes-in-VHT-even-if-HT.patch
deleted file mode 100644
index b67030d135..0000000000
--- a/package/kernel/mac80211/patches/subsys/330-mac80211-allow-bigger-A-MSDU-sizes-in-VHT-even-if-HT.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Wed, 16 Sep 2020 18:43:46 +0200
-Subject: [PATCH] mac80211: allow bigger A-MSDU sizes in VHT, even if HT is
- limited
-
-Some APs (e.g. Asus RT-AC88U) have been observed to report an HT MSDU size
-limit of 3839 and a VHT limit of 7991. These APs can handle bigger frames
-than 3839 bytes just fine, so we should remove the VHT limit based on the
-HT capabilities. This improves tx throughput.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/vht.c
-+++ b/net/mac80211/vht.c
-@@ -315,10 +315,6 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(stru
- 
- 	sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta);
- 
--	/* If HT IE reported 3839 bytes only, stay with that size. */
--	if (sta->sta.max_amsdu_len == IEEE80211_MAX_MPDU_LEN_HT_3839)
--		return;
--
- 	switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
- 	case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
- 		sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454;
diff --git a/package/kernel/mac80211/patches/subsys/332-mac80211-fix-regression-in-sta-connection-monitor.patch b/package/kernel/mac80211/patches/subsys/332-mac80211-fix-regression-in-sta-connection-monitor.patch
deleted file mode 100644
index 93a9eca51f..0000000000
--- a/package/kernel/mac80211/patches/subsys/332-mac80211-fix-regression-in-sta-connection-monitor.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Mon, 21 Sep 2020 17:43:06 +0200
-Subject: [PATCH] mac80211: fix regression in sta connection monitor
-
-When a frame was acked and probe frames were sent, the connection monitoring
-needs to be reset, otherwise it will keep probing until the connection is
-considered dead, even though frames have been acked in the mean time.
-
-Fixes: 9abf4e49830d ("mac80211: optimize station connection monitor")
-Reported-by: Georgi Valkov <gvalkov at abv.bg>
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -989,10 +989,6 @@ static void __ieee80211_tx_status(struct
- 		if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked)
- 			ieee80211_frame_acked(sta, skb);
- 
--		if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) &&
--		    ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
--			ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
--						acked, info->status.tx_time);
- 	}
- 
- 	/* SNMP counters
-@@ -1127,11 +1123,18 @@ void ieee80211_tx_status_ext(struct ieee
- 	noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED);
- 
- 	if (pubsta) {
-+		struct ieee80211_sub_if_data *sdata = sta->sdata;
-+
- 		if (!acked && !noack_success)
- 			sta->status_stats.retry_failed++;
- 		sta->status_stats.retry_count += retry_count;
- 
- 		if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
-+			if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-+			    skb && !(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
-+				ieee80211_sta_tx_notify(sdata, (void *) skb->data,
-+							acked, info->status.tx_time);
-+
- 			if (acked) {
- 				sta->status_stats.last_ack = jiffies;
- 
-@@ -1141,6 +1144,11 @@ void ieee80211_tx_status_ext(struct ieee
- 				/* Track when last packet was ACKed */
- 				sta->status_stats.last_pkt_time = jiffies;
- 
-+				/* Reset connection monitor */
-+				if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-+				    unlikely(sdata->u.mgd.probe_send_count > 0))
-+					sdata->u.mgd.probe_send_count = 0;
-+
- 				if (info->status.is_valid_ack_signal) {
- 					sta->status_stats.last_ack_signal =
- 							 (s8)info->status.ack_signal;
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -2508,7 +2508,9 @@ void ieee80211_sta_tx_notify(struct ieee
- 	    !sdata->u.mgd.probe_send_count)
- 		return;
- 
--	if (!ack)
-+	if (ack)
-+		sdata->u.mgd.probe_send_count = 0;
-+	else
- 		sdata->u.mgd.nullfunc_failed = true;
- 	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
- }
diff --git a/package/kernel/mac80211/patches/subsys/333-mac80211-fix-memory-leak-on-filtered-powersave-frame.patch b/package/kernel/mac80211/patches/subsys/333-mac80211-fix-memory-leak-on-filtered-powersave-frame.patch
deleted file mode 100644
index e518f5134f..0000000000
--- a/package/kernel/mac80211/patches/subsys/333-mac80211-fix-memory-leak-on-filtered-powersave-frame.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Fri, 16 Oct 2020 19:54:49 +0200
-Subject: [PATCH] mac80211: fix memory leak on filtered powersave frames
-
-After the status rework, ieee80211_tx_status_ext is leaking un-acknowledged
-packets for stations in powersave mode.
-To fix this, move the code handling those packets from __ieee80211_tx_status
-into ieee80211_tx_status_ext
-
-Reported-by: Tobias Waldvogel <tobias.waldvogel at gmail.com>
-Fixes: 3318111cf63d ("mac80211: reduce duplication in tx status functions")
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -49,7 +49,8 @@ static void ieee80211_handle_filtered_fr
- 	int ac;
- 
- 	if (info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
--			   IEEE80211_TX_CTL_AMPDU)) {
-+			   IEEE80211_TX_CTL_AMPDU |
-+			   IEEE80211_TX_CTL_HW_80211_ENCAP)) {
- 		ieee80211_free_txskb(&local->hw, skb);
- 		return;
- 	}
-@@ -922,15 +923,6 @@ static void __ieee80211_tx_status(struct
- 			ieee80211_mpsp_trigger_process(
- 				ieee80211_get_qos_ctl(hdr), sta, true, acked);
- 
--		if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) {
--			/*
--			 * The STA is in power save mode, so assume
--			 * that this TX packet failed because of that.
--			 */
--			ieee80211_handle_filtered_frame(local, sta, skb);
--			return;
--		}
--
- 		if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL) &&
- 		    (ieee80211_is_data(hdr->frame_control)) &&
- 		    (rates_idx != -1))
-@@ -1157,6 +1149,12 @@ void ieee80211_tx_status_ext(struct ieee
- 							    -info->status.ack_signal);
- 				}
- 			} else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
-+				/*
-+				 * The STA is in power save mode, so assume
-+				 * that this TX packet failed because of that.
-+				 */
-+				if (skb)
-+					ieee80211_handle_filtered_frame(local, sta, skb);
- 				return;
- 			} else if (noack_success) {
- 				/* nothing to do here, do not account as lost */
diff --git a/package/kernel/mac80211/patches/subsys/336-mac80211-do-not-drop-tx-nulldata-packets-on-encrypte.patch b/package/kernel/mac80211/patches/subsys/336-mac80211-do-not-drop-tx-nulldata-packets-on-encrypte.patch
index d3fb3875f6..d05217d1f8 100644
--- a/package/kernel/mac80211/patches/subsys/336-mac80211-do-not-drop-tx-nulldata-packets-on-encrypte.patch
+++ b/package/kernel/mac80211/patches/subsys/336-mac80211-do-not-drop-tx-nulldata-packets-on-encrypte.patch
@@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -658,7 +658,7 @@ ieee80211_tx_h_select_key(struct ieee802
+@@ -662,7 +662,7 @@ ieee80211_tx_h_select_key(struct ieee802
  		if (!skip_hw && tx->key &&
  		    tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
  			info->control.hw_key = &tx->key->conf;
diff --git a/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch b/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch
index 8fd93247af..96ee595ac1 100644
--- a/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch
+++ b/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 
 --- a/net/mac80211/Makefile
 +++ b/net/mac80211/Makefile
-@@ -54,11 +54,9 @@ mac80211-$(CONFIG_PM) += pm.o
+@@ -55,11 +55,9 @@ mac80211-$(CONFIG_PM) += pm.o
  CFLAGS_trace.o := -I$(src)
  
  rc80211_minstrel-y := \
diff --git a/package/kernel/mac80211/patches/subsys/353-mac80211-fix-station-rate-table-updates-on-assoc.patch b/package/kernel/mac80211/patches/subsys/353-mac80211-fix-station-rate-table-updates-on-assoc.patch
index c96fc56921..7df24fa4bd 100644
--- a/package/kernel/mac80211/patches/subsys/353-mac80211-fix-station-rate-table-updates-on-assoc.patch
+++ b/package/kernel/mac80211/patches/subsys/353-mac80211-fix-station-rate-table-updates-on-assoc.patch
@@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  		drv_sta_remove(local, sdata, &sta->sta);
 --- a/net/mac80211/rate.c
 +++ b/net/mac80211/rate.c
-@@ -934,7 +934,8 @@ int rate_control_set_rates(struct ieee80
+@@ -960,7 +960,8 @@ int rate_control_set_rates(struct ieee80
  	if (old)
  		kfree_rcu(old, rcu_head);
  
diff --git a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch
index feb6b5b11e..f9c4caa51c 100644
--- a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch
+++ b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch
@@ -5,7 +5,7 @@ and we should ignore this.
 
 --- a/net/wireless/core.c
 +++ b/net/wireless/core.c
-@@ -612,21 +612,6 @@ static int wiphy_verify_combinations(str
+@@ -614,21 +614,6 @@ static int wiphy_verify_combinations(str
  				    c->limits[j].max > 1))
  				return -EINVAL;
  
diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch
index 683c9950d6..d76fc88238 100644
--- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch
+++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch
@@ -1,6 +1,6 @@
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -3637,6 +3637,7 @@ struct mgmt_frame_regs {
+@@ -3736,6 +3736,7 @@ struct mgmt_frame_regs {
   *	(as advertised by the nl80211 feature flag.)
   * @get_tx_power: store the current TX power into the dbm variable;
   *	return 0 if successful
@@ -8,7 +8,7 @@
   *
   * @set_wds_peer: set the WDS peer for a WDS interface
   *
-@@ -3959,6 +3960,7 @@ struct cfg80211_ops {
+@@ -4058,6 +4059,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
-@@ -1524,6 +1524,7 @@ enum ieee80211_smps_mode {
+@@ -1558,6 +1558,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
-@@ -1544,6 +1545,7 @@ enum ieee80211_smps_mode {
+@@ -1578,6 +1579,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
-@@ -2515,6 +2515,9 @@ enum nl80211_commands {
-  * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from
-  *	association request when used with NL80211_CMD_NEW_STATION).
+@@ -2527,6 +2527,9 @@ enum nl80211_commands {
+  *	override mask. Used with NL80211_ATTR_S1G_CAPABILITY in
+  *	NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT.
   *
 + * @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
-@@ -2997,6 +3000,8 @@ enum nl80211_attrs {
- 
- 	NL80211_ATTR_HE_6GHZ_CAPABILITY,
+@@ -3016,6 +3019,8 @@ enum nl80211_attrs {
+ 	NL80211_ATTR_S1G_CAPABILITY,
+ 	NL80211_ATTR_S1G_CAPABILITY_MASK,
  
 +	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
 +
@@ -57,7 +57,7 @@
  	__NL80211_ATTR_AFTER_LAST,
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2619,6 +2619,19 @@ static int ieee80211_get_tx_power(struct
+@@ -2707,6 +2707,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)
  {
-@@ -4049,6 +4062,7 @@ const struct cfg80211_ops mac80211_confi
+@@ -4137,6 +4150,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
-@@ -1386,6 +1386,7 @@ struct ieee80211_local {
+@@ -1401,6 +1401,7 @@ struct ieee80211_local {
  	int dynamic_ps_forced_timeout;
  
  	int user_power_level; /* in dBm, for all interfaces */
@@ -129,15 +129,15 @@
  	local->hw.max_mtu = IEEE80211_MAX_DATA_LEN;
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -658,6 +658,7 @@ static const struct nla_policy nl80211_p
- 		.type = NLA_EXACT_LEN,
- 		.len = sizeof(struct ieee80211_he_6ghz_capa),
- 	},
+@@ -732,6 +732,7 @@ static const struct nla_policy nl80211_p
+ 		NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
+ 	[NL80211_ATTR_S1G_CAPABILITY_MASK] =
+ 		NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
 +	[NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
  };
  
  /* policy for the key attributes */
-@@ -3139,6 +3140,20 @@ static int nl80211_set_wiphy(struct sk_b
+@@ -3240,6 +3241,20 @@ static int nl80211_set_wiphy(struct sk_b
  		if (result)
  			return result;
  	}
diff --git a/package/kernel/mt76/patches/100-mac80211-5.10.patch b/package/kernel/mt76/patches/100-mac80211-5.10.patch
new file mode 100644
index 0000000000..b7b5a5691c
--- /dev/null
+++ b/package/kernel/mt76/patches/100-mac80211-5.10.patch
@@ -0,0 +1,82 @@
+--- a/mt7615/mcu.c
++++ b/mt7615/mcu.c
+@@ -730,12 +730,12 @@ mt7615_mcu_add_beacon_offload(struct mt7
+ 	memcpy(req.pkt + MT_TXD_SIZE, skb->data, skb->len);
+ 	req.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
+ 	req.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
+-	if (offs.csa_counter_offs[0]) {
++	if (offs.cntdwn_counter_offs[0]) {
+ 		u16 csa_offs;
+ 
+-		csa_offs = MT_TXD_SIZE + offs.csa_counter_offs[0] - 4;
++		csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;
+ 		req.csa_ie_pos = cpu_to_le16(csa_offs);
+-		req.csa_cnt = skb->data[offs.csa_counter_offs[0]];
++		req.csa_cnt = skb->data[offs.cntdwn_counter_offs[0]];
+ 	}
+ 	dev_kfree_skb(skb);
+ 
+@@ -1801,10 +1801,10 @@ mt7615_mcu_uni_add_beacon_offload(struct
+ 	req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
+ 	req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
+ 
+-	if (offs.csa_counter_offs[0]) {
++	if (offs.cntdwn_counter_offs[0]) {
+ 		u16 csa_offs;
+ 
+-		csa_offs = MT_TXD_SIZE + offs.csa_counter_offs[0] - 4;
++		csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;
+ 		req.beacon_tlv.csa_ie_pos = cpu_to_le16(csa_offs);
+ 	}
+ 	dev_kfree_skb(skb);
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -2358,7 +2358,7 @@ mt7915_mcu_beacon_csa(struct sk_buff *rs
+ 		      struct bss_info_bcn *bcn,
+ 		      struct ieee80211_mutable_offsets *offs)
+ {
+-	if (offs->csa_counter_offs[0]) {
++	if (offs->cntdwn_counter_offs[0]) {
+ 		struct tlv *tlv;
+ 		struct bss_info_bcn_csa *csa;
+ 
+@@ -2366,7 +2366,7 @@ mt7915_mcu_beacon_csa(struct sk_buff *rs
+ 						   sizeof(*csa), &bcn->sub_ntlv,
+ 						   &bcn->len);
+ 		csa = (struct bss_info_bcn_csa *)tlv;
+-		csa->cnt = skb->data[offs->csa_counter_offs[0]];
++		csa->cnt = skb->data[offs->cntdwn_counter_offs[0]];
+ 	}
+ }
+ 
+@@ -2388,8 +2388,8 @@ mt7915_mcu_beacon_cont(struct mt7915_dev
+ 	cont->pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
+ 	cont->tim_ofs = cpu_to_le16(offs->tim_offset);
+ 
+-	if (offs->csa_counter_offs[0])
+-		cont->csa_ofs = cpu_to_le16(offs->csa_counter_offs[0] - 4);
++	if (offs->cntdwn_counter_offs[0])
++		cont->csa_ofs = cpu_to_le16(offs->cntdwn_counter_offs[0] - 4);
+ 
+ 	buf = (u8 *)tlv + sizeof(*cont);
+ 	mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL,
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -1082,7 +1082,7 @@ EXPORT_SYMBOL_GPL(mt76_get_txpower);
+ static void
+ __mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ {
+-	if (vif->csa_active && ieee80211_csa_is_complete(vif))
++	if (vif->csa_active && ieee80211_beacon_cntdwn_is_complete(vif))
+ 		ieee80211_csa_finish(vif);
+ }
+ 
+@@ -1107,7 +1107,7 @@ __mt76_csa_check(void *priv, u8 *mac, st
+ 	if (!vif->csa_active)
+ 		return;
+ 
+-	dev->csa_complete |= ieee80211_csa_is_complete(vif);
++	dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif);
+ }
+ 
+ void mt76_csa_check(struct mt76_dev *dev)
diff --git a/package/network/utils/iw/patches/001-nl80211_h_sync.patch b/package/network/utils/iw/patches/001-nl80211_h_sync.patch
index 4b462d3f20..394acbd0e7 100644
--- a/package/network/utils/iw/patches/001-nl80211_h_sync.patch
+++ b/package/network/utils/iw/patches/001-nl80211_h_sync.patch
@@ -1,21 +1,363 @@
 --- a/nl80211.h
 +++ b/nl80211.h
-@@ -2515,6 +2515,9 @@ enum nl80211_commands {
+@@ -252,9 +252,13 @@
+  * DOC: SAE authentication offload
+  *
+  * By setting @NL80211_EXT_FEATURE_SAE_OFFLOAD flag drivers can indicate they
+- * support offloading SAE authentication for WPA3-Personal networks. In
+- * %NL80211_CMD_CONNECT the password for SAE should be specified using
+- * %NL80211_ATTR_SAE_PASSWORD.
++ * support offloading SAE authentication for WPA3-Personal networks in station
++ * mode. Similarly @NL80211_EXT_FEATURE_SAE_OFFLOAD_AP flag can be set by
++ * drivers indicating the offload support in AP mode.
++ *
++ * The password for SAE should be specified using %NL80211_ATTR_SAE_PASSWORD in
++ * %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP for station and AP mode
++ * respectively.
+  */
+ 
+ /**
+@@ -647,13 +651,9 @@
+  *	authentication/association or not receiving a response from the AP.
+  *	Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as
+  *	well to remain backwards compatible.
+- *	When establishing a security association, drivers that support 4 way
+- *	handshake offload should send %NL80211_CMD_PORT_AUTHORIZED event when
+- *	the 4 way handshake is completed successfully.
+  * @NL80211_CMD_ROAM: Notification indicating the card/driver roamed by itself.
+- *	When a security association was established with the new AP (e.g. if
+- *	the FT protocol was used for roaming or the driver completed the 4 way
+- *	handshake), this event should be followed by an
++ *	When a security association was established on an 802.1X network using
++ *	fast transition, this event should be followed by an
+  *	%NL80211_CMD_PORT_AUTHORIZED event.
+  * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
+  *	userspace that a connection was dropped by the AP or due to other
+@@ -1067,13 +1067,11 @@
+  * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously
+  *	configured PMK for the authenticator address identified by
+  *	%NL80211_ATTR_MAC.
+- * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates that the 4 way
+- *	handshake was completed successfully by the driver. The BSSID is
+- *	specified with %NL80211_ATTR_MAC. Drivers that support 4 way handshake
+- *	offload should send this event after indicating 802.11 association with
+- *	%NL80211_CMD_CONNECT or %NL80211_CMD_ROAM. If the 4 way handshake failed
+- *	%NL80211_CMD_DISCONNECT should be indicated instead.
+- *
++ * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates an 802.1X FT roam was
++ *	completed successfully. Drivers that support 4 way handshake offload
++ *	should send this event after indicating 802.1X FT assocation with
++ *	%NL80211_CMD_ROAM. If the 4 way handshake failed %NL80211_CMD_DISCONNECT
++ *	should be indicated instead.
+  * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
+  *	and RX notification.  This command is used both as a request to transmit
+  *	a control port frame and as a notification that a control port frame
+@@ -2082,10 +2080,10 @@ enum nl80211_commands {
+  *	operation).
+  * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
+  *	for the time while performing a channel switch.
+- * @NL80211_ATTR_CSA_C_OFF_BEACON: An array of offsets (u16) to the channel
+- *	switch counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
+- * @NL80211_ATTR_CSA_C_OFF_PRESP: An array of offsets (u16) to the channel
+- *	switch counters in the probe response (%NL80211_ATTR_PROBE_RESP).
++ * @NL80211_ATTR_CNTDWN_OFFS_BEACON: An array of offsets (u16) to the channel
++ *	switch or color change counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
++ * @NL80211_ATTR_CNTDWN_OFFS_PRESP: An array of offsets (u16) to the channel
++ *	switch or color change counters in the probe response (%NL80211_ATTR_PROBE_RESP).
+  *
+  * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
+  *	As specified in the &enum nl80211_rxmgmt_flags.
+@@ -2515,6 +2513,23 @@ enum nl80211_commands {
   * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from
   *	association request when used with NL80211_CMD_NEW_STATION).
   *
++ * @NL80211_ATTR_FILS_DISCOVERY: Optional parameter to configure FILS
++ *	discovery. It is a nested attribute, see
++ *	&enum nl80211_fils_discovery_attributes.
++ *
++ * @NL80211_ATTR_UNSOL_BCAST_PROBE_RESP: Optional parameter to configure
++ *	unsolicited broadcast probe response. It is a nested attribute, see
++ *	&enum nl80211_unsol_bcast_probe_resp_attributes.
++ *
++ * @NL80211_ATTR_S1G_CAPABILITY: S1G Capability information element (from
++ *	association request when used with NL80211_CMD_NEW_STATION)
++ * @NL80211_ATTR_S1G_CAPABILITY_MASK: S1G Capability Information element
++ *	override mask. Used with NL80211_ATTR_S1G_CAPABILITY in
++ *	NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT.
++ *
 + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
 + *	transmit power to stay within regulatory limits. u32, dBi.
 + *
   * @NUM_NL80211_ATTR: total number of nl80211_attrs available
   * @NL80211_ATTR_MAX: highest attribute number currently defined
   * @__NL80211_ATTR_AFTER_LAST: internal use
-@@ -2997,6 +3000,8 @@ enum nl80211_attrs {
+@@ -2821,8 +2836,8 @@ enum nl80211_attrs {
+ 	NL80211_ATTR_CH_SWITCH_COUNT,
+ 	NL80211_ATTR_CH_SWITCH_BLOCK_TX,
+ 	NL80211_ATTR_CSA_IES,
+-	NL80211_ATTR_CSA_C_OFF_BEACON,
+-	NL80211_ATTR_CSA_C_OFF_PRESP,
++	NL80211_ATTR_CNTDWN_OFFS_BEACON,
++	NL80211_ATTR_CNTDWN_OFFS_PRESP,
+ 
+ 	NL80211_ATTR_RXMGMT_FLAGS,
+ 
+@@ -2997,6 +3012,15 @@ enum nl80211_attrs {
  
  	NL80211_ATTR_HE_6GHZ_CAPABILITY,
  
++	NL80211_ATTR_FILS_DISCOVERY,
++
++	NL80211_ATTR_UNSOL_BCAST_PROBE_RESP,
++
++	NL80211_ATTR_S1G_CAPABILITY,
++	NL80211_ATTR_S1G_CAPABILITY_MASK,
++
 +	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
 +
  	/* add attributes here, update the policy in nl80211.c */
  
  	__NL80211_ATTR_AFTER_LAST,
+@@ -3009,6 +3033,8 @@ enum nl80211_attrs {
+ #define	NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG
+ #define NL80211_ATTR_IFACE_SOCKET_OWNER NL80211_ATTR_SOCKET_OWNER
+ #define NL80211_ATTR_SAE_DATA NL80211_ATTR_AUTH_DATA
++#define NL80211_ATTR_CSA_C_OFF_BEACON NL80211_ATTR_CNTDWN_OFFS_BEACON
++#define NL80211_ATTR_CSA_C_OFF_PRESP NL80211_ATTR_CNTDWN_OFFS_PRESP
+ 
+ /*
+  * Allow user space programs to use #ifdef on new attributes by defining them
+@@ -3186,6 +3212,18 @@ enum nl80211_he_gi {
+ 	NL80211_RATE_INFO_HE_GI_3_2,
+ };
+ 
++/**
++ * enum nl80211_he_ltf - HE long training field
++ * @NL80211_RATE_INFO_HE_1xLTF: 3.2 usec
++ * @NL80211_RATE_INFO_HE_2xLTF: 6.4 usec
++ * @NL80211_RATE_INFO_HE_4xLTF: 12.8 usec
++ */
++enum nl80211_he_ltf {
++	NL80211_RATE_INFO_HE_1XLTF,
++	NL80211_RATE_INFO_HE_2XLTF,
++	NL80211_RATE_INFO_HE_4XLTF,
++};
++
+ /**
+  * enum nl80211_he_ru_alloc - HE RU allocation values
+  * @NL80211_RATE_INFO_HE_RU_ALLOC_26: 26-tone RU allocation
+@@ -3725,6 +3763,16 @@ enum nl80211_wmm_rule {
+  * @NL80211_FREQUENCY_ATTR_NO_HE: HE operation is not allowed on this channel
+  *	in current regulatory domain.
+  * @NL80211_FREQUENCY_ATTR_OFFSET: frequency offset in KHz
++ * @NL80211_FREQUENCY_ATTR_1MHZ: 1 MHz operation is allowed
++ *	on this channel in current regulatory domain.
++ * @NL80211_FREQUENCY_ATTR_2MHZ: 2 MHz operation is allowed
++ *	on this channel in current regulatory domain.
++ * @NL80211_FREQUENCY_ATTR_4MHZ: 4 MHz operation is allowed
++ *	on this channel in current regulatory domain.
++ * @NL80211_FREQUENCY_ATTR_8MHZ: 8 MHz operation is allowed
++ *	on this channel in current regulatory domain.
++ * @NL80211_FREQUENCY_ATTR_16MHZ: 16 MHz operation is allowed
++ *	on this channel in current regulatory domain.
+  * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
+  *	currently defined
+  * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
+@@ -3756,6 +3804,11 @@ enum nl80211_frequency_attr {
+ 	NL80211_FREQUENCY_ATTR_WMM,
+ 	NL80211_FREQUENCY_ATTR_NO_HE,
+ 	NL80211_FREQUENCY_ATTR_OFFSET,
++	NL80211_FREQUENCY_ATTR_1MHZ,
++	NL80211_FREQUENCY_ATTR_2MHZ,
++	NL80211_FREQUENCY_ATTR_4MHZ,
++	NL80211_FREQUENCY_ATTR_8MHZ,
++	NL80211_FREQUENCY_ATTR_16MHZ,
+ 
+ 	/* keep last */
+ 	__NL80211_FREQUENCY_ATTR_AFTER_LAST,
+@@ -4049,6 +4102,7 @@ enum nl80211_user_reg_hint_type {
+  *	receiving frames destined to the local BSS
+  * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
+  *	currently defined
++ * @NL80211_SURVEY_INFO_FREQUENCY_OFFSET: center frequency offset in KHz
+  * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
+  */
+ enum nl80211_survey_info {
+@@ -4064,6 +4118,7 @@ enum nl80211_survey_info {
+ 	NL80211_SURVEY_INFO_TIME_SCAN,
+ 	NL80211_SURVEY_INFO_PAD,
+ 	NL80211_SURVEY_INFO_TIME_BSS_RX,
++	NL80211_SURVEY_INFO_FREQUENCY_OFFSET,
+ 
+ 	/* keep last */
+ 	__NL80211_SURVEY_INFO_AFTER_LAST,
+@@ -4741,6 +4796,10 @@ enum nl80211_key_attributes {
+  * @NL80211_TXRATE_VHT: VHT rates allowed for TX rate selection,
+  *	see &struct nl80211_txrate_vht
+  * @NL80211_TXRATE_GI: configure GI, see &enum nl80211_txrate_gi
++ * @NL80211_TXRATE_HE: HE rates allowed for TX rate selection,
++ *	see &struct nl80211_txrate_he
++ * @NL80211_TXRATE_HE_GI: configure HE GI, 0.8us, 1.6us and 3.2us.
++ * @NL80211_TXRATE_HE_LTF: configure HE LTF, 1XLTF, 2XLTF and 4XLTF.
+  * @__NL80211_TXRATE_AFTER_LAST: internal
+  * @NL80211_TXRATE_MAX: highest TX rate attribute
+  */
+@@ -4750,6 +4809,9 @@ enum nl80211_tx_rate_attributes {
+ 	NL80211_TXRATE_HT,
+ 	NL80211_TXRATE_VHT,
+ 	NL80211_TXRATE_GI,
++	NL80211_TXRATE_HE,
++	NL80211_TXRATE_HE_GI,
++	NL80211_TXRATE_HE_LTF,
+ 
+ 	/* keep last */
+ 	__NL80211_TXRATE_AFTER_LAST,
+@@ -4767,6 +4829,15 @@ struct nl80211_txrate_vht {
+ 	__u16 mcs[NL80211_VHT_NSS_MAX];
+ };
+ 
++#define NL80211_HE_NSS_MAX		8
++/**
++ * struct nl80211_txrate_he - HE MCS/NSS txrate bitmap
++ * @mcs: MCS bitmap table for each NSS (array index 0 for 1 stream, etc.)
++ */
++struct nl80211_txrate_he {
++	__u16 mcs[NL80211_HE_NSS_MAX];
++};
++
+ enum nl80211_txrate_gi {
+ 	NL80211_TXRATE_DEFAULT_GI,
+ 	NL80211_TXRATE_FORCE_SGI,
+@@ -5821,6 +5892,15 @@ enum nl80211_feature_flags {
+  *	handshake with PSK in AP mode (PSK is passed as part of the start AP
+  *	command).
+  *
++ * @NL80211_EXT_FEATURE_SAE_OFFLOAD_AP: Device wants to do SAE authentication
++ *	in AP mode (SAE password is passed as part of the start AP command).
++ *
++ * @NL80211_EXT_FEATURE_FILS_DISCOVERY: Driver/device supports FILS discovery
++ *	frames transmission
++ *
++ * @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports
++ *	unsolicited broadcast probe response transmission
++ *
+  * @NUM_NL80211_EXT_FEATURES: number of extended features.
+  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
+  */
+@@ -5878,6 +5958,9 @@ enum nl80211_ext_feature_index {
+ 	NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS,
+ 	NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION,
+ 	NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK,
++	NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
++	NL80211_EXT_FEATURE_FILS_DISCOVERY,
++	NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
+ 
+ 	/* add new features before the definition below */
+ 	NUM_NL80211_EXT_FEATURES,
+@@ -5992,6 +6075,8 @@ enum nl80211_timeout_reason {
+  * @NL80211_SCAN_FLAG_FREQ_KHZ: report scan results with
+  *	%NL80211_ATTR_SCAN_FREQ_KHZ. This also means
+  *	%NL80211_ATTR_SCAN_FREQUENCIES will not be included.
++ * @NL80211_SCAN_FLAG_COLOCATED_6GHZ: scan for colocated APs reported by
++ *	2.4/5 GHz APs
+  */
+ enum nl80211_scan_flags {
+ 	NL80211_SCAN_FLAG_LOW_PRIORITY				= 1<<0,
+@@ -6008,6 +6093,7 @@ enum nl80211_scan_flags {
+ 	NL80211_SCAN_FLAG_RANDOM_SN				= 1<<11,
+ 	NL80211_SCAN_FLAG_MIN_PREQ_CONTENT			= 1<<12,
+ 	NL80211_SCAN_FLAG_FREQ_KHZ				= 1<<13,
++	NL80211_SCAN_FLAG_COLOCATED_6GHZ			= 1<<14,
+ };
+ 
+ /**
+@@ -6910,6 +6996,13 @@ enum nl80211_peer_measurement_ftm_resp {
+  *
+  * @NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET: the OBSS PD minimum tx power offset.
+  * @NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET: the OBSS PD maximum tx power offset.
++ * @NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET: the non-SRG OBSS PD maximum
++ *	tx power offset.
++ * @NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP: bitmap that indicates the BSS color
++ *	values used by members of the SRG.
++ * @NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP: bitmap that indicates the partial
++ *	BSSID values used by members of the SRG.
++ * @NL80211_HE_OBSS_PD_ATTR_SR_CTRL: The SR Control field of SRP element.
+  *
+  * @__NL80211_HE_OBSS_PD_ATTR_LAST: Internal
+  * @NL80211_HE_OBSS_PD_ATTR_MAX: highest OBSS PD attribute.
+@@ -6919,6 +7012,10 @@ enum nl80211_obss_pd_attributes {
+ 
+ 	NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET,
+ 	NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET,
++	NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET,
++	NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP,
++	NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP,
++	NL80211_HE_OBSS_PD_ATTR_SR_CTRL,
+ 
+ 	/* keep last */
+ 	__NL80211_HE_OBSS_PD_ATTR_LAST,
+@@ -6972,4 +7069,64 @@ enum nl80211_iftype_akm_attributes {
+ 	NL80211_IFTYPE_AKM_ATTR_MAX = __NL80211_IFTYPE_AKM_ATTR_LAST - 1,
+ };
+ 
++/**
++ * enum nl80211_fils_discovery_attributes - FILS discovery configuration
++ * from IEEE Std 802.11ai-2016, Annex C.3 MIB detail.
++ *
++ * @__NL80211_FILS_DISCOVERY_ATTR_INVALID: Invalid
++ *
++ * @NL80211_FILS_DISCOVERY_ATTR_INT_MIN: Minimum packet interval (u32, TU).
++ *	Allowed range: 0..10000 (TU = Time Unit)
++ * @NL80211_FILS_DISCOVERY_ATTR_INT_MAX: Maximum packet interval (u32, TU).
++ *	Allowed range: 0..10000 (TU = Time Unit)
++ * @NL80211_FILS_DISCOVERY_ATTR_TMPL: Template data for FILS discovery action
++ *	frame including the headers.
++ *
++ * @__NL80211_FILS_DISCOVERY_ATTR_LAST: Internal
++ * @NL80211_FILS_DISCOVERY_ATTR_MAX: highest attribute
++ */
++enum nl80211_fils_discovery_attributes {
++	__NL80211_FILS_DISCOVERY_ATTR_INVALID,
++
++	NL80211_FILS_DISCOVERY_ATTR_INT_MIN,
++	NL80211_FILS_DISCOVERY_ATTR_INT_MAX,
++	NL80211_FILS_DISCOVERY_ATTR_TMPL,
++
++	/* keep last */
++	__NL80211_FILS_DISCOVERY_ATTR_LAST,
++	NL80211_FILS_DISCOVERY_ATTR_MAX = __NL80211_FILS_DISCOVERY_ATTR_LAST - 1
++};
++
++/*
++ * FILS discovery template minimum length with action frame headers and
++ * mandatory fields.
++ */
++#define NL80211_FILS_DISCOVERY_TMPL_MIN_LEN 42
++
++/**
++ * enum nl80211_unsol_bcast_probe_resp_attributes - Unsolicited broadcast probe
++ *	response configuration. Applicable only in 6GHz.
++ *
++ * @__NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INVALID: Invalid
++ *
++ * @NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT: Maximum packet interval (u32, TU).
++ *	Allowed range: 0..20 (TU = Time Unit). IEEE P802.11ax/D6.0
++ *	26.17.2.3.2 (AP behavior for fast passive scanning).
++ * @NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL: Unsolicited broadcast probe response
++ *	frame template (binary).
++ *
++ * @__NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST: Internal
++ * @NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX: highest attribute
++ */
++enum nl80211_unsol_bcast_probe_resp_attributes {
++	__NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INVALID,
++
++	NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT,
++	NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL,
++
++	/* keep last */
++	__NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST,
++	NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX =
++		__NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST - 1
++};
+ #endif /* __LINUX_NL80211_H */



More information about the lede-commits mailing list