[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(¶ms->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],
++ ¶ms.counter_offsets_sta_prof,
++ ¶ms.n_counter_offsets_sta_prof);
++ if (err)
++ goto free;
++
+ skip_beacons:
+ err = nl80211_parse_chandef(rdev, info, ¶ms.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, ¶ms.chandef, NL80211_DFS_AVAILABLE);
+ }
+
+- if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, ¶ms.chandef,
+- wdev->iftype)) {
++ /* handle DFS CAC after CSA is sent */
++ if (!cfg80211_reg_can_beacon_dfs_relax(&rdev->wiphy, ¶ms.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 \
"