[rdkb][common][bsp][Refactor and sync wifi from openwrt]

[Description]
3a2eef0b [MAC80211][Release][Update release note for Filogic 880/860 MLO Beta release]
cfbd2411 [MAC80211][Release][Filogic 880/860 MLO Beta release]
6c180e3f [MAC80211][WiFi7][misc][Add Eagle BE14000 efem default bin]
a55f34db [MAC80211][Release][Prepare for Filogic 880/860 release]
5b45ebca [MAC80211][WiFi7][hostapd][Add puncture bitmap to ucode]
95bbea73 [MAC80211][WiFi6][mt76][Add PID to only report data-frame TX rate]
b15ced26 [MAC80211][WiFi6][hostapd][Fix DFS channel selection issue]
d59133cb [MAC80211][WiFi6][mt76][Fix pse info not correct information]
3921b4b2 [MAC80211][WiFi6][mt76][Fix incomplete QoS-map setting to FW]
4e7690c7 [MAC80211][WiFi6/7][app][Change ATECHANNEL mapping cmd]
eb37af90 [MAC80211][WiFi7][app][Add support for per-packet bw & primary selection]
0ea82adf [MAC80211][WiFi6][core][Fix DFS CAC issue after CSA]

[Release-log]

Change-Id: I9bec97ec1b2e1c49ed43a812a07a5b21fcbb70a6
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0001-sync-backports-patches-build.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0001-backports-sync-openwrt-patches-build.patch
similarity index 73%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0001-sync-backports-patches-build.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0001-backports-sync-openwrt-patches-build.patch
index e926f0b..17147cd 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0001-sync-backports-patches-build.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0001-backports-sync-openwrt-patches-build.patch
@@ -1,13 +1,19 @@
-From 45a2c927c790c9f71a81983f6d59b15cfb6b05ac Mon Sep 17 00:00:00 2001
+From a0f11f79e303ee8fc152c388bf58ed192e735102 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 12 Mar 2024 11:25:41 +0800
-Subject: [PATCH 01/61] sync backports patches/build
+Date: Wed, 17 Jul 2024 20:40:32 +0800
+Subject: [PATCH 01/89] backports: sync openwrt patches/build
 
 ---
  Kconfig.local                                 | 111 -----------------
  Kconfig.sources                               |   5 -
- Makefile                                      | 116 +++++++++---------
+ Makefile                                      | 115 ++++++++++--------
+ Makefile.kernel                               |   4 -
  Makefile.real                                 |  29 ++++-
+ .../linux/bcma/bcma_driver_chipcommon.h       |  10 ++
+ backport-include/linux/iommu.h                |  23 ++++
+ backport-include/linux/list.h                 |   2 +-
+ backport-include/linux/random.h               |   2 +-
+ backport-include/net/dropreason.h             |   3 +-
  compat/main.c                                 |  25 ----
  drivers/net/wireless/ath/ath11k/Kconfig       |   6 +-
  drivers/net/wireless/broadcom/b43/Kconfig     |  12 +-
@@ -15,20 +21,24 @@
  .../net/wireless/broadcom/b43legacy/Kconfig   |   8 +-
  .../net/wireless/broadcom/b43legacy/main.c    |   4 +-
  .../net/wireless/broadcom/brcm80211/Kconfig   |   2 +-
- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |   2 +-
- drivers/net/wireless/intel/iwlwifi/mvm/tt.c   |  21 ++--
+ .../broadcom/brcm80211/brcmfmac/usb.c         |   4 +
+ drivers/net/wireless/intel/iwlwifi/mvm/tt.c   |  10 ++
  drivers/staging/rtl8723bs/Kconfig             |   1 -
  kconf/Makefile                                |   4 +-
  kconf/conf.c                                  |  30 +----
  kconf/confdata.c                              |   4 +-
  local-symbols                                 |  45 -------
- 18 files changed, 118 insertions(+), 311 deletions(-)
+ net/wireless/nl80211.c                        |  10 ++
+ net/wireless/sysfs.c                          |   4 +
+ 26 files changed, 171 insertions(+), 306 deletions(-)
+ create mode 100644 backport-include/linux/bcma/bcma_driver_chipcommon.h
+ create mode 100644 backport-include/linux/iommu.h
 
 diff --git a/Kconfig.local b/Kconfig.local
-index d9495b1..547f8ad 100644
+index 91158d6..f142374 100644
 --- a/Kconfig.local
 +++ b/Kconfig.local
-@@ -1420,117 +1420,6 @@ config BACKPORTED_USB_NET_AQC111
+@@ -1414,117 +1414,6 @@ config BACKPORTED_USB_NET_AQC111
  config BACKPORTED_USB_RTL8153_ECM
  	tristate
  	default USB_RTL8153_ECM
@@ -167,7 +177,7 @@
  
  source "$BACKPORT_DIR/drivers/staging/Kconfig"
 diff --git a/Makefile b/Makefile
-index 77c2670..c431b71 100644
+index 548d813..989faff 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -2,10 +2,10 @@
@@ -201,7 +211,7 @@
  	@set -e ; test -f local-symbols || (						\
  	echo "/--------------"								;\
  	echo "| You shouldn't run make in the backports tree, but only in"		;\
-@@ -60,58 +62,62 @@ mrproper:
+@@ -60,57 +62,62 @@ mrproper:
  	echo "| (that isn't currently running.)"					;\
  	echo "\\--"									;\
  	false)
@@ -230,13 +240,12 @@
 -			done								\
 -		) > Kconfig.kernel							;\
 -		kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR)	\
--			kernelversion |	sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
+-			kernelversion |	sed 's/^\(\([3-6]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
 -		test "$$kver" != "" || echo "Kernel version parse failed!"		;\
 -		test "$$kver" != ""							;\
--		kvers="$$(seq 14 39 | sed 's/^/2.6./')"					;\
--		kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')"				;\
 -		kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')"				;\
--		kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')"				;\
+-		kvers="$$kvers $$(seq 0 19 | sed 's/^/5./')"				;\
+-		kvers="$$kvers $$(seq 0 20 | sed 's/^/6./')"				;\
 -		print=0									;\
 -		for v in $$kvers ; do							\
 -			if [ "$$print" = "1" ] ; then					\
@@ -286,14 +295,13 @@
 +	@echo " done."
 +
 +Kconfig.versions: Kconfig.kernel
-+	@kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \
-+		kernelversion |	sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
++	@kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR)	\
++		kernelversion |	sed 's/^\(\([3-6]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
 +	test "$$kver" != "" || echo "Kernel version parse failed!"		;\
 +	test "$$kver" != ""							;\
-+	kvers="$$(seq 14 39 | sed 's/^/2.6./')"					;\
-+	kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')"				;\
 +	kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')"				;\
-+	kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')"				;\
++	kvers="$$kvers $$(seq 0 19 | sed 's/^/5./')"				;\
++	kvers="$$kvers $$(seq 0 20 | sed 's/^/6./')"				;\
 +	print=0									;\
 +	for v in $$kvers ; do							\
 +		if [ "$$print" = "1" ] ; then					\
@@ -301,8 +309,9 @@
 +			echo "    def_bool y"					;\
 +		fi								;\
 +		if [ "$$v" = "$$kver" ] ; then print=1 ; fi			;\
-+	done > $@
-+	@RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | 			\
++	done > Kconfig.versions							;\
++	# RHEL as well, sadly we need to grep for it				;\
++	RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | 			\
 +				sed 's/.*=\s*\([0-9]*\)/\1/;t;d')		;\
 +	RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | 			\
 +				sed 's/.*=\s*\([0-9]*\)/\1/;t;d')		;\
@@ -316,6 +325,23 @@
  	@$(MAKE) -f Makefile.real "$@"
  
  .PHONY: defconfig-help
+diff --git a/Makefile.kernel b/Makefile.kernel
+index 9d9c341..c72a1ab 100644
+--- a/Makefile.kernel
++++ b/Makefile.kernel
+@@ -38,12 +38,8 @@ obj-y += compat/
+ 
+ obj-$(CPTCFG_CFG80211) += net/wireless/
+ obj-$(CPTCFG_MAC80211) += net/mac80211/
+-obj-$(CPTCFG_QRTR) += net/qrtr/
+ obj-$(CPTCFG_QCOM_QMI_HELPERS) += drivers/soc/qcom/
+-obj-$(CPTCFG_MHI_BUS) += drivers/bus/mhi/
+ #obj-$(CPTCFG_WLAN) += drivers/net/wireless/
+-obj-$(CPTCFG_SSB) += drivers/ssb/
+-obj-$(CPTCFG_BCMA) += drivers/bcma/
+ obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
+ 
+ obj-$(CPTCFG_USB_WDM) += drivers/usb/class/
 diff --git a/Makefile.real b/Makefile.real
 index 6550802..971a543 100644
 --- a/Makefile.real
@@ -388,6 +414,93 @@
  	@echo " done."
  
  .PHONY: modules
+diff --git a/backport-include/linux/bcma/bcma_driver_chipcommon.h b/backport-include/linux/bcma/bcma_driver_chipcommon.h
+new file mode 100644
+index 0000000..42e028b
+--- /dev/null
++++ b/backport-include/linux/bcma/bcma_driver_chipcommon.h
+@@ -0,0 +1,10 @@
++#ifndef __BACKPORT_BCMA_DRIVER_CHIPCOMMON_H
++#define __BACKPORT_BCMA_DRIVER_CHIPCOMMON_H
++
++#include_next <linux/bcma/bcma_driver_chipcommon.h>
++
++#ifndef BCMA_CC_SROM_CONTROL_OTP_PRESENT
++#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020
++#endif
++
++#endif
+diff --git a/backport-include/linux/iommu.h b/backport-include/linux/iommu.h
+new file mode 100644
+index 0000000..1c1e877
+--- /dev/null
++++ b/backport-include/linux/iommu.h
+@@ -0,0 +1,23 @@
++#ifndef __BACKPORT_LINUX_IOMMU_H
++#define __BACKPORT_LINUX_IOMMU_H
++
++#include_next <linux/iommu.h>
++#include <linux/version.h>
++
++#if LINUX_VERSION_IS_LESS(6,3,0)
++
++static inline int LINUX_BACKPORT(iommu_map)(struct iommu_domain *domain,
++					    unsigned long iova,
++					    phys_addr_t paddr, size_t size,
++					    int prot, gfp_t gfp)
++{
++	if (gfp == GFP_ATOMIC)
++		return iommu_map_atomic(domain, iova, paddr, size, prot);
++
++	return iommu_map(domain, iova, paddr, size, prot);
++}
++#define iommu_map LINUX_BACKPORT(iommu_map)
++
++#endif /* < 6.3 */
++
++#endif
+diff --git a/backport-include/linux/list.h b/backport-include/linux/list.h
+index 78367e9..a948c22 100644
+--- a/backport-include/linux/list.h
++++ b/backport-include/linux/list.h
+@@ -3,7 +3,7 @@
+ #include_next <linux/list.h>
+ #include <linux/version.h>
+ 
+-#if LINUX_VERSION_IS_LESS(6,3,0)
++#if 0 /* OpenWrt backports list_count_nodes() on its own */
+ /**
+  * list_count_nodes - count nodes in the list
+  * @head:	the head for your list.
+diff --git a/backport-include/linux/random.h b/backport-include/linux/random.h
+index 51bb17d..ca206c4 100644
+--- a/backport-include/linux/random.h
++++ b/backport-include/linux/random.h
+@@ -15,7 +15,7 @@ static inline u16 get_random_u16(void)
+ }
+ #endif
+ 
+-#if LINUX_VERSION_IS_LESS(6,2,0)
++#if LINUX_VERSION_IS_LESS(6,1,4)
+ static inline u32 __get_random_u32_below(u32 ceil)
+ {
+ 	/*
+diff --git a/backport-include/net/dropreason.h b/backport-include/net/dropreason.h
+index ec74e71..ab6a632 100644
+--- a/backport-include/net/dropreason.h
++++ b/backport-include/net/dropreason.h
+@@ -3,10 +3,9 @@
+ 
+ #include <linux/version.h>
+ 
++#include <net/dropreason-core.h>
+ #if LINUX_VERSION_IS_GEQ(6,0,0)
+ #include_next <net/dropreason.h>
+-#else
+-#include <net/dropreason-core.h>
+ #endif
+ 
+ #if LINUX_VERSION_IS_LESS(6,4,0)
 diff --git a/compat/main.c b/compat/main.c
 index d4f3340..651ab63 100644
 --- a/compat/main.c
@@ -488,7 +601,7 @@
  
  config B43_PHY_G
 diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c
-index c2e0a05..bf2be0a 100644
+index a9e16ad..b6dbcdb 100644
 --- a/drivers/net/wireless/broadcom/b43/main.c
 +++ b/drivers/net/wireless/broadcom/b43/main.c
 @@ -2854,7 +2854,7 @@ static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)
@@ -542,7 +655,7 @@
  
  # LED support
 diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c
-index edd91ff..0222f63 100644
+index 1154b4a..f2873a1 100644
 --- a/drivers/net/wireless/broadcom/b43legacy/main.c
 +++ b/drivers/net/wireless/broadcom/b43legacy/main.c
 @@ -1907,7 +1907,7 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
@@ -576,81 +689,50 @@
  	select BRCMUTIL
  	depends on FW_LOADER
  	depends on CORDIC
-diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
-index b1a1ce5..66f9281 100644
---- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
-+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
-@@ -555,7 +555,7 @@ struct iwl_mvm_tt_mgmt {
-  * @tzone: thermal zone device data
- */
- struct iwl_mvm_thermal_device {
--	struct thermal_trip trips[IWL_MAX_DTS_TRIPS];
-+	s16 temp_trips[IWL_MAX_DTS_TRIPS];
- 	u8 fw_trips_index[IWL_MAX_DTS_TRIPS];
- 	struct thermal_zone_device *tzone;
- };
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+index 8afbf52..2a2831b 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+@@ -1574,7 +1574,11 @@ static int brcmf_usb_reset_device(struct device *dev, void *notused)
+ 
+ void brcmf_usb_exit(void)
+ {
++#if LINUX_VERSION_IS_GEQ(6,8,0)
+ 	struct device_driver *drv = &brcmf_usbdrvr.driver;
++#else
++	struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver;
++#endif
+ 	int ret;
+ 
+ 	brcmf_dbg(USB, "Enter\n");
 diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
-index dee9c36..1fb364d 100644
+index 718184b..2f4c792 100644
 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
 +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
-@@ -573,11 +573,11 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
- 	 * and uncompressed, the FW should get it compressed and sorted
- 	 */
- 
--	/* compress trips to cmd array, remove uninitialized values*/
-+	/* compress temp_trips to cmd array, remove uninitialized values*/
- 	for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
--		if (mvm->tz_device.trips[i].temperature != INT_MIN) {
-+		if (mvm->tz_device.temp_trips[i] != S16_MIN) {
- 			cmd.thresholds[idx++] =
--				cpu_to_le16((s16)(mvm->tz_device.trips[i].temperature / 1000));
-+				cpu_to_le16(mvm->tz_device.temp_trips[i]);
- 		}
- 	}
- 	cmd.num_temps = cpu_to_le32(idx);
-@@ -593,8 +593,8 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
- 	 */
- 	for (i = 0; i < idx; i++) {
- 		for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) {
--			if ((int)(le16_to_cpu(cmd.thresholds[i]) * 1000) ==
--			    mvm->tz_device.trips[j].temperature)
-+			if (le16_to_cpu(cmd.thresholds[i]) ==
-+				mvm->tz_device.temp_trips[j])
- 				mvm->tz_device.fw_trips_index[i] = j;
- 		}
+@@ -676,13 +676,23 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
+ 	for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) {
+ 		mvm->tz_device.trips[i].temperature = THERMAL_TEMP_INVALID;
+ 		mvm->tz_device.trips[i].type = THERMAL_TRIP_PASSIVE;
++#if LINUX_VERSION_IS_GEQ(6,9,0)
+ 		mvm->tz_device.trips[i].flags = THERMAL_TRIP_FLAG_RW_TEMP;
++#endif
  	}
-@@ -665,6 +665,8 @@ out:
- 
- static  struct thermal_zone_device_ops tzone_ops = {
- 	.get_temp = iwl_mvm_tzone_get_temp,
-+	.get_trip_temp = iwl_mvm_tzone_get_trip_temp,
-+	.get_trip_type = iwl_mvm_tzone_get_trip_type,
- 	.set_trip_temp = iwl_mvm_tzone_set_trip_temp,
- };
- 
-@@ -686,8 +688,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
- 	BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
- 
- 	sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
--	mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
--							mvm->tz_device.trips,
-+	mvm->tz_device.tzone = thermal_zone_device_register(name,
++#if LINUX_VERSION_IS_GEQ(6,9,0)
+ 	mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
+ 							mvm->tz_device.trips,
  							IWL_MAX_DTS_TRIPS,
- 							IWL_WRITABLE_TRIPS_MSK,
  							mvm, &tzone_ops,
-@@ -710,10 +711,8 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
- 	/* 0 is a valid temperature,
- 	 * so initialize the array with S16_MIN which invalid temperature
- 	 */
--	for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) {
--		mvm->tz_device.trips[i].temperature = INT_MIN;
--		mvm->tz_device.trips[i].type = THERMAL_TRIP_PASSIVE;
--	}
-+	for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++)
-+		mvm->tz_device.temp_trips[i] = S16_MIN;
- }
- 
- static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,
+ 							NULL, 0, 0);
++#else
++	mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
++							mvm->tz_device.trips,
++							IWL_MAX_DTS_TRIPS, 0,
++							mvm, &tzone_ops,
++							NULL, 0, 0);
++#endif
+ 	if (IS_ERR(mvm->tz_device.tzone)) {
+ 		IWL_DEBUG_TEMP(mvm,
+ 			       "Failed to register to thermal zone (err = %ld)\n",
 diff --git a/drivers/staging/rtl8723bs/Kconfig b/drivers/staging/rtl8723bs/Kconfig
 index b51916c..b46ff98 100644
 --- a/drivers/staging/rtl8723bs/Kconfig
@@ -748,10 +830,10 @@
  	 * We have different type of choice blocks.
  	 * If curr.tri equals to mod then we can select several
 diff --git a/local-symbols b/local-symbols
-index 078fe8b..0743888 100644
+index 243f776..d7653ac 100644
 --- a/local-symbols
 +++ b/local-symbols
-@@ -67,14 +67,6 @@ MAC80211_MESH_PS_DEBUG=
+@@ -59,14 +59,6 @@ MAC80211_MESH_PS_DEBUG=
  MAC80211_TDLS_DEBUG=
  MAC80211_DEBUG_COUNTERS=
  MAC80211_STA_HASH_MAX_SIZE=
@@ -766,7 +848,7 @@
  QCOM_AOSS_QMP=
  QCOM_COMMAND_DB=
  QCOM_GENI_SE=
-@@ -472,43 +464,6 @@ USB_VL600=
+@@ -470,43 +462,6 @@ USB_VL600=
  USB_NET_CH9200=
  USB_NET_AQC111=
  USB_RTL8153_ECM=
@@ -810,6 +892,56 @@
  USB_ACM=
  USB_PRINTER=
  USB_WDM=
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index cbc5626..6f7273a 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -16542,9 +16542,14 @@ static u32 nl80211_internal_flags[] = {
+ #undef SELECTOR
+ };
+ 
++#if LINUX_VERSION_IS_LESS(6,2,0)
++static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
++			    struct genl_info *info)
++#else
+ static int nl80211_pre_doit(const struct genl_split_ops *ops,
+ 			    struct sk_buff *skb,
+ 			    struct genl_info *info)
++#endif
+ {
+ 	struct cfg80211_registered_device *rdev = NULL;
+ 	struct wireless_dev *wdev = NULL;
+@@ -16644,9 +16649,14 @@ out_unlock:
+ 	return err;
+ }
+ 
++#if LINUX_VERSION_IS_LESS(6,2,0)
++static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
++			      struct genl_info *info)
++#else
+ static void nl80211_post_doit(const struct genl_split_ops *ops,
+ 			      struct sk_buff *skb,
+ 			      struct genl_info *info)
++#endif
+ {
+ 	u32 internal_flags = nl80211_internal_flags[ops->internal_flags];
+ 
+diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
+index 62f2661..4f855bf 100644
+--- a/net/wireless/sysfs.c
++++ b/net/wireless/sysfs.c
+@@ -154,7 +154,11 @@ static SIMPLE_DEV_PM_OPS(wiphy_pm_ops, wiphy_suspend, wiphy_resume);
+ #define WIPHY_PM_OPS NULL
+ #endif
+ 
++#if LINUX_VERSION_IS_GEQ(6,2,0)
+ static const void *wiphy_namespace(const struct device *d)
++#else
++static const void *wiphy_namespace(struct device *d)
++#endif
+ {
+ 	struct wiphy *wiphy = container_of(d, struct wiphy, dev);
+ 
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0002-sync-backports-patches-ath.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0002-backports-sync-openwrt-patches-ath.patch
similarity index 67%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0002-sync-backports-patches-ath.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0002-backports-sync-openwrt-patches-ath.patch
index f47e6f5..2995c8e 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0002-sync-backports-patches-ath.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0002-backports-sync-openwrt-patches-ath.patch
@@ -1,24 +1,18 @@
-From 429745cbf1435d31a656d4d912b7ea1cdd271be2 Mon Sep 17 00:00:00 2001
+From bcafe92bd89916905cdff549d4919429b845ccba Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 12 Mar 2024 11:26:07 +0800
-Subject: [PATCH 02/61] sync backports patches/ath
+Date: Wed, 17 Jul 2024 20:40:58 +0800
+Subject: [PATCH 02/89] backports: sync openwrt patches/ath
 
 ---
- drivers/net/wireless/ath/Kconfig              |  5 +-
- drivers/net/wireless/ath/Makefile             |  2 +-
- drivers/net/wireless/ath/ath.h                | 17 ++---
- drivers/net/wireless/ath/ath5k/ani.c          |  2 +-
- drivers/net/wireless/ath/ath5k/base.c         |  4 +-
- drivers/net/wireless/ath/ath5k/mac80211-ops.c |  2 +-
- drivers/net/wireless/ath/ath5k/pci.c          | 26 ++++++-
- drivers/net/wireless/ath/ath9k/link.c         |  2 +-
- drivers/net/wireless/ath/ath9k/main.c         |  4 +-
- drivers/net/wireless/ath/hw.c                 |  2 +-
- drivers/net/wireless/ath/regd.c               | 72 +++++++++++++------
- drivers/net/wireless/ath/regd_common.h        |  3 +
- local-symbols                                 |  1 +
- net/wireless/reg.c                            |  3 +
- 14 files changed, 102 insertions(+), 43 deletions(-)
+ drivers/net/wireless/ath/Kconfig       |  5 +-
+ drivers/net/wireless/ath/Makefile      |  2 +-
+ drivers/net/wireless/ath/ath.h         |  7 ---
+ drivers/net/wireless/ath/ath5k/pci.c   | 26 +++++++++-
+ drivers/net/wireless/ath/regd.c        | 72 ++++++++++++++++++--------
+ drivers/net/wireless/ath/regd_common.h |  3 ++
+ local-symbols                          |  1 +
+ net/wireless/reg.c                     |  3 ++
+ 8 files changed, 88 insertions(+), 31 deletions(-)
 
 diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
 index 9ef8d46..bd576b4 100644
@@ -59,27 +53,10 @@
  
  CFLAGS_trace.o := -I$(src)
 diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
-index e9d95c7..888c5e2 100644
+index 1bfd992..eb63efd 100644
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -43,10 +43,12 @@ struct ath_ani {
- };
- 
- struct ath_cycle_counters {
--	u32 cycles;
--	u32 rx_busy;
--	u32 rx_frame;
--	u32 tx_frame;
-+	struct_group(cnts,
-+		u32 cycles;
-+		u32 rx_busy;
-+		u32 rx_frame;
-+		u32 tx_frame;
-+	);
- };
- 
- enum ath_device_state {
-@@ -319,14 +321,7 @@ void _ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask,
+@@ -321,14 +321,7 @@ void _ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask,
  #endif /* CPTCFG_ATH_DEBUG */
  
  /** Returns string describing opmode, or NULL if unknown mode. */
@@ -94,47 +71,6 @@
  
  extern const char *ath_bus_type_strings[];
  static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype)
-diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
-index 11fd1ca..897cfd9 100644
---- a/drivers/net/wireless/ath/ath5k/ani.c
-+++ b/drivers/net/wireless/ath/ath5k/ani.c
-@@ -379,7 +379,7 @@ ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
- 	spin_lock_bh(&common->cc_lock);
- 
- 	ath_hw_cycle_counters_update(common);
--	memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc));
-+	memcpy(&as->last_cc.cnts, &common->cc_ani.cnts, sizeof(as->last_cc.cnts));
- 
- 	/* clears common->cc_ani */
- 	listen = ath_hw_get_listen_time(common);
-diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
-index 7ec5d9a..bad83fd 100644
---- a/drivers/net/wireless/ath/ath5k/base.c
-+++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -2985,8 +2985,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
- 	memset(&ah->survey, 0, sizeof(ah->survey));
- 	spin_lock_bh(&common->cc_lock);
- 	ath_hw_cycle_counters_update(common);
--	memset(&common->cc_survey, 0, sizeof(common->cc_survey));
--	memset(&common->cc_ani, 0, sizeof(common->cc_ani));
-+	memset(&common->cc_survey.cnts, 0, sizeof(common->cc_survey.cnts));
-+	memset(&common->cc_ani.cnts, 0, sizeof(common->cc_ani.cnts));
- 	spin_unlock_bh(&common->cc_lock);
- 
- 	/*
-diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-index eea4bda..da9dc62 100644
---- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-@@ -664,7 +664,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
- 		ah->survey.time_rx += cc->rx_frame / div;
- 		ah->survey.time_tx += cc->tx_frame / div;
- 	}
--	memset(cc, 0, sizeof(*cc));
-+	memset(&cc->cnts, 0, sizeof(cc->cnts));
- 	spin_unlock_bh(&common->cc_lock);
- 
- 	memcpy(survey, &ah->survey, sizeof(*survey));
 diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
 index b51fce5..c4315dd 100644
 --- a/drivers/net/wireless/ath/ath5k/pci.c
@@ -193,47 +129,6 @@
  	AR5K_EEPROM_READ(0x20, data);
  
  	for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
-diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
-index d1e5767..7f18d71 100644
---- a/drivers/net/wireless/ath/ath9k/link.c
-+++ b/drivers/net/wireless/ath/ath9k/link.c
-@@ -536,7 +536,7 @@ int ath_update_survey_stats(struct ath_softc *sc)
- 	if (cc->cycles > 0)
- 		ret = cc->rx_busy * 100 / cc->cycles;
- 
--	memset(cc, 0, sizeof(*cc));
-+	memset(&cc->cnts, 0, sizeof(cc->cnts));
- 
- 	ath_update_survey_nf(sc, pos);
- 
-diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
-index 34d11b0..6d120df 100644
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -135,8 +135,8 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
- 	if (power_mode != ATH9K_PM_AWAKE) {
- 		spin_lock(&common->cc_lock);
- 		ath_hw_cycle_counters_update(common);
--		memset(&common->cc_survey, 0, sizeof(common->cc_survey));
--		memset(&common->cc_ani, 0, sizeof(common->cc_ani));
-+		memset(&common->cc_survey.cnts, 0, sizeof(common->cc_survey.cnts));
-+		memset(&common->cc_ani.cnts, 0, sizeof(common->cc_ani.cnts));
- 		spin_unlock(&common->cc_lock);
- 	}
- 
-diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
-index 8595557..be8bfed 100644
---- a/drivers/net/wireless/ath/hw.c
-+++ b/drivers/net/wireless/ath/hw.c
-@@ -183,7 +183,7 @@ int32_t ath_hw_get_listen_time(struct ath_common *common)
- 	listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
- 		      (common->clockrate * 1000);
- 
--	memset(cc, 0, sizeof(*cc));
-+	memset(&cc->cnts, 0, sizeof(cc->cnts));
- 
- 	return listen_time;
- }
 diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
 index 2afdebf..3ba9fc3 100644
 --- a/drivers/net/wireless/ath/regd.c
@@ -445,10 +340,10 @@
  	{CTRY_UNITED_STATES3, FCC3_FCCA, "US"},
  	/* This "PS" is for US public safety actually... to support this we
 diff --git a/local-symbols b/local-symbols
-index 0743888..b200b00 100644
+index d7653ac..3421d93 100644
 --- a/local-symbols
 +++ b/local-symbols
-@@ -101,6 +101,7 @@ ADM8211=
+@@ -94,6 +94,7 @@ ADM8211=
  ATH_COMMON=
  WLAN_VENDOR_ATH=
  ATH_DEBUG=
@@ -457,7 +352,7 @@
  ATH_REG_DYNAMIC_USER_REG_HINTS=
  ATH_REG_DYNAMIC_USER_CERT_TESTING=
 diff --git a/net/wireless/reg.c b/net/wireless/reg.c
-index 233ebab..2c0c1f1 100644
+index 1accfff..4219dc2 100644
 --- a/net/wireless/reg.c
 +++ b/net/wireless/reg.c
 @@ -3365,6 +3365,8 @@ void regulatory_hint_country_ie(struct wiphy *wiphy, enum nl80211_band band,
@@ -478,5 +373,5 @@
  	 * ignore IE from connected access point but clearance of beacon hints
  	 * is required when wiphy(s) supports beacon hints.
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0003-sync-backports-patches-ath5k.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0003-backports-sync-openwrt-patches-ath5k.patch
similarity index 97%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0003-sync-backports-patches-ath5k.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0003-backports-sync-openwrt-patches-ath5k.patch
index e0051b5..e233678 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0003-sync-backports-patches-ath5k.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0003-backports-sync-openwrt-patches-ath5k.patch
@@ -1,7 +1,7 @@
-From 410e3c08cd5f7bd85e3ca3965fcbf79b9eb6d1e4 Mon Sep 17 00:00:00 2001
+From 3443489559c628356163e9bd4613152c1f6a4ffa Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 12 Mar 2024 11:26:26 +0800
-Subject: [PATCH 03/61] sync backports patches/ath5k
+Date: Wed, 17 Jul 2024 20:41:10 +0800
+Subject: [PATCH 03/89] backports: sync openwrt patches/ath5k
 
 ---
  drivers/net/wireless/ath/ath5k/ath5k.h        |  1 +
@@ -29,7 +29,7 @@
  
  	/* Antenna Control */
 diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
-index bad83fd..fb0366c 100644
+index d7adbf2..1cfabd6 100644
 --- a/drivers/net/wireless/ath/ath5k/base.c
 +++ b/drivers/net/wireless/ath/ath5k/base.c
 @@ -465,6 +465,9 @@ ath5k_chan_set(struct ath5k_hw *ah, struct cfg80211_chan_def *chandef)
@@ -222,7 +222,7 @@
  	{ AR5K_TOPS,		8 },
  	{ AR5K_RXNOFRM,		8 },
 diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-index da9dc62..2fb37d3 100644
+index eea4bda..67efda7 100644
 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
 +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
 @@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
@@ -311,5 +311,5 @@
 +
 +#endif /* _LINUX_ATH5K_PLATFORM_H */
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0004-sync-backports-patches-ath9k.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0004-backports-sync-openwrt-patches-ath9k.patch
similarity index 96%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0004-sync-backports-patches-ath9k.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0004-backports-sync-openwrt-patches-ath9k.patch
index 93b4572..e23257f 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0004-sync-backports-patches-ath9k.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0004-backports-sync-openwrt-patches-ath9k.patch
@@ -1,13 +1,13 @@
-From 58736b0bd1ae576889c23c0639aa36f29ab6a74f Mon Sep 17 00:00:00 2001
+From 4c05df4286198949bf3022827e3ebf897e181784 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 12 Mar 2024 11:26:51 +0800
-Subject: [PATCH 04/61] sync backports patches/ath9k
+Date: Wed, 17 Jul 2024 20:41:29 +0800
+Subject: [PATCH 04/89] backports: sync openwrt patches/ath9k
 
 ---
  drivers/net/wireless/ath/ath.h                |   2 +
  drivers/net/wireless/ath/ath9k/Kconfig        |  13 +
  drivers/net/wireless/ath/ath9k/Makefile       |   1 +
- drivers/net/wireless/ath/ath9k/ahb.c          | 260 ++++++++++++-
+ drivers/net/wireless/ath/ath9k/ahb.c          | 216 ++++++++++-
  drivers/net/wireless/ath/ath9k/ani.h          |   2 +-
  drivers/net/wireless/ath/ath9k/ar5008_phy.c   |  72 ++--
  drivers/net/wireless/ath/ath9k/ar9002_phy.h   |  11 +
@@ -31,17 +31,16 @@
  drivers/net/wireless/ath/ath9k/main.c         |  12 +
  drivers/net/wireless/ath/ath9k/pci.c          |   1 +
  drivers/net/wireless/ath/ath9k/phy.h          |   3 +
- include/linux/ath9k_platform.h                |   7 +
  local-symbols                                 |   1 +
- 29 files changed, 1438 insertions(+), 220 deletions(-)
+ 28 files changed, 1387 insertions(+), 220 deletions(-)
  create mode 100644 drivers/net/wireless/ath/ath9k/hsr.c
  create mode 100644 drivers/net/wireless/ath/ath9k/hsr.h
 
 diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
-index 888c5e2..f7e2e89 100644
+index eb63efd..5377a35 100644
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -153,6 +153,7 @@ struct ath_common {
+@@ -151,6 +151,7 @@ struct ath_common {
  	int debug_mask;
  	enum ath_device_state state;
  	unsigned long op_flags;
@@ -94,7 +93,7 @@
  ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o
  
 diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
-index 1a6697b..f9a76e7 100644
+index 1a6697b..70fae7a 100644
 --- a/drivers/net/wireless/ath/ath9k/ahb.c
 +++ b/drivers/net/wireless/ath/ath9k/ahb.c
 @@ -20,7 +20,15 @@
@@ -113,7 +112,7 @@
  
  static const struct platform_device_id ath9k_platform_id_table[] = {
  	{
-@@ -69,6 +77,236 @@ static const struct ath_bus_ops ath_ahb_bus_ops  = {
+@@ -69,6 +77,192 @@ static const struct ath_bus_ops ath_ahb_bus_ops  = {
  	.eeprom_read = ath_ahb_eeprom_read,
  };
  
@@ -122,47 +121,6 @@
 +#define QCA955X_DDR_CTL_CONFIG          0x108
 +#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23)
 +
-+static int of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata)
-+{
-+#ifdef CONFIG_MTD
-+	struct device_node *mtd_np = NULL;
-+	size_t retlen;
-+	int size, ret;
-+	struct mtd_info *mtd;
-+	const char *part;
-+	const __be32 *list;
-+	phandle phandle;
-+
-+	list = of_get_property(np, "mtd-cal-data", &size);
-+	if (!list)
-+		return 0;
-+
-+	if (size != (2 * sizeof(*list)))
-+		return 1;
-+
-+	phandle = be32_to_cpup(list++);
-+	if (phandle)
-+		mtd_np = of_find_node_by_phandle(phandle);
-+
-+	if (!mtd_np)
-+		return 1;
-+
-+	part = of_get_property(mtd_np, "label", NULL);
-+	if (!part)
-+		part = mtd_np->name;
-+
-+	mtd = get_mtd_device_nm(part);
-+	if (IS_ERR(mtd))
-+		return 1;
-+
-+	ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data),
-+			&retlen, (u8*)pdata->eeprom_data);
-+	put_mtd_device(mtd);
-+
-+#endif
-+	return 0;
-+}
-+
 +static int ar913x_wmac_reset(void)
 +{
 +	ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
@@ -340,9 +298,6 @@
 +
 +	pdata->get_mac_revision = data->soc_revision;
 +
-+	if (of_get_wifi_cal(pdev->dev.of_node, pdata))
-+		dev_err(&pdev->dev, "failed to load calibration data from mtd device\n");
-+
 +	return data->dev_id;
 +}
 +#endif
@@ -350,7 +305,7 @@
  static int ath_ahb_probe(struct platform_device *pdev)
  {
  	void __iomem *mem;
-@@ -80,6 +318,17 @@ static int ath_ahb_probe(struct platform_device *pdev)
+@@ -80,6 +274,17 @@ static int ath_ahb_probe(struct platform_device *pdev)
  	int ret = 0;
  	struct ath_hw *ah;
  	char hw_name[64];
@@ -368,7 +323,7 @@
  
  	if (!dev_get_platdata(&pdev->dev)) {
  		dev_err(&pdev->dev, "no platform data specified\n");
-@@ -118,17 +367,23 @@ static int ath_ahb_probe(struct platform_device *pdev)
+@@ -118,17 +323,23 @@ static int ath_ahb_probe(struct platform_device *pdev)
  	sc->mem = mem;
  	sc->irq = irq;
  
@@ -393,7 +348,7 @@
  
  	ah = sc->sc_ah;
  	ath9k_hw_name(ah, hw_name, sizeof(hw_name));
-@@ -162,6 +417,9 @@ static struct platform_driver ath_ahb_driver = {
+@@ -162,6 +373,9 @@ static struct platform_driver ath_ahb_driver = {
  	.remove_new = ath_ahb_remove,
  	.driver		= {
  		.name	= "ath9k",
@@ -2404,7 +2359,7 @@
  	ath9k_hw_disable_mib_counters(ah);
  }
 diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
-index 6d120df..2807d36 100644
+index 9310844..1e3484a 100644
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
 @@ -18,6 +18,7 @@
@@ -2415,7 +2370,7 @@
  
  static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  			u32 queues, bool drop);
-@@ -538,6 +539,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -537,6 +538,11 @@ irqreturn_t ath_isr(int irq, void *dev)
  		return IRQ_HANDLED;
  	}
  
@@ -2427,7 +2382,7 @@
  	/*
  	 * If there are no status bits set, then this interrupt was not
  	 * for me (should have been caught above).
-@@ -654,6 +660,7 @@ void ath_reset_work(struct work_struct *work)
+@@ -653,6 +659,7 @@ void ath_reset_work(struct work_struct *work)
  static int ath9k_start(struct ieee80211_hw *hw)
  {
  	struct ath_softc *sc = hw->priv;
@@ -2435,7 +2390,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;
-@@ -732,6 +739,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
+@@ -731,6 +738,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
  					  AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
  	}
  
@@ -2473,29 +2428,11 @@
  enum ath9k_ant_div_comb_lna_conf {
  	ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
  	ATH_ANT_DIV_COMB_LNA2,
-diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
-index 76860a4..e210108 100644
---- a/include/linux/ath9k_platform.h
-+++ b/include/linux/ath9k_platform.h
-@@ -46,6 +46,13 @@ struct ath9k_platform_data {
- 	int (*external_reset)(void);
- 
- 	bool use_eeprom;
-+
-+	int num_leds;
-+	const struct gpio_led *leds;
-+
-+	unsigned num_btns;
-+	const struct gpio_keys_button *btns;
-+	unsigned btn_poll_interval;
- };
- 
- #endif /* _LINUX_ATH9K_PLATFORM_H */
 diff --git a/local-symbols b/local-symbols
-index b200b00..b5745bf 100644
+index 3421d93..3b2db43 100644
 --- a/local-symbols
 +++ b/local-symbols
-@@ -128,6 +128,7 @@ ATH9K_WOW=
+@@ -121,6 +121,7 @@ ATH9K_WOW=
  ATH9K_RFKILL=
  ATH9K_CHANNEL_CONTEXT=
  ATH9K_PCOEM=
@@ -2504,5 +2441,5 @@
  ATH9K_HTC=
  ATH9K_HTC_DEBUGFS=
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0005-backports-sync-openwrt-patches-ath10k.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0005-backports-sync-openwrt-patches-ath10k.patch
new file mode 100644
index 0000000..3c17715
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0005-backports-sync-openwrt-patches-ath10k.patch
@@ -0,0 +1,417 @@
+From e99a66604dd4cfdfcbf349d3b1fe2007af87e1e6 Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Wed, 17 Jul 2024 20:42:15 +0800
+Subject: [PATCH 05/89] backports: sync openwrt patches/ath10k
+
+---
+ drivers/net/wireless/ath/ath10k/Kconfig   |  6 +++
+ drivers/net/wireless/ath/ath10k/core.c    | 13 +++++
+ drivers/net/wireless/ath/ath10k/core.h    |  4 ++
+ drivers/net/wireless/ath/ath10k/htt.h     |  4 ++
+ drivers/net/wireless/ath/ath10k/leds.c    |  2 +-
+ drivers/net/wireless/ath/ath10k/mac.c     | 65 +++++++++++++++++++++--
+ drivers/net/wireless/ath/ath10k/pci.c     | 16 ++++++
+ drivers/net/wireless/ath/ath10k/thermal.h |  2 +-
+ drivers/net/wireless/ath/ath10k/wmi.c     | 43 +++++++++++++++
+ drivers/net/wireless/ath/ath10k/wmi.h     | 35 ++++++++++++
+ local-symbols                             |  2 +
+ 11 files changed, 186 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
+index 57c3be9..d8f919c 100644
+--- a/drivers/net/wireless/ath/ath10k/Kconfig
++++ b/drivers/net/wireless/ath/ath10k/Kconfig
+@@ -94,6 +94,12 @@ config ATH10K_TRACING
+ 	help
+ 	  Select this to ath10k use tracing infrastructure.
+ 
++config ATH10K_THERMAL
++	bool "Atheros ath10k thermal monitoring support"
++	depends on THERMAL
++	---help---
++	  Select this to ath10k use hwmon for thermal measurement.
++
+ config ATH10K_DFS_CERTIFIED
+ 	bool "Atheros DFS support for certified platforms"
+ 	depends on ATH10K && CFG80211_CERTIFICATION_ONUS
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index b329428..ff87580 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -9,6 +9,7 @@
+ #include <linux/module.h>
+ #include <linux/firmware.h>
+ #include <linux/of.h>
++#include <linux/of_net.h>
+ #include <linux/property.h>
+ #include <linux/dmi.h>
+ #include <linux/ctype.h>
+@@ -3411,6 +3412,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
+ 
+ 	device_get_mac_address(ar->dev, ar->mac_addr);
+ 
++	of_get_mac_address(ar->dev->of_node, ar->mac_addr);
++
+ 	ret = ath10k_core_init_firmware_features(ar);
+ 	if (ret) {
+ 		ath10k_err(ar, "fatal problem with firmware features: %d\n",
+@@ -3539,6 +3542,16 @@ int ath10k_core_register(struct ath10k *ar,
+ 
+ 	queue_work(ar->workqueue, &ar->register_work);
+ 
++	/* OpenWrt requires all PHYs to be initialized to create the
++	 * configuration files during bootup. ath10k violates this
++	 * because it delays the creation of the PHY to a not well defined
++	 * point in the future.
++	 *
++	 * Forcing the work to be done immediately works around this problem
++	 * but may also delay the boot when firmware images cannot be found.
++	 */
++	flush_workqueue(ar->workqueue);
++
+ 	return 0;
+ }
+ EXPORT_SYMBOL(ath10k_core_register);
+diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
+index b893c43..394c978 100644
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -1315,6 +1315,10 @@ struct ath10k {
+ 	s32 tx_power_2g_limit;
+ 	s32 tx_power_5g_limit;
+ 
++#ifdef CPTCFG_MAC80211_LEDS
++	const char *led_default_trigger;
++#endif
++
+ 	/* must be last */
+ 	u8 drv_priv[] __aligned(sizeof(void *));
+ };
+diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
+index 603f6de..bea1d16 100644
+--- a/drivers/net/wireless/ath/ath10k/htt.h
++++ b/drivers/net/wireless/ath/ath10k/htt.h
+@@ -236,7 +236,11 @@ enum htt_rx_ring_flags {
+ };
+ 
+ #define HTT_RX_RING_SIZE_MIN 128
++#ifndef CONFIG_ATH10K_SMALLBUFFERS
+ #define HTT_RX_RING_SIZE_MAX 2048
++#else
++#define HTT_RX_RING_SIZE_MAX 512
++#endif
+ #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX
+ #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1)
+ #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1)
+diff --git a/drivers/net/wireless/ath/ath10k/leds.c b/drivers/net/wireless/ath/ath10k/leds.c
+index 9b1d04e..b82033b 100644
+--- a/drivers/net/wireless/ath/ath10k/leds.c
++++ b/drivers/net/wireless/ath/ath10k/leds.c
+@@ -70,7 +70,7 @@ int ath10k_leds_register(struct ath10k *ar)
+ 
+ 	ar->leds.cdev.name = ar->leds.label;
+ 	ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
+-	ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger;
++	ar->leds.cdev.default_trigger = ar->led_default_trigger;
+ 
+ 	ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
+ 	if (ret)
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 35cb06d..9f96315 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -1022,6 +1022,40 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
+ 	return ar->last_wmi_vdev_start_status;
+ }
+ 
++static u32 ath10k_get_max_antenna_gain(struct ath10k *ar,
++				       u32 ch_max_antenna_gain)
++{
++	u32 max_antenna_gain;
++
++	if (ar->dfs_detector && ar->dfs_detector->region == NL80211_DFS_FCC) {
++		/* FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4):
++		 *
++		 * > (4) The conducted output power limit
++		 * > specified in paragraph (b) of this section
++		 * > is based on the use of antennas
++		 * > with directional gains that do not exceed
++		 * > 6 dBi. Except as shown in paragraph
++		 * > (c) of this section, if transmitting
++		 * > antennas of directional gain greater
++		 * > than 6 dBi are used, the conducted
++		 * > output power from the intentional radiator
++		 * > shall be reduced below the stated
++		 * > values in paragraphs (b)(1), (b)(2),
++		 * > and (b)(3) of this section, as appropriate,
++		 * > by the amount in dB that the
++		 * > directional gain of the antenna exceeds
++		 * > 6 dBi.
++		 *
++		 * https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf
++		 */
++		max_antenna_gain = 6;
++	} else {
++		max_antenna_gain = 0;
++	}
++
++	return max(ch_max_antenna_gain, max_antenna_gain);
++}
++
+ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
+ {
+ 	struct cfg80211_chan_def *chandef = NULL;
+@@ -1054,7 +1088,8 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
+ 	arg.channel.min_power = 0;
+ 	arg.channel.max_power = channel->max_power * 2;
+ 	arg.channel.max_reg_power = channel->max_reg_power * 2;
+-	arg.channel.max_antenna_gain = channel->max_antenna_gain;
++	arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
++						channel->max_antenna_gain);
+ 
+ 	reinit_completion(&ar->vdev_setup_done);
+ 	reinit_completion(&ar->vdev_delete_done);
+@@ -1500,7 +1535,8 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
+ 	arg.channel.min_power = 0;
+ 	arg.channel.max_power = chandef->chan->max_power * 2;
+ 	arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
+-	arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
++	arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
++					chandef->chan->max_antenna_gain);
+ 
+ 	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
+ 		arg.ssid = arvif->u.ap.ssid;
+@@ -3431,7 +3467,8 @@ static int ath10k_update_channel_list(struct ath10k *ar)
+ 			ch->min_power = 0;
+ 			ch->max_power = channel->max_power * 2;
+ 			ch->max_reg_power = channel->max_reg_power * 2;
+-			ch->max_antenna_gain = channel->max_antenna_gain;
++			ch->max_antenna_gain = ath10k_get_max_antenna_gain(ar,
++						channel->max_antenna_gain);
+ 			ch->reg_class_id = 0; /* FIXME */
+ 
+ 			/* FIXME: why use only legacy modes, why not any
+@@ -9919,6 +9956,21 @@ static int ath10k_mac_init_rd(struct ath10k *ar)
+ 	return 0;
+ }
+ 
++#ifdef CPTCFG_MAC80211_LEDS
++static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = {
++	{ .throughput = 0 * 1024, .blink_time = 334 },
++	{ .throughput = 1 * 1024, .blink_time = 260 },
++	{ .throughput = 2 * 1024, .blink_time = 220 },
++	{ .throughput = 5 * 1024, .blink_time = 190 },
++	{ .throughput = 10 * 1024, .blink_time = 170 },
++	{ .throughput = 25 * 1024, .blink_time = 150 },
++	{ .throughput = 54 * 1024, .blink_time = 130 },
++	{ .throughput = 120 * 1024, .blink_time = 110 },
++	{ .throughput = 265 * 1024, .blink_time = 80 },
++	{ .throughput = 586 * 1024, .blink_time = 50 },
++};
++#endif
++
+ int ath10k_mac_register(struct ath10k *ar)
+ {
+ 	static const u32 cipher_suites[] = {
+@@ -10037,7 +10089,6 @@ int ath10k_mac_register(struct ath10k *ar)
+ 	ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
+ 	ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
+ 	ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
+-	ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
+ 
+ 	if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
+ 		ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
+@@ -10281,6 +10332,12 @@ int ath10k_mac_register(struct ath10k *ar)
+ 
+ 	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
+ 
++#ifdef CPTCFG_MAC80211_LEDS
++	ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw,
++		IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
++		ARRAY_SIZE(ath10k_tpt_blink));
++#endif
++
+ 	ret = ieee80211_register_hw(ar->hw);
+ 	if (ret) {
+ 		ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
+diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
+index 36ac452..3c5164c 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -132,7 +132,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
+ 		.flags = CE_ATTR_FLAGS,
+ 		.src_nentries = 0,
+ 		.src_sz_max = 2048,
++#ifndef CONFIG_ATH10K_SMALLBUFFERS
+ 		.dest_nentries = 512,
++#else
++		.dest_nentries = 128,
++#endif
+ 		.recv_cb = ath10k_pci_htt_htc_rx_cb,
+ 	},
+ 
+@@ -141,7 +145,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
+ 		.flags = CE_ATTR_FLAGS,
+ 		.src_nentries = 0,
+ 		.src_sz_max = 2048,
++#ifndef CONFIG_ATH10K_SMALLBUFFERS
+ 		.dest_nentries = 128,
++#else
++		.dest_nentries = 64,
++#endif
+ 		.recv_cb = ath10k_pci_htc_rx_cb,
+ 	},
+ 
+@@ -168,7 +176,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
+ 		.flags = CE_ATTR_FLAGS,
+ 		.src_nentries = 0,
+ 		.src_sz_max = 512,
++#ifndef CONFIG_ATH10K_SMALLBUFFERS
+ 		.dest_nentries = 512,
++#else
++		.dest_nentries = 128,
++#endif
+ 		.recv_cb = ath10k_pci_htt_rx_cb,
+ 	},
+ 
+@@ -193,7 +205,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
+ 		.flags = CE_ATTR_FLAGS,
+ 		.src_nentries = 0,
+ 		.src_sz_max = 2048,
++#ifndef CONFIG_ATH10K_SMALLBUFFERS
+ 		.dest_nentries = 128,
++#else
++		.dest_nentries = 96,
++#endif
+ 		.recv_cb = ath10k_pci_pktlog_rx_cb,
+ 	},
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/thermal.h b/drivers/net/wireless/ath/ath10k/thermal.h
+index 1f4de9f..fcfa3c2 100644
+--- a/drivers/net/wireless/ath/ath10k/thermal.h
++++ b/drivers/net/wireless/ath/ath10k/thermal.h
+@@ -25,7 +25,7 @@ struct ath10k_thermal {
+ 	int temperature;
+ };
+ 
+-#if IS_REACHABLE(CONFIG_THERMAL)
++#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL)
+ int ath10k_thermal_register(struct ath10k *ar);
+ void ath10k_thermal_unregister(struct ath10k *ar);
+ void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
+diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
+index 6b428b4..6a54ba7 100644
+--- a/drivers/net/wireless/ath/ath10k/wmi.c
++++ b/drivers/net/wireless/ath/ath10k/wmi.c
+@@ -7536,6 +7536,49 @@ static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar,
+ 	return skb;
+ }
+ 
++static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar,
++						     u32 gpio_num, u32 input,
++						     u32 pull_type, u32 intr_mode)
++{
++	struct wmi_gpio_config_cmd *cmd;
++	struct sk_buff *skb;
++
++	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
++	if (!skb)
++		return ERR_PTR(-ENOMEM);
++
++	cmd = (struct wmi_gpio_config_cmd *)skb->data;
++	cmd->pull_type = __cpu_to_le32(pull_type);
++	cmd->gpio_num = __cpu_to_le32(gpio_num);
++	cmd->input = __cpu_to_le32(input);
++	cmd->intr_mode = __cpu_to_le32(intr_mode);
++
++	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n",
++		   gpio_num, input, pull_type, intr_mode);
++
++	return skb;
++}
++
++static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar,
++						     u32 gpio_num, u32 set)
++{
++	struct wmi_gpio_output_cmd *cmd;
++	struct sk_buff *skb;
++
++	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
++	if (!skb)
++		return ERR_PTR(-ENOMEM);
++
++	cmd = (struct wmi_gpio_output_cmd *)skb->data;
++	cmd->gpio_num = __cpu_to_le32(gpio_num);
++	cmd->set = __cpu_to_le32(set);
++
++	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n",
++		   gpio_num, set);
++
++	return skb;
++}
++
+ static struct sk_buff *
+ ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
+ 			     enum wmi_sta_ps_mode psmode)
+diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
+index 0faefc0..06a7b3a 100644
+--- a/drivers/net/wireless/ath/ath10k/wmi.h
++++ b/drivers/net/wireless/ath/ath10k/wmi.h
+@@ -3069,6 +3069,41 @@ struct wmi_gpio_input_event {
+ 	__le32 gpio_num;    /* GPIO number which changed state */
+ } __packed;
+ 
++/* WMI_GPIO_CPTCFG_CMDID */
++enum {
++	WMI_GPIO_PULL_NONE,
++	WMI_GPIO_PULL_UP,
++	WMI_GPIO_PULL_DOWN,
++};
++
++enum {
++	WMI_GPIO_INTTYPE_DISABLE,
++	WMI_GPIO_INTTYPE_RISING_EDGE,
++	WMI_GPIO_INTTYPE_FALLING_EDGE,
++	WMI_GPIO_INTTYPE_BOTH_EDGE,
++	WMI_GPIO_INTTYPE_LEVEL_LOW,
++	WMI_GPIO_INTTYPE_LEVEL_HIGH
++};
++
++/* WMI_GPIO_CPTCFG_CMDID */
++struct wmi_gpio_config_cmd {
++	__le32 gpio_num;             /* GPIO number to be setup */
++	__le32 input;                /* 0 - Output/ 1 - Input */
++	__le32 pull_type;            /* Pull type defined above */
++	__le32 intr_mode;            /* Interrupt mode defined above (Input) */
++} __packed;
++
++/* WMI_GPIO_OUTPUT_CMDID */
++struct wmi_gpio_output_cmd {
++	__le32 gpio_num;    /* GPIO number to be setup */
++	__le32 set;         /* Set the GPIO pin*/
++} __packed;
++
++/* WMI_GPIO_INPUT_EVENTID */
++struct wmi_gpio_input_event {
++	__le32 gpio_num;    /* GPIO number which changed state */
++} __packed;
++
+ struct wmi_ext_resource_config_10_4_cmd {
+ 	/* contains enum wmi_host_platform_type */
+ 	__le32 host_platform_config;
+diff --git a/local-symbols b/local-symbols
+index 3b2db43..c8f7132 100644
+--- a/local-symbols
++++ b/local-symbols
+@@ -154,6 +154,8 @@ ATH10K_DEBUG=
+ ATH10K_DEBUGFS=
+ ATH10K_LEDS=
+ ATH10K_SPECTRAL=
++ATH10K_THERMAL=
++ATH10K_LEDS=
+ ATH10K_TRACING=
+ ATH10K_DFS_CERTIFIED=
+ WCN36XX=
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0005-sync-backports-patches-ath10k.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0005-sync-backports-patches-ath10k.patch
deleted file mode 100644
index feebf11..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0005-sync-backports-patches-ath10k.patch
+++ /dev/null
@@ -1,835 +0,0 @@
-From 38cce019a8791ff3d295bd936362432cc592e061 Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 12 Mar 2024 11:27:11 +0800
-Subject: [PATCH 05/61] sync backports patches/ath10k
-
----
- drivers/net/wireless/ath/ath10k/Kconfig   |  16 ++++
- drivers/net/wireless/ath/ath10k/Makefile  |   3 +-
- drivers/net/wireless/ath/ath10k/core.c    |  34 ++++++++
- drivers/net/wireless/ath/ath10k/core.h    |  12 +++
- drivers/net/wireless/ath/ath10k/htt.h     |   4 +
- drivers/net/wireless/ath/ath10k/hw.h      |   1 +
- drivers/net/wireless/ath/ath10k/leds.c    | 101 ++++++++++++++++++++++
- drivers/net/wireless/ath/ath10k/leds.h    |  41 +++++++++
- drivers/net/wireless/ath/ath10k/mac.c     |  66 +++++++++++++-
- drivers/net/wireless/ath/ath10k/pci.c     |  16 ++++
- drivers/net/wireless/ath/ath10k/thermal.h |   2 +-
- drivers/net/wireless/ath/ath10k/wmi-ops.h |  32 +++++++
- drivers/net/wireless/ath/ath10k/wmi-tlv.c |   2 +
- drivers/net/wireless/ath/ath10k/wmi.c     |  54 ++++++++++++
- drivers/net/wireless/ath/ath10k/wmi.h     |  35 ++++++++
- local-symbols                             |   2 +
- 16 files changed, 415 insertions(+), 6 deletions(-)
- create mode 100644 drivers/net/wireless/ath/ath10k/leds.c
- create mode 100644 drivers/net/wireless/ath/ath10k/leds.h
-
-diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
-index d10c65d..5cabe0e 100644
---- a/drivers/net/wireless/ath/ath10k/Kconfig
-+++ b/drivers/net/wireless/ath/ath10k/Kconfig
-@@ -72,6 +72,16 @@ config ATH10K_DEBUGFS
- 
- 	  If unsure, say Y to make it easier to debug problems.
- 
-+config ATH10K_LEDS
-+	bool "Atheros ath10k LED support"
-+	depends on ATH10K
-+	select MAC80211_LEDS
-+	select LEDS_CLASS
-+	select NEW_LEDS
-+	default y
-+	---help---
-+	  This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N.
-+
- config ATH10K_SPECTRAL
- 	bool "Atheros ath10k spectral scan support"
- 	depends on ATH10K_DEBUGFS
-@@ -87,6 +97,12 @@ config ATH10K_TRACING
- 	help
- 	  Select this to ath10k use tracing infrastructure.
- 
-+config ATH10K_THERMAL
-+	bool "Atheros ath10k thermal monitoring support"
-+	depends on THERMAL
-+	---help---
-+	  Select this to ath10k use hwmon for thermal measurement.
-+
- config ATH10K_DFS_CERTIFIED
- 	bool "Atheros DFS support for certified platforms"
- 	depends on ATH10K && CFG80211_CERTIFICATION_ONUS
-diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile
-index 24d846a..e040d84 100644
---- a/drivers/net/wireless/ath/ath10k/Makefile
-+++ b/drivers/net/wireless/ath/ath10k/Makefile
-@@ -18,7 +18,8 @@ ath10k_core-y += mac.o \
- ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o
- ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
- ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
--ath10k_core-$(CONFIG_THERMAL) += thermal.o
-+ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
-+ath10k_core-$(CPTCFG_ATH10K_LEDS) += leds.o
- ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o
- ath10k_core-$(CONFIG_PM) += wow.o
- ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
-diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
-index 9ce6f49..a168fdf 100644
---- a/drivers/net/wireless/ath/ath10k/core.c
-+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -9,6 +9,7 @@
- #include <linux/module.h>
- #include <linux/firmware.h>
- #include <linux/of.h>
-+#include <linux/of_net.h>
- #include <linux/property.h>
- #include <linux/dmi.h>
- #include <linux/ctype.h>
-@@ -27,6 +28,7 @@
- #include "testmode.h"
- #include "wmi-ops.h"
- #include "coredump.h"
-+#include "leds.h"
- 
- unsigned int ath10k_debug_mask;
- EXPORT_SYMBOL(ath10k_debug_mask);
-@@ -66,6 +68,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
- 		.dev_id = QCA988X_2_0_DEVICE_ID,
- 		.bus = ATH10K_BUS_PCI,
- 		.name = "qca988x hw2.0",
-+		.led_pin = 1,
- 		.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
- 		.uart_pin = 7,
- 		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
-@@ -149,6 +152,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
- 		.dev_id = QCA9887_1_0_DEVICE_ID,
- 		.bus = ATH10K_BUS_PCI,
- 		.name = "qca9887 hw1.0",
-+		.led_pin = 1,
- 		.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
- 		.uart_pin = 7,
- 		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
-@@ -396,6 +400,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
- 		.dev_id = QCA99X0_2_0_DEVICE_ID,
- 		.bus = ATH10K_BUS_PCI,
- 		.name = "qca99x0 hw2.0",
-+		.led_pin = 17,
- 		.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
- 		.uart_pin = 7,
- 		.otp_exe_param = 0x00000700,
-@@ -443,6 +448,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
- 		.dev_id = QCA9984_1_0_DEVICE_ID,
- 		.bus = ATH10K_BUS_PCI,
- 		.name = "qca9984/qca9994 hw1.0",
-+		.led_pin = 17,
- 		.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
- 		.uart_pin = 7,
- 		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
-@@ -497,6 +503,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
- 		.dev_id = QCA9888_2_0_DEVICE_ID,
- 		.bus = ATH10K_BUS_PCI,
- 		.name = "qca9888 hw2.0",
-+		.led_pin = 17,
- 		.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
- 		.uart_pin = 7,
- 		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
-@@ -3239,6 +3246,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
- 		goto err_hif_stop;
- 	}
- 
-+	status = ath10k_leds_start(ar);
-+	if (status)
-+		goto err_hif_stop;
-+
- 	return 0;
- 
- err_hif_stop:
-@@ -3405,6 +3416,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
- 
- 	device_get_mac_address(ar->dev, ar->mac_addr);
- 
-+	of_get_mac_address(ar->dev->of_node, ar->mac_addr);
-+
- 	ret = ath10k_core_init_firmware_features(ar);
- 	if (ret) {
- 		ath10k_err(ar, "fatal problem with firmware features: %d\n",
-@@ -3497,9 +3510,18 @@ static void ath10k_core_register_work(struct work_struct *work)
- 		goto err_spectral_destroy;
- 	}
- 
-+	status = ath10k_leds_register(ar);
-+	if (status) {
-+		ath10k_err(ar, "could not register leds: %d\n",
-+			   status);
-+		goto err_thermal_unregister;
-+	}
-+
- 	set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
- 	return;
- 
-+err_thermal_unregister:
-+	ath10k_thermal_unregister(ar);
- err_spectral_destroy:
- 	ath10k_spectral_destroy(ar);
- err_debug_destroy:
-@@ -3524,6 +3546,16 @@ int ath10k_core_register(struct ath10k *ar,
- 
- 	queue_work(ar->workqueue, &ar->register_work);
- 
-+	/* OpenWrt requires all PHYs to be initialized to create the
-+	 * configuration files during bootup. ath10k violates this
-+	 * because it delays the creation of the PHY to a not well defined
-+	 * point in the future.
-+	 *
-+	 * Forcing the work to be done immediately works around this problem
-+	 * but may also delay the boot when firmware images cannot be found.
-+	 */
-+	flush_workqueue(ar->workqueue);
-+
- 	return 0;
- }
- EXPORT_SYMBOL(ath10k_core_register);
-@@ -3535,6 +3567,8 @@ void ath10k_core_unregister(struct ath10k *ar)
- 	if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
- 		return;
- 
-+	ath10k_leds_unregister(ar);
-+
- 	ath10k_thermal_unregister(ar);
- 	/* Stop spectral before unregistering from mac80211 to remove the
- 	 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree
-diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
-index 2435291..8546f2f 100644
---- a/drivers/net/wireless/ath/ath10k/core.h
-+++ b/drivers/net/wireless/ath/ath10k/core.h
-@@ -15,6 +15,7 @@
- #include <linux/pci.h>
- #include <linux/uuid.h>
- #include <linux/time.h>
-+#include <linux/leds.h>
- 
- #include "htt.h"
- #include "htc.h"
-@@ -1256,6 +1257,13 @@ struct ath10k {
- 		bool utf_monitor;
- 	} testmode;
- 
-+	struct {
-+		struct gpio_led wifi_led;
-+		struct led_classdev cdev;
-+		char label[48];
-+		u32 gpio_state_pin;
-+	} leds;
-+
- 	struct {
- 		/* protected by data_lock */
- 		u32 rx_crc_err_drop;
-@@ -1305,6 +1313,10 @@ struct ath10k {
- 	s32 tx_power_2g_limit;
- 	s32 tx_power_5g_limit;
- 
-+#ifdef CPTCFG_MAC80211_LEDS
-+	const char *led_default_trigger;
-+#endif
-+
- 	/* must be last */
- 	u8 drv_priv[] __aligned(sizeof(void *));
- };
-diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
-index 603f6de..bea1d16 100644
---- a/drivers/net/wireless/ath/ath10k/htt.h
-+++ b/drivers/net/wireless/ath/ath10k/htt.h
-@@ -236,7 +236,11 @@ enum htt_rx_ring_flags {
- };
- 
- #define HTT_RX_RING_SIZE_MIN 128
-+#ifndef CONFIG_ATH10K_SMALLBUFFERS
- #define HTT_RX_RING_SIZE_MAX 2048
-+#else
-+#define HTT_RX_RING_SIZE_MAX 512
-+#endif
- #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX
- #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1)
- #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1)
-diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
-index 3b26994..aeada6c 100644
---- a/drivers/net/wireless/ath/ath10k/hw.h
-+++ b/drivers/net/wireless/ath/ath10k/hw.h
-@@ -520,6 +520,7 @@ struct ath10k_hw_params {
- 	const char *name;
- 	u32 patch_load_addr;
- 	int uart_pin;
-+	int led_pin;
- 	u32 otp_exe_param;
- 
- 	/* Type of hw cycle counter wraparound logic, for more info
-diff --git a/drivers/net/wireless/ath/ath10k/leds.c b/drivers/net/wireless/ath/ath10k/leds.c
-new file mode 100644
-index 0000000..be8f255
---- /dev/null
-+++ b/drivers/net/wireless/ath/ath10k/leds.c
-@@ -0,0 +1,101 @@
-+/*
-+ * Copyright (c) 2005-2011 Atheros Communications Inc.
-+ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
-+ * Copyright (c) 2018 Sebastian Gottschall <s.gottschall@dd-wrt.com>
-+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/leds.h>
-+
-+#include "core.h"
-+#include "wmi.h"
-+#include "wmi-ops.h"
-+
-+#include "leds.h"
-+
-+static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev,
-+					       enum led_brightness brightness)
-+{
-+	struct ath10k *ar = container_of(led_cdev, struct ath10k,
-+					 leds.cdev);
-+	struct gpio_led *led = &ar->leds.wifi_led;
-+
-+	mutex_lock(&ar->conf_mutex);
-+
-+	if (ar->state != ATH10K_STATE_ON)
-+		goto out;
-+
-+	ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low;
-+	ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin);
-+
-+out:
-+	mutex_unlock(&ar->conf_mutex);
-+
-+	return 0;
-+}
-+
-+int ath10k_leds_start(struct ath10k *ar)
-+{
-+	if (ar->hw_params.led_pin == 0)
-+		/* leds not supported */
-+		return 0;
-+
-+	/* under some circumstances, the gpio pin gets reconfigured
-+	 * to default state by the firmware, so we need to
-+	 * reconfigure it this behaviour has only ben seen on
-+	 * QCA9984 and QCA99XX devices so far
-+	 */
-+	ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0,
-+			       WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE);
-+	ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1);
-+
-+	return 0;
-+}
-+
-+int ath10k_leds_register(struct ath10k *ar)
-+{
-+	int ret;
-+
-+	if (ar->hw_params.led_pin == 0)
-+		/* leds not supported */
-+		return 0;
-+
-+	snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s",
-+		 wiphy_name(ar->hw->wiphy));
-+	ar->leds.wifi_led.active_low = 1;
-+	ar->leds.wifi_led.gpio = ar->hw_params.led_pin;
-+	ar->leds.wifi_led.name = ar->leds.label;
-+	ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
-+
-+	ar->leds.cdev.name = ar->leds.label;
-+	ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
-+	ar->leds.cdev.default_trigger = ar->led_default_trigger;
-+
-+	ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+void ath10k_leds_unregister(struct ath10k *ar)
-+{
-+	if (ar->hw_params.led_pin == 0)
-+		/* leds not supported */
-+		return;
-+
-+	led_classdev_unregister(&ar->leds.cdev);
-+}
-+
-diff --git a/drivers/net/wireless/ath/ath10k/leds.h b/drivers/net/wireless/ath/ath10k/leds.h
-new file mode 100644
-index 0000000..a0f5c84
---- /dev/null
-+++ b/drivers/net/wireless/ath/ath10k/leds.h
-@@ -0,0 +1,41 @@
-+/*
-+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+#ifndef _LEDS_H_
-+#define _LEDS_H_
-+
-+#include "core.h"
-+
-+#ifdef CPTCFG_ATH10K_LEDS
-+void ath10k_leds_unregister(struct ath10k *ar);
-+int ath10k_leds_start(struct ath10k *ar);
-+int ath10k_leds_register(struct ath10k *ar);
-+#else
-+static inline void ath10k_leds_unregister(struct ath10k *ar)
-+{
-+}
-+
-+static inline int ath10k_leds_start(struct ath10k *ar)
-+{
-+	return 0;
-+}
-+
-+static inline int ath10k_leds_register(struct ath10k *ar)
-+{
-+	return 0;
-+}
-+
-+#endif
-+#endif /* _LEDS_H_ */
-diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
-index ec43216..f179dff 100644
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -25,6 +25,7 @@
- #include "wmi-tlv.h"
- #include "wmi-ops.h"
- #include "wow.h"
-+#include "leds.h"
- 
- /*********/
- /* Rates */
-@@ -1021,6 +1022,40 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
- 	return ar->last_wmi_vdev_start_status;
- }
- 
-+static u32 ath10k_get_max_antenna_gain(struct ath10k *ar,
-+				       u32 ch_max_antenna_gain)
-+{
-+	u32 max_antenna_gain;
-+
-+	if (ar->dfs_detector && ar->dfs_detector->region == NL80211_DFS_FCC) {
-+		/* FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4):
-+		 *
-+		 * > (4) The conducted output power limit
-+		 * > specified in paragraph (b) of this section
-+		 * > is based on the use of antennas
-+		 * > with directional gains that do not exceed
-+		 * > 6 dBi. Except as shown in paragraph
-+		 * > (c) of this section, if transmitting
-+		 * > antennas of directional gain greater
-+		 * > than 6 dBi are used, the conducted
-+		 * > output power from the intentional radiator
-+		 * > shall be reduced below the stated
-+		 * > values in paragraphs (b)(1), (b)(2),
-+		 * > and (b)(3) of this section, as appropriate,
-+		 * > by the amount in dB that the
-+		 * > directional gain of the antenna exceeds
-+		 * > 6 dBi.
-+		 *
-+		 * https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf
-+		 */
-+		max_antenna_gain = 6;
-+	} else {
-+		max_antenna_gain = 0;
-+	}
-+
-+	return max(ch_max_antenna_gain, max_antenna_gain);
-+}
-+
- static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
- {
- 	struct cfg80211_chan_def *chandef = NULL;
-@@ -1053,7 +1088,8 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
- 	arg.channel.min_power = 0;
- 	arg.channel.max_power = channel->max_power * 2;
- 	arg.channel.max_reg_power = channel->max_reg_power * 2;
--	arg.channel.max_antenna_gain = channel->max_antenna_gain;
-+	arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
-+						channel->max_antenna_gain);
- 
- 	reinit_completion(&ar->vdev_setup_done);
- 	reinit_completion(&ar->vdev_delete_done);
-@@ -1499,7 +1535,8 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
- 	arg.channel.min_power = 0;
- 	arg.channel.max_power = chandef->chan->max_power * 2;
- 	arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
--	arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
-+	arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
-+					chandef->chan->max_antenna_gain);
- 
- 	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
- 		arg.ssid = arvif->u.ap.ssid;
-@@ -3430,7 +3467,8 @@ static int ath10k_update_channel_list(struct ath10k *ar)
- 			ch->min_power = 0;
- 			ch->max_power = channel->max_power * 2;
- 			ch->max_reg_power = channel->max_reg_power * 2;
--			ch->max_antenna_gain = channel->max_antenna_gain;
-+			ch->max_antenna_gain = ath10k_get_max_antenna_gain(ar,
-+						channel->max_antenna_gain);
- 			ch->reg_class_id = 0; /* FIXME */
- 
- 			/* FIXME: why use only legacy modes, why not any
-@@ -9918,6 +9956,21 @@ static int ath10k_mac_init_rd(struct ath10k *ar)
- 	return 0;
- }
- 
-+#ifdef CPTCFG_MAC80211_LEDS
-+static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = {
-+	{ .throughput = 0 * 1024, .blink_time = 334 },
-+	{ .throughput = 1 * 1024, .blink_time = 260 },
-+	{ .throughput = 2 * 1024, .blink_time = 220 },
-+	{ .throughput = 5 * 1024, .blink_time = 190 },
-+	{ .throughput = 10 * 1024, .blink_time = 170 },
-+	{ .throughput = 25 * 1024, .blink_time = 150 },
-+	{ .throughput = 54 * 1024, .blink_time = 130 },
-+	{ .throughput = 120 * 1024, .blink_time = 110 },
-+	{ .throughput = 265 * 1024, .blink_time = 80 },
-+	{ .throughput = 586 * 1024, .blink_time = 50 },
-+};
-+#endif
-+
- int ath10k_mac_register(struct ath10k *ar)
- {
- 	static const u32 cipher_suites[] = {
-@@ -10036,7 +10089,6 @@ int ath10k_mac_register(struct ath10k *ar)
- 	ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
- 	ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
- 	ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
--	ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
- 
- 	if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
- 		ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
-@@ -10280,6 +10332,12 @@ int ath10k_mac_register(struct ath10k *ar)
- 
- 	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
- 
-+#ifdef CPTCFG_MAC80211_LEDS
-+	ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw,
-+		IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
-+		ARRAY_SIZE(ath10k_tpt_blink));
-+#endif
-+
- 	ret = ieee80211_register_hw(ar->hw);
- 	if (ret) {
- 		ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
-diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
-index d7ac5ae..c7e8e90 100644
---- a/drivers/net/wireless/ath/ath10k/pci.c
-+++ b/drivers/net/wireless/ath/ath10k/pci.c
-@@ -132,7 +132,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
- 		.flags = CE_ATTR_FLAGS,
- 		.src_nentries = 0,
- 		.src_sz_max = 2048,
-+#ifndef CONFIG_ATH10K_SMALLBUFFERS
- 		.dest_nentries = 512,
-+#else
-+		.dest_nentries = 128,
-+#endif
- 		.recv_cb = ath10k_pci_htt_htc_rx_cb,
- 	},
- 
-@@ -141,7 +145,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
- 		.flags = CE_ATTR_FLAGS,
- 		.src_nentries = 0,
- 		.src_sz_max = 2048,
-+#ifndef CONFIG_ATH10K_SMALLBUFFERS
- 		.dest_nentries = 128,
-+#else
-+		.dest_nentries = 64,
-+#endif
- 		.recv_cb = ath10k_pci_htc_rx_cb,
- 	},
- 
-@@ -168,7 +176,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
- 		.flags = CE_ATTR_FLAGS,
- 		.src_nentries = 0,
- 		.src_sz_max = 512,
-+#ifndef CONFIG_ATH10K_SMALLBUFFERS
- 		.dest_nentries = 512,
-+#else
-+		.dest_nentries = 128,
-+#endif
- 		.recv_cb = ath10k_pci_htt_rx_cb,
- 	},
- 
-@@ -193,7 +205,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
- 		.flags = CE_ATTR_FLAGS,
- 		.src_nentries = 0,
- 		.src_sz_max = 2048,
-+#ifndef CONFIG_ATH10K_SMALLBUFFERS
- 		.dest_nentries = 128,
-+#else
-+		.dest_nentries = 96,
-+#endif
- 		.recv_cb = ath10k_pci_pktlog_rx_cb,
- 	},
- 
-diff --git a/drivers/net/wireless/ath/ath10k/thermal.h b/drivers/net/wireless/ath/ath10k/thermal.h
-index 1f4de9f..fcfa3c2 100644
---- a/drivers/net/wireless/ath/ath10k/thermal.h
-+++ b/drivers/net/wireless/ath/ath10k/thermal.h
-@@ -25,7 +25,7 @@ struct ath10k_thermal {
- 	int temperature;
- };
- 
--#if IS_REACHABLE(CONFIG_THERMAL)
-+#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL)
- int ath10k_thermal_register(struct ath10k *ar);
- void ath10k_thermal_unregister(struct ath10k *ar);
- void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
-diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
-index aa57d80..f3f6b59 100644
---- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
-+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
-@@ -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);
- 
-+	struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set);
- };
- 
- int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
-@@ -1122,6 +1125,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *ar,
- 	return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
- }
- 
-+static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num,
-+					 u32 input, u32 pull_type, u32 intr_mode)
-+{
-+	struct sk_buff *skb;
-+
-+	if (!ar->wmi.ops->gen_gpio_config)
-+		return -EOPNOTSUPP;
-+
-+	skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode);
-+	if (IS_ERR(skb))
-+		return PTR_ERR(skb);
-+
-+	return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid);
-+}
-+
-+static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set)
-+{
-+	struct sk_buff *skb;
-+
-+	if (!ar->wmi.ops->gen_gpio_config)
-+		return -EOPNOTSUPP;
-+
-+	skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set);
-+	if (IS_ERR(skb))
-+		return PTR_ERR(skb);
-+
-+	return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid);
-+}
-+
- static inline int
- ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level)
- {
-diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
-index aed97fd..dbaf26d 100644
---- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
-+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
-@@ -4606,6 +4606,8 @@ static const struct wmi_ops wmi_tlv_ops = {
- 	.gen_echo = ath10k_wmi_tlv_op_gen_echo,
- 	.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
- 	.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
-+	/* .gen_gpio_config not implemented */
-+	/* .gen_gpio_output not implemented */
- };
- 
- static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
-diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
-index 5d80988..6b428b4 100644
---- a/drivers/net/wireless/ath/ath10k/wmi.c
-+++ b/drivers/net/wireless/ath/ath10k/wmi.c
-@@ -7493,6 +7493,49 @@ ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
- 	return skb;
- }
- 
-+static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar,
-+						     u32 gpio_num, u32 input,
-+						     u32 pull_type, u32 intr_mode)
-+{
-+	struct wmi_gpio_config_cmd *cmd;
-+	struct sk_buff *skb;
-+
-+	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
-+	if (!skb)
-+		return ERR_PTR(-ENOMEM);
-+
-+	cmd = (struct wmi_gpio_config_cmd *)skb->data;
-+	cmd->pull_type = __cpu_to_le32(pull_type);
-+	cmd->gpio_num = __cpu_to_le32(gpio_num);
-+	cmd->input = __cpu_to_le32(input);
-+	cmd->intr_mode = __cpu_to_le32(intr_mode);
-+
-+	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n",
-+		   gpio_num, input, pull_type, intr_mode);
-+
-+	return skb;
-+}
-+
-+static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar,
-+						     u32 gpio_num, u32 set)
-+{
-+	struct wmi_gpio_output_cmd *cmd;
-+	struct sk_buff *skb;
-+
-+	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
-+	if (!skb)
-+		return ERR_PTR(-ENOMEM);
-+
-+	cmd = (struct wmi_gpio_output_cmd *)skb->data;
-+	cmd->gpio_num = __cpu_to_le32(gpio_num);
-+	cmd->set = __cpu_to_le32(set);
-+
-+	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n",
-+		   gpio_num, set);
-+
-+	return skb;
-+}
-+
- static struct sk_buff *
- ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
- 			     enum wmi_sta_ps_mode psmode)
-@@ -9157,6 +9200,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,
-+	.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
-+	.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
-+
- 	/* .gen_bcn_tmpl not implemented */
- 	/* .gen_prb_tmpl not implemented */
- 	/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9227,6 +9273,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,
-+	.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
-+	.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
- 	/* .gen_bcn_tmpl not implemented */
- 	/* .gen_prb_tmpl not implemented */
- 	/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9299,6 +9347,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,
-+	.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
-+	.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
- 	/* .gen_pdev_enable_adaptive_cca not implemented */
- };
- 
-@@ -9370,6 +9420,8 @@ static const struct wmi_ops wmi_10_2_4_ops = {
- 		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,
-+	.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
-+	.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
- 	/* .gen_bcn_tmpl not implemented */
- 	/* .gen_prb_tmpl not implemented */
- 	/* .gen_p2p_go_bcn_ie not implemented */
-@@ -9451,6 +9503,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,
-+	.gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
-+	.gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
- };
- 
- int ath10k_wmi_attach(struct ath10k *ar)
-diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
-index 2379501..0faefc0 100644
---- a/drivers/net/wireless/ath/ath10k/wmi.h
-+++ b/drivers/net/wireless/ath/ath10k/wmi.h
-@@ -3034,6 +3034,41 @@ enum wmi_10_4_feature_mask {
- 
- };
- 
-+/* WMI_GPIO_CONFIG_CMDID */
-+enum {
-+	WMI_GPIO_PULL_NONE,
-+	WMI_GPIO_PULL_UP,
-+	WMI_GPIO_PULL_DOWN,
-+};
-+
-+enum {
-+	WMI_GPIO_INTTYPE_DISABLE,
-+	WMI_GPIO_INTTYPE_RISING_EDGE,
-+	WMI_GPIO_INTTYPE_FALLING_EDGE,
-+	WMI_GPIO_INTTYPE_BOTH_EDGE,
-+	WMI_GPIO_INTTYPE_LEVEL_LOW,
-+	WMI_GPIO_INTTYPE_LEVEL_HIGH
-+};
-+
-+/* WMI_GPIO_CONFIG_CMDID */
-+struct wmi_gpio_config_cmd {
-+	__le32 gpio_num;             /* GPIO number to be setup */
-+	__le32 input;                /* 0 - Output/ 1 - Input */
-+	__le32 pull_type;            /* Pull type defined above */
-+	__le32 intr_mode;            /* Interrupt mode defined above (Input) */
-+} __packed;
-+
-+/* WMI_GPIO_OUTPUT_CMDID */
-+struct wmi_gpio_output_cmd {
-+	__le32 gpio_num;    /* GPIO number to be setup */
-+	__le32 set;         /* Set the GPIO pin*/
-+} __packed;
-+
-+/* WMI_GPIO_INPUT_EVENTID */
-+struct wmi_gpio_input_event {
-+	__le32 gpio_num;    /* GPIO number which changed state */
-+} __packed;
-+
- struct wmi_ext_resource_config_10_4_cmd {
- 	/* contains enum wmi_host_platform_type */
- 	__le32 host_platform_config;
-diff --git a/local-symbols b/local-symbols
-index b5745bf..3d81ba5 100644
---- a/local-symbols
-+++ b/local-symbols
-@@ -160,6 +160,8 @@ ATH10K_SNOC=
- ATH10K_DEBUG=
- ATH10K_DEBUGFS=
- ATH10K_SPECTRAL=
-+ATH10K_THERMAL=
-+ATH10K_LEDS=
- ATH10K_TRACING=
- ATH10K_DFS_CERTIFIED=
- WCN36XX=
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0006-sync-backports-patches-rt2x00.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0006-backports-sync-openwrt-patches-rt2x00.patch
similarity index 97%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0006-sync-backports-patches-rt2x00.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0006-backports-sync-openwrt-patches-rt2x00.patch
index 39975b3..be2f21e 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0006-sync-backports-patches-rt2x00.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0006-backports-sync-openwrt-patches-rt2x00.patch
@@ -1,7 +1,7 @@
-From a08aa9e789ade7bb35eb442afa6566368d5a318f Mon Sep 17 00:00:00 2001
+From c36bd4545de8ae553fde7710a979cd2ddf87ec8c Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 12 Mar 2024 11:27:40 +0800
-Subject: [PATCH 06/61] sync backports patches/rt2x00
+Date: Wed, 17 Jul 2024 20:42:40 +0800
+Subject: [PATCH 06/89] backports: sync openwrt patches/rt2x00
 
 ---
  drivers/net/wireless/ralink/rt2x00/Kconfig    |  23 +-
@@ -12,7 +12,7 @@
  .../net/wireless/ralink/rt2x00/rt2800pci.c    |   7 +
  .../net/wireless/ralink/rt2x00/rt2800soc.c    |  52 ++-
  .../net/wireless/ralink/rt2x00/rt2800usb.c    |   7 +
- drivers/net/wireless/ralink/rt2x00/rt2x00.h   |  15 +
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h   |   9 +
  .../net/wireless/ralink/rt2x00/rt2x00dev.c    |  34 +-
  .../net/wireless/ralink/rt2x00/rt2x00eeprom.c | 208 ++++++++++
  .../net/wireless/ralink/rt2x00/rt2x00leds.c   |   3 +
@@ -20,7 +20,7 @@
  .../net/wireless/ralink/rt2x00/rt2x00soc.h    |   9 +
  include/linux/rt2x00_platform.h               |  23 ++
  local-symbols                                 |   1 +
- 16 files changed, 635 insertions(+), 166 deletions(-)
+ 16 files changed, 629 insertions(+), 166 deletions(-)
  create mode 100644 drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
  create mode 100644 include/linux/rt2x00_platform.h
 
@@ -825,7 +825,7 @@
  
  static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
 diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-index 0ac4ae9..27d283b 100644
+index 4e1ef18..b4b8b89 100644
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
 @@ -28,6 +28,8 @@
@@ -837,7 +837,7 @@
  
  #include <net/mac80211.h>
  
-@@ -407,6 +409,7 @@ struct hw_mode_spec {
+@@ -397,6 +399,7 @@ struct hw_mode_spec {
  	unsigned int supported_bands;
  #define SUPPORT_BAND_2GHZ	0x00000001
  #define SUPPORT_BAND_5GHZ	0x00000002
@@ -845,7 +845,7 @@
  
  	unsigned int supported_rates;
  #define SUPPORT_RATE_CCK	0x00000001
-@@ -702,6 +705,7 @@ enum rt2x00_capability_flags {
+@@ -692,6 +695,7 @@ enum rt2x00_capability_flags {
  	REQUIRE_HT_TX_DESC,
  	REQUIRE_PS_AUTOWAKE,
  	REQUIRE_DELAYED_RFKILL,
@@ -853,7 +853,7 @@
  
  	/*
  	 * Capabilities
-@@ -1024,6 +1028,11 @@ struct rt2x00_dev {
+@@ -1014,6 +1018,11 @@ struct rt2x00_dev {
  
  	/* Clock for System On Chip devices. */
  	struct clk *clk;
@@ -865,19 +865,6 @@
  };
  
  struct rt2x00_bar_list_entry {
-@@ -1271,6 +1280,12 @@ rt2x00_has_cap_external_pa(struct rt2x00_dev *rt2x00dev)
- 	return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_PA_TX0);
- }
- 
-+static inline bool
-+rt2x00_has_cap_external_pa(struct rt2x00_dev *rt2x00dev)
-+{
-+	return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_PA_TX0);
-+}
-+
- static inline bool
- rt2x00_has_cap_double_antenna(struct rt2x00_dev *rt2x00dev)
- {
 diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
 index 274524e..69f8d5a 100644
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1247,10 +1234,10 @@
 +
 +#endif /* _RT2X00_PLATFORM_H */
 diff --git a/local-symbols b/local-symbols
-index 3d81ba5..beafad9 100644
+index c8f7132..ccc6ef7 100644
 --- a/local-symbols
 +++ b/local-symbols
-@@ -331,6 +331,7 @@ RT2X00_LIB_FIRMWARE=
+@@ -326,6 +326,7 @@ RT2X00_LIB_FIRMWARE=
  RT2X00_LIB_CRYPTO=
  RT2X00_LIB_LEDS=
  RT2X00_LIB_DEBUGFS=
@@ -1259,5 +1246,5 @@
  WLAN_VENDOR_REALTEK=
  RTL8180=
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0007-sync-backports-patches-subsys.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0007-backports-sync-openwrt-patches-subsys.patch
similarity index 62%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0007-sync-backports-patches-subsys.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0007-backports-sync-openwrt-patches-subsys.patch
index 2ab7252..e274749 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0007-sync-backports-patches-subsys.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0007-backports-sync-openwrt-patches-subsys.patch
@@ -1,36 +1,68 @@
-From 3a7f4236d9d089c749bbc4ff537f8ff2437acf2e Mon Sep 17 00:00:00 2001
+From 9e1ab5bbae5b4f2282ede448efb780d92f7187bb Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 12 Mar 2024 11:29:55 +0800
-Subject: [PATCH 07/61] sync backports patches/subsys
+Date: Wed, 17 Jul 2024 20:48:15 +0800
+Subject: [PATCH 07/89] backports: sync openwrt patches/subsys
 
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 ---
- include/net/cfg80211.h             | 28 +++++++++++
- net/mac80211/cfg.c                 |  2 +
+ backport-include/linux/of_net.h    | 26 -----------
+ include/net/cfg80211.h             | 13 ++++++
+ include/net/mac80211.h             |  2 +-
+ net/mac80211/cfg.c                 |  8 +---
  net/mac80211/debugfs.c             | 13 +++++-
  net/mac80211/ieee80211_i.h         |  4 ++
  net/mac80211/main.c                | 19 +-------
- net/mac80211/mesh.c                |  8 +++-
- net/mac80211/mesh.h                | 31 ++++++++++--
- net/mac80211/mesh_pathtbl.c        | 19 +++++---
  net/mac80211/rc80211_minstrel_ht.c | 75 +++++++-----------------------
  net/mac80211/rc80211_minstrel_ht.h |  2 +-
- net/mac80211/rx.c                  | 13 ++++--
- net/mac80211/sta_info.c            | 29 +++++++-----
- net/mac80211/tx.c                  | 46 +++++++++---------
+ net/mac80211/sta_info.c            | 29 +++++++++++-
+ net/mac80211/sta_info.h            |  3 +-
+ net/mac80211/status.c              |  5 +-
+ net/mac80211/tx.c                  | 63 +++++++++++++------------
  net/wireless/ap.c                  |  6 +--
  net/wireless/chan.c                | 45 ++++++++++++++++++
  net/wireless/core.c                | 15 ------
  net/wireless/core.h                |  2 +
  net/wireless/mlme.c                |  7 +--
  net/wireless/sysfs.c               | 27 +++++++++--
- 19 files changed, 240 insertions(+), 151 deletions(-)
+ 19 files changed, 192 insertions(+), 172 deletions(-)
+ delete mode 100644 backport-include/linux/of_net.h
 
+diff --git a/backport-include/linux/of_net.h b/backport-include/linux/of_net.h
+deleted file mode 100644
+index 9b9276f..0000000
+--- a/backport-include/linux/of_net.h
++++ /dev/null
+@@ -1,26 +0,0 @@
+-#ifndef _BP_OF_NET_H
+-#define _BP_OF_NET_H
+-#include_next <linux/of_net.h>
+-#include <linux/version.h>
+-#include <linux/etherdevice.h>
+-
+-/* The behavior of of_get_mac_address() changed in kernel 5.2, it now
+- * returns an error code and not NULL in case of an error.
+- */
+-#if LINUX_VERSION_IS_LESS(5,13,0)
+-static inline int backport_of_get_mac_address(struct device_node *np, u8 *mac_out)
+-{
+-	const void *mac = of_get_mac_address(np);
+-
+-	if (!mac)
+-		return -ENODEV;
+-	if (IS_ERR(mac))
+-		return PTR_ERR(mac);
+-	ether_addr_copy(mac_out, mac);
+-	
+-	return 0;
+-}
+-#define of_get_mac_address LINUX_BACKPORT(of_get_mac_address)
+-#endif /* < 5.2 */
+-
+-#endif /* _BP_OF_NET_H */
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 0b5799f..4c5daf9 100644
+index ca7135d..850861b 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -189,6 +189,8 @@ enum ieee80211_channel_flags {
+@@ -192,6 +192,8 @@ enum ieee80211_channel_flags {
   * @dfs_state: current state of this channel. Only relevant if radar is required
   *	on this channel.
   * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
@@ -39,7 +71,7 @@
   * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
   * @psd: power spectral density (in dBm)
   */
-@@ -206,6 +208,7 @@ struct ieee80211_channel {
+@@ -209,6 +211,7 @@ struct ieee80211_channel {
  	int orig_mag, orig_mpwr;
  	enum nl80211_dfs_state dfs_state;
  	unsigned long dfs_state_entered;
@@ -47,38 +79,7 @@
  	unsigned int dfs_cac_ms;
  	s8 psd;
  };
-@@ -1075,6 +1078,30 @@ int cfg80211_chandef_primary(const struct cfg80211_chan_def *chandef,
- 			     enum nl80211_chan_width primary_chan_width,
- 			     u16 *punctured);
- 
-+/**
-+ * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable and we
-+ *				 can/need start CAC on such channel
-+ * @wiphy: the wiphy to validate against
-+ * @chandef: the channel definition to check
-+ *
-+ * Return: true if all channels available and at least
-+ *	   one channel requires CAC (NL80211_DFS_USABLE)
-+ */
-+bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
-+				 const struct cfg80211_chan_def *chandef);
-+
-+/**
-+ * cfg80211_chandef_dfs_cac_time - get the DFS CAC time (in ms) for given
-+ *				   channel definition
-+ * @wiphy: the wiphy to validate against
-+ * @chandef: the channel definition to check
-+ *
-+ * Returns: DFS CAC time (in ms) which applies for this channel definition
-+ */
-+unsigned int
-+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
-+			      const struct cfg80211_chan_def *chandef);
-+
- /**
-  * nl80211_send_chandef - sends the channel definition.
-  * @msg: the msg to send channel definition
-@@ -3413,6 +3440,7 @@ enum wiphy_params_flags {
+@@ -3425,6 +3428,7 @@ enum wiphy_params_flags {
  /* The per TXQ device queue limit in airtime */
  #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L	5000
  #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H	12000
@@ -86,11 +87,54 @@
  
  /* The per interface airtime threshold to switch to lower queue limit */
  #define IEEE80211_AQL_THRESHOLD			24000
+@@ -6527,6 +6531,15 @@ static inline bool cfg80211_channel_is_psc(struct ieee80211_channel *chan)
+ bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
+ 				  const struct cfg80211_chan_def *chandef);
+ 
++/**
++ * cfg80211_radio_chandef_valid - Check if the radio supports the chandef
++ *
++ * @radio: wiphy radio
++ * @chandef: chandef for current channel
++ */
++bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
++				  const struct cfg80211_chan_def *chandef);
++
+ /**
+  * ieee80211_get_response_rate - get basic rate for a given rate
+  *
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index c50b8a2..c43d511 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1221,8 +1221,8 @@ struct ieee80211_tx_info {
+ 	    status_data_idr:1,
+ 	    status_data:13,
+ 	    hw_queue:4,
++	    tx_time_mc:1,
+ 	    tx_time_est:10;
+-	/* 1 free bit */
+ 
+ 	union {
+ 		struct {
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index db71792..72e64be 100644
+index a88cc41..1bf8626 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2851,6 +2851,8 @@ static int ieee80211_scan(struct wiphy *wiphy,
+@@ -1649,12 +1649,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
+ 
+ 	__sta_info_flush(sdata, true, link_id);
+ 
+-	ieee80211_remove_link_keys(link, &keys);
+-	if (!list_empty(&keys)) {
+-		synchronize_net();
+-		ieee80211_free_key_list(local, &keys);
+-	}
+-
+ 	link_conf->enable_beacon = false;
+ 	sdata->beacon_rate_set = false;
+ 	sdata->vif.cfg.ssid_len = 0;
+@@ -2869,6 +2863,8 @@ static int ieee80211_scan(struct wiphy *wiphy,
  		 */
  		fallthrough;
  	case NL80211_IFTYPE_AP:
@@ -100,7 +144,7 @@
  		 * If the scan has been forced (and the driver supports
  		 * forcing), don't care about being beaconing already.
 diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
-index c660138..f9c5ed8 100644
+index f9528ab..ce8eb40 100644
 --- a/net/mac80211/debugfs.c
 +++ b/net/mac80211/debugfs.c
 @@ -215,11 +215,13 @@ static ssize_t aql_pending_read(struct file *file,
@@ -150,10 +194,10 @@
  		return -EINVAL;
  
 diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
-index 4827825..c5781c3 100644
+index 44cc978..c9d6743 100644
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -102,6 +102,8 @@ ieee80211_sta_keep_active(struct sta_info *sta, u8 ac)
+@@ -103,6 +103,8 @@ ieee80211_sta_keep_active(struct sta_info *sta, u8 ac)
  	return time_before_eq(jiffies, sta->airtime[ac].last_active + HZ / 10);
  }
  
@@ -162,7 +206,7 @@
  struct ieee80211_bss {
  	u32 device_ts_beacon, device_ts_presp;
  
-@@ -1343,10 +1345,12 @@ struct ieee80211_local {
+@@ -1353,10 +1355,12 @@ struct ieee80211_local {
  	spinlock_t handle_wake_tx_queue_lock;
  
  	u16 airtime_flags;
@@ -176,10 +220,10 @@
  
  	const struct ieee80211_ops *ops;
 diff --git a/net/mac80211/main.c b/net/mac80211/main.c
-index 6518ca5..81a9645 100644
+index 3257545..79c77af 100644
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
-@@ -944,6 +944,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
+@@ -952,6 +952,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
  	spin_lock_init(&local->rx_path_lock);
  	spin_lock_init(&local->queue_stop_reason_lock);
  
@@ -187,9 +231,9 @@
  	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
  		INIT_LIST_HEAD(&local->active_txqs[i]);
  		spin_lock_init(&local->active_txq_lock[i]);
-@@ -1562,24 +1563,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
- 	debugfs_hw_add(local);
- 	rate_control_add_debugfs(local);
+@@ -1581,24 +1582,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+ 
+ 	ieee80211_check_wbrf_support(local);
  
 -	rtnl_lock();
 -	wiphy_lock(hw->wiphy);
@@ -212,170 +256,11 @@
  #ifdef CONFIG_INET
  	local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
  	result = register_inetaddr_notifier(&local->ifa_notifier);
-diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
-index 32475da..cbc9b5e 100644
---- a/net/mac80211/mesh.c
-+++ b/net/mac80211/mesh.c
-@@ -747,6 +747,9 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
- 			      struct sk_buff *skb, u32 ctrl_flags)
- {
- 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-+	struct ieee80211_mesh_fast_tx_key key = {
-+		.type = MESH_FAST_TX_TYPE_LOCAL
-+	};
- 	struct ieee80211_mesh_fast_tx *entry;
- 	struct ieee80211s_hdr *meshhdr;
- 	u8 sa[ETH_ALEN] __aligned(2);
-@@ -782,7 +785,10 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
- 			return false;
- 	}
- 
--	entry = mesh_fast_tx_get(sdata, skb->data);
-+	ether_addr_copy(key.addr, skb->data);
-+	if (!ether_addr_equal(skb->data + ETH_ALEN, sdata->vif.addr))
-+		key.type = MESH_FAST_TX_TYPE_PROXIED;
-+	entry = mesh_fast_tx_get(sdata, &key);
- 	if (!entry)
- 		return false;
- 
-diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
-index c472b49..c0c357f 100644
---- a/net/mac80211/mesh.h
-+++ b/net/mac80211/mesh.h
-@@ -134,10 +134,34 @@ struct mesh_path {
- #define MESH_FAST_TX_CACHE_THRESHOLD_SIZE	384
- #define MESH_FAST_TX_CACHE_TIMEOUT		8000 /* msecs */
- 
-+/**
-+ * enum ieee80211_mesh_fast_tx_type - cached mesh fast tx entry type
-+ *
-+ * @MESH_FAST_TX_TYPE_LOCAL: tx from the local vif address as SA
-+ * @MESH_FAST_TX_TYPE_PROXIED: local tx with a different SA (e.g. bridged)
-+ * @MESH_FAST_TX_TYPE_FORWARDED: forwarded from a different mesh point
-+ */
-+enum ieee80211_mesh_fast_tx_type {
-+	MESH_FAST_TX_TYPE_LOCAL,
-+	MESH_FAST_TX_TYPE_PROXIED,
-+	MESH_FAST_TX_TYPE_FORWARDED,
-+};
-+
-+/**
-+ * struct ieee80211_mesh_fast_tx_key - cached mesh fast tx entry key
-+ *
-+ * @addr: The Ethernet DA for this entry
-+ * @type: cache entry type
-+ */
-+struct ieee80211_mesh_fast_tx_key {
-+	u8 addr[ETH_ALEN] __aligned(2);
-+	enum ieee80211_mesh_fast_tx_type type;
-+};
-+
- /**
-  * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry
-  * @rhash: rhashtable pointer
-- * @addr_key: The Ethernet DA which is the key for this entry
-+ * @key: the lookup key for this cache entry
-  * @fast_tx: base fast_tx data
-  * @hdr: cached mesh and rfc1042 headers
-  * @hdrlen: length of mesh + rfc1042
-@@ -148,7 +172,7 @@ struct mesh_path {
-  */
- struct ieee80211_mesh_fast_tx {
- 	struct rhash_head rhash;
--	u8 addr_key[ETH_ALEN] __aligned(2);
-+	struct ieee80211_mesh_fast_tx_key key;
- 
- 	struct ieee80211_fast_tx fast_tx;
- 	u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)];
-@@ -334,7 +358,8 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
- 
- bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
- struct ieee80211_mesh_fast_tx *
--mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr);
-+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata,
-+		 struct ieee80211_mesh_fast_tx_key *key);
- bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
- 			      struct sk_buff *skb, u32 ctrl_flags);
- void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
-diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
-index 91b55d6..93f6a03 100644
---- a/net/mac80211/mesh_pathtbl.c
-+++ b/net/mac80211/mesh_pathtbl.c
-@@ -37,8 +37,8 @@ static const struct rhashtable_params mesh_rht_params = {
- static const struct rhashtable_params fast_tx_rht_params = {
- 	.nelem_hint = 10,
- 	.automatic_shrinking = true,
--	.key_len = ETH_ALEN,
--	.key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key),
-+	.key_len = sizeof(struct ieee80211_mesh_fast_tx_key),
-+	.key_offset = offsetof(struct ieee80211_mesh_fast_tx, key),
- 	.head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash),
- 	.hashfn = mesh_table_hash,
- };
-@@ -431,20 +431,21 @@ static void mesh_fast_tx_entry_free(struct mesh_tx_cache *cache,
- }
- 
- struct ieee80211_mesh_fast_tx *
--mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr)
-+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata,
-+		 struct ieee80211_mesh_fast_tx_key *key)
- {
- 	struct ieee80211_mesh_fast_tx *entry;
- 	struct mesh_tx_cache *cache;
- 
- 	cache = &sdata->u.mesh.tx_cache;
--	entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
-+	entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params);
- 	if (!entry)
- 		return NULL;
- 
- 	if (!(entry->mpath->flags & MESH_PATH_ACTIVE) ||
- 	    mpath_expired(entry->mpath)) {
- 		spin_lock_bh(&cache->walk_lock);
--		entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
-+		entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params);
- 		if (entry)
- 		    mesh_fast_tx_entry_free(cache, entry);
- 		spin_unlock_bh(&cache->walk_lock);
-@@ -489,18 +490,24 @@ void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
- 	if (!sta)
- 		return;
- 
-+	build.key.type = MESH_FAST_TX_TYPE_LOCAL;
- 	if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) {
- 		/* This is required to keep the mppath alive */
- 		mppath = mpp_path_lookup(sdata, meshhdr->eaddr1);
- 		if (!mppath)
- 			return;
- 		build.mppath = mppath;
-+		if (!ether_addr_equal(meshhdr->eaddr2, sdata->vif.addr))
-+			build.key.type = MESH_FAST_TX_TYPE_PROXIED;
- 	} else if (ieee80211_has_a4(hdr->frame_control)) {
- 		mppath = mpath;
- 	} else {
- 		return;
- 	}
- 
-+	if (!ether_addr_equal(hdr->addr4, sdata->vif.addr))
-+		build.key.type = MESH_FAST_TX_TYPE_FORWARDED;
-+
- 	/* rate limit, in case fast xmit can't be enabled */
- 	if (mppath->fast_tx_check == jiffies)
- 		return;
-@@ -547,7 +554,7 @@ void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
- 		}
- 	}
- 
--	memcpy(build.addr_key, mppath->dst, ETH_ALEN);
-+	memcpy(build.key.addr, mppath->dst, ETH_ALEN);
- 	build.timestamp = jiffies;
- 	build.fast_tx.band = info->band;
- 	build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3);
 diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
-index 62f323a..74413d7 100644
+index b128191..802cd6c 100644
 --- a/net/mac80211/rc80211_minstrel_ht.c
 +++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -582,6 +582,14 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
+@@ -580,6 +580,14 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
  	int cur_tp_avg, cur_group, cur_idx;
  	int max_gpr_group, max_gpr_idx;
  	int max_gpr_tp_avg, max_gpr_prob;
@@ -390,7 +275,7 @@
  
  	cur_group = MI_RATE_GROUP(index);
  	cur_idx = MI_RATE_IDX(index);
-@@ -603,11 +611,6 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
+@@ -601,11 +609,6 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
  	    !minstrel_ht_is_legacy_group(max_tp_group))
  		return;
  
@@ -402,7 +287,7 @@
  	max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate);
  	max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate);
  	max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
-@@ -665,40 +668,6 @@ minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
+@@ -663,40 +666,6 @@ minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
  
  }
  
@@ -443,7 +328,7 @@
  static u16
  __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi,
  			      enum minstrel_sample_type type)
-@@ -771,7 +740,8 @@ minstrel_ht_calc_rate_stats(struct minstrel_priv *mp,
+@@ -769,7 +738,8 @@ minstrel_ht_calc_rate_stats(struct minstrel_priv *mp,
  	unsigned int cur_prob;
  
  	if (unlikely(mrs->attempts > 0)) {
@@ -453,7 +338,7 @@
  		minstrel_filter_avg_add(&mrs->prob_avg,
  					&mrs->prob_avg_1, cur_prob);
  		mrs->att_hist += mrs->attempts;
-@@ -1177,8 +1147,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
+@@ -1175,8 +1145,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
  
  	mi->max_prob_rate = tmp_max_prob_rate;
  
@@ -462,7 +347,7 @@
  	minstrel_ht_refill_sample_rates(mi);
  
  #ifdef CPTCFG_MAC80211_DEBUGFS
-@@ -1257,7 +1225,7 @@ minstrel_ht_ri_txstat_valid(struct minstrel_priv *mp,
+@@ -1255,7 +1223,7 @@ minstrel_ht_ri_txstat_valid(struct minstrel_priv *mp,
  }
  
  static void
@@ -471,7 +356,7 @@
  {
  	int group, orig_group;
  
-@@ -1272,11 +1240,7 @@ minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
+@@ -1270,11 +1238,7 @@ minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
  		    minstrel_mcs_groups[orig_group].streams)
  			continue;
  
@@ -484,7 +369,7 @@
  	}
  }
  
-@@ -1287,7 +1251,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
+@@ -1285,7 +1249,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
  	struct ieee80211_tx_info *info = st->info;
  	struct minstrel_ht_sta *mi = priv_sta;
  	struct ieee80211_tx_rate *ar = info->status.rates;
@@ -493,7 +378,7 @@
  	struct minstrel_priv *mp = priv;
  	u32 update_interval = mp->update_interval;
  	bool last, update = false;
-@@ -1355,18 +1319,13 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
+@@ -1353,18 +1317,13 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
  		/*
  		 * check for sudden death of spatial multiplexing,
  		 * downgrade to a lower number of streams if necessary.
@@ -529,90 +414,53 @@
  #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
  
  #define EWMA_LEVEL	96	/* ewma weighting factor [/EWMA_DIV] */
-diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 42ffd1e..be724c2 100644
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2767,7 +2767,10 @@ ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata,
- 			       struct sk_buff *skb, int hdrlen)
- {
- 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
--	struct ieee80211_mesh_fast_tx *entry = NULL;
-+	struct ieee80211_mesh_fast_tx_key key = {
-+		.type = MESH_FAST_TX_TYPE_FORWARDED
-+	};
-+	struct ieee80211_mesh_fast_tx *entry;
- 	struct ieee80211s_hdr *mesh_hdr;
- 	struct tid_ampdu_tx *tid_tx;
- 	struct sta_info *sta;
-@@ -2776,9 +2779,13 @@ ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata,
- 
- 	mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth));
- 	if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
--		entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1);
-+		ether_addr_copy(key.addr, mesh_hdr->eaddr1);
- 	else if (!(mesh_hdr->flags & MESH_FLAGS_AE))
--		entry = mesh_fast_tx_get(sdata, skb->data);
-+		ether_addr_copy(key.addr, skb->data);
-+	else
-+		return false;
-+
-+	entry = mesh_fast_tx_get(sdata, &key);
- 	if (!entry)
- 		return false;
- 
 diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
-index 32d050c..411a610 100644
+index 16f28db..83e98c7 100644
 --- a/net/mac80211/sta_info.c
 +++ b/net/mac80211/sta_info.c
-@@ -912,6 +912,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
+@@ -565,6 +565,11 @@ __sta_info_alloc(struct ieee80211_sub_if_data *sdata,
+ 	spin_lock_init(&sta->ps_lock);
+ 	INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
+ 	wiphy_work_init(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
++#if LINUX_VERSION_IS_LESS(6,2,0)
++	sta->ampdu_mlme.dialog_token_allocator = prandom_u32_max(U8_MAX);
++#else
++	sta->ampdu_mlme.dialog_token_allocator = get_random_u32_below(U8_MAX);
++#endif
+ #ifdef CPTCFG_MAC80211_MESH
+ 	if (ieee80211_vif_is_mesh(&sdata->vif)) {
+ 		sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);
+@@ -2352,13 +2357,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggregates);
  
- 	if (ieee80211_vif_is_mesh(&sdata->vif))
- 		mesh_accept_plinks_update(sdata);
-+	ieee80211_check_fast_xmit(sta);
- 
- 	ieee80211_check_fast_xmit(sta);
- 
-@@ -2354,28 +2355,27 @@ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
+ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
  					  struct sta_info *sta, u8 ac,
- 					  u16 tx_airtime, bool tx_completed)
+-					  u16 tx_airtime, bool tx_completed)
++					  u16 tx_airtime, bool tx_completed,
++					  bool mcast)
  {
-+	atomic_t *counter;
  	int tx_pending;
  
  	if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
  		return;
- 
--	if (!tx_completed) {
--		if (sta)
--			atomic_add(tx_airtime,
--				   &sta->airtime[ac].aql_tx_pending);
-+	if (sta)
-+		counter = &sta->airtime[ac].aql_tx_pending;
-+	else
-+		counter = &local->aql_bc_pending_airtime;
- 
-+	if (!tx_completed) {
-+		atomic_add(tx_airtime, counter);
- 		atomic_add(tx_airtime, &local->aql_total_pending_airtime);
- 		atomic_add(tx_airtime, &local->aql_ac_pending_airtime[ac]);
- 		return;
- 	}
  
--	if (sta) {
--		tx_pending = atomic_sub_return(tx_airtime,
--					       &sta->airtime[ac].aql_tx_pending);
--		if (tx_pending < 0)
--			atomic_cmpxchg(&sta->airtime[ac].aql_tx_pending,
--				       tx_pending, 0);
--	}
-+	tx_pending = atomic_sub_return(tx_airtime, counter);
-+	if (tx_pending < 0)
-+		atomic_cmpxchg(counter, tx_pending, 0);
- 
- 	atomic_sub(tx_airtime, &local->aql_total_pending_airtime);
- 	tx_pending = atomic_sub_return(tx_airtime,
-@@ -2439,6 +2439,13 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
++	if (mcast) {
++		if (!tx_completed) {
++			atomic_add(tx_airtime, &local->aql_bc_pending_airtime);
++			return;
++		}
++
++		tx_pending = atomic_sub_return(tx_airtime,
++					       &local->aql_bc_pending_airtime);
++		if (tx_pending < 0)
++			atomic_cmpxchg(&local->aql_bc_pending_airtime,
++				       tx_pending, 0);
++		return;
++	}
++
+ 	if (!tx_completed) {
+ 		if (sta)
+ 			atomic_add(tx_airtime,
+@@ -2439,6 +2459,13 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
  
  		sband = local->hw.wiphy->bands[band];
  
@@ -626,11 +474,60 @@
  		if (WARN_ON_ONCE(!sband->bitrates))
  			break;
  
+diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
+index d1b3a61..40513d8 100644
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -147,7 +147,8 @@ struct airtime_info {
+ 
+ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
+ 					  struct sta_info *sta, u8 ac,
+-					  u16 tx_airtime, bool tx_completed);
++					  u16 tx_airtime, bool tx_completed,
++					  bool mcast);
+ 
+ struct sta_info;
+ 
+diff --git a/net/mac80211/status.c b/net/mac80211/status.c
+index df5a329..3f72c7e 100644
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -734,7 +734,7 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
+ 		ieee80211_sta_update_pending_airtime(local, sta,
+ 						     skb_get_queue_mapping(skb),
+ 						     tx_time_est,
+-						     true);
++						     true, info->tx_time_mc);
+ 		rcu_read_unlock();
+ 	}
+ 
+@@ -1162,10 +1162,11 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
+ 		/* Do this here to avoid the expensive lookup of the sta
+ 		 * in ieee80211_report_used_skb().
+ 		 */
++		bool mcast = IEEE80211_SKB_CB(skb)->tx_time_mc;
+ 		ieee80211_sta_update_pending_airtime(local, sta,
+ 						     skb_get_queue_mapping(skb),
+ 						     tx_time_est,
+-						     true);
++						     true, mcast);
+ 		ieee80211_info_set_tx_time_est(IEEE80211_SKB_CB(skb), 0);
+ 	}
+ 
 diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
-index 141b094..f479d87 100644
+index bec9cc3..65f9c26 100644
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -3978,9 +3978,8 @@ begin:
+@@ -2554,7 +2554,7 @@ static u16 ieee80211_store_ack_skb(struct ieee80211_local *local,
+ 
+ 		spin_lock_irqsave(&local->ack_status_lock, flags);
+ 		id = idr_alloc(&local->ack_status_frames, ack_skb,
+-			       1, 0x2000, GFP_ATOMIC);
++			       1, 0x1000, GFP_ATOMIC);
+ 		spin_unlock_irqrestore(&local->ack_status_lock, flags);
+ 
+ 		if (id >= 0) {
+@@ -3981,20 +3981,20 @@ begin:
  encap_out:
  	info->control.vif = vif;
  
@@ -642,7 +539,26 @@
  		u32 airtime;
  
  		airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
-@@ -4043,6 +4042,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
+ 							     skb->len, ampdu);
+-		if (airtime) {
+-			airtime = ieee80211_info_set_tx_time_est(info, airtime);
+-			ieee80211_sta_update_pending_airtime(local, tx.sta,
+-							     txq->ac,
+-							     airtime,
+-							     false);
+-		}
++		if (!airtime)
++			return skb;
++
++		airtime = ieee80211_info_set_tx_time_est(info, airtime);
++		info->tx_time_mc = !tx.sta;
++		ieee80211_sta_update_pending_airtime(local, tx.sta, txq->ac,
++						     airtime, false,
++						     info->tx_time_mc);
+ 	}
+ 
+ 	return skb;
+@@ -4046,6 +4046,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
  	struct ieee80211_txq *ret = NULL;
  	struct txq_info *txqi = NULL, *head = NULL;
  	bool found_eligible_txq = false;
@@ -650,7 +566,7 @@
  
  	spin_lock_bh(&local->active_txq_lock[ac]);
  
-@@ -4066,26 +4066,26 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
+@@ -4069,26 +4070,26 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
  	if (!head)
  		head = txqi;
  
@@ -690,7 +606,7 @@
  	if (txqi->schedule_round == local->schedule_round[ac])
  		goto out;
  
-@@ -4150,7 +4150,8 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
+@@ -4153,7 +4154,8 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
  		return true;
  
  	if (!txq->sta)
@@ -700,7 +616,7 @@
  
  	if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
  		return true;
-@@ -4199,15 +4200,15 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
+@@ -4202,15 +4204,15 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
  
  	spin_lock_bh(&local->active_txq_lock[ac]);
  
@@ -719,7 +635,7 @@
  	list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
  				 schedule_order) {
  		if (iter == txqi)
-@@ -4220,7 +4221,8 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
+@@ -4223,7 +4225,8 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
  		}
  		sta = container_of(iter->txq.sta, struct sta_info, sta);
  		if (ieee80211_sta_deficit(sta, ac) < 0)
@@ -729,7 +645,7 @@
  		list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
  	}
  
-@@ -4228,7 +4230,7 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
+@@ -4231,7 +4234,7 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
  	if (sta->airtime[ac].deficit >= 0)
  		goto out;
  
@@ -763,10 +679,10 @@
  	}
  
 diff --git a/net/wireless/chan.c b/net/wireless/chan.c
-index 14c27bc..4bac395 100644
+index 138df3a..edc9034 100644
 --- a/net/wireless/chan.c
 +++ b/net/wireless/chan.c
-@@ -560,6 +560,8 @@ static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
+@@ -598,6 +598,8 @@ static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
  
  		c->dfs_state = dfs_state;
  		c->dfs_state_entered = jiffies;
@@ -775,7 +691,7 @@
  	}
  }
  
-@@ -1049,6 +1051,49 @@ static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
+@@ -1087,6 +1089,49 @@ static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
  	return true;
  }
  
@@ -826,10 +742,10 @@
  				const struct cfg80211_chan_def *chandef)
  {
 diff --git a/net/wireless/core.c b/net/wireless/core.c
-index 0cd5c78..ac9417e 100644
+index 79d5526..45e2d94 100644
 --- a/net/wireless/core.c
 +++ b/net/wireless/core.c
-@@ -662,21 +662,6 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
+@@ -665,21 +665,6 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
  				    c->limits[j].max > 1))
  				return -EINVAL;
  
@@ -852,7 +768,7 @@
  			/*
  			 * Don't advertise an unsupported type
 diff --git a/net/wireless/core.h b/net/wireless/core.h
-index 2e19279..7bef6b0 100644
+index 4304d1a..cebc5a1 100644
 --- a/net/wireless/core.h
 +++ b/net/wireless/core.h
 @@ -467,6 +467,8 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
@@ -892,7 +808,7 @@
  				c->dfs_state = NL80211_DFS_USABLE;
  				c->dfs_state_entered = jiffies;
 diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
-index 1387106..49aac4c 100644
+index 4f855bf..7d0cca8 100644
 --- a/net/wireless/sysfs.c
 +++ b/net/wireless/sysfs.c
 @@ -24,18 +24,35 @@ static inline struct cfg80211_registered_device *dev_to_rdev(
@@ -937,5 +853,5 @@
  static ssize_t name_show(struct device *dev,
  			 struct device_attribute *attr,
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0008-backports-additional-fixes-for-5.4.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0008-backports-additional-fixes-for-5.4.patch
new file mode 100644
index 0000000..fb741ce
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0008-backports-additional-fixes-for-5.4.patch
@@ -0,0 +1,351 @@
+From 583499fbb339855db968cbee875b3d267ee7eedf Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Thu, 18 Jul 2024 12:05:11 +0800
+Subject: [PATCH 08/89] backports: additional fixes for 5.4
+
+Modify some parts to let current backports work on kernel 5.4.
+
+Including:
+Revert "wifi: mac80211: Move stats allocation to core"
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ backport-include/linux/of_net.h               | 26 +++++++++++++++++++
+ backport-include/linux/skbuff.h               |  8 ++++++
+ backport-include/linux/soc/mediatek/mtk_wed.h |  2 +-
+ backport-include/linux/thermal.h              |  4 +--
+ backport-include/net/dropreason-core.h        |  6 +++++
+ backport-include/net/netlink.h                | 26 ++++++++++++++++++-
+ net/mac80211/iface.c                          | 17 ++++++++----
+ net/mac80211/trace.h                          |  2 +-
+ net/wireless/nl80211.c                        | 22 +++++++++++++++-
+ net/wireless/trace.h                          |  2 +-
+ 10 files changed, 103 insertions(+), 12 deletions(-)
+ create mode 100644 backport-include/linux/of_net.h
+
+diff --git a/backport-include/linux/of_net.h b/backport-include/linux/of_net.h
+new file mode 100644
+index 0000000..9b9276f
+--- /dev/null
++++ b/backport-include/linux/of_net.h
+@@ -0,0 +1,26 @@
++#ifndef _BP_OF_NET_H
++#define _BP_OF_NET_H
++#include_next <linux/of_net.h>
++#include <linux/version.h>
++#include <linux/etherdevice.h>
++
++/* The behavior of of_get_mac_address() changed in kernel 5.2, it now
++ * returns an error code and not NULL in case of an error.
++ */
++#if LINUX_VERSION_IS_LESS(5,13,0)
++static inline int backport_of_get_mac_address(struct device_node *np, u8 *mac_out)
++{
++	const void *mac = of_get_mac_address(np);
++
++	if (!mac)
++		return -ENODEV;
++	if (IS_ERR(mac))
++		return PTR_ERR(mac);
++	ether_addr_copy(mac_out, mac);
++	
++	return 0;
++}
++#define of_get_mac_address LINUX_BACKPORT(of_get_mac_address)
++#endif /* < 5.2 */
++
++#endif /* _BP_OF_NET_H */
+diff --git a/backport-include/linux/skbuff.h b/backport-include/linux/skbuff.h
+index b40d25c..8c3d839 100644
+--- a/backport-include/linux/skbuff.h
++++ b/backport-include/linux/skbuff.h
+@@ -88,4 +88,12 @@ static inline struct sk_buff *LINUX_BACKPORT(skb_recv_datagram)(struct sock *sk,
+ #define skb_recv_datagram LINUX_BACKPORT(skb_recv_datagram)
+ #endif /* < 5.17 */
+ 
++#if LINUX_VERSION_IS_LESS(6,0,0)
++#define kfree_skb_reason LINUX_BACKPORT(kfree_skb_reason)
++static inline void kfree_skb_reason(struct sk_buff *skb, int reason)
++{
++	return kfree_skb(skb);
++}
++#endif /* < 6.0.0 */
++
+ #endif /* __BACKPORT_SKBUFF_H */
+diff --git a/backport-include/linux/soc/mediatek/mtk_wed.h b/backport-include/linux/soc/mediatek/mtk_wed.h
+index 46caa89..cd96b4a 100644
+--- a/backport-include/linux/soc/mediatek/mtk_wed.h
++++ b/backport-include/linux/soc/mediatek/mtk_wed.h
+@@ -2,7 +2,7 @@
+ #define __BACKPORT_MTK_WED_H
+ #include <linux/version.h>
+ 
+-#if LINUX_VERSION_IS_GEQ(5,19,0)
++#if LINUX_VERSION_IS_GEQ(5,4,0)
+ #include_next <linux/soc/mediatek/mtk_wed.h>
+ #else
+ #include <linux/kernel.h>
+diff --git a/backport-include/linux/thermal.h b/backport-include/linux/thermal.h
+index d6b8a8f..e78f2fb 100644
+--- a/backport-include/linux/thermal.h
++++ b/backport-include/linux/thermal.h
+@@ -37,7 +37,7 @@ static inline void *thermal_zone_device_priv(struct thermal_zone_device *tzd)
+ }
+ #endif
+ 
+-#if LINUX_VERSION_IS_LESS(6,6,0)
++#if LINUX_VERSION_IS_LESS(5,4,0)
+ #define for_each_thermal_trip LINUX_BACKPORT(for_each_thermal_trip)
+ static inline int for_each_thermal_trip(struct thermal_zone_device *tz,
+ 					int (*cb)(struct thermal_trip *, void *),
+@@ -56,6 +56,6 @@ static inline int for_each_thermal_trip(struct thermal_zone_device *tz,
+ 
+ 	return 0;
+ }
+-#endif /* < 6.6 */
++#endif /* < 5.4 */
+ 
+ #endif /* __BACKPORT_LINUX_THERMAL_H */
+diff --git a/backport-include/net/dropreason-core.h b/backport-include/net/dropreason-core.h
+index ab8532e..31c60b9 100644
+--- a/backport-include/net/dropreason-core.h
++++ b/backport-include/net/dropreason-core.h
+@@ -13,6 +13,12 @@
+ 
+ #include <linux/version.h>
+ 
++/* backport for 5.4 */
++#if LINUX_VERSION_IS_LESS(5,5,0)
++#define SKB_DROP_REASON_NOT_SPECIFIED 2
++#define SKB_DROP_REASON_MAX 69
++#endif
++
+ #if LINUX_VERSION_IS_LESS(5,18,0)
+ #define SKB_NOT_DROPPED_YET SKB_DROP_REASON_MAX
+ #endif
+diff --git a/backport-include/net/netlink.h b/backport-include/net/netlink.h
+index 0a6740b..68bf3e8 100644
+--- a/backport-include/net/netlink.h
++++ b/backport-include/net/netlink.h
+@@ -348,6 +348,30 @@ enum nla_policy_validation {
+ }
+ #endif /* < 4.20 */
+ 
++#if LINUX_VERSION_IS_GEQ(5,10,0)
++#define __NLA_IS_UINT_TYPE(tp)					\
++	(tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 ||	\
++	 tp == NLA_U64 || tp == NLA_UINT ||			\
++	 tp == NLA_BE16 || tp == NLA_BE32)
++#define __NLA_IS_SINT_TYPE(tp)						\
++	(tp == NLA_S8 || tp == NLA_S16 || tp == NLA_S32 || tp == NLA_S64 || \
++	 tp == NLA_SINT)
++
++#define NLA_ENSURE_UINT_TYPE(tp)			\
++	(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp)) + tp)
++#define NLA_ENSURE_UINT_OR_BINARY_TYPE(tp)		\
++	(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) ||	\
++		      tp == NLA_MSECS ||		\
++		      tp == NLA_BINARY) + tp)
++#define NLA_ENSURE_SINT_TYPE(tp)			\
++	(__NLA_ENSURE(__NLA_IS_SINT_TYPE(tp)) + tp)
++#define NLA_ENSURE_INT_OR_BINARY_TYPE(tp)		\
++	(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) ||		\
++		      __NLA_IS_SINT_TYPE(tp) ||		\
++		      tp == NLA_MSECS ||		\
++		      tp == NLA_BINARY) + tp)
++#endif
++
+ #if LINUX_VERSION_IS_LESS(5,10,0)
+ // pre-declare all the minimum lengths in use
+ #define MIN_LEN_VALIDATION(n)						\
+@@ -382,7 +406,7 @@ MIN_LEN_VALIDATION(42)
+ #define NLA_POLICY_FULL_RANGE(tp, _range) {		\
+ 	.type = NLA_ENSURE_UINT_OR_BINARY_TYPE(tp),	\
+ 	.validation_type = NLA_VALIDATE_RANGE_PTR,	\
+-	.range = (struct netlink_range_validation *)_range, \
+ }
+ 
++/* .range = (struct netlink_range_validation *)_range, */
+ #endif /* __BACKPORT_NET_NETLINK_H */
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index ee93439..b63a3c4 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -873,7 +873,6 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
+ 	.ndo_select_queue	= ieee80211_monitor_select_queue,
+ };
+ 
+-#if LINUX_VERSION_IS_GEQ(5,13,0)
+ static int ieee80211_netdev_fill_forward_path(struct net_device_path_ctx *ctx,
+ 					      struct net_device_path *path)
+ {
+@@ -931,7 +930,6 @@ out:
+ 
+ 	return ret;
+ }
+-#endif /* LINUX_VERSION_IS_GEQ(5,13,0) */
+ 
+ static const struct net_device_ops ieee80211_dataif_8023_ops = {
+ 	.ndo_open		= ieee80211_open,
+@@ -940,9 +938,7 @@ static const struct net_device_ops ieee80211_dataif_8023_ops = {
+ 	.ndo_start_xmit		= ieee80211_subif_start_xmit_8023,
+ 	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
+ 	.ndo_set_mac_address	= ieee80211_change_mac,
+-#if LINUX_VERSION_IS_GEQ(5,13,0)
+ 	.ndo_fill_forward_path	= ieee80211_netdev_fill_forward_path,
+-#endif
+ 	.ndo_setup_tc		= ieee80211_netdev_setup_tc,
+ };
+ 
+@@ -1451,6 +1447,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
+ 	return res;
+ }
+ 
++static void ieee80211_if_free(struct net_device *dev)
++{
++	free_percpu(dev->tstats);
++}
++
+ static void ieee80211_if_setup(struct net_device *dev)
+ {
+ 	ether_setup(dev);
+@@ -1458,6 +1459,7 @@ static void ieee80211_if_setup(struct net_device *dev)
+ 	dev->priv_flags |= IFF_NO_QUEUE;
+ 	dev->netdev_ops = &ieee80211_dataif_ops;
+ 	dev->needs_free_netdev = true;
++	dev->priv_destructor = ieee80211_if_free;
+ }
+ 
+ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
+@@ -2090,7 +2092,11 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+ 
+ 		dev_net_set(ndev, wiphy_net(local->hw.wiphy));
+ 
+-		ndev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
++		ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
++		if (!ndev->tstats) {
++			free_netdev(ndev);
++			return -ENOMEM;
++		}
+ 
+ 		ndev->needed_headroom = local->tx_headroom +
+ 					4*6 /* four MAC addresses */
+@@ -2103,6 +2109,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+ 
+ 		ret = dev_alloc_name(ndev, ndev->name);
+ 		if (ret < 0) {
++			ieee80211_if_free(ndev);
+ 			free_netdev(ndev);
+ 			return ret;
+ 		}
+diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
+index dc498cd..78ffd3b 100644
+--- a/net/mac80211/trace.h
++++ b/net/mac80211/trace.h
+@@ -33,7 +33,7 @@
+ 			__string(vif_name, sdata->name)
+ #define VIF_ASSIGN	__entry->vif_type = sdata->vif.type; __entry->sdata = sdata;	\
+ 			__entry->p2p = sdata->vif.p2p;					\
+-			__assign_str(vif_name)
++			__assign_str(vif_name, sdata->name)
+ #define VIF_PR_FMT	" vif:%s(%d%s)"
+ #define VIF_PR_ARG	__get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
+ 
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 6f7273a..6489fe9 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -285,6 +285,7 @@ static int validate_ie_attr(const struct nlattr *attr,
+ 	return -EINVAL;
+ }
+ 
++#if LINUX_VERSION_IS_GEQ(5,10,0)
+ static int validate_he_capa(const struct nlattr *attr,
+ 			    struct netlink_ext_ack *extack)
+ {
+@@ -293,6 +294,7 @@ static int validate_he_capa(const struct nlattr *attr,
+ 
+ 	return 0;
+ }
++#endif
+ 
+ /* policy for the attributes */
+ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
+@@ -465,6 +467,7 @@ nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
+ 	[NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
+ };
+ 
++#if LINUX_VERSION_IS_GEQ(5,8,0)
+ static const struct netlink_range_validation nl80211_punct_bitmap_range = {
+ 	.min = 0,
+ 	.max = 0xffff,
+@@ -473,6 +476,7 @@ static const struct netlink_range_validation nl80211_punct_bitmap_range = {
+ static const struct netlink_range_validation q_range = {
+ 	.max = INT_MAX,
+ };
++#endif
+ 
+ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
+@@ -772,10 +776,19 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 
+ 	[NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
+ 	[NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
++#if LINUX_VERSION_IS_GEQ(5,8,0)
+ 	[NL80211_ATTR_TXQ_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &q_range),
++#else
++	[NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
++#endif
++#if LINUX_VERSION_IS_GEQ(5,10,0)
+ 	[NL80211_ATTR_HE_CAPABILITY] =
+ 		NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_he_capa,
+ 				       NL80211_HE_MAX_CAPABILITY_LEN),
++#else
++	[NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
++					 .len = NL80211_HE_MAX_CAPABILITY_LEN },
++#endif
+ 	[NL80211_ATTR_FTM_RESPONDER] =
+ 		NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
+ 	[NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
+@@ -821,8 +834,12 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED },
+ 	[NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_AP_SETTINGS_FLAGS] = { .type = NLA_U32 },
++#if LINUX_VERSION_IS_GEQ(5,10,0)
+ 	[NL80211_ATTR_EHT_CAPABILITY] =
+ 		NLA_POLICY_BINARY_RANGE(NL80211_EHT_MIN_CAPABILITY_LEN, NL80211_EHT_MAX_CAPABILITY_LEN),
++#else
++	[NL80211_ATTR_EHT_CAPABILITY] = { .type = NLA_BINARY, .len = NL80211_EHT_MAX_CAPABILITY_LEN },
++#endif
+ 		[NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG },
+ 		[NL80211_ATTR_MLO_LINKS] =
+ 		NLA_POLICY_NESTED_ARRAY(nl80211_policy),
+@@ -832,8 +849,11 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
+ 	[NL80211_ATTR_PUNCT_BITMAP] =
++#if LINUX_VERSION_IS_GEQ(5,8,0)
+ 		NLA_POLICY_FULL_RANGE(NLA_U32, &nl80211_punct_bitmap_range),
+-
++#else
++		{ .type = NLA_U32 },
++#endif
+ 	[NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 },
+ 	[NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index e52164d..6f2e9a5 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -446,7 +446,7 @@ TRACE_EVENT(rdev_add_virtual_intf,
+ 	),
+ 	TP_fast_assign(
+ 		WIPHY_ASSIGN;
+-		__assign_str(vir_intf_name);
++		__assign_str(vir_intf_name, name ? name : "<noname>");
+ 		__entry->type = type;
+ 	),
+ 	TP_printk(WIPHY_PR_FMT ", virtual intf name: %s, type: %d",
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0009-bp-Revert-wifi-mac80211-move-radar-detect-work-to-sd.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0009-bp-Revert-wifi-mac80211-move-radar-detect-work-to-sd.patch
new file mode 100644
index 0000000..201e792
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0009-bp-Revert-wifi-mac80211-move-radar-detect-work-to-sd.patch
@@ -0,0 +1,158 @@
+From 52b5f8547ca2c00bc4c491901d56340205a241ac Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Thu, 11 Jul 2024 09:21:40 +0530
+Subject: [PATCH 09/89] bp: Revert "wifi: mac80211: move radar detect work to
+ sdata"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This reverts commit ce9e660ef32e ("wifi: mac80211: move radar detect work to sdata").
+
+To enable radar detection with MLO, it’s essential to handle it on a
+per-link basis. This is because when using MLO, multiple links may already
+be active and beaconing. In this scenario, another link should be able to
+initiate a radar detection. Also, if underlying links are associated with
+different hardware devices but grouped together for MLO, they could
+potentially start radar detection simultaneously. Therefore, it makes
+sense to manage radar detection settings separately for each link by moving
+them back to a per-link data structure.
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+---
+ net/mac80211/cfg.c         | 6 +++---
+ net/mac80211/ieee80211_i.h | 3 +--
+ net/mac80211/iface.c       | 4 +---
+ net/mac80211/link.c        | 2 ++
+ net/mac80211/mlme.c        | 9 +++++----
+ net/mac80211/util.c        | 2 +-
+ 6 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 1bf8626..18b9f7c 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1658,7 +1658,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
+ 
+ 	if (sdata->wdev.cac_started) {
+ 		chandef = link_conf->chanreq.oper;
+-		wiphy_delayed_work_cancel(wiphy, &sdata->dfs_cac_timer_work);
++		wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_ABORTED,
+ 				   GFP_KERNEL);
+@@ -3478,7 +3478,7 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
+ 	if (err)
+ 		goto out_unlock;
+ 
+-	wiphy_delayed_work_queue(wiphy, &sdata->dfs_cac_timer_work,
++	wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
+ 				 msecs_to_jiffies(cac_time_ms));
+ 
+  out_unlock:
+@@ -3495,7 +3495,7 @@ static void ieee80211_end_cac(struct wiphy *wiphy,
+ 
+ 	list_for_each_entry(sdata, &local->interfaces, list) {
+ 		wiphy_delayed_work_cancel(wiphy,
+-					  &sdata->dfs_cac_timer_work);
++					  &sdata->deflink.dfs_cac_timer_work);
+ 
+ 		if (sdata->wdev.cac_started) {
+ 			ieee80211_link_release_channel(&sdata->deflink);
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index c9d6743..f7c9892 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1073,6 +1073,7 @@ struct ieee80211_link_data {
+ 	int ap_power_level; /* in dBm */
+ 
+ 	bool radar_required;
++	struct wiphy_delayed_work dfs_cac_timer_work;
+ 
+ 	union {
+ 		struct ieee80211_link_data_managed mgd;
+@@ -1171,8 +1172,6 @@ struct ieee80211_sub_if_data {
+ 	struct ieee80211_link_data deflink;
+ 	struct ieee80211_link_data __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
+ 
+-	struct wiphy_delayed_work dfs_cac_timer_work;
+-
+ 	/* for ieee80211_set_active_links_async() */
+ 	struct wiphy_work activate_links_work;
+ 	u16 desired_active_links;
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index b63a3c4..00d75e0 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -550,7 +550,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ 	wiphy_work_cancel(local->hw.wiphy,
+ 			  &sdata->deflink.color_change_finalize_work);
+ 	wiphy_delayed_work_cancel(local->hw.wiphy,
+-				  &sdata->dfs_cac_timer_work);
++				  &sdata->deflink.dfs_cac_timer_work);
+ 
+ 	if (sdata->wdev.cac_started) {
+ 		chandef = sdata->vif.bss_conf.chanreq.oper;
+@@ -1735,8 +1735,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
+ 	wiphy_work_init(&sdata->work, ieee80211_iface_work);
+ 	wiphy_work_init(&sdata->activate_links_work,
+ 			ieee80211_activate_links_work);
+-	wiphy_delayed_work_init(&sdata->dfs_cac_timer_work,
+-				ieee80211_dfs_cac_timer_work);
+ 
+ 	switch (type) {
+ 	case NL80211_IFTYPE_P2P_GO:
+diff --git a/net/mac80211/link.c b/net/mac80211/link.c
+index 1a211b8..b437896 100644
+--- a/net/mac80211/link.c
++++ b/net/mac80211/link.c
+@@ -45,6 +45,8 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
+ 			  ieee80211_color_collision_detection_work);
+ 	INIT_LIST_HEAD(&link->assigned_chanctx_list);
+ 	INIT_LIST_HEAD(&link->reserved_chanctx_list);
++	wiphy_delayed_work_init(&link->dfs_cac_timer_work,
++				ieee80211_dfs_cac_timer_work);
+ 
+ 	if (!deflink) {
+ 		switch (sdata->vif.type) {
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 4779a18..5b83e7b 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3031,15 +3031,16 @@ void ieee80211_dynamic_ps_timer(struct timer_list *t)
+ 
+ void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work)
+ {
+-	struct ieee80211_sub_if_data *sdata =
+-		container_of(work, struct ieee80211_sub_if_data,
++	struct ieee80211_link_data *link =
++		container_of(work, struct ieee80211_link_data,
+ 			     dfs_cac_timer_work.work);
+-	struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chanreq.oper;
++	struct cfg80211_chan_def chandef = link->conf->chanreq.oper;
++	struct ieee80211_sub_if_data *sdata = link->sdata;
+ 
+ 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
+ 
+ 	if (sdata->wdev.cac_started) {
+-		ieee80211_link_release_channel(&sdata->deflink);
++		ieee80211_link_release_channel(link);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_FINISHED,
+ 				   GFP_KERNEL);
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index ced19ce..77d1e44 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3460,7 +3460,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
+ 
+ 	list_for_each_entry(sdata, &local->interfaces, list) {
+ 		wiphy_delayed_work_cancel(local->hw.wiphy,
+-					  &sdata->dfs_cac_timer_work);
++					  &sdata->deflink.dfs_cac_timer_work);
+ 
+ 		if (sdata->wdev.cac_started) {
+ 			chandef = sdata->vif.bss_conf.chanreq.oper;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0010-bp-wifi-mac80211-remove-label-usage-in-ieee80211_sta.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0010-bp-wifi-mac80211-remove-label-usage-in-ieee80211_sta.patch
new file mode 100644
index 0000000..c2405f1
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0010-bp-wifi-mac80211-remove-label-usage-in-ieee80211_sta.patch
@@ -0,0 +1,56 @@
+From f7ecd5b188e49fd8edb08b2d5d14f98ccfa0a9b5 Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Thu, 11 Jul 2024 09:21:41 +0530
+Subject: [PATCH 10/89] bp: wifi: mac80211: remove label usage in
+ ieee80211_start_radar_detection()
+
+After locks rework [1], ieee80211_start_radar_detection() function is no
+longer acquiring any lock as such explicitly. Hence, it is not unlocking
+anything as well. However, label "out_unlock" is still used which creates
+confusion. Also, now there is no need of goto label as such.
+
+Get rid of the goto logic and use direct return statements.
+
+[1]: https://lore.kernel.org/all/20230828135928.b1c6efffe9ad.I4aec875e25abc9ef0b5ad1e70b5747fd483fbd3c@changeid/
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+---
+ net/mac80211/cfg.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 18b9f7c..ec47ab1 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3464,10 +3464,8 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 
+-	if (!list_empty(&local->roc_list) || local->scanning) {
+-		err = -EBUSY;
+-		goto out_unlock;
+-	}
++	if (!list_empty(&local->roc_list) || local->scanning)
++		return -EBUSY;
+ 
+ 	/* whatever, but channel contexts should not complain about that one */
+ 	sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
+@@ -3476,13 +3474,12 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
+ 	err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
+ 					 IEEE80211_CHANCTX_SHARED);
+ 	if (err)
+-		goto out_unlock;
++		return err;
+ 
+ 	wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
+ 				 msecs_to_jiffies(cac_time_ms));
+ 
+- out_unlock:
+-	return err;
++	return 0;
+ }
+ 
+ static void ieee80211_end_cac(struct wiphy *wiphy,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0011-bp-wifi-trace-unlink-rdev_end_cac-trace-event-from-w.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0011-bp-wifi-trace-unlink-rdev_end_cac-trace-event-from-w.patch
new file mode 100644
index 0000000..d77e086
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0011-bp-wifi-trace-unlink-rdev_end_cac-trace-event-from-w.patch
@@ -0,0 +1,48 @@
+From 0ad2cafa823d9ebff0ef978ec37d3142c3d42a9f Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Thu, 11 Jul 2024 09:21:42 +0530
+Subject: [PATCH 11/89] bp: wifi: trace: unlink rdev_end_cac trace event from
+ wiphy_netdev_evt class
+
+rdev_end_cac trace event is linked with wiphy_netdev_evt event class.
+There is no option to pass link ID currently to wiphy_netdev_evt class.
+A subsequent change would pass link ID to rdev_end_cac event and hence
+it can no longer derive the event class from wiphy_netdev_evt.
+
+Therefore, unlink rdev_end_cac event from wiphy_netdev_evt and define it's
+own independent trace event. Link ID would be passed in subsequent change.
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+---
+ net/wireless/trace.h | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index 6f2e9a5..881c01d 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -805,9 +805,18 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa,
+ 	TP_ARGS(wiphy, netdev)
+ );
+ 
+-DEFINE_EVENT(wiphy_netdev_evt, rdev_end_cac,
+-	     TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
+-	     TP_ARGS(wiphy, netdev)
++TRACE_EVENT(rdev_end_cac,
++	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
++	TP_ARGS(wiphy, netdev),
++	TP_STRUCT__entry(
++		WIPHY_ENTRY
++		NETDEV_ENTRY
++	),
++	TP_fast_assign(
++		WIPHY_ASSIGN;
++		NETDEV_ASSIGN;
++	),
++	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
+ );
+ 
+ DECLARE_EVENT_CLASS(station_add_change,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0012-bp-wifi-cfg80211-move-DFS-related-members-to-links-i.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0012-bp-wifi-cfg80211-move-DFS-related-members-to-links-i.patch
new file mode 100644
index 0000000..c9f99a3
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0012-bp-wifi-cfg80211-move-DFS-related-members-to-links-i.patch
@@ -0,0 +1,354 @@
+From 47d4c2ad004b10dff89ff8c5a506df3d78a042f5 Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Thu, 11 Jul 2024 09:21:43 +0530
+Subject: [PATCH 12/89] bp: wifi: cfg80211: move DFS related members to links[]
+ in wireless_dev
+
+A few members related to DFS handling are currently under per wireless
+device data structure. However, in order to support DFS with MLO, there is
+a need to have them on a per-link manner.
+
+Hence, as a preliminary step, move members cac_started, cac_start_time
+and cac_time_ms to be on a per-link basis.
+
+Since currently, link ID is not known at all places, use default value of
+0 for now.
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+---
+ drivers/net/wireless/marvell/mwifiex/11h.c      |  4 ++--
+ drivers/net/wireless/marvell/mwifiex/cfg80211.c |  4 ++--
+ drivers/net/wireless/quantenna/qtnfmac/event.c  |  6 +++---
+ include/net/cfg80211.h                          | 17 +++++++++--------
+ net/mac80211/cfg.c                              |  8 ++++----
+ net/mac80211/iface.c                            |  2 +-
+ net/mac80211/mlme.c                             |  2 +-
+ net/mac80211/scan.c                             |  2 +-
+ net/mac80211/util.c                             |  2 +-
+ net/wireless/ibss.c                             |  2 +-
+ net/wireless/mesh.c                             |  2 +-
+ net/wireless/mlme.c                             | 11 ++++++-----
+ net/wireless/nl80211.c                          | 10 +++++-----
+ net/wireless/reg.c                              |  2 +-
+ 14 files changed, 38 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c
+index b90f922..fb2cad0 100644
+--- a/drivers/net/wireless/marvell/mwifiex/11h.c
++++ b/drivers/net/wireless/marvell/mwifiex/11h.c
+@@ -117,7 +117,7 @@ void mwifiex_dfs_cac_work_queue(struct work_struct *work)
+ 				     dfs_cac_work);
+ 
+ 	chandef = priv->dfs_chandef;
+-	if (priv->wdev.cac_started) {
++	if (priv->wdev.links[0].cac_started) {
+ 		mwifiex_dbg(priv->adapter, MSG,
+ 			    "CAC timer finished; No radar detected\n");
+ 		cfg80211_cac_event(priv->netdev, &chandef,
+@@ -174,7 +174,7 @@ int mwifiex_stop_radar_detection(struct mwifiex_private *priv,
+  */
+ void mwifiex_abort_cac(struct mwifiex_private *priv)
+ {
+-	if (priv->wdev.cac_started) {
++	if (priv->wdev.links[0].cac_started) {
+ 		if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
+ 			mwifiex_dbg(priv->adapter, ERROR,
+ 				    "failed to stop CAC in FW\n");
+diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+index 7a744ce..436d391 100644
+--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+@@ -1880,7 +1880,7 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
+ 	struct mwifiex_sta_node *sta_node;
+ 	u8 deauth_mac[ETH_ALEN];
+ 
+-	if (!priv->bss_started && priv->wdev.cac_started) {
++	if (!priv->bss_started && priv->wdev.links[0].cac_started) {
+ 		mwifiex_dbg(priv->adapter, INFO, "%s: abort CAC!\n", __func__);
+ 		mwifiex_abort_cac(priv);
+ 	}
+@@ -3978,7 +3978,7 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ 		return -EBUSY;
+ 	}
+ 
+-	if (priv->wdev.cac_started)
++	if (priv->wdev.links[0].cac_started)
+ 		return -EBUSY;
+ 
+ 	if (cfg80211_chandef_identical(&params->chandef,
+diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
+index 76b07db..8bd1e14 100644
+--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
+@@ -520,21 +520,21 @@ static int qtnf_event_handle_radar(struct qtnf_vif *vif,
+ 		cfg80211_radar_event(wiphy, &chandef, GFP_KERNEL);
+ 		break;
+ 	case QLINK_RADAR_CAC_FINISHED:
+-		if (!vif->wdev.cac_started)
++		if (!vif->wdev.links[0].cac_started)
+ 			break;
+ 
+ 		cfg80211_cac_event(vif->netdev, &chandef,
+ 				   NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
+ 		break;
+ 	case QLINK_RADAR_CAC_ABORTED:
+-		if (!vif->wdev.cac_started)
++		if (!vif->wdev.links[0].cac_started)
+ 			break;
+ 
+ 		cfg80211_cac_event(vif->netdev, &chandef,
+ 				   NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
+ 		break;
+ 	case QLINK_RADAR_CAC_STARTED:
+-		if (vif->wdev.cac_started)
++		if (vif->wdev.links[0].cac_started)
+ 			break;
+ 
+ 		if (!wiphy_ext_feature_isset(wiphy,
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 850861b..86634cc 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6206,9 +6206,6 @@ enum ieee80211_ap_reg_power {
+  * @address: The address for this device, valid only if @netdev is %NULL
+  * @is_running: true if this is a non-netdev device that has been started, e.g.
+  *	the P2P Device.
+- * @cac_started: true if DFS channel availability check has been started
+- * @cac_start_time: timestamp (jiffies) when the dfs state was entered.
+- * @cac_time_ms: CAC time in ms
+  * @ps: powersave mode is enabled
+  * @ps_timeout: dynamic powersave timeout
+  * @ap_unexpected_nlportid: (private) netlink port ID of application
+@@ -6232,6 +6229,11 @@ enum ieee80211_ap_reg_power {
+  *	unprotected beacon report
+  * @links: array of %IEEE80211_MLD_MAX_NUM_LINKS elements containing @addr
+  *	@ap and @client for each link
++ * @links[].cac_started: true if DFS channel availability check has been
++ *	started
++ * @links[].cac_start_time: timestamp (jiffies) when the dfs state was
++ *	entered.
++ * @links[].cac_time_ms: CAC time in ms
+  * @valid_links: bitmap describing what elements of @links are valid
+  */
+ struct wireless_dev {
+@@ -6273,11 +6275,6 @@ struct wireless_dev {
+ 	u32 owner_nlportid;
+ 	bool nl_owner_dead;
+ 
+-	/* FIXME: need to rework radar detection for MLO */
+-	bool cac_started;
+-	unsigned long cac_start_time;
+-	unsigned int cac_time_ms;
+-
+ #ifdef CPTCFG_CFG80211_WEXT
+ 	/* wext data */
+ 	struct {
+@@ -6344,6 +6341,10 @@ struct wireless_dev {
+ 				struct cfg80211_internal_bss *current_bss;
+ 			} client;
+ 		};
++
++		bool cac_started;
++		unsigned long cac_start_time;
++		unsigned int cac_time_ms;
+ 	} links[IEEE80211_MLD_MAX_NUM_LINKS];
+ 	u16 valid_links;
+ };
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index ec47ab1..4d5eb60 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1656,7 +1656,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
+ 	ieee80211_link_info_change_notify(sdata, link,
+ 					  BSS_CHANGED_BEACON_ENABLED);
+ 
+-	if (sdata->wdev.cac_started) {
++	if (sdata->wdev.links[0].cac_started) {
+ 		chandef = link_conf->chanreq.oper;
+ 		wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+@@ -3494,9 +3494,9 @@ static void ieee80211_end_cac(struct wiphy *wiphy,
+ 		wiphy_delayed_work_cancel(wiphy,
+ 					  &sdata->deflink.dfs_cac_timer_work);
+ 
+-		if (sdata->wdev.cac_started) {
++		if (sdata->wdev.links[0].cac_started) {
+ 			ieee80211_link_release_channel(&sdata->deflink);
+-			sdata->wdev.cac_started = false;
++			sdata->wdev.links[0].cac_started = false;
+ 		}
+ 	}
+ }
+@@ -3951,7 +3951,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ 	if (!list_empty(&local->roc_list) || local->scanning)
+ 		return -EBUSY;
+ 
+-	if (sdata->wdev.cac_started)
++	if (sdata->wdev.links[0].cac_started)
+ 		return -EBUSY;
+ 
+ 	if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 00d75e0..f0d9024 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -552,7 +552,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ 	wiphy_delayed_work_cancel(local->hw.wiphy,
+ 				  &sdata->deflink.dfs_cac_timer_work);
+ 
+-	if (sdata->wdev.cac_started) {
++	if (sdata->wdev.links[0].cac_started) {
+ 		chandef = sdata->vif.bss_conf.chanreq.oper;
+ 		WARN_ON(local->suspended);
+ 		ieee80211_link_release_channel(&sdata->deflink);
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 5b83e7b..2258858 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3039,7 +3039,7 @@ void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work)
+ 
+ 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
+ 
+-	if (sdata->wdev.cac_started) {
++	if (sdata->wdev.links[0].cac_started) {
+ 		ieee80211_link_release_channel(link);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_FINISHED,
+diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
+index b5f2df6..7d8e7af 100644
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -585,7 +585,7 @@ static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata)
+ 		return false;
+ 
+ 	list_for_each_entry(sdata_iter, &local->interfaces, list) {
+-		if (sdata_iter->wdev.cac_started)
++		if (sdata_iter->wdev.links[0].cac_started)
+ 			return false;
+ 	}
+ 
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 77d1e44..424d8d6 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3462,7 +3462,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
+ 		wiphy_delayed_work_cancel(local->hw.wiphy,
+ 					  &sdata->deflink.dfs_cac_timer_work);
+ 
+-		if (sdata->wdev.cac_started) {
++		if (sdata->wdev.links[0].cac_started) {
+ 			chandef = sdata->vif.bss_conf.chanreq.oper;
+ 			ieee80211_link_release_channel(&sdata->deflink);
+ 			cfg80211_cac_event(sdata->dev,
+diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
+index 0651e9b..0fc930a 100644
+--- a/net/wireless/ibss.c
++++ b/net/wireless/ibss.c
+@@ -94,7 +94,7 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+ 
+ 	lockdep_assert_held(&rdev->wiphy.mtx);
+ 
+-	if (wdev->cac_started)
++	if (wdev->links[0].cac_started)
+ 		return -EBUSY;
+ 
+ 	if (wdev->u.ibss.ssid_len)
+diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
+index aaca65b..2c66540 100644
+--- a/net/wireless/mesh.c
++++ b/net/wireless/mesh.c
+@@ -127,7 +127,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
+ 	if (!rdev->ops->join_mesh)
+ 		return -EOPNOTSUPP;
+ 
+-	if (wdev->cac_started)
++	if (wdev->links[0].cac_started)
+ 		return -EBUSY;
+ 
+ 	if (!setup->chandef.chan) {
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index c7e62eb..eda999d 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -1124,13 +1124,14 @@ void cfg80211_cac_event(struct net_device *netdev,
+ 
+ 	trace_cfg80211_cac_event(netdev, event);
+ 
+-	if (WARN_ON(!wdev->cac_started && event != NL80211_RADAR_CAC_STARTED))
++	if (WARN_ON(!wdev->links[0].cac_started &&
++		    event != NL80211_RADAR_CAC_STARTED))
+ 		return;
+ 
+ 	switch (event) {
+ 	case NL80211_RADAR_CAC_FINISHED:
+-		timeout = wdev->cac_start_time +
+-			  msecs_to_jiffies(wdev->cac_time_ms);
++		timeout = wdev->links[0].cac_start_time +
++			  msecs_to_jiffies(wdev->links[0].cac_time_ms);
+ 		WARN_ON(!time_after_eq(jiffies, timeout));
+ 		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
+ 		memcpy(&rdev->cac_done_chandef, chandef,
+@@ -1139,10 +1140,10 @@ void cfg80211_cac_event(struct net_device *netdev,
+ 		cfg80211_sched_dfs_chan_update(rdev);
+ 		fallthrough;
+ 	case NL80211_RADAR_CAC_ABORTED:
+-		wdev->cac_started = false;
++		wdev->links[0].cac_started = false;
+ 		break;
+ 	case NL80211_RADAR_CAC_STARTED:
+-		wdev->cac_started = true;
++		wdev->links[0].cac_started = true;
+ 		break;
+ 	default:
+ 		WARN_ON(1);
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 6489fe9..3e87f5a 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -6099,7 +6099,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
+ 	if (!rdev->ops->start_ap)
+ 		return -EOPNOTSUPP;
+ 
+-	if (wdev->cac_started)
++	if (wdev->links[0].cac_started)
+ 		return -EBUSY;
+ 
+ 	if (wdev->links[link_id].ap.beacon_interval)
+@@ -10154,7 +10154,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 		goto unlock;
+ 	}
+ 
+-	if (cfg80211_beaconing_iface_active(wdev) || wdev->cac_started) {
++	if (cfg80211_beaconing_iface_active(wdev) || wdev->links[0].cac_started) {
+ 		err = -EBUSY;
+ 		goto unlock;
+ 	}
+@@ -10177,9 +10177,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 	err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
+ 	if (!err) {
+ 		wdev->links[0].ap.chandef = chandef;
+-		wdev->cac_started = true;
+-		wdev->cac_start_time = jiffies;
+-		wdev->cac_time_ms = cac_time_ms;
++		wdev->links[0].cac_started = true;
++		wdev->links[0].cac_start_time = jiffies;
++		wdev->links[0].cac_time_ms = cac_time_ms;
+ 	}
+ unlock:
+ 	wiphy_unlock(wiphy);
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 4219dc2..0040862 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -4245,7 +4245,7 @@ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
+ 	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+ 		struct cfg80211_chan_def *chandef;
+ 
+-		if (!wdev->cac_started)
++		if (!wdev->links[0].cac_started)
+ 			continue;
+ 
+ 		/* FIXME: radar detection is tied to link 0 for now */
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0013-bp-wifi-cfg80211-handle-DFS-per-link.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0013-bp-wifi-cfg80211-handle-DFS-per-link.patch
new file mode 100644
index 0000000..0dc5ea2
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0013-bp-wifi-cfg80211-handle-DFS-per-link.patch
@@ -0,0 +1,480 @@
+From f08e9c0b36a76033554c0fc89b6e3cfbf8019d8c Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Thu, 11 Jul 2024 09:21:44 +0530
+Subject: [PATCH 13/89] bp: wifi: cfg80211: handle DFS per link
+
+Currently, during starting a radar detection, no link id information is
+parsed and passed down. In order to support starting radar detection
+during Multi Link Operation, it is required to pass link id as well.
+
+Add changes to first parse and then pass link id in the start radar
+detection path.
+
+Additionally, update notification APIs to allow drivers/mac80211 to
+pass the link ID.
+
+However, everything is handled at link 0 only until all API's are ready to
+handle it per link.
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+---
+ drivers/net/wireless/marvell/mwifiex/11h.c    |  7 +++--
+ .../net/wireless/marvell/mwifiex/cfg80211.c   |  2 +-
+ .../net/wireless/quantenna/qtnfmac/cfg80211.c |  2 +-
+ .../net/wireless/quantenna/qtnfmac/event.c    |  6 ++--
+ include/net/cfg80211.h                        |  8 +++--
+ net/mac80211/cfg.c                            |  6 ++--
+ net/mac80211/iface.c                          |  2 +-
+ net/mac80211/mlme.c                           |  2 +-
+ net/mac80211/util.c                           |  2 +-
+ net/wireless/mlme.c                           |  9 +++---
+ net/wireless/nl80211.c                        | 24 +++++++++++---
+ net/wireless/rdev-ops.h                       | 13 ++++----
+ net/wireless/reg.c                            | 19 +++++++-----
+ net/wireless/trace.h                          | 31 ++++++++++++-------
+ 14 files changed, 82 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c
+index fb2cad0..032b93a 100644
+--- a/drivers/net/wireless/marvell/mwifiex/11h.c
++++ b/drivers/net/wireless/marvell/mwifiex/11h.c
+@@ -122,7 +122,7 @@ void mwifiex_dfs_cac_work_queue(struct work_struct *work)
+ 			    "CAC timer finished; No radar detected\n");
+ 		cfg80211_cac_event(priv->netdev, &chandef,
+ 				   NL80211_RADAR_CAC_FINISHED,
+-				   GFP_KERNEL);
++				   GFP_KERNEL, 0);
+ 	}
+ }
+ 
+@@ -182,7 +182,8 @@ void mwifiex_abort_cac(struct mwifiex_private *priv)
+ 			    "Aborting delayed work for CAC.\n");
+ 		cancel_delayed_work_sync(&priv->dfs_cac_work);
+ 		cfg80211_cac_event(priv->netdev, &priv->dfs_chandef,
+-				   NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
++				   NL80211_RADAR_CAC_ABORTED, GFP_KERNEL,
++				   0);
+ 	}
+ }
+ 
+@@ -221,7 +222,7 @@ int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv,
+ 				cfg80211_cac_event(priv->netdev,
+ 						   &priv->dfs_chandef,
+ 						   NL80211_RADAR_DETECTED,
+-						   GFP_KERNEL);
++						   GFP_KERNEL, 0);
+ 			}
+ 			break;
+ 		default:
+diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+index 436d391..18fe850 100644
+--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+@@ -4145,7 +4145,7 @@ static int
+ mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
+ 				       struct net_device *dev,
+ 				       struct cfg80211_chan_def *chandef,
+-				       u32 cac_time_ms)
++				       u32 cac_time_ms, int link_id)
+ {
+ 	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ 	struct mwifiex_radar_params radar_params;
+diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+index 663d777..8b97acc 100644
+--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+@@ -837,7 +837,7 @@ static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ static int qtnf_start_radar_detection(struct wiphy *wiphy,
+ 				      struct net_device *ndev,
+ 				      struct cfg80211_chan_def *chandef,
+-				      u32 cac_time_ms)
++				      u32 cac_time_ms, int link_id)
+ {
+ 	struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
+ 	int ret;
+diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
+index 8bd1e14..71840f4 100644
+--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
+@@ -524,14 +524,14 @@ static int qtnf_event_handle_radar(struct qtnf_vif *vif,
+ 			break;
+ 
+ 		cfg80211_cac_event(vif->netdev, &chandef,
+-				   NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
++				   NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
+ 		break;
+ 	case QLINK_RADAR_CAC_ABORTED:
+ 		if (!vif->wdev.links[0].cac_started)
+ 			break;
+ 
+ 		cfg80211_cac_event(vif->netdev, &chandef,
+-				   NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
++				   NL80211_RADAR_CAC_ABORTED, GFP_KERNEL, 0);
+ 		break;
+ 	case QLINK_RADAR_CAC_STARTED:
+ 		if (vif->wdev.links[0].cac_started)
+@@ -542,7 +542,7 @@ static int qtnf_event_handle_radar(struct qtnf_vif *vif,
+ 			break;
+ 
+ 		cfg80211_cac_event(vif->netdev, &chandef,
+-				   NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
++				   NL80211_RADAR_CAC_STARTED, GFP_KERNEL, 0);
+ 		break;
+ 	default:
+ 		pr_warn("%s: unhandled radar event %u\n",
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 86634cc..906e48b 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4846,9 +4846,9 @@ struct cfg80211_ops {
+ 	int	(*start_radar_detection)(struct wiphy *wiphy,
+ 					 struct net_device *dev,
+ 					 struct cfg80211_chan_def *chandef,
+-					 u32 cac_time_ms);
++					 u32 cac_time_ms, int link_id);
+ 	void	(*end_cac)(struct wiphy *wiphy,
+-				struct net_device *dev);
++			   struct net_device *dev, unsigned int link_id);
+ 	int	(*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
+ 				 struct cfg80211_update_ft_ies_params *ftie);
+ 	int	(*crit_proto_start)(struct wiphy *wiphy,
+@@ -8762,6 +8762,7 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
+  * @chandef: chandef for the current channel
+  * @event: type of event
+  * @gfp: context flags
++ * @link_id: valid link_id for MLO operation or 0 otherwise.
+  *
+  * This function is called when a Channel availability check (CAC) is finished
+  * or aborted. This must be called to notify the completion of a CAC process,
+@@ -8769,7 +8770,8 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
+  */
+ void cfg80211_cac_event(struct net_device *netdev,
+ 			const struct cfg80211_chan_def *chandef,
+-			enum nl80211_radar_event event, gfp_t gfp);
++			enum nl80211_radar_event event, gfp_t gfp,
++			unsigned int link_id);
+ 
+ /**
+  * cfg80211_background_cac_abort - Channel Availability Check offchan abort event
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 4d5eb60..cf60420 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1661,7 +1661,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
+ 		wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_ABORTED,
+-				   GFP_KERNEL);
++				   GFP_KERNEL, 0);
+ 	}
+ 
+ 	drv_stop_ap(sdata->local, sdata, link_conf);
+@@ -3455,7 +3455,7 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
+ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
+ 					   struct net_device *dev,
+ 					   struct cfg80211_chan_def *chandef,
+-					   u32 cac_time_ms)
++					   u32 cac_time_ms, int link_id)
+ {
+ 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ 	struct ieee80211_chan_req chanreq = { .oper = *chandef };
+@@ -3483,7 +3483,7 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
+ }
+ 
+ static void ieee80211_end_cac(struct wiphy *wiphy,
+-			      struct net_device *dev)
++			      struct net_device *dev, unsigned int link_id)
+ {
+ 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ 	struct ieee80211_local *local = sdata->local;
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index f0d9024..71e8b0d 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -558,7 +558,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ 		ieee80211_link_release_channel(&sdata->deflink);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_ABORTED,
+-				   GFP_KERNEL);
++				   GFP_KERNEL, 0);
+ 	}
+ 
+ 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 2258858..2c7a3dc 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3043,7 +3043,7 @@ void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work)
+ 		ieee80211_link_release_channel(link);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_FINISHED,
+-				   GFP_KERNEL);
++				   GFP_KERNEL, 0);
+ 	}
+ }
+ 
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 424d8d6..5996ea7 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3468,7 +3468,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
+ 			cfg80211_cac_event(sdata->dev,
+ 					   &chandef,
+ 					   NL80211_RADAR_CAC_ABORTED,
+-					   GFP_KERNEL);
++					   GFP_KERNEL, 0);
+ 		}
+ 	}
+ }
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index eda999d..7d52222 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -1111,18 +1111,19 @@ EXPORT_SYMBOL(__cfg80211_radar_event);
+ 
+ void cfg80211_cac_event(struct net_device *netdev,
+ 			const struct cfg80211_chan_def *chandef,
+-			enum nl80211_radar_event event, gfp_t gfp)
++			enum nl80211_radar_event event, gfp_t gfp,
++			unsigned int link_id)
+ {
+ 	struct wireless_dev *wdev = netdev->ieee80211_ptr;
+ 	struct wiphy *wiphy = wdev->wiphy;
+ 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ 	unsigned long timeout;
+ 
+-	/* not yet supported */
+-	if (wdev->valid_links)
++	if (WARN_ON(wdev->valid_links &&
++		    !(wdev->valid_links & BIT(link_id))))
+ 		return;
+ 
+-	trace_cfg80211_cac_event(netdev, event);
++	trace_cfg80211_cac_event(netdev, event, link_id);
+ 
+ 	if (WARN_ON(!wdev->links[0].cac_started &&
+ 		    event != NL80211_RADAR_CAC_STARTED))
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 3e87f5a..6893256 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -10154,7 +10154,20 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 		goto unlock;
+ 	}
+ 
+-	if (cfg80211_beaconing_iface_active(wdev) || wdev->links[0].cac_started) {
++	if (cfg80211_beaconing_iface_active(wdev)) {
++		/* During MLO other link(s) can beacon, only the current link
++		 * can not already beacon
++		 */
++		if (wdev->valid_links &&
++		    !wdev->links[0].ap.beacon_interval) {
++			/* nothing */
++		} else {
++			err = -EBUSY;
++			goto unlock;
++		}
++	}
++
++	if (wdev->links[0].cac_started) {
+ 		err = -EBUSY;
+ 		goto unlock;
+ 	}
+@@ -10174,7 +10187,8 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 	if (WARN_ON(!cac_time_ms))
+ 		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
+ 
+-	err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
++	err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms,
++					 0);
+ 	if (!err) {
+ 		wdev->links[0].ap.chandef = chandef;
+ 		wdev->links[0].cac_started = true;
+@@ -16531,10 +16545,10 @@ nl80211_set_ttlm(struct sk_buff *skb, struct genl_info *info)
+ 	SELECTOR(__sel, NETDEV_UP_NOTMX,		\
+ 		 NL80211_FLAG_NEED_NETDEV_UP |		\
+ 		 NL80211_FLAG_NO_WIPHY_MTX)		\
+-	SELECTOR(__sel, NETDEV_UP_NOTMX_NOMLO,		\
++	SELECTOR(__sel, NETDEV_UP_NOTMX_MLO,		\
+ 		 NL80211_FLAG_NEED_NETDEV_UP |		\
+ 		 NL80211_FLAG_NO_WIPHY_MTX |		\
+-		 NL80211_FLAG_MLO_UNSUPPORTED)		\
++		 NL80211_FLAG_MLO_VALID_LINK_ID)	\
+ 	SELECTOR(__sel, NETDEV_UP_CLEAR,		\
+ 		 NL80211_FLAG_NEED_NETDEV_UP |		\
+ 		 NL80211_FLAG_CLEAR_SKB)		\
+@@ -17441,7 +17455,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
+ 		.flags = GENL_UNS_ADMIN_PERM,
+ 		.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
+ 					 NL80211_FLAG_NO_WIPHY_MTX |
+-					 NL80211_FLAG_MLO_UNSUPPORTED),
++					 NL80211_FLAG_MLO_VALID_LINK_ID),
+ 	},
+ 	{
+ 		.cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
+diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
+index 951ca95..4e8c895 100644
+--- a/net/wireless/rdev-ops.h
++++ b/net/wireless/rdev-ops.h
+@@ -1200,26 +1200,27 @@ static inline int
+ rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
+ 			   struct net_device *dev,
+ 			   struct cfg80211_chan_def *chandef,
+-			   u32 cac_time_ms)
++			   u32 cac_time_ms, int link_id)
+ {
+ 	int ret = -EOPNOTSUPP;
+ 
+ 	trace_rdev_start_radar_detection(&rdev->wiphy, dev, chandef,
+-					 cac_time_ms);
++					 cac_time_ms, link_id);
+ 	if (rdev->ops->start_radar_detection)
+ 		ret = rdev->ops->start_radar_detection(&rdev->wiphy, dev,
+-						       chandef, cac_time_ms);
++						       chandef, cac_time_ms,
++						       link_id);
+ 	trace_rdev_return_int(&rdev->wiphy, ret);
+ 	return ret;
+ }
+ 
+ static inline void
+ rdev_end_cac(struct cfg80211_registered_device *rdev,
+-	     struct net_device *dev)
++	     struct net_device *dev, unsigned int link_id)
+ {
+-	trace_rdev_end_cac(&rdev->wiphy, dev);
++	trace_rdev_end_cac(&rdev->wiphy, dev, link_id);
+ 	if (rdev->ops->end_cac)
+-		rdev->ops->end_cac(&rdev->wiphy, dev);
++		rdev->ops->end_cac(&rdev->wiphy, dev, link_id);
+ 	trace_rdev_return_void(&rdev->wiphy);
+ }
+ 
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 0040862..1a393f3 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -4233,6 +4233,8 @@ EXPORT_SYMBOL(regulatory_pre_cac_allowed);
+ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
+ {
+ 	struct wireless_dev *wdev;
++	unsigned int link_id;
++
+ 	/* If we finished CAC or received radar, we should end any
+ 	 * CAC running on the same channels.
+ 	 * the check !cfg80211_chandef_dfs_usable contain 2 options:
+@@ -4245,16 +4247,17 @@ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
+ 	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+ 		struct cfg80211_chan_def *chandef;
+ 
+-		if (!wdev->links[0].cac_started)
+-			continue;
++		for_each_valid_link(wdev, link_id) {
++			if (!wdev->links[link_id].cac_started)
++				continue;
+ 
+-		/* FIXME: radar detection is tied to link 0 for now */
+-		chandef = wdev_chandef(wdev, 0);
+-		if (!chandef)
+-			continue;
++			chandef = wdev_chandef(wdev, link_id);
++			if (!chandef)
++				continue;
+ 
+-		if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
+-			rdev_end_cac(rdev, wdev->netdev);
++			if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
++				rdev_end_cac(rdev, wdev->netdev, link_id);
++		}
+ 	}
+ }
+ 
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index 881c01d..a831f94 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -806,17 +806,21 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa,
+ );
+ 
+ TRACE_EVENT(rdev_end_cac,
+-	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
+-	TP_ARGS(wiphy, netdev),
++	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
++		 unsigned int link_id),
++	TP_ARGS(wiphy, netdev, link_id),
+ 	TP_STRUCT__entry(
+ 		WIPHY_ENTRY
+ 		NETDEV_ENTRY
++		__field(unsigned int, link_id)
+ 	),
+ 	TP_fast_assign(
+ 		WIPHY_ASSIGN;
+ 		NETDEV_ASSIGN;
++		__entry->link_id = link_id;
+ 	),
+-	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
++	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d",
++		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id)
+ );
+ 
+ DECLARE_EVENT_CLASS(station_add_change,
+@@ -2661,24 +2665,26 @@ TRACE_EVENT(rdev_external_auth,
+ TRACE_EVENT(rdev_start_radar_detection,
+ 	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ 		 struct cfg80211_chan_def *chandef,
+-		 u32 cac_time_ms),
+-	TP_ARGS(wiphy, netdev, chandef, cac_time_ms),
++		 u32 cac_time_ms, int link_id),
++	TP_ARGS(wiphy, netdev, chandef, cac_time_ms, link_id),
+ 	TP_STRUCT__entry(
+ 		WIPHY_ENTRY
+ 		NETDEV_ENTRY
+ 		CHAN_DEF_ENTRY
+ 		__field(u32, cac_time_ms)
++		__field(int, link_id)
+ 	),
+ 	TP_fast_assign(
+ 		WIPHY_ASSIGN;
+ 		NETDEV_ASSIGN;
+ 		CHAN_DEF_ASSIGN(chandef);
+ 		__entry->cac_time_ms = cac_time_ms;
++		__entry->link_id = link_id;
+ 	),
+ 	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT
+-		  ", cac_time_ms=%u",
++		  ", cac_time_ms=%u, link_id=%d",
+ 		  WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG,
+-		  __entry->cac_time_ms)
++		  __entry->cac_time_ms, __entry->link_id)
+ );
+ 
+ TRACE_EVENT(rdev_set_mcast_rate,
+@@ -3492,18 +3498,21 @@ TRACE_EVENT(cfg80211_radar_event,
+ );
+ 
+ TRACE_EVENT(cfg80211_cac_event,
+-	TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt),
+-	TP_ARGS(netdev, evt),
++	TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt,
++		 unsigned int link_id),
++	TP_ARGS(netdev, evt, link_id),
+ 	TP_STRUCT__entry(
+ 		NETDEV_ENTRY
+ 		__field(enum nl80211_radar_event, evt)
++		__field(unsigned int, link_id)
+ 	),
+ 	TP_fast_assign(
+ 		NETDEV_ASSIGN;
+ 		__entry->evt = evt;
++		__entry->link_id = link_id;
+ 	),
+-	TP_printk(NETDEV_PR_FMT ",  event: %d",
+-		  NETDEV_PR_ARG, __entry->evt)
++	TP_printk(NETDEV_PR_FMT ",  event: %d, link_id=%u",
++		  NETDEV_PR_ARG, __entry->evt, __entry->link_id)
+ );
+ 
+ DECLARE_EVENT_CLASS(cfg80211_rx_evt,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0014-bp-wifi-mac80211-handle-DFS-per-link.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0014-bp-wifi-mac80211-handle-DFS-per-link.patch
new file mode 100644
index 0000000..e11bb25
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0014-bp-wifi-mac80211-handle-DFS-per-link.patch
@@ -0,0 +1,151 @@
+From bd62e65e77de5464c1014610d391699e9d8e1bb6 Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Thu, 11 Jul 2024 09:21:45 +0530
+Subject: [PATCH 14/89] bp: wifi: mac80211: handle DFS per link
+
+In order to support DFS with MLO, handle the link ID now passed from
+cfg80211, adjust the code to do everything per link and call the
+notifications to cfg80211 correctly.
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+---
+ net/mac80211/cfg.c  | 26 ++++++++++++++++++--------
+ net/mac80211/link.c | 10 ++++++++++
+ net/mac80211/util.c | 29 +++++++++++++++++++++++------
+ 3 files changed, 51 insertions(+), 14 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index cf60420..d5ddbce 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3460,6 +3460,7 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
+ 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ 	struct ieee80211_chan_req chanreq = { .oper = *chandef };
+ 	struct ieee80211_local *local = sdata->local;
++	struct ieee80211_link_data *link_data;
+ 	int err;
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+@@ -3467,16 +3468,20 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
+ 	if (!list_empty(&local->roc_list) || local->scanning)
+ 		return -EBUSY;
+ 
++	link_data = sdata_dereference(sdata->link[link_id], sdata);
++	if (!link_data)
++		return -ENOLINK;
++
+ 	/* whatever, but channel contexts should not complain about that one */
+-	sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
+-	sdata->deflink.needed_rx_chains = local->rx_chains;
++	link_data->smps_mode = IEEE80211_SMPS_OFF;
++	link_data->needed_rx_chains = local->rx_chains;
+ 
+-	err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
++	err = ieee80211_link_use_channel(link_data, &chanreq,
+ 					 IEEE80211_CHANCTX_SHARED);
+ 	if (err)
+ 		return err;
+ 
+-	wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
++	wiphy_delayed_work_queue(wiphy, &link_data->dfs_cac_timer_work,
+ 				 msecs_to_jiffies(cac_time_ms));
+ 
+ 	return 0;
+@@ -3487,16 +3492,21 @@ static void ieee80211_end_cac(struct wiphy *wiphy,
+ {
+ 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ 	struct ieee80211_local *local = sdata->local;
++	struct ieee80211_link_data *link_data;
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 
+ 	list_for_each_entry(sdata, &local->interfaces, list) {
++		link_data = sdata_dereference(sdata->link[link_id], sdata);
++		if (!link_data)
++			continue;
++
+ 		wiphy_delayed_work_cancel(wiphy,
+-					  &sdata->deflink.dfs_cac_timer_work);
++					  &link_data->dfs_cac_timer_work);
+ 
+-		if (sdata->wdev.links[0].cac_started) {
+-			ieee80211_link_release_channel(&sdata->deflink);
+-			sdata->wdev.links[0].cac_started = false;
++		if (sdata->wdev.links[link_id].cac_started) {
++			ieee80211_link_release_channel(link_data);
++			sdata->wdev.links[link_id].cac_started = false;
+ 		}
+ 	}
+ }
+diff --git a/net/mac80211/link.c b/net/mac80211/link.c
+index b437896..0bbac64 100644
+--- a/net/mac80211/link.c
++++ b/net/mac80211/link.c
+@@ -77,6 +77,16 @@ void ieee80211_link_stop(struct ieee80211_link_data *link)
+ 			  &link->color_change_finalize_work);
+ 	wiphy_work_cancel(link->sdata->local->hw.wiphy,
+ 			  &link->csa.finalize_work);
++
++	if (link->sdata->wdev.links[link->link_id].cac_started) {
++		wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
++					  &link->dfs_cac_timer_work);
++		cfg80211_cac_event(link->sdata->dev,
++				   &link->conf->chanreq.oper,
++				   NL80211_RADAR_CAC_ABORTED,
++				   GFP_KERNEL, link->link_id);
++	}
++
+ 	ieee80211_link_release_channel(link);
+ }
+ 
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 5996ea7..59dde03 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3455,20 +3455,37 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
+ {
+ 	struct ieee80211_sub_if_data *sdata;
+ 	struct cfg80211_chan_def chandef;
++	struct ieee80211_link_data *link_data;
++	struct ieee80211_bss_conf *link_conf;
++	unsigned int link_id;
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 
+ 	list_for_each_entry(sdata, &local->interfaces, list) {
+-		wiphy_delayed_work_cancel(local->hw.wiphy,
+-					  &sdata->deflink.dfs_cac_timer_work);
++		for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
++		     link_id++) {
++			link_data = sdata_dereference(sdata->link[link_id],
++						      sdata);
++			if (!link_data)
++				continue;
++
++			wiphy_delayed_work_cancel(local->hw.wiphy,
++						  &link_data->dfs_cac_timer_work);
++
++			if (!sdata->wdev.links[link_id].cac_started)
++				continue;
++
++			link_conf =
++				rcu_dereference(sdata->vif.link_conf[link_id]);
++			if (!link_conf)
++				continue;
+ 
+-		if (sdata->wdev.links[0].cac_started) {
+-			chandef = sdata->vif.bss_conf.chanreq.oper;
+-			ieee80211_link_release_channel(&sdata->deflink);
++			chandef = link_conf->chanreq.oper;
++			ieee80211_link_release_channel(link_data);
+ 			cfg80211_cac_event(sdata->dev,
+ 					   &chandef,
+ 					   NL80211_RADAR_CAC_ABORTED,
+-					   GFP_KERNEL, 0);
++					   GFP_KERNEL, link_id);
+ 		}
+ 	}
+ }
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0015-bp-wifi-cfg80211-mac80211-use-proper-link-ID-for-DFS.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0015-bp-wifi-cfg80211-mac80211-use-proper-link-ID-for-DFS.patch
new file mode 100644
index 0000000..27424fd
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0015-bp-wifi-cfg80211-mac80211-use-proper-link-ID-for-DFS.patch
@@ -0,0 +1,182 @@
+From df89e7fc87a11e44e8a074370a22987467c8e973 Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Thu, 11 Jul 2024 09:21:46 +0530
+Subject: [PATCH 15/89] bp: wifi: cfg80211/mac80211: use proper link ID for DFS
+
+Now that all APIs have support to handle DFS per link, use proper link ID
+instead of 0.
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+---
+ net/mac80211/cfg.c     |  6 +++---
+ net/mac80211/mlme.c    |  4 ++--
+ net/mac80211/scan.c    |  6 ++++--
+ net/wireless/mlme.c    | 10 +++++-----
+ net/wireless/nl80211.c | 17 +++++++++--------
+ 5 files changed, 23 insertions(+), 20 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index d5ddbce..a8e7540 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1656,12 +1656,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
+ 	ieee80211_link_info_change_notify(sdata, link,
+ 					  BSS_CHANGED_BEACON_ENABLED);
+ 
+-	if (sdata->wdev.links[0].cac_started) {
++	if (sdata->wdev.links[link_id].cac_started) {
+ 		chandef = link_conf->chanreq.oper;
+ 		wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_ABORTED,
+-				   GFP_KERNEL, 0);
++				   GFP_KERNEL, link_id);
+ 	}
+ 
+ 	drv_stop_ap(sdata->local, sdata, link_conf);
+@@ -3961,7 +3961,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ 	if (!list_empty(&local->roc_list) || local->scanning)
+ 		return -EBUSY;
+ 
+-	if (sdata->wdev.links[0].cac_started)
++	if (sdata->wdev.links[link_id].cac_started)
+ 		return -EBUSY;
+ 
+ 	if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 2c7a3dc..75b9976 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3039,11 +3039,11 @@ void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work)
+ 
+ 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
+ 
+-	if (sdata->wdev.links[0].cac_started) {
++	if (sdata->wdev.links[link->link_id].cac_started) {
+ 		ieee80211_link_release_channel(link);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_FINISHED,
+-				   GFP_KERNEL, 0);
++				   GFP_KERNEL, link->link_id);
+ 	}
+ }
+ 
+diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
+index 7d8e7af..0b8d69f 100644
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -575,6 +575,7 @@ static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata)
+ {
+ 	struct ieee80211_local *local = sdata->local;
+ 	struct ieee80211_sub_if_data *sdata_iter;
++	unsigned int link_id;
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 
+@@ -585,8 +586,9 @@ static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata)
+ 		return false;
+ 
+ 	list_for_each_entry(sdata_iter, &local->interfaces, list) {
+-		if (sdata_iter->wdev.links[0].cac_started)
+-			return false;
++		for_each_valid_link(&sdata_iter->wdev, link_id)
++			if (sdata_iter->wdev.links[link_id].cac_started)
++				return false;
+ 	}
+ 
+ 	return true;
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index 7d52222..5c96273 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -1125,14 +1125,14 @@ void cfg80211_cac_event(struct net_device *netdev,
+ 
+ 	trace_cfg80211_cac_event(netdev, event, link_id);
+ 
+-	if (WARN_ON(!wdev->links[0].cac_started &&
++	if (WARN_ON(!wdev->links[link_id].cac_started &&
+ 		    event != NL80211_RADAR_CAC_STARTED))
+ 		return;
+ 
+ 	switch (event) {
+ 	case NL80211_RADAR_CAC_FINISHED:
+-		timeout = wdev->links[0].cac_start_time +
+-			  msecs_to_jiffies(wdev->links[0].cac_time_ms);
++		timeout = wdev->links[link_id].cac_start_time +
++			  msecs_to_jiffies(wdev->links[link_id].cac_time_ms);
+ 		WARN_ON(!time_after_eq(jiffies, timeout));
+ 		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
+ 		memcpy(&rdev->cac_done_chandef, chandef,
+@@ -1141,10 +1141,10 @@ void cfg80211_cac_event(struct net_device *netdev,
+ 		cfg80211_sched_dfs_chan_update(rdev);
+ 		fallthrough;
+ 	case NL80211_RADAR_CAC_ABORTED:
+-		wdev->links[0].cac_started = false;
++		wdev->links[link_id].cac_started = false;
+ 		break;
+ 	case NL80211_RADAR_CAC_STARTED:
+-		wdev->links[0].cac_started = true;
++		wdev->links[link_id].cac_started = true;
+ 		break;
+ 	default:
+ 		WARN_ON(1);
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 6893256..b0c1a4a 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -6099,7 +6099,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
+ 	if (!rdev->ops->start_ap)
+ 		return -EOPNOTSUPP;
+ 
+-	if (wdev->links[0].cac_started)
++	if (wdev->links[link_id].cac_started)
+ 		return -EBUSY;
+ 
+ 	if (wdev->links[link_id].ap.beacon_interval)
+@@ -10105,6 +10105,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ 	struct net_device *dev = info->user_ptr[1];
+ 	struct wireless_dev *wdev = dev->ieee80211_ptr;
++	int link_id = nl80211_link_id(info->attrs);
+ 	struct wiphy *wiphy = wdev->wiphy;
+ 	struct cfg80211_chan_def chandef;
+ 	enum nl80211_dfs_regions dfs_region;
+@@ -10159,7 +10160,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 		 * can not already beacon
+ 		 */
+ 		if (wdev->valid_links &&
+-		    !wdev->links[0].ap.beacon_interval) {
++		    !wdev->links[link_id].ap.beacon_interval) {
+ 			/* nothing */
+ 		} else {
+ 			err = -EBUSY;
+@@ -10167,7 +10168,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 		}
+ 	}
+ 
+-	if (wdev->links[0].cac_started) {
++	if (wdev->links[link_id].cac_started) {
+ 		err = -EBUSY;
+ 		goto unlock;
+ 	}
+@@ -10188,12 +10189,12 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
+ 
+ 	err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms,
+-					 0);
++					 link_id);
+ 	if (!err) {
+-		wdev->links[0].ap.chandef = chandef;
+-		wdev->links[0].cac_started = true;
+-		wdev->links[0].cac_start_time = jiffies;
+-		wdev->links[0].cac_time_ms = cac_time_ms;
++		wdev->links[link_id].ap.chandef = chandef;
++		wdev->links[link_id].cac_started = true;
++		wdev->links[link_id].cac_start_time = jiffies;
++		wdev->links[link_id].cac_time_ms = cac_time_ms;
+ 	}
+ unlock:
+ 	wiphy_unlock(wiphy);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0016-bp-wifi-mac80211-handle-ieee80211_radar_detected-for.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0016-bp-wifi-mac80211-handle-ieee80211_radar_detected-for.patch
new file mode 100644
index 0000000..16e5390
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0016-bp-wifi-mac80211-handle-ieee80211_radar_detected-for.patch
@@ -0,0 +1,396 @@
+From 758238bd1a839b399d4b1cbf1e8ee8a16729603a Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Thu, 11 Jul 2024 09:21:47 +0530
+Subject: [PATCH 16/89] bp: wifi: mac80211: handle ieee80211_radar_detected()
+ for MLO
+
+Currently DFS works under assumption there could be only one channel
+context in the hardware. Hence, drivers just calls the function
+ieee80211_radar_detected() passing the hardware structure. However, with
+MLO, this obviously will not work since number of channel contexts will be
+more than one and hence drivers would need to pass the channel information
+as well on which the radar is detected.
+
+Hence, in order to support DFS with MLO, do the following changes -
+  * Add channel context conf pointer as an argument to the function
+    ieee80211_radar_detected(). During MLO, drivers would have to pass on
+    which channel context conf radar is detected. Otherwise, drivers could
+    just pass NULL.
+  * ieee80211_radar_detected() will iterate over all channel contexts
+    present and
+  	* if channel context conf is passed, only mark that as radar
+  	  detected
+  	* if NULL is passed, then mark all channel contexts as radar
+  	  detected
+  	* Then as usual, schedule the radar detected work.
+  * In the worker, go over all the contexts again and for all such context
+    which is marked with radar detected, add it to a local linked list.
+  * Cancel the ongoing CAC.
+  * If number of contexts found marked with radar is more than one and if
+    the wiphy does not support MLO flag, throw a warning and return.
+  * Process the local linked list and call the radar event for each entry.
+
+This would also help in scenarios where there is split phy 5 GHz radio,
+which is capable of DFS channels in both lower and upper band. In this
+case, simultaneous radars can be detected.
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+---
+ drivers/net/wireless/ath/ath10k/debug.c       |  4 +-
+ drivers/net/wireless/ath/ath10k/mac.c         |  2 +-
+ drivers/net/wireless/ath/ath10k/wmi.c         |  2 +-
+ drivers/net/wireless/ath/ath11k/wmi.c         |  2 +-
+ drivers/net/wireless/ath/ath12k/wmi.c         |  2 +-
+ drivers/net/wireless/ath/ath9k/dfs.c          |  2 +-
+ drivers/net/wireless/ath/ath9k/dfs_debug.c    |  2 +-
+ .../net/wireless/mediatek/mt76/mt7615/mcu.c   |  2 +-
+ .../net/wireless/mediatek/mt76/mt76x02_dfs.c  |  4 +-
+ .../net/wireless/mediatek/mt76/mt7915/mcu.c   |  2 +-
+ .../net/wireless/mediatek/mt76/mt7996/mcu.c   |  2 +-
+ drivers/net/wireless/ti/wl18xx/event.c        |  2 +-
+ include/net/mac80211.h                        |  7 +-
+ net/mac80211/chan.c                           |  1 +
+ net/mac80211/ieee80211_i.h                    |  5 ++
+ net/mac80211/util.c                           | 71 ++++++++++++++++---
+ 16 files changed, 88 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
+index e577eed..8337ffb 100644
+--- a/drivers/net/wireless/ath/ath10k/debug.c
++++ b/drivers/net/wireless/ath/ath10k/debug.c
+@@ -3,7 +3,7 @@
+  * Copyright (c) 2005-2011 Atheros Communications Inc.
+  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
++ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ 
+ #include <linux/module.h>
+@@ -1774,7 +1774,7 @@ static ssize_t ath10k_write_simulate_radar(struct file *file,
+ 	if (!arvif->is_started)
+ 		return -EINVAL;
+ 
+-	ieee80211_radar_detected(ar->hw);
++	ieee80211_radar_detected(ar->hw, NULL);
+ 
+ 	return count;
+ }
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 9f96315..97bdd1d 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -1472,7 +1472,7 @@ static void ath10k_recalc_radar_detection(struct ath10k *ar)
+ 		 * by indicating that radar was detected.
+ 		 */
+ 		ath10k_warn(ar, "failed to start CAC: %d\n", ret);
+-		ieee80211_radar_detected(ar->hw);
++		ieee80211_radar_detected(ar->hw, NULL);
+ 	}
+ }
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
+index 6a54ba7..b36ced3 100644
+--- a/drivers/net/wireless/ath/ath10k/wmi.c
++++ b/drivers/net/wireless/ath/ath10k/wmi.c
+@@ -3990,7 +3990,7 @@ static void ath10k_radar_detected(struct ath10k *ar)
+ 	if (ar->dfs_block_radar_events)
+ 		ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
+ 	else
+-		ieee80211_radar_detected(ar->hw);
++		ieee80211_radar_detected(ar->hw, NULL);
+ }
+ 
+ static void ath10k_radar_confirmation_work(struct work_struct *work)
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 38f175d..8839825 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -8356,7 +8356,7 @@ ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base *ab, struct sk_buff
+ 	if (ar->dfs_block_radar_events)
+ 		ath11k_info(ab, "DFS Radar detected, but ignored as requested\n");
+ 	else
+-		ieee80211_radar_detected(ar->hw);
++		ieee80211_radar_detected(ar->hw, NULL);
+ 
+ exit:
+ 	rcu_read_unlock();
+diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
+index 9f6be55..350a87a 100644
+--- a/drivers/net/wireless/ath/ath12k/wmi.c
++++ b/drivers/net/wireless/ath/ath12k/wmi.c
+@@ -6788,7 +6788,7 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
+ 	if (ar->dfs_block_radar_events)
+ 		ath12k_info(ab, "DFS Radar detected, but ignored as requested\n");
+ 	else
+-		ieee80211_radar_detected(ath12k_ar_to_hw(ar));
++		ieee80211_radar_detected(ath12k_ar_to_hw(ar), NULL);
+ 
+ exit:
+ 	rcu_read_unlock();
+diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c
+index 1134921..3689e12 100644
+--- a/drivers/net/wireless/ath/ath9k/dfs.c
++++ b/drivers/net/wireless/ath/ath9k/dfs.c
+@@ -280,7 +280,7 @@ ath9k_dfs_process_radar_pulse(struct ath_softc *sc, struct pulse_event *pe)
+ 	if (!pd->add_pulse(pd, pe, NULL))
+ 		return;
+ 	DFS_STAT_INC(sc, radar_detected);
+-	ieee80211_radar_detected(sc->hw);
++	ieee80211_radar_detected(sc->hw, NULL);
+ }
+ 
+ /*
+diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.c b/drivers/net/wireless/ath/ath9k/dfs_debug.c
+index 8e18e9b..426caa0 100644
+--- a/drivers/net/wireless/ath/ath9k/dfs_debug.c
++++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c
+@@ -116,7 +116,7 @@ static ssize_t write_file_simulate_radar(struct file *file,
+ {
+ 	struct ath_softc *sc = file->private_data;
+ 
+-	ieee80211_radar_detected(sc->hw);
++	ieee80211_radar_detected(sc->hw, NULL);
+ 
+ 	return count;
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+index d50d967..53c8ebe 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+@@ -394,7 +394,7 @@ mt7615_mcu_rx_radar_detected(struct mt7615_dev *dev, struct sk_buff *skb)
+ 	if (mt76_phy_dfs_state(mphy) < MT_DFS_STATE_CAC)
+ 		return;
+ 
+-	ieee80211_radar_detected(mphy->hw);
++	ieee80211_radar_detected(mphy->hw, NULL);
+ 	dev->hw_pattern++;
+ }
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
+index 024a5c0..7a07636 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
+@@ -630,7 +630,7 @@ static void mt76x02_dfs_tasklet(struct tasklet_struct *t)
+ 		radar_detected = mt76x02_dfs_check_detection(dev);
+ 		if (radar_detected) {
+ 			/* sw detector rx radar pattern */
+-			ieee80211_radar_detected(dev->mt76.hw);
++			ieee80211_radar_detected(dev->mt76.hw, NULL);
+ 			mt76x02_dfs_detector_reset(dev);
+ 
+ 			return;
+@@ -658,7 +658,7 @@ static void mt76x02_dfs_tasklet(struct tasklet_struct *t)
+ 
+ 		/* hw detector rx radar pattern */
+ 		dfs_pd->stats[i].hw_pattern++;
+-		ieee80211_radar_detected(dev->mt76.hw);
++		ieee80211_radar_detected(dev->mt76.hw, NULL);
+ 		mt76x02_dfs_detector_reset(dev);
+ 
+ 		return;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index bce6cda..590c185 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -293,7 +293,7 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
+ 						&dev->rdd2_chandef,
+ 						GFP_ATOMIC);
+ 	else
+-		ieee80211_radar_detected(mphy->hw);
++		ieee80211_radar_detected(mphy->hw, NULL);
+ 	dev->hw_pattern++;
+ }
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+index 2e4fa9f..f892154 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+@@ -371,7 +371,7 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
+ 						&dev->rdd2_chandef,
+ 						GFP_ATOMIC);
+ 	else
+-		ieee80211_radar_detected(mphy->hw);
++		ieee80211_radar_detected(mphy->hw, NULL);
+ 	dev->hw_pattern++;
+ }
+ 
+diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c
+index 34d95f4..a9f090e 100644
+--- a/drivers/net/wireless/ti/wl18xx/event.c
++++ b/drivers/net/wireless/ti/wl18xx/event.c
+@@ -142,7 +142,7 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
+ 			    wl18xx_radar_type_decode(mbox->radar_type));
+ 
+ 		if (!wl->radar_debug_mode)
+-			ieee80211_radar_detected(wl->hw);
++			ieee80211_radar_detected(wl->hw, NULL);
+ 	}
+ 
+ 	if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index c43d511..1953f91 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -257,6 +257,7 @@ struct ieee80211_chan_req {
+  *	after RTS/CTS handshake to receive SMPS MIMO transmissions;
+  *	this will always be >= @rx_chains_static.
+  * @radar_enabled: whether radar detection is enabled on this channel.
++ * @radar_detected: whether radar got detected on this channel.
+  * @drv_priv: data area for driver use, will always be aligned to
+  *	sizeof(void *), size is determined in hw information.
+  */
+@@ -269,6 +270,7 @@ struct ieee80211_chanctx_conf {
+ 	u8 rx_chains_static, rx_chains_dynamic;
+ 
+ 	bool radar_enabled;
++	bool radar_detected;
+ 
+ 	u8 drv_priv[] __aligned(sizeof(void *));
+ };
+@@ -6724,8 +6726,11 @@ void ieee80211_cqm_beacon_loss_notify(struct ieee80211_vif *vif, gfp_t gfp);
+  * ieee80211_radar_detected - inform that a radar was detected
+  *
+  * @hw: pointer as obtained from ieee80211_alloc_hw()
++ * @chanctx_conf: Channel context on which radar is detected. Mandatory to
++ *	pass a valid pointer during MLO. For non-MLO %NULL can be passed
+  */
+-void ieee80211_radar_detected(struct ieee80211_hw *hw);
++void ieee80211_radar_detected(struct ieee80211_hw *hw,
++			      struct ieee80211_chanctx_conf *chanctx_conf);
+ 
+ /**
+  * ieee80211_chswitch_done - Complete channel switch process
+diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
+index e856772..6041735 100644
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -681,6 +681,7 @@ ieee80211_alloc_chanctx(struct ieee80211_local *local,
+ 	ctx->mode = mode;
+ 	ctx->conf.radar_enabled = false;
+ 	ctx->conf.radio_idx = radio_idx;
++	ctx->conf.radar_detected = false;
+ 	_ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false);
+ 
+ 	return ctx;
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index f7c9892..bea5058 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1335,6 +1335,11 @@ enum mac80211_scan_state {
+ 
+ DECLARE_STATIC_KEY_FALSE(aql_disable);
+ 
++struct radar_info {
++	struct list_head list;
++	struct cfg80211_chan_def chandef;
++};
++
+ struct ieee80211_local {
+ 	/* embed the driver visible part.
+ 	 * don't cast (use the static inlines below), but we keep
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 59dde03..ecda005 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3495,35 +3495,88 @@ void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
+ {
+ 	struct ieee80211_local *local =
+ 		container_of(work, struct ieee80211_local, radar_detected_work);
+-	struct cfg80211_chan_def chandef = local->hw.conf.chandef;
++	struct radar_info *radar_info, *temp;
++	struct list_head radar_info_list;
+ 	struct ieee80211_chanctx *ctx;
++	bool trigger_event = true;
+ 	int num_chanctx = 0;
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 
++	INIT_LIST_HEAD(&radar_info_list);
++
+ 	list_for_each_entry(ctx, &local->chanctx_list, list) {
+ 		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
+ 			continue;
+ 
+-		num_chanctx++;
+-		chandef = ctx->conf.def;
++		if (ctx->conf.radar_detected) {
++			ctx->conf.radar_detected = false;
++			num_chanctx++;
++
++			radar_info = kzalloc(sizeof(*radar_info), GFP_KERNEL);
++			if (WARN_ON(!radar_info))
++				continue;
++
++			INIT_LIST_HEAD(&radar_info->list);
++			radar_info->chandef = ctx->conf.def;
++			list_add_tail(&radar_info->list, &radar_info_list);
++		}
+ 	}
+ 
+ 	ieee80211_dfs_cac_cancel(local);
+ 
+-	if (num_chanctx > 1)
+-		/* XXX: multi-channel is not supported yet */
+-		WARN_ON(1);
+-	else
+-		cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
++	if (num_chanctx > 1) {
++		/* XXX: multi-channel is not supported yet in case of non-MLO */
++		if (WARN_ON(!(wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO)))
++			trigger_event = false;
++	}
++
++	/* this will clear the nodes which were created and added above.
++	 * trigger_event decides whether to trigger the radar event or not
++	 */
++	list_for_each_entry_safe(radar_info, temp, &radar_info_list,
++				 list) {
++		if (trigger_event)
++			cfg80211_radar_event(local->hw.wiphy,
++					     &radar_info->chandef,
++					     GFP_KERNEL);
++		kfree(radar_info);
++	}
+ }
+ 
+-void ieee80211_radar_detected(struct ieee80211_hw *hw)
++static void
++ieee80211_radar_mark_chan_ctx_iterator(struct ieee80211_hw *hw,
++				       struct ieee80211_chanctx_conf *chanctx_conf,
++				       void *data)
++{
++	struct ieee80211_chanctx *ctx =
++		container_of(chanctx_conf, struct ieee80211_chanctx,
++			     conf);
++	struct ieee80211_chanctx_conf *itr_data =
++		(struct ieee80211_chanctx_conf *)data;
++
++	if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
++		return;
++
++	if (itr_data) {
++		if (itr_data == chanctx_conf)
++			chanctx_conf->radar_detected = true;
++		return;
++	}
++
++	chanctx_conf->radar_detected = true;
++}
++
++void ieee80211_radar_detected(struct ieee80211_hw *hw,
++			      struct ieee80211_chanctx_conf *chanctx_conf)
+ {
+ 	struct ieee80211_local *local = hw_to_local(hw);
+ 
+ 	trace_api_radar_detected(local);
+ 
++	ieee80211_iter_chan_contexts_atomic(hw, ieee80211_radar_mark_chan_ctx_iterator,
++					    chanctx_conf);
++
+ 	wiphy_work_queue(hw->wiphy, &local->radar_detected_work);
+ }
+ EXPORT_SYMBOL(ieee80211_radar_detected);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0008-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0017-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch
similarity index 68%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0008-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0017-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch
index b7d52f5..6cced0d 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0008-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0017-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch
@@ -1,7 +1,7 @@
-From ab5065afa6302d7241b2252a6f2ebdba8dc9763b Mon Sep 17 00:00:00 2001
+From 1741b996a7e2470a5b706f14e61f2729cdb02e2c Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Tue, 18 Jan 2022 20:29:44 +0800
-Subject: [PATCH 08/61] mtk: mac80211: do not setup twt when twt responder is
+Subject: [PATCH 17/89] mtk: mac80211: do not setup twt when twt responder is
  false
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 3 insertions(+)
 
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index be724c2..89a1199 100644
+index 956110f..4ca7ae1 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3458,6 +3458,9 @@ ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
+@@ -3461,6 +3461,9 @@ ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
  	if (sdata->vif.type != NL80211_IFTYPE_AP)
  		return false;
  
@@ -23,5 +23,5 @@
  		return false;
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0009-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0018-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch
similarity index 79%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0009-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0018-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch
index d5a498d..af9ca97 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0009-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0018-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch
@@ -1,7 +1,7 @@
-From e27e641fd771a6d882a61a889b9295cdab5dcc72 Mon Sep 17 00:00:00 2001
+From 1711e567e6a8508b831b80d604501260d67ea214 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 29 Mar 2022 16:06:30 +0800
-Subject: [PATCH 09/61] mtk: cfg80211: extend CAC time for weather radar
+Subject: [PATCH 18/89] mtk: cfg80211: extend CAC time for weather radar
  channels
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
@@ -13,10 +13,10 @@
  3 files changed, 11 insertions(+)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 4c5daf9..d987b62 100644
+index 906e48b..c78a4a2 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -163,6 +163,7 @@ enum ieee80211_channel_flags {
+@@ -166,6 +166,7 @@ enum ieee80211_channel_flags {
  	(IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
  
  #define IEEE80211_DFS_MIN_CAC_TIME_MS		60000
@@ -25,10 +25,10 @@
  
  /**
 diff --git a/net/wireless/chan.c b/net/wireless/chan.c
-index 4bac395..2224329 100644
+index edc9034..be2261f 100644
 --- a/net/wireless/chan.c
 +++ b/net/wireless/chan.c
-@@ -1152,6 +1152,13 @@ static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
+@@ -1190,6 +1190,13 @@ static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
  		if (!(c->flags & IEEE80211_CHAN_RADAR))
  			continue;
  
@@ -43,19 +43,19 @@
  			dfs_cac_ms = c->dfs_cac_ms;
  	}
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 3d11013..b8c8848 100644
+index b0c1a4a..93b37dd 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -10019,6 +10019,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+@@ -10188,6 +10188,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
  	if (WARN_ON(!cac_time_ms))
  		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
  
 +	pr_info("%s: region = %u, center freq1 = %u, center freq2 = %u, cac time ms = %u\n",
 +		__func__, dfs_region, chandef.center_freq1, chandef.center_freq2, cac_time_ms);
 +
- 	err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
+ 	err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms,
+ 					 link_id);
  	if (!err) {
- 		wdev->links[0].ap.chandef = chandef;
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0010-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0019-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch
similarity index 71%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0010-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0019-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch
index 1fefb28..97c32d9 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0010-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0019-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch
@@ -1,7 +1,7 @@
-From 639c4598fd67a554c8502d113eb64ef3cf7660d4 Mon Sep 17 00:00:00 2001
+From 31b43a255c2fc56b6cd6d6ccd70a98346d8df78d Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Fri, 1 Apr 2022 09:15:21 +0800
-Subject: [PATCH 10/61] mtk: mac80211: it's invalid case when frag_threshold is
+Subject: [PATCH 19/89] mtk: mac80211: it's invalid case when frag_threshold is
  greater than 2346
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 3 insertions(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index b8c8848..54e19b1 100644
+index 93b37dd..abda8ca 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -3701,6 +3701,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+@@ -3832,6 +3832,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
  			goto out;
  		}
  
@@ -24,5 +24,5 @@
  			/*
  			 * Fragments (apart from the last one) are required to
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0011-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0020-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch
similarity index 93%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0011-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0020-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch
index be103d3..0f137f6 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0011-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0020-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch
@@ -1,7 +1,7 @@
-From 60adbabe8df3bdbab9bd3c2146f19b4c83b69def Mon Sep 17 00:00:00 2001
+From 83c09e9304119117ce7d517de2fa44e2c158b307 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 22 Sep 2022 14:27:41 +0800
-Subject: [PATCH 11/61] mtk: cfg80211: implement DFS status show, cac and nop
+Subject: [PATCH 20/89] mtk: cfg80211: implement DFS status show, cac and nop
  skip command via debugfs
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -20,22 +20,22 @@
  7 files changed, 381 insertions(+), 7 deletions(-)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index d987b62..c55028f 100644
+index c78a4a2..cc1ed48 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -4965,6 +4965,7 @@ struct cfg80211_ops {
- 				    struct cfg80211_set_hw_timestamp *hwts);
+@@ -4956,6 +4956,7 @@ struct cfg80211_ops {
  	int	(*set_ttlm)(struct wiphy *wiphy, struct net_device *dev,
  			    struct cfg80211_ttlm_params *params);
+ 	u32	(*get_radio_mask)(struct wiphy *wiphy, struct net_device *dev);
 +	void	(*skip_cac)(struct wireless_dev *wdev, unsigned int link_id);
  };
  
  /*
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 72e64be..3f4c129 100644
+index a8e7540..42b6d4a 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -5055,6 +5055,30 @@ ieee80211_set_ttlm(struct wiphy *wiphy, struct net_device *dev,
+@@ -5093,6 +5093,30 @@ ieee80211_set_ttlm(struct wiphy *wiphy, struct net_device *dev,
  	return ieee80211_req_neg_ttlm(sdata, params);
  }
  
@@ -66,14 +66,14 @@
  const struct cfg80211_ops mac80211_config_ops = {
  	.add_virtual_intf = ieee80211_add_iface,
  	.del_virtual_intf = ieee80211_del_iface,
-@@ -5168,4 +5192,5 @@ const struct cfg80211_ops mac80211_config_ops = {
- 	.del_link_station = ieee80211_del_link_station,
+@@ -5207,4 +5231,5 @@ const struct cfg80211_ops mac80211_config_ops = {
  	.set_hw_timestamp = ieee80211_set_hw_timestamp,
  	.set_ttlm = ieee80211_set_ttlm,
+ 	.get_radio_mask = ieee80211_get_radio_mask,
 +	.skip_cac = ieee80211_skip_cac,
  };
 diff --git a/net/wireless/core.h b/net/wireless/core.h
-index 7bef6b0..ae6b7fa 100644
+index cebc5a1..d6ed8be 100644
 --- a/net/wireless/core.h
 +++ b/net/wireless/core.h
 @@ -86,6 +86,9 @@ struct cfg80211_registered_device {
@@ -87,7 +87,7 @@
  	struct work_struct background_cac_abort_wk;
  
 diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
-index 7c59a25..a246b2c 100644
+index 40e4907..27b4608 100644
 --- a/net/wireless/debugfs.c
 +++ b/net/wireless/debugfs.c
 @@ -10,6 +10,7 @@
@@ -436,10 +436,10 @@
  
  struct debugfs_read_work {
 diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
-index c7e62eb..d42b65b 100644
+index 5c96273..7a92f87 100644
 --- a/net/wireless/mlme.c
 +++ b/net/wireless/mlme.c
-@@ -1177,13 +1177,16 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
+@@ -1179,13 +1179,16 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
  		queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
  		cfg80211_sched_dfs_chan_update(rdev);
  		wdev = rdev->background_radar_wdev;
@@ -456,7 +456,7 @@
  		break;
  	default:
  		return;
-@@ -1203,6 +1206,7 @@ cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
+@@ -1205,6 +1208,7 @@ cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
  					chandef, event);
  	wiphy_unlock(&rdev->wiphy);
  }
@@ -464,7 +464,7 @@
  
  void cfg80211_background_cac_done_wk(struct work_struct *work)
  {
-@@ -1264,8 +1268,10 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
+@@ -1266,8 +1270,10 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
  	if (!cac_time_ms)
  		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
  
@@ -476,12 +476,12 @@
  	__cfg80211_background_cac_event(rdev, wdev, chandef,
  					NL80211_RADAR_CAC_STARTED);
 diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
-index 466828f..2ae7fc5 100644
+index 4e8c895..e4a77a8 100644
 --- a/net/wireless/rdev-ops.h
 +++ b/net/wireless/rdev-ops.h
-@@ -1542,4 +1542,18 @@ rdev_set_ttlm(struct cfg80211_registered_device *rdev,
+@@ -1545,4 +1545,18 @@ rdev_get_radio_mask(struct cfg80211_registered_device *rdev,
  
- 	return ret;
+ 	return rdev->ops->get_radio_mask(wiphy, dev);
  }
 +
 +static inline int
@@ -499,11 +499,11 @@
 +}
  #endif /* __CFG80211_RDEV_OPS */
 diff --git a/net/wireless/trace.h b/net/wireless/trace.h
-index 7073a70..aa3284f 100644
+index a831f94..21956c8 100644
 --- a/net/wireless/trace.h
 +++ b/net/wireless/trace.h
-@@ -4005,6 +4005,19 @@ TRACE_EVENT(rdev_set_ttlm,
- 		  WIPHY_PR_ARG, NETDEV_PR_ARG)
+@@ -4102,6 +4102,19 @@ TRACE_EVENT(cfg80211_links_removed,
+ 		  __entry->link_mask)
  );
  
 +TRACE_EVENT(rdev_skip_cac,
@@ -523,5 +523,5 @@
  
  #undef TRACE_INCLUDE_PATH
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0012-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0021-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch
similarity index 85%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0012-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0021-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch
index ee54b68..a86472f 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0012-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0021-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch
@@ -1,7 +1,7 @@
-From f3260628a2860a7af6176205fb201ffe7a5334e7 Mon Sep 17 00:00:00 2001
+From 94b249091fc28f486ee9dcf5434169b10cd31ce7 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Tue, 4 Oct 2022 10:47:05 +0800
-Subject: [PATCH 12/61] mtk: mac80211: Set TWT Information Frame Disabled bit
+Subject: [PATCH 21/89] mtk: mac80211: Set TWT Information Frame Disabled bit
  as 1.
 
 This modification means that current implementation do not support twt information frame.
@@ -22,5 +22,5 @@
  	/* broadcast TWT not supported yet */
  	if (twt->control & IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST) {
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0013-mtk-mac80211-check-the-control-channel-before-downgr.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0022-mtk-mac80211-check-the-control-channel-before-downgr.patch
similarity index 78%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0013-mtk-mac80211-check-the-control-channel-before-downgr.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0022-mtk-mac80211-check-the-control-channel-before-downgr.patch
index 6aaf0f5..305cd11 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0013-mtk-mac80211-check-the-control-channel-before-downgr.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0022-mtk-mac80211-check-the-control-channel-before-downgr.patch
@@ -1,7 +1,7 @@
-From 32cfa2d7e115d5cdeeb130fbec61a248e9fe3676 Mon Sep 17 00:00:00 2001
+From 38b24ff76fe1532825f8926057d11b60cb444613 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 16 Dec 2022 03:31:06 +0800
-Subject: [PATCH 13/61] mtk: mac80211: check the control channel before
+Subject: [PATCH 22/89] mtk: mac80211: check the control channel before
  downgrading the bandwidth
 
 ---
@@ -9,11 +9,11 @@
  1 file changed, 23 insertions(+)
 
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index b653c7d..77e5898 100644
+index 75b9976..073e361 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
-@@ -4994,6 +4994,26 @@ ieee80211_determine_our_sta_mode_assoc(struct ieee80211_sub_if_data *sdata,
- 			       conn->bw_limit, tmp.bw_limit);
+@@ -5417,6 +5417,26 @@ ieee80211_ap_power_type(u8 control)
+ 	}
  }
  
 +static bool ieee80211_check_same_ctrl_channel(struct ieee80211_sub_if_data *sdata,
@@ -39,7 +39,7 @@
  static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
  				  struct ieee80211_link_data *link,
  				  int link_id,
-@@ -5073,6 +5093,9 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
+@@ -5493,6 +5513,9 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
  	    chanreq.oper.width == NL80211_CHAN_WIDTH_10)
  		return ret;
  
@@ -50,5 +50,5 @@
  		ieee80211_chanreq_downgrade(&chanreq, conn);
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0014-mtk-mac80211-fix-tx-amsdu-aggregation.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0023-mtk-mac80211-fix-tx-amsdu-aggregation.patch
similarity index 87%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0014-mtk-mac80211-fix-tx-amsdu-aggregation.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0023-mtk-mac80211-fix-tx-amsdu-aggregation.patch
index 8c29c26..aff5ba5 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0014-mtk-mac80211-fix-tx-amsdu-aggregation.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0023-mtk-mac80211-fix-tx-amsdu-aggregation.patch
@@ -1,7 +1,7 @@
-From ead7bd30ec2e85057d69c23429fe7cc2a184e45c Mon Sep 17 00:00:00 2001
+From 19b60e35c6662ae573af038a5fec349366e3269a Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Wed, 14 Dec 2022 00:26:50 -0800
-Subject: [PATCH 14/61] mtk: mac80211: fix tx amsdu aggregation
+Subject: [PATCH 23/89] mtk: mac80211: fix tx amsdu aggregation
 
 ---
  include/net/mac80211.h | 7 +++++++
@@ -9,10 +9,10 @@
  2 files changed, 11 insertions(+), 2 deletions(-)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index c8375b1..8cda233 100644
+index 1953f91..859afcf 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -3043,6 +3043,13 @@ static inline void _ieee80211_hw_set(struct ieee80211_hw *hw,
+@@ -3074,6 +3074,13 @@ static inline void _ieee80211_hw_set(struct ieee80211_hw *hw,
  }
  #define ieee80211_hw_set(hw, flg)	_ieee80211_hw_set(hw, IEEE80211_HW_##flg)
  
@@ -27,7 +27,7 @@
   * struct ieee80211_scan_request - hw scan request
   *
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 21d55dc..068b5b9 100644
+index 677bbba..589494f 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
 @@ -66,7 +66,8 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
@@ -51,5 +51,5 @@
  	capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
  	capab |= u16_encode_bits(agg_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0015-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0024-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch
similarity index 83%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0015-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0024-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch
index 1521470..aa96627 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0015-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0024-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch
@@ -1,7 +1,7 @@
-From 5c16c13e56474ee77a9bd8ea59aeaeaae8923ea8 Mon Sep 17 00:00:00 2001
+From 7e201d350d68f2c0588b8e5f7748e4f733fd8bbc Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Wed, 18 May 2022 15:10:22 +0800
-Subject: [PATCH 15/61] mtk: mac80211: add fill receive path ops to get wed idx
+Subject: [PATCH 24/89] mtk: mac80211: add fill receive path ops to get wed idx
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
@@ -12,10 +12,10 @@
  4 files changed, 50 insertions(+)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 8cda233..01cfcc0 100644
+index 859afcf..5856fc6 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -4390,6 +4390,8 @@ struct ieee80211_prep_tx_info {
+@@ -4420,6 +4420,8 @@ struct ieee80211_prep_tx_info {
   *	resolve a path for hardware flow offloading
   * @can_activate_links: Checks if a specific active_links bitmap is
   *	supported by the driver.
@@ -24,7 +24,7 @@
   * @change_vif_links: Change the valid links on an interface, note that while
   *	removing the old link information is still valid (link_conf pointer),
   *	but may immediately disappear after the function returns. The old or
-@@ -4778,6 +4780,9 @@ struct ieee80211_ops {
+@@ -4808,6 +4810,9 @@ struct ieee80211_ops {
  	bool (*can_activate_links)(struct ieee80211_hw *hw,
  				   struct ieee80211_vif *vif,
  				   u16 active_links);
@@ -35,10 +35,10 @@
  				struct ieee80211_vif *vif,
  				u16 old_links, u16 new_links,
 diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
-index 1eda9ec..9be87b8 100644
+index 9ffbca2..4cddc3c 100644
 --- a/net/mac80211/driver-ops.h
 +++ b/net/mac80211/driver-ops.h
-@@ -1649,6 +1649,19 @@ static inline int drv_net_fill_forward_path(struct ieee80211_local *local,
+@@ -1661,6 +1661,19 @@ static inline int drv_net_fill_forward_path(struct ieee80211_local *local,
  	return ret;
  }
  
@@ -59,10 +59,10 @@
  				   struct ieee80211_sub_if_data *sdata,
  				   struct net_device *dev,
 diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index 6363e8c..0ae31a9 100644
+index 71e8b0d..c454826 100644
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
-@@ -988,6 +988,28 @@ out:
+@@ -931,6 +931,28 @@ out:
  	return ret;
  }
  
@@ -89,18 +89,18 @@
 +}
 +
  static const struct net_device_ops ieee80211_dataif_8023_ops = {
- #if LINUX_VERSION_IS_LESS(4,10,0)
- 	.ndo_change_mtu = __change_mtu,
-@@ -1006,6 +1028,7 @@ static const struct net_device_ops ieee80211_dataif_8023_ops = {
- #endif
- 	
+ 	.ndo_open		= ieee80211_open,
+ 	.ndo_stop		= ieee80211_stop,
+@@ -939,6 +961,7 @@ static const struct net_device_ops ieee80211_dataif_8023_ops = {
+ 	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
+ 	.ndo_set_mac_address	= ieee80211_change_mac,
  	.ndo_fill_forward_path	= ieee80211_netdev_fill_forward_path,
 +	.ndo_fill_receive_path	= ieee80211_netdev_fill_receive_path,
  	.ndo_setup_tc		= ieee80211_netdev_setup_tc,
  };
  
 diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index cda398d..dd06bd2 100644
+index ecda005..1877400 100644
 --- a/net/mac80211/util.c
 +++ b/net/mac80211/util.c
 @@ -874,6 +874,15 @@ struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
@@ -120,5 +120,5 @@
   * Nothing should have been stuffed into the workqueue during
   * the suspend->resume cycle. Since we can't check each caller
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0024-mtk-mac80211-avoid-calling-switch_vif_chanctx-when-u.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0024-mtk-mac80211-avoid-calling-switch_vif_chanctx-when-u.patch
deleted file mode 100644
index 6a68e82..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0024-mtk-mac80211-avoid-calling-switch_vif_chanctx-when-u.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From d9d2bfeed54c0506a2f387354464d3ef474e1777 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Mon, 7 Aug 2023 19:00:53 +0800
-Subject: [PATCH 24/61] mtk: mac80211: avoid calling switch_vif_chanctx when
- use_chanctx is false
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- net/mac80211/chan.c | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
-index 32094ef..8043d1d 100644
---- a/net/mac80211/chan.c
-+++ b/net/mac80211/chan.c
-@@ -1219,13 +1219,15 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
- 	list_del(&link->reserved_chanctx_list);
- 	link->reserved_chanctx = NULL;
- 
--	err = drv_switch_vif_chanctx(local, vif_chsw, 1,
--				     CHANCTX_SWMODE_REASSIGN_VIF);
--	if (err) {
--		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
--			ieee80211_free_chanctx(local, new_ctx, false);
-+	if (!local->emulate_chanctx) {
-+		err = drv_switch_vif_chanctx(local, vif_chsw, 1,
-+					     CHANCTX_SWMODE_REASSIGN_VIF);
-+		if (err) {
-+			if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
-+				ieee80211_free_chanctx(local, new_ctx, false);
- 
--		goto out;
-+			goto out;
-+		}
- 	}
- 
- 	list_move(&link->assigned_chanctx_list, &new_ctx->assigned_links);
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0016-mtk-mac80211-track-obss-color-bitmap.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0025-mtk-mac80211-track-obss-color-bitmap.patch
similarity index 76%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0016-mtk-mac80211-track-obss-color-bitmap.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0025-mtk-mac80211-track-obss-color-bitmap.patch
index 01c513d..09b75e0 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0016-mtk-mac80211-track-obss-color-bitmap.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0025-mtk-mac80211-track-obss-color-bitmap.patch
@@ -1,7 +1,7 @@
-From 71be2e718dc884fb35433338dc21d6547b237819 Mon Sep 17 00:00:00 2001
+From 6361a2d7187f547a498fee824207c27345ec3d99 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Mon, 13 Mar 2023 05:23:37 +0800
-Subject: [PATCH 16/61] mtk: mac80211: track obss color bitmap
+Subject: [PATCH 25/89] mtk: mac80211: track obss color bitmap
 
 Track OBSS BSS color when receive their beacon.
 
@@ -12,14 +12,14 @@
 ---
  include/net/mac80211.h |  1 +
  net/mac80211/rx.c      |  6 +++++-
- net/mac80211/trace.h   | 22 ++++++++++++++++++++++
- 3 files changed, 28 insertions(+), 1 deletion(-)
+ net/mac80211/trace.h   | 21 +++++++++++++++++++++
+ 3 files changed, 27 insertions(+), 1 deletion(-)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 01cfcc0..965a026 100644
+index 5856fc6..6449af9 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -762,6 +762,7 @@ struct ieee80211_bss_conf {
+@@ -803,6 +803,7 @@ struct ieee80211_bss_conf {
  	} he_oper;
  	struct ieee80211_he_obss_pd he_obss_pd;
  	struct cfg80211_he_bss_color he_bss_color;
@@ -28,10 +28,10 @@
  	u32 unsol_bcast_probe_resp_interval;
  	struct cfg80211_bitrate_mask beacon_tx_rate;
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 89a1199..65982a6 100644
+index 4ca7ae1..5c7fc70 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3395,9 +3395,13 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
+@@ -3397,9 +3397,13 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
  
  		color = le32_get_bits(he_oper->he_oper_params,
  				      IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
@@ -41,16 +41,16 @@
 +		// trace_bss_color_bitmap(color, bss_conf->used_color_bitmap);
  		if (color == bss_conf->he_bss_color.color)
  			ieee80211_obss_color_collision_notify(&rx->sdata->vif,
--							      BIT_ULL(color));
-+							      bss_conf->used_color_bitmap);
+-							      BIT_ULL(color),
++							      bss_conf->used_color_bitmap,
+ 							      bss_conf->link_id);
  	}
  }
- 
 diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
-index 8e758b5..9ec45ce 100644
+index 78ffd3b..68f86c3 100644
 --- a/net/mac80211/trace.h
 +++ b/net/mac80211/trace.h
-@@ -3145,6 +3145,28 @@ TRACE_EVENT(drv_neg_ttlm_res,
+@@ -3154,6 +3154,27 @@ TRACE_EVENT(drv_neg_ttlm_res,
  		  LOCAL_PR_ARG, VIF_PR_ARG, __entry->res
  	)
  );
@@ -75,10 +75,9 @@
 +		"color=%u color_bitmap=0x%llx", __entry->color, __entry->color_bitmap
 +	)
 +);
-+
  #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
  
  #undef TRACE_INCLUDE_PATH
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0017-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0026-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch
similarity index 77%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0017-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0026-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch
index b764033..f65257f 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0017-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0026-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch
@@ -1,7 +1,7 @@
-From cd9eddae9afaece218189e1d3ccaffe256b3ccc8 Mon Sep 17 00:00:00 2001
+From 191969896637f094e9da64eccd8d110864891252 Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Fri, 14 Apr 2023 05:05:17 +0800
-Subject: [PATCH 17/61] mtk: mac80211: update max_bssid_indicator based on real
+Subject: [PATCH 26/89] mtk: mac80211: update max_bssid_indicator based on real
  BSS numbers
 
 Fix max_bssid_indicator get empty value due to wrong pointer.
@@ -11,10 +11,10 @@
  1 file changed, 3 insertions(+), 2 deletions(-)
 
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 3f4c129..cb91223 100644
+index 42b6d4a..e119373 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1167,9 +1167,11 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+@@ -1164,9 +1164,11 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
  	/* copy in optional mbssid_ies */
  	if (mbssid) {
  		u8 *pos = new->tail + new->tail_len;
@@ -26,7 +26,7 @@
  		pos += ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies,
  						    mbssid);
  		if (rnr) {
-@@ -1178,8 +1180,7 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+@@ -1175,8 +1177,7 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
  			ieee80211_copy_rnr_beacon(pos, new->rnr_ies, rnr);
  		}
  		/* update bssid_indicator */
@@ -37,5 +37,5 @@
  
  	if (csa) {
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0018-mtk-mac80211-support-configurable-addba-resp-time.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0027-mtk-mac80211-support-configurable-addba-resp-time.patch
similarity index 88%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0018-mtk-mac80211-support-configurable-addba-resp-time.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0027-mtk-mac80211-support-configurable-addba-resp-time.patch
index a4b0d15..b44933d 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0018-mtk-mac80211-support-configurable-addba-resp-time.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0027-mtk-mac80211-support-configurable-addba-resp-time.patch
@@ -1,14 +1,14 @@
-From cc6fe6fd359d941ccd376aa6f185eaeb0020fb04 Mon Sep 17 00:00:00 2001
+From 274b34c23a8f35e3d8260fe88badb10af80be3d4 Mon Sep 17 00:00:00 2001
 From: Lian Chen <lian.chen@mediatek.com>
 Date: Wed, 7 Jun 2023 15:30:34 +0800
-Subject: [PATCH 18/61] mtk: mac80211: support configurable addba resp time.
+Subject: [PATCH 27/89] mtk: mac80211: support configurable addba resp time.
 
 ---
  net/mac80211/agg-tx.c | 8 +++++++-
  1 file changed, 7 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 068b5b9..af3d8e6 100644
+index 589494f..9c640ca 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
 @@ -16,10 +16,16 @@
@@ -38,5 +38,5 @@
  	       sta->sta.addr, tid);
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0019-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0028-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch
similarity index 77%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0019-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0028-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch
index aa94d8f..669ddd0 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0019-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0028-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch
@@ -1,24 +1,30 @@
-From 103b24de6741cb11d088e6e2be478c7839d32ec4 Mon Sep 17 00:00:00 2001
+From 5c4cda67753544ea5bb793d6d36fbbb7330ca0c8 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 14:25:24 +0800
-Subject: [PATCH 19/61] mtk: mac80211: add sta-assisted DFS state update
+Subject: [PATCH 28/89] mtk: mac80211: add sta-assisted DFS state update
  mechanism
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Add cfg80211_any_wiphy_oper_chan check before clearing dfs state.
+This avoids STA clearing the dfs state of the channel, which still has
+APs/offchain operating on the it.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
- include/net/cfg80211.h       | 14 +++++++++
- include/uapi/linux/nl80211.h |  6 ++++
- net/mac80211/mlme.c          | 14 +++++++++
- net/wireless/chan.c          | 61 ++++++++++++++++++++++++++++++++++++
- 4 files changed, 95 insertions(+)
+ include/net/cfg80211.h       | 14 +++++++
+ include/uapi/linux/nl80211.h |  6 +++
+ net/mac80211/mlme.c          | 14 +++++++
+ net/wireless/chan.c          | 72 ++++++++++++++++++++++++++++++++++++
+ 4 files changed, 106 insertions(+)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index c55028f..19cf7f7 100644
+index cc1ed48..16a9a24 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -8679,6 +8679,20 @@ void cfg80211_cac_event(struct net_device *netdev,
- 			const struct cfg80211_chan_def *chandef,
- 			enum nl80211_radar_event event, gfp_t gfp);
+@@ -8775,6 +8775,20 @@ void cfg80211_cac_event(struct net_device *netdev,
+ 			enum nl80211_radar_event event, gfp_t gfp,
+ 			unsigned int link_id);
  
 +/**
 + * cfg80211_sta_update_dfs_state - Update channel's DFS state during STA channel switch,
@@ -38,10 +44,10 @@
   * cfg80211_background_cac_abort - Channel Availability Check offchan abort event
   * @wiphy: the wiphy
 diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
-index f917bc6..7999a65 100644
+index f97f5ad..622fa71 100644
 --- a/include/uapi/linux/nl80211.h
 +++ b/include/uapi/linux/nl80211.h
-@@ -6822,6 +6822,10 @@ enum nl80211_smps_mode {
+@@ -6843,6 +6843,10 @@ enum nl80211_smps_mode {
   *	applicable for ETSI dfs domain where pre-CAC is valid for ever.
   * @NL80211_RADAR_CAC_STARTED: Channel Availability Check has been started,
   *	should be generated by HW if NL80211_EXT_FEATURE_DFS_OFFLOAD is enabled.
@@ -52,7 +58,7 @@
   */
  enum nl80211_radar_event {
  	NL80211_RADAR_DETECTED,
-@@ -6830,6 +6834,8 @@ enum nl80211_radar_event {
+@@ -6851,6 +6855,8 @@ enum nl80211_radar_event {
  	NL80211_RADAR_NOP_FINISHED,
  	NL80211_RADAR_PRE_CAC_EXPIRED,
  	NL80211_RADAR_CAC_STARTED,
@@ -62,12 +68,12 @@
  
  /**
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 77e5898..52d1cd8 100644
+index 073e361..bf8a532 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
-@@ -2170,6 +2170,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
- 		sdata->csa_blocked_tx = true;
- 	}
+@@ -2599,6 +2599,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
+ 	if (csa_ie.mode)
+ 		ieee80211_vif_block_queues_csa(sdata);
  
 +	cfg80211_sta_update_dfs_state(&sdata->wdev,
 +				      &link->conf->chanreq.oper,
@@ -77,7 +83,7 @@
  	cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chanreq.oper,
  					  link->link_id, csa_ie.count,
  					  csa_ie.mode);
-@@ -3245,6 +3250,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
+@@ -3665,6 +3670,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
  		link = sdata_dereference(sdata->link[link_id], sdata);
  		if (!link)
  			continue;
@@ -88,7 +94,7 @@
  		ieee80211_link_release_channel(link);
  	}
  
-@@ -5512,6 +5521,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+@@ -5932,6 +5941,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
  		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
  			if (link->tx_conf[ac].uapsd)
  				resp.uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
@@ -101,7 +107,7 @@
  
  	if (ieee80211_vif_is_mld(&sdata->vif)) {
 diff --git a/net/wireless/chan.c b/net/wireless/chan.c
-index 2224329..c851db8 100644
+index be2261f..7b511d3 100644
 --- a/net/wireless/chan.c
 +++ b/net/wireless/chan.c
 @@ -14,6 +14,7 @@
@@ -112,7 +118,7 @@
  
  static bool cfg80211_valid_60g_freq(u32 freq)
  {
-@@ -1671,6 +1672,66 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
+@@ -1721,6 +1722,77 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
  }
  EXPORT_SYMBOL(cfg80211_any_usable_channels);
  
@@ -140,6 +146,8 @@
 +	enum nl80211_dfs_state dfs_state = NL80211_DFS_USABLE;
 +	enum nl80211_radar_event event = NL80211_RADAR_STA_CAC_EXPIRED;
 +
++	lockdep_assert_wiphy(wdev->wiphy);
++
 +	if (!bss_chandef || !bss_chandef->chan ||
 +	    bss_chandef->chan->band != NL80211_BAND_5GHZ)
 +		return;
@@ -164,6 +172,15 @@
 +		event = NL80211_RADAR_STA_CAC_SKIPPED;
 +	}
 +
++	/* avoid setting the dfs state to usable
++	 * when other interfaces still operate on this channel
++	 */
++	if (dfs_state == NL80211_DFS_USABLE &&
++	    (cfg80211_is_wiphy_oper_chan(wdev->wiphy, bss_chandef->chan) ||
++	     cfg80211_offchan_chain_is_active(wiphy_to_rdev(wdev->wiphy),
++					      bss_chandef->chan)))
++		return;
++
 +	cfg80211_set_dfs_state(wdev->wiphy, bss_chandef, dfs_state);
 +	cfg80211_sta_radar_notify(wdev->wiphy, bss_chandef, event);
 +
@@ -180,5 +197,5 @@
  				       unsigned int link_id)
  {
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0020-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0029-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch
similarity index 76%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0020-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0029-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch
index 1810958..4dd3216 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0020-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0029-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch
@@ -1,17 +1,17 @@
-From 0be90bf2df2df04a24a376f1aab1078874a7d5cc Mon Sep 17 00:00:00 2001
+From 7ae92738c631b522bcca96ed5212fff330ab8381 Mon Sep 17 00:00:00 2001
 From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
 Date: Fri, 17 Mar 2023 17:36:01 +0800
-Subject: [PATCH 20/61] mtk: nl80211: Mark DFS channel as available for CSA.
+Subject: [PATCH 29/89] mtk: nl80211: Mark DFS channel as available for CSA.
 
 ---
  net/wireless/nl80211.c | 5 +++++
  1 file changed, 5 insertions(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 54e19b1..7085133 100644
+index abda8ca..41e9f8d 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -10247,6 +10247,11 @@ skip_beacons:
+@@ -10416,6 +10416,11 @@ skip_beacons:
  	if (err)
  		goto free;
  
@@ -24,5 +24,5 @@
  					   wdev->iftype)) {
  		err = -EINVAL;
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0021-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0030-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch
similarity index 77%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0021-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0030-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch
index acb1a8a..937efeb 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0021-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0030-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch
@@ -1,7 +1,7 @@
-From 5f16034ca52f980a612f1fddb4d730480d12decd Mon Sep 17 00:00:00 2001
+From 1a56eee4f7f5a7f9312219d41ae74d5472b75857 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 27 Jul 2023 10:25:59 +0800
-Subject: [PATCH 21/61] mtk: cfg80211: fix early return in
+Subject: [PATCH 30/89] mtk: cfg80211: fix early return in
  cfg80211_stop_background_radar_detection
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
-index d42b65b..56095b3 100644
+index 7a92f87..3b62f9a 100644
 --- a/net/wireless/mlme.c
 +++ b/net/wireless/mlme.c
-@@ -1292,9 +1292,9 @@ void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
+@@ -1294,9 +1294,9 @@ void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
  		return;
  
  	rdev_set_radar_background(rdev, NULL);
@@ -25,5 +25,5 @@
 +	rdev->background_radar_wdev = NULL; /* Release offchain ownership */
  }
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0022-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0031-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch
similarity index 64%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0022-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0031-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch
index c8c5f69..8470097 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0022-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0031-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch
@@ -1,7 +1,7 @@
-From b4960511afc66cff070b19204da6e8cc54cf9630 Mon Sep 17 00:00:00 2001
+From af06ac5ac954a801dceb279fd42a5e7af88b4222 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 27 Jul 2023 10:27:04 +0800
-Subject: [PATCH 22/61] mtk: cfg80211: add background radar stop when
+Subject: [PATCH 31/89] mtk: cfg80211: add background radar stop when
  background channel is overlapped with operating channel
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,13 +10,13 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 7085133..1f1856b 100644
+index 41e9f8d..6b03037 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -10031,6 +10031,10 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
- 		wdev->cac_started = true;
- 		wdev->cac_start_time = jiffies;
- 		wdev->cac_time_ms = cac_time_ms;
+@@ -10201,6 +10201,10 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ 		wdev->links[link_id].cac_started = true;
+ 		wdev->links[link_id].cac_start_time = jiffies;
+ 		wdev->links[link_id].cac_time_ms = cac_time_ms;
 +		if (rdev->background_cac_started &&
 +		    cfg80211_is_sub_chan(&chandef, rdev->background_radar_chandef.chan, false)) {
 +			cfg80211_stop_background_radar_detection(rdev->background_radar_wdev);
@@ -25,5 +25,5 @@
  unlock:
  	wiphy_unlock(wiphy);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0023-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0032-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch
similarity index 72%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0023-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0032-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch
index 6fdac3c..9eb0d55 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0023-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0032-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch
@@ -1,7 +1,7 @@
-From 9ccc4eaa0168f60bd9f78f4122433ec0528a70cd Mon Sep 17 00:00:00 2001
+From 3bdb886e69a33e97bddd62032390f0bf6c0df24d Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Thu, 3 Aug 2023 07:17:44 +0800
-Subject: [PATCH 23/61] mtk: mac80211: avoid kernel warning of
+Subject: [PATCH 32/89] mtk: mac80211: avoid kernel warning of
  check_flush_dependency
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/net/mac80211/main.c b/net/mac80211/main.c
-index 81a9645..e9d8581 100644
+index 79c77af..ca371ef 100644
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
-@@ -1458,7 +1458,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+@@ -1475,7 +1475,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
  		hw->queues = IEEE80211_MAX_QUEUES;
  
  	local->workqueue =
@@ -22,5 +22,5 @@
  		result = -ENOMEM;
  		goto fail_workqueue;
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0025-mtk-mac80211-add-EHT-BA1024-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0033-mtk-mac80211-add-EHT-BA1024-support.patch
similarity index 90%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0025-mtk-mac80211-add-EHT-BA1024-support.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0033-mtk-mac80211-add-EHT-BA1024-support.patch
index c16cfe8..3194de2 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0025-mtk-mac80211-add-EHT-BA1024-support.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0033-mtk-mac80211-add-EHT-BA1024-support.patch
@@ -1,7 +1,7 @@
-From 61947ae7c04a86c4d6526d080e37e53fe4d17599 Mon Sep 17 00:00:00 2001
+From 64158fc5e1118537334c5fb512f18e7e1e1daa02 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Sun, 25 Dec 2022 22:43:46 +0800
-Subject: [PATCH 25/61] mtk: mac80211: add EHT BA1024 support
+Subject: [PATCH 33/89] mtk: mac80211: add EHT BA1024 support
 
 ---
  include/linux/ieee80211.h |  2 ++
@@ -9,10 +9,10 @@
  2 files changed, 45 insertions(+), 2 deletions(-)
 
 diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
-index 95c39b7..70f0135 100644
+index 30cef3b..3039cb1 100644
 --- a/include/linux/ieee80211.h
 +++ b/include/linux/ieee80211.h
-@@ -1391,6 +1391,8 @@ struct ieee80211_mgmt {
+@@ -1445,6 +1445,8 @@ struct ieee80211_mgmt {
  					__le16 status;
  					__le16 capab;
  					__le16 timeout;
@@ -22,7 +22,7 @@
  				struct{
  					u8 action_code;
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index af3d8e6..5cf478e 100644
+index 9c640ca..de1b2b2 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
 @@ -72,10 +72,17 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
@@ -73,7 +73,7 @@
  	} else {
  		/*
  		 * We really should use what the driver told us it will
-@@ -980,8 +999,10 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
+@@ -982,8 +1001,10 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
  {
  	struct tid_ampdu_tx *tid_tx;
  	struct ieee80211_txq *txq;
@@ -84,7 +84,7 @@
  
  	lockdep_assert_wiphy(sta->local->hw.wiphy);
  
-@@ -989,6 +1010,26 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
+@@ -991,6 +1012,26 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
  	amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK;
  	tid = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_TID_MASK);
  	buf_size = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
@@ -112,5 +112,5 @@
  
  	txq = sta->sta.txq[tid];
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0026-mtk-mac80211-add-rate-duration-for-EHT-rate.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0034-mtk-mac80211-add-rate-duration-for-EHT-rate.patch
similarity index 99%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0026-mtk-mac80211-add-rate-duration-for-EHT-rate.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0034-mtk-mac80211-add-rate-duration-for-EHT-rate.patch
index 91b1b07..99dbb95 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0026-mtk-mac80211-add-rate-duration-for-EHT-rate.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0034-mtk-mac80211-add-rate-duration-for-EHT-rate.patch
@@ -1,7 +1,7 @@
-From f2f18cce7c4d2467312ccebd927308d65d5cc27b Mon Sep 17 00:00:00 2001
+From 4540637b8a7905d67cd86bce3f85a42a79226561 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Sun, 25 Dec 2022 22:43:46 +0800
-Subject: [PATCH 26/61] mtk: mac80211: add rate duration for EHT rate.
+Subject: [PATCH 34/89] mtk: mac80211: add rate duration for EHT rate.
 
 ---
  net/mac80211/airtime.c | 349 ++++++++++++++++++++++++++++++++++++++++-
@@ -436,5 +436,5 @@
  	if (stat->encoding != RX_ENC_LEGACY)
  		return true;
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0027-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0035-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch
similarity index 75%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0027-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0035-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch
index 8de0ea7..83cd829 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0027-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0035-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch
@@ -1,7 +1,7 @@
-From baa27bc8d70bab050630a127c7d58d140ac9ed21 Mon Sep 17 00:00:00 2001
+From b277487ebbe327c928e6ed30733ee5adebf9a7b2 Mon Sep 17 00:00:00 2001
 From: ye he <ye.he@mediatek.com>
 Date: Wed, 22 Feb 2023 16:09:32 +0800
-Subject: [PATCH 27/61] mtk: mac80211: add send bar action when recieve addba
+Subject: [PATCH 35/89] mtk: mac80211: add send bar action when recieve addba
  rsp
 
 Signed-off-by: ye he <ye.he@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 5cf478e..8480b64 100644
+index de1b2b2..0abc77b 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
-@@ -1080,7 +1080,8 @@ next:
+@@ -1082,7 +1082,8 @@ next:
  
  		tid_tx->buf_size = buf_size;
  		tid_tx->amsdu = amsdu;
@@ -24,5 +24,5 @@
  			ieee80211_agg_tx_operational(local, sta, tid);
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0036-backports-update-kernel-version-check-for-eth_hw_add.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0036-backports-update-kernel-version-check-for-eth_hw_add.patch
deleted file mode 100644
index 01f9aaf..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0036-backports-update-kernel-version-check-for-eth_hw_add.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0bf57d6aacff7859372d546ef491f2722098bc0c Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Mon, 27 Nov 2023 16:39:36 +0800
-Subject: [PATCH 36/61] backports: update kernel version check for
- eth_hw_addr_set()
-
-Kernel v5.4.260 has added this API, so update kernel version check in
-backports include.
-
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- backport-include/linux/etherdevice.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/backport-include/linux/etherdevice.h b/backport-include/linux/etherdevice.h
-index 51a7d6d..ecc3bc2 100644
---- a/backport-include/linux/etherdevice.h
-+++ b/backport-include/linux/etherdevice.h
-@@ -39,7 +39,7 @@ static inline void u64_to_ether_addr(u64 u, u8 *addr)
- }
- #endif /* LINUX_VERSION_IS_LESS(4,11,0) */
- 
--#if LINUX_VERSION_IS_LESS(5,15,0)
-+#if LINUX_VERSION_IS_LESS(5,4,260)
- /**
-  * eth_hw_addr_set - Assign Ethernet address to a net_device
-  * @dev: pointer to net_device structure
-@@ -51,7 +51,7 @@ static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr)
- {
- 	ether_addr_copy(dev->dev_addr, addr);
- }
--#endif /* LINUX_VERSION_IS_LESS(5,15,0) */
-+#endif /* LINUX_VERSION_IS_LESS(5,4,260) */
- 
- #if LINUX_VERSION_IS_LESS(5,16,0)
- static inline int backport_device_get_mac_address(struct device *dev, char *addr)
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0028-mtk-mac80211-inrease-beacon-loss-count.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0036-mtk-mac80211-inrease-beacon-loss-count.patch
similarity index 84%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0028-mtk-mac80211-inrease-beacon-loss-count.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0036-mtk-mac80211-inrease-beacon-loss-count.patch
index c6a9e9d..4bee695 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0028-mtk-mac80211-inrease-beacon-loss-count.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0036-mtk-mac80211-inrease-beacon-loss-count.patch
@@ -1,7 +1,7 @@
-From 235df226520ae9c161bed6fe45920331662b26e6 Mon Sep 17 00:00:00 2001
+From 3116b6dcf3eeace943d3775658eb81dca7f6053a Mon Sep 17 00:00:00 2001
 From: Amit Khatri <amit.khatri@mediatek.com>
 Date: Thu, 6 Apr 2023 21:37:33 +0800
-Subject: [PATCH 28/61] mtk: mac80211: inrease beacon loss count
+Subject: [PATCH 36/89] mtk: mac80211: inrease beacon loss count
 
 as per eagle code beacone loss time out is
 4 seconds.
@@ -16,7 +16,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 52d1cd8..a27682e 100644
+index bf8a532..9c83b96 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
 @@ -66,7 +66,7 @@ MODULE_PARM_DESC(max_probe_tries,
@@ -29,5 +29,5 @@
  MODULE_PARM_DESC(beacon_loss_count,
  		 "Number of beacon intervals before we decide beacon was lost.");
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0029-mtk-cfg80211-add-support-for-updating-background-cha.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0037-mtk-cfg80211-add-support-for-updating-background-cha.patch
similarity index 86%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0029-mtk-cfg80211-add-support-for-updating-background-cha.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0037-mtk-cfg80211-add-support-for-updating-background-cha.patch
index ffc8f1c..c94d277 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0029-mtk-cfg80211-add-support-for-updating-background-cha.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0037-mtk-cfg80211-add-support-for-updating-background-cha.patch
@@ -1,7 +1,7 @@
-From e4e9d4cdfc3b5e27a3ad3f05810a96447ccf1f56 Mon Sep 17 00:00:00 2001
+From 00e391d6cfcebf553c4f9378fe56d17b48e7f9b2 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 09:49:02 +0800
-Subject: [PATCH 29/61] mtk: cfg80211: add support for updating background
+Subject: [PATCH 37/89] mtk: cfg80211: add support for updating background
  channel
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -12,10 +12,10 @@
  3 files changed, 32 insertions(+)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 19cf7f7..bd516d1 100644
+index 16a9a24..993b9a1 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -8693,6 +8693,20 @@ void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
+@@ -8789,6 +8789,20 @@ void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
  				   const struct cfg80211_chan_def *csa_chandef,
  				   bool associated);
  
@@ -37,10 +37,10 @@
   * cfg80211_background_cac_abort - Channel Availability Check offchan abort event
   * @wiphy: the wiphy
 diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
-index 7999a65..e859c96 100644
+index 622fa71..d425c79 100644
 --- a/include/uapi/linux/nl80211.h
 +++ b/include/uapi/linux/nl80211.h
-@@ -6822,6 +6822,10 @@ enum nl80211_smps_mode {
+@@ -6843,6 +6843,10 @@ enum nl80211_smps_mode {
   *	applicable for ETSI dfs domain where pre-CAC is valid for ever.
   * @NL80211_RADAR_CAC_STARTED: Channel Availability Check has been started,
   *	should be generated by HW if NL80211_EXT_FEATURE_DFS_OFFLOAD is enabled.
@@ -51,7 +51,7 @@
   * @NL80211_RADAR_STA_CAC_SKIPPED: STA set the DFS state to available
   *	when receiving CSA/assoc resp
   * @NL80211_RADAR_STA_CAC_EXPIRED: STA set the DFS state to usable
-@@ -6834,6 +6838,8 @@ enum nl80211_radar_event {
+@@ -6855,6 +6859,8 @@ enum nl80211_radar_event {
  	NL80211_RADAR_NOP_FINISHED,
  	NL80211_RADAR_PRE_CAC_EXPIRED,
  	NL80211_RADAR_CAC_STARTED,
@@ -61,10 +61,10 @@
  	NL80211_RADAR_STA_CAC_EXPIRED,
  };
 diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
-index 56095b3..3da7886 100644
+index 3b62f9a..cddee2f 100644
 --- a/net/wireless/mlme.c
 +++ b/net/wireless/mlme.c
-@@ -1281,6 +1281,18 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
+@@ -1283,6 +1283,18 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
  	return 0;
  }
  
@@ -84,5 +84,5 @@
  {
  	struct wiphy *wiphy = wdev->wiphy;
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0030-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0038-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch
similarity index 73%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0030-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0038-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch
index ca8cdc0..e8190ba 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0030-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0038-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch
@@ -1,7 +1,7 @@
-From bfe137c0bceae36a34e766d2623893c4b1cbdd53 Mon Sep 17 00:00:00 2001
+From 75f507486da757510fddd49289d783c6529ab9fc Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Fri, 7 Jul 2023 17:17:30 +0800
-Subject: [PATCH 30/61] mtk: mac80211: Allow STA interface to set TX queue
+Subject: [PATCH 38/89] mtk: mac80211: Allow STA interface to set TX queue
  parameters
 
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 1 insertion(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 1f1856b..079fedf 100644
+index 6b03037..d4e7ed8 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -3557,6 +3557,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+@@ -3688,6 +3688,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
  		}
  
  		if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
@@ -22,5 +22,5 @@
  			result = -EINVAL;
  			goto out;
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0031-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0039-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch
similarity index 88%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0031-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0039-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch
index f070841..e9deb46 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0031-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0039-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch
@@ -1,7 +1,7 @@
-From 2a5c863cc42d21d20a25496426696c95cea45312 Mon Sep 17 00:00:00 2001
+From fbc38ce3f33a8171a197d34fc5d6c57c1209c81a Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Fri, 23 Jun 2023 05:53:50 +0800
-Subject: [PATCH 31/61] mtk: mac80211: export ieee80211_tpt_led_trig_tx/rx for
+Subject: [PATCH 39/89] mtk: mac80211: export ieee80211_tpt_led_trig_tx/rx for
  driver
 
 Whenever the H/W path is enabled and traffic is in the binding state,
@@ -22,10 +22,10 @@
  5 files changed, 36 insertions(+), 20 deletions(-)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 965a026..860ad6e 100644
+index 6449af9..215d499 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -4893,6 +4893,8 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw,
+@@ -4923,6 +4923,8 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw,
  				   unsigned int flags,
  				   const struct ieee80211_tpt_blink *blink_table,
  				   unsigned int blink_table_len);
@@ -34,7 +34,7 @@
  #endif
  /**
   * ieee80211_get_tx_led_name - get name of TX LED
-@@ -5003,6 +5005,21 @@ ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags,
+@@ -5033,6 +5035,21 @@ ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags,
  #endif
  }
  
@@ -111,10 +111,10 @@
 -#endif
 -}
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 65982a6..fe3d9fb 100644
+index 5c7fc70..733f365 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -5469,7 +5469,7 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+@@ -5477,7 +5477,7 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
  	if (skb) {
  		if ((status->flag & RX_FLAG_8023) ||
  			ieee80211_is_data_present(hdr->frame_control))
@@ -124,10 +124,10 @@
  		if (status->flag & RX_FLAG_8023)
  			__ieee80211_rx_handle_8023(hw, pubsta, skb, list);
 diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
-index f479d87..344f4bf 100644
+index 65f9c26..02e7ae6 100644
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -4340,7 +4340,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
+@@ -4344,7 +4344,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
  	len = 0;
   out:
  	if (len)
@@ -136,7 +136,7 @@
  	rcu_read_unlock();
  }
  
-@@ -4671,7 +4671,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
+@@ -4675,7 +4675,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
  	sta->deflink.tx_stats.packets[queue] += skbs;
  	sta->deflink.tx_stats.bytes[queue] += len;
  
@@ -146,5 +146,5 @@
  	ieee80211_tx_8023(sdata, skb, sta, false);
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0032-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0040-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch
similarity index 88%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0032-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0040-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch
index d879e5e..b6591a5 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0032-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0040-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch
@@ -1,7 +1,7 @@
-From fc5c4fd0f0edc27c7a21e43a51e1a90a2f7b17b2 Mon Sep 17 00:00:00 2001
+From be1bbf4ad51cf99310f9d17206afd22975d13d2f Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Tue, 22 Aug 2023 05:02:53 +0800
-Subject: [PATCH 32/61] mtk: mac80211: add packet count input for
+Subject: [PATCH 40/89] mtk: mac80211: add packet count input for
  dev_sw_netstat_rx_add
 
 ---
@@ -13,10 +13,10 @@
  5 files changed, 15 insertions(+), 11 deletions(-)
 
 diff --git a/backport-include/linux/netdevice.h b/backport-include/linux/netdevice.h
-index 1d2ac66..04d76d7 100644
+index bd35ec7..e638f31 100644
 --- a/backport-include/linux/netdevice.h
 +++ b/backport-include/linux/netdevice.h
-@@ -112,13 +112,15 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s,
+@@ -46,13 +46,15 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s,
  #define netif_rx_any_context LINUX_BACKPORT(netif_rx_any_context)
  int netif_rx_any_context(struct sk_buff *skb);
  
@@ -34,7 +34,7 @@
  	u64_stats_update_end(&tstats->syncp);
  }
  
-@@ -140,13 +142,15 @@ static inline void dev_sw_netstats_tx_add(struct net_device *dev,
+@@ -74,13 +76,15 @@ static inline void dev_sw_netstats_tx_add(struct net_device *dev,
  
  #if LINUX_VERSION_IS_LESS(5,10,0)
  #define dev_sw_netstats_rx_add LINUX_BACKPORT(dev_sw_netstats_rx_add)
@@ -53,10 +53,10 @@
  }
  #endif /* < 5.10 */
 diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
-index f7f640f..436e37d 100644
+index e656f73..768d9d8 100644
 --- a/drivers/net/usb/qmi_wwan.c
 +++ b/drivers/net/usb/qmi_wwan.c
-@@ -228,7 +228,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+@@ -210,7 +210,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
  			net->stats.rx_errors++;
  			return 0;
  		} else {
@@ -92,7 +92,7 @@
  				netif_receive_skb(skb);
  			} else {
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index fe3d9fb..da3fc51 100644
+index 733f365..334c246 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
 @@ -863,7 +863,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
@@ -113,7 +113,7 @@
  
  	if (rx->sta) {
  		/* The seqno index has the same property as needed
-@@ -4111,7 +4111,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
+@@ -4119,7 +4119,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
  		}
  
  		prev_dev = sdata->dev;
@@ -122,7 +122,7 @@
  	}
  
  	if (prev_dev) {
-@@ -4819,7 +4819,7 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
+@@ -4827,7 +4827,7 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
  
  	skb->dev = fast_rx->dev;
  
@@ -132,5 +132,5 @@
  	/* The seqno index has the same property as needed
  	 * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0033-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0041-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch
similarity index 83%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0033-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0041-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch
index cdc396e..4557a06 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0033-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0041-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch
@@ -1,7 +1,7 @@
-From 4d85822963f5d150be638d78ea84c5199f80d676 Mon Sep 17 00:00:00 2001
+From 9cb21d47008d6fd6f0aee1cef7c5c92a03074f4a Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Wed, 16 Aug 2023 07:23:34 +0800
-Subject: [PATCH 33/61] mtk: mac80211: add per-bss flag to support vendors
+Subject: [PATCH 41/89] mtk: mac80211: add per-bss flag to support vendors
  counter
 
 ---
@@ -11,10 +11,10 @@
  3 files changed, 17 insertions(+), 5 deletions(-)
 
 diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
-index e859c96..220d20d 100644
+index d425c79..257528d 100644
 --- a/include/uapi/linux/nl80211.h
 +++ b/include/uapi/linux/nl80211.h
-@@ -6620,6 +6620,7 @@ enum nl80211_ext_feature_index {
+@@ -6641,6 +6641,7 @@ enum nl80211_ext_feature_index {
  	NL80211_EXT_FEATURE_OWE_OFFLOAD_AP,
  	NL80211_EXT_FEATURE_DFS_CONCURRENT,
  	NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT,
@@ -23,7 +23,7 @@
  	/* add new features before the definition below */
  	NUM_NL80211_EXT_FEATURES,
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index da3fc51..06725f3 100644
+index 334c246..78e9c6e 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
 @@ -2672,7 +2672,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
@@ -37,7 +37,7 @@
  
  	if (rx->sta) {
  		/* The seqno index has the same property as needed
-@@ -4819,7 +4821,9 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
+@@ -4827,7 +4829,9 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
  
  	skb->dev = fast_rx->dev;
  
@@ -49,10 +49,10 @@
  	/* The seqno index has the same property as needed
  	 * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
 diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
-index 344f4bf..a2ed041 100644
+index 02e7ae6..3ac51a2 100644
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -3559,7 +3559,9 @@ ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
+@@ -3562,7 +3562,9 @@ ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
  	if (key)
  		info->control.hw_key = &key->conf;
  
@@ -63,7 +63,7 @@
  
  	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
  		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-@@ -4330,7 +4332,9 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
+@@ -4334,7 +4336,9 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
  			goto out;
  		}
  
@@ -74,7 +74,7 @@
  
  		ieee80211_xmit(sdata, sta, skb);
  	}
-@@ -4667,7 +4671,10 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
+@@ -4671,7 +4675,10 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
  			info->status_data_idr = 1;
  	}
  
@@ -87,5 +87,5 @@
  	sta->deflink.tx_stats.bytes[queue] += len;
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0041-mtk-mac80211-fix-crash-when-starting-tx-ba-session.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0041-mtk-mac80211-fix-crash-when-starting-tx-ba-session.patch
deleted file mode 100644
index aa1b7ae..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0041-mtk-mac80211-fix-crash-when-starting-tx-ba-session.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From c115759fb0b11ba3ce09d078e8609203dc5e772f Mon Sep 17 00:00:00 2001
-From: Bo Jiao <Bo.Jiao@mediatek.com>
-Date: Fri, 10 Nov 2023 15:34:57 +0800
-Subject: [PATCH 41/61] mtk: mac80211: fix crash when starting tx ba session
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
----
- net/mac80211/agg-tx.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 7117576..da9b7f0 100644
---- a/net/mac80211/agg-tx.c
-+++ b/net/mac80211/agg-tx.c
-@@ -642,7 +642,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
- 		 "Requested to start BA session on reserved tid=%d", tid))
- 		return -EINVAL;
- 
--	if (!pubsta->deflink.ht_cap.ht_supported &&
-+	if (!sta->sdata->vif.active_links &&
-+	    !pubsta->deflink.ht_cap.ht_supported &&
- 	    sta->sdata->vif.bss_conf.chanreq.oper.chan->band != NL80211_BAND_6GHZ)
- 		return -EINVAL;
- 
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0034-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0042-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch
similarity index 72%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0034-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0042-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch
index ecdc233..bab839c 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0034-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0042-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch
@@ -1,7 +1,7 @@
-From 2531350e6d261ef54adb85ce59c5012dc4d5db90 Mon Sep 17 00:00:00 2001
+From 1520597ada5bda09bdad5883f79d028fb6082ce0 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Wed, 25 Oct 2023 13:37:00 +0800
-Subject: [PATCH 34/61] mtk: mac80211: set eht_support to false when AP is not
+Subject: [PATCH 42/89] mtk: mac80211: set eht_support to false when AP is not
  in EHT mode
 
 Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 1 insertion(+)
 
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index cb91223..215b5d2 100644
+index e119373..0b7763d 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1384,6 +1384,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
+@@ -1386,6 +1386,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
  		link_conf->eht_su_beamformer = false;
  		link_conf->eht_su_beamformee = false;
  		link_conf->eht_mu_beamformer = false;
@@ -22,5 +22,5 @@
  
  	if (sdata->vif.type == NL80211_IFTYPE_AP &&
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0043-cfg80211-mtk-implement-DFS-radar-detect-for-MLO.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0043-cfg80211-mtk-implement-DFS-radar-detect-for-MLO.patch
deleted file mode 100644
index b2a7cbf..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0043-cfg80211-mtk-implement-DFS-radar-detect-for-MLO.patch
+++ /dev/null
@@ -1,469 +0,0 @@
-From 1c581514b49ffe917cb40d4e073c56b6d1f47416 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 19 Jan 2024 14:35:17 +0800
-Subject: [PATCH 43/61] cfg80211: mtk: implement DFS radar detect for MLO
-
-Implement DFS radar detect for MLO
-1. Add link id info for radar detection in MLD
-2. Note that the radar detection flow requires channel switch, which is not yet
-complete in MLO, so postpone it.
-   (a) cac_started, cac_start_time should be moved into wdev->link, but
-channel switch will use it, so wait until channel switch is completed.
-   (b) ieee80211_dfs_cac_cancel, ieee80211_dfs_radar_detected_work, ...
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-
-rework radar detected flow for mlo
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- include/net/cfg80211.h     |  4 +++-
- net/mac80211/cfg.c         | 26 +++++++++++++++++++-------
- net/mac80211/ieee80211_i.h |  2 +-
- net/mac80211/main.c        |  6 +++---
- net/mac80211/pm.c          |  9 ++++++++-
- net/mac80211/util.c        | 26 +++++++++++++++++++-------
- net/wireless/core.c        |  4 ++--
- net/wireless/mlme.c        |  4 ++--
- net/wireless/nl80211.c     | 10 +++++-----
- net/wireless/rdev-ops.h    | 13 +++++++------
- net/wireless/reg.c         | 15 +++++++++------
- net/wireless/trace.h       | 28 ++++++++++++++++++++++------
- 12 files changed, 100 insertions(+), 47 deletions(-)
-
-diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index bd516d1..e55309b 100644
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -4856,10 +4856,12 @@ struct cfg80211_ops {
- 
- 	int	(*start_radar_detection)(struct wiphy *wiphy,
- 					 struct net_device *dev,
-+					 unsigned int link_id,
- 					 struct cfg80211_chan_def *chandef,
- 					 u32 cac_time_ms);
- 	void	(*end_cac)(struct wiphy *wiphy,
--				struct net_device *dev);
-+			   struct net_device *dev,
-+			   unsigned int link_id);
- 	int	(*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
- 				 struct cfg80211_update_ft_ies_params *ftie);
- 	int	(*crit_proto_start)(struct wiphy *wiphy,
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 215b5d2..3233e2a 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -3443,12 +3443,14 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
- 
- static int ieee80211_start_radar_detection(struct wiphy *wiphy,
- 					   struct net_device *dev,
-+					   unsigned int link_id,
- 					   struct cfg80211_chan_def *chandef,
- 					   u32 cac_time_ms)
- {
- 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- 	struct ieee80211_chan_req chanreq = { .oper = *chandef };
- 	struct ieee80211_local *local = sdata->local;
-+	struct ieee80211_link_data *link;
- 	int err;
- 
- 	lockdep_assert_wiphy(local->hw.wiphy);
-@@ -3458,16 +3460,20 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
- 		goto out_unlock;
- 	}
- 
-+	link = sdata_dereference(sdata->link[link_id], sdata);
-+	if (!link)
-+		return -ENOLINK;
-+
- 	/* whatever, but channel contexts should not complain about that one */
--	sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
--	sdata->deflink.needed_rx_chains = local->rx_chains;
-+	link->smps_mode = IEEE80211_SMPS_OFF;
-+	link->needed_rx_chains = local->rx_chains;
- 
--	err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
-+	err = ieee80211_link_use_channel(link, &chanreq,
- 					 IEEE80211_CHANCTX_SHARED);
- 	if (err)
- 		goto out_unlock;
- 
--	wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
-+	wiphy_delayed_work_queue(wiphy, &link->dfs_cac_timer_work,
- 				 msecs_to_jiffies(cac_time_ms));
- 
-  out_unlock:
-@@ -3475,23 +3481,29 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
- }
- 
- static void ieee80211_end_cac(struct wiphy *wiphy,
--			      struct net_device *dev)
-+			      struct net_device *dev,
-+			      unsigned int link_id)
- {
- 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- 	struct ieee80211_local *local = sdata->local;
-+	struct ieee80211_link_data *link;
- 
- 	lockdep_assert_wiphy(local->hw.wiphy);
- 
-+	link = sdata_dereference(sdata->link[link_id], sdata);
-+	if (!link)
-+		return;
-+
- 	list_for_each_entry(sdata, &local->interfaces, list) {
- 		/* it might be waiting for the local->mtx, but then
- 		 * by the time it gets it, sdata->wdev.cac_started
- 		 * will no longer be true
- 		 */
- 		wiphy_delayed_work_cancel(wiphy,
--					  &sdata->deflink.dfs_cac_timer_work);
-+					  &link->dfs_cac_timer_work);
- 
- 		if (sdata->wdev.cac_started) {
--			ieee80211_link_release_channel(&sdata->deflink);
-+			ieee80211_link_release_channel(link);
- 			sdata->wdev.cac_started = false;
- 		}
- 	}
-diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
-index c5781c3..608e442 100644
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -2592,7 +2592,7 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
- bool ieee80211_is_radar_required(struct ieee80211_local *local);
- 
- void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work);
--void ieee80211_dfs_cac_cancel(struct ieee80211_local *local);
-+void ieee80211_dfs_cac_cancel(struct ieee80211_local *local, unsigned int link_id);
- void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
- 				       struct wiphy_work *work);
- int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
-diff --git a/net/mac80211/main.c b/net/mac80211/main.c
-index e9d8581..f6f0509 100644
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -1173,8 +1173,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
- 			if (comb->num_different_channels > 1)
- 				return -EINVAL;
- 		}
--	} else {
--		/* DFS is not supported with multi-channel combinations yet */
-+	}/* else {
-+		// DFS is not supported with multi-channel combinations yet
- 		for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
- 			const struct ieee80211_iface_combination *comb;
- 
-@@ -1184,7 +1184,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
- 			    comb->num_different_channels > 1)
- 				return -EINVAL;
- 		}
--	}
-+	} */
- 
- 	/* Only HW csum features are currently compatible with mac80211 */
- 	if (WARN_ON(hw->netdev_features & ~MAC80211_SUPPORTED_FEATURES))
-diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
-index c1fa26e..5a25245 100644
---- a/net/mac80211/pm.c
-+++ b/net/mac80211/pm.c
-@@ -22,6 +22,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
- {
- 	struct ieee80211_local *local = hw_to_local(hw);
- 	struct ieee80211_sub_if_data *sdata;
-+	struct ieee80211_chanctx *ctx;
- 	struct sta_info *sta;
- 
- 	if (!local->open_count)
-@@ -32,7 +33,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
- 
- 	ieee80211_scan_cancel(local);
- 
--	ieee80211_dfs_cac_cancel(local);
-+	list_for_each_entry(ctx, &local->chanctx_list, list) {
-+		struct ieee80211_link_data *link, *tmp;
-+
-+		list_for_each_entry_safe(link, tmp, &ctx->assigned_links,
-+					 assigned_chanctx_list)
-+			ieee80211_dfs_cac_cancel(local, link->link_id);
-+	}
- 
- 	ieee80211_roc_purge(local, NULL);
- 
-diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index 55f1566..e5ac902 100644
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -3450,9 +3450,10 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
- 	return ts;
- }
- 
--void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
-+void ieee80211_dfs_cac_cancel(struct ieee80211_local *local, unsigned int link_id)
- {
- 	struct ieee80211_sub_if_data *sdata;
-+	struct ieee80211_link_data *link;
- 	struct cfg80211_chan_def chandef;
- 
- 	lockdep_assert_wiphy(local->hw.wiphy);
-@@ -3462,12 +3463,20 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
- 		 * by the time it gets it, sdata->wdev.cac_started
- 		 * will no longer be true
- 		 */
-+		link = sdata_dereference(sdata->link[link_id], sdata);
-+		if (!link)
-+			continue;
-+
-+		if (link->conf->chanreq.oper.chan &&
-+		    link->conf->chanreq.oper.chan->band != NL80211_BAND_5GHZ)
-+			return;
-+
- 		wiphy_delayed_work_cancel(local->hw.wiphy,
--					  &sdata->deflink.dfs_cac_timer_work);
-+					  &link->dfs_cac_timer_work);
- 
- 		if (sdata->wdev.cac_started) {
--			chandef = sdata->vif.bss_conf.chanreq.oper;
--			ieee80211_link_release_channel(&sdata->deflink);
-+			chandef = link->conf->chanreq.oper;
-+			ieee80211_link_release_channel(link);
- 			cfg80211_cac_event(sdata->dev,
- 					   &chandef,
- 					   NL80211_RADAR_CAC_ABORTED,
-@@ -3483,20 +3492,23 @@ void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
- 		container_of(work, struct ieee80211_local, radar_detected_work);
- 	struct cfg80211_chan_def chandef = local->hw.conf.chandef;
- 	struct ieee80211_chanctx *ctx;
-+	struct ieee80211_link_data *link, *tmp;
- 	int num_chanctx = 0;
- 
- 	lockdep_assert_wiphy(local->hw.wiphy);
- 
- 	list_for_each_entry(ctx, &local->chanctx_list, list) {
--		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
-+		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER ||
-+		    !ctx->conf.def.chan || ctx->conf.def.chan->band != NL80211_BAND_5GHZ)
- 			continue;
- 
- 		num_chanctx++;
- 		chandef = ctx->conf.def;
-+		list_for_each_entry_safe(link, tmp, &ctx->assigned_links,
-+					 assigned_chanctx_list)
-+			ieee80211_dfs_cac_cancel(local, link->link_id);
- 	}
- 
--	ieee80211_dfs_cac_cancel(local);
--
- 	if (num_chanctx > 1)
- 		/* XXX: multi-channel is not supported yet */
- 		WARN_ON(1);
-diff --git a/net/wireless/core.c b/net/wireless/core.c
-index ac9417e..16f40f3 100644
---- a/net/wireless/core.c
-+++ b/net/wireless/core.c
-@@ -629,10 +629,10 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
- 		if (WARN_ON(!c->num_different_channels))
- 			return -EINVAL;
- 
--		/* DFS only works on one channel. */
-+		/* DFS only works on one channel.
- 		if (WARN_ON(c->radar_detect_widths &&
- 			    (c->num_different_channels > 1)))
--			return -EINVAL;
-+			return -EINVAL; */
- 
- 		if (WARN_ON(!c->n_limits))
- 			return -EINVAL;
-diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
-index 3da7886..a957989 100644
---- a/net/wireless/mlme.c
-+++ b/net/wireless/mlme.c
-@@ -1118,9 +1118,9 @@ void cfg80211_cac_event(struct net_device *netdev,
- 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
- 	unsigned long timeout;
- 
--	/* not yet supported */
-+	/* not yet supported
- 	if (wdev->valid_links)
--		return;
-+		return; */
- 
- 	trace_cfg80211_cac_event(netdev, event);
- 
-diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 079fedf..2045cdc 100644
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -9964,6 +9964,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
- 	struct cfg80211_chan_def chandef;
- 	enum nl80211_dfs_regions dfs_region;
- 	unsigned int cac_time_ms;
-+	unsigned int link_id = nl80211_link_id(info->attrs);
- 	int err = -EINVAL;
- 
- 	flush_delayed_work(&rdev->dfs_update_channels_wk);
-@@ -9998,7 +9999,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
- 		goto unlock;
- 	}
- 
--	if (netif_carrier_ok(dev)) {
-+	if (!wdev->valid_links && netif_carrier_ok(dev)) {
- 		err = -EBUSY;
- 		goto unlock;
- 	}
-@@ -10026,9 +10027,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
- 	pr_info("%s: region = %u, center freq1 = %u, center freq2 = %u, cac time ms = %u\n",
- 		__func__, dfs_region, chandef.center_freq1, chandef.center_freq2, cac_time_ms);
- 
--	err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
-+	err = rdev_start_radar_detection(rdev, dev, link_id, &chandef, cac_time_ms);
- 	if (!err) {
--		wdev->links[0].ap.chandef = chandef;
-+		wdev->links[link_id].ap.chandef = chandef;
- 		wdev->cac_started = true;
- 		wdev->cac_start_time = jiffies;
- 		wdev->cac_time_ms = cac_time_ms;
-@@ -17304,8 +17305,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
- 		.doit = nl80211_start_radar_detection,
- 		.flags = GENL_UNS_ADMIN_PERM,
- 		.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
--					 NL80211_FLAG_NO_WIPHY_MTX |
--					 NL80211_FLAG_MLO_UNSUPPORTED),
-+					 NL80211_FLAG_NO_WIPHY_MTX),
- 	},
- 	{
- 		.cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
-diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
-index 2ae7fc5..561637c 100644
---- a/net/wireless/rdev-ops.h
-+++ b/net/wireless/rdev-ops.h
-@@ -1197,15 +1197,16 @@ rdev_tdls_cancel_channel_switch(struct cfg80211_registered_device *rdev,
- static inline int
- rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
- 			   struct net_device *dev,
-+			   unsigned int link_id,
- 			   struct cfg80211_chan_def *chandef,
- 			   u32 cac_time_ms)
- {
- 	int ret = -EOPNOTSUPP;
- 
--	trace_rdev_start_radar_detection(&rdev->wiphy, dev, chandef,
--					 cac_time_ms);
-+	trace_rdev_start_radar_detection(&rdev->wiphy, dev, link_id,
-+					 chandef, cac_time_ms);
- 	if (rdev->ops->start_radar_detection)
--		ret = rdev->ops->start_radar_detection(&rdev->wiphy, dev,
-+		ret = rdev->ops->start_radar_detection(&rdev->wiphy, dev, link_id,
- 						       chandef, cac_time_ms);
- 	trace_rdev_return_int(&rdev->wiphy, ret);
- 	return ret;
-@@ -1213,11 +1214,11 @@ rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
- 
- static inline void
- rdev_end_cac(struct cfg80211_registered_device *rdev,
--	     struct net_device *dev)
-+	     struct net_device *dev, unsigned int link_id)
- {
--	trace_rdev_end_cac(&rdev->wiphy, dev);
-+	trace_rdev_end_cac(&rdev->wiphy, dev, link_id);
- 	if (rdev->ops->end_cac)
--		rdev->ops->end_cac(&rdev->wiphy, dev);
-+		rdev->ops->end_cac(&rdev->wiphy, dev, link_id);
- 	trace_rdev_return_void(&rdev->wiphy);
- }
- 
-diff --git a/net/wireless/reg.c b/net/wireless/reg.c
-index 2c0c1f1..6883aa0 100644
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -4246,17 +4246,20 @@ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
- 	 */
- 	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
- 		struct cfg80211_chan_def *chandef;
-+		unsigned int link_id;
- 
- 		if (!wdev->cac_started)
- 			continue;
- 
--		/* FIXME: radar detection is tied to link 0 for now */
--		chandef = wdev_chandef(wdev, 0);
--		if (!chandef)
--			continue;
-+		for_each_valid_link(wdev, link_id) {
-+			chandef = wdev_chandef(wdev, link_id);
-+			if (!chandef || !chandef->chan ||
-+			    chandef->chan->band != NL80211_BAND_5GHZ)
-+				continue;
- 
--		if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
--			rdev_end_cac(rdev, wdev->netdev);
-+			if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
-+				rdev_end_cac(rdev, wdev->netdev, link_id);
-+		}
- 	}
- }
- 
-diff --git a/net/wireless/trace.h b/net/wireless/trace.h
-index aa3284f..22b1fcc 100644
---- a/net/wireless/trace.h
-+++ b/net/wireless/trace.h
-@@ -731,9 +731,22 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa,
- 	TP_ARGS(wiphy, netdev)
- );
- 
--DEFINE_EVENT(wiphy_netdev_evt, rdev_end_cac,
--	     TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
--	     TP_ARGS(wiphy, netdev)
-+TRACE_EVENT(rdev_end_cac,
-+	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
-+		 unsigned int link_id),
-+	TP_ARGS(wiphy, netdev, link_id),
-+	TP_STRUCT__entry(
-+		WIPHY_ENTRY
-+		NETDEV_ENTRY
-+		__field(u32, link_id)
-+	),
-+	TP_fast_assign(
-+		WIPHY_ASSIGN;
-+		NETDEV_ASSIGN;
-+		__entry->link_id = link_id;
-+	),
-+	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id=%u",
-+		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id)
- );
- 
- DECLARE_EVENT_CLASS(station_add_change,
-@@ -2577,24 +2590,27 @@ TRACE_EVENT(rdev_external_auth,
- 
- TRACE_EVENT(rdev_start_radar_detection,
- 	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
-+		 unsigned int link_id,
- 		 struct cfg80211_chan_def *chandef,
- 		 u32 cac_time_ms),
--	TP_ARGS(wiphy, netdev, chandef, cac_time_ms),
-+	TP_ARGS(wiphy, netdev, link_id, chandef, cac_time_ms),
- 	TP_STRUCT__entry(
- 		WIPHY_ENTRY
- 		NETDEV_ENTRY
-+		__field(u32, link_id)
- 		CHAN_DEF_ENTRY
- 		__field(u32, cac_time_ms)
- 	),
- 	TP_fast_assign(
- 		WIPHY_ASSIGN;
- 		NETDEV_ASSIGN;
-+		__entry->link_id = link_id;
- 		CHAN_DEF_ASSIGN(chandef);
- 		__entry->cac_time_ms = cac_time_ms;
- 	),
--	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT
-+	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id=%u, " CHAN_DEF_PR_FMT
- 		  ", cac_time_ms=%u",
--		  WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG,
-+		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id, CHAN_DEF_PR_ARG,
- 		  __entry->cac_time_ms)
- );
- 
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0035-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0043-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch
similarity index 89%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0035-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0043-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch
index 9d76079..612ed69 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0035-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0043-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch
@@ -1,7 +1,7 @@
-From ba967d748120a6681f3e0f106dfaf3ad882034c0 Mon Sep 17 00:00:00 2001
+From 1519b6ddc0a4256bddcaaeb8fc43db7fd7c6ee8f Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Thu, 9 Nov 2023 11:37:37 +0800
-Subject: [PATCH 35/61] mtk: mac80211: Add cert mode to disable ba timeout
+Subject: [PATCH 43/89] mtk: mac80211: Add cert mode to disable ba timeout
 
 Add a switch of certification mode in debugfs as cert_mode. In the case
 we use it to disable BA timeout from STA to prevent crashing STA.
@@ -18,10 +18,10 @@
  3 files changed, 59 insertions(+), 1 deletion(-)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 860ad6e..89bba19 100644
+index 215d499..98678c8 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -3028,8 +3028,14 @@ struct ieee80211_hw {
+@@ -3059,8 +3059,14 @@ struct ieee80211_hw {
  	u32 max_mtu;
  	const s8 *tx_power_levels;
  	u8 max_txpwr_levels_idx;
@@ -37,10 +37,10 @@
  				       enum ieee80211_hw_flags flg)
  {
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 8480b64..7117576 100644
+index 0abc77b..2f351a7 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
-@@ -1090,7 +1090,10 @@ next:
+@@ -1092,7 +1092,10 @@ next:
  		tid_tx->timeout =
  			le16_to_cpu(mgmt->u.action.u.addba_resp.timeout);
  
@@ -53,7 +53,7 @@
  				  TU_TO_EXP_TIME(tid_tx->timeout));
  			tid_tx->last_tx = jiffies;
 diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
-index f9c5ed8..d655a19 100644
+index ce8eb40..376abfc 100644
 --- a/net/mac80211/debugfs.c
 +++ b/net/mac80211/debugfs.c
 @@ -450,6 +450,54 @@ static const struct file_operations reset_ops = {
@@ -111,7 +111,7 @@
  static const char *hw_flag_names[] = {
  #define FLAG(F)	[IEEE80211_HW_##F] = #F
  	FLAG(HAS_RATE_CONTROL),
-@@ -684,6 +732,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
+@@ -683,6 +731,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
  	debugfs_create_u32("aql_threshold", 0600,
  			   phyd, &local->aql_threshold);
  
@@ -120,5 +120,5 @@
  
  #ifdef CPTCFG_MAC80211_DEBUG_COUNTERS
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0037-mac80211-mtk-ACS-channel-time-is-reset-by-ch_restore.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0044-mtk-mac80211-ACS-channel-time-is-reset-by-ch_restore.patch
similarity index 77%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0037-mac80211-mtk-ACS-channel-time-is-reset-by-ch_restore.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0044-mtk-mac80211-ACS-channel-time-is-reset-by-ch_restore.patch
index 806bfd5..e558be2 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0037-mac80211-mtk-ACS-channel-time-is-reset-by-ch_restore.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0044-mtk-mac80211-ACS-channel-time-is-reset-by-ch_restore.patch
@@ -1,7 +1,7 @@
-From 9c1106eb80f31723780a6eb098b5c146a33d45a2 Mon Sep 17 00:00:00 2001
+From 41a3454ac2b2bd0116deb0f00553f1959f29329e Mon Sep 17 00:00:00 2001
 From: "fancy.liu" <fancy.liu@mediatek.com>
 Date: Wed, 29 Nov 2023 13:51:13 +0800
-Subject: [PATCH 37/61] mac80211: mtk: ACS channel time is reset by ch_restore
+Subject: [PATCH 44/89] mtk: mac80211: ACS channel time is reset by ch_restore
 
 Issue:
 There's a chance that the channel time for duty channel is zero in ACS
@@ -25,14 +25,14 @@
 Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
 ---
  include/net/mac80211.h | 7 +++++++
- net/mac80211/util.c    | 9 +++++++++
- 2 files changed, 16 insertions(+)
+ net/mac80211/util.c    | 8 ++++++++
+ 2 files changed, 15 insertions(+)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 89bba19..d7b1f9d 100644
+index 98678c8..5321c22 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -7665,4 +7665,11 @@ int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
+@@ -7708,4 +7708,11 @@ int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
  					 int n_vifs,
  					 enum ieee80211_chanctx_switch_mode mode);
  
@@ -45,11 +45,11 @@
 +
  #endif /* MAC80211_H */
 diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index dd06bd2..55f1566 100644
+index 1877400..7f93739 100644
 --- a/net/mac80211/util.c
 +++ b/net/mac80211/util.c
-@@ -4340,3 +4340,12 @@ ieee80211_min_bw_limit_from_chandef(struct cfg80211_chan_def *chandef)
- 		return IEEE80211_CONN_BW_LIMIT_20;
+@@ -4486,3 +4486,11 @@ void ieee80211_clear_tpe(struct ieee80211_parsed_tpe *tpe)
+ 		       sizeof(tpe->psd_reg_client[i].power));
  	}
  }
 +
@@ -60,7 +60,6 @@
 +	return local->scanning;
 +}
 +EXPORT_SYMBOL(ieee80211_get_scanning);
-+
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0044-mtk-wifi-mac80211-add-wds-mlo-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0044-mtk-wifi-mac80211-add-wds-mlo-support.patch
deleted file mode 100644
index 52e91c0..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0044-mtk-wifi-mac80211-add-wds-mlo-support.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From 5f294c8632c08814df00df8ed297e852d21b0e02 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Fri, 19 Jan 2024 15:22:00 +0800
-Subject: [PATCH 44/61] mtk: wifi: mac80211: add wds mlo support
-
-Support WDS mode when using MLO.
-1. Remove use_4addr check.
-2. Copy link information to AP_VLAN interface.
-3. Fill 4addr nullfunc by mld address.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- net/mac80211/cfg.c   |  7 -------
- net/mac80211/iface.c | 23 +++++++++++++++--------
- net/mac80211/mlme.c  | 15 +++++++++------
- 3 files changed, 24 insertions(+), 21 deletions(-)
-
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 3233e2a..0cb68fb 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -229,10 +229,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
- 		if (params->use_4addr == ifmgd->use_4addr)
- 			return 0;
- 
--		/* FIXME: no support for 4-addr MLO yet */
--		if (ieee80211_vif_is_mld(&sdata->vif))
--			return -EOPNOTSUPP;
--
- 		sdata->u.mgd.use_4addr = params->use_4addr;
- 		if (!ifmgd->associated)
- 			return 0;
-@@ -4922,9 +4918,6 @@ static int ieee80211_add_intf_link(struct wiphy *wiphy,
- 
- 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
- 
--	if (wdev->use_4addr)
--		return -EOPNOTSUPP;
--
- 	return ieee80211_vif_set_links(sdata, wdev->valid_links, 0);
- }
- 
-diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index 0ae31a9..fce9834 100644
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -381,19 +381,26 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
- 							nsdata->vif.type))
- 				return -ENOTUNIQ;
- 
--			/* No support for VLAN with MLO yet */
--			if (iftype == NL80211_IFTYPE_AP_VLAN &&
--			    sdata->wdev.use_4addr &&
--			    nsdata->vif.type == NL80211_IFTYPE_AP &&
--			    nsdata->vif.valid_links)
--				return -EOPNOTSUPP;
--
- 			/*
- 			 * can only add VLANs to enabled APs
- 			 */
- 			if (iftype == NL80211_IFTYPE_AP_VLAN &&
--			    nsdata->vif.type == NL80211_IFTYPE_AP)
-+			    nsdata->vif.type == NL80211_IFTYPE_AP) {
-+				int i;
-+
- 				sdata->bss = &nsdata->u.ap;
-+				sdata->vif.valid_links = nsdata->vif.valid_links;
-+				sdata->vif.active_links = nsdata->vif.active_links;
-+				sdata->vif.dormant_links = nsdata->vif.dormant_links;
-+				for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
-+					if (!ieee80211_vif_is_mld(&nsdata->vif) &&
-+					    sdata->link[i] == &sdata->deflink)
-+						continue;
-+
-+					sdata->link[i] = nsdata->link[i];
-+					sdata->vif.link_conf[i] = nsdata->vif.link_conf[i];
-+				}
-+			}
- 		}
- 	}
- 
-diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 84ea805..674f3f5 100644
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -1829,6 +1829,7 @@ void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
- {
- 	struct sk_buff *skb;
- 	struct ieee80211_hdr *nullfunc;
-+	u8 assoc_link_id = ifmgd->assoc_data->assoc_link_id;
- 	__le16 fc;
- 
- 	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
-@@ -1844,11 +1845,17 @@ void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
- 	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
- 			 IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
- 	nullfunc->frame_control = fc;
--	memcpy(nullfunc->addr1, sdata->deflink.u.mgd.bssid, ETH_ALEN);
- 	memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
--	memcpy(nullfunc->addr3, sdata->deflink.u.mgd.bssid, ETH_ALEN);
- 	memcpy(nullfunc->addr4, sdata->vif.addr, ETH_ALEN);
- 
-+	if (ieee80211_vif_is_mld(&sdata->vif)) {
-+		memcpy(nullfunc->addr1, sdata->vif.cfg.ap_addr, ETH_ALEN);
-+		memcpy(nullfunc->addr3, sdata->vif.cfg.ap_addr, ETH_ALEN);
-+	} else {
-+		memcpy(nullfunc->addr1, sdata->deflink.u.mgd.bssid, ETH_ALEN);
-+		memcpy(nullfunc->addr3, sdata->deflink.u.mgd.bssid, ETH_ALEN);
-+	}
-+
- 	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
- 	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
- 	ieee80211_tx_skb(sdata, skb);
-@@ -8229,10 +8236,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
- 	for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++)
- 		size += req->links[i].elems_len;
- 
--	/* FIXME: no support for 4-addr MLO yet */
--	if (sdata->u.mgd.use_4addr && req->link_id >= 0)
--		return -EOPNOTSUPP;
--
- 	assoc_data = kzalloc(size, GFP_KERNEL);
- 	if (!assoc_data)
- 		return -ENOMEM;
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0038-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0045-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch
similarity index 80%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0038-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0045-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch
index 93a9f79..aa67634 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0038-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0045-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch
@@ -1,7 +1,7 @@
-From 8a8535abf02e5cb6f0dcaf924e33183a1a1fa410 Mon Sep 17 00:00:00 2001
+From 8b48d9cd47d92a99b296f187aa0aa53a39af4179 Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Thu, 30 Nov 2023 14:01:29 +0800
-Subject: [PATCH 38/61] mtk: mac80211: Fix SMPS action frame cap check
+Subject: [PATCH 45/89] mtk: mac80211: Fix SMPS action frame cap check
 
 Fix SMPS action frame cap check.
 Due to 6G band doesn't have HT cap, we change cap check into each action
@@ -13,10 +13,10 @@
  1 file changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 06725f3..1d273ef 100644
+index 78e9c6e..237ab52 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3528,9 +3528,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
+@@ -3531,9 +3531,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
  
  	switch (mgmt->u.action.category) {
  	case WLAN_CATEGORY_HT:
@@ -26,7 +26,7 @@
  
  		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
  		    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
-@@ -3549,6 +3546,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
+@@ -3552,6 +3549,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
  			enum ieee80211_smps_mode smps_mode;
  			struct sta_opmode_info sta_opmode = {};
  
@@ -39,5 +39,5 @@
  			    sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
  				goto handled;
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0039-mtk-mac80211-allow-multiple-links-for-STA-vif.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0046-mtk-mac80211-allow-multiple-links-for-STA-vif.patch
similarity index 73%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0039-mtk-mac80211-allow-multiple-links-for-STA-vif.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0046-mtk-mac80211-allow-multiple-links-for-STA-vif.patch
index 2161fef..bdc3dcd 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0039-mtk-mac80211-allow-multiple-links-for-STA-vif.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0046-mtk-mac80211-allow-multiple-links-for-STA-vif.patch
@@ -1,7 +1,7 @@
-From 9de692d990d4d83e957ea89e3fc23367f696bbc3 Mon Sep 17 00:00:00 2001
+From 87be910eb2392b8d9c40330dde73bf01f7e07323 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 19 Oct 2023 00:27:15 +0800
-Subject: [PATCH 39/61] mtk: mac80211: allow multiple links for STA vif
+Subject: [PATCH 46/89] mtk: mac80211: allow multiple links for STA vif
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 ---
@@ -9,10 +9,10 @@
  1 file changed, 3 deletions(-)
 
 diff --git a/net/mac80211/link.c b/net/mac80211/link.c
-index 43f9672..a33a845 100644
+index 0bbac64..f77dab2 100644
 --- a/net/mac80211/link.c
 +++ b/net/mac80211/link.c
-@@ -168,10 +168,7 @@ static void ieee80211_set_vif_links_bitmaps(struct ieee80211_sub_if_data *sdata,
+@@ -180,10 +180,7 @@ static void ieee80211_set_vif_links_bitmaps(struct ieee80211_sub_if_data *sdata,
  		WARN_ON(dormant_links);
  		break;
  	case NL80211_IFTYPE_STATION:
@@ -24,5 +24,5 @@
  	default:
  		WARN_ON(1);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0040-mtk-mac80211-increase-association-timeout-time.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0047-mtk-mac80211-increase-association-timeout-time.patch
similarity index 76%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0040-mtk-mac80211-increase-association-timeout-time.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0047-mtk-mac80211-increase-association-timeout-time.patch
index eb85ebc..b34ef91 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0040-mtk-mac80211-increase-association-timeout-time.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0047-mtk-mac80211-increase-association-timeout-time.patch
@@ -1,7 +1,7 @@
-From 48d97cc83f3098481fbc2a6d38da75e94703708f Mon Sep 17 00:00:00 2001
+From 786c6183c040ed6f6e440410957aa42d4086df03 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 19 Oct 2023 00:35:11 +0800
-Subject: [PATCH 40/61] mtk: mac80211: increase association timeout time
+Subject: [PATCH 47/89] mtk: mac80211: increase association timeout time
 
 Prevent from sending multiple association requests while AP is already
 hanlding the request.
@@ -12,10 +12,10 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index a27682e..84ea805 100644
+index 9c83b96..ebd4d74 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
-@@ -7202,7 +7202,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
+@@ -7789,7 +7789,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
  			 */
  			if (status_acked) {
  				ifmgd->assoc_data->timeout =
@@ -25,5 +25,5 @@
  			} else {
  				ifmgd->assoc_data->timeout = jiffies - 1;
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0048-mtk-cfg80211-rework-cac-started-cac-start-time-for-m.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0048-mtk-cfg80211-rework-cac-started-cac-start-time-for-m.patch
deleted file mode 100644
index f711fcd..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0048-mtk-cfg80211-rework-cac-started-cac-start-time-for-m.patch
+++ /dev/null
@@ -1,388 +0,0 @@
-From 286c36e1252e070ae30be3231b1349edb8cb74b6 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Thu, 1 Feb 2024 10:57:39 +0800
-Subject: [PATCH 48/61] mtk: cfg80211: rework cac started, cac start time for
- multi-link support
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- include/net/cfg80211.h | 20 ++++++++++++++------
- net/mac80211/cfg.c     | 26 +++++++++++++-------------
- net/mac80211/iface.c   | 22 +++++++++++++++-------
- net/mac80211/mlme.c    |  4 ++--
- net/mac80211/pm.c      | 10 ++++------
- net/mac80211/scan.c    |  2 +-
- net/mac80211/util.c    |  6 +++---
- net/wireless/debugfs.c | 10 ++++++----
- net/wireless/mlme.c    | 13 +++++++------
- net/wireless/nl80211.c |  8 ++++----
- net/wireless/reg.c     |  4 ++--
- 11 files changed, 71 insertions(+), 54 deletions(-)
-
-diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index e55309b..e88cc1e 100644
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -6223,11 +6223,6 @@ struct wireless_dev {
- 	u32 owner_nlportid;
- 	bool nl_owner_dead;
- 
--	/* FIXME: need to rework radar detection for MLO */
--	bool cac_started;
--	unsigned long cac_start_time;
--	unsigned int cac_time_ms;
--
- #ifdef CPTCFG_CFG80211_WEXT
- 	/* wext data */
- 	struct {
-@@ -6294,8 +6289,11 @@ struct wireless_dev {
- 				struct cfg80211_internal_bss *current_bss;
- 			} client;
- 		};
-+		unsigned long cac_start_time;
-+		unsigned int cac_time_ms;
- 	} links[IEEE80211_MLD_MAX_NUM_LINKS];
- 	u16 valid_links;
-+	u16 cac_links;
- };
- 
- static inline const u8 *wdev_address(struct wireless_dev *wdev)
-@@ -6350,6 +6348,15 @@ static inline void WARN_INVALID_LINK_ID(struct wireless_dev *wdev,
- 		if (!(link_info)->valid_links ||		\
- 		    ((link_info)->valid_links & BIT(link_id)))
- 
-+#define for_each_cac_link(link_info, link_id)			\
-+	for (link_id = 0;					\
-+	     link_id < ((link_info)->cac_links ?		\
-+			ARRAY_SIZE((link_info)->links) : 1);	\
-+	     link_id++)						\
-+		if (!(link_info)->cac_links ||			\
-+		    ((link_info)->cac_links & BIT(link_id)))
-+
-+
- /**
-  * DOC: Utility functions
-  *
-@@ -8669,6 +8676,7 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
- /**
-  * cfg80211_cac_event - Channel availability check (CAC) event
-  * @netdev: network device
-+ * @link_id: the link ID for MLO, must be 0 for non-MLO
-  * @chandef: chandef for the current channel
-  * @event: type of event
-  * @gfp: context flags
-@@ -8677,7 +8685,7 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
-  * or aborted. This must be called to notify the completion of a CAC process,
-  * also by full-MAC drivers.
-  */
--void cfg80211_cac_event(struct net_device *netdev,
-+void cfg80211_cac_event(struct net_device *netdev, unsigned int link_id,
- 			const struct cfg80211_chan_def *chandef,
- 			enum nl80211_radar_event event, gfp_t gfp);
- 
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 6e3b28e..871623d 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1658,10 +1658,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
- 	ieee80211_link_info_change_notify(sdata, link,
- 					  BSS_CHANGED_BEACON_ENABLED);
- 
--	if (sdata->wdev.cac_started) {
-+	if (sdata->wdev.cac_links & BIT(link_id)) {
- 		chandef = link_conf->chanreq.oper;
- 		wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work);
--		cfg80211_cac_event(sdata->dev, &chandef,
-+		cfg80211_cac_event(sdata->dev, link_id, &chandef,
- 				   NL80211_RADAR_CAC_ABORTED,
- 				   GFP_KERNEL);
- 	}
-@@ -3492,15 +3492,15 @@ static void ieee80211_end_cac(struct wiphy *wiphy,
- 
- 	list_for_each_entry(sdata, &local->interfaces, list) {
- 		/* it might be waiting for the local->mtx, but then
--		 * by the time it gets it, sdata->wdev.cac_started
-+		 * by the time it gets it, sdata->wdev.cac_links & BIT(link_id)
- 		 * will no longer be true
- 		 */
- 		wiphy_delayed_work_cancel(wiphy,
- 					  &link->dfs_cac_timer_work);
- 
--		if (sdata->wdev.cac_started) {
-+		if (sdata->wdev.cac_links & BIT(link_id)) {
- 			ieee80211_link_release_channel(link);
--			sdata->wdev.cac_started = false;
-+			sdata->wdev.cac_links &= ~BIT(link_id);
- 		}
- 	}
- }
-@@ -3959,12 +3959,12 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- 	if (!list_empty(&local->roc_list) || local->scanning)
- 		return -EBUSY;
- 
--	if (sdata->wdev.cac_started)
--		return -EBUSY;
--
- 	if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
- 		return -EINVAL;
- 
-+	if (sdata->wdev.cac_links & BIT(link_id))
-+		return -EBUSY;
-+
- 	link_data = wiphy_dereference(wiphy, sdata->link[link_id]);
- 	if (!link_data)
- 		return -ENOLINK;
-@@ -5078,12 +5078,12 @@ ieee80211_skip_cac(struct wireless_dev *wdev, unsigned int link_id)
- 
- 	wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
- 				  &link->dfs_cac_timer_work);
--	if (wdev->cac_started) {
-+	if (wdev->cac_links & BIT(link_id)) {
- 		ieee80211_link_release_channel(link);
--		cac_time_ms = wdev->cac_time_ms;
--		wdev->cac_start_time = jiffies -
--				       msecs_to_jiffies(cac_time_ms + 1);
--		cfg80211_cac_event(wdev->netdev, &link->conf->chanreq.oper,
-+		cac_time_ms = wdev->links[link_id].cac_time_ms;
-+		wdev->links[link_id].cac_start_time = jiffies -
-+						      msecs_to_jiffies(cac_time_ms + 1);
-+		cfg80211_cac_event(wdev->netdev, link_id, &link->conf->chanreq.oper,
- 				   NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
- 	}
- }
-diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index fce9834..be52a83 100644
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -563,13 +563,21 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
- 	wiphy_delayed_work_cancel(local->hw.wiphy,
- 				  &sdata->deflink.dfs_cac_timer_work);
- 
--	if (sdata->wdev.cac_started) {
--		chandef = sdata->vif.bss_conf.chanreq.oper;
--		WARN_ON(local->suspended);
--		ieee80211_link_release_channel(&sdata->deflink);
--		cfg80211_cac_event(sdata->dev, &chandef,
--				   NL80211_RADAR_CAC_ABORTED,
--				   GFP_KERNEL);
-+	if (sdata->wdev.cac_links) {
-+		struct ieee80211_link_data *link;
-+		unsigned int link_id;
-+
-+		for_each_cac_link(&sdata->wdev, link_id) {
-+			link = sdata_dereference(sdata->link[link_id], sdata);
-+			if (!link)
-+				continue;
-+			chandef = link->conf->chanreq.oper;
-+			WARN_ON(local->suspended);
-+			ieee80211_link_release_channel(link);
-+			cfg80211_cac_event(sdata->dev, link_id, &chandef,
-+					   NL80211_RADAR_CAC_ABORTED,
-+					   GFP_KERNEL);
-+		}
- 	}
- 
- 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
-diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 674f3f5..e4564de 100644
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -2611,9 +2611,9 @@ void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work)
- 
- 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
- 
--	if (sdata->wdev.cac_started) {
-+	if (sdata->wdev.cac_links & BIT(link->link_id)) {
- 		ieee80211_link_release_channel(link);
--		cfg80211_cac_event(sdata->dev, &chandef,
-+		cfg80211_cac_event(sdata->dev, link->link_id, &chandef,
- 				   NL80211_RADAR_CAC_FINISHED,
- 				   GFP_KERNEL);
- 	}
-diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
-index 5a25245..6fae264 100644
---- a/net/mac80211/pm.c
-+++ b/net/mac80211/pm.c
-@@ -22,7 +22,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
- {
- 	struct ieee80211_local *local = hw_to_local(hw);
- 	struct ieee80211_sub_if_data *sdata;
--	struct ieee80211_chanctx *ctx;
- 	struct sta_info *sta;
- 
- 	if (!local->open_count)
-@@ -33,12 +32,11 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
- 
- 	ieee80211_scan_cancel(local);
- 
--	list_for_each_entry(ctx, &local->chanctx_list, list) {
--		struct ieee80211_link_data *link, *tmp;
-+	list_for_each_entry(sdata, &local->interfaces, list) {
-+		unsigned int link_id;
- 
--		list_for_each_entry_safe(link, tmp, &ctx->assigned_links,
--					 assigned_chanctx_list)
--			ieee80211_dfs_cac_cancel(local, link->link_id);
-+		for_each_cac_link(&sdata->wdev, link_id)
-+			ieee80211_dfs_cac_cancel(local, link_id);
- 	}
- 
- 	ieee80211_roc_purge(local, NULL);
-diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
-index 977f8eb..5a430cb 100644
---- a/net/mac80211/scan.c
-+++ b/net/mac80211/scan.c
-@@ -584,7 +584,7 @@ static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata)
- 		return false;
- 
- 	list_for_each_entry(sdata_iter, &local->interfaces, list) {
--		if (sdata_iter->wdev.cac_started)
-+		if (sdata_iter->wdev.cac_links)
- 			return false;
- 	}
- 
-diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index e5ac902..732232a 100644
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -3460,7 +3460,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local, unsigned int link_i
- 
- 	list_for_each_entry(sdata, &local->interfaces, list) {
- 		/* it might be waiting for the local->mtx, but then
--		 * by the time it gets it, sdata->wdev.cac_started
-+		 * by the time it gets it, sdata->wdev.cac_links & BIT(link_id)
- 		 * will no longer be true
- 		 */
- 		link = sdata_dereference(sdata->link[link_id], sdata);
-@@ -3474,10 +3474,10 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local, unsigned int link_i
- 		wiphy_delayed_work_cancel(local->hw.wiphy,
- 					  &link->dfs_cac_timer_work);
- 
--		if (sdata->wdev.cac_started) {
-+		if (sdata->wdev.cac_links & BIT(link_id)) {
- 			chandef = link->conf->chanreq.oper;
- 			ieee80211_link_release_channel(link);
--			cfg80211_cac_event(sdata->dev,
-+			cfg80211_cac_event(sdata->dev, link_id,
- 					   &chandef,
- 					   NL80211_RADAR_CAC_ABORTED,
- 					   GFP_KERNEL);
-diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
-index a246b2c..cbeed9f 100644
---- a/net/wireless/debugfs.c
-+++ b/net/wireless/debugfs.c
-@@ -187,10 +187,11 @@ static int dfs_status_read_wdev(struct wiphy *wiphy, struct wireless_dev *wdev,
- 				if (remain_time > wait_time_ms)
- 					remain_time = 0;
- 			} else if (chan->dfs_state == NL80211_DFS_USABLE) {
--				if (wdev->cac_started &&
-+				if ((wdev->cac_links & BIT(link_id)) &&
- 				    cfg80211_is_sub_chan(chandef, chan, false)) {
--					jiffies_passed = jiffies - wdev->cac_start_time;
--					wait_time_ms = wdev->cac_time_ms;
-+					jiffies_passed = jiffies -
-+							 wdev->links[link_id].cac_start_time;
-+					wait_time_ms = wdev->links[link_id].cac_time_ms;
- 					remain_time = (wait_time_ms -
- 						       jiffies_to_msecs(jiffies_passed));
- 				}
-@@ -336,7 +337,8 @@ dfs_cac_skip(void *data, u64 val)
- 					continue;
- 
- 				if (cfg80211_chandef_dfs_required(wiphy, c, wdev->iftype) > 0 &&
--				    cfg80211_chandef_dfs_usable(wiphy, c) && wdev->cac_started) {
-+				    cfg80211_chandef_dfs_usable(wiphy, c) &&
-+				    (wdev->cac_links & BIT(link_id))) {
- 					rdev_skip_cac(rdev, wdev, link_id);
- 				}
- 			}
-diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
-index a957989..265c2f2 100644
---- a/net/wireless/mlme.c
-+++ b/net/wireless/mlme.c
-@@ -1109,7 +1109,7 @@ void __cfg80211_radar_event(struct wiphy *wiphy,
- }
- EXPORT_SYMBOL(__cfg80211_radar_event);
- 
--void cfg80211_cac_event(struct net_device *netdev,
-+void cfg80211_cac_event(struct net_device *netdev, unsigned int link_id,
- 			const struct cfg80211_chan_def *chandef,
- 			enum nl80211_radar_event event, gfp_t gfp)
- {
-@@ -1124,13 +1124,14 @@ void cfg80211_cac_event(struct net_device *netdev,
- 
- 	trace_cfg80211_cac_event(netdev, event);
- 
--	if (WARN_ON(!wdev->cac_started && event != NL80211_RADAR_CAC_STARTED))
-+	if (WARN_ON(!(wdev->cac_links & BIT(link_id)) &&
-+		    event != NL80211_RADAR_CAC_STARTED))
- 		return;
- 
- 	switch (event) {
- 	case NL80211_RADAR_CAC_FINISHED:
--		timeout = wdev->cac_start_time +
--			  msecs_to_jiffies(wdev->cac_time_ms);
-+		timeout = wdev->links[link_id].cac_start_time +
-+			  msecs_to_jiffies(wdev->links[link_id].cac_time_ms);
- 		WARN_ON(!time_after_eq(jiffies, timeout));
- 		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
- 		memcpy(&rdev->cac_done_chandef, chandef,
-@@ -1139,10 +1140,10 @@ void cfg80211_cac_event(struct net_device *netdev,
- 		cfg80211_sched_dfs_chan_update(rdev);
- 		fallthrough;
- 	case NL80211_RADAR_CAC_ABORTED:
--		wdev->cac_started = false;
-+		wdev->cac_links &= ~BIT(link_id);
- 		break;
- 	case NL80211_RADAR_CAC_STARTED:
--		wdev->cac_started = true;
-+		wdev->cac_links |= BIT(link_id);
- 		break;
- 	default:
- 		WARN_ON(1);
-diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 2045cdc..2a34884 100644
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -10004,7 +10004,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
- 		goto unlock;
- 	}
- 
--	if (wdev->cac_started) {
-+	if (wdev->cac_links & BIT(link_id)) {
- 		err = -EBUSY;
- 		goto unlock;
- 	}
-@@ -10030,9 +10030,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
- 	err = rdev_start_radar_detection(rdev, dev, link_id, &chandef, cac_time_ms);
- 	if (!err) {
- 		wdev->links[link_id].ap.chandef = chandef;
--		wdev->cac_started = true;
--		wdev->cac_start_time = jiffies;
--		wdev->cac_time_ms = cac_time_ms;
-+		wdev->cac_links |= BIT(link_id);
-+		wdev->links[link_id].cac_start_time = jiffies;
-+		wdev->links[link_id].cac_time_ms = cac_time_ms;
- 		if (rdev->background_cac_started &&
- 		    cfg80211_is_sub_chan(&chandef, rdev->background_radar_chandef.chan, false)) {
- 			cfg80211_stop_background_radar_detection(rdev->background_radar_wdev);
-diff --git a/net/wireless/reg.c b/net/wireless/reg.c
-index 6883aa0..ebe0ed4 100644
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -4248,10 +4248,10 @@ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
- 		struct cfg80211_chan_def *chandef;
- 		unsigned int link_id;
- 
--		if (!wdev->cac_started)
-+		if (!wdev->cac_links)
- 			continue;
- 
--		for_each_valid_link(wdev, link_id) {
-+		for_each_cac_link(wdev, link_id) {
- 			chandef = wdev_chandef(wdev, link_id);
- 			if (!chandef || !chandef->chan ||
- 			    chandef->chan->band != NL80211_BAND_5GHZ)
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0042-mtk-mac80211-use-link-address-for-eapol-source-in-ie.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0048-mtk-mac80211-use-link-address-for-eapol-source-in-ie.patch
similarity index 75%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0042-mtk-mac80211-use-link-address-for-eapol-source-in-ie.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0048-mtk-mac80211-use-link-address-for-eapol-source-in-ie.patch
index f223bff..9c2fd48 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0042-mtk-mac80211-use-link-address-for-eapol-source-in-ie.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0048-mtk-mac80211-use-link-address-for-eapol-source-in-ie.patch
@@ -1,7 +1,7 @@
-From 7ec8b9cd491c09f83dfc03976fa0160f89c60eb1 Mon Sep 17 00:00:00 2001
+From 70b9d48977bb89474da6996e4ef3124dc5f4f6a9 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 19 Dec 2023 17:42:56 +0800
-Subject: [PATCH 42/61] mtk: mac80211: use link address for eapol source in
+Subject: [PATCH 48/89] mtk: mac80211: use link address for eapol source in
  ieee80211_tx_control_port()
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
-index a2ed041..e72bb7e 100644
+index 3ac51a2..9e95dbd 100644
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -6237,9 +6237,10 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+@@ -6241,9 +6241,10 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
  		 * for MLO STA, the SA should be the AP MLD address, but
  		 * the link ID has been selected already
  		 */
@@ -26,5 +26,5 @@
  
  start_xmit:
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0049-mtk-cfg80211-implement-DFS-radar-detect-for-MLO.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0049-mtk-cfg80211-implement-DFS-radar-detect-for-MLO.patch
new file mode 100644
index 0000000..1523dff
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0049-mtk-cfg80211-implement-DFS-radar-detect-for-MLO.patch
@@ -0,0 +1,151 @@
+From 78281526ce83b2623939c6060c7baf65cb5644ee Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 19 Jan 2024 14:35:17 +0800
+Subject: [PATCH 49/89] mtk: cfg80211: implement DFS radar detect for MLO
+
+Implement DFS radar detect for MLO
+1. Add link id info for radar detection in MLD
+2. Note that the radar detection flow requires channel switch, which is not yet
+complete in MLO, so postpone it.
+   (a) cac_started, cac_start_time should be moved into wdev->link, but
+channel switch will use it, so wait until channel switch is completed.
+   (b) ieee80211_dfs_cac_cancel, ieee80211_dfs_radar_detected_work, ...
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+rework radar detected flow for mlo
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h | 1 +
+ net/mac80211/main.c    | 3 +++
+ net/mac80211/pm.c      | 1 +
+ net/mac80211/util.c    | 7 ++++++-
+ net/wireless/core.c    | 4 ++--
+ net/wireless/reg.c     | 4 +++-
+ net/wireless/trace.h   | 1 +
+ 7 files changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 993b9a1..862932a 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4846,6 +4846,7 @@ struct cfg80211_ops {
+ 
+ 	int	(*start_radar_detection)(struct wiphy *wiphy,
+ 					 struct net_device *dev,
++					 unsigned int link_id,
+ 					 struct cfg80211_chan_def *chandef,
+ 					 u32 cac_time_ms, int link_id);
+ 	void	(*end_cac)(struct wiphy *wiphy,
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index ca371ef..1de7f1d 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1095,6 +1095,8 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
+ static bool
+ ieee80211_ifcomb_check(const struct ieee80211_iface_combination *c, int n_comb)
+ {
++	/* FIXME: currently skip all checks */
++#if 0
+ 	int i, j;
+ 
+ 	for (i = 0; i < n_comb; i++, c++) {
+@@ -1109,6 +1111,7 @@ ieee80211_ifcomb_check(const struct ieee80211_iface_combination *c, int n_comb)
+ 			    c->limits[j].max > 1)
+ 				return false;
+ 	}
++#endif
+ 
+ 	return true;
+ }
+diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
+index d823d58..e47c2c4 100644
+--- a/net/mac80211/pm.c
++++ b/net/mac80211/pm.c
+@@ -22,6 +22,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+ {
+ 	struct ieee80211_local *local = hw_to_local(hw);
+ 	struct ieee80211_sub_if_data *sdata;
++	struct ieee80211_chanctx *ctx;
+ 	struct sta_info *sta;
+ 
+ 	if (!local->open_count)
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 7f93739..2d2b871 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3478,6 +3478,10 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
+ 			if (!link_data)
+ 				continue;
+ 
++			if (link_data->conf->chanreq.oper.chan &&
++			    link_data->conf->chanreq.oper.chan->band != NL80211_BAND_5GHZ)
++				continue;
++
+ 			wiphy_delayed_work_cancel(local->hw.wiphy,
+ 						  &link_data->dfs_cac_timer_work);
+ 
+@@ -3515,7 +3519,8 @@ void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
+ 	INIT_LIST_HEAD(&radar_info_list);
+ 
+ 	list_for_each_entry(ctx, &local->chanctx_list, list) {
+-		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
++		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER ||
++		    !ctx->conf.def.chan || ctx->conf.def.chan->band != NL80211_BAND_5GHZ)
+ 			continue;
+ 
+ 		if (ctx->conf.radar_detected) {
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 45e2d94..51fb382 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -632,10 +632,10 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
+ 		if (WARN_ON(!c->num_different_channels))
+ 			return -EINVAL;
+ 
+-		/* DFS only works on one channel. */
++		/* DFS only works on one channel.
+ 		if (WARN_ON(c->radar_detect_widths &&
+ 			    (c->num_different_channels > 1)))
+-			return -EINVAL;
++			return -EINVAL; */
+ 
+ 		if (WARN_ON(!c->n_limits))
+ 			return -EINVAL;
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 1a393f3..39a456b 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -4246,13 +4246,15 @@ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
+ 	 */
+ 	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+ 		struct cfg80211_chan_def *chandef;
++		unsigned int link_id;
+ 
+ 		for_each_valid_link(wdev, link_id) {
+ 			if (!wdev->links[link_id].cac_started)
+ 				continue;
+ 
+ 			chandef = wdev_chandef(wdev, link_id);
+-			if (!chandef)
++			if (!chandef || !chandef->chan ||
++			    chandef->chan->band != NL80211_BAND_5GHZ)
+ 				continue;
+ 
+ 			if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef))
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index 21956c8..6ff6091 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -2677,6 +2677,7 @@ TRACE_EVENT(rdev_start_radar_detection,
+ 	TP_fast_assign(
+ 		WIPHY_ASSIGN;
+ 		NETDEV_ASSIGN;
++		__entry->link_id = link_id;
+ 		CHAN_DEF_ASSIGN(chandef);
+ 		__entry->cac_time_ms = cac_time_ms;
+ 		__entry->link_id = link_id;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0050-mtk-mac80211-add-wds-mlo-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0050-mtk-mac80211-add-wds-mlo-support.patch
new file mode 100644
index 0000000..7ef9758
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0050-mtk-mac80211-add-wds-mlo-support.patch
@@ -0,0 +1,304 @@
+From 6dd24bc475be0ba5ca1c4dfd717ac21bc2427430 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Fri, 19 Jan 2024 15:22:00 +0800
+Subject: [PATCH 50/89] mtk: mac80211: add wds mlo support
+
+Support WDS mode when using MLO.
+1. Remove use_4addr check.
+2. Copy link information to AP_VLAN interface.
+3. Fill 4addr nullfunc by mld address.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+
+1. For the MLO AP_VLAN interface, it would use the same link_data and
+bss_conf as AP interface. AP interface would maintain the bss_conf
+and link_data so AP_VLAN interface should not modify them.
+2. ieee80211_check_concurrent_iface is used to check if interface
+setting are valid so copy AP link information to AP_VLAN in
+ieee80211_do_open.
+3. Assign station's valid links to AP_VLAN's valid links so the iw
+command can show correct link information.
+4. Reassign AP_VLAN link information when AP set links.
+5. Use AP's sdata in ieee80211_sta_remove_link to prevent kernel warning
+in drv_change_sta_links.
+
+The link->reserved of the AP VLAN might be used in the following commit
+change.
+However, the link->reserved of the AP VLAN is not initialized and not
+assigned during the channel switch, so we should use the link->reserved
+of the AP instead.
+Without this fix, wds ap & sta will crash during the channel switch.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ net/mac80211/cfg.c         | 13 +++++--------
+ net/mac80211/chan.c        | 18 ++++++++++++++++--
+ net/mac80211/ieee80211_i.h |  2 ++
+ net/mac80211/iface.c       | 10 +++-------
+ net/mac80211/link.c        | 31 +++++++++++++++++++++++++++++++
+ net/mac80211/mlme.c        | 15 +++++++++------
+ net/mac80211/sta_info.c    |  7 ++++++-
+ 7 files changed, 72 insertions(+), 24 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 0b7763d..87066e1 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -222,6 +222,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
+ 
+ 	if (type == NL80211_IFTYPE_AP_VLAN && params->use_4addr == 0) {
+ 		RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
++		sdata->wdev.valid_links = 0;
+ 		ieee80211_check_fast_rx_iface(sdata);
+ 	} else if (type == NL80211_IFTYPE_STATION && params->use_4addr >= 0) {
+ 		struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+@@ -229,10 +230,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
+ 		if (params->use_4addr == ifmgd->use_4addr)
+ 			return 0;
+ 
+-		/* FIXME: no support for 4-addr MLO yet */
+-		if (ieee80211_vif_is_mld(&sdata->vif))
+-			return -EOPNOTSUPP;
+-
+ 		sdata->u.mgd.use_4addr = params->use_4addr;
+ 		if (!ifmgd->associated)
+ 			return 0;
+@@ -2211,11 +2208,14 @@ static int ieee80211_change_station(struct wiphy *wiphy,
+ 			rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
+ 			__ieee80211_check_fast_rx_iface(vlansdata);
+ 			drv_sta_set_4addr(local, sta->sdata, &sta->sta, true);
++			vlansdata->wdev.valid_links = sta->sta.valid_links;
+ 		}
+ 
+ 		if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+-		    sta->sdata->u.vlan.sta)
++		    sta->sdata->u.vlan.sta) {
+ 			RCU_INIT_POINTER(sta->sdata->u.vlan.sta, NULL);
++			sta->sdata->wdev.valid_links = 0;
++		}
+ 
+ 		if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
+ 			ieee80211_vif_dec_num_mcast(sta->sdata);
+@@ -4970,9 +4970,6 @@ static int ieee80211_add_intf_link(struct wiphy *wiphy,
+ 
+ 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
+ 
+-	if (wdev->use_4addr)
+-		return -EOPNOTSUPP;
+-
+ 	return ieee80211_vif_set_links(sdata, wdev->valid_links, 0);
+ }
+ 
+diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
+index 6041735..608ed52 100644
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -452,6 +452,16 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local,
+ 			else
+ 				new_chandef = &link_conf->chanreq.oper;
+ 
++			/* Access the reserved chanreq of the AP when it is AP VLAN */
++			if (reserved && sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
++				struct ieee80211_sub_if_data *ap;
++				struct ieee80211_link_data *ap_link;
++
++				ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
++				ap_link = rcu_dereference(ap->link[link_id]);
++				new_chandef = &ap_link->reserved.oper;
++			}
++
+ 			new_sta_bw = _ieee80211_sta_cur_vht_bw(link_sta,
+ 							       new_chandef);
+ 
+@@ -1015,7 +1025,8 @@ __ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link,
+ 	struct ieee80211_sub_if_data *vlan;
+ 	struct ieee80211_chanctx_conf *conf;
+ 
+-	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
++	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP) ||
++	    ieee80211_vif_is_mld(&sdata->vif))
+ 		return;
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+@@ -1271,7 +1282,7 @@ ieee80211_link_update_chanreq(struct ieee80211_link_data *link,
+ 
+ 	link->conf->chanreq = *chanreq;
+ 
+-	if (sdata->vif.type != NL80211_IFTYPE_AP)
++	if (sdata->vif.type != NL80211_IFTYPE_AP || ieee80211_vif_is_mld(&sdata->vif))
+ 		return;
+ 
+ 	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
+@@ -2118,6 +2129,9 @@ void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link)
+ 
+ 	ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
+ 
++	if (ieee80211_vif_is_mld(&ap->vif))
++		return;
++
+ 	ap_conf = wiphy_dereference(local->hw.wiphy,
+ 				    ap->vif.link_conf[link_id]);
+ 	conf = wiphy_dereference(local->hw.wiphy,
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index bea5058..d18f049 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -2065,6 +2065,8 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
+ void ieee80211_link_stop(struct ieee80211_link_data *link);
+ int ieee80211_vif_set_links(struct ieee80211_sub_if_data *sdata,
+ 			    u16 new_links, u16 dormant_links);
++void __ieee80211_copy_links_to_vlan(struct ieee80211_sub_if_data *vlan,
++				    struct ieee80211_sub_if_data *ap);
+ static inline void ieee80211_vif_clear_links(struct ieee80211_sub_if_data *sdata)
+ {
+ 	ieee80211_vif_set_links(sdata, 0, 0);
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index c454826..9b95230 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -381,13 +381,6 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
+ 							nsdata->vif.type))
+ 				return -ENOTUNIQ;
+ 
+-			/* No support for VLAN with MLO yet */
+-			if (iftype == NL80211_IFTYPE_AP_VLAN &&
+-			    sdata->wdev.use_4addr &&
+-			    nsdata->vif.type == NL80211_IFTYPE_AP &&
+-			    nsdata->vif.valid_links)
+-				return -EOPNOTSUPP;
+-
+ 			/*
+ 			 * can only add VLANs to enabled APs
+ 			 */
+@@ -1266,6 +1259,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
+ 		       sizeof(sdata->vif.hw_queue));
+ 		sdata->vif.bss_conf.chanreq = master->vif.bss_conf.chanreq;
+ 
++		if (ieee80211_vif_is_mld(&master->vif))
++			__ieee80211_copy_links_to_vlan(sdata, master);
++
+ 		sdata->crypto_tx_tailroom_needed_cnt +=
+ 			master->crypto_tx_tailroom_needed_cnt;
+ 
+diff --git a/net/mac80211/link.c b/net/mac80211/link.c
+index f77dab2..11502da 100644
+--- a/net/mac80211/link.c
++++ b/net/mac80211/link.c
+@@ -306,6 +306,36 @@ deinit:
+ 	return ret;
+ }
+ 
++void __ieee80211_copy_links_to_vlan(struct ieee80211_sub_if_data *vlan,
++				    struct ieee80211_sub_if_data *ap)
++{
++	int i;
++
++	vlan->vif.valid_links = ap->vif.valid_links;
++	vlan->vif.active_links = ap->vif.active_links;
++	vlan->vif.dormant_links = ap->vif.dormant_links;
++	memcpy(vlan->wdev.links, ap->wdev.links, sizeof(vlan->wdev.links));
++
++	for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
++		rcu_assign_pointer(vlan->link[i], ap->link[i]);
++		rcu_assign_pointer(vlan->vif.link_conf[i], ap->vif.link_conf[i]);
++	}
++}
++
++static void ieee80211_copy_links_to_vlan(struct ieee80211_sub_if_data *sdata)
++{
++	struct ieee80211_sub_if_data *vlan;
++
++	if (sdata->vif.type != NL80211_IFTYPE_AP || !ieee80211_vif_is_mld(&sdata->vif))
++		return;
++
++	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
++		__ieee80211_copy_links_to_vlan(vlan, sdata);
++		/* Todo: modify it when reconfiguration */
++		vlan->wdev.valid_links &= sdata->wdev.valid_links;
++	}
++}
++
+ int ieee80211_vif_set_links(struct ieee80211_sub_if_data *sdata,
+ 			    u16 new_links, u16 dormant_links)
+ {
+@@ -314,6 +344,7 @@ int ieee80211_vif_set_links(struct ieee80211_sub_if_data *sdata,
+ 
+ 	ret = ieee80211_vif_update_links(sdata, links, new_links,
+ 					 dormant_links);
++	ieee80211_copy_links_to_vlan(sdata);
+ 	ieee80211_free_links(sdata, links);
+ 
+ 	return ret;
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index ebd4d74..c7d08fb 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -2047,6 +2047,7 @@ void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
+ {
+ 	struct sk_buff *skb;
+ 	struct ieee80211_hdr *nullfunc;
++	u8 assoc_link_id = ifmgd->assoc_data->assoc_link_id;
+ 	__le16 fc;
+ 
+ 	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
+@@ -2062,11 +2063,17 @@ void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
+ 	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+ 			 IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
+ 	nullfunc->frame_control = fc;
+-	memcpy(nullfunc->addr1, sdata->deflink.u.mgd.bssid, ETH_ALEN);
+ 	memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
+-	memcpy(nullfunc->addr3, sdata->deflink.u.mgd.bssid, ETH_ALEN);
+ 	memcpy(nullfunc->addr4, sdata->vif.addr, ETH_ALEN);
+ 
++	if (ieee80211_vif_is_mld(&sdata->vif)) {
++		memcpy(nullfunc->addr1, sdata->vif.cfg.ap_addr, ETH_ALEN);
++		memcpy(nullfunc->addr3, sdata->vif.cfg.ap_addr, ETH_ALEN);
++	} else {
++		memcpy(nullfunc->addr1, sdata->deflink.u.mgd.bssid, ETH_ALEN);
++		memcpy(nullfunc->addr3, sdata->deflink.u.mgd.bssid, ETH_ALEN);
++	}
++
+ 	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+ 	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
+ 	ieee80211_tx_skb(sdata, skb);
+@@ -8819,10 +8826,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
+ 	for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++)
+ 		size += req->links[i].elems_len;
+ 
+-	/* FIXME: no support for 4-addr MLO yet */
+-	if (sdata->u.mgd.use_4addr && req->link_id >= 0)
+-		return -EOPNOTSUPP;
+-
+ 	assoc_data = kzalloc(size, GFP_KERNEL);
+ 	if (!assoc_data)
+ 		return -ENOMEM;
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 83e98c7..57a2809 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -1275,8 +1275,10 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
+ 		drv_sta_pre_rcu_remove(local, sta->sdata, sta);
+ 
+ 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+-	    rcu_access_pointer(sdata->u.vlan.sta) == sta)
++	    rcu_access_pointer(sdata->u.vlan.sta) == sta) {
+ 		RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
++		sdata->wdev.valid_links = 0;
++	}
+ 
+ 	return 0;
+ }
+@@ -3013,6 +3015,9 @@ void ieee80211_sta_remove_link(struct sta_info *sta, unsigned int link_id)
+ 
+ 	sta->sta.valid_links &= ~BIT(link_id);
+ 
++	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && sdata->bss)
++		sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
++
+ 	if (!WARN_ON(!test_sta_flag(sta, WLAN_STA_INSERTED)))
+ 		drv_change_sta_links(sdata->local, sdata, &sta->sta,
+ 				     old_links, sta->sta.valid_links);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0045-mtk-mac80211-fix-ieee80211_probe_client-warning.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0051-mtk-mac80211-fix-ieee80211_probe_client-warning.patch
similarity index 85%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0045-mtk-mac80211-fix-ieee80211_probe_client-warning.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0051-mtk-mac80211-fix-ieee80211_probe_client-warning.patch
index 1bb036d..7514a82 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0045-mtk-mac80211-fix-ieee80211_probe_client-warning.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0051-mtk-mac80211-fix-ieee80211_probe_client-warning.patch
@@ -1,7 +1,7 @@
-From 65e5845ce53a6060cb3201a7dcae96b57eb2ea45 Mon Sep 17 00:00:00 2001
+From 0a76f35b9b5cbd42f5b7a6d5fafb19d787a14e1d Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Mon, 29 Jan 2024 18:37:15 +0800
-Subject: [PATCH 45/61] mtk: mac80211: fix ieee80211_probe_client warning
+Subject: [PATCH 51/89] mtk: mac80211: fix ieee80211_probe_client warning
 
 Only get chanctx for non-mld VIF.
 
@@ -11,7 +11,7 @@
  1 file changed, 6 insertions(+), 4 deletions(-)
 
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 0cb68fb..6e3b28e 100644
+index 87066e1..e7c0d24 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
 @@ -4211,11 +4211,13 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0046-mtk-mac80211-remove-link-0-warn-on-in-rate_control_r.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0052-mtk-mac80211-remove-link-0-warn-on-in-rate_control_r.patch
similarity index 87%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0046-mtk-mac80211-remove-link-0-warn-on-in-rate_control_r.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0052-mtk-mac80211-remove-link-0-warn-on-in-rate_control_r.patch
index 94b0038..5711846 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0046-mtk-mac80211-remove-link-0-warn-on-in-rate_control_r.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0052-mtk-mac80211-remove-link-0-warn-on-in-rate_control_r.patch
@@ -1,7 +1,7 @@
-From 5ec53c93f1361412ff263a1bf8eb38c18e447d4a Mon Sep 17 00:00:00 2001
+From 07204d9541bd6b6eff3b77d7698bf406e546d267 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 31 Jan 2024 11:40:28 +0800
-Subject: [PATCH 46/61] mtk: mac80211: remove link != 0 warn on in
+Subject: [PATCH 52/89] mtk: mac80211: remove link != 0 warn on in
  rate_control_rate_update for mlo channel switch
 
 Remove link warning for mlo channel switch
@@ -12,7 +12,7 @@
  1 file changed, 8 insertions(+), 2 deletions(-)
 
 diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
-index bbdd3b8..8f54562 100644
+index 7c31a3c..c287576 100644
 --- a/net/mac80211/rate.c
 +++ b/net/mac80211/rate.c
 @@ -100,13 +100,19 @@ void rate_control_rate_update(struct ieee80211_local *local,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0047-mtk-mac80211-fix-radar-required-of-link-issue-in-res.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0053-mtk-mac80211-fix-radar-required-of-link-issue-in-res.patch
similarity index 77%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0047-mtk-mac80211-fix-radar-required-of-link-issue-in-res.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0053-mtk-mac80211-fix-radar-required-of-link-issue-in-res.patch
index d79d929..680e21c 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0047-mtk-mac80211-fix-radar-required-of-link-issue-in-res.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0053-mtk-mac80211-fix-radar-required-of-link-issue-in-res.patch
@@ -1,7 +1,7 @@
-From f5a7e57bca203a7d063faf0b9b54b4da8c42f884 Mon Sep 17 00:00:00 2001
+From 19524840c953100d64d44763576b75a30377f3bf Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 1 Feb 2024 17:46:49 +0800
-Subject: [PATCH 47/61] mtk: mac80211: fix radar required of link issue in
+Subject: [PATCH 53/89] mtk: mac80211: fix radar required of link issue in
  reserve_reassign and reserve_assign
 
 link->radar_required is not updated in
@@ -15,10 +15,10 @@
  1 file changed, 2 insertions(+)
 
 diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
-index 8043d1d..ac22524 100644
+index 608ed52..bdff227 100644
 --- a/net/mac80211/chan.c
 +++ b/net/mac80211/chan.c
-@@ -1207,6 +1207,7 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
+@@ -1337,6 +1337,7 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
  	if (link_conf->chanreq.oper.width != link->reserved.oper.width)
  		changed = BSS_CHANGED_BANDWIDTH;
  
@@ -26,12 +26,12 @@
  	ieee80211_link_update_chanreq(link, &link->reserved);
  
  	_ieee80211_change_chanctx(local, new_ctx, old_ctx, chanreq, link);
-@@ -1290,6 +1291,7 @@ ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link)
+@@ -1418,6 +1419,7 @@ ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link)
  	list_del(&link->reserved_chanctx_list);
  	link->reserved_chanctx = NULL;
  
 +	link->radar_required = link->reserved_radar_required;
- 	err = ieee80211_assign_link_chanctx(link, new_ctx);
+ 	err = ieee80211_assign_link_chanctx(link, new_ctx, false);
  	if (err) {
  		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
 -- 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0053-mtk-mac80211-workaround-for-configuring-txpower-in-m.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0053-mtk-mac80211-workaround-for-configuring-txpower-in-m.patch
deleted file mode 100644
index 40da0b4..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0053-mtk-mac80211-workaround-for-configuring-txpower-in-m.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-From 23f6000da41a1c393b3c2e85554e6c8da4d728a2 Mon Sep 17 00:00:00 2001
-From: Allen Ye <allen.ye@mediatek.com>
-Date: Thu, 22 Feb 2024 15:21:49 +0800
-Subject: [PATCH 53/61] mtk: mac80211: workaround for configuring txpower in
- mld ap
-
-As for mt76 design, we expect to set txpower per link. So, we add
-another parameter to ieee80211_recalc_txpower function to set
-txpower to per link. For the functions that mac80211 don't pass link
-id to which, we specify to use the FIRST link as the parameter.
-
-Apply the patch will make uci and iw set txpower commamd only effect
-the link which id is 0 when we enable mld AP.
-
----
- net/mac80211/cfg.c         | 15 ++++++++++++---
- net/mac80211/chan.c        |  4 ++--
- net/mac80211/ieee80211_i.h |  5 +++--
- net/mac80211/iface.c       | 15 ++++++++-------
- net/mac80211/mlme.c        |  2 +-
- 5 files changed, 26 insertions(+), 15 deletions(-)
-
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index c3b9d10..cca3e08 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -3059,7 +3059,11 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
- 			sdata->vif.bss_conf.txpower_type = txp_type;
- 		}
- 
--		ieee80211_recalc_txpower(sdata, update_txp_type);
-+		/* Due to mac80211 not pass link id to here, use first link for now */
-+		if (ieee80211_vif_is_mld(&sdata->vif))
-+			ieee80211_recalc_txpower(sdata, update_txp_type, sdata->link[0]);
-+		else
-+			ieee80211_recalc_txpower(sdata, update_txp_type, &sdata->deflink);
- 
- 		return 0;
- 	}
-@@ -3090,7 +3094,12 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
- 	list_for_each_entry(sdata, &local->interfaces, list) {
- 		if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
- 			continue;
--		ieee80211_recalc_txpower(sdata, update_txp_type);
-+		/* Due to mac80211 not pass link id to here, use first link for now */
-+		if (ieee80211_vif_is_mld(&sdata->vif))
-+			ieee80211_recalc_txpower(sdata, update_txp_type, sdata->link[0]);
-+		else
-+			ieee80211_recalc_txpower(sdata, update_txp_type, &sdata->deflink);
-+
- 	}
- 
- 	if (has_monitor) {
-@@ -3102,7 +3111,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
- 				update_txp_type = true;
- 			sdata->vif.bss_conf.txpower_type = txp_type;
- 
--			ieee80211_recalc_txpower(sdata, update_txp_type);
-+			ieee80211_recalc_txpower(sdata, update_txp_type, &sdata->deflink);
- 		}
- 	}
- 
-diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
-index ac22524..f09cac4 100644
---- a/net/mac80211/chan.c
-+++ b/net/mac80211/chan.c
-@@ -842,7 +842,7 @@ out:
- 	}
- 
- 	if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
--		ieee80211_recalc_txpower(sdata, false);
-+		ieee80211_recalc_txpower(sdata, false, link);
- 		ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL);
- 	}
- 
-@@ -1570,7 +1570,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
- 								  link,
- 								  changed);
- 
--			ieee80211_recalc_txpower(sdata, false);
-+			ieee80211_recalc_txpower(sdata, false, link);
- 		}
- 
- 		ieee80211_recalc_chanctx_chantype(local, ctx);
-diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
-index 608e442..6f1b783 100644
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -2023,9 +2023,10 @@ void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata);
- int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
- void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
- 
--bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
-+bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
-+				struct ieee80211_link_data *link);
- void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
--			      bool update_bss);
-+			      bool update_bss, struct ieee80211_link_data *link);
- void ieee80211_recalc_offload(struct ieee80211_local *local);
- 
- static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
-diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index b267b21..5070c24 100644
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -44,13 +44,14 @@
- 
- static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work);
- 
--bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
-+bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
-+				struct ieee80211_link_data *link)
- {
- 	struct ieee80211_chanctx_conf *chanctx_conf;
- 	int power;
- 
- 	rcu_read_lock();
--	chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
-+	chanctx_conf = rcu_dereference(link->conf->chanctx_conf);
- 	if (!chanctx_conf) {
- 		rcu_read_unlock();
- 		return false;
-@@ -65,8 +66,8 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
- 	if (sdata->deflink.ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
- 		power = min(power, sdata->deflink.ap_power_level);
- 
--	if (power != sdata->vif.bss_conf.txpower) {
--		sdata->vif.bss_conf.txpower = power;
-+	if (power != link->conf->txpower) {
-+		link->conf->txpower = power;
- 		ieee80211_hw_config(sdata->local, 0);
- 		return true;
- 	}
-@@ -75,11 +76,11 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
- }
- 
- void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
--			      bool update_bss)
-+			      bool update_bss, struct ieee80211_link_data *link)
- {
--	if (__ieee80211_recalc_txpower(sdata) ||
-+	if (__ieee80211_recalc_txpower(sdata, link) ||
- 	    (update_bss && ieee80211_sdata_running(sdata)))
--		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
-+		ieee80211_link_info_change_notify(sdata, link,
- 						  BSS_CHANGED_TXPOWER);
- }
- 
-diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index b9d10e9..2efd98e 100644
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -2362,7 +2362,7 @@ static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link,
- 	}
- 
- 	link->ap_power_level = new_ap_level;
--	if (__ieee80211_recalc_txpower(sdata))
-+	if (__ieee80211_recalc_txpower(sdata, link))
- 		return BSS_CHANGED_TXPOWER;
- 	return 0;
- }
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0054-mtk-cfg80211-rework-cac-started-cac-start-time-for-m.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0054-mtk-cfg80211-rework-cac-started-cac-start-time-for-m.patch
new file mode 100644
index 0000000..1abdf93
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0054-mtk-cfg80211-rework-cac-started-cac-start-time-for-m.patch
@@ -0,0 +1,176 @@
+From 0ccd5699b0f780baf72c943ea9f49d875fc199f5 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 1 Feb 2024 10:57:39 +0800
+Subject: [PATCH 54/89] mtk: cfg80211: rework cac started, cac start time for
+ multi-link support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+During wifi reload, the dfs_cac_timer_work of a link in the pre-setup CAC stage
+will not be canceled in ieee80211_stop_ap since the AP of this
+link hasn't started up yet.
+If the link exists after the dfs_cac_timer_work that failed to be canceled
+reaches its timeout, then nothing will happen.
+On the contrary, if the link is released, then a call trace will occur
+since the dfs_cac_timer_work will access protected memory space.
+This explains why this call trace appears only when we switch from the
+MLD AP config to the legacy AP config, but not when we simply reload the MLD AP.
+
+The link in the pre-setup CAC stage will be released in
+ieee80211_tear_down_links when the interface is going to be deleted.
+Therefore, this commit adds wiphy_delayed_work_cancel for
+dfs_cac_timer_work in ieee80211_link_stop and ieee80211_do_stop.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h |  1 +
+ net/mac80211/cfg.c     | 10 +++++-----
+ net/mac80211/iface.c   | 19 +++++++++++++------
+ net/mac80211/mlme.c    |  2 +-
+ net/mac80211/pm.c      |  1 -
+ net/wireless/debugfs.c | 10 ++++++----
+ net/wireless/reg.c     |  1 -
+ 7 files changed, 26 insertions(+), 18 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 862932a..a104094 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -8762,6 +8762,7 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
+ /**
+  * cfg80211_cac_event - Channel availability check (CAC) event
+  * @netdev: network device
++ * @link_id: the link ID for MLO, must be 0 for non-MLO
+  * @chandef: chandef for the current channel
+  * @event: type of event
+  * @gfp: context flags
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index e7c0d24..f98b65f 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -5108,13 +5108,13 @@ ieee80211_skip_cac(struct wireless_dev *wdev, unsigned int link_id)
+ 
+ 	wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+ 				  &link->dfs_cac_timer_work);
+-	if (wdev->cac_started) {
++	if (wdev->cac_links & BIT(link_id)) {
+ 		ieee80211_link_release_channel(link);
+-		cac_time_ms = wdev->cac_time_ms;
+-		wdev->cac_start_time = jiffies -
+-				       msecs_to_jiffies(cac_time_ms + 1);
++		cac_time_ms = wdev->links[link_id].cac_time_ms;
++		wdev->links[link_id].cac_start_time = jiffies -
++						      msecs_to_jiffies(cac_time_ms + 1);
+ 		cfg80211_cac_event(wdev->netdev, &link->conf->chanreq.oper,
+-				   NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
++				   NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, link_id);
+ 	}
+ }
+ 
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 9b95230..09bb321 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -462,6 +462,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ 	struct cfg80211_chan_def chandef;
+ 	bool cancel_scan;
+ 	struct cfg80211_nan_func *func;
++	struct ieee80211_link_data *link;
++	unsigned int link_id;
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 
+@@ -545,13 +547,18 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ 	wiphy_delayed_work_cancel(local->hw.wiphy,
+ 				  &sdata->deflink.dfs_cac_timer_work);
+ 
+-	if (sdata->wdev.links[0].cac_started) {
+-		chandef = sdata->vif.bss_conf.chanreq.oper;
++	for_each_valid_link(&sdata->wdev, link_id) {
++		link = sdata_dereference(sdata->link[link_id], sdata);
++		if (!link)
++			continue;
++		chandef = link->conf->chanreq.oper;
+ 		WARN_ON(local->suspended);
+-		ieee80211_link_release_channel(&sdata->deflink);
+-		cfg80211_cac_event(sdata->dev, &chandef,
+-				   NL80211_RADAR_CAC_ABORTED,
+-				   GFP_KERNEL, 0);
++		wiphy_delayed_work_cancel(local->hw.wiphy, &link->dfs_cac_timer_work);
++		ieee80211_link_release_channel(link);
++		if (sdata->wdev.links[link_id].cac_started)
++			cfg80211_cac_event(sdata->dev, &chandef,
++					   NL80211_RADAR_CAC_ABORTED, GFP_KERNEL,
++					   link_id);
+ 	}
+ 
+ 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index c7d08fb..13712a5 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -2608,7 +2608,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
+ 
+ 	cfg80211_sta_update_dfs_state(&sdata->wdev,
+ 				      &link->conf->chanreq.oper,
+-				      &link->csa_chanreq.oper,
++				      &link->csa.chanreq.oper,
+ 				      sdata->vif.cfg.assoc);
+ 
+ 	cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chanreq.oper,
+diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
+index e47c2c4..d823d58 100644
+--- a/net/mac80211/pm.c
++++ b/net/mac80211/pm.c
+@@ -22,7 +22,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+ {
+ 	struct ieee80211_local *local = hw_to_local(hw);
+ 	struct ieee80211_sub_if_data *sdata;
+-	struct ieee80211_chanctx *ctx;
+ 	struct sta_info *sta;
+ 
+ 	if (!local->open_count)
+diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
+index 27b4608..a0398c7 100644
+--- a/net/wireless/debugfs.c
++++ b/net/wireless/debugfs.c
+@@ -187,10 +187,11 @@ static int dfs_status_read_wdev(struct wiphy *wiphy, struct wireless_dev *wdev,
+ 				if (remain_time > wait_time_ms)
+ 					remain_time = 0;
+ 			} else if (chan->dfs_state == NL80211_DFS_USABLE) {
+-				if (wdev->cac_started &&
++				if (wdev->links[link_id].cac_started &&
+ 				    cfg80211_is_sub_chan(chandef, chan, false)) {
+-					jiffies_passed = jiffies - wdev->cac_start_time;
+-					wait_time_ms = wdev->cac_time_ms;
++					jiffies_passed = jiffies -
++							 wdev->links[link_id].cac_start_time;
++					wait_time_ms = wdev->links[link_id].cac_time_ms;
+ 					remain_time = (wait_time_ms -
+ 						       jiffies_to_msecs(jiffies_passed));
+ 				}
+@@ -336,7 +337,8 @@ dfs_cac_skip(void *data, u64 val)
+ 					continue;
+ 
+ 				if (cfg80211_chandef_dfs_required(wiphy, c, wdev->iftype) > 0 &&
+-				    cfg80211_chandef_dfs_usable(wiphy, c) && wdev->cac_started) {
++				    cfg80211_chandef_dfs_usable(wiphy, c) &&
++				    wdev->links[link_id].cac_started) {
+ 					rdev_skip_cac(rdev, wdev, link_id);
+ 				}
+ 			}
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 39a456b..9cd7fb2 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -4233,7 +4233,6 @@ EXPORT_SYMBOL(regulatory_pre_cac_allowed);
+ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
+ {
+ 	struct wireless_dev *wdev;
+-	unsigned int link_id;
+ 
+ 	/* If we finished CAC or received radar, we should end any
+ 	 * CAC running on the same channels.
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0055-mtk-mac80211-fix-mlo-BW-160-channel-switch-issue.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0055-mtk-mac80211-fix-mlo-BW-160-channel-switch-issue.patch
deleted file mode 100644
index e210794..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0055-mtk-mac80211-fix-mlo-BW-160-channel-switch-issue.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 3529be517dc9be0c911b06a1165ae80e3d051238 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 15 Mar 2024 14:34:11 +0800
-Subject: [PATCH 55/61] mtk: mac80211: fix mlo BW 160 channel switch issue
-
-The link_id argument for cfg80211_ch_switch_started_notify is missing
-after maintainer rebasing for chanreq
-The original commit has link_id instead of 0
-https://patchwork.kernel.org/project/linux-wireless/list/?series=821321&state=*
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- net/mac80211/cfg.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index cca3e08..856c956 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -4045,7 +4045,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- 	}
- 
- 	cfg80211_ch_switch_started_notify(sdata->dev,
--					  &link_data->csa_chanreq.oper, 0,
-+					  &link_data->csa_chanreq.oper, link_id,
- 					  params->count, params->block_tx);
- 
- 	if (changed) {
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0049-mtk-mac80211-remove-links-when-removing-AP_VLAN-inte.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0055-mtk-mac80211-remove-links-when-removing-AP_VLAN-inte.patch
similarity index 60%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0049-mtk-mac80211-remove-links-when-removing-AP_VLAN-inte.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0055-mtk-mac80211-remove-links-when-removing-AP_VLAN-inte.patch
index 9bbab60..ae4a70d 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0049-mtk-mac80211-remove-links-when-removing-AP_VLAN-inte.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0055-mtk-mac80211-remove-links-when-removing-AP_VLAN-inte.patch
@@ -1,7 +1,7 @@
-From c1553f36bfb1b80be2306a50d98c0a2d256725b7 Mon Sep 17 00:00:00 2001
+From 5d9b5ac643659b15be86a2ae1bdb84dabb56b762 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Tue, 6 Feb 2024 15:03:49 +0800
-Subject: [PATCH 49/61] mtk: mac80211: remove links when removing AP_VLAN
+Subject: [PATCH 55/89] mtk: mac80211: remove links when removing AP_VLAN
  interface
 
 Remove links information when removing AP_VLAN interface.
@@ -10,17 +10,16 @@
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
 ---
- net/mac80211/cfg.c   | 14 ++++++++++++++
- net/mac80211/iface.c |  4 ++--
- net/mac80211/mlme.c  |  1 -
- net/wireless/util.c  |  8 ++++++++
- 4 files changed, 24 insertions(+), 3 deletions(-)
+ net/mac80211/cfg.c  | 14 ++++++++++++++
+ net/mac80211/mlme.c |  1 -
+ net/wireless/util.c |  8 ++++++++
+ 3 files changed, 22 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 871623d..c3b9d10 100644
+index f98b65f..27afd90 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -4929,6 +4929,20 @@ static void ieee80211_del_intf_link(struct wiphy *wiphy,
+@@ -4981,6 +4981,20 @@ static void ieee80211_del_intf_link(struct wiphy *wiphy,
  {
  	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
  
@@ -41,26 +40,11 @@
  	lockdep_assert_wiphy(sdata->local->hw.wiphy);
  
  	ieee80211_vif_set_links(sdata, wdev->valid_links, 0);
-diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index be52a83..e41bf5c 100644
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -397,8 +397,8 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
- 					    sdata->link[i] == &sdata->deflink)
- 						continue;
- 
--					sdata->link[i] = nsdata->link[i];
--					sdata->vif.link_conf[i] = nsdata->vif.link_conf[i];
-+					rcu_assign_pointer(sdata->link[i], nsdata->link[i]);
-+					rcu_assign_pointer(sdata->vif.link_conf[i], nsdata->vif.link_conf[i]);
- 				}
- 			}
- 		}
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index e4564de..ebdcf57 100644
+index 13712a5..91ba00d 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
-@@ -1829,7 +1829,6 @@ void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
+@@ -2047,7 +2047,6 @@ void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
  {
  	struct sk_buff *skb;
  	struct ieee80211_hdr *nullfunc;
@@ -69,10 +53,10 @@
  
  	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
 diff --git a/net/wireless/util.c b/net/wireless/util.c
-index 2bde8a3..d03f612 100644
+index 9a7c3ad..eb2ded7 100644
 --- a/net/wireless/util.c
 +++ b/net/wireless/util.c
-@@ -2826,6 +2826,14 @@ void cfg80211_remove_links(struct wireless_dev *wdev)
+@@ -2852,6 +2852,14 @@ void cfg80211_remove_links(struct wireless_dev *wdev)
  {
  	unsigned int link_id;
  
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0056-mtk-mac80211-extend-IEEE80211_KEY_FLAG_GENERATE_MMIE.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0056-mtk-mac80211-extend-IEEE80211_KEY_FLAG_GENERATE_MMIE.patch
deleted file mode 100644
index a3cdf5e..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0056-mtk-mac80211-extend-IEEE80211_KEY_FLAG_GENERATE_MMIE.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From c2aed160872b89580f253fdfb2369e59951e3695 Mon Sep 17 00:00:00 2001
-From: Michael-CY Lee <michael-cy.lee@mediatek.com>
-Date: Thu, 21 Mar 2024 10:58:59 +0800
-Subject: [PATCH 56/61] mtk: mac80211: extend IEEE80211_KEY_FLAG_GENERATE_MMIE
- to other ciphers
-
-This commit extends the flag IEEE80211_KEY_FLAG_GENERATE_MMIE to
-CMAC-256 and GMAC for the same reason that this flag was added.
-(a0b449: mac80211: add IEEE80211_KEY_FLAG_GENERATE_MMIE to ieee80211_key_flags)
-
-Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
----
- net/mac80211/wpa.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
-index daf1bcc..e66f917 100644
---- a/net/mac80211/wpa.c
-+++ b/net/mac80211/wpa.c
-@@ -903,7 +903,8 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)
- 
- 	info = IEEE80211_SKB_CB(skb);
- 
--	if (info->control.hw_key)
-+	if (info->control.hw_key &&
-+	    !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE))
- 		return TX_CONTINUE;
- 
- 	if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
-@@ -919,6 +920,9 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)
- 
- 	bip_ipn_set64(mmie->sequence_number, pn64);
- 
-+	if (info->control.hw_key)
-+		return TX_CONTINUE;
-+
- 	bip_aad(skb, aad);
- 
- 	/* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128)
-@@ -1048,7 +1052,8 @@ ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx)
- 
- 	info = IEEE80211_SKB_CB(skb);
- 
--	if (info->control.hw_key)
-+	if (info->control.hw_key &&
-+	    !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE))
- 		return TX_CONTINUE;
- 
- 	if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
-@@ -1064,6 +1069,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx)
- 
- 	bip_ipn_set64(mmie->sequence_number, pn64);
- 
-+	if (info->control.hw_key)
-+		return TX_CONTINUE;
-+
- 	bip_aad(skb, aad);
- 
- 	hdr = (struct ieee80211_hdr *)skb->data;
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0050-mtk-mac80211-fix-AP-mgmt-not-encrypted-in-WDS-mode-w.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0056-mtk-mac80211-fix-AP-mgmt-not-encrypted-in-WDS-mode-w.patch
similarity index 81%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0050-mtk-mac80211-fix-AP-mgmt-not-encrypted-in-WDS-mode-w.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0056-mtk-mac80211-fix-AP-mgmt-not-encrypted-in-WDS-mode-w.patch
index 41f46d6..d81b7a0 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0050-mtk-mac80211-fix-AP-mgmt-not-encrypted-in-WDS-mode-w.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0056-mtk-mac80211-fix-AP-mgmt-not-encrypted-in-WDS-mode-w.patch
@@ -1,7 +1,7 @@
-From d90c8383297753b4d89012b6b5e5760e919b6503 Mon Sep 17 00:00:00 2001
+From 918df54f28978540816e00860677b87a36922c6a Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Thu, 25 Jan 2024 14:07:23 +0800
-Subject: [PATCH 50/61] mtk: mac80211: fix AP mgmt not encrypted in WDS mode
+Subject: [PATCH 56/89] mtk: mac80211: fix AP mgmt not encrypted in WDS mode
  with PMF on
 
 In ieee80211_tx_prepare(), if tx->sta is still NULL after calling
@@ -15,10 +15,10 @@
  1 file changed, 7 insertions(+)
 
 diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
-index e72bb7e..2808bc2 100644
+index 9e95dbd..00294cc 100644
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -1234,6 +1234,13 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
+@@ -1239,6 +1239,13 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
  		if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) {
  			tx->sta = sta_info_get(sdata, hdr->addr1);
  			aggr_check = true;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0051-mtk-mac80211-fix-ieee80211_ht_cap_ie_to_sta_ht_cap-w.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0057-mtk-mac80211-fix-ieee80211_ht_cap_ie_to_sta_ht_cap-w.patch
similarity index 83%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0051-mtk-mac80211-fix-ieee80211_ht_cap_ie_to_sta_ht_cap-w.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0057-mtk-mac80211-fix-ieee80211_ht_cap_ie_to_sta_ht_cap-w.patch
index 70677dd..1d5630a 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0051-mtk-mac80211-fix-ieee80211_ht_cap_ie_to_sta_ht_cap-w.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0057-mtk-mac80211-fix-ieee80211_ht_cap_ie_to_sta_ht_cap-w.patch
@@ -1,7 +1,7 @@
-From 53ca97bf26ea7ce77d2cf34b90349e08d2569326 Mon Sep 17 00:00:00 2001
+From 93932d436b0f688fb57cad5a29562f8049542c52 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 15 Feb 2024 14:30:02 +0800
-Subject: [PATCH 51/61] mtk: mac80211: fix ieee80211_ht_cap_ie_to_sta_ht_cap
+Subject: [PATCH 57/89] mtk: mac80211: fix ieee80211_ht_cap_ie_to_sta_ht_cap
  warn on
 
 Fix ieee80211_ht_cap_ie_to_sta_ht_cap warning.
@@ -15,10 +15,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index ebdcf57..b9d10e9 100644
+index 91ba00d..ae171cd 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
-@@ -4398,7 +4398,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
+@@ -4832,7 +4832,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
  	sband = local->hw.wiphy->bands[link->conf->chanreq.oper.chan->band];
  
  	/* Set up internal HT/VHT capabilities */
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0052-mtk-mac80211-fix-mac-address-to-support-hw-path-in-s.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0058-mtk-mac80211-fix-mac-address-to-support-hw-path-in-s.patch
similarity index 76%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0052-mtk-mac80211-fix-mac-address-to-support-hw-path-in-s.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0058-mtk-mac80211-fix-mac-address-to-support-hw-path-in-s.patch
index 74531ef..083b961 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0052-mtk-mac80211-fix-mac-address-to-support-hw-path-in-s.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0058-mtk-mac80211-fix-mac-address-to-support-hw-path-in-s.patch
@@ -1,7 +1,7 @@
-From 93ef1345d2859a21daf239a6c931b16e46286d59 Mon Sep 17 00:00:00 2001
+From d192caa409dcd10acb6ecfdfac5c940db6c8e264 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Fri, 16 Feb 2024 17:38:22 +0800
-Subject: [PATCH 52/61] mtk: mac80211: fix mac address to support hw path in
+Subject: [PATCH 58/89] mtk: mac80211: fix mac address to support hw path in
  station mode
 
 Use AP's MLD address instead of using deflink.
@@ -12,10 +12,10 @@
  1 file changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index e41bf5c..b267b21 100644
+index 09bb321..3936181 100644
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
-@@ -987,7 +987,10 @@ static int ieee80211_netdev_fill_forward_path(struct net_device_path_ctx *ctx,
+@@ -915,7 +915,10 @@ static int ieee80211_netdev_fill_forward_path(struct net_device_path_ctx *ctx,
  			}
  		}
  
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0054-mtk-mac80211-send-broadcast-multicast-mgmt.-via-all-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0059-mtk-mac80211-send-broadcast-multicast-mgmt.-via-all-.patch
similarity index 82%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0054-mtk-mac80211-send-broadcast-multicast-mgmt.-via-all-.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0059-mtk-mac80211-send-broadcast-multicast-mgmt.-via-all-.patch
index 26c07c3..12d35b2 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0054-mtk-mac80211-send-broadcast-multicast-mgmt.-via-all-.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0059-mtk-mac80211-send-broadcast-multicast-mgmt.-via-all-.patch
@@ -1,7 +1,7 @@
-From 06d3d93fc257b9f8cef083b9b84711fc9c3cee19 Mon Sep 17 00:00:00 2001
+From 33536ba0cdb3937796ac410303f6cb9f2efd2965 Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Wed, 21 Feb 2024 16:32:13 +0800
-Subject: [PATCH 54/61] mtk: mac80211: send broadcast/multicast mgmt. via all
+Subject: [PATCH 59/89] mtk: mac80211: send broadcast/multicast mgmt. via all
  links.
 
 This patch makes broadcast/multicast mgmt. be sent via all links.
@@ -13,10 +13,10 @@
  1 file changed, 19 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
-index 3ed5fc5..ec1d7a1 100644
+index e014f1b..520e8bf 100644
 --- a/net/mac80211/offchannel.c
 +++ b/net/mac80211/offchannel.c
-@@ -976,7 +976,25 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -1019,7 +1019,25 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
  	}
  
  	if (!need_offchan) {
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0057-mtk-wifi-mt76-mt7996-not-to-check-need_offchan-for-M.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0060-mtk-mac80211-not-to-check-need_offchan-for-MLD-multi.patch
similarity index 76%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0057-mtk-wifi-mt76-mt7996-not-to-check-need_offchan-for-M.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0060-mtk-mac80211-not-to-check-need_offchan-for-MLD-multi.patch
index 16278ac..014fca1 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0057-mtk-wifi-mt76-mt7996-not-to-check-need_offchan-for-M.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0060-mtk-mac80211-not-to-check-need_offchan-for-MLD-multi.patch
@@ -1,8 +1,8 @@
-From b311c85cdc3fe0a91d4b93628b6f559a2dfe3f5c Mon Sep 17 00:00:00 2001
+From ba7e99be3159a093c0632920b05799cd7fa269be Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Mon, 25 Mar 2024 18:59:35 +0800
-Subject: [PATCH 57/61] mtk: wifi: mt76: mt7996: not to check 'need_offchan'
- for MLD multicast mgmt.
+Subject: [PATCH 60/89] mtk: mac80211: not to check 'need_offchan' for MLD
+ multicast mgmt.
 
 Multicast mgmt. sent by the MLD AP should be transmitted via all links,
 so it is not necessary to check 'need_offchan'.
@@ -13,10 +13,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
-index ec1d7a1..a571be0 100644
+index 520e8bf..dd3ebee 100644
 --- a/net/mac80211/offchannel.c
 +++ b/net/mac80211/offchannel.c
-@@ -874,7 +874,8 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -907,7 +907,8 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
  	/* Check if the operating channel is the requested channel */
  	if (!params->chan && mlo_sta) {
  		need_offchan = false;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0058-mtk-wifi-mt76-mt7996-assign-link-address-to-the-head.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0061-mtk-mac80211-assign-link-address-to-the-header-of-br.patch
similarity index 82%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0058-mtk-wifi-mt76-mt7996-assign-link-address-to-the-head.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0061-mtk-mac80211-assign-link-address-to-the-header-of-br.patch
index 136ef38..06f48b1 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0058-mtk-wifi-mt76-mt7996-assign-link-address-to-the-head.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0061-mtk-mac80211-assign-link-address-to-the-header-of-br.patch
@@ -1,8 +1,8 @@
-From db3b035491cb7be00b1ac169863a172a5aebbacf Mon Sep 17 00:00:00 2001
+From 699ee38bca47b22ee46e560587a3a0a5630075f3 Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Mon, 25 Mar 2024 16:26:34 +0800
-Subject: [PATCH 58/61] mtk: wifi: mt76: mt7996: assign link address to the
- header of broadcast mgmt.
+Subject: [PATCH 61/89] mtk: mac80211: assign link address to the header of
+ broadcast mgmt
 
 AAD calculation should use link addr as input for broadcast mgmt. skb.
 This commit assigns link address to the header of cloned broadcast mgmt.
@@ -14,10 +14,10 @@
  1 file changed, 13 insertions(+), 3 deletions(-)
 
 diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
-index a571be0..15948f9 100644
+index dd3ebee..9e4f26a 100644
 --- a/net/mac80211/offchannel.c
 +++ b/net/mac80211/offchannel.c
-@@ -981,16 +981,26 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -1024,16 +1024,26 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
  		if (is_multicast_ether_addr(mgmt->da) && hweight16(links) > 1) {
  			unsigned int link;
  			struct sk_buff *dskb;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0061-mtk-wifi-mac80211-fix-radar-trigger-issue-due-to-ref.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0061-mtk-wifi-mac80211-fix-radar-trigger-issue-due-to-ref.patch
deleted file mode 100644
index 8e19d75..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0061-mtk-wifi-mac80211-fix-radar-trigger-issue-due-to-ref.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 017795da32681ed521917cf446ddacf5d33f649d Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Thu, 18 Apr 2024 18:08:48 +0800
-Subject: [PATCH 61/61] mtk: wifi: mac80211: fix radar trigger issue due to
- refactoring to single wiphy
-
-Since we change to single wiphy, we cannot directly return during cac cancel if the link conf in local->interfaces list is not for 5G band.
-local->interfaces might contain 2/5/6G sdata
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- net/mac80211/util.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index 732232a..d030ebc 100644
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -3469,7 +3469,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local, unsigned int link_i
- 
- 		if (link->conf->chanreq.oper.chan &&
- 		    link->conf->chanreq.oper.chan->band != NL80211_BAND_5GHZ)
--			return;
-+			continue;
- 
- 		wiphy_delayed_work_cancel(local->hw.wiphy,
- 					  &link->dfs_cac_timer_work);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0059-mtk-wifi-mt76-mt7996-Do-MLD-address-translation-befo.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0062-mtk-mac80211-Do-MLD-address-translation-before-STA-p.patch
similarity index 83%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0059-mtk-wifi-mt76-mt7996-Do-MLD-address-translation-befo.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0062-mtk-mac80211-Do-MLD-address-translation-before-STA-p.patch
index 7d99fae..8355500 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0059-mtk-wifi-mt76-mt7996-Do-MLD-address-translation-befo.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0062-mtk-mac80211-Do-MLD-address-translation-before-STA-p.patch
@@ -1,8 +1,8 @@
-From 26fc78265ac13821bb7d075be2859a1f5896f924 Mon Sep 17 00:00:00 2001
+From dadbe24860119878b5d1ff45ca8fd16d32a10919 Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Tue, 26 Mar 2024 11:36:35 +0800
-Subject: [PATCH 59/61] mtk: wifi: mt76: mt7996: Do MLD address translation
- before STA process BMC mgmt. frame
+Subject: [PATCH 62/89] mtk: mac80211: Do MLD address translation before STA
+ process BMC mgmt. frame
 
 In the function ieee80211_prepare_and_rx_handle(), BMC mgmt. frames are
 not MLD translated since the AAD calculation needs the header being link
@@ -19,10 +19,10 @@
  1 file changed, 9 insertions(+)
 
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 2efd98e..e4d5eac 100644
+index ae171cd..4d6dfd6 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
-@@ -6931,6 +6931,15 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
+@@ -7504,6 +7504,15 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
  			return;
  	}
  
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0060-mtk-wifi-mac80211-defer-enabling-beacon-for-MLD-AP.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0063-mtk-mac80211-defer-enabling-beacon-for-MLD-AP.patch
similarity index 82%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0060-mtk-wifi-mac80211-defer-enabling-beacon-for-MLD-AP.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0063-mtk-mac80211-defer-enabling-beacon-for-MLD-AP.patch
index 2dfd135..7966ae1 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0060-mtk-wifi-mac80211-defer-enabling-beacon-for-MLD-AP.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0063-mtk-mac80211-defer-enabling-beacon-for-MLD-AP.patch
@@ -1,7 +1,7 @@
-From cd576eae15b45ef97e3ee180482d2e884889fb09 Mon Sep 17 00:00:00 2001
+From 7476aaf4ab6a998ee5f3736e8db5460187777ebf Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Fri, 12 Apr 2024 11:45:41 +0800
-Subject: [PATCH 60/61] mtk: wifi: mac80211: defer enabling beacon for MLD AP
+Subject: [PATCH 63/89] mtk: mac80211: defer enabling beacon for MLD AP
 
 Do not enable beacon on the first beacon update (NL80211_CMD_NEW_BEACON)
 for MLD AP, let it start from the next beacon update
@@ -15,10 +15,10 @@
  1 file changed, 6 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 856c956..e091ccd 100644
+index 27afd90..20e48f0 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1424,7 +1424,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
+@@ -1427,7 +1427,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
  	}
  
  	link_conf->dtim_period = params->dtim_period;
@@ -27,7 +27,7 @@
  	link_conf->allow_p2p_go_ps = sdata->vif.p2p;
  	link_conf->twt_responder = params->twt_responder;
  	link_conf->he_obss_pd = params->he_obss_pd;
-@@ -1491,6 +1491,11 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
+@@ -1497,6 +1497,11 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
  	ieee80211_recalc_dtim(local, sdata);
  	ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_SSID);
  	ieee80211_link_info_change_notify(sdata, link, changed);
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0064-mtk-mac80211-prevent-STA-MLD-s-link-addr-from-being-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0064-mtk-mac80211-prevent-STA-MLD-s-link-addr-from-being-.patch
new file mode 100644
index 0000000..dbfd2de
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0064-mtk-mac80211-prevent-STA-MLD-s-link-addr-from-being-.patch
@@ -0,0 +1,57 @@
+From 3266d6c2cc19929c310361f00c4823c09a3ae8b4 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Mon, 6 May 2024 15:06:55 +0800
+Subject: [PATCH 64/89] mtk: mac80211: prevent STA MLD's link addr from being
+ randaomized
+
+STA MLD's link address should be fixed, otherwise it sends AUTH request
+via different link address every time and causes connection issues.
+
+STA MLD's link address is determined by MLD address and link_id.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ net/mac80211/mlme.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 4d6dfd6..1b19583 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -8163,11 +8163,13 @@ void ieee80211_mgd_setup_link(struct ieee80211_link_data *link)
+ 
+ 	ieee80211_clear_tpe(&link->conf->tpe);
+ 
+-	if (sdata->u.mgd.assoc_data)
++	if (sdata->u.mgd.assoc_data) {
+ 		ether_addr_copy(link->conf->addr,
+ 				sdata->u.mgd.assoc_data->link[link_id].addr);
+-	else if (!is_valid_ether_addr(link->conf->addr))
+-		eth_random_addr(link->conf->addr);
++	} else if (!is_valid_ether_addr(link->conf->addr)) {
++		ether_addr_copy(link->conf->addr, sdata->vif.addr);
++		link->conf->addr[4] += link_id + 1;
++	}
+ }
+ 
+ /* scan finished notification */
+@@ -8932,11 +8934,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
+ 			}
+ 
+ 			link = sdata_dereference(sdata->link[i], sdata);
+-			if (link)
++			if (link) {
+ 				ether_addr_copy(assoc_data->link[i].addr,
+ 						link->conf->addr);
+-			else
+-				eth_random_addr(assoc_data->link[i].addr);
++			} else {
++				ether_addr_copy(assoc_data->link[i].addr, sdata->vif.addr);
++				assoc_data->link[i].addr[4] += i + 1;
++			}
+ 			sband = local->hw.wiphy->bands[link_cbss->channel->band];
+ 
+ 			if (match_auth && i == assoc_link_id && link)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0065-mtk-mac80211-add-per-sta-prof-CSA-countdown-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0065-mtk-mac80211-add-per-sta-prof-CSA-countdown-support.patch
new file mode 100644
index 0000000..e370afa
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0065-mtk-mac80211-add-per-sta-prof-CSA-countdown-support.patch
@@ -0,0 +1,242 @@
+From 462379a27140857e77f4fe1131d6f2856e394f08 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 9 Apr 2024 11:01:51 +0800
+Subject: [PATCH 65/89] mtk: mac80211: add per-sta prof CSA countdown support
+
+Add CSA/eCSA offset of per-sta profile
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h       |  6 ++++++
+ include/net/mac80211.h       |  4 ++++
+ include/uapi/linux/nl80211.h |  8 ++++++++
+ net/mac80211/cfg.c           | 27 +++++++++++++++++----------
+ net/mac80211/ieee80211_i.h   |  3 +++
+ net/mac80211/tx.c            |  8 +++++---
+ net/wireless/nl80211.c       | 13 ++++++++++++-
+ 7 files changed, 55 insertions(+), 14 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index a104094..4dde28b 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -1555,8 +1555,12 @@ struct cfg80211_ap_update {
+  * @beacon_csa: beacon data while performing the switch
+  * @counter_offsets_beacon: offsets of the counters within the beacon (tail)
+  * @counter_offsets_presp: offsets of the counters within the probe response
++ * @counter_offsets_sta_prof: offsets of the counters within the per-STA profile
++ *	corresponding to the channel switch link
+  * @n_counter_offsets_beacon: number of csa counters the beacon (tail)
+  * @n_counter_offsets_presp: number of csa counters in the probe response
++ * @n_counter_offsets_sta_prof: number of csa counters in the per-STA profile
++ *	corresponding to the channel switch link
+  * @beacon_after: beacon data to be used on the new channel
+  * @radar_required: whether radar detection is required on the new channel
+  * @block_tx: whether transmissions should be blocked while changing
+@@ -1569,8 +1573,10 @@ struct cfg80211_csa_settings {
+ 	struct cfg80211_beacon_data beacon_csa;
+ 	const u16 *counter_offsets_beacon;
+ 	const u16 *counter_offsets_presp;
++	const u16 *counter_offsets_sta_prof;
+ 	unsigned int n_counter_offsets_beacon;
+ 	unsigned int n_counter_offsets_presp;
++	unsigned int n_counter_offsets_sta_prof;
+ 	struct cfg80211_beacon_data beacon_after;
+ 	bool radar_required;
+ 	bool block_tx;
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 5321c22..9e03302 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -5487,6 +5487,9 @@ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets);
+  * @cntdwn_counter_offs: array of IEEE80211_MAX_CNTDWN_COUNTERS_NUM offsets
+  *	to countdown counters.  This array can contain zero values which
+  *	should be ignored.
++ * @sta_prof_cntdwn_offs: array of IEEE80211_MAX_CNTDWN_COUNTERS_NUM offsets
++ *	to countdown counters in per-STA profile.
++ *	This array can contain zero values which should be ignored.
+  * @mbssid_off: position of the multiple bssid element
+  */
+ struct ieee80211_mutable_offsets {
+@@ -5494,6 +5497,7 @@ struct ieee80211_mutable_offsets {
+ 	u16 tim_length;
+ 
+ 	u16 cntdwn_counter_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM];
++	u16 sta_prof_cntdwn_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM];
+ 	u16 mbssid_off;
+ };
+ 
+diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
+index 257528d..6a2291d 100644
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -2868,6 +2868,10 @@ enum nl80211_commands {
+  *	nested item, it contains attributes defined in
+  *	&enum nl80211_if_combination_attrs.
+  *
++ * @NL80211_ATTR_CNTDWN_OFFS_STA_PROF: An array of offsets (u16) to the channel
++ *	switch or color change counters in the per-STA profile corresponding to
++ *	the affected AP.
++ *
+  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
+  * @NL80211_ATTR_MAX: highest attribute number currently defined
+  * @__NL80211_ATTR_AFTER_LAST: internal use
+@@ -3418,6 +3422,9 @@ enum nl80211_attrs {
+ 
+ 	/* add attributes here, update the policy in nl80211.c */
+ 
++	/* MTK internal */
++	NL80211_ATTR_CNTDWN_OFFS_STA_PROF,
++
+ 	__NL80211_ATTR_AFTER_LAST,
+ 	NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
+ 	NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
+@@ -3430,6 +3437,7 @@ enum nl80211_attrs {
+ #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
++#define NL80211_ATTR_CSA_C_OFF_STA_PROF NL80211_ATTR_CNTDWN_OFFS_STA_PROF
+ 
+ /*
+  * Allow user space programs to use #ifdef on new attributes by defining them
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 20e48f0..28c35ad 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1182,6 +1182,9 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+ 		memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_beacon,
+ 		       csa->n_counter_offsets_beacon *
+ 		       sizeof(new->cntdwn_counter_offsets[0]));
++		memcpy(new->sta_prof_cntdwn_offs, csa->counter_offsets_sta_prof,
++		       csa->n_counter_offsets_sta_prof *
++		       sizeof(new->sta_prof_cntdwn_offs[0]));
+ 	} else if (cca) {
+ 		new->cntdwn_current_counter = cca->count;
+ 		new->cntdwn_counter_offsets[0] = cca->counter_offset_beacon;
+@@ -3847,8 +3850,10 @@ static int ieee80211_set_csa_beacon(struct ieee80211_link_data *link_data,
+ 
+ 		csa.counter_offsets_beacon = params->counter_offsets_beacon;
+ 		csa.counter_offsets_presp = params->counter_offsets_presp;
++		csa.counter_offsets_sta_prof = params->counter_offsets_sta_prof;
+ 		csa.n_counter_offsets_beacon = params->n_counter_offsets_beacon;
+ 		csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
++		csa.n_counter_offsets_sta_prof = params->n_counter_offsets_sta_prof;
+ 		csa.count = params->count;
+ 
+ 		err = ieee80211_assign_beacon(sdata, link_data,
+@@ -4011,17 +4016,19 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ 	if (err)
+ 		goto out;
+ 
+-	err = ieee80211_link_reserve_chanctx(link_data, &chanreq,
+-					     chanctx->mode,
+-					     params->radar_required);
+-	if (err)
+-		goto out;
++	if (!cfg80211_chandef_identical(&conf->def, &chanreq.oper)) {
++		err = ieee80211_link_reserve_chanctx(link_data, &chanreq,
++						     chanctx->mode,
++						     params->radar_required);
++		if (err)
++			goto out;
+ 
+-	/* if reservation is invalid then this will fail */
+-	err = ieee80211_check_combinations(sdata, NULL, chanctx->mode, 0, -1);
+-	if (err) {
+-		ieee80211_link_unreserve_chanctx(link_data);
+-		goto out;
++		/* if reservation is invalid then this will fail */
++		err = ieee80211_check_combinations(sdata, NULL, chanctx->mode, 0, -1);
++		if (err) {
++			ieee80211_link_unreserve_chanctx(link_data);
++			goto out;
++		}
+ 	}
+ 
+ 	/* if there is a color change in progress, abort it */
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index d18f049..a5c0d6c 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -261,9 +261,11 @@ struct ieee80211_rx_data {
+ struct ieee80211_csa_settings {
+ 	const u16 *counter_offsets_beacon;
+ 	const u16 *counter_offsets_presp;
++	const u16 *counter_offsets_sta_prof;
+ 
+ 	int n_counter_offsets_beacon;
+ 	int n_counter_offsets_presp;
++	int n_counter_offsets_sta_prof;
+ 
+ 	u8 count;
+ };
+@@ -280,6 +282,7 @@ struct beacon_data {
+ 	struct ieee80211_meshconf_ie *meshconf;
+ 	u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM];
+ 	u8 cntdwn_current_counter;
++	u16 sta_prof_cntdwn_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM];
+ 	struct cfg80211_mbssid_elems *mbssid_ies;
+ 	struct cfg80211_rnr_elems *rnr_ies;
+ 	struct rcu_head rcu_head;
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 00294cc..ebe3ae2 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -5241,11 +5241,13 @@ ieee80211_beacon_get_finish(struct ieee80211_hw *hw,
+ 
+ 		for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; i++) {
+ 			u16 csa_off = beacon->cntdwn_counter_offsets[i];
++			u16 sta_prof_csa_off = beacon->sta_prof_cntdwn_offs[i];
+ 
+-			if (!csa_off)
+-				continue;
++			if (csa_off)
++				offs->cntdwn_counter_offs[i] = csa_off_base + csa_off;
+ 
+-			offs->cntdwn_counter_offs[i] = csa_off_base + csa_off;
++			if (sta_prof_csa_off)
++				offs->sta_prof_cntdwn_offs[i] = csa_off_base + sta_prof_csa_off;
+ 		}
+ 	}
+ 
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index d4e7ed8..b6f8fc1 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -862,6 +862,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
+ 	[NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
+ 	[NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
++	[NL80211_ATTR_CNTDWN_OFFS_STA_PROF] = { .type = NLA_BINARY },
+ };
+ 
+ /* policy for the key attributes */
+@@ -10393,7 +10394,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
+ 	if (err)
+ 		goto free;
+ 
+-	if (!csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
++	if (!csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON] &&
++	    !csa_attrs[NL80211_ATTR_CNTDWN_OFFS_STA_PROF]) {
+ 		err = -EINVAL;
+ 		goto free;
+ 	}
+@@ -10416,6 +10418,15 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
+ 	if (err)
+ 		goto free;
+ 
++	err = nl80211_parse_counter_offsets(rdev, params.beacon_csa.tail,
++					    params.beacon_csa.tail_len,
++					    params.count,
++					    csa_attrs[NL80211_ATTR_CNTDWN_OFFS_STA_PROF],
++					    &params.counter_offsets_sta_prof,
++					    &params.n_counter_offsets_sta_prof);
++	if (err)
++		goto free;
++
+ skip_beacons:
+ 	err = nl80211_parse_chandef(rdev, info, &params.chandef);
+ 	if (err)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0066-mtk-mac80211-Add-support-for-EMLSR-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0066-mtk-mac80211-Add-support-for-EMLSR-support.patch
new file mode 100644
index 0000000..3bf6b3f
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0066-mtk-mac80211-Add-support-for-EMLSR-support.patch
@@ -0,0 +1,81 @@
+From 077f0bdcee690c198def8700b38e70fd5e63c6ff Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+Date: Mon, 29 Apr 2024 10:20:07 +0800
+Subject: [PATCH 66/89] mtk: mac80211: Add support for EMLSR support
+
+Send the EML capability to driver
+Specify the time for eml_capa in advance to avoid the driver setting
+padding delay and transition delay without having obtained the correct
+values.
+
+Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+---
+ include/net/cfg80211.h | 1 +
+ include/net/mac80211.h | 1 +
+ net/mac80211/cfg.c     | 3 +++
+ net/wireless/nl80211.c | 4 ++++
+ 4 files changed, 9 insertions(+)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 4dde28b..8ce51d2 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -1797,6 +1797,7 @@ struct station_parameters {
+ 	u8 supported_oper_classes_len;
+ 	int support_p2p_ps;
+ 	u16 airtime_weight;
++	u16 eml_capa;
+ 	struct link_station_parameters link_sta_params;
+ };
+ 
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 9e03302..5cd9432 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -2507,6 +2507,7 @@ struct ieee80211_sta {
+ 	bool mlo;
+ 	bool spp_amsdu;
+ 	u8 max_amsdu_subframes;
++	u16 eml_capa;
+ 
+ 	struct ieee80211_sta_aggregates *cur;
+ 
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 28c35ad..8eb9800 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -2044,6 +2044,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
+ 	if (ret)
+ 		return ret;
+ 
++	if (params->eml_capa)
++		sta->sta.eml_capa = params->eml_capa;
++
+ 	if (params->support_p2p_ps >= 0)
+ 		sta->sta.support_p2p_ps = params->support_p2p_ps;
+ 
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index b6f8fc1..ea251a9 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -861,6 +861,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
+ 	[NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
++	[NL80211_ATTR_EML_CAPABILITY] = { .type = NLA_U16 },
+ 	[NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_CNTDWN_OFFS_STA_PROF] = { .type = NLA_BINARY },
+ };
+@@ -7432,6 +7433,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
+ 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ 	}
+ 
++	if (info->attrs[NL80211_ATTR_EML_CAPABILITY])
++		params.eml_capa =
++			nla_get_u16(info->attrs[NL80211_ATTR_EML_CAPABILITY]);
+ 
+ 	if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
+ 		params.link_sta_params.supported_rates =
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0067-mtk-mac80211-set-max_amsdu_len-for-link_sta.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0067-mtk-mac80211-set-max_amsdu_len-for-link_sta.patch
new file mode 100644
index 0000000..b1a8084
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0067-mtk-mac80211-set-max_amsdu_len-for-link_sta.patch
@@ -0,0 +1,42 @@
+From f2be5c5dc8ca3f2fb9b195a16d5717abc5dba797 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Thu, 9 May 2024 11:10:43 +0800
+Subject: [PATCH 67/89] mtk: mac80211: set max_amsdu_len for link_sta
+
+Get station's max mpdu length from eht cap and compare with AP's
+capability. Update agg.max_amsdu_len in link_sta for driver can
+get correct max mpdu length.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ net/mac80211/eht.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/net/mac80211/eht.c b/net/mac80211/eht.c
+index ddc7acc..020a035 100644
+--- a/net/mac80211/eht.c
++++ b/net/mac80211/eht.c
+@@ -75,4 +75,20 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata,
+ 
+ 	link_sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(link_sta);
+ 	link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta);
++
++	switch (u8_get_bits(eht_cap->eht_cap_elem.mac_cap_info[0],
++			    IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK)) {
++	case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454:
++		link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454;
++		break;
++	case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991:
++		link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_7991;
++		break;
++	case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_3895:
++	default:
++		link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_3895;
++		break;
++	}
++
++	ieee80211_sta_recalc_aggregates(&link_sta->sta->sta);
+ }
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0068-mtk-mac80211-legacy-AP-scan-request-should-contain-v.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0068-mtk-mac80211-legacy-AP-scan-request-should-contain-v.patch
new file mode 100644
index 0000000..c77d97d
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0068-mtk-mac80211-legacy-AP-scan-request-should-contain-v.patch
@@ -0,0 +1,65 @@
+From aaa8ad411db97a885da1d3a7f925df38df294f75 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Thu, 9 May 2024 09:24:43 +0800
+Subject: [PATCH 68/89] mtk: mac80211: legacy AP scan request should contain
+ valid channels
+
+In single-wiphy, if scan_freqs is not specified in scan request,
+mac80211 will trigger a scan that includes all bands.
+However, legacy AP should only scan the channels of its operating band.
+
+This commit adds the checks for including valid channels in legacy AP
+scan.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+
+preset_chandef is only set on the first wdev of each phy, so we refer to
+another data structure for the band of current wdev.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ net/wireless/nl80211.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index ea251a9..cb14460 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -9382,6 +9382,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
+ 		n_channels = validate_scan_freqs(scan_freqs);
+ 		if (!n_channels)
+ 			return -EINVAL;
++	} else if (wdev->iftype == NL80211_IFTYPE_AP && !wdev->valid_links) {
++		struct ieee80211_channel *chan = wdev->links[0].ap.chandef.chan;
++		if (!chan || !wiphy->bands[chan->band])
++			return -EINVAL;
++
++		n_channels = wiphy->bands[chan->band]->n_channels;
+ 	} else {
+ 		n_channels = ieee80211_get_num_supported_channels(wiphy);
+ 	}
+@@ -9434,6 +9440,21 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
+ 			}
+ 
+ 			/* ignore disabled channels */
++			if (chan->flags & IEEE80211_CHAN_DISABLED)
++				continue;
++
++			request->channels[i] = chan;
++			i++;
++		}
++	} else if (wdev->iftype == NL80211_IFTYPE_AP && !wdev->valid_links) {
++		enum nl80211_band band = wdev->links[0].ap.chandef.chan->band;
++		int j;
++
++		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
++			struct ieee80211_channel *chan;
++
++			chan = &wiphy->bands[band]->channels[j];
++
+ 			if (chan->flags & IEEE80211_CHAN_DISABLED)
+ 				continue;
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0069-mtk-mac80211-do-not-check-pre-CAC-allowed-for-scan.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0069-mtk-mac80211-do-not-check-pre-CAC-allowed-for-scan.patch
new file mode 100644
index 0000000..ae16703
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0069-mtk-mac80211-do-not-check-pre-CAC-allowed-for-scan.patch
@@ -0,0 +1,32 @@
+From 91cc054d85812aad1a3203f7a009b1b2083df074 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Fri, 10 May 2024 13:14:43 +0800
+Subject: [PATCH 69/89] mtk: mac80211: do not check pre-CAC allowed for scan
+
+When scanning, interfaces only leave the channels in a very short time,
+which can be tolerated. Therefore we do not check pre-CAC allowed for
+scan.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ net/mac80211/scan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
+index 0b8d69f..c6dcffa 100644
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -582,8 +582,10 @@ static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata)
+ 	if (!ieee80211_is_radar_required(local))
+ 		return true;
+ 
++	/* FIXME do not check pre-CAC allowed for scan.
+ 	if (!regulatory_pre_cac_allowed(local->hw.wiphy))
+ 		return false;
++	*/
+ 
+ 	list_for_each_entry(sdata_iter, &local->interfaces, list) {
+ 		for_each_valid_link(&sdata_iter->wdev, link_id)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0070-mtk-mac80211-add-mlo-probe-client-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0070-mtk-mac80211-add-mlo-probe-client-support.patch
new file mode 100644
index 0000000..877730e
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0070-mtk-mac80211-add-mlo-probe-client-support.patch
@@ -0,0 +1,39 @@
+From 997603fb7f8335d007430e2682cc3db7ee5bcae5 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 15 May 2024 11:25:19 +0800
+Subject: [PATCH 70/89] mtk: mac80211: add mlo probe client support
+
+Add link unspec for mld case; otherwise it would be link 0
+instead of primary link
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Send the null func in min rate.
+Without this patch, the null data frame will fail to tx in both legacy
+AP and MLD AP.
+(appears in ICS log but not in air).
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ net/mac80211/cfg.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 8eb9800..c52cde0 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -4266,7 +4266,10 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
+ 	info = IEEE80211_SKB_CB(skb);
+ 
+ 	info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
+-		       IEEE80211_TX_INTFL_NL80211_FRAME_TX;
++		       IEEE80211_TX_INTFL_NL80211_FRAME_TX |
++		       IEEE80211_TX_CTL_USE_MINRATE;
++	if (ieee80211_vif_is_mld(&sdata->vif))
++		info->control.flags |= IEEE80211_TX_CTRL_MLO_LINK_UNSPEC;
+ 	info->band = band;
+ 
+ 	skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0071-mtk-mac80211-rework-radar-notify-for-MLO.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0071-mtk-mac80211-rework-radar-notify-for-MLO.patch
new file mode 100644
index 0000000..05e2de2
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0071-mtk-mac80211-rework-radar-notify-for-MLO.patch
@@ -0,0 +1,322 @@
+From 4cbed3e79fa9c53deaa251254a21650a7fe6dcb0 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Mon, 27 May 2024 13:23:59 +0800
+Subject: [PATCH 71/89] mtk: mac80211: rework radar notify for MLO
+
+Rework radar notify for MLO.
+A netdev/wdev containing 5G link is required for all radar events since
+userspace daemon will only process the event with the first netdev
+(might not include 5G links) if netdev/wdev is not specified.
+For instance, the radar event will be ignored in the following
+configuration.
+wdev 1: MLD AP (2+6G)
+wdev 2: MLD AP (2+5+6G)
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+There is a chance that the DFS pre-CAC check, triggered by a non-5G interface,
+is executed during the switching time of 5G interfaces.
+In this case, cfg80211_any_wiphy_oper_chan of target channel  will return 0,
+as the 5G interface is not yet operating on the target channel.
+Therefore, a pre-CAC expired event of the target channel will be issued to hostapd.
+This causes the AP to re-CAC the target channel after switching to it,
+which usually occurs after background radar CAC is completed.
+
+=> Avoid scheduling dfs channel update work for non-5G link.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h | 20 ++++++++++++++++++++
+ net/wireless/chan.c    | 42 ++++++++++++++----------------------------
+ net/wireless/mlme.c    | 15 +++++----------
+ net/wireless/nl80211.c | 34 +++++++++++++++++++++-------------
+ net/wireless/nl80211.h |  3 +--
+ net/wireless/reg.c     |  2 +-
+ 6 files changed, 62 insertions(+), 54 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 8ce51d2..5de1d1c 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6411,6 +6411,26 @@ static inline void WARN_INVALID_LINK_ID(struct wireless_dev *wdev,
+ 		if (!(link_info)->valid_links ||		\
+ 		    ((link_info)->valid_links & BIT(link_id)))
+ 
++static inline struct wireless_dev *
++wiphy_get_band_first_wdev(struct wiphy *wiphy, int band, unsigned int *link)
++{
++	struct wireless_dev *wdev;
++	struct cfg80211_chan_def *c;
++	unsigned int link_id;
++
++	list_for_each_entry(wdev, &wiphy->wdev_list, list) {
++		for_each_valid_link(wdev, link_id) {
++			c = wdev_chandef(wdev, link_id);
++			if (c && c->chan && c->chan->band == band) {
++				*link = link_id;
++				return wdev;
++			}
++		}
++	}
++
++	return NULL;
++}
++
+ /**
+  * DOC: Utility functions
+  *
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index 7b511d3..38e8432 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -1722,31 +1722,18 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
+ }
+ EXPORT_SYMBOL(cfg80211_any_usable_channels);
+ 
+-static void cfg80211_sta_radar_notify(struct wiphy *wiphy,
+-				      const struct cfg80211_chan_def *chandef,
+-				      enum nl80211_radar_event event)
+-{
+-	struct wireless_dev *wdev;
+-
+-	list_for_each_entry(wdev, &wiphy->wdev_list, list) {
+-		if (cfg80211_chandef_dfs_required(wiphy, chandef, wdev->iftype) > 0) {
+-			nl80211_radar_notify(wiphy_to_rdev(wiphy), chandef,
+-					     event, wdev->netdev, GFP_KERNEL);
+-			return;
+-		}
+-	}
+-}
+-
+ void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
+ 				   const struct cfg80211_chan_def *bss_chandef,
+ 				   const struct cfg80211_chan_def *csa_chandef,
+ 				   bool associated)
+ {
++	struct wiphy *wiphy = wdev->wiphy;
++	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ 	bool csa_active = !!csa_chandef;
+ 	enum nl80211_dfs_state dfs_state = NL80211_DFS_USABLE;
+ 	enum nl80211_radar_event event = NL80211_RADAR_STA_CAC_EXPIRED;
+ 
+-	lockdep_assert_wiphy(wdev->wiphy);
++	lockdep_assert_wiphy(wiphy);
+ 
+ 	if (!bss_chandef || !bss_chandef->chan ||
+ 	    bss_chandef->chan->band != NL80211_BAND_5GHZ)
+@@ -1754,17 +1741,17 @@ void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
+ 
+ 	/* assume csa channel is cac completed */
+ 	if (csa_active &&
+-	    (cfg80211_chandef_dfs_usable(wdev->wiphy, csa_chandef) ||
+-	    cfg80211_chandef_dfs_available(wdev->wiphy, csa_chandef))) {
+-		cfg80211_set_dfs_state(wdev->wiphy, csa_chandef, NL80211_DFS_AVAILABLE);
+-		cfg80211_sta_radar_notify(wdev->wiphy, csa_chandef,
+-					  NL80211_RADAR_STA_CAC_SKIPPED);
++	    (cfg80211_chandef_dfs_usable(wiphy, csa_chandef) ||
++	    cfg80211_chandef_dfs_available(wiphy, csa_chandef))) {
++		cfg80211_set_dfs_state(wiphy, csa_chandef, NL80211_DFS_AVAILABLE);
++		nl80211_radar_notify(rdev, csa_chandef,
++				     NL80211_RADAR_STA_CAC_SKIPPED, GFP_KERNEL);
+ 		netdev_info(wdev->netdev, "Set CSA channel's DFS state to available\n");
+ 	}
+ 
+ 	/* avoid updating the dfs state during nop */
+-	if (!cfg80211_chandef_dfs_usable(wdev->wiphy, bss_chandef) &&
+-	    !cfg80211_chandef_dfs_available(wdev->wiphy, bss_chandef))
++	if (!cfg80211_chandef_dfs_usable(wiphy, bss_chandef) &&
++	    !cfg80211_chandef_dfs_available(wiphy, bss_chandef))
+ 		return;
+ 
+ 	if (associated && !csa_active) {
+@@ -1776,13 +1763,12 @@ void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
+ 	 * when other interfaces still operate on this channel
+ 	 */
+ 	if (dfs_state == NL80211_DFS_USABLE &&
+-	    (cfg80211_is_wiphy_oper_chan(wdev->wiphy, bss_chandef->chan) ||
+-	     cfg80211_offchan_chain_is_active(wiphy_to_rdev(wdev->wiphy),
+-					      bss_chandef->chan)))
++	    (cfg80211_is_wiphy_oper_chan(wiphy, bss_chandef->chan) ||
++	     cfg80211_offchan_chain_is_active(rdev, bss_chandef->chan)))
+ 		return;
+ 
+-	cfg80211_set_dfs_state(wdev->wiphy, bss_chandef, dfs_state);
+-	cfg80211_sta_radar_notify(wdev->wiphy, bss_chandef, event);
++	cfg80211_set_dfs_state(wiphy, bss_chandef, dfs_state);
++	nl80211_radar_notify(rdev, bss_chandef, event, GFP_KERNEL);
+ 
+ 	if (csa_active)
+ 		netdev_info(wdev->netdev, "Set origin channel's DFS state to usable\n");
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index cddee2f..9cc8071 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -1058,8 +1058,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
+ 							NL80211_CHAN_NO_HT);
+ 
+ 				nl80211_radar_notify(rdev, &chandef,
+-						     radar_event, NULL,
+-						     GFP_ATOMIC);
++						     radar_event, GFP_ATOMIC);
+ 
+ 				regulatory_propagate_dfs_state(wiphy, &chandef,
+ 							       c->dfs_state,
+@@ -1102,7 +1101,7 @@ void __cfg80211_radar_event(struct wiphy *wiphy,
+ 
+ 	cfg80211_sched_dfs_chan_update(rdev);
+ 
+-	nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
++	nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, gfp);
+ 
+ 	memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def));
+ 	queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
+@@ -1151,7 +1150,7 @@ void cfg80211_cac_event(struct net_device *netdev,
+ 		return;
+ 	}
+ 
+-	nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
++	nl80211_radar_notify(rdev, chandef, event, gfp);
+ }
+ EXPORT_SYMBOL(cfg80211_cac_event);
+ 
+@@ -1162,7 +1161,6 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
+ 				enum nl80211_radar_event event)
+ {
+ 	struct wiphy *wiphy = &rdev->wiphy;
+-	struct net_device *netdev;
+ 
+ 	lockdep_assert_wiphy(&rdev->wiphy);
+ 
+@@ -1178,13 +1176,11 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
+ 		memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef));
+ 		queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
+ 		cfg80211_sched_dfs_chan_update(rdev);
+-		wdev = rdev->background_radar_wdev;
+ 		rdev->background_cac_started = false;
+ 		break;
+ 	case NL80211_RADAR_CAC_ABORTED:
+ 		if (!cancel_delayed_work(&rdev->background_cac_done_wk))
+ 			return;
+-		wdev = rdev->background_radar_wdev;
+ 		rdev->background_cac_started = false;
+ 		break;
+ 	case NL80211_RADAR_CAC_STARTED:
+@@ -1194,8 +1190,7 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
+ 		return;
+ 	}
+ 
+-	netdev = wdev ? wdev->netdev : NULL;
+-	nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL);
++	nl80211_radar_notify(rdev, chandef, event, GFP_KERNEL);
+ }
+ 
+ static void
+@@ -1291,7 +1286,7 @@ void cfg80211_background_radar_update_channel(struct wiphy *wiphy,
+ 
+ 	event = expand ? NL80211_RADAR_BACKGROUND_CHAN_EXPAND :
+ 			 NL80211_RADAR_BACKGROUND_CHAN_UPDATE;
+-	nl80211_radar_notify(wiphy_to_rdev(wiphy), chandef, event, NULL, GFP_ATOMIC);
++	nl80211_radar_notify(wiphy_to_rdev(wiphy), chandef, event, GFP_ATOMIC);
+ }
+ EXPORT_SYMBOL(cfg80211_background_radar_update_channel);
+ 
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index cb14460..ba1190d 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -19686,7 +19686,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
+ 	}
+ 
+ 	cfg80211_schedule_channels_check(wdev);
+-	cfg80211_sched_dfs_chan_update(rdev);
++	if (chandef->chan && chandef->chan->band == NL80211_BAND_5GHZ)
++		cfg80211_sched_dfs_chan_update(rdev);
+ 
+ 	nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL,
+ 				 NL80211_CMD_CH_SWITCH_NOTIFY, 0, false);
+@@ -19766,12 +19767,22 @@ EXPORT_SYMBOL(cfg80211_bss_color_notify);
+ void
+ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
+ 		     const struct cfg80211_chan_def *chandef,
+-		     enum nl80211_radar_event event,
+-		     struct net_device *netdev, gfp_t gfp)
++		     enum nl80211_radar_event event, gfp_t gfp)
+ {
++	struct wiphy *wiphy = &rdev->wiphy;
++	struct wireless_dev *wdev;
+ 	struct sk_buff *msg;
++	unsigned int link_id;
+ 	void *hdr;
+ 
++	/* Specifying a wdev containing a 5G link is necessary for MLO.
++	 * Otherwise, userspace will only process the radar event
++	 * with the first wdev, which may not have 5G links.
++	 */
++	wdev = wiphy_get_band_first_wdev(wiphy, NL80211_BAND_5GHZ, &link_id);
++	if (!wdev)
++		return;
++
+ 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ 	if (!msg)
+ 		return;
+@@ -19785,15 +19796,12 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
+ 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
+ 		goto nla_put_failure;
+ 
+-	/* NOP and radar events don't need a netdev parameter */
+-	if (netdev) {
+-		struct wireless_dev *wdev = netdev->ieee80211_ptr;
+-
+-		if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+-		    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+-				      NL80211_ATTR_PAD))
+-			goto nla_put_failure;
+-	}
++	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
++	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
++			      NL80211_ATTR_PAD) ||
++	    (wdev->valid_links &&
++	     nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)))
++		goto nla_put_failure;
+ 
+ 	if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
+ 		goto nla_put_failure;
+@@ -19803,7 +19811,7 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
+ 
+ 	genlmsg_end(msg, hdr);
+ 
+-	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
++	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
+ 				NL80211_MCGRP_MLME, gfp);
+ 	return;
+ 
+diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
+index ffaab9a..ee68488 100644
+--- a/net/wireless/nl80211.h
++++ b/net/wireless/nl80211.h
+@@ -114,8 +114,7 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
+ void
+ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
+ 		     const struct cfg80211_chan_def *chandef,
+-		     enum nl80211_radar_event event,
+-		     struct net_device *netdev, gfp_t gfp);
++		     enum nl80211_radar_event event, gfp_t gfp);
+ 
+ void nl80211_send_ap_stopped(struct wireless_dev *wdev, unsigned int link_id);
+ 
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 9cd7fb2..2a13721 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -4293,7 +4293,7 @@ void regulatory_propagate_dfs_state(struct wiphy *wiphy,
+ 			cfg80211_check_and_end_cac(rdev);
+ 		}
+ 
+-		nl80211_radar_notify(rdev, chandef, event, NULL, GFP_KERNEL);
++		nl80211_radar_notify(rdev, chandef, event, GFP_KERNEL);
+ 	}
+ }
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0072-mtk-mac80211-add-DFS-CAC-countdown-in-CSA-flow.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0072-mtk-mac80211-add-DFS-CAC-countdown-in-CSA-flow.patch
new file mode 100644
index 0000000..39e8817
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0072-mtk-mac80211-add-DFS-CAC-countdown-in-CSA-flow.patch
@@ -0,0 +1,415 @@
+From 16ec7de7b7f4d09a4b84ea2d85fb287a579626b2 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 6 Feb 2024 17:46:10 +0800
+Subject: [PATCH 72/89] mtk: mac80211: add DFS CAC countdown in CSA flow
+
+Add DFS channel CAC countdown mechanism in CSA flow
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h     | 38 ++++++++++++++++-
+ net/mac80211/cfg.c         | 85 ++++++++++++++++++++++++++++++++++++--
+ net/mac80211/ieee80211_i.h |  1 +
+ net/mac80211/mlme.c        |  6 ++-
+ net/mac80211/util.c        |  7 +++-
+ net/wireless/chan.c        | 74 +++++++++++++++++++++++++++++++++
+ net/wireless/nl80211.c     |  5 ++-
+ net/wireless/rdev-ops.h    | 18 ++++++++
+ net/wireless/reg.c         |  8 +++-
+ 9 files changed, 232 insertions(+), 10 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 5de1d1c..bedf711 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4481,6 +4481,8 @@ struct mgmt_frame_regs {
+  *
+  * @start_radar_detection: Start radar detection in the driver.
+  *
++ * @start_radar_detection_post_csa: Start radar detection during post CSA.
++ *
+  * @end_cac: End running CAC, probably because a related CAC
+  *	was finished on another phy.
+  *
+@@ -4853,9 +4855,13 @@ struct cfg80211_ops {
+ 
+ 	int	(*start_radar_detection)(struct wiphy *wiphy,
+ 					 struct net_device *dev,
+-					 unsigned int link_id,
+ 					 struct cfg80211_chan_def *chandef,
+ 					 u32 cac_time_ms, int link_id);
++	int	(*start_radar_detection_post_csa)(struct wiphy *wiphy,
++						  struct net_device *dev,
++						  unsigned int link_id,
++						  struct cfg80211_chan_def *chandef,
++						  u32 cac_time_ms);
+ 	void	(*end_cac)(struct wiphy *wiphy,
+ 			   struct net_device *dev, unsigned int link_id);
+ 	int	(*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
+@@ -9018,6 +9024,36 @@ cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
+ }
+ 
+ /**
++ * cfg80211_reg_can_beacon_dfs_relax - check if beaconing is allowed with DFS & IR-relaxation
++ * @wiphy: the wiphy
++ * @chandef: the channel definition
++ * @iftype: interface type
++ *
++ * Return: %true if there is no secondary channel or the secondary channel(s)
++ * can be used for beaconing. This version bypasses radar channel check, allowing
++ * channel switch to a USABLE DFS channel and performing CAC after the channel switch.
++ * It also checks if IR-relaxation conditions apply, to allow beaconing under more
++ * permissive conditions.
++ *
++ * Requires the wiphy mutex to be held.
++ */
++bool cfg80211_reg_can_beacon_dfs_relax(struct wiphy *wiphy,
++				       struct cfg80211_chan_def *chandef,
++				       enum nl80211_iftype iftype);
++
++/**
++ * cfg80211_start_radar_detection_post_csa - start radar detection after CSA
++ * @wiphy: the wiphy
++ * @wdev: the wireless device
++ * @link_id: the link ID for MLO, must be 0 for non-MLO
++ * @chandef: the channel definition to start radar detection on
++ */
++int cfg80211_start_radar_detection_post_csa(struct wiphy *wiphy,
++					    struct wireless_dev *wdev,
++					    unsigned int link_id,
++					    struct cfg80211_chan_def *chandef);
++
++/*
+  * cfg80211_ch_switch_notify - update wdev channel and notify userspace
+  * @dev: the device which switched channels
+  * @chandef: the new channel definition
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index c52cde0..36c898c 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1576,7 +1576,7 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
+ 	return 0;
+ }
+ 
+-static void ieee80211_free_next_beacon(struct ieee80211_link_data *link)
++void ieee80211_free_next_beacon(struct ieee80211_link_data *link)
+ {
+ 	if (!link->u.ap.next_beacon)
+ 		return;
+@@ -3725,6 +3725,72 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_link_data *link_data,
+ 	return 0;
+ }
+ 
++static int ieee80211_start_radar_detection_post_csa(struct wiphy *wiphy,
++						    struct net_device *dev,
++						    unsigned int link_id,
++						    struct cfg80211_chan_def *chandef,
++						    u32 cac_time_ms)
++{
++	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++	struct ieee80211_local *local = sdata->local;
++	struct ieee80211_link_data *link;
++
++	if (!list_empty(&local->roc_list) || local->scanning)
++		return -EBUSY;
++
++	link = sdata_dereference(sdata->link[link_id], sdata);
++	if (!link)
++		return -ENOLINK;
++
++	/* whatever, but channel contexts should not complain about that one */
++	link->smps_mode = IEEE80211_SMPS_OFF;
++	link->needed_rx_chains = local->rx_chains;
++
++	if (hweight16(sdata->vif.valid_links) <= 1)
++		sta_info_flush(sdata, -1);
++
++	wiphy_delayed_work_queue(wiphy, &link->dfs_cac_timer_work,
++				 msecs_to_jiffies(cac_time_ms));
++
++	return 1;
++}
++
++static void ieee80211_csa_send_deauth(struct ieee80211_link_data *link_data)
++{
++	struct ieee80211_sub_if_data *sdata = link_data->sdata;
++	struct ieee80211_local *local = sdata->local;
++	struct ieee80211_bss_conf *link_conf = link_data->conf;
++	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
++	u8 broadcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
++	bool send_deauth;
++
++	send_deauth = !cfg80211_chandef_identical(&link_conf->chanreq.oper,
++						  &link_data->csa.chanreq.oper) &&
++		      !cfg80211_reg_can_beacon_relax(local->hw.wiphy,
++						     &link_data->csa.chanreq.oper,
++						     sdata->wdev.iftype) &&
++		      hweight16(sdata->vif.valid_links) <= 1;
++	/* broadcast deauth frame if CAC is required for non MLD or single link MLD AP */
++	if (!send_deauth)
++		return;
++
++	if (sdata->csa_blocked_queues) {
++		ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA);
++		ieee80211_send_deauth_disassoc(sdata, broadcast,
++					       link_conf->bssid,
++					       IEEE80211_STYPE_DEAUTH,
++					       WLAN_REASON_DEAUTH_LEAVING,
++					       send_deauth, frame_buf);
++		ieee80211_stop_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA);
++		return;
++	}
++
++	ieee80211_send_deauth_disassoc(sdata, broadcast,
++				       link_conf->bssid, IEEE80211_STYPE_DEAUTH,
++				       WLAN_REASON_DEAUTH_LEAVING,
++				       send_deauth, frame_buf);
++}
++
+ static int __ieee80211_csa_finalize(struct ieee80211_link_data *link_data)
+ {
+ 	struct ieee80211_sub_if_data *sdata = link_data->sdata;
+@@ -3735,6 +3801,8 @@ static int __ieee80211_csa_finalize(struct ieee80211_link_data *link_data)
+ 
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 
++	ieee80211_csa_send_deauth(link_data);
++
+ 	/*
+ 	 * using reservation isn't immediate as it may be deferred until later
+ 	 * with multi-vif. once reservation is complete it will re-schedule the
+@@ -3758,6 +3826,12 @@ static int __ieee80211_csa_finalize(struct ieee80211_link_data *link_data)
+ 					&link_data->csa.chanreq.oper))
+ 		return -EINVAL;
+ 
++	err = cfg80211_start_radar_detection_post_csa(local->hw.wiphy, &sdata->wdev,
++						      link_data->link_id,
++						      &link_conf->chanreq.oper);
++	if (err)
++		return err > 0 ? 0 : err;
++
+ 	link_conf->csa_active = false;
+ 
+ 	err = ieee80211_set_after_csa_beacon(link_data, &changed);
+@@ -5140,8 +5214,12 @@ ieee80211_skip_cac(struct wireless_dev *wdev, unsigned int link_id)
+ 
+ 	wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+ 				  &link->dfs_cac_timer_work);
+-	if (wdev->cac_links & BIT(link_id)) {
+-		ieee80211_link_release_channel(link);
++	if (wdev->links[link_id].cac_started) {
++		if (link->conf->csa_active)
++			wiphy_work_queue(sdata->local->hw.wiphy,
++					 &link->csa.finalize_work);
++		else
++			ieee80211_link_release_channel(link);
+ 		cac_time_ms = wdev->links[link_id].cac_time_ms;
+ 		wdev->links[link_id].cac_start_time = jiffies -
+ 						      msecs_to_jiffies(cac_time_ms + 1);
+@@ -5233,6 +5311,7 @@ const struct cfg80211_ops mac80211_config_ops = {
+ #endif
+ 	.get_channel = ieee80211_cfg_get_channel,
+ 	.start_radar_detection = ieee80211_start_radar_detection,
++	.start_radar_detection_post_csa = ieee80211_start_radar_detection_post_csa,
+ 	.end_cac = ieee80211_end_cac,
+ 	.channel_switch = ieee80211_channel_switch,
+ 	.set_qos_map = ieee80211_set_qos_map,
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index a5c0d6c..2cb80c3 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -2015,6 +2015,7 @@ int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+ void ieee80211_csa_finalize_work(struct wiphy *wiphy, struct wiphy_work *work);
+ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ 			     struct cfg80211_csa_settings *params);
++void ieee80211_free_next_beacon(struct ieee80211_link_data *link);
+ 
+ /* color change handling */
+ void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 1b19583..b684fed 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3051,7 +3051,11 @@ void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work)
+ 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
+ 
+ 	if (sdata->wdev.links[link->link_id].cac_started) {
+-		ieee80211_link_release_channel(link);
++		if (link->conf->csa_active)
++			wiphy_work_queue(sdata->local->hw.wiphy,
++					 &link->csa.finalize_work);
++		else
++			ieee80211_link_release_channel(link);
+ 		cfg80211_cac_event(sdata->dev, &chandef,
+ 				   NL80211_RADAR_CAC_FINISHED,
+ 				   GFP_KERNEL, link->link_id);
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 2d2b871..df4fa1a 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3494,7 +3494,12 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
+ 				continue;
+ 
+ 			chandef = link_conf->chanreq.oper;
+-			ieee80211_link_release_channel(link_data);
++			if (link_conf->csa_active) {
++				link_conf->csa_active = false;
++				ieee80211_free_next_beacon(link_data);
++			} else {
++				ieee80211_link_release_channel(link_data);
++			}
+ 			cfg80211_cac_event(sdata->dev,
+ 					   &chandef,
+ 					   NL80211_RADAR_CAC_ABORTED,
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index 38e8432..03747bb 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -1680,6 +1680,80 @@ bool cfg80211_reg_check_beaconing(struct wiphy *wiphy,
+ }
+ EXPORT_SYMBOL(cfg80211_reg_check_beaconing);
+ 
++bool cfg80211_reg_can_beacon_dfs_relax(struct wiphy *wiphy,
++				       struct cfg80211_chan_def *chandef,
++				       enum nl80211_iftype iftype)
++{
++	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
++	u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
++			       IEEE80211_CHAN_RADAR;
++
++	lockdep_assert_held(&rdev->wiphy.mtx);
++
++	/* Bypass available and usable dfs channel */
++	if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 &&
++	    (cfg80211_chandef_dfs_usable(wiphy, chandef) ||
++	     cfg80211_chandef_dfs_available(wiphy, chandef)))
++		prohibited_flags = IEEE80211_CHAN_DISABLED;
++
++	/*
++	 * Under certain conditions suggested by some regulatory bodies a
++	 * GO/STA can IR on channels marked with IEEE80211_NO_IR. Set this flag
++	 * only if such relaxations are not enabled and the conditions are not
++	 * met.
++	 */
++	if (!cfg80211_ir_permissive_chan(wiphy, iftype, chandef->chan))
++		prohibited_flags |= IEEE80211_CHAN_NO_IR;
++
++	return cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
++}
++EXPORT_SYMBOL(cfg80211_reg_can_beacon_dfs_relax);
++
++int cfg80211_start_radar_detection_post_csa(struct wiphy *wiphy,
++					    struct wireless_dev *wdev,
++					    unsigned int link_id,
++					    struct cfg80211_chan_def *chandef)
++{
++	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
++	u32 cac_time_ms;
++	enum nl80211_dfs_regions dfs_region;
++	int ret = 0;
++
++	if (cfg80211_chandef_dfs_available(wiphy, chandef))
++		goto out;
++
++	/* Update DFS channel state especially when original channel include DFS channel */
++	cfg80211_sched_dfs_chan_update(rdev);
++
++	dfs_region = reg_get_dfs_region(wiphy);
++	if (dfs_region == NL80211_DFS_UNSET)
++		goto out;
++
++	cac_time_ms = cfg80211_chandef_dfs_cac_time(wiphy, chandef);
++	if (WARN_ON(!cac_time_ms))
++		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
++
++	pr_info("%s: region = %u, center freq1 = %u, center freq2 = %u, cac time ms = %u\n",
++		__func__, dfs_region, chandef->center_freq1, chandef->center_freq2, cac_time_ms);
++
++	ret = rdev_start_radar_detection_post_csa(rdev, wdev->netdev, link_id,
++						  chandef, cac_time_ms);
++	if (ret > 0) {
++		wdev->links[link_id].ap.chandef = *chandef;
++		wdev->links[link_id].cac_start_time = jiffies;
++		wdev->links[link_id].cac_time_ms = cac_time_ms;
++		if (rdev->background_cac_started &&
++		    cfg80211_is_sub_chan(chandef, rdev->background_radar_chandef.chan, false))
++			cfg80211_stop_background_radar_detection(rdev->background_radar_wdev);
++		cfg80211_cac_event(wdev->netdev, chandef,
++				   NL80211_RADAR_CAC_STARTED, GFP_KERNEL, link_id);
++	}
++
++out:
++	return ret;
++}
++EXPORT_SYMBOL(cfg80211_start_radar_detection_post_csa);
++
+ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
+ 				 struct cfg80211_chan_def *chandef)
+ {
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index ba1190d..756a29a 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -10462,8 +10462,9 @@ skip_beacons:
+ 		cfg80211_set_dfs_state(&rdev->wiphy, &params.chandef, NL80211_DFS_AVAILABLE);
+ 	}
+ 
+-	if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
+-					   wdev->iftype)) {
++	/* handle DFS CAC after CSA is sent */
++	if (!cfg80211_reg_can_beacon_dfs_relax(&rdev->wiphy, &params.chandef,
++					       wdev->iftype)) {
+ 		err = -EINVAL;
+ 		goto free;
+ 	}
+diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
+index e4a77a8..5b3c94f 100644
+--- a/net/wireless/rdev-ops.h
++++ b/net/wireless/rdev-ops.h
+@@ -1214,6 +1214,24 @@ rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
+ 	return ret;
+ }
+ 
++static inline int
++rdev_start_radar_detection_post_csa(struct cfg80211_registered_device *rdev,
++				    struct net_device *dev,
++				    unsigned int link_id,
++				    struct cfg80211_chan_def *chandef,
++				    u32 cac_time_ms)
++{
++	int ret = -EOPNOTSUPP;
++
++	trace_rdev_start_radar_detection(&rdev->wiphy, dev, chandef,
++					 cac_time_ms, link_id);
++	if (rdev->ops->start_radar_detection_post_csa)
++		ret = rdev->ops->start_radar_detection_post_csa(&rdev->wiphy, dev, link_id,
++								chandef, cac_time_ms);
++	trace_rdev_return_int(&rdev->wiphy, ret);
++	return ret;
++}
++
+ static inline void
+ rdev_end_cac(struct cfg80211_registered_device *rdev,
+ 	     struct net_device *dev, unsigned int link_id)
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 2a13721..651f286 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -2441,8 +2441,12 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
+ 		case NL80211_IFTYPE_P2P_GO:
+ 		case NL80211_IFTYPE_ADHOC:
+ 		case NL80211_IFTYPE_MESH_POINT:
+-			ret = cfg80211_reg_can_beacon_relax(wiphy, &chandef,
+-							    iftype);
++			if (wdev->links[link].cac_started)
++				ret = cfg80211_reg_can_beacon_dfs_relax(wiphy, &chandef,
++									iftype);
++			else
++				ret = cfg80211_reg_can_beacon_relax(wiphy, &chandef,
++								    iftype);
+ 			if (!ret)
+ 				return ret;
+ 			break;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0073-mtk-mac80211-add-mlo-related-debugfs-knob.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0073-mtk-mac80211-add-mlo-related-debugfs-knob.patch
new file mode 100644
index 0000000..e9a2ebc
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0073-mtk-mac80211-add-mlo-related-debugfs-knob.patch
@@ -0,0 +1,69 @@
+From 77c5db25a8d03ab48f06d66cdab058757ba9a2fc Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Mon, 27 May 2024 19:10:51 +0800
+Subject: [PATCH 73/89] mtk: mac80211: add mlo related debugfs knob
+
+Add the following debugfs knob
+- /sys/kernel/debug/ieee80211/phy0/<interface>/ttlm
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ net/mac80211/debugfs_netdev.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
+index 3017f09..33fa0d9 100644
+--- a/net/mac80211/debugfs_netdev.c
++++ b/net/mac80211/debugfs_netdev.c
+@@ -613,6 +613,24 @@ static ssize_t ieee80211_if_fmt_num_buffered_multicast(
+ }
+ IEEE80211_IF_FILE_R(num_buffered_multicast);
+ 
++static ssize_t ieee80211_if_fmt_ttlm(
++	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
++{
++	const struct ieee80211_vif *vif = &sdata->vif;
++	int i = 0, len = 0;
++
++	len += scnprintf(buf + len, buflen - len, "valid = %d\n", vif->neg_ttlm.valid);
++
++	for(i = 0; i < IEEE80211_TTLM_NUM_TIDS; i++)
++		len += scnprintf(buf + len, buflen - len,
++				 "tid%d: dl = %u, ul = %u\n", i,
++				 vif->neg_ttlm.downlink[i],
++				 vif->neg_ttlm.uplink[i]);
++
++	return len;
++}
++IEEE80211_IF_FILE_R(ttlm);
++
+ static ssize_t ieee80211_if_fmt_aqm(
+ 	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
+ {
+@@ -839,6 +857,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
+ {
+ 	DEBUGFS_ADD(bssid);
+ 	DEBUGFS_ADD(aid);
++	DEBUGFS_ADD(ttlm);
+ 	DEBUGFS_ADD(beacon_timeout);
+ 	DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
+ 	DEBUGFS_ADD_MODE(beacon_loss, 0200);
+@@ -855,6 +874,7 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
+ 	DEBUGFS_ADD(num_mcast_sta);
+ 	DEBUGFS_ADD(num_sta_ps);
+ 	DEBUGFS_ADD(dtim_count);
++	DEBUGFS_ADD(ttlm);
+ 	DEBUGFS_ADD(num_buffered_multicast);
+ 	DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
+ 	DEBUGFS_ADD_MODE(multicast_to_unicast, 0600);
+@@ -865,6 +885,7 @@ static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
+ 	/* add num_mcast_sta_vlan using name num_mcast_sta */
+ 	debugfs_create_file("num_mcast_sta", 0400, sdata->vif.debugfs_dir,
+ 			    sdata, &num_mcast_sta_vlan_ops);
++	DEBUGFS_ADD(ttlm);
+ }
+ 
+ static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0074-mtk-mac80211-Add-exported-function-for-SoftMAC-drive.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0074-mtk-mac80211-Add-exported-function-for-SoftMAC-drive.patch
new file mode 100644
index 0000000..991bbf4
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0074-mtk-mac80211-Add-exported-function-for-SoftMAC-drive.patch
@@ -0,0 +1,197 @@
+From f7b9caab67609cfc9e33228d575e47b6fab4a4ba Mon Sep 17 00:00:00 2001
+From: Rex Lu <rex.lu@mediatek.com>
+Date: Fri, 7 Jun 2024 13:25:08 +0800
+Subject: [PATCH 74/89] mtk: mac80211: Add exported function for SoftMAC driver
+ to get QoS map
+
+Add exported function for SoftMAC driver to get QoS map.
+1. Because the mapping from IP DSCP to IEEE 802.11 user priority may be customized.
+Therefore, driver needs to pass the mapping to HW, so that the QoS type of traffic can be mapped in a consistent manner for both SW and HW paths.
+2. due to this change(https://github.com/torvalds/linux/commit/6fdb8b8781d59796324efa25909f3e2112833f01) in backport 6.10.
+we need to add a default QoS map. when hostapd config didn't set QoS map, we need pass default QoS map to HW.
+
+Signed-off-by: Rex Lu <rex.lu@mediatek.com>
+
+1. Remove exported function for SoftMAC driver to get QoS map.
+Instead, add callback function for mac80211 to set QoS map in HW, which is more intuitive.
+2. Fix inconsistent QoS mapping between AP and AP_VLAN IFs.
+Specifically, when WDS AP IF is connected by a WDS STA, the QoS map of the AP_VLAN VIF is NULL.
+So the QoS types of packets to the WDS STA will be determined using the default mapping rule.
+However, SoftMAC driver uses the QoS map of the AP VIF, which may already be set.
+Therefore, it is possible that the QoS mappings of SW and HW are inconsistent.
+Thus, sync QoS map of AP VIF to that of AP_VLAN VIF.
+
+Signed-off-by: Rex Lu <rex.lu@mediatek.com>
+
+Refactor drv_set_qos_map function.
+1. use dscp exception to instead of dscp range.
+for example: if dscp value is 15. Original way will translte to tid 0.
+but mac80211 will translate to tid 1.
+
+Signed-off-by: Rex Lu <rex.lu@mediatek.com>
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+---
+ include/net/mac80211.h    |  4 +++-
+ net/mac80211/cfg.c        |  2 +-
+ net/mac80211/chan.c       |  7 +++++++
+ net/mac80211/driver-ops.h | 22 ++++++++++++++++++++++
+ net/mac80211/iface.c      | 23 ++++++++++++++++++++++-
+ net/mac80211/trace.h      |  6 ++++++
+ net/mac80211/util.c       |  2 +-
+ 7 files changed, 62 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 5cd9432..bb4f12f 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -4453,6 +4453,7 @@ struct ieee80211_prep_tx_info {
+  *	if the requested TID-To-Link mapping can be accepted or not.
+  *	If it's not accepted the driver may suggest a preferred mapping and
+  *	modify @ttlm parameter with the suggested TID-to-Link mapping.
++ * @set_qos_map: Set QoS mapping information to driver.
+  */
+ struct ieee80211_ops {
+ 	void (*tx)(struct ieee80211_hw *hw,
+@@ -4840,6 +4841,8 @@ struct ieee80211_ops {
+ 	enum ieee80211_neg_ttlm_res
+ 	(*can_neg_ttlm)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			struct ieee80211_neg_ttlm *ttlm);
++	int (*set_qos_map)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++			   struct cfg80211_qos_map *qos_map);
+ };
+ 
+ /**
+@@ -7719,5 +7722,4 @@ int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
+  * @hw: pointer as obtained from ieee80211_alloc_hw()
+  */
+ unsigned long ieee80211_get_scanning(struct ieee80211_hw *hw);
+-
+ #endif /* MAC80211_H */
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 36c898c..02374b0 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -4431,7 +4431,7 @@ static int ieee80211_set_qos_map(struct wiphy *wiphy,
+ 	if (old_qos_map)
+ 		kfree_rcu(old_qos_map, rcu_head);
+ 
+-	return 0;
++	return drv_set_qos_map(sdata->local, sdata);
+ }
+ 
+ static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy,
+diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
+index bdff227..31d7fa8 100644
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -941,6 +941,13 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
+ 
+ 	ieee80211_check_fast_xmit_iface(sdata);
+ 
++	/* FIXME: QoS MAP should be configured for each link (BSS).
++	 * We use assign_link_chanctx for the time being.
++	 * The problematic part is that everytime channel switch happens
++	 * the qos_map would get redundantly configured once.
++	 */
++	drv_set_qos_map(local, sdata);
++
+ 	return ret;
+ }
+ 
+diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
+index 4cddc3c..d226e31 100644
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -1741,4 +1741,26 @@ drv_can_neg_ttlm(struct ieee80211_local *local,
+ 
+ 	return res;
+ }
++
++static inline int drv_set_qos_map(struct ieee80211_local *local,
++				  struct ieee80211_sub_if_data *sdata)
++{
++	int ret = -EOPNOTSUPP;
++	struct mac80211_qos_map *qos_map;
++
++	might_sleep();
++	if (!check_sdata_in_driver(sdata))
++		return -EIO;
++
++	qos_map = sdata_dereference(sdata->qos_map, sdata);
++
++	trace_drv_set_qos_map(local, sdata);
++	if (local->ops->set_qos_map)
++		ret = local->ops->set_qos_map(&local->hw, &sdata->vif,
++					      qos_map ? &qos_map->qos_map : NULL);
++	trace_drv_return_int(local, ret);
++
++	return ret;
++}
++
+ #endif /* __MAC80211_DRIVER_OPS */
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 3936181..d959901 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -385,8 +385,29 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
+ 			 * can only add VLANs to enabled APs
+ 			 */
+ 			if (iftype == NL80211_IFTYPE_AP_VLAN &&
+-			    nsdata->vif.type == NL80211_IFTYPE_AP)
++			    nsdata->vif.type == NL80211_IFTYPE_AP) {
++				struct mac80211_qos_map *old_map, *new_map = NULL;
++
+ 				sdata->bss = &nsdata->u.ap;
++
++				rcu_read_lock();
++				old_map = rcu_dereference(nsdata->qos_map);
++				if (old_map) {
++					new_map = kzalloc(sizeof(*new_map), GFP_KERNEL);
++					if (!new_map) {
++						rcu_read_unlock();
++						return -ENOMEM;
++					}
++					memcpy(&new_map->qos_map, &old_map->qos_map,
++					       sizeof(new_map->qos_map));
++				}
++				rcu_read_unlock();
++
++				old_map = sdata_dereference(sdata->qos_map, sdata);
++				rcu_assign_pointer(sdata->qos_map, new_map);
++				if (old_map)
++					kfree_rcu(old_map, rcu_head);
++			}
+ 		}
+ 	}
+ 
+diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
+index 68f86c3..36e500d 100644
+--- a/net/mac80211/trace.h
++++ b/net/mac80211/trace.h
+@@ -3175,6 +3175,12 @@ TRACE_EVENT(bss_color_bitmap,
+ 		"color=%u color_bitmap=0x%llx", __entry->color, __entry->color_bitmap
+ 	)
+ );
++
++DEFINE_EVENT(local_sdata_evt, drv_set_qos_map,
++	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
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index df4fa1a..4da6831 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -4503,4 +4503,4 @@ unsigned long ieee80211_get_scanning(struct ieee80211_hw *hw)
+ 
+ 	return local->scanning;
+ }
+-EXPORT_SYMBOL(ieee80211_get_scanning);
++EXPORT_SYMBOL(ieee80211_get_scanning);
+\ No newline at end of file
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0075-mtk-mac80211-add-per-link-txpower-config.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0075-mtk-mac80211-add-per-link-txpower-config.patch
new file mode 100644
index 0000000..7320f77
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0075-mtk-mac80211-add-per-link-txpower-config.patch
@@ -0,0 +1,528 @@
+From 0f6ae2024ce001cf003239b3aaa56cb4a279bba9 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 22 Feb 2024 15:21:49 +0800
+Subject: [PATCH 75/89] mtk: mac80211: add per-link txpower config
+
+Add per-link txpower config & info dump
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h     |  5 ++--
+ include/net/mac80211.h     |  2 +-
+ net/mac80211/cfg.c         | 48 +++++++++++++++++++++++++++-----------
+ net/mac80211/chan.c        |  4 ++--
+ net/mac80211/driver-ops.h  |  7 +++---
+ net/mac80211/ieee80211_i.h |  5 ++--
+ net/mac80211/iface.c       | 23 +++++++++---------
+ net/mac80211/link.c        |  3 +++
+ net/mac80211/mlme.c        |  2 +-
+ net/mac80211/trace.h       | 10 ++++----
+ net/wireless/nl80211.c     | 17 +++++++++++---
+ net/wireless/rdev-ops.h    | 12 ++++++----
+ net/wireless/trace.h       | 30 ++++++++++++++++++------
+ net/wireless/wext-compat.c |  4 ++--
+ 14 files changed, 116 insertions(+), 56 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index bedf711..a63f5bb 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4749,9 +4749,10 @@ struct cfg80211_ops {
+ 	int	(*set_wiphy_params)(struct wiphy *wiphy, u32 changed);
+ 
+ 	int	(*set_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
+-				enum nl80211_tx_power_setting type, int mbm);
++				unsigned int link_id, enum nl80211_tx_power_setting type,
++				int mbm);
+ 	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
+-				int *dbm);
++				unsigned int link_id, int *dbm);
+ 
+ 	void	(*rfkill_poll)(struct wiphy *wiphy);
+ 
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index bb4f12f..30aa436 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -4746,7 +4746,7 @@ struct ieee80211_ops {
+ 	u32 (*get_expected_throughput)(struct ieee80211_hw *hw,
+ 				       struct ieee80211_sta *sta);
+ 	int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-			   int *dbm);
++			   unsigned int link_id, int *dbm);
+ 
+ 	int (*tdls_channel_switch)(struct ieee80211_hw *hw,
+ 				   struct ieee80211_vif *vif,
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 02374b0..19171b0 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3048,10 +3048,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+ 
+ static int ieee80211_set_tx_power(struct wiphy *wiphy,
+ 				  struct wireless_dev *wdev,
++				  unsigned int link_id,
+ 				  enum nl80211_tx_power_setting type, int mbm)
+ {
+ 	struct ieee80211_local *local = wiphy_priv(wiphy);
+ 	struct ieee80211_sub_if_data *sdata;
++	struct ieee80211_link_data *link;
++	struct ieee80211_bss_conf *link_conf;
+ 	enum nl80211_tx_power_setting txp_type = type;
+ 	bool update_txp_type = false;
+ 	bool has_monitor = false;
+@@ -3060,6 +3063,11 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
+ 
+ 	if (wdev) {
+ 		sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
++		link = sdata_dereference(sdata->link[link_id], sdata);
++		if (!link)
++			return -ENOLINK;
++
++		link_conf = link->conf;
+ 
+ 		if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+ 			sdata = wiphy_dereference(local->hw.wiphy,
+@@ -3070,7 +3078,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
+ 
+ 		switch (type) {
+ 		case NL80211_TX_POWER_AUTOMATIC:
+-			sdata->deflink.user_power_level =
++			link->user_power_level =
+ 				IEEE80211_UNSET_POWER_LEVEL;
+ 			txp_type = NL80211_TX_POWER_LIMITED;
+ 			break;
+@@ -3078,20 +3086,24 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
+ 		case NL80211_TX_POWER_FIXED:
+ 			if (mbm < 0 || (mbm % 100))
+ 				return -EOPNOTSUPP;
+-			sdata->deflink.user_power_level = MBM_TO_DBM(mbm);
++			link->user_power_level = MBM_TO_DBM(mbm);
+ 			break;
+ 		}
+ 
+-		if (txp_type != sdata->vif.bss_conf.txpower_type) {
++		if (txp_type != link_conf->txpower_type) {
+ 			update_txp_type = true;
+-			sdata->vif.bss_conf.txpower_type = txp_type;
++			link_conf->txpower_type = txp_type;
+ 		}
+ 
+-		ieee80211_recalc_txpower(sdata, update_txp_type);
++		ieee80211_recalc_txpower(sdata, update_txp_type, link);
+ 
+ 		return 0;
+ 	}
+ 
++	/*TODO: handle single wiphy */
++	wiphy_info(wiphy, "Setting txpower for the entire band is not supported\n");
++	return -EOPNOTSUPP;
++
+ 	switch (type) {
+ 	case NL80211_TX_POWER_AUTOMATIC:
+ 		local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
+@@ -3118,7 +3130,12 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
+ 	list_for_each_entry(sdata, &local->interfaces, list) {
+ 		if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+ 			continue;
+-		ieee80211_recalc_txpower(sdata, update_txp_type);
++		/* Due to mac80211 not pass link id to here, use first link for now */
++		if (ieee80211_vif_is_mld(&sdata->vif))
++			ieee80211_recalc_txpower(sdata, update_txp_type, sdata->link[0]);
++		else
++			ieee80211_recalc_txpower(sdata, update_txp_type, &sdata->deflink);
++
+ 	}
+ 
+ 	if (has_monitor) {
+@@ -3130,7 +3147,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
+ 				update_txp_type = true;
+ 			sdata->vif.bss_conf.txpower_type = txp_type;
+ 
+-			ieee80211_recalc_txpower(sdata, update_txp_type);
++			ieee80211_recalc_txpower(sdata, update_txp_type, &sdata->deflink);
+ 		}
+ 	}
+ 
+@@ -3139,18 +3156,23 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
+ 
+ static int ieee80211_get_tx_power(struct wiphy *wiphy,
+ 				  struct wireless_dev *wdev,
+-				  int *dbm)
++				  unsigned int link_id, int *dbm)
+ {
+ 	struct ieee80211_local *local = wiphy_priv(wiphy);
+ 	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
++	struct ieee80211_link_data *link;
+ 
+ 	if (local->ops->get_txpower)
+-		return drv_get_txpower(local, sdata, dbm);
++		return drv_get_txpower(local, sdata, link_id, dbm);
+ 
+-	if (local->emulate_chanctx)
+-		*dbm = local->hw.conf.power_level;
+-	else
+-		*dbm = sdata->vif.bss_conf.txpower;
++	*dbm = local->hw.conf.power_level;
++	if (!local->emulate_chanctx) {
++		link = sdata_dereference(sdata->link[link_id], sdata);
++		if (!link)
++			return -ENOLINK;
++
++		*dbm = link->conf->txpower;
++	}
+ 
+ 	/* INT_MIN indicates no power level was set yet */
+ 	if (*dbm == INT_MIN)
+diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
+index 31d7fa8..e7d2ee2 100644
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -913,7 +913,7 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
+ 	}
+ 
+ 	if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
+-		ieee80211_recalc_txpower(sdata, false);
++		ieee80211_recalc_txpower(sdata, false, link);
+ 		ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL, false);
+ 	}
+ 
+@@ -1730,7 +1730,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
+ 								  link,
+ 								  changed);
+ 
+-			ieee80211_recalc_txpower(sdata, false);
++			ieee80211_recalc_txpower(sdata, false, link);
+ 		}
+ 
+ 		ieee80211_recalc_chanctx_chantype(local, ctx);
+diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
+index d226e31..aca4426 100644
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -1273,7 +1273,8 @@ static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
+ }
+ 
+ static inline int drv_get_txpower(struct ieee80211_local *local,
+-				  struct ieee80211_sub_if_data *sdata, int *dbm)
++				  struct ieee80211_sub_if_data *sdata,
++				  unsigned int link_id, int *dbm)
+ {
+ 	int ret;
+ 
+@@ -1283,8 +1284,8 @@ static inline int drv_get_txpower(struct ieee80211_local *local,
+ 	if (!local->ops->get_txpower)
+ 		return -EOPNOTSUPP;
+ 
+-	ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
+-	trace_drv_get_txpower(local, sdata, *dbm, ret);
++	ret = local->ops->get_txpower(&local->hw, &sdata->vif, link_id, dbm);
++	trace_drv_get_txpower(local, sdata, link_id, *dbm, ret);
+ 
+ 	return ret;
+ }
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index 2cb80c3..6f9a9a6 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -2050,9 +2050,10 @@ void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata);
+ int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
+ void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
+ 
+-bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
++bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
++				struct ieee80211_link_data *link);
+ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
+-			      bool update_bss);
++			      bool update_bss, struct ieee80211_link_data *link);
+ void ieee80211_recalc_offload(struct ieee80211_local *local);
+ 
+ static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index d959901..eb7a05d 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -44,13 +44,14 @@
+ 
+ static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work);
+ 
+-bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
++bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
++				struct ieee80211_link_data *link)
+ {
+ 	struct ieee80211_chanctx_conf *chanctx_conf;
+ 	int power;
+ 
+ 	rcu_read_lock();
+-	chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
++	chanctx_conf = rcu_dereference(link->conf->chanctx_conf);
+ 	if (!chanctx_conf) {
+ 		rcu_read_unlock();
+ 		return false;
+@@ -59,14 +60,14 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
+ 	power = ieee80211_chandef_max_power(&chanctx_conf->def);
+ 	rcu_read_unlock();
+ 
+-	if (sdata->deflink.user_power_level != IEEE80211_UNSET_POWER_LEVEL)
+-		power = min(power, sdata->deflink.user_power_level);
++	if (link->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
++		power = min(power, link->user_power_level);
+ 
+-	if (sdata->deflink.ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
+-		power = min(power, sdata->deflink.ap_power_level);
++	if (link->ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
++		power = min(power, link->ap_power_level);
+ 
+-	if (power != sdata->vif.bss_conf.txpower) {
+-		sdata->vif.bss_conf.txpower = power;
++	if (power != link->conf->txpower) {
++		link->conf->txpower = power;
+ 		ieee80211_hw_config(sdata->local, 0);
+ 		return true;
+ 	}
+@@ -75,11 +76,11 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
+ }
+ 
+ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
+-			      bool update_bss)
++			      bool update_bss, struct ieee80211_link_data *link)
+ {
+-	if (__ieee80211_recalc_txpower(sdata) ||
++	if (__ieee80211_recalc_txpower(sdata, link) ||
+ 	    (update_bss && ieee80211_sdata_running(sdata)))
+-		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
++		ieee80211_link_info_change_notify(sdata, link,
+ 						  BSS_CHANGED_TXPOWER);
+ }
+ 
+diff --git a/net/mac80211/link.c b/net/mac80211/link.c
+index 11502da..349f596 100644
+--- a/net/mac80211/link.c
++++ b/net/mac80211/link.c
+@@ -37,6 +37,9 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
+ 	link_conf->link_id = link_id;
+ 	link_conf->vif = &sdata->vif;
+ 
++	link->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
++	link->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
++
+ 	wiphy_work_init(&link->csa.finalize_work,
+ 			ieee80211_csa_finalize_work);
+ 	wiphy_work_init(&link->color_change_finalize_work,
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index b684fed..a3873d2 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -2802,7 +2802,7 @@ static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link,
+ 	}
+ 
+ 	link->ap_power_level = new_ap_level;
+-	if (__ieee80211_recalc_txpower(sdata))
++	if (__ieee80211_recalc_txpower(sdata, link))
+ 		return BSS_CHANGED_TXPOWER;
+ 	return 0;
+ }
+diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
+index 36e500d..3e06017 100644
+--- a/net/mac80211/trace.h
++++ b/net/mac80211/trace.h
+@@ -2170,13 +2170,14 @@ DEFINE_EVENT(chanswitch_evt, drv_channel_switch_rx_beacon,
+ TRACE_EVENT(drv_get_txpower,
+ 	TP_PROTO(struct ieee80211_local *local,
+ 		 struct ieee80211_sub_if_data *sdata,
+-		 int dbm, int ret),
++		 unsigned int link_id, int dbm, int ret),
+ 
+-	TP_ARGS(local, sdata, dbm, ret),
++	TP_ARGS(local, sdata, link_id, dbm, ret),
+ 
+ 	TP_STRUCT__entry(
+ 		LOCAL_ENTRY
+ 		VIF_ENTRY
++		__field(unsigned int, link_id)
+ 		__field(int, dbm)
+ 		__field(int, ret)
+ 	),
+@@ -2184,13 +2185,14 @@ TRACE_EVENT(drv_get_txpower,
+ 	TP_fast_assign(
+ 		LOCAL_ASSIGN;
+ 		VIF_ASSIGN;
++		__entry->link_id = link_id;
+ 		__entry->dbm = dbm;
+ 		__entry->ret = ret;
+ 	),
+ 
+ 	TP_printk(
+-		LOCAL_PR_FMT VIF_PR_FMT " dbm:%d ret:%d",
+-		LOCAL_PR_ARG, VIF_PR_ARG, __entry->dbm, __entry->ret
++		LOCAL_PR_FMT VIF_PR_FMT " link_id:%d dbm:%d ret:%d",
++		LOCAL_PR_ARG, VIF_PR_ARG, __entry->link_id, __entry->dbm, __entry->ret
+ 	)
+ );
+ 
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 756a29a..36d35f0 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -3753,6 +3753,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ 		struct wireless_dev *txp_wdev = wdev;
+ 		enum nl80211_tx_power_setting type;
+ 		int idx, mbm = 0;
++		unsigned int link_id = nl80211_link_id(info->attrs);
+ 
+ 		if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
+ 			txp_wdev = NULL;
+@@ -3776,7 +3777,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ 			mbm = nla_get_u32(info->attrs[idx]);
+ 		}
+ 
+-		result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
++		result = rdev_set_tx_power(rdev, txp_wdev, link_id, type, mbm);
+ 		if (result)
+ 			goto out;
+ 	}
+@@ -4047,10 +4048,10 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
+ 			goto nla_put_failure;
+ 	}
+ 
+-	if (rdev->ops->get_tx_power) {
++	if (!wdev->valid_links && rdev->ops->get_tx_power) {
+ 		int dbm, ret;
+ 
+-		ret = rdev_get_tx_power(rdev, wdev, &dbm);
++		ret = rdev_get_tx_power(rdev, wdev, 0, &dbm);
+ 		if (ret == 0 &&
+ 		    nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
+ 				DBM_TO_MBM(dbm)))
+@@ -4119,6 +4120,16 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
+ 			if (ret == 0 && nl80211_send_chandef(msg, &chandef))
+ 				goto nla_put_failure;
+ 
++			if (rdev->ops->get_tx_power) {
++				int dbm, ret;
++
++				ret = rdev_get_tx_power(rdev, wdev, link_id, &dbm);
++				if (ret == 0 &&
++				    nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
++						DBM_TO_MBM(dbm)))
++					goto nla_put_failure;
++			}
++
+ 			nla_nest_end(msg, link);
+ 		}
+ 
+diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
+index 5b3c94f..9b411db 100644
+--- a/net/wireless/rdev-ops.h
++++ b/net/wireless/rdev-ops.h
+@@ -589,21 +589,23 @@ rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed)
+ 
+ static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev,
+ 				    struct wireless_dev *wdev,
++				    unsigned int link_id,
+ 				    enum nl80211_tx_power_setting type, int mbm)
+ {
+ 	int ret;
+-	trace_rdev_set_tx_power(&rdev->wiphy, wdev, type, mbm);
+-	ret = rdev->ops->set_tx_power(&rdev->wiphy, wdev, type, mbm);
++	trace_rdev_set_tx_power(&rdev->wiphy, wdev, link_id, type, mbm);
++	ret = rdev->ops->set_tx_power(&rdev->wiphy, wdev, link_id, type, mbm);
+ 	trace_rdev_return_int(&rdev->wiphy, ret);
+ 	return ret;
+ }
+ 
+ static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev,
+-				    struct wireless_dev *wdev, int *dbm)
++				    struct wireless_dev *wdev,
++				    unsigned int link_id, int *dbm)
+ {
+ 	int ret;
+-	trace_rdev_get_tx_power(&rdev->wiphy, wdev);
+-	ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, dbm);
++	trace_rdev_get_tx_power(&rdev->wiphy, wdev, link_id);
++	ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, link_id, dbm);
+ 	trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm);
+ 	return ret;
+ }
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index 6ff6091..6af432e 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -1688,29 +1688,45 @@ TRACE_EVENT(rdev_set_wiphy_params,
+ 		  WIPHY_PR_ARG, __entry->changed)
+ );
+ 
+-DEFINE_EVENT(wiphy_wdev_evt, rdev_get_tx_power,
+-	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+-	TP_ARGS(wiphy, wdev)
++TRACE_EVENT(rdev_get_tx_power,
++	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
++		 unsigned int link_id),
++	TP_ARGS(wiphy, wdev, link_id),
++	TP_STRUCT__entry(
++		WIPHY_ENTRY
++		WDEV_ENTRY
++		__field(unsigned int, link_id)
++	),
++	TP_fast_assign(
++		WIPHY_ASSIGN;
++		WDEV_ASSIGN;
++		__entry->link_id = link_id;
++	),
++	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %d",
++		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id)
+ );
+ 
+ TRACE_EVENT(rdev_set_tx_power,
+ 	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+-		 enum nl80211_tx_power_setting type, int mbm),
+-	TP_ARGS(wiphy, wdev, type, mbm),
++		 unsigned int link_id, enum nl80211_tx_power_setting type,
++		 int mbm),
++	TP_ARGS(wiphy, wdev, link_id, type, mbm),
+ 	TP_STRUCT__entry(
+ 		WIPHY_ENTRY
+ 		WDEV_ENTRY
++		__field(unsigned int, link_id)
+ 		__field(enum nl80211_tx_power_setting, type)
+ 		__field(int, mbm)
+ 	),
+ 	TP_fast_assign(
+ 		WIPHY_ASSIGN;
+ 		WDEV_ASSIGN;
++		__entry->link_id = link_id;
+ 		__entry->type = type;
+ 		__entry->mbm = mbm;
+ 	),
+-	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", type: %u, mbm: %d",
+-		  WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm)
++	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %d, type: %u, mbm: %d",
++		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id, __entry->type, __entry->mbm)
+ );
+ 
+ TRACE_EVENT(rdev_return_int_int,
+diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
+index 2371069..73ef854 100644
+--- a/net/wireless/wext-compat.c
++++ b/net/wireless/wext-compat.c
+@@ -952,7 +952,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev,
+ 	}
+ 
+ 	wiphy_lock(&rdev->wiphy);
+-	ret = rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
++	ret = rdev_set_tx_power(rdev, wdev, 0, type, DBM_TO_MBM(dbm));
+ 	wiphy_unlock(&rdev->wiphy);
+ 
+ 	return ret;
+@@ -975,7 +975,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev,
+ 		return -EOPNOTSUPP;
+ 
+ 	wiphy_lock(&rdev->wiphy);
+-	err = rdev_get_tx_power(rdev, wdev, &val);
++	err = rdev_get_tx_power(rdev, wdev, 0, &val);
+ 	wiphy_unlock(&rdev->wiphy);
+ 	if (err)
+ 		return err;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0076-mtk-mac80211-add-link-information-when-dump-station.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0076-mtk-mac80211-add-link-information-when-dump-station.patch
new file mode 100644
index 0000000..20d05c5
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0076-mtk-mac80211-add-link-information-when-dump-station.patch
@@ -0,0 +1,657 @@
+From 419c3cdbd941ce47b8b660e7fa69e48b8de5b12b Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Tue, 11 Jun 2024 18:08:13 +0800
+Subject: [PATCH 76/89] mtk: mac80211: add link information when dump station
+
+Report following per-link information to upper-layer application:
+- TX/RX byte counts
+- TX MPDU failed/retried counts
+- RX MPDU total/failed counts
+- TX/RX airtime
+- ACK RSSI
+
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ include/net/cfg80211.h    |  67 ++++++++++++
+ include/net/mac80211.h    |   9 +-
+ net/mac80211/driver-ops.h |  18 ++++
+ net/mac80211/ethtool.c    |  39 +++----
+ net/mac80211/sta_info.c   |  26 +++++
+ net/wireless/nl80211.c    | 211 ++++++++++++++++++++++++++++++++------
+ 6 files changed, 317 insertions(+), 53 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index a63f5bb..110e555 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -2051,6 +2051,64 @@ struct cfg80211_tid_stats {
+ 
+ #define IEEE80211_MAX_CHAINS	4
+ 
++/**
++ * struct station_link_info - station link information
++ *
++ * @filled: bitflag of flags using the bits of &enum nl80211_sta_info to
++ *	indicate the relevant values in this struct for them
++ * @link_addr: link address
++ * @rx_bytes: bytes (size of MPDUs) received from this station link
++ * @tx_bytes: bytes (size of MPDUs) transmitted to this station link
++ * @signal: The signal strength, type depends on the wiphy's signal_type.
++ *	For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
++ * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
++ *	For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
++ * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
++ * @chain_signal: per-chain signal strength of last received packet in dBm
++ * @chain_signal_avg: per-chain signal strength average in dBm
++ * @txrate: current unicast bitrate to this station link
++ * @rxrate: current unicast bitrate from this station link
++ * @tx_retries: cumulative retry counts (MPDUs)
++ * @tx_failed: number of failed transmissions (MPDUs) (retries exceeded, no ACK)
++ * @bss_param: current BSS parameters
++ * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer
++ * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer
++ * @ack_signal: signal strength (in dBm) of the last ACK frame.
++ * @avg_ack_signal: average rssi value of ack packet for the no of msdu's has
++ *	been sent.
++ * @rx_mpdu_count: number of MPDUs received from this station link
++ * @fcs_err_count: number of packets (MPDUs) received from this station link with
++ *	an FCS error. This counter should be incremented only when TA of the
++ *	received packet with an FCS error matches the peer MAC address.
++ */
++struct station_link_info {
++	u64 filled;
++	u8 link_addr[ETH_ALEN] __aligned(2);
++	u64 rx_bytes;
++	u64 tx_bytes;
++	s8 signal;
++	s8 signal_avg;
++
++	u8 chains;
++	s8 chain_signal[IEEE80211_MAX_CHAINS];
++	s8 chain_signal_avg[IEEE80211_MAX_CHAINS];
++
++	struct rate_info txrate;
++	struct rate_info rxrate;
++	u32 tx_retries;
++	u32 tx_failed;
++	struct sta_bss_parameters bss_param;
++
++	u64 tx_duration;
++	u64 rx_duration;
++
++	s8 ack_signal;
++	s8 avg_ack_signal;
++
++	u32 rx_mpdu_count;
++	u32 fcs_err_count;
++};
++
+ /**
+  * struct station_info - station information
+  *
+@@ -2200,6 +2258,15 @@ struct station_info {
+ 	u8 mld_addr[ETH_ALEN] __aligned(2);
+ 	const u8 *assoc_resp_ies;
+ 	size_t assoc_resp_ies_len;
++
++	u16 valid_links;
++
++	/*
++	 * FIXME: Should be refactored to legacy (real) + links (pointer)
++	 * for saving memory space, as MAX_NUM_LINKS is 15 which would
++	 * cause much of the space allocated but never unused
++	 */
++	struct station_link_info links[IEEE80211_MLD_MAX_NUM_LINKS];
+ };
+ 
+ /**
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 30aa436..916f37c 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1491,7 +1491,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
+  * @RX_FLAG_AMPDU_EOF_BIT_KNOWN: The EOF value is known
+  * @RX_FLAG_RADIOTAP_HE: HE radiotap data is present
+  *	(&struct ieee80211_radiotap_he, mac80211 will fill in
+- *	
++ *
+  *	 - DATA3_DATA_MCS
+  *	 - DATA3_DATA_DCM
+  *	 - DATA3_CODING
+@@ -1499,7 +1499,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
+  *	 - DATA5_DATA_BW_RU_ALLOC
+  *	 - DATA6_NSTS
+  *	 - DATA3_STBC
+- *	
++ *
+  *	from the RX info data, so leave those zeroed when building this data)
+  * @RX_FLAG_RADIOTAP_HE_MU: HE MU radiotap data is present
+  *	(&struct ieee80211_radiotap_he_mu)
+@@ -4581,6 +4581,11 @@ struct ieee80211_ops {
+ 			       struct ieee80211_vif *vif,
+ 			       struct ieee80211_sta *sta,
+ 			       struct station_info *sinfo);
++	void (*sta_link_statistics)(struct ieee80211_hw *hw,
++				    struct ieee80211_vif *vif,
++				    struct ieee80211_sta *sta,
++				    unsigned int link_id,
++				    struct station_link_info *linfo);
+ 	int (*conf_tx)(struct ieee80211_hw *hw,
+ 		       struct ieee80211_vif *vif,
+ 		       unsigned int link_id, u16 ac,
+diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
+index aca4426..b76fae2 100644
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -631,6 +631,24 @@ static inline void drv_sta_statistics(struct ieee80211_local *local,
+ 	trace_drv_return_void(local);
+ }
+ 
++static inline void drv_sta_link_statistics(struct ieee80211_local *local,
++					   struct ieee80211_sub_if_data *sdata,
++					   struct ieee80211_sta *sta,
++					   unsigned int link_id,
++					   struct station_link_info *linfo)
++{
++	might_sleep();
++	lockdep_assert_wiphy(local->hw.wiphy);
++
++	sdata = get_bss_sdata(sdata);
++	if (!check_sdata_in_driver(sdata))
++		return;
++
++	if (local->ops->sta_link_statistics)
++		local->ops->sta_link_statistics(&local->hw, &sdata->vif, sta,
++						link_id, linfo);
++}
++
+ int drv_conf_tx(struct ieee80211_local *local,
+ 		struct ieee80211_link_data *link, u16 ac,
+ 		const struct ieee80211_tx_queue_params *params);
+diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c
+index 03c2de9..0f25fb9 100644
+--- a/net/mac80211/ethtool.c
++++ b/net/mac80211/ethtool.c
+@@ -89,7 +89,7 @@ static void ieee80211_get_stats(struct net_device *dev,
+ 	struct ieee80211_channel *channel;
+ 	struct sta_info *sta;
+ 	struct ieee80211_local *local = sdata->local;
+-	struct station_info sinfo;
++	struct station_info *sinfo;
+ 	struct survey_info survey;
+ 	int i, q;
+ #define STA_STATS_SURVEY_LEN 7
+@@ -98,17 +98,17 @@ static void ieee80211_get_stats(struct net_device *dev,
+ 
+ #define ADD_STA_STATS(sta)					\
+ 	do {							\
+-		data[i++] += sinfo.rx_packets;			\
+-		data[i++] += sinfo.rx_bytes;			\
++		data[i++] += sinfo->rx_packets;			\
++		data[i++] += sinfo->rx_bytes;			\
+ 		data[i++] += (sta)->rx_stats.num_duplicates;	\
+ 		data[i++] += (sta)->rx_stats.fragments;		\
+-		data[i++] += sinfo.rx_dropped_misc;		\
++		data[i++] += sinfo->rx_dropped_misc;		\
+ 								\
+-		data[i++] += sinfo.tx_packets;			\
+-		data[i++] += sinfo.tx_bytes;			\
++		data[i++] += sinfo->tx_packets;			\
++		data[i++] += sinfo->tx_bytes;			\
+ 		data[i++] += (sta)->status_stats.filtered;	\
+-		data[i++] += sinfo.tx_failed;			\
+-		data[i++] += sinfo.tx_retries;			\
++		data[i++] += sinfo->tx_failed;			\
++		data[i++] += sinfo->tx_retries;			\
+ 	} while (0)
+ 
+ 	/* For Managed stations, find the single station based on BSSID
+@@ -116,6 +116,9 @@ static void ieee80211_get_stats(struct net_device *dev,
+ 	 * stations and add stats for any station that is assigned to this
+ 	 * network device.
+ 	 */
++	sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
++	if (!sinfo)
++		return;
+ 
+ 	wiphy_lock(local->hw.wiphy);
+ 
+@@ -125,8 +128,7 @@ static void ieee80211_get_stats(struct net_device *dev,
+ 		if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
+ 			goto do_survey;
+ 
+-		memset(&sinfo, 0, sizeof(sinfo));
+-		sta_set_sinfo(sta, &sinfo, false);
++		sta_set_sinfo(sta, sinfo, false);
+ 
+ 		i = 0;
+ 		ADD_STA_STATS(&sta->deflink);
+@@ -134,17 +136,17 @@ static void ieee80211_get_stats(struct net_device *dev,
+ 		data[i++] = sta->sta_state;
+ 
+ 
+-		if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))
++		if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))
+ 			data[i] = 100000ULL *
+-				cfg80211_calculate_bitrate(&sinfo.txrate);
++				cfg80211_calculate_bitrate(&sinfo->txrate);
+ 		i++;
+-		if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE))
++		if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE))
+ 			data[i] = 100000ULL *
+-				cfg80211_calculate_bitrate(&sinfo.rxrate);
++				cfg80211_calculate_bitrate(&sinfo->rxrate);
+ 		i++;
+ 
+-		if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))
+-			data[i] = (u8)sinfo.signal_avg;
++		if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))
++			data[i] = (u8)sinfo->signal_avg;
+ 		i++;
+ 	} else {
+ 		list_for_each_entry(sta, &local->sta_list, list) {
+@@ -152,14 +154,15 @@ static void ieee80211_get_stats(struct net_device *dev,
+ 			if (sta->sdata->dev != dev)
+ 				continue;
+ 
+-			memset(&sinfo, 0, sizeof(sinfo));
+-			sta_set_sinfo(sta, &sinfo, false);
++			memset(sinfo, 0, sizeof(*sinfo));
++			sta_set_sinfo(sta, sinfo, false);
+ 			i = 0;
+ 			ADD_STA_STATS(&sta->deflink);
+ 		}
+ 	}
+ 
+ do_survey:
++	kfree(sinfo);
+ 	i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
+ 	/* Get survey stats for current channel */
+ 	survey.filled = 0;
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 57a2809..b1eb519 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2862,6 +2862,32 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
+ 		sinfo->airtime_link_metric =
+ 			airtime_link_metric_get(local, sta);
+ 	}
++
++	sinfo->valid_links = sta->sta.valid_links;
++	if (sinfo->valid_links) {
++		unsigned int link_id;
++
++		sinfo->mlo_params_valid = true;
++		memcpy(sinfo->mld_addr, sta->sta.addr, ETH_ALEN);
++		for_each_valid_link(sinfo, link_id) {
++			struct ieee80211_link_sta *link_sta =
++				link_sta_dereference_protected(&sta->sta, link_id);
++			struct ieee80211_bss_conf *link_conf =
++				sdata_dereference(sdata->vif.link_conf[link_id],
++						  sdata);
++			struct station_link_info *linfo = &sinfo->links[link_id];
++
++			if (!link_sta || !link_conf)
++				continue;
++
++			memcpy(linfo->link_addr, link_sta->addr, ETH_ALEN);
++			drv_sta_link_statistics(local, sdata, &sta->sta,
++						link_id, linfo);
++			linfo->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
++			linfo->bss_param.dtim_period = link_conf->dtim_period;
++			linfo->bss_param.beacon_interval = link_conf->beacon_int;
++		}
++	}
+ }
+ 
+ u32 sta_get_expected_throughput(struct sta_info *sta)
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 36d35f0..e62116e 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -6939,14 +6939,121 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
+ 		goto nla_put_failure;
+ 
+ 	if (sinfo->mlo_params_valid) {
+-		if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID,
+-			       sinfo->assoc_link_id))
+-			goto nla_put_failure;
++		struct nlattr *nested;
++		unsigned int link_id;
++		int i = 1;
+ 
+ 		if (!is_zero_ether_addr(sinfo->mld_addr) &&
+ 		    nla_put(msg, NL80211_ATTR_MLD_ADDR, ETH_ALEN,
+ 			    sinfo->mld_addr))
+ 			goto nla_put_failure;
++
++		nested = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS);
++		if (!nested)
++			goto nla_put_failure;
++
++		for_each_valid_link(sinfo, link_id) {
++			struct nlattr *nested_mlo_links;
++			struct station_link_info *linfo = &sinfo->links[link_id];
++
++			nested_mlo_links = nla_nest_start(msg, i);
++			if (!nested_mlo_links)
++				goto nla_put_failure;
++
++			if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id) ||
++			    (linfo->link_addr &&
++			    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
++				    linfo->link_addr)))
++				goto nla_put_failure;
++
++			sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO);
++			if (!sinfoattr)
++				goto nla_put_failure;
++
++#define PUT_LINFO(attr, memb, type) do {				\
++	BUILD_BUG_ON(sizeof(type) == sizeof(u64));			\
++	if (linfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) &&	\
++	    nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr,		\
++			     linfo->memb))				\
++		goto nla_put_failure;					\
++	} while (0)
++#define PUT_LINFO_U64(attr, memb) do {					\
++	if (linfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) &&	\
++	    nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr,		\
++			      linfo->memb, NL80211_STA_INFO_PAD))	\
++		goto nla_put_failure;					\
++	} while (0)
++
++			PUT_LINFO_U64(RX_BYTES64, rx_bytes);
++			PUT_LINFO_U64(TX_BYTES64, tx_bytes);
++			PUT_LINFO_U64(RX_DURATION, rx_duration);
++			PUT_LINFO_U64(TX_DURATION, tx_duration);
++
++			switch (rdev->wiphy.signal_type) {
++			case CFG80211_SIGNAL_TYPE_MBM:
++				PUT_LINFO(SIGNAL, signal, u8);
++				PUT_LINFO(SIGNAL_AVG, signal_avg, u8);
++				break;
++			default:
++				break;
++			}
++			if (linfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
++				if (!nl80211_put_signal(msg, linfo->chains,
++							linfo->chain_signal,
++							NL80211_STA_INFO_CHAIN_SIGNAL))
++					goto nla_put_failure;
++			}
++			if (linfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
++				if (!nl80211_put_signal(msg, linfo->chains,
++							linfo->chain_signal_avg,
++							NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
++					goto nla_put_failure;
++			}
++			if (linfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
++				if (!nl80211_put_sta_rate(msg, &linfo->txrate,
++							  NL80211_STA_INFO_TX_BITRATE))
++					goto nla_put_failure;
++			}
++			if (linfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
++				if (!nl80211_put_sta_rate(msg, &linfo->rxrate,
++							  NL80211_STA_INFO_RX_BITRATE))
++					goto nla_put_failure;
++			}
++
++			PUT_LINFO(TX_RETRIES, tx_retries, u32);
++			PUT_LINFO(TX_FAILED, tx_failed, u32);
++
++			if (linfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
++				bss_param = nla_nest_start_noflag(msg,
++								  NL80211_STA_INFO_BSS_PARAM);
++				if (!bss_param)
++					goto nla_put_failure;
++
++				if (nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
++					       linfo->bss_param.dtim_period) ||
++				    nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
++						linfo->bss_param.beacon_interval))
++					goto nla_put_failure;
++
++				nla_nest_end(msg, bss_param);
++			}
++
++			PUT_LINFO(RX_MPDUS, rx_mpdu_count, u32);
++			PUT_LINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
++			if (wiphy_ext_feature_isset(&rdev->wiphy,
++						    NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
++				PUT_LINFO(ACK_SIGNAL, ack_signal, u8);
++				PUT_LINFO(ACK_SIGNAL_AVG, avg_ack_signal, u8);
++			}
++
++#undef PUT_LINFO
++#undef PUT_LINFO_U64
++
++			nla_nest_end(msg, sinfoattr);
++			nla_nest_end(msg, nested_mlo_links);
++			i++;
++		}
++		nla_nest_end(msg, nested);
+ 	}
+ 
+ 	cfg80211_sinfo_release_content(sinfo);
+@@ -6962,7 +7069,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
+ static int nl80211_dump_station(struct sk_buff *skb,
+ 				struct netlink_callback *cb)
+ {
+-	struct station_info sinfo;
++	struct station_info *sinfo;
+ 	struct cfg80211_registered_device *rdev;
+ 	struct wireless_dev *wdev;
+ 	u8 mac_addr[ETH_ALEN];
+@@ -6972,6 +7079,10 @@ static int nl80211_dump_station(struct sk_buff *skb,
+ 	err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
+ 	if (err)
+ 		return err;
++
++	sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
++	if (!sinfo)
++		return -ENOMEM;
+ 	/* nl80211_prepare_wdev_dump acquired it in the successful case */
+ 	__acquire(&rdev->wiphy.mtx);
+ 
+@@ -6986,9 +7097,9 @@ static int nl80211_dump_station(struct sk_buff *skb,
+ 	}
+ 
+ 	while (1) {
+-		memset(&sinfo, 0, sizeof(sinfo));
++		memset(sinfo, 0, sizeof(*sinfo));
+ 		err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
+-					mac_addr, &sinfo);
++					mac_addr, sinfo);
+ 		if (err == -ENOENT)
+ 			break;
+ 		if (err)
+@@ -6998,7 +7109,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
+ 				NETLINK_CB(cb->skb).portid,
+ 				cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ 				rdev, wdev->netdev, mac_addr,
+-				&sinfo) < 0)
++				sinfo) < 0)
+ 			goto out;
+ 
+ 		sta_idx++;
+@@ -7009,6 +7120,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
+ 	err = skb->len;
+  out_err:
+ 	wiphy_unlock(&rdev->wiphy);
++	kfree(sinfo);
+ 
+ 	return err;
+ }
+@@ -7017,13 +7129,11 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
+ {
+ 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ 	struct net_device *dev = info->user_ptr[1];
+-	struct station_info sinfo;
++	struct station_info *sinfo;
+ 	struct sk_buff *msg;
+ 	u8 *mac_addr = NULL;
+ 	int err;
+ 
+-	memset(&sinfo, 0, sizeof(sinfo));
+-
+ 	if (!info->attrs[NL80211_ATTR_MAC])
+ 		return -EINVAL;
+ 
+@@ -7032,24 +7142,35 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
+ 	if (!rdev->ops->get_station)
+ 		return -EOPNOTSUPP;
+ 
+-	err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
++	sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
++	if (!sinfo)
++		return -ENOMEM;
++
++	err = rdev_get_station(rdev, dev, mac_addr, sinfo);
+ 	if (err)
+-		return err;
++		goto out;
+ 
+ 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ 	if (!msg) {
+-		cfg80211_sinfo_release_content(&sinfo);
+-		return -ENOMEM;
++		cfg80211_sinfo_release_content(sinfo);
++		err = -ENOMEM;
++		goto out;
+ 	}
+ 
+ 	if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
+ 				 info->snd_portid, info->snd_seq, 0,
+-				 rdev, dev, mac_addr, &sinfo) < 0) {
++				 rdev, dev, mac_addr, sinfo) < 0) {
+ 		nlmsg_free(msg);
+-		return -ENOBUFS;
++		err = -ENOBUFS;
++		goto out;
+ 	}
+ 
+-	return genlmsg_reply(msg, info);
++	err = genlmsg_reply(msg, info);
++
++out:
++	kfree(sinfo);
++
++	return err;
+ }
+ 
+ int cfg80211_check_station_change(struct wiphy *wiphy,
+@@ -13098,19 +13219,27 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
+ 	if (!cqm_config->last_rssi_event_value &&
+ 	    wdev->links[0].client.current_bss &&
+ 	    rdev->ops->get_station) {
+-		struct station_info sinfo = {};
++		struct station_info *sinfo;
+ 		u8 *mac_addr;
+ 
++		sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
++		if (!sinfo)
++			return -ENOMEM;
++
+ 		mac_addr = wdev->links[0].client.current_bss->pub.bssid;
+ 
+-		err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
+-		if (err)
++		err = rdev_get_station(rdev, dev, mac_addr, sinfo);
++		if (err) {
++			kfree(sinfo);
+ 			return err;
++		}
+ 
+-		cfg80211_sinfo_release_content(&sinfo);
+-		if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
++		cfg80211_sinfo_release_content(sinfo);
++		if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
+ 			cqm_config->last_rssi_event_value =
+-				(s8) sinfo.rx_beacon_signal_avg;
++				(s8) sinfo->rx_beacon_signal_avg;
++
++		kfree(sinfo);
+ 	}
+ 
+ 	last = cqm_config->last_rssi_event_value;
+@@ -15997,7 +16126,7 @@ static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
+ 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ 	struct net_device *dev = info->user_ptr[1];
+ 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+-	struct station_info sinfo = {};
++	struct station_info *sinfo;
+ 	const u8 *buf;
+ 	size_t len;
+ 	u8 *dest;
+@@ -16026,13 +16155,22 @@ static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
+ 	    !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
+ 		return -EINVAL;
+ 
+-	err = rdev_get_station(rdev, dev, dest, &sinfo);
++	sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
++	if (!sinfo)
++		return -ENOMEM;
++
++	err = rdev_get_station(rdev, dev, dest, sinfo);
+ 	if (err)
+-		return err;
++		goto out;
+ 
+-	cfg80211_sinfo_release_content(&sinfo);
++	cfg80211_sinfo_release_content(sinfo);
+ 
+-	return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
++	err = rdev_probe_mesh_link(rdev, dev, dest, buf, len);
++
++out:
++	kfree(sinfo);
++
++	return err;
+ }
+ 
+ static int parse_tid_conf(struct cfg80211_registered_device *rdev,
+@@ -18981,27 +19119,34 @@ void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
+ 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+ 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ 	struct sk_buff *msg;
+-	struct station_info empty_sinfo = {};
++	bool new_allocate = false;
+ 
+-	if (!sinfo)
+-		sinfo = &empty_sinfo;
++	if (!sinfo) {
++		sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
++		if (!sinfo)
++			return;
++		new_allocate = true;
++	}
+ 
+ 	trace_cfg80211_del_sta(dev, mac_addr);
+ 
+ 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ 	if (!msg) {
+ 		cfg80211_sinfo_release_content(sinfo);
+-		return;
++		goto out;
+ 	}
+ 
+ 	if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
+ 				 rdev, dev, mac_addr, sinfo) < 0) {
+ 		nlmsg_free(msg);
+-		return;
++		goto out;
+ 	}
+ 
+ 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+ 				NL80211_MCGRP_MLME, gfp);
++out:
++	if (new_allocate)
++		kfree(sinfo);
+ }
+ EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0077-mtk-mac80211-add-new-argument-link_id-in-set_bitrate.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0077-mtk-mac80211-add-new-argument-link_id-in-set_bitrate.patch
new file mode 100644
index 0000000..f8cc34b
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0077-mtk-mac80211-add-new-argument-link_id-in-set_bitrate.patch
@@ -0,0 +1,114 @@
+From 39cfb7b5c0e2b92676a351c4bc3949f79bd41a86 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Thu, 30 May 2024 16:08:54 +0800
+Subject: [PATCH 77/89] mtk: mac80211: add new argument link_id in
+ set_bitrate_mask
+
+mt76 driver needs link id to fix parital rate on the specific link.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+
+---
+ include/net/mac80211.h    |  3 ++-
+ net/mac80211/cfg.c        |  2 +-
+ net/mac80211/driver-ops.h |  7 ++++---
+ net/mac80211/trace.h      | 12 ++++++++----
+ 4 files changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 916f37c..08c15a7 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -4665,7 +4665,8 @@ struct ieee80211_ops {
+ 			      u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
+ 	bool (*tx_frames_pending)(struct ieee80211_hw *hw);
+ 	int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-				const struct cfg80211_bitrate_mask *mask);
++				const struct cfg80211_bitrate_mask *mask,
++				unsigned int link_id);
+ 	void (*event_callback)(struct ieee80211_hw *hw,
+ 			       struct ieee80211_vif *vif,
+ 			       const struct ieee80211_event *event);
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 19171b0..51a9b21 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3448,7 +3448,7 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
+ 	}
+ 
+ 	if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
+-		ret = drv_set_bitrate_mask(local, sdata, mask);
++		ret = drv_set_bitrate_mask(local, sdata, mask, link_id);
+ 		if (ret)
+ 			return ret;
+ 	}
+diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
+index b76fae2..4c0ac85 100644
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -865,7 +865,8 @@ static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
+ 
+ static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
+ 				       struct ieee80211_sub_if_data *sdata,
+-				       const struct cfg80211_bitrate_mask *mask)
++				       const struct cfg80211_bitrate_mask *mask,
++				       unsigned int link_id)
+ {
+ 	int ret = -EOPNOTSUPP;
+ 
+@@ -875,10 +876,10 @@ static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
+ 	if (!check_sdata_in_driver(sdata))
+ 		return -EIO;
+ 
+-	trace_drv_set_bitrate_mask(local, sdata, mask);
++	trace_drv_set_bitrate_mask(local, sdata, mask, link_id);
+ 	if (local->ops->set_bitrate_mask)
+ 		ret = local->ops->set_bitrate_mask(&local->hw,
+-						   &sdata->vif, mask);
++						   &sdata->vif, mask, link_id);
+ 	trace_drv_return_int(local, ret);
+ 
+ 	return ret;
+diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
+index 3e06017..48fcc8f 100644
+--- a/net/mac80211/trace.h
++++ b/net/mac80211/trace.h
+@@ -1418,15 +1418,17 @@ DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait,
+ TRACE_EVENT(drv_set_bitrate_mask,
+ 	TP_PROTO(struct ieee80211_local *local,
+ 		 struct ieee80211_sub_if_data *sdata,
+-		 const struct cfg80211_bitrate_mask *mask),
++		 const struct cfg80211_bitrate_mask *mask,
++		 unsigned int link_id),
+ 
+-	TP_ARGS(local, sdata, mask),
++	TP_ARGS(local, sdata, mask, link_id),
+ 
+ 	TP_STRUCT__entry(
+ 		LOCAL_ENTRY
+ 		VIF_ENTRY
+ 		__field(u32, legacy_2g)
+ 		__field(u32, legacy_5g)
++		__field(unsigned int, link_id)
+ 	),
+ 
+ 	TP_fast_assign(
+@@ -1434,11 +1436,13 @@ TRACE_EVENT(drv_set_bitrate_mask,
+ 		VIF_ASSIGN;
+ 		__entry->legacy_2g = mask->control[NL80211_BAND_2GHZ].legacy;
+ 		__entry->legacy_5g = mask->control[NL80211_BAND_5GHZ].legacy;
++		__entry->link_id = link_id;
+ 	),
+ 
+ 	TP_printk(
+-		LOCAL_PR_FMT  VIF_PR_FMT " 2G Mask:0x%x 5G Mask:0x%x",
+-		LOCAL_PR_ARG, VIF_PR_ARG, __entry->legacy_2g, __entry->legacy_5g
++		LOCAL_PR_FMT  VIF_PR_FMT " 2G Mask:0x%x 5G Mask:0x%x, link_id: %d",
++		LOCAL_PR_ARG, VIF_PR_ARG, __entry->legacy_2g, __entry->legacy_5g,
++		__entry->link_id
+ 	)
+ );
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0078-mtk-mac80211-add-per-radio-antenna-config.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0078-mtk-mac80211-add-per-radio-antenna-config.patch
new file mode 100644
index 0000000..44043ac
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0078-mtk-mac80211-add-per-radio-antenna-config.patch
@@ -0,0 +1,463 @@
+From a218fd8e2e8a2d390d995e62ba9e351c6cee30fb Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 11 Jun 2024 16:10:12 +0800
+Subject: [PATCH 78/89] mtk: mac80211: add per-radio antenna config
+
+Add per-radio antenna config
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h    |  9 ++--
+ include/net/mac80211.h    |  4 +-
+ net/mac80211/cfg.c        | 19 +++++---
+ net/mac80211/driver-ops.h | 12 ++---
+ net/mac80211/trace.h      | 22 +++++----
+ net/wireless/nl80211.c    | 97 +++++++++++++++++++++++++--------------
+ net/wireless/rdev-ops.h   | 12 ++---
+ net/wireless/trace.h      | 24 ++++++----
+ 8 files changed, 122 insertions(+), 77 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 110e555..835735f 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4881,8 +4881,8 @@ struct cfg80211_ops {
+ 						   struct wireless_dev *wdev,
+ 						   struct mgmt_frame_regs *upd);
+ 
+-	int	(*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
+-	int	(*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant);
++	int	(*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant, int band);
++	int	(*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant, int band);
+ 
+ 	int	(*sched_scan_start)(struct wiphy *wiphy,
+ 				struct net_device *dev,
+@@ -5831,8 +5831,9 @@ struct wiphy {
+ 
+ 	u8 max_num_pmkids;
+ 
+-	u32 available_antennas_tx;
+-	u32 available_antennas_rx;
++	/* FIXME: This should move to per-radio data struct */
++	u32 available_antennas_tx[NUM_NL80211_BANDS];
++	u32 available_antennas_rx[NUM_NL80211_BANDS];
+ 
+ 	u32 probe_resp_offload;
+ 
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 08c15a7..9471892 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -4650,8 +4650,8 @@ struct ieee80211_ops {
+ 	void (*channel_switch)(struct ieee80211_hw *hw,
+ 			       struct ieee80211_vif *vif,
+ 			       struct ieee80211_channel_switch *ch_switch);
+-	int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
+-	int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
++	int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant, int band);
++	int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant, int band);
+ 
+ 	int (*remain_on_channel)(struct ieee80211_hw *hw,
+ 				 struct ieee80211_vif *vif,
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 51a9b21..69c3e81 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -4255,15 +4255,22 @@ ieee80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
+ 		ieee80211_configure_filter(local);
+ }
+ 
+-static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
++static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant, int band)
+ {
+ 	struct ieee80211_local *local = wiphy_priv(wiphy);
+ 	int ret;
+ 
+-	if (local->started)
+-		return -EOPNOTSUPP;
++	/* FIXME:
++	 * This flag should be moved to per-radio data struct; otherwise,
++	 * radio 1 or 2 will be blocked when radio 0 is started.
++	 * Temporarily disable this check until we have a better solution.
++	 * if (local->started)
++	 *	return -EOPNOTSUPP;
++	 */
++	wiphy_info(wiphy,
++		   "Temporarily disable local->started check during setting antenna\n");
+ 
+-	ret = drv_set_antenna(local, tx_ant, rx_ant);
++	ret = drv_set_antenna(local, tx_ant, rx_ant, band);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -4271,11 +4278,11 @@ static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
+ 	return 0;
+ }
+ 
+-static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
++static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant, int band)
+ {
+ 	struct ieee80211_local *local = wiphy_priv(wiphy);
+ 
+-	return drv_get_antenna(local, tx_ant, rx_ant);
++	return drv_get_antenna(local, tx_ant, rx_ant, band);
+ }
+ 
+ static int ieee80211_set_rekey_data(struct wiphy *wiphy,
+diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
+index 4c0ac85..3bf8768 100644
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -762,26 +762,26 @@ static inline void drv_channel_switch(struct ieee80211_local *local,
+ 
+ 
+ static inline int drv_set_antenna(struct ieee80211_local *local,
+-				  u32 tx_ant, u32 rx_ant)
++				  u32 tx_ant, u32 rx_ant, int band)
+ {
+ 	int ret = -EOPNOTSUPP;
+ 	might_sleep();
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 	if (local->ops->set_antenna)
+-		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
+-	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
++		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant, band);
++	trace_drv_set_antenna(local, tx_ant, rx_ant, band, ret);
+ 	return ret;
+ }
+ 
+ static inline int drv_get_antenna(struct ieee80211_local *local,
+-				  u32 *tx_ant, u32 *rx_ant)
++				  u32 *tx_ant, u32 *rx_ant, int band)
+ {
+ 	int ret = -EOPNOTSUPP;
+ 	might_sleep();
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+ 	if (local->ops->get_antenna)
+-		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
+-	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
++		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant, band);
++	trace_drv_get_antenna(local, *tx_ant, *rx_ant, band, ret);
+ 	return ret;
+ }
+ 
+diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
+index 48fcc8f..84b5c35 100644
+--- a/net/mac80211/trace.h
++++ b/net/mac80211/trace.h
+@@ -1263,14 +1263,16 @@ DEFINE_EVENT(chanswitch_evt, drv_channel_switch,
+ );
+ 
+ TRACE_EVENT(drv_set_antenna,
+-	TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret),
++	TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant,
++		 int band, int ret),
+ 
+-	TP_ARGS(local, tx_ant, rx_ant, ret),
++	TP_ARGS(local, tx_ant, rx_ant, band, ret),
+ 
+ 	TP_STRUCT__entry(
+ 		LOCAL_ENTRY
+ 		__field(u32, tx_ant)
+ 		__field(u32, rx_ant)
++		__field(int, band)
+ 		__field(int, ret)
+ 	),
+ 
+@@ -1278,24 +1280,27 @@ TRACE_EVENT(drv_set_antenna,
+ 		LOCAL_ASSIGN;
+ 		__entry->tx_ant = tx_ant;
+ 		__entry->rx_ant = rx_ant;
++		__entry->band = band;
+ 		__entry->ret = ret;
+ 	),
+ 
+ 	TP_printk(
+-		LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d",
+-		LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret
++		LOCAL_PR_FMT " tx_ant:%d rx_ant:%d band:%d ret:%d",
++		LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant,
++		__entry->band, __entry->ret
+ 	)
+ );
+ 
+ TRACE_EVENT(drv_get_antenna,
+-	TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret),
++	TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int band, int ret),
+ 
+-	TP_ARGS(local, tx_ant, rx_ant, ret),
++	TP_ARGS(local, tx_ant, rx_ant, band, ret),
+ 
+ 	TP_STRUCT__entry(
+ 		LOCAL_ENTRY
+ 		__field(u32, tx_ant)
+ 		__field(u32, rx_ant)
++		__field(int, band)
+ 		__field(int, ret)
+ 	),
+ 
+@@ -1303,12 +1308,13 @@ TRACE_EVENT(drv_get_antenna,
+ 		LOCAL_ASSIGN;
+ 		__entry->tx_ant = tx_ant;
+ 		__entry->rx_ant = rx_ant;
++		__entry->rx_ant = band;
+ 		__entry->ret = ret;
+ 	),
+ 
+ 	TP_printk(
+-		LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d",
+-		LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret
++		LOCAL_PR_FMT " tx_ant:%d rx_ant:%d band:%d ret:%d",
++		LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->band, __entry->ret
+ 	)
+ );
+ 
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index e62116e..c38a5d0 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -618,8 +618,6 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
+ 	[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
+ 	[NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
+-	[NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
+-	[NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
+ 	[NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
+ 	[NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
+@@ -2626,10 +2624,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
+ 		    nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
+ 			goto nla_put_failure;
+ 
+-		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
+-				rdev->wiphy.available_antennas_tx) ||
+-		    nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
+-				rdev->wiphy.available_antennas_rx))
++		if (nla_put(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
++			    sizeof(rdev->wiphy.available_antennas_tx),
++			    rdev->wiphy.available_antennas_tx) ||
++		    nla_put(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
++			    sizeof(rdev->wiphy.available_antennas_rx),
++			    rdev->wiphy.available_antennas_rx))
+ 			goto nla_put_failure;
+ 
+ 		if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
+@@ -2637,22 +2637,29 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
+ 				rdev->wiphy.probe_resp_offload))
+ 			goto nla_put_failure;
+ 
+-		if ((rdev->wiphy.available_antennas_tx ||
+-		     rdev->wiphy.available_antennas_rx) &&
+-		    rdev->ops->get_antenna) {
+-			u32 tx_ant = 0, rx_ant = 0;
++		if (rdev->ops->get_antenna) {
++			u32 tx_ants[NUM_NL80211_BANDS], rx_ants[NUM_NL80211_BANDS];
++			u32 tx_ant, rx_ant;
+ 			int res;
+ 
+-			res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
+-			if (!res) {
+-				if (nla_put_u32(msg,
+-						NL80211_ATTR_WIPHY_ANTENNA_TX,
+-						tx_ant) ||
+-				    nla_put_u32(msg,
+-						NL80211_ATTR_WIPHY_ANTENNA_RX,
+-						rx_ant))
+-					goto nla_put_failure;
++			memset(tx_ants, 0, sizeof(tx_ants));
++			memset(rx_ants, 0, sizeof(rx_ants));
++			for (i = 0; i < NUM_NL80211_BANDS; i++) {
++				if (!rdev->wiphy.available_antennas_tx[i] ||
++				    !rdev->wiphy.available_antennas_rx[i])
++					continue;
++
++				res = rdev_get_antenna(rdev, &tx_ant, &rx_ant, i);
++				if (!res) {
++					tx_ants[i] = tx_ant;
++					rx_ants[i] = rx_ant;
++				}
+ 			}
++			if (nla_put(msg, NL80211_ATTR_WIPHY_ANTENNA_TX,
++				    sizeof(tx_ants), tx_ants) ||
++			    nla_put(msg, NL80211_ATTR_WIPHY_ANTENNA_RX,
++				    sizeof(rx_ants), rx_ants))
++				goto nla_put_failure;
+ 		}
+ 
+ 		state->split_start++;
+@@ -3784,32 +3791,52 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ 
+ 	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+ 	    info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+-		u32 tx_ant, rx_ant;
++		u32 *tx_ants, *rx_ants;
++		int bandid, tx_num, rx_num;
+ 
+-		if ((!rdev->wiphy.available_antennas_tx &&
+-		     !rdev->wiphy.available_antennas_rx) ||
+-		    !rdev->ops->set_antenna) {
++		if (!rdev->ops->set_antenna) {
+ 			result = -EOPNOTSUPP;
+ 			goto out;
+ 		}
+ 
+-		tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
+-		rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
+-
+-		/* reject antenna configurations which don't match the
+-		 * available antenna masks, except for the "all" mask */
+-		if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
+-		    (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
++		tx_num = nla_len(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]) / sizeof(u32);
++		rx_num = nla_len(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) / sizeof(u32);
++		if (tx_num != rx_num || tx_num != NUM_NL80211_BANDS) {
+ 			result = -EINVAL;
+ 			goto out;
+ 		}
++		tx_ants = nla_data(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
++		rx_ants = nla_data(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
+ 
+-		tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
+-		rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
++		/* reject antenna configurations which don't match the
++		 * available antenna masks in wiphy, except for the "all" mask
++		 */
++		for (bandid = 0; bandid < NUM_NL80211_BANDS; bandid++) {
++			struct ieee80211_supported_band *sband = rdev->wiphy.bands[bandid];
++			u32 tx_ant = tx_ants[bandid], rx_ant = rx_ants[bandid];
++			u32 avail_ants_tx = rdev->wiphy.available_antennas_tx[bandid];
++			u32 avail_ants_rx = rdev->wiphy.available_antennas_rx[bandid];
+ 
+-		result = rdev_set_antenna(rdev, tx_ant, rx_ant);
+-		if (result)
+-			goto out;
++			if (!sband || !tx_ant || !rx_ant)
++				continue;
++
++			if (!avail_ants_tx && !avail_ants_rx) {
++				result = -EOPNOTSUPP;
++				goto out;
++			}
++
++			if ((~tx_ant && (tx_ant & ~avail_ants_tx)) ||
++			    (~rx_ant && (rx_ant & ~avail_ants_rx))) {
++				result = -EINVAL;
++				goto out;
++			}
++
++			tx_ant = tx_ant & avail_ants_tx;
++			rx_ant = rx_ant & avail_ants_rx;
++			result = rdev_set_antenna(rdev, tx_ant, rx_ant, bandid);
++			if (result)
++				goto out;
++		}
+ 	}
+ 
+ 	changed = 0;
+diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
+index 9b411db..bcd51fc 100644
+--- a/net/wireless/rdev-ops.h
++++ b/net/wireless/rdev-ops.h
+@@ -857,26 +857,26 @@ rdev_update_mgmt_frame_registrations(struct cfg80211_registered_device *rdev,
+ }
+ 
+ static inline int rdev_set_antenna(struct cfg80211_registered_device *rdev,
+-				   u32 tx_ant, u32 rx_ant)
++				   u32 tx_ant, u32 rx_ant, int band)
+ {
+ 	int ret;
+-	trace_rdev_set_antenna(&rdev->wiphy, tx_ant, rx_ant);
+-	ret = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
++	trace_rdev_set_antenna(&rdev->wiphy, tx_ant, rx_ant, band);
++	ret = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant, band);
+ 	trace_rdev_return_int(&rdev->wiphy, ret);
+ 	return ret;
+ }
+ 
+ static inline int rdev_get_antenna(struct cfg80211_registered_device *rdev,
+-				   u32 *tx_ant, u32 *rx_ant)
++				   u32 *tx_ant, u32 *rx_ant, int band)
+ {
+ 	int ret;
+ 	trace_rdev_get_antenna(&rdev->wiphy);
+-	ret = rdev->ops->get_antenna(&rdev->wiphy, tx_ant, rx_ant);
++	ret = rdev->ops->get_antenna(&rdev->wiphy, tx_ant, rx_ant, band);
+ 	if (ret)
+ 		trace_rdev_return_int(&rdev->wiphy, ret);
+ 	else
+ 		trace_rdev_return_int_tx_rx(&rdev->wiphy, ret, *tx_ant,
+-					    *rx_ant);
++					    *rx_ant, band);
+ 	return ret;
+ }
+ 
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index 6af432e..90ba38a 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -1818,22 +1818,24 @@ TRACE_EVENT(rdev_update_mgmt_frame_registrations,
+ );
+ 
+ TRACE_EVENT(rdev_return_int_tx_rx,
+-	TP_PROTO(struct wiphy *wiphy, int ret, u32 tx, u32 rx),
+-	TP_ARGS(wiphy, ret, tx, rx),
++	TP_PROTO(struct wiphy *wiphy, int ret, u32 tx, u32 rx, int band),
++	TP_ARGS(wiphy, ret, tx, rx, band),
+ 	TP_STRUCT__entry(
+ 		WIPHY_ENTRY
+ 		__field(int, ret)
+ 		__field(u32, tx)
+ 		__field(u32, rx)
++		__field(int, band)
+ 	),
+ 	TP_fast_assign(
+ 		WIPHY_ASSIGN;
+ 		__entry->ret = ret;
+ 		__entry->tx = tx;
+ 		__entry->rx = rx;
++		__entry->band = band;
+ 	),
+-	TP_printk(WIPHY_PR_FMT ", returned %d, tx: %u, rx: %u",
+-		  WIPHY_PR_ARG, __entry->ret, __entry->tx, __entry->rx)
++	TP_printk(WIPHY_PR_FMT ", returned %d, tx: %u, rx: %u band %d",
++		  WIPHY_PR_ARG, __entry->ret, __entry->tx, __entry->rx, __entry->band)
+ );
+ 
+ TRACE_EVENT(rdev_return_void_tx_rx,
+@@ -1860,25 +1862,27 @@ TRACE_EVENT(rdev_return_void_tx_rx,
+ );
+ 
+ DECLARE_EVENT_CLASS(tx_rx_evt,
+-	TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
+-	TP_ARGS(wiphy, tx, rx),
++	TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx, int band),
++	TP_ARGS(wiphy, rx, tx, band),
+ 	TP_STRUCT__entry(
+ 		WIPHY_ENTRY
+ 		__field(u32, tx)
+ 		__field(u32, rx)
++		__field(int, band)
+ 	),
+ 	TP_fast_assign(
+ 		WIPHY_ASSIGN;
+ 		__entry->tx = tx;
+ 		__entry->rx = rx;
++		__entry->band = band;
+ 	),
+-	TP_printk(WIPHY_PR_FMT ", tx: %u, rx: %u ",
+-		  WIPHY_PR_ARG, __entry->tx, __entry->rx)
++	TP_printk(WIPHY_PR_FMT ", tx: %u, rx: %u band: %d ",
++		  WIPHY_PR_ARG, __entry->tx, __entry->rx, __entry->band)
+ );
+ 
+ DEFINE_EVENT(tx_rx_evt, rdev_set_antenna,
+-	TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
+-	TP_ARGS(wiphy, tx, rx)
++	TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx, int band),
++	TP_ARGS(wiphy, rx, tx, band)
+ );
+ 
+ DECLARE_EVENT_CLASS(wiphy_netdev_id_evt,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0079-mtk-mac80211-add-new-rc-changed-enum-for-wifi7-cert.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0079-mtk-mac80211-add-new-rc-changed-enum-for-wifi7-cert.patch
new file mode 100644
index 0000000..e37fd17
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0079-mtk-mac80211-add-new-rc-changed-enum-for-wifi7-cert.patch
@@ -0,0 +1,31 @@
+From 56333cc7dbfb80bf94c86b614f330a981be21258 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Thu, 20 Jun 2024 09:01:35 +0800
+Subject: [PATCH 79/89] mtk: mac80211: add new rc changed enum for wifi7 cert
+
+Add a new rc enum "IEEE80211_RC_CODING_TYPE_CHANGED" for wifi7 r1. This
+enum is used to mark that the coding type has changed by user space
+commands.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+
+---
+ include/net/mac80211.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 9471892..f9afddd 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -3757,6 +3757,8 @@ enum ieee80211_rate_control_changed {
+ 	IEEE80211_RC_SMPS_CHANGED	= BIT(1),
+ 	IEEE80211_RC_SUPP_RATES_CHANGED	= BIT(2),
+ 	IEEE80211_RC_NSS_CHANGED	= BIT(3),
++	/* Defined for mtk vendor command */
++	IEEE80211_RC_CODING_TYPE_CHANGED= BIT(7),
+ };
+ 
+ /**
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0080-mtk-mac80211-do-not-check-radar-required-for-remain-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0080-mtk-mac80211-do-not-check-radar-required-for-remain-.patch
new file mode 100644
index 0000000..b5f7195
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0080-mtk-mac80211-do-not-check-radar-required-for-remain-.patch
@@ -0,0 +1,28 @@
+From 49baf7ad24eed63700f62fa631b32014c686b6e3 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Fri, 14 Jun 2024 11:16:07 +0800
+Subject: [PATCH 80/89] mtk: mac80211: do not check radar required for
+ remain-on-channel operation
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ net/mac80211/offchannel.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
+index 9e4f26a..b73cf54 100644
+--- a/net/mac80211/offchannel.c
++++ b/net/mac80211/offchannel.c
+@@ -613,8 +613,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
+ 	}
+ 
+ 	/* if there's no need to queue, handle it immediately */
+-	if (list_empty(&local->roc_list) &&
+-	    !local->scanning && !ieee80211_is_radar_required(local)) {
++	if (list_empty(&local->roc_list) && !local->scanning) {
+ 		/* if not HW assist, just queue & schedule work */
+ 		if (!local->ops->remain_on_channel) {
+ 			list_add_tail(&roc->list, &local->roc_list);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0081-mtk-mac80211-Add-ba_disable-debugfs-to-disable-ba.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0081-mtk-mac80211-Add-ba_disable-debugfs-to-disable-ba.patch
new file mode 100644
index 0000000..3356048
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0081-mtk-mac80211-Add-ba_disable-debugfs-to-disable-ba.patch
@@ -0,0 +1,125 @@
+From d9f41790746aa35852953ea5f1944abb58ad48ec Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+Date: Thu, 20 Jun 2024 14:56:42 +0800
+Subject: [PATCH 81/89] mtk: mac80211: Add ba_disable debugfs to disable ba
+
+Add ba_disable debugfs to diable ba for Wi-Fi 7 cert
+
+Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+---
+ include/net/mac80211.h |  6 ++++++
+ net/mac80211/agg-tx.c  |  6 ++++++
+ net/mac80211/debugfs.c | 49 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 61 insertions(+)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index f9afddd..5ff8ced 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -3061,6 +3061,7 @@ struct ieee80211_hw {
+ 	const s8 *tx_power_levels;
+ 	u8 max_txpwr_levels_idx;
+ 	bool cert_mode;
++	bool ba_disable;
+ };
+ 
+ static inline bool ieee80211_is_cert_mode(struct ieee80211_hw *hw)
+@@ -3068,6 +3069,11 @@ static inline bool ieee80211_is_cert_mode(struct ieee80211_hw *hw)
+ 	return hw->cert_mode;
+ }
+ 
++static inline bool ieee80211_is_ba_disable(struct ieee80211_hw *hw)
++{
++	return hw->ba_disable;
++}
++
+ static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw,
+ 				       enum ieee80211_hw_flags flg)
+ {
+diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
+index 2f351a7..e398540 100644
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -638,6 +638,12 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
+ 
+ 	trace_api_start_tx_ba_session(pubsta, tid);
+ 
++	if (ieee80211_is_ba_disable(&local->hw)) {
++		ht_dbg(sdata,
++		       "BA session is forced to be shut down due to debugfs config\n");
++		return -EINVAL;
++	}
++
+ 	if (WARN(sta->reserved_tid == tid,
+ 		 "Requested to start BA session on reserved tid=%d", tid))
+ 		return -EINVAL;
+diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
+index 376abfc..fc7888a 100644
+--- a/net/mac80211/debugfs.c
++++ b/net/mac80211/debugfs.c
+@@ -498,6 +498,54 @@ static const struct file_operations cert_mode_ops = {
+ 	.llseek = noop_llseek,
+ };
+ 
++static ssize_t ba_disable_read(struct file *file,
++			       char __user *user_buf,
++			       size_t count,
++			       loff_t *ppos)
++{
++	struct ieee80211_local *local = file->private_data;
++	char buf[32];
++	int len = 0;
++
++	len = scnprintf(buf, sizeof(buf), "ba_disable: %d\n",
++			local->hw.ba_disable);
++
++	return simple_read_from_buffer(user_buf, count, ppos,
++				       buf, len);
++}
++
++static ssize_t ba_disable_write(struct file *file,
++				const char __user *user_buf,
++				size_t count,
++				loff_t *ppos)
++{
++	struct ieee80211_local *local = file->private_data;
++	char buf[16];
++
++	if (count >= sizeof(buf))
++		return -EINVAL;
++
++	if (copy_from_user(buf, user_buf, count))
++		return -EFAULT;
++
++	if (count && buf[count - 1] == '\n')
++		buf[count - 1] = '\0';
++	else
++		buf[count] = '\0';
++
++	if (kstrtobool(buf, &local->hw.ba_disable))
++		return -EINVAL;
++
++	return count;
++}
++
++static const struct file_operations ba_disable_ops = {
++	.write = ba_disable_write,
++	.read = ba_disable_read,
++	.open = simple_open,
++	.llseek = noop_llseek,
++};
++
+ static const char *hw_flag_names[] = {
+ #define FLAG(F)	[IEEE80211_HW_##F] = #F
+ 	FLAG(HAS_RATE_CONTROL),
+@@ -732,6 +780,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
+ 			   phyd, &local->aql_threshold);
+ 
+ 	DEBUGFS_ADD_MODE(cert_mode, 0644);
++	DEBUGFS_ADD_MODE(ba_disable, 0644);
+ 	statsd = debugfs_create_dir("statistics", phyd);
+ 
+ #ifdef CPTCFG_MAC80211_DEBUG_COUNTERS
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0082-mtk-mac80211-fix-incorrect-VIF-assignment-for-IEEE-8.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0082-mtk-mac80211-fix-incorrect-VIF-assignment-for-IEEE-8.patch
new file mode 100644
index 0000000..8e1fffe
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0082-mtk-mac80211-fix-incorrect-VIF-assignment-for-IEEE-8.patch
@@ -0,0 +1,36 @@
+From 326501581d550d0397a1405425d1304ecec87e32 Mon Sep 17 00:00:00 2001
+From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Date: Fri, 12 Jul 2024 15:44:03 +0800
+Subject: [PATCH 82/89] mtk: mac80211: fix incorrect VIF assignment for IEEE
+ 802.11 fragments
+
+In WDS mode, first fragment is obtained from ieee80211_local->fq, so its VIF is later changed from AP_VLAN to AP VIF.
+On the other hand, subsequent fragments are obtained from txq_info->frags, so its VIF remains AP_VLAN.
+Inconsistency in VIFs of fragments results in transmission failure.
+Therefore, VIF assignment for non-first fragments is added.
+
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+---
+ net/mac80211/tx.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index ebe3ae2..c6d3f2f 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3850,8 +3850,11 @@ begin:
+ 	skb = __skb_dequeue(&txqi->frags);
+ 	if (unlikely(skb)) {
+ 		if (!(IEEE80211_SKB_CB(skb)->control.flags &
+-				IEEE80211_TX_INTCFL_NEED_TXPROCESSING))
++				IEEE80211_TX_INTCFL_NEED_TXPROCESSING)) {
++			// TODO: report airtime of non-first fragments.
++			IEEE80211_SKB_CB(skb)->control.vif = vif;
+ 			goto out;
++		}
+ 		IEEE80211_SKB_CB(skb)->control.flags &=
+ 			~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
+ 	} else {
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0083-mtk-mac80211-Add-STA-site-link-add-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0083-mtk-mac80211-Add-STA-site-link-add-support.patch
new file mode 100644
index 0000000..2c2a8c3
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0083-mtk-mac80211-Add-STA-site-link-add-support.patch
@@ -0,0 +1,124 @@
+From b02a25d547c4959e81078bb12bdf1576182fef20 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 2 Jul 2024 14:28:26 +0800
+Subject: [PATCH 83/89] mtk: mac80211: Add STA site link add support
+
+Trigger deauth & reconnect when all the valid links of the STA receive
+the information of link addition.
+(max simultaneous link num in ML IE > the simultaneous link num stored
+after association success)
+For example, when the MLD AP completes the CAC or adds an additional link
+via the link reconfiguration command, SQC/autotest might assume that the
+MLD STA to react to it rather than ignoring it.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Do not check ifmgd->reporting_add_links when the connection is not MLO.
+
+This fixes the problem that an MLD STA cannot associate with an MLD AP.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ net/mac80211/ieee80211_i.h |  1 +
+ net/mac80211/mlme.c        | 42 ++++++++++++++++++++++++++++++++++++++
+ net/wireless/scan.c        |  5 ++---
+ 3 files changed, 45 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index 6f9a9a6..fa8d751 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -602,6 +602,7 @@ struct ieee80211_if_managed {
+ 
+ 	struct wiphy_delayed_work ml_reconf_work;
+ 	u16 removed_links;
++	u16 reporting_add_links;
+ 
+ 	/* TID-to-link mapping support */
+ 	struct wiphy_delayed_work ttlm_work;
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index a3873d2..4964d08 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3716,6 +3716,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
+ 	sdata->u.mgd.removed_links = 0;
+ 	wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+ 				  &sdata->u.mgd.ml_reconf_work);
++	sdata->u.mgd.reporting_add_links = 0;
+ 
+ 	wiphy_work_cancel(sdata->local->hw.wiphy,
+ 			  &ifmgd->teardown_ttlm_work);
+@@ -6182,6 +6183,34 @@ static bool ieee80211_rx_our_beacon(const u8 *tx_bssid,
+ 	return ether_addr_equal(tx_bssid, bss->transmitted_bss->bssid);
+ }
+ 
++static void ieee80211_ml_link_add(struct ieee80211_link_data *link,
++				  struct ieee802_11_elems *elems)
++{
++	struct ieee80211_sub_if_data *sdata = link->sdata;
++	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
++	int max_simul_links, cur_simul_links;
++	u16 mld_capa_op;
++
++	if (!ieee80211_vif_is_mld(&sdata->vif) || !elems->ml_basic ||
++	    !ifmgd->associated)
++		return;
++
++	mld_capa_op = ieee80211_mle_get_mld_capa_op((const void *)elems->ml_basic);
++	if (!mld_capa_op)
++		return;
++
++	/* TODO: parse RNR to check the capability of STA before reconnecting */
++	max_simul_links = mld_capa_op & IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS;
++	cur_simul_links = sdata->vif.cfg.mld_capa_op &
++			  IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS;
++	if (max_simul_links > cur_simul_links) {
++		ifmgd->reporting_add_links |= BIT(link->link_id);
++		sdata_info(sdata,
++			   "MLO Reconfig: link %d: cur_simul_links=%d, max_simul_links=%d\n",
++			   link->link_id, cur_simul_links, max_simul_links);
++	}
++}
++
+ static void ieee80211_ml_reconf_work(struct wiphy *wiphy,
+ 				     struct wiphy_work *work)
+ {
+@@ -6950,6 +6979,19 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
+ 
+ 	ieee80211_rx_bss_info(link, mgmt, len, rx_status);
+ 
++	ieee80211_ml_link_add(link, elems);
++	if (ieee80211_vif_is_mld(&sdata->vif) &&
++	    ifmgd->reporting_add_links == sdata->vif.valid_links) {
++		ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
++				       WLAN_REASON_DEAUTH_LEAVING,
++				       true, deauth_buf);
++		ieee80211_report_disconnect(sdata, deauth_buf,
++					    sizeof(deauth_buf), true,
++					    WLAN_REASON_DEAUTH_LEAVING,
++					    true);
++		goto free;
++	}
++
+ 	ieee80211_sta_process_chanswitch(link, rx_status->mactime,
+ 					 rx_status->device_timestamp,
+ 					 elems, elems,
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 1138c0b..35d2f00 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -1879,9 +1879,8 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ 
+ 		rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);
+ 
+-		/* Override IEs if they were from a beacon before */
+-		if (old == rcu_access_pointer(known->pub.ies))
+-			rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
++		/* No points to keep pointing to the old data derived from probe resp */
++		rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
+ 
+ 		cfg80211_update_hidden_bsses(known,
+ 					     rcu_access_pointer(new->pub.beacon_ies),
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0084-mtk-mac80211-Fix-channel-switch-punct-bitmap-would-b.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0084-mtk-mac80211-Fix-channel-switch-punct-bitmap-would-b.patch
new file mode 100644
index 0000000..b56b257
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0084-mtk-mac80211-Fix-channel-switch-punct-bitmap-would-b.patch
@@ -0,0 +1,46 @@
+From 6043522521b98b4107c339d399fd64b52b60f192 Mon Sep 17 00:00:00 2001
+From: Allen Ye <allen.ye@mediatek.com>
+Date: Wed, 10 Jul 2024 17:45:05 +0800
+Subject: [PATCH 84/89] mtk: mac80211: Fix channel switch punct bitmap would be
+ clean bug in STA mode
+
+The patch add back the puncture bitmap when mac80211 create a new channel
+definition in ieee80211_chandef_ht_oper for legacy cap check.
+
+Signed-off-by: Allen Ye <allen.ye@mediatek.com>
+---
+ net/mac80211/spectmgmt.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
+index 073ff9e..e8ac8ec 100644
+--- a/net/mac80211/spectmgmt.c
++++ b/net/mac80211/spectmgmt.c
+@@ -76,6 +76,7 @@ validate_chandef_by_ht_vht_oper(struct ieee80211_sub_if_data *sdata,
+ 				struct cfg80211_chan_def *chandef)
+ {
+ 	u32 control_freq, center_freq1, center_freq2;
++	u16 punct_bitmap;
+ 	enum nl80211_chan_width chan_width;
+ 	struct ieee80211_ht_operation ht_oper;
+ 	struct ieee80211_vht_operation vht_oper;
+@@ -90,6 +91,7 @@ validate_chandef_by_ht_vht_oper(struct ieee80211_sub_if_data *sdata,
+ 	center_freq1 = chandef->center_freq1;
+ 	center_freq2 = chandef->center_freq2;
+ 	chan_width = chandef->width;
++	punct_bitmap = chandef->punctured;
+ 
+ 	ht_oper.primary_chan = ieee80211_frequency_to_channel(control_freq);
+ 	if (control_freq != center_freq1)
+@@ -101,6 +103,8 @@ validate_chandef_by_ht_vht_oper(struct ieee80211_sub_if_data *sdata,
+ 
+ 	ieee80211_chandef_ht_oper(&ht_oper, chandef);
+ 
++	chandef->punctured = punct_bitmap;
++
+ 	if (conn->mode < IEEE80211_CONN_MODE_VHT)
+ 		return;
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0085-mtk-mac80211-add-ieee80211_links_removed-to-support-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0085-mtk-mac80211-add-ieee80211_links_removed-to-support-.patch
new file mode 100644
index 0000000..5124e93
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0085-mtk-mac80211-add-ieee80211_links_removed-to-support-.patch
@@ -0,0 +1,242 @@
+From e9974899e3d65fdd626f00aafd7bc5f1ed46b6a0 Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Fri, 3 May 2024 17:51:37 +0800
+Subject: [PATCH 85/89] mtk: mac80211: add ieee80211_links_removed() to support
+ MLD AP reconf
+
+Add ieee80211_links_removed() to let driver notify upper layers for MLD AP
+reconfiguration. Also modify some parts to prevent from removing whole
+STA while removing a link.
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ include/net/mac80211.h     |  8 ++++++++
+ net/mac80211/cfg.c         | 23 ++++++++++++++++++-----
+ net/mac80211/ieee80211_i.h |  4 ++++
+ net/mac80211/iface.c       | 19 +++++++++++++++++++
+ net/mac80211/sta_info.c    |  6 ++++++
+ net/wireless/ap.c          | 18 +++++++++++++-----
+ net/wireless/nl80211.c     |  9 ++++++---
+ 7 files changed, 74 insertions(+), 13 deletions(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 5ff8ced..be6631e 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -7730,6 +7730,14 @@ int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
+ 					 int n_vifs,
+ 					 enum ieee80211_chanctx_switch_mode mode);
+ 
++/**
++ * ieee80211_links_removed - notify removed links
++ * @vif: interface to be notified
++ * @removed_links: links bitmap being removed
++ *
++ */
++void ieee80211_links_removed(struct ieee80211_vif *vif, u16 removed_links);
++
+ /**
+  * ieee80211_get_scanning - get scanning bitmask
+  *
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 69c3e81..e8053b1 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1657,9 +1657,11 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
+ 	__sta_info_flush(sdata, true, link_id);
+ 
+ 	link_conf->enable_beacon = false;
+-	sdata->beacon_rate_set = false;
+-	sdata->vif.cfg.ssid_len = 0;
+-	clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
++	if (ieee80211_num_beaconing_links(sdata) <= 1) {
++		sdata->beacon_rate_set = false;
++		sdata->vif.cfg.ssid_len = 0;
++		clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
++	}
+ 	ieee80211_link_info_change_notify(sdata, link,
+ 					  BSS_CHANGED_BEACON_ENABLED);
+ 
+@@ -1674,8 +1676,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
+ 	drv_stop_ap(sdata->local, sdata, link_conf);
+ 
+ 	/* free all potentially still buffered bcast frames */
+-	local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
+-	ieee80211_purge_tx_queue(&local->hw, &sdata->u.ap.ps.bc_buf);
++	if (ieee80211_num_beaconing_links(sdata) <= 1) {
++		local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
++		ieee80211_purge_tx_queue(&local->hw, &sdata->u.ap.ps.bc_buf);
++	}
+ 
+ 	ieee80211_link_copy_chanctx_to_vlans(link, true);
+ 	ieee80211_link_release_channel(link);
+@@ -5257,6 +5261,15 @@ ieee80211_skip_cac(struct wireless_dev *wdev, unsigned int link_id)
+ 	}
+ }
+ 
++void ieee80211_links_removed(struct ieee80211_vif *vif, u16 removed_links)
++{
++	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
++
++	sdata->removed_links = removed_links;
++	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->links_removed_work);
++}
++EXPORT_SYMBOL_GPL(ieee80211_links_removed);
++
+ const struct cfg80211_ops mac80211_config_ops = {
+ 	.add_virtual_intf = ieee80211_add_iface,
+ 	.del_virtual_intf = ieee80211_del_iface,
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index fa8d751..a77e63c 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1182,6 +1182,10 @@ struct ieee80211_sub_if_data {
+ 
+ 	u16 restart_active_links;
+ 
++	/* for MLD reconf of affliated AP removal */
++	struct wiphy_work links_removed_work;
++	u16 removed_links;
++
+ #ifdef CPTCFG_MAC80211_DEBUGFS
+ 	struct {
+ 		struct dentry *subdir_stations;
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index eb7a05d..3714204 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -783,6 +783,7 @@ static int ieee80211_stop(struct net_device *dev)
+ 
+ 	wiphy_lock(sdata->local->hw.wiphy);
+ 	wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->activate_links_work);
++	wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->links_removed_work);
+ 
+ 	ieee80211_do_stop(sdata, true);
+ 	wiphy_unlock(sdata->local->hw.wiphy);
+@@ -1748,6 +1749,22 @@ static void ieee80211_activate_links_work(struct wiphy *wiphy,
+ 	sdata->desired_active_links = 0;
+ }
+ 
++static void ieee80211_links_removed_work(struct wiphy *wiphy,
++					 struct wiphy_work *work)
++{
++	struct ieee80211_sub_if_data *sdata =
++		container_of(work, struct ieee80211_sub_if_data, links_removed_work);
++	struct ieee80211_local *local = sdata->local;
++
++	lockdep_assert_wiphy(local->hw.wiphy);
++
++	if (!ieee80211_sdata_running(sdata))
++		return;
++
++	cfg80211_links_removed(sdata->dev, sdata->removed_links);
++	sdata->removed_links = 0;
++}
++
+ /*
+  * Helper function to initialise an interface to a specific type.
+  */
+@@ -1786,6 +1803,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
+ 	wiphy_work_init(&sdata->work, ieee80211_iface_work);
+ 	wiphy_work_init(&sdata->activate_links_work,
+ 			ieee80211_activate_links_work);
++	wiphy_work_init(&sdata->links_removed_work,
++			ieee80211_links_removed_work);
+ 
+ 	switch (type) {
+ 	case NL80211_IFTYPE_P2P_GO:
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index b1eb519..c9f3c8e 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -1596,6 +1596,12 @@ int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans,
+ 		    !(sta->sta.valid_links & BIT(link_id)))
+ 			continue;
+ 
++		/* sta still has more than one link */
++		if (link_id >= 0 && (sta->sta.valid_links & ~BIT(link_id))) {
++			ieee80211_sta_remove_link(sta, link_id);
++			continue;
++		}
++
+ 		if (!WARN_ON(__sta_info_destroy_part1(sta)))
+ 			list_add(&sta->free_list, &free_list);
+ 
+diff --git a/net/wireless/ap.c b/net/wireless/ap.c
+index 9cd0ab4..9fc296a 100644
+--- a/net/wireless/ap.c
++++ b/net/wireless/ap.c
+@@ -16,10 +16,15 @@ static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
+ 			       bool notify)
+ {
+ 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+-	int err;
++	int err, i;
++	u16 beaconing_links = 0;
+ 
+ 	lockdep_assert_wiphy(wdev->wiphy);
+ 
++	for_each_valid_link(wdev, i)
++		if (wdev->links[i].ap.beacon_interval)
++			beaconing_links |= BIT(i);
++
+ 	if (!rdev->ops->stop_ap)
+ 		return -EOPNOTSUPP;
+ 
+@@ -35,19 +40,22 @@ static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
+ 
+ 	err = rdev_stop_ap(rdev, dev, link_id);
+ 	if (!err) {
+-		wdev->conn_owner_nlportid = 0;
+ 		wdev->links[link_id].ap.beacon_interval = 0;
+ 		memset(&wdev->links[link_id].ap.chandef, 0,
+ 		       sizeof(wdev->links[link_id].ap.chandef));
+-		wdev->u.ap.ssid_len = 0;
+-		rdev_set_qos_map(rdev, dev, NULL);
++		if (hweight16(beaconing_links) <= 1) {
++			wdev->conn_owner_nlportid = 0;
++			wdev->u.ap.ssid_len = 0;
++			rdev_set_qos_map(rdev, dev, NULL);
++		}
+ 		if (notify)
+ 			nl80211_send_ap_stopped(wdev, link_id);
+ 
+ 		cfg80211_sched_dfs_chan_update(rdev);
+ 	}
+ 
+-	schedule_work(&cfg80211_disconnect_work);
++	if (hweight16(beaconing_links) <= 1)
++		schedule_work(&cfg80211_disconnect_work);
+ 
+ 	return err;
+ }
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index c38a5d0..e451977 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -18767,7 +18767,8 @@ void cfg80211_links_removed(struct net_device *dev, u16 link_mask)
+ 	trace_cfg80211_links_removed(dev, link_mask);
+ 
+ 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
+-		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
++		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT &&
++		    wdev->iftype != NL80211_IFTYPE_AP))
+ 		return;
+ 
+ 	if (WARN_ON(!wdev->valid_links || !link_mask ||
+@@ -18775,8 +18776,10 @@ void cfg80211_links_removed(struct net_device *dev, u16 link_mask)
+ 		    wdev->valid_links == link_mask))
+ 		return;
+ 
+-	cfg80211_wdev_release_link_bsses(wdev, link_mask);
+-	wdev->valid_links &= ~link_mask;
++	if (wdev->iftype != NL80211_IFTYPE_AP) {
++		cfg80211_wdev_release_link_bsses(wdev, link_mask);
++		wdev->valid_links &= ~link_mask;
++	}
+ 
+ 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ 	if (!msg)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0086-mtk-mac80211-add-A-TTLM-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0086-mtk-mac80211-add-A-TTLM-support.patch
new file mode 100644
index 0000000..643f7d5
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0086-mtk-mac80211-add-A-TTLM-support.patch
@@ -0,0 +1,384 @@
+From 137d2eae370d772d579f737f9d99c9cc14850bf6 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Wed, 3 Jul 2024 17:05:01 +0800
+Subject: [PATCH 86/89] mtk: mac80211: add A-TTLM support
+
+There are 3 A-TTLM events from the driver, and mac80211 just forward
+them
+1. A-TTLM started: the switch time in TSF is also sent.
+2. A-TTLM switch time expired
+3. A-TTLM ended
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ include/net/cfg80211.h       | 11 ++++++
+ include/net/mac80211.h       | 12 ++++++
+ include/uapi/linux/nl80211.h | 16 ++++++++
+ net/mac80211/cfg.c           | 23 +++++++++++
+ net/wireless/nl80211.c       | 75 ++++++++++++++++++++++++++++++++++++
+ net/wireless/rdev-ops.h      | 18 +++++++++
+ net/wireless/trace.h         | 45 ++++++++++++++++++++++
+ 7 files changed, 200 insertions(+)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 835735f..bc3e585 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -5035,6 +5035,8 @@ struct cfg80211_ops {
+ 				    struct link_station_del_parameters *params);
+ 	int	(*set_hw_timestamp)(struct wiphy *wiphy, struct net_device *dev,
+ 				    struct cfg80211_set_hw_timestamp *hwts);
++	int	(*set_attlm)(struct wiphy *wiphy, struct net_device *dev,
++			     u16 disabled_links, u16 switch_time, u32 duration);
+ 	int	(*set_ttlm)(struct wiphy *wiphy, struct net_device *dev,
+ 			    struct cfg80211_ttlm_params *params);
+ 	u32	(*get_radio_mask)(struct wiphy *wiphy, struct net_device *dev);
+@@ -9743,6 +9745,15 @@ int cfg80211_bss_color_notify(struct net_device *dev,
+ 			      enum nl80211_commands cmd, u8 count,
+ 			      u64 color_bitmap, u8 link_id);
+ 
++/**
++ * cfg80211_attlm_notify - notify about Advertised Tid-to-Link Mapping
++ * @wdev: the wireless device to check.
++ * @switch_time_tsf_tu: switch time TSF in unit of TUs that is reported by driver.
++ * @event: A-TTLM event
++ * @gfp: allocation flags
++ */
++void cfg80211_attlm_notify(struct wireless_dev *wdev, u16 switch_time_tsf_tu,
++			   enum nl80211_attlm_event event, gfp_t gfp);
+ /**
+  * cfg80211_obss_color_collision_notify - notify about bss color collision
+  * @dev: network device
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index be6631e..1345676 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -4852,6 +4852,8 @@ struct ieee80211_ops {
+ 			    struct net_device *dev,
+ 			    enum tc_setup_type type,
+ 			    void *type_data);
++	int (*set_attlm)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++			 u16 disabled_links, u16 switch_time, u32 druation);
+ 	enum ieee80211_neg_ttlm_res
+ 	(*can_neg_ttlm)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			struct ieee80211_neg_ttlm *ttlm);
+@@ -7730,6 +7732,16 @@ int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
+ 					 int n_vifs,
+ 					 enum ieee80211_chanctx_switch_mode mode);
+ 
++/**
++ * ieee80211_attlm_notify - notify Advertised Tid-to-Link-Mapping
++ * @vif: interface to be notified
++ * @switch_time_tsf_tu: switch time TSF in unit of TUs that is reported by driver.
++ * @event: A-TTLM event
++ * @gfp: allocation flags
++ */
++void ieee80211_attlm_notify(struct ieee80211_vif *vif, u16 switch_time_tsf_tu,
++			    enum nl80211_attlm_event event, gfp_t gfp);
++
+ /**
+  * ieee80211_links_removed - notify removed links
+  * @vif: interface to be notified
+diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
+index 6a2291d..7188839 100644
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -1588,6 +1588,10 @@ enum nl80211_commands {
+ 
+ 	/* add new commands above here */
+ 
++	/* MTK internal */
++	NL80211_CMD_ATTLM_EVENT,
++	NL80211_CMD_SET_ATTLM,
++
+ 	/* used to define NL80211_CMD_MAX below */
+ 	__NL80211_CMD_AFTER_LAST,
+ 	NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
+@@ -3388,6 +3392,7 @@ enum nl80211_attrs {
+ 
+ 	NL80211_ATTR_MLO_LINKS,
+ 	NL80211_ATTR_MLO_LINK_ID,
++	NL80211_ATTR_MLO_LINK_DISABLED_BMP,
+ 	NL80211_ATTR_MLD_ADDR,
+ 
+ 	NL80211_ATTR_MLO_SUPPORT,
+@@ -3425,6 +3430,11 @@ enum nl80211_attrs {
+ 	/* MTK internal */
+ 	NL80211_ATTR_CNTDWN_OFFS_STA_PROF,
+ 
++	NL80211_ATTR_MLO_ATTLM_EVENT,
++	NL80211_ATTR_MLO_ATTLM_SWITCH_TIME,
++	NL80211_ATTR_MLO_ATTLM_DURATION,
++	NL80211_ATTR_MLO_ATTLM_SWITCH_TIME_TSF_TU,
++
+ 	__NL80211_ATTR_AFTER_LAST,
+ 	NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
+ 	NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
+@@ -8091,4 +8101,10 @@ enum nl80211_wiphy_radio_freq_range {
+ 	NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST - 1,
+ };
+ 
++enum nl80211_attlm_event {
++	NL80211_ATTLM_STARTED,
++	NL80211_ATTLM_SWITCH_TIME_EXPIRED,
++	NL80211_ATTLM_END,
++};
++
+ #endif /* __LINUX_NL80211_H */
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index e8053b1..1784b8b 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -5222,6 +5222,20 @@ static int ieee80211_set_hw_timestamp(struct wiphy *wiphy,
+ 	return local->ops->set_hw_timestamp(&local->hw, &sdata->vif, hwts);
+ }
+ 
++static int
++ieee80211_set_attlm(struct wiphy *wiphy, struct net_device *dev,
++		    u16 disabled_links, u16 switch_time, u32 duration)
++{
++	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++	struct ieee80211_local *local = sdata->local;
++
++	if (!local->ops->set_attlm)
++		return -EOPNOTSUPP;
++
++	return local->ops->set_attlm(&local->hw, &sdata->vif, disabled_links,
++				     switch_time, duration);
++}
++
+ static int
+ ieee80211_set_ttlm(struct wiphy *wiphy, struct net_device *dev,
+ 		   struct cfg80211_ttlm_params *params)
+@@ -5261,6 +5275,14 @@ ieee80211_skip_cac(struct wireless_dev *wdev, unsigned int link_id)
+ 	}
+ }
+ 
++void ieee80211_attlm_notify(struct ieee80211_vif *vif, u16 switch_time_tsf_tu,
++			   enum nl80211_attlm_event event, gfp_t gfp)
++{
++	cfg80211_attlm_notify(ieee80211_vif_to_wdev(vif), switch_time_tsf_tu,
++			      event, gfp);
++}
++EXPORT_SYMBOL_GPL(ieee80211_attlm_notify);
++
+ void ieee80211_links_removed(struct ieee80211_vif *vif, u16 removed_links)
+ {
+ 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+@@ -5383,6 +5405,7 @@ const struct cfg80211_ops mac80211_config_ops = {
+ 	.mod_link_station = ieee80211_mod_link_station,
+ 	.del_link_station = ieee80211_del_link_station,
+ 	.set_hw_timestamp = ieee80211_set_hw_timestamp,
++	.set_attlm = ieee80211_set_attlm,
+ 	.set_ttlm = ieee80211_set_ttlm,
+ 	.get_radio_mask = ieee80211_get_radio_mask,
+ 	.skip_cac = ieee80211_skip_cac,
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index e451977..5439aa0 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -843,6 +843,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 		NLA_POLICY_NESTED_ARRAY(nl80211_policy),
+ 	[NL80211_ATTR_MLO_LINK_ID] =
+ 		NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS),
++	[NL80211_ATTR_MLO_LINK_DISABLED_BMP] = { .type = NLA_U16 },
+ 	[NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
+ 	[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
+@@ -856,6 +857,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
+ 	[NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG },
++	[NL80211_ATTR_MLO_ATTLM_SWITCH_TIME] = { .type = NLA_U16 },
++	[NL80211_ATTR_MLO_ATTLM_DURATION] = { .type = NLA_U32 },
++	[NL80211_ATTR_MLO_ATTLM_SWITCH_TIME_TSF_TU] = { .type = NLA_U16 },
+ 	[NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
+ 	[NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
+@@ -16689,6 +16693,30 @@ static int nl80211_set_hw_timestamp(struct sk_buff *skb,
+ 	return rdev_set_hw_timestamp(rdev, dev, &hwts);
+ }
+ 
++static int
++nl80211_set_attlm(struct sk_buff *skb, struct genl_info *info)
++{
++	struct cfg80211_registered_device *rdev = info->user_ptr[0];
++	struct net_device *dev = info->user_ptr[1];
++	struct wireless_dev *wdev = dev->ieee80211_ptr;
++	u16 switch_time, disabled_links;
++	u32 duration;
++
++	if (wdev->iftype != NL80211_IFTYPE_AP)
++		return -EOPNOTSUPP;
++
++	if (!info->attrs[NL80211_ATTR_MLO_LINK_DISABLED_BMP] ||
++	    !info->attrs[NL80211_ATTR_MLO_ATTLM_SWITCH_TIME] ||
++	    !info->attrs[NL80211_ATTR_MLO_ATTLM_DURATION])
++		return -EINVAL;
++
++	disabled_links = nla_get_u16(info->attrs[NL80211_ATTR_MLO_LINK_DISABLED_BMP]);
++	switch_time = nla_get_u16(info->attrs[NL80211_ATTR_MLO_ATTLM_SWITCH_TIME]);
++	duration = nla_get_u32(info->attrs[NL80211_ATTR_MLO_ATTLM_DURATION]);
++
++	return rdev_set_attlm(rdev, dev, disabled_links, switch_time, duration);
++}
++
+ static int
+ nl80211_set_ttlm(struct sk_buff *skb, struct genl_info *info)
+ {
+@@ -17916,6 +17944,12 @@ static const struct genl_small_ops nl80211_small_ops[] = {
+ 		.flags = GENL_UNS_ADMIN_PERM,
+ 		.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+ 	},
++	{
++		.cmd = NL80211_CMD_SET_ATTLM,
++		.doit = nl80211_set_attlm,
++		.flags = GENL_UNS_ADMIN_PERM,
++		.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
++	},
+ 	{
+ 		.cmd = NL80211_CMD_SET_TID_TO_LINK_MAPPING,
+ 		.doit = nl80211_set_ttlm,
+@@ -19951,6 +19985,47 @@ nla_put_failure:
+ }
+ EXPORT_SYMBOL(cfg80211_bss_color_notify);
+ 
++void cfg80211_attlm_notify(struct wireless_dev *wdev, u16 switch_time_tsf_tu,
++			   enum nl80211_attlm_event event, gfp_t gfp)
++{
++	struct wiphy *wiphy = wdev->wiphy;
++	struct net_device *netdev = wdev->netdev;
++	struct sk_buff *msg;
++	void *hdr;
++
++	trace_cfg80211_attlm_notify(wiphy, netdev, event, switch_time_tsf_tu);
++
++	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
++	if (!msg)
++		return;
++
++	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ATTLM_EVENT);
++	if (!hdr) {
++		nlmsg_free(msg);
++		return;
++	}
++
++	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
++		goto nla_put_failure;
++
++	if (nla_put_u32(msg, NL80211_ATTR_MLO_ATTLM_EVENT, event))
++		goto nla_put_failure;
++
++	if (nla_put_u16(msg, NL80211_ATTR_MLO_ATTLM_SWITCH_TIME_TSF_TU,
++			switch_time_tsf_tu))
++		goto nla_put_failure;
++
++	genlmsg_end(msg, hdr);
++
++	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
++				NL80211_MCGRP_MLME, gfp);
++	return;
++
++nla_put_failure:
++	nlmsg_free(msg);
++}
++EXPORT_SYMBOL(cfg80211_attlm_notify);
++
+ void
+ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
+ 		     const struct cfg80211_chan_def *chandef,
+diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
+index bcd51fc..4056f70 100644
+--- a/net/wireless/rdev-ops.h
++++ b/net/wireless/rdev-ops.h
+@@ -1538,6 +1538,24 @@ rdev_set_hw_timestamp(struct cfg80211_registered_device *rdev,
+ 	return ret;
+ }
+ 
++static inline int
++rdev_set_attlm(struct cfg80211_registered_device *rdev, struct net_device *dev,
++	       u16 disabled_links, u16 switch_time, u32 duration)
++{
++	struct wiphy *wiphy = &rdev->wiphy;
++	int ret;
++
++	if (!rdev->ops->set_attlm)
++		return -EOPNOTSUPP;
++
++	trace_rdev_set_attlm(wiphy, dev, disabled_links, switch_time, duration);
++	ret = rdev->ops->set_attlm(wiphy, dev, disabled_links, switch_time,
++				   duration);
++	trace_rdev_return_int(wiphy, ret);
++
++	return ret;
++}
++
+ static inline int
+ rdev_set_ttlm(struct cfg80211_registered_device *rdev,
+ 	      struct net_device *dev,
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index 90ba38a..9de35cc 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -3048,6 +3048,30 @@ TRACE_EVENT(rdev_set_hw_timestamp,
+ 		  __entry->enable)
+ );
+ 
++TRACE_EVENT(rdev_set_attlm,
++	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
++		 u16 disabled_links, u16 switch_time, u32 duration),
++	TP_ARGS(wiphy, netdev, disabled_links, switch_time, duration),
++	TP_STRUCT__entry(
++		WIPHY_ENTRY
++		NETDEV_ENTRY
++		__field(u16, disabled_links)
++		__field(u16, switch_time)
++		__field(u32, duration)
++	),
++	TP_fast_assign(
++		WIPHY_ASSIGN;
++		NETDEV_ASSIGN;
++		__entry->disabled_links = disabled_links;
++		__entry->switch_time = switch_time;
++		__entry->duration = duration;
++	),
++	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", disabled_link: %u"
++		  ", switch_time=%u, duration=%u",
++		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->disabled_links,
++		  __entry->switch_time, __entry->duration)
++);
++
+ TRACE_EVENT(rdev_set_ttlm,
+ 	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ 		 struct cfg80211_ttlm_params *params),
+@@ -4018,6 +4042,27 @@ TRACE_EVENT(cfg80211_bss_color_notify,
+ 		  __entry->color_bitmap)
+ );
+ 
++TRACE_EVENT(cfg80211_attlm_notify,
++	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
++		 enum nl80211_attlm_event event, u16 switch_time_tsf_tu),
++	TP_ARGS(wiphy, netdev, event, switch_time_tsf_tu),
++	TP_STRUCT__entry(
++		WIPHY_ENTRY
++		NETDEV_ENTRY
++		__field(u32, event)
++		__field(u16, switch_time_tsf_tu)
++	),
++	TP_fast_assign(
++		WIPHY_ASSIGN;
++		NETDEV_ASSIGN;
++		__entry->event = event;
++		__entry->switch_time_tsf_tu = switch_time_tsf_tu;
++	),
++	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", event: %x, switch_time_tsf_tu: %u",
++		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->event,
++		  __entry->switch_time_tsf_tu)
++);
++
+ TRACE_EVENT(cfg80211_assoc_comeback,
+ 	TP_PROTO(struct wireless_dev *wdev, const u8 *ap_addr, u32 timeout),
+ 	TP_ARGS(wdev, ap_addr, timeout),
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0087-mtk-mac80211-add-SCS-capa-definition.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0087-mtk-mac80211-add-SCS-capa-definition.patch
new file mode 100644
index 0000000..8e588c0
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0087-mtk-mac80211-add-SCS-capa-definition.patch
@@ -0,0 +1,29 @@
+From 5d05ee69f1435865e4b74db81a6f15dc985300f0 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Fri, 5 Jul 2024 09:42:46 +0800
+Subject: [PATCH 87/89] mtk: mac80211: add SCS capa definition
+
+Add scs capabilities definition in extended capabilities ie.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+
+---
+ include/linux/ieee80211.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
+index 3039cb1..10587c6 100644
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -4028,6 +4028,8 @@ enum ieee80211_tdls_actioncode {
+ #define WLAN_EXT_CAPA5_TDLS_PROHIBITED	BIT(6)
+ #define WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED	BIT(7)
+ 
++#define WLAN_EXT_CAPA7_SCS_SUPPORT 	BIT(6)
++
+ #define WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED	BIT(5)
+ #define WLAN_EXT_CAPA8_OPMODE_NOTIF	BIT(6)
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0088-mtk-mac80211-add-puncture-bitmap-sync-for-extender.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0088-mtk-mac80211-add-puncture-bitmap-sync-for-extender.patch
new file mode 100644
index 0000000..68ea938
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0088-mtk-mac80211-add-puncture-bitmap-sync-for-extender.patch
@@ -0,0 +1,78 @@
+From 432b8c55111c12f1ec1fdc1c6e50c17084343cad Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 6 Aug 2024 10:15:01 +0800
+Subject: [PATCH 88/89] mtk: mac80211: add puncture bitmap sync for extender
+
+Add puncture bitmap sync for extender.
+The latest puncture bitmap is not synchronized with the bitmap in the
+chandef passed to ieee80211_determine_ap_chan.
+Therefore, extender STA should use the latest puncture bitmap to check
+the ap mode of the extender AP when it is updated by root AP.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h |  2 ++
+ net/mac80211/mlme.c    | 13 ++++++++++---
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index bc3e585..17fb1c7 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -838,6 +838,8 @@ struct cfg80211_chan_def {
+ 	u16 punctured;
+ };
+ 
++#define IEEE80211_PUNCT_UNSPECIFIED	0xffff
++
+ /*
+  * cfg80211_bitrate_mask - masks for bitrate control
+  */
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 4964d08..6cbcfe4 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -154,7 +154,8 @@ ieee80211_determine_ap_chan(struct ieee80211_sub_if_data *sdata,
+ 			    const struct ieee802_11_elems *elems,
+ 			    bool ignore_ht_channel_mismatch,
+ 			    const struct ieee80211_conn_settings *conn,
+-			    struct cfg80211_chan_def *chandef)
++			    struct cfg80211_chan_def *chandef,
++			    u16 punctured)
+ {
+ 	const struct ieee80211_ht_operation *ht_oper = elems->ht_operation;
+ 	const struct ieee80211_vht_operation *vht_oper = elems->vht_operation;
+@@ -321,6 +322,10 @@ ieee80211_determine_ap_chan(struct ieee80211_sub_if_data *sdata,
+ 
+ 		eht_chandef.punctured =
+ 			ieee80211_eht_oper_dis_subchan_bitmap(eht_oper);
++		if (punctured == IEEE80211_PUNCT_UNSPECIFIED)
++			chandef->punctured = eht_chandef.punctured;
++		else
++			chandef->punctured = punctured;
+ 
+ 		if (!cfg80211_chandef_valid(&eht_chandef)) {
+ 			sdata_info(sdata,
+@@ -840,7 +845,8 @@ again:
+ 		return ERR_PTR(-ENOMEM);
+ 
+ 	ap_mode = ieee80211_determine_ap_chan(sdata, channel, bss->vht_cap_info,
+-					      elems, false, conn, ap_chandef);
++					      elems, false, conn, ap_chandef,
++					      IEEE80211_PUNCT_UNSPECIFIED);
+ 
+ 	/* this should be impossible since parsing depends on our mode */
+ 	if (WARN_ON(ap_mode > conn->mode)) {
+@@ -1007,7 +1013,8 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,
+ 
+ 	ap_mode = ieee80211_determine_ap_chan(sdata, channel, vht_cap_info,
+ 					      elems, true, &link->u.mgd.conn,
+-					      &ap_chandef);
++					      &ap_chandef,
++					      link->conf->chanreq.oper.punctured);
+ 
+ 	if (ap_mode != link->u.mgd.conn.mode) {
+ 		link_info(link,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0089-mtk-mac80211-add-STA-A-TTLM-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0089-mtk-mac80211-add-STA-A-TTLM-support.patch
new file mode 100644
index 0000000..96b579f
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/0089-mtk-mac80211-add-STA-A-TTLM-support.patch
@@ -0,0 +1,305 @@
+From 1d72b21f1119a0c50c70002b14408da5c800bea7 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Fri, 2 Aug 2024 17:08:08 +0800
+Subject: [PATCH 89/89] mtk: mac80211: add STA A-TTLM support
+
+Move adv_ttlm_info to ieee80211_vif so that driver can use it in
+vif_cfg_changed callback.
+
+Add BSS_CHANGED_MLD_ADV_TTLM and re-name the changed flag for
+negotiation TTLM.
+
+It is necessary to distinguish adv_ttlm from neg_ttlm because of the
+different data structure used.
+(ieee80211_adv_ttlm_info vs. ieee80211_neg_ttlm)
+
+This change includes:
+1. do not call ieee80211_set_active_link(), which will remove
+   disabled/dormant links. Removing the disabled/dormant links is not
+   the purpose of TTLM.
+2. use the flag BSS_CHANGED_MLD_ADV_TTLM properly.
+3. set adv_ttlm_info to active _before_ calling ieee80211_ttlm_set_links
+   so that driver knows the adv-TTLM is active or not when handle the
+   vif_cfg_vhanged callback.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ .../wireless/intel/iwlwifi/mvm/mld-mac80211.c |  2 +-
+ include/net/mac80211.h                        | 27 +++++++++--
+ net/mac80211/ieee80211_i.h                    | 12 -----
+ net/mac80211/main.c                           |  3 +-
+ net/mac80211/mlme.c                           | 48 +++++++++++--------
+ 5 files changed, 56 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+index 1dbc346..865c273 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+@@ -952,7 +952,7 @@ static void iwl_mvm_mld_vif_cfg_changed_station(struct iwl_mvm *mvm,
+ 			IWL_ERR(mvm, "failed to update power mode\n");
+ 	}
+ 
+-	if (changes & (BSS_CHANGED_MLD_VALID_LINKS | BSS_CHANGED_MLD_TTLM) &&
++	if (changes & (BSS_CHANGED_MLD_VALID_LINKS | BSS_CHANGED_MLD_NEG_TTLM) &&
+ 	    ieee80211_vif_is_mld(vif) && mvmvif->authorized)
+ 		wiphy_delayed_work_queue(mvm->hw->wiphy,
+ 					 &mvmvif->mlo_int_scan_wk, 0);
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 1345676..16e1861 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -365,7 +365,8 @@ struct ieee80211_vif_chanctx_switch {
+  * @BSS_CHANGED_UNSOL_BCAST_PROBE_RESP: Unsolicited broadcast probe response
+  *	status changed.
+  * @BSS_CHANGED_MLD_VALID_LINKS: MLD valid links status changed.
+- * @BSS_CHANGED_MLD_TTLM: negotiated TID to link mapping was changed
++ * @BSS_CHANGED_MLD_NEG_TTLM: negotiated TID to link mapping was changed
++ * @BSS_CHANGED_MLD_ADV_TTLM: advertised TID to link mapping was changed
+  * @BSS_CHANGED_TPE: transmit power envelope changed
+  */
+ enum ieee80211_bss_change {
+@@ -402,8 +403,9 @@ enum ieee80211_bss_change {
+ 	BSS_CHANGED_FILS_DISCOVERY      = 1<<30,
+ 	BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = 1<<31,
+ 	BSS_CHANGED_MLD_VALID_LINKS	= BIT_ULL(33),
+-	BSS_CHANGED_MLD_TTLM		= BIT_ULL(34),
+-	BSS_CHANGED_TPE			= BIT_ULL(35),
++	BSS_CHANGED_MLD_NEG_TTLM	= BIT_ULL(34),
++	BSS_CHANGED_MLD_ADV_TTLM	= BIT_ULL(35),
++	BSS_CHANGED_TPE			= BIT_ULL(36),
+ 
+ 	/* when adding here, make sure to change ieee80211_reconfig */
+ };
+@@ -1929,6 +1931,22 @@ struct ieee80211_vif_cfg {
+ 
+ #define IEEE80211_TTLM_NUM_TIDS 8
+ 
++/**
++ * struct ieee8021_adv_ttlm - advertised TID to link map info
++ *
++ * @switch_time: time in TUs at which the new mapping is established, or 0 if
++ *      there is no planned advertised TID-to-link mapping.
++ * @duration: duration of the planned TID-to-link mapping in TUs.
++ * @map: bitmap of usable links for all TIDs.
++ * @active: whether the advertised mapping is active or not.
++ */
++struct ieee80211_adv_ttlm {
++	u16 switch_time;
++	u32 duration;
++	u16 map;
++	bool active;
++};
++
+ /**
+  * struct ieee80211_neg_ttlm - negotiated TID to link map info
+  *
+@@ -1979,6 +1997,8 @@ enum ieee80211_neg_ttlm_res {
+  *	suspended due to negotiated TTLM, and could be activated in the
+  *	future by tearing down the TTLM negotiation.
+  *	0 for non-MLO.
++ * @adv_ttlm: advertised TID to link mapping info.
++ *	see &struct ieee80211_adv_ttlm.
+  * @neg_ttlm: negotiated TID to link mapping info.
+  *	see &struct ieee80211_neg_ttlm.
+  * @addr: address of this interface
+@@ -2019,6 +2039,7 @@ struct ieee80211_vif {
+ 	struct ieee80211_bss_conf bss_conf;
+ 	struct ieee80211_bss_conf __rcu *link_conf[IEEE80211_MLD_MAX_NUM_LINKS];
+ 	u16 valid_links, active_links, dormant_links, suspended_links;
++	struct ieee80211_adv_ttlm adv_ttlm;
+ 	struct ieee80211_neg_ttlm neg_ttlm;
+ 	u8 addr[ETH_ALEN] __aligned(2);
+ 	bool p2p;
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index a77e63c..9027209 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -496,17 +496,6 @@ struct ieee80211_sta_tx_tspec {
+ 	bool downgraded;
+ };
+ 
+-/* Advertised TID-to-link mapping info */
+-struct ieee80211_adv_ttlm_info {
+-	/* time in TUs at which the new mapping is established, or 0 if there is
+-	 * no planned advertised TID-to-link mapping
+-	 */
+-	u16 switch_time;
+-	u32 duration; /* duration of the planned T2L map in TUs */
+-	u16 map; /* map of usable links for all TIDs */
+-	bool active; /* whether the advertised mapping is active or not */
+-};
+-
+ DECLARE_EWMA(beacon_signal, 4, 4)
+ 
+ struct ieee80211_if_managed {
+@@ -606,7 +595,6 @@ struct ieee80211_if_managed {
+ 
+ 	/* TID-to-link mapping support */
+ 	struct wiphy_delayed_work ttlm_work;
+-	struct ieee80211_adv_ttlm_info ttlm_info;
+ 	struct wiphy_work teardown_ttlm_work;
+ 
+ 	/* dialog token enumerator for neg TTLM request */
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index 1de7f1d..6ab7a0c 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -328,7 +328,8 @@ EXPORT_SYMBOL(ieee80211_emulate_switch_vif_chanctx);
+ 				   BSS_CHANGED_ARP_FILTER |\
+ 				   BSS_CHANGED_SSID |\
+ 				   BSS_CHANGED_MLD_VALID_LINKS |\
+-				   BSS_CHANGED_MLD_TTLM)
++				   BSS_CHANGED_MLD_ADV_TTLM |\
++				   BSS_CHANGED_MLD_NEG_TTLM)
+ 
+ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
+ 				      u64 changed)
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 6cbcfe4..b235a43 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3712,8 +3712,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
+ 	sdata->vif.cfg.eml_med_sync_delay = 0;
+ 	sdata->vif.cfg.mld_capa_op = 0;
+ 
+-	memset(&sdata->u.mgd.ttlm_info, 0,
+-	       sizeof(sdata->u.mgd.ttlm_info));
++	memset(&sdata->vif.adv_ttlm, 0,
++	       sizeof(sdata->vif.adv_ttlm));
+ 	wiphy_delayed_work_cancel(sdata->local->hw.wiphy, &ifmgd->ttlm_work);
+ 
+ 	memset(&sdata->vif.neg_ttlm, 0, sizeof(sdata->vif.neg_ttlm));
+@@ -6383,7 +6383,7 @@ static int ieee80211_ttlm_set_links(struct ieee80211_sub_if_data *sdata,
+ 	if (sdata->vif.neg_ttlm.valid) {
+ 		memset(&sdata->vif.neg_ttlm, 0, sizeof(sdata->vif.neg_ttlm));
+ 		sdata->vif.suspended_links = 0;
+-		changed = BSS_CHANGED_MLD_TTLM;
++		changed = BSS_CHANGED_MLD_NEG_TTLM;
+ 	}
+ 
+ 	if (sdata->vif.active_links != active_links) {
+@@ -6391,6 +6391,9 @@ static int ieee80211_ttlm_set_links(struct ieee80211_sub_if_data *sdata,
+ 		 * so notify the driver about the status change
+ 		 */
+ 		changed |= BSS_CHANGED_MLD_VALID_LINKS;
++		/* FIXME calling ieee80211_set_active_links leads to inactive
++		 * links being deleted, which should not be the purpose of
++		 * "disabling links"
+ 		active_links &= sdata->vif.active_links;
+ 		if (!active_links)
+ 			active_links =
+@@ -6401,6 +6404,7 @@ static int ieee80211_ttlm_set_links(struct ieee80211_sub_if_data *sdata,
+ 			sdata_info(sdata, "Failed to set TTLM active links\n");
+ 			goto out;
+ 		}
++		*/
+ 	}
+ 
+ 	ret = ieee80211_vif_set_links(sdata, sdata->vif.valid_links,
+@@ -6412,7 +6416,10 @@ static int ieee80211_ttlm_set_links(struct ieee80211_sub_if_data *sdata,
+ 
+ 	sdata->vif.suspended_links = suspended_links;
+ 	if (sdata->vif.suspended_links)
+-		changed |= BSS_CHANGED_MLD_TTLM;
++		changed |= BSS_CHANGED_MLD_NEG_TTLM;
++
++	if (sdata->vif.adv_ttlm.active)
++		changed |= BSS_CHANGED_MLD_ADV_TTLM;
+ 
+ 	ieee80211_vif_cfg_change_notify(sdata, changed);
+ 
+@@ -6431,18 +6438,19 @@ static void ieee80211_tid_to_link_map_work(struct wiphy *wiphy,
+ 		container_of(work, struct ieee80211_sub_if_data,
+ 			     u.mgd.ttlm_work.work);
+ 
+-	new_active_links = sdata->u.mgd.ttlm_info.map &
++	new_active_links = sdata->vif.adv_ttlm.map &
+ 			   sdata->vif.valid_links;
+-	new_dormant_links = ~sdata->u.mgd.ttlm_info.map &
++	new_dormant_links = ~sdata->vif.adv_ttlm.map &
+ 			    sdata->vif.valid_links;
++	sdata->vif.adv_ttlm.active = true;
++	sdata->vif.adv_ttlm.switch_time = 0;
+ 
+ 	ieee80211_vif_set_links(sdata, sdata->vif.valid_links, 0);
+ 	if (ieee80211_ttlm_set_links(sdata, new_active_links, new_dormant_links,
+-				     0))
++				     0)) {
++		sdata->vif.adv_ttlm.active = false;
+ 		return;
+-
+-	sdata->u.mgd.ttlm_info.active = true;
+-	sdata->u.mgd.ttlm_info.switch_time = 0;
++	}
+ }
+ 
+ static u16 ieee80211_get_ttlm(u8 bm_size, u8 *data)
+@@ -6456,7 +6464,7 @@ static u16 ieee80211_get_ttlm(u8 bm_size, u8 *data)
+ static int
+ ieee80211_parse_adv_t2l(struct ieee80211_sub_if_data *sdata,
+ 			const struct ieee80211_ttlm_elem *ttlm,
+-			struct ieee80211_adv_ttlm_info *ttlm_info)
++			struct ieee80211_adv_ttlm *ttlm_info)
+ {
+ 	/* The element size was already validated in
+ 	 * ieee80211_tid_to_link_map_size_ok()
+@@ -6545,13 +6553,13 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
+ 		return;
+ 
+ 	if (!elems->ttlm_num) {
+-		if (sdata->u.mgd.ttlm_info.switch_time) {
++		if (sdata->vif.adv_ttlm.switch_time) {
+ 			/* if a planned TID-to-link mapping was cancelled -
+ 			 * abort it
+ 			 */
+ 			wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+ 						  &sdata->u.mgd.ttlm_work);
+-		} else if (sdata->u.mgd.ttlm_info.active) {
++		} else if (sdata->vif.adv_ttlm.active) {
+ 			/* if no TID-to-link element, set to default mapping in
+ 			 * which all TIDs are mapped to all setup links
+ 			 */
+@@ -6562,16 +6570,18 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
+ 				sdata_info(sdata, "Failed setting valid/dormant links\n");
+ 				return;
+ 			}
++			sdata->vif.adv_ttlm.active = false;
+ 			ieee80211_vif_cfg_change_notify(sdata,
+-							BSS_CHANGED_MLD_VALID_LINKS);
++							BSS_CHANGED_MLD_VALID_LINKS |
++							BSS_CHANGED_MLD_ADV_TTLM);
+ 		}
+-		memset(&sdata->u.mgd.ttlm_info, 0,
+-		       sizeof(sdata->u.mgd.ttlm_info));
++		memset(&sdata->vif.adv_ttlm, 0,
++		       sizeof(sdata->vif.adv_ttlm));
+ 		return;
+ 	}
+ 
+ 	for (i = 0; i < elems->ttlm_num; i++) {
+-		struct ieee80211_adv_ttlm_info ttlm_info;
++		struct ieee80211_adv_ttlm ttlm_info;
+ 		u32 res;
+ 
+ 		res = ieee80211_parse_adv_t2l(sdata, elems->ttlm[i],
+@@ -6617,7 +6627,7 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
+ 			else
+ 				delay_jiffies = 0;
+ 
+-			sdata->u.mgd.ttlm_info = ttlm_info;
++			sdata->vif.adv_ttlm = ttlm_info;
+ 			wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+ 						  &sdata->u.mgd.ttlm_work);
+ 			wiphy_delayed_work_queue(sdata->local->hw.wiphy,
+@@ -7476,7 +7486,7 @@ static void ieee80211_teardown_ttlm_work(struct wiphy *wiphy,
+ 	sdata->vif.suspended_links = 0;
+ 	ieee80211_vif_set_links(sdata, sdata->vif.valid_links,
+ 				new_dormant_links);
+-	ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_MLD_TTLM |
++	ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_MLD_NEG_TTLM |
+ 					       BSS_CHANGED_MLD_VALID_LINKS);
+ }
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/subsys.inc b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/subsys.inc
index 9bb2504..55ac991 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/subsys.inc
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/subsys.inc
@@ -1,64 +1,92 @@
 #patch subsys (come from openwrt/lede/target/linux/mediatek)
 SRC_URI_append = " \
-    file://0001-sync-backports-patches-build.patch \
-    file://0002-sync-backports-patches-ath.patch \
-    file://0003-sync-backports-patches-ath5k.patch \
-    file://0004-sync-backports-patches-ath9k.patch \
-    file://0005-sync-backports-patches-ath10k.patch \
-    file://0006-sync-backports-patches-rt2x00.patch \
-    file://0007-sync-backports-patches-subsys.patch \
-    file://0008-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch \
-    file://0009-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch \
-    file://0010-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch \
-    file://0011-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch \
-    file://0012-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch \
-    file://0013-mtk-mac80211-check-the-control-channel-before-downgr.patch \
-    file://0014-mtk-mac80211-fix-tx-amsdu-aggregation.patch \
-    file://0015-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch \
-    file://0016-mtk-mac80211-track-obss-color-bitmap.patch \
-    file://0017-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch \
-    file://0018-mtk-mac80211-support-configurable-addba-resp-time.patch \
-    file://0019-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch \
-    file://0020-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch \
-    file://0021-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch \
-    file://0022-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch \
-    file://0023-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch \
-    file://0024-mtk-mac80211-avoid-calling-switch_vif_chanctx-when-u.patch \
-    file://0025-mtk-mac80211-add-EHT-BA1024-support.patch \
-    file://0026-mtk-mac80211-add-rate-duration-for-EHT-rate.patch \
-    file://0027-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch \
-    file://0028-mtk-mac80211-inrease-beacon-loss-count.patch \
-    file://0029-mtk-cfg80211-add-support-for-updating-background-cha.patch \
-    file://0030-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch \
-    file://0031-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch \
-    file://0032-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch \
-    file://0033-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch \
-    file://0034-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch \
-    file://0035-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch \
-    file://0036-backports-update-kernel-version-check-for-eth_hw_add.patch \
-    file://0037-mac80211-mtk-ACS-channel-time-is-reset-by-ch_restore.patch \
-    file://0038-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch \
-    file://0039-mtk-mac80211-allow-multiple-links-for-STA-vif.patch \
-    file://0040-mtk-mac80211-increase-association-timeout-time.patch \
-    file://0041-mtk-mac80211-fix-crash-when-starting-tx-ba-session.patch \
-    file://0042-mtk-mac80211-use-link-address-for-eapol-source-in-ie.patch \
-    file://0043-cfg80211-mtk-implement-DFS-radar-detect-for-MLO.patch \
-    file://0044-mtk-wifi-mac80211-add-wds-mlo-support.patch \
-    file://0045-mtk-mac80211-fix-ieee80211_probe_client-warning.patch \
-    file://0046-mtk-mac80211-remove-link-0-warn-on-in-rate_control_r.patch \
-    file://0047-mtk-mac80211-fix-radar-required-of-link-issue-in-res.patch \
-    file://0048-mtk-cfg80211-rework-cac-started-cac-start-time-for-m.patch \
-    file://0049-mtk-mac80211-remove-links-when-removing-AP_VLAN-inte.patch \
-    file://0050-mtk-mac80211-fix-AP-mgmt-not-encrypted-in-WDS-mode-w.patch \
-    file://0051-mtk-mac80211-fix-ieee80211_ht_cap_ie_to_sta_ht_cap-w.patch \
-    file://0052-mtk-mac80211-fix-mac-address-to-support-hw-path-in-s.patch \
-    file://0053-mtk-mac80211-workaround-for-configuring-txpower-in-m.patch \
-    file://0054-mtk-mac80211-send-broadcast-multicast-mgmt.-via-all-.patch \
-    file://0055-mtk-mac80211-fix-mlo-BW-160-channel-switch-issue.patch \
-    file://0056-mtk-mac80211-extend-IEEE80211_KEY_FLAG_GENERATE_MMIE.patch \
-    file://0057-mtk-wifi-mt76-mt7996-not-to-check-need_offchan-for-M.patch \
-    file://0058-mtk-wifi-mt76-mt7996-assign-link-address-to-the-head.patch \
-    file://0059-mtk-wifi-mt76-mt7996-Do-MLD-address-translation-befo.patch \
-    file://0060-mtk-wifi-mac80211-defer-enabling-beacon-for-MLD-AP.patch \
-    file://0061-mtk-wifi-mac80211-fix-radar-trigger-issue-due-to-ref.patch \
+    file://0001-backports-sync-openwrt-patches-build.patch \
+    file://0002-backports-sync-openwrt-patches-ath.patch \
+    file://0003-backports-sync-openwrt-patches-ath5k.patch \
+    file://0004-backports-sync-openwrt-patches-ath9k.patch \
+    file://0005-backports-sync-openwrt-patches-ath10k.patch \
+    file://0006-backports-sync-openwrt-patches-rt2x00.patch \
+    file://0007-backports-sync-openwrt-patches-subsys.patch \
+    file://0008-backports-additional-fixes-for-5.4.patch \
+    file://0009-bp-Revert-wifi-mac80211-move-radar-detect-work-to-sd.patch \
+    file://0010-bp-wifi-mac80211-remove-label-usage-in-ieee80211_sta.patch \
+    file://0011-bp-wifi-trace-unlink-rdev_end_cac-trace-event-from-w.patch \
+    file://0012-bp-wifi-cfg80211-move-DFS-related-members-to-links-i.patch \
+    file://0013-bp-wifi-cfg80211-handle-DFS-per-link.patch \
+    file://0014-bp-wifi-mac80211-handle-DFS-per-link.patch \
+    file://0015-bp-wifi-cfg80211-mac80211-use-proper-link-ID-for-DFS.patch \
+    file://0016-bp-wifi-mac80211-handle-ieee80211_radar_detected-for.patch \
+    file://0017-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch \
+    file://0018-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch \
+    file://0019-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch \
+    file://0020-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch \
+    file://0021-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch \
+    file://0022-mtk-mac80211-check-the-control-channel-before-downgr.patch \
+    file://0023-mtk-mac80211-fix-tx-amsdu-aggregation.patch \
+    file://0024-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch \
+    file://0025-mtk-mac80211-track-obss-color-bitmap.patch \
+    file://0026-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch \
+    file://0027-mtk-mac80211-support-configurable-addba-resp-time.patch \
+    file://0028-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch \
+    file://0029-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch \
+    file://0030-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch \
+    file://0031-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch \
+    file://0032-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch \
+    file://0033-mtk-mac80211-add-EHT-BA1024-support.patch \
+    file://0034-mtk-mac80211-add-rate-duration-for-EHT-rate.patch \
+    file://0035-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch \
+    file://0036-mtk-mac80211-inrease-beacon-loss-count.patch \
+    file://0037-mtk-cfg80211-add-support-for-updating-background-cha.patch \
+    file://0038-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch \
+    file://0039-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch \
+    file://0040-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch \
+    file://0041-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch \
+    file://0042-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch \
+    file://0043-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch \
+    file://0044-mtk-mac80211-ACS-channel-time-is-reset-by-ch_restore.patch \
+    file://0045-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch \
+    file://0046-mtk-mac80211-allow-multiple-links-for-STA-vif.patch \
+    file://0047-mtk-mac80211-increase-association-timeout-time.patch \
+    file://0048-mtk-mac80211-use-link-address-for-eapol-source-in-ie.patch \
+    file://0049-mtk-cfg80211-implement-DFS-radar-detect-for-MLO.patch \
+    file://0050-mtk-mac80211-add-wds-mlo-support.patch \
+    file://0051-mtk-mac80211-fix-ieee80211_probe_client-warning.patch \
+    file://0052-mtk-mac80211-remove-link-0-warn-on-in-rate_control_r.patch \
+    file://0053-mtk-mac80211-fix-radar-required-of-link-issue-in-res.patch \
+    file://0054-mtk-cfg80211-rework-cac-started-cac-start-time-for-m.patch \
+    file://0055-mtk-mac80211-remove-links-when-removing-AP_VLAN-inte.patch \
+    file://0056-mtk-mac80211-fix-AP-mgmt-not-encrypted-in-WDS-mode-w.patch \
+    file://0057-mtk-mac80211-fix-ieee80211_ht_cap_ie_to_sta_ht_cap-w.patch \
+    file://0058-mtk-mac80211-fix-mac-address-to-support-hw-path-in-s.patch \
+    file://0059-mtk-mac80211-send-broadcast-multicast-mgmt.-via-all-.patch \
+    file://0060-mtk-mac80211-not-to-check-need_offchan-for-MLD-multi.patch \
+    file://0061-mtk-mac80211-assign-link-address-to-the-header-of-br.patch \
+    file://0062-mtk-mac80211-Do-MLD-address-translation-before-STA-p.patch \
+    file://0063-mtk-mac80211-defer-enabling-beacon-for-MLD-AP.patch \
+    file://0064-mtk-mac80211-prevent-STA-MLD-s-link-addr-from-being-.patch \
+    file://0065-mtk-mac80211-add-per-sta-prof-CSA-countdown-support.patch \
+    file://0066-mtk-mac80211-Add-support-for-EMLSR-support.patch \
+    file://0067-mtk-mac80211-set-max_amsdu_len-for-link_sta.patch \
+    file://0068-mtk-mac80211-legacy-AP-scan-request-should-contain-v.patch \
+    file://0069-mtk-mac80211-do-not-check-pre-CAC-allowed-for-scan.patch \
+    file://0070-mtk-mac80211-add-mlo-probe-client-support.patch \
+    file://0071-mtk-mac80211-rework-radar-notify-for-MLO.patch \
+    file://0072-mtk-mac80211-add-DFS-CAC-countdown-in-CSA-flow.patch \
+    file://0073-mtk-mac80211-add-mlo-related-debugfs-knob.patch \
+    file://0074-mtk-mac80211-Add-exported-function-for-SoftMAC-drive.patch \
+    file://0075-mtk-mac80211-add-per-link-txpower-config.patch \
+    file://0076-mtk-mac80211-add-link-information-when-dump-station.patch \
+    file://0077-mtk-mac80211-add-new-argument-link_id-in-set_bitrate.patch \
+    file://0078-mtk-mac80211-add-per-radio-antenna-config.patch \
+    file://0079-mtk-mac80211-add-new-rc-changed-enum-for-wifi7-cert.patch \
+    file://0080-mtk-mac80211-do-not-check-radar-required-for-remain-.patch \
+    file://0081-mtk-mac80211-Add-ba_disable-debugfs-to-disable-ba.patch \
+    file://0082-mtk-mac80211-fix-incorrect-VIF-assignment-for-IEEE-8.patch \
+    file://0083-mtk-mac80211-Add-STA-site-link-add-support.patch \
+    file://0084-mtk-mac80211-Fix-channel-switch-punct-bitmap-would-b.patch \
+    file://0085-mtk-mac80211-add-ieee80211_links_removed-to-support-.patch \
+    file://0086-mtk-mac80211-add-A-TTLM-support.patch \
+    file://0087-mtk-mac80211-add-SCS-capa-definition.patch \
+    file://0088-mtk-mac80211-add-puncture-bitmap-sync-for-extender.patch \
+    file://0089-mtk-mac80211-add-STA-A-TTLM-support.patch \
     "