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

[Description]
d34487c3 [MAC80211][WiFi6][mt76][Add mt7981 mt7916 mt7915 fw_wm_info support]
327eaf76 [MAC80211][wifi7][Release][Update WiFi7 Filogic680/660 Firmware]
fa03d7ea [MAC80211][WiFi6][hostapd][Fix 2/6G channel switch fail issue]
c0bf67d9 [MAC80211][misc][Add Filogic 880 Non-MLO SDK Release]
e5d03217 [MAC80211][WiFi6][Rebase Patches][Refactor set_offchan_ctrl]
6cad79ae [MAC80211][WiFi6][hostapd][Add support for DFS channel switch with CSA sent]
cde50012 [MAC80211][WiFi6][core][Add DFS channel CSA flow]
0142fd16 [MAC80211][WiFi6][mt76][Add post channel switch callback for DFS channel switch support]
cb3f4c58 [MAC80211][WiFi6][mt76][Update Connac2 CSI Feature]
1b66ac4c [MAC80211][WiFi6][mt76][Refactor precal loading and binfile mode to align upstream]
0ece467b [MAC80211][WiFi6][mt76][Fix scs feature calltrace issue]
1dca03f1 [MAC80211][WiFi6/7][Misc][Change group mgmt cipher setting to align group cipher]
0aa52762 [MAC80211][WiFi6][mt76][Fix muru_onoff as all enabled by default]
c3e5f505 [MAC80211][WiFi6][hostapd][Fix mu_onoff was overwritten with unexpected values]
7090eabe [MAC80211][WiFi6/7][core][Add tx_burst option in wireless configuration file for Kite]
669d3071 [MAC80211][WiFi6][mt76][rebase patches]
c5d6b3e7 [mac80211][mt76][Fix patch fail]
55ef4059 [MAC80211][WiFi6][mt76][Fix TxS ACK is incorrectly reported]
e166eae1 [MAC80211][WiFi6][Misc][Add Filogic 820 Build]
118ffd7e [mac80211][wifi6][mt76][Fix crash caused by per-BSS counter updating]
68015098 [MAC80211][WiFi7][mt76][Add Eagle 2adie TBTC default bin]
eae6e8c0 [MAC80211][WiFi7][mt76][Add Eagle 2adie TBTC support in mt76 Makefile]
cccc8eb9 [MAC80211[WiFi6][hostapd][Fix wds AP interface adding issue]
173fe3b0 [MAC80211][WiFi6][mt76][Add scs feature for connac2 mt76]
1b8af8d9 [MAC80211][WiFi6][mt76][rebase patches]
6dc40325 [MAC80211][WiFi7][misc][fix hostapd udebug init fail]
aa4b39ae [[mt76][csi][mt7915][mt7986] update csi feature]
7d458da2 [MAC80211][WiFi6][hostapd][Auto Channel Selection channel time issue]
f0b5502f [MAC80211][WiFi7][misc][fix build error]
b63c9cf6 [MAC80211][WiFi6/7][misc][fix ucode and backport 6.5 patch fail]
ce056dc7 [mac80211][wifi6][mt76][Add variant support for Cheetah MT76]
c5ae3f9c [MAC80211][WiFi6/7][Misc][Add country setting consistent check before enable AP.]
d57d9c5a [mac80211][misc][wifi6/7][Update libubox to the latest version]
be7dbf21 [mac80211][misc][wifi7][Revert libubox to 20230523 to prevent build fail]
ae9b4428 [MAC80211][WiFi6][mt76][Add cal free data support]
52fd5d80 [MAC80211][WiFi7][Misc][Adjust MU EDCA timer in mac80211.sh]
66c649de [mac80211][hostapd][netifd][Revert udebug for build pass]
136c7f11 [MAC80211][hostapd][wifi7][Fix build fail]
8911e727 [MAC80211][WiFi6][hostapd][Auto Channel Selection issue and patch sync]
75161456 [MAC80211][WiFi7][mt76][Fix issue for testmode bit in eagle defaut bin]
4dc2d646 [MAC80211][WiFi6][mt76][Fix cheetah 5G ibf issue]
d4561158 [MAC80211][WiFi6][Misc][Add Filogic 820 Build]
2e5a1997 [MAC80211][WiFi6][hostapd][Backport hostapd ACS patches and some ACS fixes]
b0305b6e [MAC80211][WiFi6/7][Misc][Add 6g band default enable mbo IE]

[Release-log]

Change-Id: I872b422c1fc56ebd3a1cff3252cb403a2015eabe
diff --git a/recipes-wifi/hostapd/files/002-rdkb-add-ucode-support.patch b/recipes-wifi/hostapd/files/002-rdkb-add-ucode-support.patch
index 16e099a..d31a75f 100644
--- a/recipes-wifi/hostapd/files/002-rdkb-add-ucode-support.patch
+++ b/recipes-wifi/hostapd/files/002-rdkb-add-ucode-support.patch
@@ -4,7 +4,7 @@
  OBJS += ../src/utils/ucode.o
  OBJS += ../src/ap/ucode.o
  NEED_ULOOP:=y
-+LIBS += -lblobmsg_json -lucode
++LIBS += -lblobmsg_json -lucode -ludebug
  endif
  
  ifdef NEED_ULOOP
@@ -15,7 +15,7 @@
  OBJS += ../src/utils/ucode.o
  OBJS += ucode.o
  NEED_ULOOP:=y
-+LIBS += -lblobmsg_json -lucode
++LIBS += -lblobmsg_json -lucode -ludebug
  endif
  
  ifdef NEED_ULOOP
\ No newline at end of file
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/601-ucode_support.patch b/recipes-wifi/hostapd/files/patches-2.10.3/601-ucode_support.patch
index 23f535b..cfdb51f 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/601-ucode_support.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/601-ucode_support.patch
@@ -196,7 +196,7 @@
  
  #ifdef CONFIG_BGSCAN
  	if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid)
-@@ -7596,6 +7597,7 @@ struct wpa_supplicant * wpa_supplicant_a
+@@ -7594,6 +7595,7 @@ struct wpa_supplicant * wpa_supplicant_a
  #endif /* CONFIG_P2P */
  
  	wpas_ubus_add_bss(wpa_s);
@@ -204,7 +204,7 @@
  
  	return wpa_s;
  }
-@@ -7623,6 +7625,7 @@ int wpa_supplicant_remove_iface(struct w
+@@ -7621,6 +7623,7 @@ int wpa_supplicant_remove_iface(struct w
  	struct wpa_supplicant *parent = wpa_s->parent;
  #endif /* CONFIG_MESH */
  
@@ -212,7 +212,7 @@
  	wpas_ubus_free_bss(wpa_s);
  
  	/* Remove interface from the global list of interfaces */
-@@ -7933,6 +7936,7 @@ struct wpa_global * wpa_supplicant_init(
+@@ -7931,6 +7934,7 @@ struct wpa_global * wpa_supplicant_init(
  
  	eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
  			       wpas_periodic, global, NULL);
@@ -220,7 +220,7 @@
  
  	return global;
  }
-@@ -7971,12 +7975,8 @@ int wpa_supplicant_run(struct wpa_global
+@@ -7969,12 +7973,8 @@ int wpa_supplicant_run(struct wpa_global
  	eloop_register_signal_terminate(wpa_supplicant_terminate, global);
  	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
  
@@ -233,7 +233,7 @@
  	return 0;
  }
  
-@@ -8009,6 +8009,8 @@ void wpa_supplicant_deinit(struct wpa_gl
+@@ -8007,6 +8007,8 @@ void wpa_supplicant_deinit(struct wpa_gl
  
  	wpas_notify_supplicant_deinitialized(global);
  
@@ -395,7 +395,60 @@
  {
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -1333,7 +1333,7 @@ static void wpa_driver_nl80211_event_rtm
+@@ -73,6 +73,16 @@ enum nlmsgerr_attrs {
+ 
+ #endif /* ANDROID */
+ 
++static void handle_nl_debug_hook(struct nl_msg *msg, int tx)
++{
++	const struct nlmsghdr *nlh;
++
++	if (!wpa_netlink_hook)
++		return;
++
++	nlh = nlmsg_hdr(msg);
++	wpa_netlink_hook(tx, nlh, nlh->nlmsg_len);
++}
+ 
+ static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
+ {
+@@ -379,6 +389,11 @@ static int no_seq_check(struct nl_msg *m
+ 	return NL_OK;
+ }
+ 
++static int debug_handler(struct nl_msg *msg, void *arg)
++{
++	handle_nl_debug_hook(msg, 0);
++	return NL_OK;
++}
+ 
+ static void nl80211_nlmsg_clear(struct nl_msg *msg)
+ {
+@@ -415,6 +430,7 @@ static int send_and_recv(struct nl80211_
+ 	if (!msg)
+ 		return -ENOMEM;
+ 
++	handle_nl_debug_hook(msg, 1);
+ 	cb = nl_cb_clone(global->nl_cb);
+ 	if (!cb)
+ 		goto out;
+@@ -443,6 +459,7 @@ static int send_and_recv(struct nl80211_
+ 
+ 	err = 1;
+ 
++	nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
+ 	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
+ 	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
+ 	if (ack_handler_custom) {
+@@ -919,6 +936,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs
+ 			os_free(w);
+ 			return NULL;
+ 		}
++		nl_cb_set(w->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
+ 		nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
+ 			  no_seq_check, NULL);
+ 		nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
+@@ -1333,7 +1351,7 @@ static void wpa_driver_nl80211_event_rtm
  		}
  		wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
  			   namebuf, ifname);
@@ -404,7 +457,7 @@
  			wpa_printf(MSG_DEBUG,
  				   "nl80211: Not the main interface (%s) - do not indicate interface down",
  				   drv->first_bss->ifname);
-@@ -1369,7 +1369,7 @@ static void wpa_driver_nl80211_event_rtm
+@@ -1369,7 +1387,7 @@ static void wpa_driver_nl80211_event_rtm
  		}
  		wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
  			   namebuf, ifname);
@@ -413,7 +466,23 @@
  			wpa_printf(MSG_DEBUG,
  				   "nl80211: Not the main interface (%s) - do not indicate interface up",
  				   drv->first_bss->ifname);
-@@ -8432,6 +8432,7 @@ static void *i802_init(struct hostapd_da
+@@ -1992,6 +2010,7 @@ static int wpa_driver_nl80211_init_nl_gl
+ 		/* Continue without vendor events */
+ 	}
+ 
++	nl_cb_set(global->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
+ 	nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
+ 		  no_seq_check, NULL);
+ 	nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
+@@ -2160,6 +2179,7 @@ static int nl80211_init_bss(struct i802_
+ 	if (!bss->nl_cb)
+ 		return -1;
+ 
++	nl_cb_set(bss->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
+ 	nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
+ 		  no_seq_check, NULL);
+ 	nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
+@@ -8432,6 +8452,7 @@ static void *i802_init(struct hostapd_da
  	char master_ifname[IFNAMSIZ];
  	int ifindex, br_ifindex = 0;
  	int br_added = 0;
@@ -421,7 +490,7 @@
  
  	bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
  					  params->global_priv, 1,
-@@ -8491,21 +8492,17 @@ static void *i802_init(struct hostapd_da
+@@ -8491,21 +8512,17 @@ static void *i802_init(struct hostapd_da
  	    (params->num_bridge == 0 || !params->bridge[0]))
  		add_ifidx(drv, br_ifindex, drv->ifindex);
  
@@ -453,7 +522,7 @@
  	}
  
  	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
-@@ -8875,6 +8872,50 @@ static int wpa_driver_nl80211_if_remove(
+@@ -8875,6 +8892,50 @@ static int wpa_driver_nl80211_if_remove(
  	return 0;
  }
  
@@ -504,7 +573,7 @@
  
  static int cookie_handler(struct nl_msg *msg, void *arg)
  {
-@@ -10513,6 +10554,37 @@ static int driver_nl80211_if_remove(void
+@@ -10513,6 +10574,37 @@ static int driver_nl80211_if_remove(void
  }
  
  
@@ -542,7 +611,7 @@
  static int driver_nl80211_send_mlme(void *priv, const u8 *data,
  				    size_t data_len, int noack,
  				    unsigned int freq,
-@@ -13697,6 +13769,8 @@ const struct wpa_driver_ops wpa_driver_n
+@@ -13697,6 +13789,8 @@ const struct wpa_driver_ops wpa_driver_n
  	.set_acl = wpa_driver_nl80211_set_acl,
  	.if_add = wpa_driver_nl80211_if_add,
  	.if_remove = driver_nl80211_if_remove,
@@ -551,3 +620,52 @@
  	.send_mlme = driver_nl80211_send_mlme,
  	.get_hw_feature_data = nl80211_get_hw_feature_data,
  	.sta_add = wpa_driver_nl80211_sta_add,
+--- a/src/utils/wpa_debug.c
++++ b/src/utils/wpa_debug.c
+@@ -26,6 +26,10 @@ static FILE *wpa_debug_tracing_file = NU
+ #define WPAS_TRACE_PFX "wpas <%d>: "
+ #endif /* CONFIG_DEBUG_LINUX_TRACING */
+ 
++void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
++void (*wpa_hexdump_hook)(int level, const char *title, const void *buf,
++			 size_t len);
++void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
+ 
+ int wpa_debug_level = MSG_INFO;
+ int wpa_debug_show_keys = 0;
+@@ -210,6 +214,12 @@ void _wpa_printf(int level, const char *
+ {
+ 	va_list ap;
+ 
++	if (wpa_printf_hook) {
++		va_start(ap, fmt);
++		wpa_printf_hook(level, fmt, ap);
++		va_end(ap);
++	}
++
+ 	if (level >= wpa_debug_level) {
+ #ifdef CONFIG_ANDROID_LOG
+ 		va_start(ap, fmt);
+@@ -260,6 +270,9 @@ void _wpa_hexdump(int level, const char
+ {
+ 	size_t i;
+ 
++	if (wpa_hexdump_hook)
++		wpa_hexdump_hook(level, title, buf, len);
++
+ #ifdef CONFIG_DEBUG_LINUX_TRACING
+ 	if (wpa_debug_tracing_file != NULL) {
+ 		fprintf(wpa_debug_tracing_file,
+--- a/src/utils/wpa_debug.h
++++ b/src/utils/wpa_debug.h
+@@ -11,6 +11,10 @@
+ 
+ #include "wpabuf.h"
+ 
++extern void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
++extern void (*wpa_hexdump_hook)(int level, const char *title,
++				const void *buf, size_t len);
++extern void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
+ extern int wpa_debug_level;
+ extern int wpa_debug_show_keys;
+ extern int wpa_debug_timestamp;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-mtk-hostapd-Add-neighbor-report-and-BSS-Termination-.patch
similarity index 96%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-mtk-hostapd-Add-neighbor-report-and-BSS-Termination-.patch
index 7c00526..25892c8 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-mtk-hostapd-Add-neighbor-report-and-BSS-Termination-.patch
@@ -1,7 +1,7 @@
-From 9ae2d23b69518792f81ec574c3d6e9000deb1b5d Mon Sep 17 00:00:00 2001
+From 154b32c66ff22838dc619d85332eadae16cb0353 Mon Sep 17 00:00:00 2001
 From: "howard.hsu" <howard-yh.hsu@mediatek.com>
 Date: Wed, 19 Jan 2022 19:18:07 +0800
-Subject: [PATCH 01/38] hostapd: mtk: Add neighbor report and BSS Termination
+Subject: [PATCH 01/54] mtk: hostapd: Add neighbor report and BSS Termination
  for MBO certification
 
 1. Add hostapd_neighbor_count() and hostapd_neighbor_insert_buffer ()
@@ -31,7 +31,7 @@
  9 files changed, 223 insertions(+), 4 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 0a892c9..98d598e 100644
+index 0a892c915..98d598ea9 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -1290,6 +1290,11 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
@@ -47,7 +47,7 @@
  		ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
  		if (ret)
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 298216a..73b33b4 100644
+index 298216a47..73b33b42a 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -171,6 +171,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
@@ -59,7 +59,7 @@
  
  
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 0790478..82338e2 100644
+index 0790478ee..82338e213 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -558,6 +558,7 @@ struct hostapd_bss_config {
@@ -71,7 +71,7 @@
  	/* IEEE 802.11u - Interworking */
  	int interworking;
 diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
-index 42c9593..0e173f1 100644
+index 42c959387..0e173f174 100644
 --- a/src/ap/ctrl_iface_ap.c
 +++ b/src/ap/ctrl_iface_ap.c
 @@ -1274,6 +1274,10 @@ int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
@@ -114,7 +114,7 @@
  	if (pos) {
  		unsigned int mbo_reason, cell_pref, reassoc_delay;
 diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
-index 4642e49..cce6df4 100644
+index 4642e4927..cce6df41c 100644
 --- a/src/ap/gas_serv.c
 +++ b/src/ap/gas_serv.c
 @@ -19,6 +19,7 @@
@@ -182,7 +182,7 @@
  #ifdef CONFIG_FILS
  		if (info_id == ANQP_FILS_REALM_INFO &&
 diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h
-index 7646a98..ce492b5 100644
+index 7646a98a4..ce492b53f 100644
 --- a/src/ap/gas_serv.h
 +++ b/src/ap/gas_serv.h
 @@ -40,6 +40,8 @@
@@ -195,7 +195,7 @@
   * First 15 Hotspot 2.0 vendor specific ANQP-elements can be included in the
   * optimized bitmap.
 diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
-index 5b276e8..1c14b32 100644
+index 5b276e8da..1c14b3201 100644
 --- a/src/ap/neighbor_db.c
 +++ b/src/ap/neighbor_db.c
 @@ -89,6 +89,38 @@ int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen)
@@ -329,7 +329,7 @@
 +}
 +#endif
 diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
-index 992671b..a1ddc07 100644
+index 992671b62..a1ddc075b 100644
 --- a/src/ap/neighbor_db.h
 +++ b/src/ap/neighbor_db.h
 @@ -24,4 +24,13 @@ int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
@@ -347,7 +347,7 @@
 +#endif
  #endif /* NEIGHBOR_DB_H */
 diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
-index ba1dd2e..939d447 100644
+index ba1dd2ed1..939d4471b 100644
 --- a/src/ap/wnm_ap.c
 +++ b/src/ap/wnm_ap.c
 @@ -20,6 +20,7 @@
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-mtk-hostapd-print-sae-groups-by-hostapd-ctrl.patch
similarity index 84%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-mtk-hostapd-print-sae-groups-by-hostapd-ctrl.patch
index d9b0cba..976c625 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-mtk-hostapd-print-sae-groups-by-hostapd-ctrl.patch
@@ -1,14 +1,14 @@
-From b76669952a1971105f1de99b69e9711ab71e9c63 Mon Sep 17 00:00:00 2001
+From 135e2f4368bba88d8823da63a134fdcc587fe698 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 20 Sep 2022 19:33:45 +0800
-Subject: [PATCH 02/38] hostapd: mtk: print sae groups by hostapd ctrl
+Subject: [PATCH 02/54] mtk: hostapd: print sae groups by hostapd ctrl
 
 ---
  hostapd/ctrl_iface.c | 13 +++++++++++++
  1 file changed, 13 insertions(+)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 98d598e..c03e6f6 100644
+index 98d598ea9..c03e6f608 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -1364,6 +1364,19 @@ static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-mtk-hostapd-add-support-for-runtime-set-in-band-disc.patch
similarity index 93%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-mtk-hostapd-add-support-for-runtime-set-in-band-disc.patch
index 85ffb3b..29b4c03 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-mtk-hostapd-add-support-for-runtime-set-in-band-disc.patch
@@ -1,7 +1,7 @@
-From 9aaf05a3b4ec0cf420a20cbb5b2dc65b66eacb49 Mon Sep 17 00:00:00 2001
+From 55220dcc0fcd43270edf583720e0b36e453dc2d7 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 31 May 2022 21:15:54 +0800
-Subject: [PATCH 03/38] hostapd: mtk: add support for runtime set in-band
+Subject: [PATCH 03/54] mtk: hostapd: add support for runtime set in-band
  discovery
 
 Usage:
@@ -21,7 +21,7 @@
  5 files changed, 98 insertions(+), 4 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c03e6f6..ee6d492 100644
+index c03e6f608..ee6d492f8 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -770,6 +770,69 @@ static int hostapd_ctrl_iface_send_qos_map_conf(struct hostapd_data *hapd,
@@ -105,7 +105,7 @@
  		reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
  							  reply_size);
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 61f8cba..dfc996d 100644
+index 61f8cba12..dfc996d49 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -655,6 +655,24 @@ static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
@@ -143,7 +143,7 @@
  };
  
 diff --git a/src/ap/beacon.c b/src/ap/beacon.c
-index 6366d77..d160675 100644
+index 6366d77f0..d160675cb 100644
 --- a/src/ap/beacon.c
 +++ b/src/ap/beacon.c
 @@ -1648,6 +1648,8 @@ static u8 * hostapd_fils_discovery(struct hostapd_data *hapd,
@@ -166,10 +166,10 @@
  						  &params->fd_frame_tmpl_len);
  
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index f6c5df9..c7745b6 100644
+index 98510f1cf..a3e436e95 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -4686,9 +4686,10 @@ static int nl80211_fils_discovery(struct i802_bss *bss, struct nl_msg *msg,
+@@ -4706,9 +4706,10 @@ static int nl80211_fils_discovery(struct i802_bss *bss, struct nl_msg *msg,
  			params->fd_max_int) ||
  	    (params->fd_frame_tmpl &&
  	     nla_put(msg, NL80211_FILS_DISCOVERY_ATTR_TMPL,
@@ -182,7 +182,7 @@
  	nla_nest_end(msg, attr);
  	return 0;
  }
-@@ -5300,7 +5301,10 @@ static int wpa_driver_nl80211_set_ap(void *priv,
+@@ -5320,7 +5321,10 @@ static int wpa_driver_nl80211_set_ap(void *priv,
  #endif /* CONFIG_SAE */
  
  #ifdef CONFIG_FILS
@@ -195,7 +195,7 @@
  #endif /* CONFIG_FILS */
  
 diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index c59fec4..82860ae 100644
+index c59fec406..82860ae32 100644
 --- a/src/drivers/nl80211_copy.h
 +++ b/src/drivers/nl80211_copy.h
 @@ -7591,6 +7591,7 @@ enum nl80211_fils_discovery_attributes {
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0004-hostapd-mtk-Add-mtk_vendor.h.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0004-mtk-hostapd-Add-mtk_vendor.h.patch
similarity index 97%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0004-hostapd-mtk-Add-mtk_vendor.h.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0004-mtk-hostapd-Add-mtk_vendor.h.patch
index 13a7d1d..16949b7 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0004-hostapd-mtk-Add-mtk_vendor.h.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0004-mtk-hostapd-Add-mtk_vendor.h.patch
@@ -1,7 +1,7 @@
-From 86553b9434ad98e4ec3dd19fbc5589ca24501f4d Mon Sep 17 00:00:00 2001
+From 2bba6f165367d21c44cb4da8b74904ecee956d55 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Mon, 30 May 2022 15:04:57 +0800
-Subject: [PATCH 04/38] hostapd: mtk: Add mtk_vendor.h
+Subject: [PATCH 04/54] mtk: hostapd: Add mtk_vendor.h
 
 ---
  src/common/mtk_vendor.h | 197 ++++++++++++++++++++++++++++++++++++++++
@@ -10,7 +10,7 @@
 
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
 new file mode 100644
-index 0000000..4a19d2f
+index 000000000..4a19d2fc9
 --- /dev/null
 +++ b/src/common/mtk_vendor.h
 @@ -0,0 +1,197 @@
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0005-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0005-mtk-hostapd-Support-EDCCA-hostapd-configuration.patch
similarity index 96%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0005-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0005-mtk-hostapd-Support-EDCCA-hostapd-configuration.patch
index 868adca..37f5172 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0005-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0005-mtk-hostapd-Support-EDCCA-hostapd-configuration.patch
@@ -1,7 +1,7 @@
-From 906a70c7df5918c40c9552e078690ab7305ed40e Mon Sep 17 00:00:00 2001
+From 7e1b6b0dc2167af5b9d58466ce693b67e6b5dbf2 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Mon, 30 May 2022 16:31:34 +0800
-Subject: [PATCH 05/38] hostapd: mtk: Support EDCCA hostapd configuration
+Subject: [PATCH 05/54] mtk: hostapd: Support EDCCA hostapd configuration
 
 edcca_enable and edcca_compensation and implement edcca related handlers.
 ---
@@ -20,7 +20,7 @@
  12 files changed, 428 insertions(+), 6 deletions(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 4b0f99f..d281026 100644
+index 4b0f99fd2..d281026e8 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4809,6 +4809,40 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -65,7 +65,7 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index ee6d492..cad3f86 100644
+index ee6d492f8..cad3f863c 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -542,6 +542,19 @@ static const char * pbc_status_str(enum pbc_status status)
@@ -215,7 +215,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 73b33b4..8e56d10 100644
+index 73b33b42a..8e56d1082 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -295,6 +295,9 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -237,7 +237,7 @@
  	wpabuf_free(conf->civic);
  
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 82338e2..24d540d 100644
+index 82338e213..24d540dbf 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1193,8 +1193,38 @@ struct hostapd_config {
@@ -280,7 +280,7 @@
  static inline enum oper_chan_width
  hostapd_get_oper_chwidth(struct hostapd_config *conf)
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 75ddfa1..99ba973 100644
+index 75ddfa15c..99ba973aa 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1137,3 +1137,27 @@ int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
@@ -312,7 +312,7 @@
 +	return hapd->driver->get_edcca(hapd->drv_priv, mode, value);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 96c8c4e..6ca693b 100644
+index 96c8c4e2c..6ca693b0b 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -144,6 +144,10 @@ int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
@@ -327,7 +327,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 6746de2..1b9ce6f 100644
+index a203546b6..f7c80c73b 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2511,6 +2511,13 @@ dfs_offload:
@@ -345,7 +345,7 @@
  		   iface->bss[0]->conf->iface);
  	if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 4a19d2f..6121857 100644
+index 4a19d2fc9..6121857dd 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -30,14 +30,22 @@ enum mtk_vendor_attr_edcca_ctrl {
@@ -378,10 +378,10 @@
  	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
  	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index cc49011..fca2035 100644
+index c5cc26737..7d71aa783 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5102,6 +5102,10 @@ struct wpa_driver_ops {
+@@ -5105,6 +5105,10 @@ struct wpa_driver_ops {
  			      const u8 *match, size_t match_len,
  			      bool multicast);
  #endif /* CONFIG_TESTING_OPTIONS */
@@ -393,7 +393,7 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index c7745b6..0a159d5 100644
+index a3e436e95..1a2f52b77 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
 @@ -37,6 +37,8 @@
@@ -405,7 +405,7 @@
  
  
  #ifndef NETLINK_CAP_ACK
-@@ -13748,6 +13750,174 @@ static int testing_nl80211_radio_disable(void *priv, int disabled)
+@@ -13768,6 +13770,174 @@ static int testing_nl80211_radio_disable(void *priv, int disabled)
  
  #endif /* CONFIG_TESTING_OPTIONS */
  
@@ -580,7 +580,7 @@
  
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
-@@ -13904,4 +14074,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -13924,4 +14094,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.register_frame = testing_nl80211_register_frame,
  	.radio_disable = testing_nl80211_radio_disable,
  #endif /* CONFIG_TESTING_OPTIONS */
@@ -590,7 +590,7 @@
 +	.get_edcca = nl80211_get_edcca,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index aee8c45..51b3fbe 100644
+index aee8c4512..51b3fbec8 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -202,6 +202,7 @@ struct wpa_driver_nl80211_data {
@@ -602,7 +602,7 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 5e64068..5dadf24 100644
+index f01a526a0..47654f65b 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
 @@ -18,6 +18,7 @@
@@ -613,7 +613,7 @@
  
  
  static int protocol_feature_handler(struct nl_msg *msg, void *arg)
-@@ -1107,6 +1108,12 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1111,6 +1112,12 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  					break;
  				}
  #endif /* CONFIG_DRIVER_NL80211_BRCM */
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-mtk-hostapd-Add-hostapd-MU-SET-GET-control.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-mtk-hostapd-Add-hostapd-MU-SET-GET-control.patch
index 43f214c..e0bdc50 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-mtk-hostapd-Add-hostapd-MU-SET-GET-control.patch
@@ -1,11 +1,11 @@
-From f868636d86170f6ebe9dba785f22195b06177af1 Mon Sep 17 00:00:00 2001
+From 8ed06968aea1170b6fbb7d88fbf546764c404eae Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Tue, 9 Aug 2022 10:23:44 -0700
-Subject: [PATCH 06/38] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH 06/54] mtk: hostapd: Add hostapd MU SET/GET control
 
 ---
  hostapd/config_file.c             |   9 +++
- hostapd/ctrl_iface.c              |  62 +++++++++++++++++
+ hostapd/ctrl_iface.c              |  66 ++++++++++++++++++
  hostapd/hostapd_cli.c             |  18 +++++
  src/ap/ap_config.c                |   1 +
  src/ap/ap_config.h                |   1 +
@@ -17,10 +17,10 @@
  src/drivers/driver_nl80211.c      | 110 ++++++++++++++++++++++++++++++
  src/drivers/driver_nl80211.h      |   1 +
  src/drivers/driver_nl80211_capa.c |   3 +
- 13 files changed, 251 insertions(+)
+ 13 files changed, 255 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index d281026..ec3b41a 100644
+index d281026e8..ec3b41abe 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -3677,6 +3677,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -40,10 +40,10 @@
  	} else if (os_strcmp(buf, "max_listen_interval") == 0) {
  		bss->max_listen_interval = atoi(pos);
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index cad3f86..c5d92b0 100644
+index cad3f863c..b10483652 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3488,6 +3488,63 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
+@@ -3488,6 +3488,67 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
  }
  
  
@@ -93,6 +93,10 @@
 +	pos = buf;
 +	end = buf + buflen;
 +
++	if (hapd->iface->state != HAPD_IFACE_ENABLED)
++		return os_snprintf(pos, end - pos, "Not allowed to get_mu when current state is %s\n",
++				   hostapd_state_text(hapd->iface->state));
++
 +	if (hostapd_drv_mu_dump(hapd, &mu_onoff) == 0) {
 +		hapd->iconf->mu_onoff = mu_onoff;
 +		return os_snprintf(pos, end - pos, "[hostapd_cli] = UL MU-MIMO: %d, DL MU-MIMO: %d, UL OFDMA: %d, DL OFDMA: %d\n",
@@ -107,7 +111,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4047,6 +4104,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4047,6 +4108,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "GET_EDCCA ", 10) == 0) {
  		reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
  							  reply_size);
@@ -120,7 +124,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index dfc996d..98892ee 100644
+index dfc996d49..98892ee9d 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1400,6 +1400,20 @@ static int hostapd_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
@@ -156,7 +160,7 @@
  	{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
  	  "report a scanned DPP URI from a QR Code" },
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 8e56d10..cf7f563 100644
+index 8e56d1082..cf7f56392 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -281,6 +281,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -168,7 +172,7 @@
  
  	/* The third octet of the country string uses an ASCII space character
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 24d540d..421e6a6 100644
+index 24d540dbf..421e6a647 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1146,6 +1146,7 @@ struct hostapd_config {
@@ -180,7 +184,7 @@
  
  	/* VHT enable/disable config from CHAN_SWITCH */
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 99ba973..44f494e 100644
+index 99ba973aa..44f494ed9 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1161,3 +1161,17 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
@@ -202,7 +206,7 @@
 +	return hapd->driver->mu_dump(hapd->drv_priv, mu_onoff);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 6ca693b..8a7d981 100644
+index 6ca693b0b..8a7d98128 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -148,6 +148,8 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
@@ -215,7 +219,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 1b9ce6f..865991e 100644
+index f7c80c73b..65fdc47da 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2517,6 +2517,8 @@ dfs_offload:
@@ -228,7 +232,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 6121857..60bc4cd 100644
+index 6121857dd..60bc4cd4c 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -10,6 +10,8 @@ enum mtk_nl80211_vendor_subcmds {
@@ -261,7 +265,7 @@
  #define ETH_ALEN 6
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index fca2035..542dd45 100644
+index 7d71aa783..a23de244f 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
 @@ -176,6 +176,11 @@ struct hostapd_channel_data {
@@ -276,7 +280,7 @@
  };
  
  #define HE_MAC_CAPAB_0		0
-@@ -5106,6 +5111,14 @@ struct wpa_driver_ops {
+@@ -5109,6 +5114,14 @@ struct wpa_driver_ops {
  				  const s8 edcca_compensation);
  	int (*configure_edcca_threshold)(void *priv, const int *threshold);
  	int (*get_edcca)(void *priv, const u8 mode, u8 *value);
@@ -292,10 +296,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 0a159d5..07c72f5 100644
+index 1a2f52b77..f7f157bf0 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13613,6 +13613,114 @@ fail:
+@@ -13633,6 +13633,114 @@ fail:
  }
  
  
@@ -410,7 +414,7 @@
  #ifdef CONFIG_DPP
  static int nl80211_dpp_listen(void *priv, bool enable)
  {
-@@ -14065,6 +14173,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14085,6 +14193,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.update_connect_params = nl80211_update_connection_params,
  	.send_external_auth_status = nl80211_send_external_auth_status,
  	.set_4addr_mode = nl80211_set_4addr_mode,
@@ -420,7 +424,7 @@
  	.dpp_listen = nl80211_dpp_listen,
  #endif /* CONFIG_DPP */
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 51b3fbe..bd5d284 100644
+index 51b3fbec8..bd5d28404 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -203,6 +203,7 @@ struct wpa_driver_nl80211_data {
@@ -432,10 +436,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 5dadf24..ac66a91 100644
+index 47654f65b..07f6cb133 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1113,6 +1113,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1117,6 +1117,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL:
  					drv->mtk_edcca_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-mtk-hostapd-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
similarity index 90%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-mtk-hostapd-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
index 5967879..c24b78a 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-mtk-hostapd-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
@@ -1,7 +1,7 @@
-From f02858d395fd60a2b5b772ceaccf883455605af4 Mon Sep 17 00:00:00 2001
+From 022b58d6277d12517ada28d8b5581a75e501d779 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 2 Sep 2022 01:03:23 +0800
-Subject: [PATCH 07/38] hostapd: mtk: Add three wire PTA ctrl hostapd vendor
+Subject: [PATCH 07/54] mtk: hostapd: Add three wire PTA ctrl hostapd vendor
  command
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -20,7 +20,7 @@
  11 files changed, 93 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index ec3b41a..d515b6e 100644
+index ec3b41abe..d515b6ea9 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4852,6 +4852,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -35,7 +35,7 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index cf7f563..8b11545 100644
+index cf7f56392..8b1154553 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -298,6 +298,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -47,7 +47,7 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 421e6a6..52df2e0 100644
+index 421e6a647..52df2e0c0 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1198,6 +1198,19 @@ struct hostapd_config {
@@ -71,7 +71,7 @@
  
  enum edcca_mode {
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 44f494e..2f15f99 100644
+index 44f494ed9..2f15f99f4 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1175,3 +1175,14 @@ int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
@@ -90,7 +90,7 @@
 +	return hapd->driver->three_wire_ctrl(hapd->drv_priv, hapd->iconf->three_wire_enable);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 8a7d981..ed3b4cf 100644
+index 8a7d98128..ed3b4cf11 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -150,6 +150,7 @@ int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd,
@@ -102,7 +102,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 865991e..cad5d67 100644
+index 65fdc47da..5487c9489 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2519,6 +2519,8 @@ dfs_offload:
@@ -115,7 +115,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 60bc4cd..99ecbaf 100644
+index 60bc4cd4c..99ecbaf71 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -13,6 +13,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -149,10 +149,10 @@
  	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 542dd45..07af191 100644
+index a23de244f..03d268b2e 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5119,6 +5119,14 @@ struct wpa_driver_ops {
+@@ -5122,6 +5122,14 @@ struct wpa_driver_ops {
  	 */
  	 int (*mu_ctrl)(void *priv, u8 mu_onoff);
  	 int (*mu_dump)(void *priv, u8 *mu_onoff);
@@ -168,10 +168,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 07c72f5..cf1f2d0 100644
+index f7f157bf0..d5c0ea81a 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14026,6 +14026,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
+@@ -14046,6 +14046,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
  	return ret;
  }
  
@@ -210,14 +210,14 @@
  
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
-@@ -14188,4 +14220,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14208,4 +14240,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.configure_edcca_enable = nl80211_configure_edcca_enable,
  	.configure_edcca_threshold = nl80211_configure_edcca_threshold,
  	.get_edcca = nl80211_get_edcca,
 +	.three_wire_ctrl = nl80211_enable_three_wire,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index bd5d284..99af8b0 100644
+index bd5d28404..99af8b075 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -204,6 +204,7 @@ struct wpa_driver_nl80211_data {
@@ -229,10 +229,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index ac66a91..3ff47f3 100644
+index 07f6cb133..47ba17933 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1116,6 +1116,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1120,6 +1120,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_MU_CTRL :
  					drv->mtk_mu_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-mtk-hostapd-Add-hostapd-iBF-control.patch
similarity index 92%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-mtk-hostapd-Add-hostapd-iBF-control.patch
index de3e848..8ff3fe9 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-mtk-hostapd-Add-hostapd-iBF-control.patch
@@ -1,7 +1,7 @@
-From 59a1d486171bd4976b39bcf076d7a5b50237de58 Mon Sep 17 00:00:00 2001
+From 23191149c4b3be30766166cd68db4beb6d57af78 Mon Sep 17 00:00:00 2001
 From: mtk27835 <shurong.wen@mediatek.com>
 Date: Wed, 7 Sep 2022 14:41:51 -0700
-Subject: [PATCH 08/38] hostapd: mtk: Add hostapd iBF control
+Subject: [PATCH 08/54] mtk: hostapd: Add hostapd iBF control
 
 Signed-off-by: mtk27835 <shurong.wen@mediatek.com>
 ---
@@ -21,7 +21,7 @@
  13 files changed, 224 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index d515b6e..f8560a7 100644
+index d515b6ea9..f8560a721 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4856,6 +4856,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -35,10 +35,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c5d92b0..7d7ebe3 100644
+index b10483652..cf7cc3923 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3545,6 +3545,30 @@ hostapd_ctrl_iface_get_mu(struct hostapd_data *hapd, char *buf,
+@@ -3549,6 +3549,30 @@ hostapd_ctrl_iface_get_mu(struct hostapd_data *hapd, char *buf,
  }
  
  
@@ -69,7 +69,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4109,6 +4133,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4113,6 +4137,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  							  reply_size);
  	} else if (os_strncmp(buf, "GET_MU", 6) == 0) {
  		reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
@@ -79,7 +79,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 98892ee..4fa2d32 100644
+index 98892ee9d..4fa2d323d 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1606,6 +1606,13 @@ static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
@@ -106,7 +106,7 @@
  };
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 8b11545..c9b9683 100644
+index 8b1154553..c9b9683bb 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -299,6 +299,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -118,7 +118,7 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 52df2e0..ffbc4fb 100644
+index 52df2e0c0..ffbc4fb4f 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1199,6 +1199,7 @@ struct hostapd_config {
@@ -138,7 +138,7 @@
  int hostapd_mac_comp(const void *a, const void *b);
  struct hostapd_config * hostapd_config_defaults(void);
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 2f15f99..41e76aa 100644
+index 2f15f99f4..41e76aa54 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1186,3 +1186,17 @@ int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd)
@@ -161,7 +161,7 @@
 +}
 \ No newline at end of file
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index ed3b4cf..2958661 100644
+index ed3b4cf11..295866134 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -151,6 +151,8 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value);
@@ -174,7 +174,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index cad5d67..227580e 100644
+index 5487c9489..15bc9f486 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2521,6 +2521,8 @@ dfs_offload:
@@ -187,7 +187,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 99ecbaf..9811f26 100644
+index 99ecbaf71..9811f266e 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -13,7 +13,8 @@ enum mtk_nl80211_vendor_subcmds {
@@ -240,7 +240,7 @@
  #define CSI_MAX_COUNT 256
  #define ETH_ALEN 6
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 07af191..0a99078 100644
+index 03d268b2e..58a681b7a 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
 @@ -181,6 +181,11 @@ struct hostapd_channel_data {
@@ -255,7 +255,7 @@
  };
  
  #define HE_MAC_CAPAB_0		0
-@@ -5127,6 +5132,20 @@ struct wpa_driver_ops {
+@@ -5130,6 +5135,20 @@ struct wpa_driver_ops {
  	 *
  	 */
  	 int (*three_wire_ctrl)(void *priv, u8 three_wire_enable);
@@ -277,10 +277,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index cf1f2d0..a05e047 100644
+index d5c0ea81a..daa05882f 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14059,6 +14059,112 @@ static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
+@@ -14079,6 +14079,112 @@ static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
  	return ret;
  }
  
@@ -393,7 +393,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14221,4 +14327,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14241,4 +14347,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.configure_edcca_threshold = nl80211_configure_edcca_threshold,
  	.get_edcca = nl80211_get_edcca,
  	.three_wire_ctrl = nl80211_enable_three_wire,
@@ -401,7 +401,7 @@
 +	.ibf_dump = nl80211_ibf_dump,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 99af8b0..4e64e7d 100644
+index 99af8b075..4e64e7d31 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -205,6 +205,7 @@ struct wpa_driver_nl80211_data {
@@ -413,10 +413,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 3ff47f3..7ad15ba 100644
+index 47ba17933..5b659f490 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1119,6 +1119,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1123,6 +1123,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL :
  					drv->mtk_3wire_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-mtk-hostapd-Do-not-include-HE-capab-IE-if-associated.patch
similarity index 82%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-mtk-hostapd-Do-not-include-HE-capab-IE-if-associated.patch
index ba1aa44..e8ad881 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-mtk-hostapd-Do-not-include-HE-capab-IE-if-associated.patch
@@ -1,7 +1,7 @@
-From ddca5f55f8f0468f23d4e531b3b40d0ef7d63485 Mon Sep 17 00:00:00 2001
+From 037b1cdac457c03ba44a470a7df38798ba1d5d88 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Thu, 22 Sep 2022 16:08:09 +0800
-Subject: [PATCH 09/38] hostapd: mtk: Do not include HE capab IE if associated
+Subject: [PATCH 09/54] mtk: hostapd: Do not include HE capab IE if associated
  sta's HE capab IE is invalid
 
 ---
@@ -9,7 +9,7 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index db404a6..110ad8c 100644
+index db404a6c7..110ad8c2e 100644
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
 @@ -4863,7 +4863,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0010-mtk-hostapd-Add-DFS-detection-mode.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0010-mtk-hostapd-Add-DFS-detection-mode.patch
index 3049a6b..a0f9de1 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0010-mtk-hostapd-Add-DFS-detection-mode.patch
@@ -1,7 +1,7 @@
-From e825b01701aeb6536321a9bf1bd5b4760a0cdc04 Mon Sep 17 00:00:00 2001
+From 8ee7b5e713067c29aab2f7a4389cc806b545c5d8 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 14:55:49 +0800
-Subject: [PATCH 10/38] hostapd: mtk: Add DFS detection mode
+Subject: [PATCH 10/54] mtk: hostapd: Add DFS detection mode
 
 Add DFS detection mode for testing radar detection rate.
 If DFS detection mode is on, AP will not switch channels when receiving
@@ -17,7 +17,7 @@
  4 files changed, 50 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index f8560a7..50e2993 100644
+index f8560a721..50e299303 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4859,6 +4859,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -32,10 +32,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 7d7ebe3..d8f6663 100644
+index cf7cc3923..327533f80 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3569,6 +3569,26 @@ hostapd_ctrl_iface_get_ibf(struct hostapd_data *hapd, char *buf,
+@@ -3573,6 +3573,26 @@ hostapd_ctrl_iface_get_ibf(struct hostapd_data *hapd, char *buf,
  }
  
  
@@ -62,7 +62,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4135,6 +4155,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4139,6 +4159,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
  	} else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
  		reply_len = hostapd_ctrl_iface_get_ibf(hapd, reply, reply_size);
@@ -73,7 +73,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index ffbc4fb..6576d79 100644
+index ffbc4fb4f..6576d791d 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1200,6 +1200,7 @@ struct hostapd_config {
@@ -104,7 +104,7 @@
  	EDCCA_MODE_FORCE_DISABLE = 0,
  	EDCCA_MODE_AUTO = 1,
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 29d2683..2e138e2 100644
+index 29d268351..2e138e225 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1327,6 +1327,11 @@ hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0011-mtk-hostapd-Add-DFS-offchan-channel-switch.patch
similarity index 94%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0011-mtk-hostapd-Add-DFS-offchan-channel-switch.patch
index 39cb7f2..ae9c59e 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0011-mtk-hostapd-Add-DFS-offchan-channel-switch.patch
@@ -1,7 +1,7 @@
-From 34d1517322d42ea45b6b2a792b9d7f7dd256bef6 Mon Sep 17 00:00:00 2001
+From 60b4911627763adee4fba3107acd2979ff024f10 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 14:56:55 +0800
-Subject: [PATCH 11/38] hostapd: mtk: Add DFS offchan channel switch
+Subject: [PATCH 11/54] mtk: hostapd: Add DFS offchan channel switch
 
 Add DFS background chain channel switch command for testing purpose.
 This feature is implemented via hostapd_cli command.
@@ -16,10 +16,10 @@
  3 files changed, 96 insertions(+), 16 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index d8f6663..2399979 100644
+index 327533f80..84a6127d1 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3589,6 +3589,76 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
+@@ -3593,6 +3593,76 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
  }
  
  
@@ -96,7 +96,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4158,6 +4228,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4162,6 +4232,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
  		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
  								   reply, reply_size);
@@ -106,7 +106,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 2e138e2..23e6527 100644
+index 2e138e225..23e6527b3 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -19,13 +19,6 @@
@@ -156,7 +156,7 @@
  	if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax)
  		return;
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index 606c1b3..c2556d2 100644
+index 606c1b393..c2556d2d9 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -9,6 +9,12 @@
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-mtk-hostapd-Add-amsdu-set-get-ctrl.patch
similarity index 92%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-mtk-hostapd-Add-amsdu-set-get-ctrl.patch
index de63341..f2d0484 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-mtk-hostapd-Add-amsdu-set-get-ctrl.patch
@@ -1,7 +1,7 @@
-From 2c3c314405d088440feccf8fb596849d99cce6f8 Mon Sep 17 00:00:00 2001
+From cfd3d079808b3a7d5585da349c1426351728b442 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 16 Dec 2022 03:57:11 +0800
-Subject: [PATCH 12/38] hostapd: mtk: Add amsdu set get ctrl
+Subject: [PATCH 12/54] mtk: hostapd: Add amsdu set get ctrl
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -20,7 +20,7 @@
  13 files changed, 207 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 50e2993..0b2f3dc 100644
+index 50e299303..0b2f3dc32 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4863,6 +4863,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -40,10 +40,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 2399979..c54cbb9 100644
+index 84a6127d1..57addb22d 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3659,6 +3659,30 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
+@@ -3663,6 +3663,30 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
  }
  
  
@@ -74,7 +74,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4230,6 +4254,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4234,6 +4258,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  								   reply, reply_size);
  	} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
  		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
@@ -84,7 +84,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 4fa2d32..d593730 100644
+index 4fa2d323d..d59373062 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1613,6 +1613,13 @@ static int hostapd_cli_cmd_get_ibf(struct wpa_ctrl *ctrl, int argc,
@@ -111,7 +111,7 @@
  };
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index c9b9683..f519a76 100644
+index c9b9683bb..f519a769b 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -300,6 +300,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -123,7 +123,7 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 6576d79..9f3cea2 100644
+index 6576d791d..9f3cea205 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1201,6 +1201,7 @@ struct hostapd_config {
@@ -135,7 +135,7 @@
  
  enum three_wire_mode {
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 41e76aa..a7226cf 100644
+index 41e76aa54..a7226cfa9 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1199,4 +1199,18 @@ int hostapd_drv_ibf_dump(struct hostapd_data *hapd, u8 *ibf_enable)
@@ -159,7 +159,7 @@
  }
 \ No newline at end of file
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 2958661..88bc430 100644
+index 295866134..88bc430d2 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -153,6 +153,8 @@ int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
@@ -172,7 +172,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 227580e..a166de4 100644
+index 15bc9f486..fcf346d36 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2523,6 +2523,8 @@ dfs_offload:
@@ -185,7 +185,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 9811f26..7b4d7c1 100644
+index 9811f266e..7b4d7c11a 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -170,7 +170,6 @@ enum mtk_vendor_attr_wireless_ctrl {
@@ -220,10 +220,10 @@
  	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 0a99078..38f6e8b 100644
+index 58a681b7a..577c34c07 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5146,6 +5146,15 @@ struct wpa_driver_ops {
+@@ -5149,6 +5149,15 @@ struct wpa_driver_ops {
  	 *
  	 */
  	int (*ibf_dump)(void *priv, u8 *ibf_enable);
@@ -240,10 +240,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index a05e047..808db17 100644
+index daa05882f..c1e3fcb69 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14165,6 +14165,118 @@ fail:
+@@ -14185,6 +14185,118 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -362,7 +362,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14329,4 +14441,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14349,4 +14461,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.three_wire_ctrl = nl80211_enable_three_wire,
  	.ibf_ctrl = nl80211_ibf_enable,
  	.ibf_dump = nl80211_ibf_dump,
@@ -370,7 +370,7 @@
 +	.amsdu_dump = nl80211_dump_amsdu,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 4e64e7d..0100314 100644
+index 4e64e7d31..0100314ba 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -206,6 +206,7 @@ struct wpa_driver_nl80211_data {
@@ -382,10 +382,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 7ad15ba..f14706d 100644
+index 5b659f490..0e70b7321 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1122,6 +1122,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1126,6 +1126,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL:
  					drv->mtk_ibf_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-mtk-hostapd-Add-he_ldpc-configuration.patch
similarity index 90%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-mtk-hostapd-Add-he_ldpc-configuration.patch
index 2182cc1..32ee385 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-mtk-hostapd-Add-he_ldpc-configuration.patch
@@ -1,7 +1,7 @@
-From 29d69687f1ef2150b1c81dc9a778755aa7095f2f Mon Sep 17 00:00:00 2001
+From 6d57a4121c23048f3473991435aa8673b51763ad Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Thu, 12 Jan 2023 15:18:19 +0800
-Subject: [PATCH 13/38] hostapd: mtk: Add he_ldpc configuration
+Subject: [PATCH 13/54] mtk: hostapd: Add he_ldpc configuration
 
 ---
  hostapd/config_file.c        | 2 ++
@@ -13,7 +13,7 @@
  6 files changed, 19 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 0b2f3dc..9e3dbb2 100644
+index 0b2f3dc32..9e3dbb24a 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -3515,6 +3515,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -26,7 +26,7 @@
  		conf->he_op.he_bss_color = atoi(pos) & 0x3f;
  		conf->he_op.he_bss_color_disabled = 0;
 diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
-index bafc923..f16e3b0 100644
+index bafc9232b..f16e3b08d 100644
 --- a/hostapd/hostapd.conf
 +++ b/hostapd/hostapd.conf
 @@ -833,6 +833,11 @@ wmm_ac_vo_acm=0
@@ -42,7 +42,7 @@
  #he_bss_color=1
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index f519a76..223db56 100644
+index f519a769b..223db56eb 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -269,6 +269,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -54,7 +54,7 @@
  		HE_OPERATION_RTS_THRESHOLD_OFFSET;
  	/* Set default basic MCS/NSS set to single stream MCS 0-7 */
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 9f3cea2..d0e27b2 100644
+index 9f3cea205..d0e27b28d 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -959,6 +959,7 @@ struct hostapd_bss_config {
@@ -66,7 +66,7 @@
  	bool he_su_beamformee;
  	bool he_mu_beamformer;
 diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
-index 548a448..9407dd6 100644
+index 548a44821..9407dd6e5 100644
 --- a/src/ap/ieee802_11_he.c
 +++ b/src/ap/ieee802_11_he.c
 @@ -138,6 +138,13 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid,
@@ -84,7 +84,7 @@
  		cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] |=
  			HE_PHYCAP_SU_BEAMFORMER_CAPAB;
 diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
-index e7c3f17..69f1591 100644
+index e7c3f17e1..69f15913e 100644
 --- a/src/common/ieee802_11_defs.h
 +++ b/src/common/ieee802_11_defs.h
 @@ -2358,6 +2358,9 @@ struct ieee80211_spatial_reuse {
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-mtk-hostapd-Add-vendor-command-attribute-for-RTS-BW-.patch
similarity index 80%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-mtk-hostapd-Add-vendor-command-attribute-for-RTS-BW-.patch
index eac9292..cd53d89 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-mtk-hostapd-Add-vendor-command-attribute-for-RTS-BW-.patch
@@ -1,7 +1,7 @@
-From 318e4a89d2f1ab49916820cda2795aa1d9b719b9 Mon Sep 17 00:00:00 2001
+From 45bfb188573dae7bcc4c24fb22311c51c82a22d1 Mon Sep 17 00:00:00 2001
 From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
 Date: Tue, 24 Jan 2023 19:06:44 +0800
-Subject: [PATCH 14/38] hostapd: mtk: Add vendor command attribute for RTS BW
+Subject: [PATCH 14/54] mtk: hostapd: Add vendor command attribute for RTS BW
  signaling.
 
 Signed-off-by: himanshu.goyal <himanshu.goyal@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 1 insertion(+)
 
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 7b4d7c1..ace993b 100644
+index 7b4d7c11a..ace993bc8 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -172,6 +172,7 @@ enum mtk_vendor_attr_wireless_ctrl {
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-mtk-hostapd-6G-band-does-not-require-DFS.patch
similarity index 77%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-mtk-hostapd-6G-band-does-not-require-DFS.patch
index a955f11..653ca37 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-mtk-hostapd-6G-band-does-not-require-DFS.patch
@@ -1,14 +1,14 @@
-From 38302b0ff51f0e666a2f47ef8851d0fe6e03daad Mon Sep 17 00:00:00 2001
+From 808d6d8261761d9cab0cf1500eddd812344bf7bf Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Mon, 13 Feb 2023 11:03:53 +0800
-Subject: [PATCH 15/38] hostapd: mtk: 6G band does not require DFS
+Subject: [PATCH 15/54] mtk: hostapd: 6G band does not require DFS
 
 ---
  src/ap/dfs.c | 1 +
  1 file changed, 1 insertion(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 23e6527..0a8486a 100644
+index 23e6527b3..0a8486a1e 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1516,6 +1516,7 @@ int hostapd_is_dfs_required(struct hostapd_iface *iface)
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-mtk-hostapd-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
similarity index 89%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-mtk-hostapd-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
index 76d6e0b..9e68c12 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-mtk-hostapd-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
@@ -1,7 +1,7 @@
-From f0e980941ebf54811c89881ac1ea21f318751401 Mon Sep 17 00:00:00 2001
+From bae45334df7f087ea31ddd4bc419610636ab45ea Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 11:01:18 +0800
-Subject: [PATCH 16/38] hostapd: mtk: Fix sending wrong VHT operation IE in CSA
+Subject: [PATCH 16/54] mtk: hostapd: Fix sending wrong VHT operation IE in CSA
  while using ZWDFS
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 9 insertions(+), 5 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 0a8486a..cfc3508 100644
+index 0a8486a1e..cfc350879 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1120,6 +1120,14 @@ static int
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-mtk-hostapd-Add-sta-assisted-DFS-state-update-mechan.patch
similarity index 93%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-mtk-hostapd-Add-sta-assisted-DFS-state-update-mechan.patch
index e29ecce..3c36b27 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-mtk-hostapd-Add-sta-assisted-DFS-state-update-mechan.patch
@@ -1,7 +1,7 @@
-From aa33ef52222963f20b152120ad84b6614b8421a1 Mon Sep 17 00:00:00 2001
+From 7782f39aa86e067030ee8277c7942423c6e64389 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 10:51:47 +0800
-Subject: [PATCH 17/38] hostapd: mtk: Add sta-assisted DFS state update
+Subject: [PATCH 17/54] mtk: hostapd: Add sta-assisted DFS state update
  mechanism
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,7 +16,7 @@
  7 files changed, 78 insertions(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index cfc3508..9d002cf 100644
+index cfc350879..9d002cfad 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1513,6 +1513,26 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
@@ -47,7 +47,7 @@
  {
  	int n_chans, n_chans1, start_chan_idx, start_chan_idx1, res;
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index c2556d2..25ba29c 100644
+index c2556d2d9..25ba29ca1 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -30,6 +30,9 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
@@ -61,7 +61,7 @@
  int hostapd_is_dfs_chan_available(struct hostapd_iface *iface);
  int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index f6093c1..e7f1f19 100644
+index f6093c11c..e7f1f19ce 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
 @@ -2086,6 +2086,24 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
@@ -107,7 +107,7 @@
  		/* channel list changed (regulatory?), update channel list */
  		/* TODO: check this. hostapd_get_hw_features() initializes
 diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
-index 416e0d6..62f042e 100644
+index 416e0d6a8..62f042e05 100644
 --- a/src/common/wpa_ctrl.h
 +++ b/src/common/wpa_ctrl.h
 @@ -374,6 +374,7 @@ extern "C" {
@@ -119,10 +119,10 @@
  #define AP_CSA_FINISHED "AP-CSA-FINISHED "
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 38f6e8b..0469694 100644
+index 577c34c07..24ab656fa 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5782,6 +5782,20 @@ enum wpa_event_type {
+@@ -5785,6 +5785,20 @@ enum wpa_event_type {
  	 * EVENT_LINK_RECONFIG - Notification that AP links removed
  	 */
  	EVENT_LINK_RECONFIG,
@@ -144,7 +144,7 @@
  
  
 diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
-index 701c32e..63d4401 100644
+index 701c32e7b..63d44017c 100644
 --- a/src/drivers/driver_nl80211_event.c
 +++ b/src/drivers/driver_nl80211_event.c
 @@ -2514,6 +2514,12 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
@@ -161,7 +161,7 @@
  		wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
  			   "received", event_type);
 diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index 82860ae..225864b 100644
+index 82860ae32..225864b94 100644
 --- a/src/drivers/nl80211_copy.h
 +++ b/src/drivers/nl80211_copy.h
 @@ -6643,6 +6643,10 @@ enum nl80211_smps_mode {
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-mtk-hostapd-Mark-DFS-channel-as-available-for-CSA.patch
similarity index 90%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-mtk-hostapd-Mark-DFS-channel-as-available-for-CSA.patch
index c2296fb..ef35c2d 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-mtk-hostapd-Mark-DFS-channel-as-available-for-CSA.patch
@@ -1,7 +1,7 @@
-From f3a98bc033de56fee900d0da3a33775165b714ad Mon Sep 17 00:00:00 2001
+From 8a52855a8e3425d62b7ffba05ccf1ddd08223f78 Mon Sep 17 00:00:00 2001
 From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
 Date: Fri, 3 Mar 2023 12:45:42 +0800
-Subject: [PATCH 18/38] hostapd: mtk: Mark DFS channel as available for CSA.
+Subject: [PATCH 18/54] mtk: hostapd: Mark DFS channel as available for CSA.
 
 ---
  hostapd/ctrl_iface.c   | 10 ++++++++++
@@ -10,7 +10,7 @@
  3 files changed, 12 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c54cbb9..aab5c0a 100644
+index 57addb22d..ba2137969 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -2751,6 +2751,16 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
@@ -31,7 +31,7 @@
  		dfs_range += hostapd_is_dfs_overlap(
  			iface, bandwidth, settings.freq_params.center_freq1);
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index d593730..0a374be 100644
+index d59373062..0a374be8e 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1715,7 +1715,7 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
@@ -44,7 +44,7 @@
  	{ "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL,
  	  "<addr> <url>\n"
 diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
-index 0e173f1..7bdefb4 100644
+index 0e173f174..7bdefb4cf 100644
 --- a/src/ap/ctrl_iface_ap.c
 +++ b/src/ap/ctrl_iface_ap.c
 @@ -1014,6 +1014,7 @@ int hostapd_parse_csa_settings(const char *pos,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0019-hostapd-mtk-Add-available-color-bitmap.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0019-mtk-hostapd-Add-available-color-bitmap.patch
similarity index 94%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0019-hostapd-mtk-Add-available-color-bitmap.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0019-mtk-hostapd-Add-available-color-bitmap.patch
index d4ce7cc..4f2c43b 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0019-hostapd-mtk-Add-available-color-bitmap.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0019-mtk-hostapd-Add-available-color-bitmap.patch
@@ -1,7 +1,7 @@
-From d77b2e1d3821e51f557f1292a0ccaa0a211ea11f Mon Sep 17 00:00:00 2001
+From 41e104c896bfa30a027924302a39401245e02767 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Thu, 26 Jan 2023 09:16:00 +0800
-Subject: [PATCH 19/38] hostapd: mtk: Add available color bitmap
+Subject: [PATCH 19/54] mtk: hostapd: Add available color bitmap
 
 Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 ---
@@ -17,10 +17,10 @@
  9 files changed, 324 insertions(+), 2 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index aab5c0a..a6be199 100644
+index ba2137969..e45e574be 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3692,6 +3692,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
+@@ -3696,6 +3696,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
  	return ret;
  }
  
@@ -97,7 +97,7 @@
  
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
-@@ -4266,6 +4336,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4270,6 +4340,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
  	} else if (os_strncmp(buf, "GET_AMSDU", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
@@ -109,7 +109,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 0a374be..e9e156d 100644
+index 0a374be8e..e9e156d28 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1598,6 +1598,20 @@ static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,
@@ -145,7 +145,7 @@
  	{ "driver", hostapd_cli_cmd_driver, NULL,
  	  "<driver sub command> [<hex formatted data>] = send driver command data" },
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index a7226cf..9615ca8 100644
+index a7226cfa9..9615ca8ce 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1213,4 +1213,12 @@ int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu)
@@ -164,7 +164,7 @@
 +	return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 88bc430..ecaa71f 100644
+index 88bc430d2..ecaa71f99 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -155,6 +155,8 @@ int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
@@ -177,7 +177,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index ace993b..e27fe69 100644
+index ace993bc8..e27fe69b3 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -15,6 +15,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -206,10 +206,10 @@
  #define CSI_MAX_COUNT 256
  #define ETH_ALEN 6
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 0469694..130143e 100644
+index 24ab656fa..869b0442f 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5155,6 +5155,14 @@ struct wpa_driver_ops {
+@@ -5158,6 +5158,14 @@ struct wpa_driver_ops {
  	 */
  	int (*amsdu_ctrl)(void *priv, u8 amsdu);
  	int (*amsdu_dump)(void *priv, u8 *amsdu);
@@ -225,10 +225,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 808db17..ee0912f 100644
+index c1e3fcb69..7b5a50ea6 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -12849,7 +12849,6 @@ static void nl80211_parse_btm_candidate_info(struct candidate_list *candidate,
+@@ -12869,7 +12869,6 @@ static void nl80211_parse_btm_candidate_info(struct candidate_list *candidate,
  		   num, MAC2STR(candidate->bssid), buf);
  }
  
@@ -236,7 +236,7 @@
  static int
  nl80211_get_bss_transition_status_handler(struct nl_msg *msg, void *arg)
  {
-@@ -14277,6 +14276,203 @@ fail:
+@@ -14297,6 +14296,203 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -440,14 +440,14 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14443,4 +14639,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14463,4 +14659,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.ibf_dump = nl80211_ibf_dump,
  	.amsdu_ctrl = nl80211_enable_amsdu,
  	.amsdu_dump = nl80211_dump_amsdu,
 +	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 0100314..fd1e57c 100644
+index 0100314ba..fd1e57cc2 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -207,6 +207,7 @@ struct wpa_driver_nl80211_data {
@@ -459,10 +459,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index f14706d..4f8e920 100644
+index 0e70b7321..3e8eb8cb1 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1125,6 +1125,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1129,6 +1129,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL:
  					drv->mtk_wireless_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-mtk-hostapd-Fix-ZWDFS-issue-in-BW-160.patch
similarity index 97%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-mtk-hostapd-Fix-ZWDFS-issue-in-BW-160.patch
index 84087de..3e30ba2 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-mtk-hostapd-Fix-ZWDFS-issue-in-BW-160.patch
@@ -1,7 +1,7 @@
-From 181312213a4e8a04be652734ae3ffad12c45b8ae Mon Sep 17 00:00:00 2001
+From 0e01d6aa229b84b92c9462f7101314db62857b86 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Mar 2023 16:08:30 +0800
-Subject: [PATCH 20/38] hostapd: mtk: Fix ZWDFS issue in BW 160
+Subject: [PATCH 20/54] mtk: hostapd: Fix ZWDFS issue in BW 160
 
 When background radar is enabled and bandwidth is set to 160, AP will
 fail to startup due to the lack of non-DFS channel.
@@ -14,7 +14,7 @@
  1 file changed, 79 insertions(+), 19 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 9d002cf..3b1df6d 100644
+index 9d002cfad..3b1df6dc6 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -69,15 +69,22 @@ static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-mtk-hostapd-Add-vendor-for-CAPI-certification-comman.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-mtk-hostapd-Add-vendor-for-CAPI-certification-comman.patch
index c6c039e..804aa16 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-mtk-hostapd-Add-vendor-for-CAPI-certification-comman.patch
@@ -1,22 +1,22 @@
-From 3e51ee9efe44904b7b41402fd40a25d5e34614f3 Mon Sep 17 00:00:00 2001
+From 6dee226e8db428c4434115b4c792f7ffd8a759dd Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 17 Mar 2023 16:17:14 +0800
-Subject: [PATCH 21/38] hostapd: mtk: Add vendor for CAPI certification
+Subject: [PATCH 21/54] mtk: hostapd: Add vendor for CAPI certification
  commands
 
 ---
- hostapd/ctrl_iface.c              | 97 +++++++++++++++++++++++++++++++
+ hostapd/ctrl_iface.c              | 99 +++++++++++++++++++++++++++++++
  src/ap/ap_drv_ops.c               | 21 +++++++
  src/ap/ap_drv_ops.h               |  3 +
  src/common/mtk_vendor.h           | 33 +----------
  src/drivers/driver.h              | 22 +++++++
- src/drivers/driver_nl80211.c      | 55 ++++++++++++++++++
+ src/drivers/driver_nl80211.c      | 55 +++++++++++++++++
  src/drivers/driver_nl80211.h      |  1 +
  src/drivers/driver_nl80211_capa.c |  3 +
- 8 files changed, 204 insertions(+), 31 deletions(-)
+ 8 files changed, 206 insertions(+), 31 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index a6be199..92c94c0 100644
+index e45e574be..05606eb43 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -69,6 +69,7 @@
@@ -27,7 +27,7 @@
  
  #define HOSTAPD_CLI_DUP_VALUE_MAX_LEN 256
  
-@@ -3762,6 +3763,98 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
+@@ -3766,6 +3767,100 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
  	return pos - buf;
  }
  
@@ -63,6 +63,8 @@
 +		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT ;
 +	else if (os_strncmp(config, "amsdu", 5) == 0)
 +		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU;
++	else if (os_strncmp(config, "rts_sigta", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA;
 +	else {
 +		wpa_printf(MSG_ERROR,
 +			"Unsupported parameter %s for ap_wireless", config);
@@ -126,7 +128,7 @@
  
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
-@@ -4340,6 +4433,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4344,6 +4439,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_get_bss_color(hapd, reply, reply_size);
  	} else if (os_strncmp(buf, "AVAL_COLOR_BMP", 14) == 0) {
  		reply_len = hostapd_ctrl_iface_get_aval_color_bmp(hapd, reply, reply_size);
@@ -138,7 +140,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 9615ca8..11444c7 100644
+index 9615ca8ce..11444c7eb 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1222,3 +1222,24 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
@@ -167,7 +169,7 @@
 +	return hapd->driver->ap_trigtype(hapd->drv_priv, enable, type);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index ecaa71f..32e6fc1 100644
+index ecaa71f99..32e6fc151 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -157,6 +157,9 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
@@ -181,7 +183,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index e27fe69..0b23c76 100644
+index e27fe69b3..0b23c76ad 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -50,17 +50,6 @@ enum mtk_vendor_attr_edcca_dump {
@@ -260,10 +262,10 @@
  	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 130143e..91aa9b1 100644
+index 869b0442f..2ef1a3fcd 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5163,6 +5163,28 @@ struct wpa_driver_ops {
+@@ -5166,6 +5166,28 @@ struct wpa_driver_ops {
  	 *
  	 */
  	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
@@ -293,12 +295,12 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index ee0912f..592435c 100644
+index 7b5a50ea6..3ee3ec1eb 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -76,6 +76,58 @@ enum nlmsgerr_attrs {
- #endif /* ANDROID */
- 
+@@ -86,6 +86,58 @@ static void handle_nl_debug_hook(struct nl_msg *msg, int tx)
+ 	wpa_netlink_hook(tx, nlh, nlh->nlmsg_len);
+ }
  
 +static struct nla_policy
 +ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
@@ -355,7 +357,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14640,4 +14692,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14660,4 +14712,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.amsdu_ctrl = nl80211_enable_amsdu,
  	.amsdu_dump = nl80211_dump_amsdu,
  	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
@@ -364,7 +366,7 @@
 +	.ap_trigtype = nl80211_ap_trigtype,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index fd1e57c..fc5217d 100644
+index fd1e57cc2..fc5217d61 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -208,6 +208,7 @@ struct wpa_driver_nl80211_data {
@@ -376,10 +378,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 4f8e920..c1cf5b5 100644
+index 3e8eb8cb1..16306a121 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1128,6 +1128,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1132,6 +1132,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
  					drv->mtk_bss_color_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0022-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0022-mtk-hostapd-Air-Monitor-support-in-hostapd-by-vendor.patch
similarity index 94%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0022-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0022-mtk-hostapd-Air-Monitor-support-in-hostapd-by-vendor.patch
index 7808d50..e2d1e7f 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0022-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0022-mtk-hostapd-Air-Monitor-support-in-hostapd-by-vendor.patch
@@ -1,7 +1,7 @@
-From 8fe238bed8756a0015567c41b9c31577755d1015 Mon Sep 17 00:00:00 2001
+From 8a578ff51002e783b4d9a64d24402c78529b244b Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 12 May 2023 05:18:48 +0800
-Subject: [PATCH 22/38] hostapd: mtk: Air Monitor support in hostapd by vendor
+Subject: [PATCH 22/54] mtk: hostapd: Air Monitor support in hostapd by vendor
 
 Signed-off-by: mtk23888 <dipanshu.mittal@mediatek.com>
 ---
@@ -17,10 +17,10 @@
  9 files changed, 352 insertions(+)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 92c94c0..1bb64ea 100644
+index 05606eb43..ab2768e76 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3803,6 +3803,44 @@ hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
+@@ -3809,6 +3809,44 @@ hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
  
  	if (hostapd_drv_ap_wireless(hapd, (u8) sub_cmd, atoi(value)) != 0)
  		return -1;
@@ -65,7 +65,7 @@
  
  	return os_snprintf(buf, buflen, "OK\n");
  }
-@@ -3856,6 +3894,75 @@ exit:
+@@ -3862,6 +3900,75 @@ exit:
  	return os_snprintf(buf, buflen, "OK\n");
  }
  
@@ -141,7 +141,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4437,6 +4544,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4443,6 +4550,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_ap_wireless(hapd, buf + 12, reply, reply_size);
  	} else if (os_strncmp(buf, "ap_rfeatures ", 13) == 0) {
  		reply_len = hostapd_ctrl_iface_ap_rfeatures(hapd, buf + 13, reply, reply_size);
@@ -155,7 +155,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index e9e156d..6d763f3 100644
+index e9e156d28..6d763f327 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1633,6 +1633,17 @@ static int hostapd_cli_cmd_get_amsdu(struct wpa_ctrl *ctrl, int argc,
@@ -188,7 +188,7 @@
  };
  
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 11444c7..b90dd57 100644
+index 11444c7eb..b90dd5722 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1243,3 +1243,17 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type)
@@ -210,7 +210,7 @@
 +	return hapd->driver->amnt_dump(hapd->drv_priv, amnt_idx, amnt_dump_buf);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 32e6fc1..8a97e0f 100644
+index 32e6fc151..8a97e0fea 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -161,6 +161,9 @@ int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int val
@@ -224,7 +224,7 @@
  
  int hostapd_drv_wnm_oper(struct hostapd_data *hapd,
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 0b23c76..dd1ca21 100644
+index 0b23c76ad..dd1ca2164 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -258,10 +258,18 @@ struct csi_data {
@@ -247,10 +247,10 @@
 +
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 91aa9b1..8733bb5 100644
+index 2ef1a3fcd..24c9b96df 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5185,6 +5185,22 @@ struct wpa_driver_ops {
+@@ -5188,6 +5188,22 @@ struct wpa_driver_ops {
  	* @type: trigger type
  	*/
  	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
@@ -274,10 +274,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 592435c..c55d034 100644
+index 3ee3ec1eb..3a1c32a6d 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -128,6 +128,19 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
+@@ -138,6 +138,19 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
  	[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
  };
  
@@ -297,7 +297,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14525,6 +14538,171 @@ fail:
+@@ -14545,6 +14558,171 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -469,7 +469,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14695,4 +14873,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14715,4 +14893,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.ap_wireless = nl80211_ap_wireless,
  	.ap_rfeatures = nl80211_ap_rfeatures,
  	.ap_trigtype = nl80211_ap_trigtype,
@@ -477,7 +477,7 @@
 +	.amnt_dump = nl80211_amnt_dump,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index fc5217d..0d85adf 100644
+index fc5217d61..0d85adfee 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -209,6 +209,7 @@ struct wpa_driver_nl80211_data {
@@ -489,10 +489,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index c1cf5b5..8c8b84e 100644
+index 16306a121..4bd15f348 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1127,6 +1127,8 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1131,6 +1131,8 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  					break;
  				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
  					drv->mtk_bss_color_vendor_cmd_avail = 1;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0023-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0023-mtk-hostapd-Fix-setting-wrong-seg0-index-for-5G-cent.patch
similarity index 84%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0023-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0023-mtk-hostapd-Fix-setting-wrong-seg0-index-for-5G-cent.patch
index 06ceae8..84be9e0 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0023-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0023-mtk-hostapd-Fix-setting-wrong-seg0-index-for-5G-cent.patch
@@ -1,7 +1,7 @@
-From be727db37e753f0041b2789af3ecc1eff8c0f5db Mon Sep 17 00:00:00 2001
+From da108d74412d83264355fe453a8d2ffc6f99fa86 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 12 May 2023 05:23:00 +0800
-Subject: [PATCH 23/38] hostapd: mtk: Fix setting wrong seg0 index for 5G
+Subject: [PATCH 23/54] mtk: hostapd: Fix setting wrong seg0 index for 5G
  center chan 159 BW40
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index d0e27b2..f03a957 100644
+index d0e27b28d..f03a957b7 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1308,7 +1308,8 @@ hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-muru-user-number-debug-command.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-mtk-hostapd-Add-muru-user-number-debug-command.patch
similarity index 92%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-muru-user-number-debug-command.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-mtk-hostapd-Add-muru-user-number-debug-command.patch
index 68d2e5b..d1c6e2c 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-muru-user-number-debug-command.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-mtk-hostapd-Add-muru-user-number-debug-command.patch
@@ -1,7 +1,7 @@
-From 5644beb4dc1a11a236d909d4a8f8ad4aa86c6c34 Mon Sep 17 00:00:00 2001
+From 906bc021d4e4ddd62edc985dd37d7ad61d39fdb7 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 12 May 2023 05:24:19 +0800
-Subject: [PATCH 24/38] hostapd: mtk: Add muru user number debug command
+Subject: [PATCH 24/54] mtk: hostapd: Add muru user number debug command
 
 ---
  hostapd/ctrl_iface.c         | 13 ++++++++++++-
@@ -14,7 +14,7 @@
  7 files changed, 55 insertions(+), 15 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 1bb64ea..f36c138 100644
+index ab2768e76..4515583cf 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -3398,6 +3398,8 @@ hostapd_ctrl_iface_set_edcca(struct hostapd_data *hapd, char *cmd,
@@ -58,7 +58,7 @@
  	} else {
  		return -1;
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index b90dd57..0aec9e9 100644
+index b90dd5722..0aec9e925 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1162,11 +1162,11 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
@@ -76,7 +76,7 @@
  
  int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 8a97e0f..464efba 100644
+index 8a97e0fea..464efbae1 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -148,7 +148,7 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
@@ -89,7 +89,7 @@
  int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
  int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index a166de4..28482c6 100644
+index fcf346d36..2d7fb6d39 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -57,6 +57,7 @@
@@ -110,7 +110,7 @@
  	if (hostapd_drv_three_wire_ctrl(hapd) < 0)
  		goto fail;
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index dd1ca21..99371bf 100644
+index dd1ca2164..99371bf73 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -199,6 +199,8 @@ enum mtk_vendor_attr_mu_ctrl {
@@ -133,10 +133,10 @@
 +};
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 8733bb5..a29b6ff 100644
+index 24c9b96df..83d347338 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5118,11 +5118,11 @@ struct wpa_driver_ops {
+@@ -5121,11 +5121,11 @@ struct wpa_driver_ops {
  	int (*get_edcca)(void *priv, const u8 mode, u8 *value);
  
  	/**
@@ -151,10 +151,10 @@
  
  	/**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index c55d034..fce3ec9 100644
+index 3a1c32a6d..8226bebc4 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13678,13 +13678,13 @@ fail:
+@@ -13698,13 +13698,13 @@ fail:
  
  
  #ifdef CONFIG_IEEE80211AX
@@ -170,7 +170,7 @@
  
  	if (!drv->mtk_mu_vendor_cmd_avail) {
  		wpa_printf(MSG_INFO,
-@@ -13695,17 +13695,38 @@ static int nl80211_mu_onoff(void *priv, u8 mu_onoff)
+@@ -13715,17 +13715,38 @@ static int nl80211_mu_onoff(void *priv, u8 mu_onoff)
  	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
  		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
  		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_MU_CTRL) ||
@@ -214,7 +214,7 @@
  }
  
  
-@@ -14849,7 +14870,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14869,7 +14890,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.update_connect_params = nl80211_update_connection_params,
  	.send_external_auth_status = nl80211_send_external_auth_status,
  	.set_4addr_mode = nl80211_set_4addr_mode,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0025-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0025-mtk-hostapd-add-connac3-PHY-MURU-manual-mode-config-.patch
similarity index 96%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0025-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0025-mtk-hostapd-add-connac3-PHY-MURU-manual-mode-config-.patch
index 2a2a578..db8ae73 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0025-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0025-mtk-hostapd-add-connac3-PHY-MURU-manual-mode-config-.patch
@@ -1,7 +1,7 @@
-From 033f4f509e60c698d9754057e194f4760af39845 Mon Sep 17 00:00:00 2001
+From 738370924d0153163300f44c87a68e19a5220272 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Sat, 3 Jun 2023 17:12:15 +0800
-Subject: [PATCH 25/38] hostapd: mtk: add connac3 PHY MURU manual mode config
+Subject: [PATCH 25/54] mtk: hostapd: add connac3 PHY MURU manual mode config
  support
 
 This commit supports read the following two formats to set MU/RU manual
@@ -47,7 +47,7 @@
  8 files changed, 390 insertions(+), 43 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index f36c138..c288352 100644
+index 4515583cf..ae61cf625 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -3500,22 +3500,61 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
@@ -301,7 +301,7 @@
  }
  
  
-@@ -4534,8 +4716,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4540,8 +4722,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
  							  reply_size);
  	} else if (os_strncmp(buf, "SET_MU ", 7) == 0) {
@@ -311,7 +311,7 @@
  	} else if (os_strncmp(buf, "GET_MU", 6) == 0) {
  		reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
  	} else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
-@@ -4561,6 +4742,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4567,6 +4748,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
  							reply, reply_size);
@@ -327,7 +327,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index f03a957..7c0d12a 100644
+index f03a957b7..7c0d12a3b 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1203,6 +1203,7 @@ struct hostapd_config {
@@ -339,7 +339,7 @@
  
  enum three_wire_mode {
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 0aec9e9..721bfa0 100644
+index 0aec9e925..721bfa053 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1162,11 +1162,11 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
@@ -357,7 +357,7 @@
  
  int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 464efba..1e7ae7a 100644
+index 464efbae1..1e7ae7a8d 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -148,7 +148,7 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
@@ -370,7 +370,7 @@
  int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
  int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 28482c6..3e184b5 100644
+index 2d7fb6d39..a28466405 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2518,7 +2518,7 @@ dfs_offload:
@@ -383,7 +383,7 @@
  	if (hostapd_drv_three_wire_ctrl(hapd) < 0)
  		goto fail;
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 99371bf..e140de6 100644
+index 99371bf73..e140de60b 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -199,8 +199,11 @@ enum mtk_vendor_attr_mu_ctrl {
@@ -567,10 +567,10 @@
 +
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index a29b6ff..ebc1d27 100644
+index 83d347338..8da93e025 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5122,7 +5122,7 @@ struct wpa_driver_ops {
+@@ -5125,7 +5125,7 @@ struct wpa_driver_ops {
  	 * @priv: Private driver interface data
  	 *
  	 */
@@ -580,10 +580,10 @@
  
  	/**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index fce3ec9..25e5910 100644
+index 8226bebc4..b3897e61d 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13678,12 +13678,13 @@ fail:
+@@ -13698,12 +13698,13 @@ fail:
  
  
  #ifdef CONFIG_IEEE80211AX
@@ -598,7 +598,7 @@
  	int ret = -ENOBUFS;
  
  	if (!drv->mtk_mu_vendor_cmd_avail) {
-@@ -13700,17 +13701,16 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
+@@ -13720,17 +13721,16 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
  
  	switch (mode) {
  	case MU_CTRL_ONOFF:
@@ -623,7 +623,7 @@
  		ret = -EINVAL;
  		goto fail;
  	}
-@@ -13718,9 +13718,8 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
+@@ -13738,9 +13738,8 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
  	nla_nest_end(msg, data);
  
  	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-mtk-hostapd-Add-HE-capabilities-check.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-mtk-hostapd-Add-HE-capabilities-check.patch
index cc30d42..3801eb3 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-mtk-hostapd-Add-HE-capabilities-check.patch
@@ -1,7 +1,7 @@
-From fac968ec3565072058dc92aa2f12e0c145a963e2 Mon Sep 17 00:00:00 2001
+From 1468c2bb212faf091cb4a0c0ba1394722eb2c94e Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Fri, 9 Jun 2023 09:03:05 +0800
-Subject: [PATCH 26/38] hostapd: mtk: Add HE capabilities check
+Subject: [PATCH 26/54] mtk: hostapd: Add HE capabilities check
 
 Add HE capabilities check.
 Since "HE capabilities" check has been removed by driver,
@@ -11,7 +11,7 @@
  1 file changed, 26 insertions(+)
 
 diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
-index 9d22725..9a36bcb 100644
+index 9d2272522..9a36bcb10 100644
 --- a/src/ap/hw_features.c
 +++ b/src/ap/hw_features.c
 @@ -709,6 +709,32 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-mtk-hostapd-Fix-background-channel-overlapping-opera.patch
similarity index 92%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-mtk-hostapd-Fix-background-channel-overlapping-opera.patch
index 0ba1a38..6a98b5d 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-mtk-hostapd-Fix-background-channel-overlapping-opera.patch
@@ -1,7 +1,7 @@
-From c1687a93fb5b8d72f7d68ea761a1fbaf80bf1de4 Mon Sep 17 00:00:00 2001
+From 163efaffce1344a6c2611a2a75d863eb88b17137 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 10:44:15 +0800
-Subject: [PATCH 27/38] hostapd: mtk: Fix background channel overlapping
+Subject: [PATCH 27/54] mtk: hostapd: Fix background channel overlapping
  operating channel issue
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 18 insertions(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 3b1df6d..6f76354 100644
+index 3b1df6dc6..6f7635436 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -812,6 +812,20 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0028-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0028-mtk-hostapd-Fix-hostapd_dfs_start_cac-log.patch
similarity index 86%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0028-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0028-mtk-hostapd-Fix-hostapd_dfs_start_cac-log.patch
index 57395ca..84ca877 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0028-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0028-mtk-hostapd-Fix-hostapd_dfs_start_cac-log.patch
@@ -1,7 +1,7 @@
-From 57fd7fc979251fd178175c506e64a724433c8d6d Mon Sep 17 00:00:00 2001
+From fdbb7f5123ea8f3c5c568b4f5b311e33aa396e50 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 10:47:20 +0800
-Subject: [PATCH 28/38] hostapd: mtk: Fix hostapd_dfs_start_cac log
+Subject: [PATCH 28/54] mtk: hostapd: Fix hostapd_dfs_start_cac log
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -9,7 +9,7 @@
  1 file changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 6f76354..95119a3 100644
+index 6f7635436..95119a391 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1655,9 +1655,11 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-mtk-hostapd-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
similarity index 90%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
copy to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-mtk-hostapd-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
index c247137..57b8060 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-mtk-hostapd-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
@@ -1,7 +1,7 @@
-From 31d7b7fe98e3d5d0e2769bd7ea22e529a7f1295d Mon Sep 17 00:00:00 2001
+From a08f87c88e8abd539dc75b7fcb15fef786d5a61d Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Thu, 13 Jul 2023 13:14:26 +0800
-Subject: [PATCH 29/38] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
+Subject: [PATCH 29/54] mtk: hostapd: Check the bridge after ioctl SIOCBRADDIF
  failed
 
 If ioctl returns EBUSY on command SIOCBRADDIF, the interface might
@@ -17,7 +17,7 @@
  1 file changed, 14 insertions(+), 2 deletions(-)
 
 diff --git a/src/drivers/linux_ioctl.c b/src/drivers/linux_ioctl.c
-index 7edb9df..b8c1af2 100644
+index 7edb9df2e..b8c1af2e3 100644
 --- a/src/drivers/linux_ioctl.c
 +++ b/src/drivers/linux_ioctl.c
 @@ -150,7 +150,8 @@ int linux_br_del(int sock, const char *brname)
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-mtk-hostapd-Update-parameter_set_count-in-MU-EDCA-IE.patch
similarity index 83%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-mtk-hostapd-Update-parameter_set_count-in-MU-EDCA-IE.patch
index 50e4e63..28761c5 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-mtk-hostapd-Update-parameter_set_count-in-MU-EDCA-IE.patch
@@ -1,7 +1,7 @@
-From 65f2475fbf84a7b71e5dcba2b8f7ae77eee4f36d Mon Sep 17 00:00:00 2001
+From 8e8590fe62c5b1c9daceb7588798a96b95df6039 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Fri, 14 Jul 2023 17:19:13 +0800
-Subject: [PATCH 30/38] hostapd: mtk: Update parameter_set_count in MU EDCA IE
+Subject: [PATCH 30/54] mtk: hostapd: Update parameter_set_count in MU EDCA IE
 
 without this patch, MU EDCA Parameter update count not equal to
 WMM Parameter set count.
@@ -10,7 +10,7 @@
  1 file changed, 3 insertions(+)
 
 diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
-index 9407dd6..353e815 100644
+index 9407dd6e5..353e8156c 100644
 --- a/src/ap/ieee802_11_he.c
 +++ b/src/ap/ieee802_11_he.c
 @@ -316,6 +316,9 @@ u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid)
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-mtk-hostapd-add-extension-IE-list-for-non-inherit-IE.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-mtk-hostapd-add-extension-IE-list-for-non-inherit-IE.patch
index 2abbb0b..0ad3c2d 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-mtk-hostapd-add-extension-IE-list-for-non-inherit-IE.patch
@@ -1,7 +1,7 @@
-From 0b9d85b0e28ab0425d0c6742ce581efcfcad0ed6 Mon Sep 17 00:00:00 2001
+From be61f9b1bd2f3c7bcd935968d8709565f6b231b5 Mon Sep 17 00:00:00 2001
 From: mtk20656 <chank.chen@mediatek.com>
 Date: Mon, 24 Jul 2023 11:30:27 +0800
-Subject: [PATCH 31/38] hostapd: mtk: add extension IE list for non-inherit IE
+Subject: [PATCH 31/54] mtk: hostapd: add extension IE list for non-inherit IE
  in mbssid
 
 Certain clients do not scan all non tx profiles due to absence of
@@ -19,7 +19,7 @@
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
 old mode 100644
 new mode 100755
-index 110ad8c..e05a06b
+index 110ad8c2e..e05a06b09
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
 @@ -7659,7 +7659,7 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-mtk-hostapd-Fix-rnr-ie-length-when-no-need-to-report.patch
similarity index 84%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-mtk-hostapd-Fix-rnr-ie-length-when-no-need-to-report.patch
index 52c74f9..15c97a8 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-mtk-hostapd-Fix-rnr-ie-length-when-no-need-to-report.patch
@@ -1,7 +1,7 @@
-From e9f856156f861845c160538d2d5907bf338fa489 Mon Sep 17 00:00:00 2001
+From fea4788692076f9c0701ecec68a85198a70d05c0 Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Mon, 7 Aug 2023 15:27:27 +0800
-Subject: [PATCH 32/38] hostapd: mtk: Fix rnr ie length when no need to report
+Subject: [PATCH 32/54] mtk: hostapd: Fix rnr ie length when no need to report
  bss
 
 Fix rnr ie length when no need to report bss. If we don't have content in
@@ -13,7 +13,7 @@
  1 file changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index e05a06b..7b6aabb 100755
+index e05a06b09..7b6aabbff 100755
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
 @@ -7511,8 +7511,10 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-mtk-hostapd-add-back-ht-vht-cap-missing-field-before.patch
similarity index 87%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-mtk-hostapd-add-back-ht-vht-cap-missing-field-before.patch
index 47e2970..ebc4408 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-mtk-hostapd-add-back-ht-vht-cap-missing-field-before.patch
@@ -1,7 +1,7 @@
-From 5b750f3f78cec3b64ebb9bb3b74def424c7d57fd Mon Sep 17 00:00:00 2001
+From 765215ac465b90e20c52dd48d51859d849834c80 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Tue, 8 Aug 2023 19:21:41 +0800
-Subject: [PATCH 33/38] hostapd: mtk: add back ht vht cap missing field before
+Subject: [PATCH 33/54] mtk: hostapd: add back ht vht cap missing field before
  dfs channel fallback
 
 hostapd_event_ch_switch would set / clear ht_capab and vht_capab, based
@@ -22,10 +22,10 @@
  1 file changed, 7 insertions(+)
 
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 3e184b5..b8ae8de 100644
+index a28466405..ec7677f6a 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
-@@ -4111,6 +4111,13 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+@@ -4112,6 +4112,13 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
  		break;
  	}
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-mtk-hostapd-update-op_class-when-AP-channel-switchin.patch
similarity index 88%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-mtk-hostapd-update-op_class-when-AP-channel-switchin.patch
index 5412153..6afdc0b 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-mtk-hostapd-update-op_class-when-AP-channel-switchin.patch
@@ -1,7 +1,7 @@
-From d46e85faec291f813d6b5578122cd267421e84fa Mon Sep 17 00:00:00 2001
+From 9a82dbf6c16899eeb6b98178cc6e341f164acfa6 Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Wed, 23 Aug 2023 17:44:50 +0800
-Subject: [PATCH 34/38] hostapd: mtk: update op_class when AP channel switching
+Subject: [PATCH 34/54] mtk: hostapd: update op_class when AP channel switching
 
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
 ---
@@ -9,7 +9,7 @@
  1 file changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index e7f1f19..f749b33 100644
+index e7f1f19ce..f749b33dc 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
 @@ -1041,7 +1041,7 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-mtk-hostapd-Add-support-for-gtk-rekeying-in-hostapd-.patch
similarity index 88%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-mtk-hostapd-Add-support-for-gtk-rekeying-in-hostapd-.patch
index 4dad332..5d8edfd 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-mtk-hostapd-Add-support-for-gtk-rekeying-in-hostapd-.patch
@@ -1,7 +1,7 @@
-From 4b58cd9fc60093a0f4e9fe56cf47f05e9b1287fb Mon Sep 17 00:00:00 2001
+From aa65ab579fe3c032034b2ca641a91aa62285b59f Mon Sep 17 00:00:00 2001
 From: mtk23510 <rudra.shahi@mediatek.com>
 Date: Fri, 26 May 2023 14:52:35 +0800
-Subject: [PATCH 35/38] hostapd: mtk: Add support for gtk rekeying in hostapd
+Subject: [PATCH 35/54] mtk: hostapd: Add support for gtk rekeying in hostapd
  cli
 
 Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 13 insertions(+)
 
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 6d763f3..363a6bb 100644
+index 6d763f327..363a6bb93 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1256,6 +1256,15 @@ static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-mtk-hostapd-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-mtk-hostapd-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
index 2b0f254..7fb99bd 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-mtk-hostapd-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
@@ -1,7 +1,7 @@
-From bf06bdd4ba98cebdb21408fc7c85b9adc813a956 Mon Sep 17 00:00:00 2001
+From a8d74e867652c6feda7332ee2cb40611635179f0 Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Tue, 11 Jul 2023 14:17:43 +0800
-Subject: [PATCH 36/38] hostapd: mtk: Set WMM and TX queue parameters for
+Subject: [PATCH 36/54] mtk: hostapd: Set WMM and TX queue parameters for
  wpa_supplicant
 
 Since most of the time, wpa_supplicant will be used to setup an STA
@@ -14,7 +14,7 @@
  1 file changed, 6 insertions(+), 6 deletions(-)
 
 diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
-index 2652c8a..cd40258 100644
+index 2652c8a97..cd4025884 100644
 --- a/wpa_supplicant/config.c
 +++ b/wpa_supplicant/config.c
 @@ -4673,19 +4673,19 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-mtk-hostapd-Set-STA-TX-queue-parameters-configuratio.patch
similarity index 92%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-mtk-hostapd-Set-STA-TX-queue-parameters-configuratio.patch
index a6a86d8..aab9689 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-mtk-hostapd-Set-STA-TX-queue-parameters-configuratio.patch
@@ -1,7 +1,7 @@
-From 33cbd77949640d337e4e39d462bbb6b575792de3 Mon Sep 17 00:00:00 2001
+From 7a02e5965652229833be92a9bd8f675e2015144a Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Fri, 7 Jul 2023 17:16:11 +0800
-Subject: [PATCH 37/38] hostapd: mtk: Set STA TX queue parameters configuration
+Subject: [PATCH 37/54] mtk: hostapd: Set STA TX queue parameters configuration
  after association
 
 This patch adds the way for wpa_supplicant to set driver's TX queue
@@ -17,7 +17,7 @@
  2 files changed, 28 insertions(+)
 
 diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
-index dcf5764..36ff854 100644
+index dcf576487..36ff854ad 100644
 --- a/wpa_supplicant/driver_i.h
 +++ b/wpa_supplicant/driver_i.h
 @@ -321,6 +321,18 @@ static inline int wpa_drv_set_country(struct wpa_supplicant *wpa_s,
@@ -40,7 +40,7 @@
  				    const u8 *data, size_t data_len, int noack,
  				    unsigned int freq, unsigned int wait)
 diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
-index 3b8596d..f5ac62e 100644
+index 3b8596d6f..f5ac62eda 100644
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
 @@ -3559,6 +3559,20 @@ out:
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-mtk-hostapd-avoid-color-switch-when-beacon-is-not-se.patch
similarity index 70%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-mtk-hostapd-avoid-color-switch-when-beacon-is-not-se.patch
index e076eae..23ca582 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-mtk-hostapd-avoid-color-switch-when-beacon-is-not-se.patch
@@ -1,7 +1,7 @@
-From 7a2d1d5e7d43fbd7ecf008447e08118c10905d63 Mon Sep 17 00:00:00 2001
+From 695e63f81f817c302e4594e44b49e1f7a8c7969c Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Fri, 1 Sep 2023 15:31:24 +0800
-Subject: [PATCH 38/38] hostapd: mtk: avoid color switch when beacon is not set
+Subject: [PATCH 38/54] mtk: hostapd: avoid color switch when beacon is not set
 
 Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
 ---
@@ -9,10 +9,10 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index b8ae8de..a4fffd9 100644
+index ec7677f6a..2b563a572 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
-@@ -4249,7 +4249,7 @@ void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap)
+@@ -4250,7 +4250,7 @@ void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap)
  {
  	struct os_reltime now;
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0039-mtk-hostapd-6g-bss-connect-do-not-consider-ht-operat.patch
similarity index 68%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0039-mtk-hostapd-6g-bss-connect-do-not-consider-ht-operat.patch
index 105e188..0a5a04f 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0039-mtk-hostapd-6g-bss-connect-do-not-consider-ht-operat.patch
@@ -1,20 +1,22 @@
-From d11dea1d3dee3577be404bfb6f7dc2460858242d Mon Sep 17 00:00:00 2001
+From 4fe45b586ebb86cfbdd61ab91d5ebef110ce74aa Mon Sep 17 00:00:00 2001
 From: mtk20656 <chank.chen@mediatek.com>
 Date: Wed, 13 Sep 2023 19:29:51 +0800
-Subject: [PATCH] [hostapd][mt76]6g bss connect do not consider ht operation
+Subject: [PATCH 39/54] mtk: hostapd: 6g bss connect do not consider ht
+ operation
 
 Signed-off-by: mtk20656 <chank.chen@mediatek.com>
 ---
  src/ap/ieee802_11.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
+ mode change 100755 => 100644 src/ap/ieee802_11.c
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
 old mode 100755
 new mode 100644
-index ef520c8..904b1b5
+index 7b6aabbff..38fce3e82
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -5434,7 +5434,8 @@ static void handle_assoc(struct hostapd_data *hapd,
+@@ -5451,7 +5451,8 @@ static void handle_assoc(struct hostapd_data *hapd,
  			ieee802_11_set_beacons(hapd->iface);
  	}
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0040-mtk-hostapd-avoid-unnecessary-beacon-update-for-6-GH.patch
similarity index 78%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0040-mtk-hostapd-avoid-unnecessary-beacon-update-for-6-GH.patch
index 1695996..7c3853f 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0040-mtk-hostapd-avoid-unnecessary-beacon-update-for-6-GH.patch
@@ -1,7 +1,7 @@
-From 53dbf487d72a05ae692d98930852c3b98cc6dad6 Mon Sep 17 00:00:00 2001
+From 49b5d37f77fa48f215b3abc9c3ce74c26bbabefc Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Wed, 4 Oct 2023 11:12:52 +0800
-Subject: [PATCH] hostapd: mtk: avoid unnecessary beacon update for 6 GHz
+Subject: [PATCH 40/54] mtk: hostapd: avoid unnecessary beacon update for 6 GHz
  co-location
 
 There are two reasons to update beacon for 6 GHz co-location:
@@ -24,13 +24,13 @@
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
 Signed-off-by: Money Wang <money.wang@mediatek.com>
 ---
- src/ap/beacon.c   | 8 +++++++-
+ src/ap/beacon.c   | 6 ++++++
  src/ap/beacon.h   | 1 +
  src/ap/bss_load.c | 2 +-
- 3 files changed, 9 insertions(+), 2 deletions(-)
+ 3 files changed, 8 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/beacon.c b/src/ap/beacon.c
-index d160675..684bdc0 100644
+index d160675cb..b74396a8d 100644
 --- a/src/ap/beacon.c
 +++ b/src/ap/beacon.c
 @@ -2216,6 +2216,12 @@ fail:
@@ -46,17 +46,8 @@
  int ieee802_11_set_beacon(struct hostapd_data *hapd)
  {
  	struct hostapd_iface *iface = hapd->iface;
-@@ -2246,7 +2252,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
- 			mld_ap = true;
- #endif /* CONFIG_IEEE80211BE */
- 
--		if (is_6g == is_6ghz_op_class(other->conf->op_class) &&
-+		if ((!is_6g || is_6ghz_op_class(other->conf->op_class)) &&
- 		    !mld_ap)
- 			continue;
- 
 diff --git a/src/ap/beacon.h b/src/ap/beacon.h
-index c320825..b32b2a7 100644
+index c320825f3..b32b2a7d0 100644
 --- a/src/ap/beacon.h
 +++ b/src/ap/beacon.h
 @@ -15,6 +15,7 @@ struct ieee80211_mgmt;
@@ -68,7 +59,7 @@
  int ieee802_11_set_beacons(struct hostapd_iface *iface);
  int ieee802_11_update_beacons(struct hostapd_iface *iface);
 diff --git a/src/ap/bss_load.c b/src/ap/bss_load.c
-index 725d3cd..e9baafc 100644
+index 725d3cd34..e9baafc96 100644
 --- a/src/ap/bss_load.c
 +++ b/src/ap/bss_load.c
 @@ -55,7 +55,7 @@ static void update_channel_utilization(void *eloop_data, void *user_data)
@@ -81,5 +72,5 @@
  	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
  		return;
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-mtk-hostapd-refactor-the-flow-to-create-Wide-Bandwid.patch
similarity index 95%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-mtk-hostapd-refactor-the-flow-to-create-Wide-Bandwid.patch
index f02f935..d1e24d5 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-mtk-hostapd-refactor-the-flow-to-create-Wide-Bandwid.patch
@@ -1,8 +1,8 @@
-From 92caaf40a058d4eac8061c0e3240f0b23aba69ce Mon Sep 17 00:00:00 2001
+From 5daee94e29d5d7a3db5b8c8f03b15aa4a914f85f Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Thu, 24 Aug 2023 10:04:15 +0800
-Subject: hostapd: mtk: refactor the flow to create Wide Bandwidth
- Channel Switch IE
+Subject: [PATCH 41/54] mtk: hostapd: refactor the flow to create Wide
+ Bandwidth Channel Switch IE
 
 This patch changes the flow to create Wide Bandwidth Channel Switch IE:
 1. 2 GHz: Wide Bandwidth Channel Switch IE should not present.
@@ -26,10 +26,10 @@
  1 file changed, 76 insertions(+), 23 deletions(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index ef520c8..5f4d78f 100755
+index 38fce3e82..d46c5a42b 100644
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -7065,57 +7065,110 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
+@@ -7083,57 +7083,110 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
  
  u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
  {
@@ -164,5 +164,5 @@
  	return eid;
  }
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-mtk-hostapd-Add-ACS-chanlist-info-in-get_config.patch
old mode 100755
new mode 100644
similarity index 88%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-mtk-hostapd-Add-ACS-chanlist-info-in-get_config.patch
index b699fc5..6508476
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-mtk-hostapd-Add-ACS-chanlist-info-in-get_config.patch
@@ -1,7 +1,7 @@
-From c515d269b08190aede080b9c59bf758f5d65e5a5 Mon Sep 17 00:00:00 2001
+From 5e51c981aa0540864803b5f5b68e715a8d98a338 Mon Sep 17 00:00:00 2001
 From: "fancy.liu" <fancy.liu@mediatek.com>
 Date: Sun, 8 Oct 2023 11:50:06 +0800
-Subject: [PATCH] hostapd: mtk: Add ACS chanlist info in get_config
+Subject: [PATCH 42/54] mtk: hostapd: Add ACS chanlist info in get_config
 
 This patch is used to add ACS chanlist info displaying
 for upper layer application obtaining.
@@ -15,10 +15,10 @@
  1 file changed, 59 insertions(+)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 537d5cf..2108198 100644
+index ae61cf625..aba22e1e6 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -1120,6 +1120,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
+@@ -1048,6 +1048,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
  {
  	int ret;
  	char *pos, *end;
@@ -26,7 +26,7 @@
  
  	pos = buf;
  	end = buf + buflen;
-@@ -1299,6 +1300,64 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
+@@ -1227,6 +1228,64 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
  		pos += ret;
  	}
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0043-mtk-hostapd-Fix-RSNXE-Interop-issue-with-STA.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0043-mtk-hostapd-Fix-RSNXE-Interop-issue-with-STA.patch
new file mode 100644
index 0000000..aae2359
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0043-mtk-hostapd-Fix-RSNXE-Interop-issue-with-STA.patch
@@ -0,0 +1,43 @@
+From c21e12bb63b9c3906143ffb368297e3b6a155eb3 Mon Sep 17 00:00:00 2001
+From: mtk25255 <rohit.kamat@mediatek.com>
+Date: Thu, 12 Oct 2023 14:29:23 +0800
+Subject: [PATCH 43/54] mtk: hostapd: Fix RSNXE Interop issue with STA
+
+---
+ src/ap/ieee802_11.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
+index d46c5a42b..1db66a783 100644
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -5181,6 +5181,7 @@ static void handle_assoc(struct hostapd_data *hapd,
+ 	int delay_assoc = 0;
+ #endif /* CONFIG_FILS */
+ 	int omit_rsnxe = 0;
++	bool sae_pk = false;
+ 
+ 	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
+ 				      sizeof(mgmt->u.assoc_req))) {
+@@ -5399,7 +5400,17 @@ static void handle_assoc(struct hostapd_data *hapd,
+ 	if (resp != WLAN_STATUS_SUCCESS)
+ 		goto fail;
+ 	omit_rsnxe = !get_ie(pos, left, WLAN_EID_RSNX);
+-
++#ifdef CONFIG_SAE_PK
++	sae_pk = hostapd_sae_pk_in_use(hapd->conf);
++#endif /* CONFIG_SAE_PK */
++	if (omit_rsnxe) {
++		if (!reassoc && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
++				(hapd->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
++				 hapd->conf->sae_pwe == SAE_PWE_BOTH || sae_pk ||
++				 wpa_key_mgmt_sae_ext_key(hapd->conf->wpa_key_mgmt))) {
++			omit_rsnxe = 0;
++		}
++	}
+ 	if (hostapd_get_aid(hapd, sta) < 0) {
+ 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
+ 			       HOSTAPD_LEVEL_INFO, "No room for more AIDs");
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-mtk-hostapd-Fix-chan_switch-to-usable-DFS-channel-fa.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-mtk-hostapd-Fix-chan_switch-to-usable-DFS-channel-fa.patch
new file mode 100644
index 0000000..2816120
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-mtk-hostapd-Fix-chan_switch-to-usable-DFS-channel-fa.patch
@@ -0,0 +1,44 @@
+From a56c6b0ea29d278bd7ec67e45c298eac8526a055 Mon Sep 17 00:00:00 2001
+From: "fancy.liu" <fancy.liu@mediatek.com>
+Date: Wed, 1 Nov 2023 19:58:05 +0800
+Subject: [PATCH 44/54] mtk: hostapd: Fix chan_switch to usable DFS channel
+ fail due to ACS
+
+Step and issue:
+1. Enable ACS in hostapd config;
+2. Bootup and then use hostapd_cli cmd switch channel to a DFS channel;
+3. Will do ACS again, and no work on channel specified in step 2.
+
+Root cause:
+When need do DFS-CAC, hostapd will do intf disable, then set the new
+channel into running config settings, and finally enable intf;
+In the test case, new DFS channel is set to runnint config settings, but
+another param "acs" is still 1 (enable), caused the ACS running when
+intf enabled.
+
+Solution:
+In the hostapd_switch_channel_fallback, need to disable acs if channel
+is valid.
+
+Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
+---
+ src/ap/hostapd.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index 2b563a572..f01f607f3 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -4121,6 +4121,9 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+ 
+ 	iface->freq = freq_params->freq;
+ 	iface->conf->channel = freq_params->channel;
++	if (iface->conf->channel != 0) /* If channel not zero, will disable acs. */
++		iface->conf->acs = 0;
++
+ 	iface->conf->secondary_channel = freq_params->sec_channel_offset;
+ 	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
+ 	hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0045-mtk-hostapd-update-eht-operation-element.patch
similarity index 83%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0045-mtk-hostapd-update-eht-operation-element.patch
index 5092a61..5b1c065 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0045-mtk-hostapd-update-eht-operation-element.patch
@@ -1,14 +1,14 @@
-From eaf03e5841437d268c929bd8215d8499fbdbfbb0 Mon Sep 17 00:00:00 2001
+From 9d81aac8e0c2a6e1aa968581a9c77cec7468cd60 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 10 May 2023 13:11:34 +0800
-Subject: [PATCH 1001/1005] hostapd: mtk: update eht operation element
+Subject: [PATCH 45/54] mtk: hostapd: update eht operation element
 
 ---
  src/ap/ieee802_11_eht.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c
-index 9a07f75..f132e1d 100644
+index 9a07f7501..f132e1d9c 100644
 --- a/src/ap/ieee802_11_eht.c
 +++ b/src/ap/ieee802_11_eht.c
 @@ -215,9 +215,9 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid)
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0046-mtk-hostapd-ucode-add-support-for-ucode-to-parse-BW3.patch
similarity index 64%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0046-mtk-hostapd-ucode-add-support-for-ucode-to-parse-BW3.patch
index 9c23287..be86061 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0046-mtk-hostapd-ucode-add-support-for-ucode-to-parse-BW3.patch
@@ -1,7 +1,7 @@
-From 5d04c65f6a625dea4b8ff7cfa35311dbfa2e4ae7 Mon Sep 17 00:00:00 2001
+From c73597bd17673ac6f33a314458cce14009a15fb0 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 30 Aug 2023 04:23:37 +0800
-Subject: [PATCH 1002/1005] hostapd: mtk: ucode: add support for ucode to parse
+Subject: [PATCH 46/54] mtk: hostapd: ucode: add support for ucode to parse
  BW320MHz info
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/src/utils/ucode.c b/src/utils/ucode.c
-index 2beeb9a..122c619 100644
+index 29c753c32..4b6ed3a94 100644
 --- a/src/utils/ucode.c
 +++ b/src/utils/ucode.c
-@@ -85,6 +85,10 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -144,6 +144,10 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
  	case 2:
  		chanwidth = CONF_OPER_CHWIDTH_160MHZ;
  		break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0047-mtk-hostapd-synchronize-bandwidth-in-AP-STA-support.patch
similarity index 94%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0047-mtk-hostapd-synchronize-bandwidth-in-AP-STA-support.patch
index 5a63279..c508d77 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0047-mtk-hostapd-synchronize-bandwidth-in-AP-STA-support.patch
@@ -1,7 +1,7 @@
-From 804f9b03e7f143d3a80741cb67721810e27ed2d8 Mon Sep 17 00:00:00 2001
+From 9238758c9fb0efb9b979eacef7d09914332186af Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Mon, 11 Sep 2023 10:16:35 +0800
-Subject: [PATCH] hostapd: mtk: synchronize bandwidth in AP/STA support
+Subject: [PATCH 47/54] mtk: hostapd: synchronize bandwidth in AP/STA support
 
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
 ---
@@ -11,7 +11,7 @@
  3 files changed, 117 insertions(+), 18 deletions(-)
 
 diff --git a/src/ap/ucode.c b/src/ap/ucode.c
-index af97091..79d568f 100644
+index 16d1b5153..98b2a3bf2 100644
 --- a/src/ap/ucode.c
 +++ b/src/ap/ucode.c
 @@ -489,6 +489,9 @@ uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs)
@@ -105,10 +105,10 @@
  		ret = hostapd_switch_channel(iface->bss[i], &csa);
  
 diff --git a/src/utils/ucode.c b/src/utils/ucode.c
-index 122c619..0990e7b 100644
+index 4b6ed3a94..6f82382f3 100644
 --- a/src/utils/ucode.c
 +++ b/src/utils/ucode.c
-@@ -51,6 +51,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -110,6 +110,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
  	uc_value_t *freq = uc_fn_arg(0);
  	uc_value_t *sec = uc_fn_arg(1);
  	int width = ucv_uint64_get(uc_fn_arg(2));
@@ -116,7 +116,7 @@
  	int freq_val, center_idx, center_ofs;
  	enum oper_chan_width chanwidth;
  	enum hostapd_hw_mode hw_mode;
-@@ -88,6 +89,9 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -147,6 +148,9 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
  	case 9:
  		width = 3;
  		chanwidth = CONF_OPER_CHWIDTH_320MHZ;
@@ -126,7 +126,7 @@
  		break;
  	default:
  		return NULL;
-@@ -119,12 +123,16 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -178,12 +182,16 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
  	ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr)));
  	ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel));
  	ucv_object_add(ret, "frequency", ucv_int64_new(freq_val));
@@ -146,7 +146,7 @@
  		center_ofs = 20;
  	else
 diff --git a/wpa_supplicant/ucode.c b/wpa_supplicant/ucode.c
-index 6cba73d..d5489ea 100644
+index 397f85bde..542ca25c9 100644
 --- a/wpa_supplicant/ucode.c
 +++ b/wpa_supplicant/ucode.c
 @@ -7,6 +7,8 @@
@@ -275,5 +275,5 @@
  
  #ifdef CONFIG_MESH
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0048-mtk-hostapd-Add-support-for-updating-background-chan.patch
similarity index 96%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0048-mtk-hostapd-Add-support-for-updating-background-chan.patch
index 23aa563..ab4ff5b 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0048-mtk-hostapd-Add-support-for-updating-background-chan.patch
@@ -1,7 +1,7 @@
-From 00555b91d4d25c64eb556fe1b8815e522970b130 Mon Sep 17 00:00:00 2001
+From 8590ccd17827862e02b9f40ccca29a03dc3e0ab6 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 10:25:01 +0800
-Subject: [PATCH 1004/1005] hostapd: mtk: Add support for updating background
+Subject: [PATCH 48/54] mtk: hostapd: Add support for updating background
  channel by driver
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,7 +16,7 @@
  7 files changed, 160 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 95119a3..008596b 100644
+index 95119a391..008596bb2 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -814,11 +814,14 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
@@ -201,7 +201,7 @@
  			  int ht_enabled, int chan_offset, int chan_width,
  			  int cf1, int cf2)
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index 25ba29c..a1a2be5 100644
+index 25ba29ca1..a1a2be5ec 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -30,6 +30,9 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
@@ -215,7 +215,7 @@
  				 int ht_enabled, int chan_offset, int chan_width,
  				 int cf1, int cf2, u32 state);
 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index f749b33..12419c6 100644
+index f749b33dc..12419c6d4 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
 @@ -2089,6 +2089,18 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
@@ -255,7 +255,7 @@
  		if (!data)
  			break;
 diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
-index 1849f38..ea8d725 100644
+index 1849f38d8..ea8d7254a 100644
 --- a/src/ap/hostapd.h
 +++ b/src/ap/hostapd.h
 @@ -602,6 +602,11 @@ struct hostapd_iface {
@@ -271,10 +271,10 @@
  
  	u16 hw_flags;
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index ebc1d27..a9f48a1 100644
+index 8da93e025..b0a6e3514 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5842,6 +5842,18 @@ enum wpa_event_type {
+@@ -5845,6 +5845,18 @@ enum wpa_event_type {
  	 * The channel in the notification is now marked as usable.
  	 */
  	EVENT_DFS_STA_CAC_EXPIRED,
@@ -294,7 +294,7 @@
  
  
 diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
-index 63d4401..c1a65eb 100644
+index 63d44017c..c1a65eb4e 100644
 --- a/src/drivers/driver_nl80211_event.c
 +++ b/src/drivers/driver_nl80211_event.c
 @@ -2514,6 +2514,12 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
@@ -311,7 +311,7 @@
  		wpa_supplicant_event(drv->ctx, EVENT_DFS_STA_CAC_SKIPPED, &data);
  		break;
 diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index 225864b..9b0a817 100644
+index 225864b94..9b0a8171a 100644
 --- a/src/drivers/nl80211_copy.h
 +++ b/src/drivers/nl80211_copy.h
 @@ -6643,6 +6643,10 @@ enum nl80211_smps_mode {
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0049-mtk-hostapd-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0049-mtk-hostapd-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
index fcfd0bf..623e3fc 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0049-mtk-hostapd-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
@@ -1,8 +1,7 @@
-From 5bcd4472062750b192c98d944b74e07b14ab3af5 Mon Sep 17 00:00:00 2001
+From e878e546ee5d1e86f174b2713b7a46fb05b6a7b9 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 2 Aug 2023 19:00:34 +0800
-Subject: [PATCH 1005/1005] hostapd: mtk: add zwdfs mode ctrl for eagle efem
- hwits
+Subject: [PATCH 49/54] mtk: hostapd: add zwdfs mode ctrl for eagle efem hwits
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -19,7 +18,7 @@
  10 files changed, 115 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 9e3dbb2..a751993 100644
+index 9e3dbb24a..a75199345 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -3183,6 +3183,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -32,10 +31,10 @@
  		int val = atoi(pos);
  
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c288352..517ebd6 100644
+index aba22e1e6..f7c7a09f3 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -4156,6 +4156,33 @@ hostapd_ctrl_iface_dump_amnt(struct hostapd_data *hapd, char *cmd,
+@@ -4221,6 +4221,33 @@ hostapd_ctrl_iface_dump_amnt(struct hostapd_data *hapd, char *cmd,
  		return pos - buf;
  }
  
@@ -69,7 +68,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4750,6 +4777,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4815,6 +4842,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		if (pos)
  			*pos = ' ';
  		reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 23, reply, reply_size);
@@ -80,7 +79,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 7c0d12a..b6f05e7 100644
+index 7c0d12a3b..b6f05e7af 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1025,6 +1025,7 @@ struct hostapd_config {
@@ -104,7 +103,7 @@
  	DFS_DETECT_MODE_DISABLE,
  	DFS_DETECT_MODE_AP_ENABLE,
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 721bfa0..5b93ea6 100644
+index 721bfa053..5b93ea647 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1257,3 +1257,17 @@ int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_
@@ -126,7 +125,7 @@
 +						   hapd->iconf->background_radar_mode);
 +}
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 008596b..2564168 100644
+index 008596bb2..2564168bb 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -983,6 +983,9 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
@@ -150,7 +149,7 @@
  
  	return 0;
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index e140de6..5bc1e04 100644
+index e140de60b..5bc1e0444 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -16,6 +16,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -180,10 +179,10 @@
  #define ETH_ALEN 6
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index a9f48a1..bc82d28 100644
+index b0a6e3514..0c1b2e452 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5201,6 +5201,13 @@ struct wpa_driver_ops {
+@@ -5204,6 +5204,13 @@ struct wpa_driver_ops {
  	* @amnt_dump_buf: Buffer to print
  	*/
  	int (*amnt_dump)(void *priv, u8 amnt_idx, u8 *amnt_dump_buf);
@@ -198,10 +197,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 25e5910..73401fd 100644
+index b3897e61d..3cbf8610a 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14723,6 +14723,39 @@ fail:
+@@ -14743,6 +14743,39 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -241,14 +240,14 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14895,4 +14928,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14915,4 +14948,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.ap_trigtype = nl80211_ap_trigtype,
  	.amnt_set = nl80211_amnt_set,
  	.amnt_dump = nl80211_amnt_dump,
 +	.background_radar_mode = nl80211_background_radar_mode,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 0d85adf..74ee9b1 100644
+index 0d85adfee..74ee9b191 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -210,6 +210,7 @@ struct wpa_driver_nl80211_data {
@@ -260,10 +259,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 8c8b84e..90711b4 100644
+index 4bd15f348..74c3e0d86 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1133,6 +1133,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1137,6 +1137,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
  					drv->mtk_rfeatures_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0050-mtk-hostapd-add-support-enable-disable-preamble-punc.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0050-mtk-hostapd-add-support-enable-disable-preamble-punc.patch
index 4178b68..fc9a02d 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0050-mtk-hostapd-add-support-enable-disable-preamble-punc.patch
@@ -1,8 +1,8 @@
-From df3d6a354fc1243f8c862f2b61ee9ac09eabe482 Mon Sep 17 00:00:00 2001
+From d0f78e1b2efd0d0842c98a8733b06a7b59a9bd07 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Thu, 21 Sep 2023 10:29:46 +0800
-Subject: [PATCH] hostapd: mtk: add support enable/disable preamble puncture
- from mtk vendor command
+Subject: [PATCH 50/54] mtk: hostapd: add support enable/disable preamble
+ puncture from mtk vendor command
 
 This commit supports two ways to enable/disable preamble puncture
 feature.
@@ -40,7 +40,7 @@
  12 files changed, 161 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index a751993..278f6b3 100644
+index a75199345..278f6b347 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4801,6 +4801,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -69,10 +69,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 517ebd6..7315d12 100644
+index f7c7a09f3..64bab0228 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -4183,6 +4183,59 @@ hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cm
+@@ -4248,6 +4248,59 @@ hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cm
  	return os_snprintf(buf, buflen, "OK\n");
  }
  
@@ -132,7 +132,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4769,6 +4822,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4834,6 +4887,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
  							reply, reply_size);
@@ -146,7 +146,7 @@
  		// Replace first ':' with a single space ' '
  		char *pos = buf + 23;
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 223db56..d8dd549 100644
+index 223db56eb..d8dd5495a 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -302,6 +302,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -158,7 +158,7 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index b6f05e7..9e39e82 100644
+index b6f05e7af..9e39e8285 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1205,6 +1205,7 @@ struct hostapd_config {
@@ -183,7 +183,7 @@
  #define EDCCA_MIN_COMPENSATION -126
  #define EDCCA_MAX_COMPENSATION 126
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 5b93ea6..d0d8279 100644
+index 5b93ea647..d0d8279e2 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1271,3 +1271,12 @@ int hostapd_drv_background_radar_mode(struct hostapd_data *hapd)
@@ -200,7 +200,7 @@
 +					 hapd->iconf->pp_mode);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 1e7ae7a..e4c2827 100644
+index 1e7ae7a8d..e4c2827bf 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -163,6 +163,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
@@ -212,7 +212,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 2b563a5..90c6c26 100644
+index f01f607f3..2ffa3d4ea 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2526,6 +2526,8 @@ dfs_offload:
@@ -225,7 +225,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 5bc1e04..6275c14 100644
+index 5bc1e0444..6275c141d 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -17,6 +17,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -255,10 +255,10 @@
  #define ETH_ALEN 6
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index bc82d28..261ed80 100644
+index 0c1b2e452..fb463aaac 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5208,6 +5208,12 @@ struct wpa_driver_ops {
+@@ -5211,6 +5211,12 @@ struct wpa_driver_ops {
  	 * @background_radar_mode: background radar mode
  	 */
  	int (*background_radar_mode)(void *priv, u8 background_radar_mode);
@@ -272,10 +272,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 2089ad6..3cc55dc 100644
+index 3cbf8610a..cbe793cc6 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -141,6 +141,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
+@@ -151,6 +151,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
  	[MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
  };
  
@@ -287,7 +287,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14756,6 +14761,49 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m
+@@ -14776,6 +14781,49 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m
  	return ret;
  }
  
@@ -337,14 +337,14 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14929,4 +14977,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14949,4 +14997,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.amnt_set = nl80211_amnt_set,
  	.amnt_dump = nl80211_amnt_dump,
  	.background_radar_mode = nl80211_background_radar_mode,
 +	.pp_mode_set = nl80211_pp_mode_set,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 74ee9b1..1bba5b1 100644
+index 74ee9b191..1bba5b14e 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -211,6 +211,7 @@ struct wpa_driver_nl80211_data {
@@ -356,10 +356,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 90711b4..f2c42b9 100644
+index 74c3e0d86..0e044b03c 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1136,6 +1136,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1140,6 +1140,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL:
  					drv->mtk_background_radar_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0051-mtk-hostapd-add-no_beacon-vendor-command-for-cert.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0051-mtk-hostapd-add-no_beacon-vendor-command-for-cert.patch
new file mode 100644
index 0000000..5f7489e
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0051-mtk-hostapd-add-no_beacon-vendor-command-for-cert.patch
@@ -0,0 +1,247 @@
+From 1ca50d17101a4812a424ed5eb6ae10d54635b055 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Wed, 22 Nov 2023 21:41:34 +0800
+Subject: [PATCH 51/54] mtk: hostapd: add no_beacon vendor command for cert
+
+Add the vendor command to disable/enable beacon
+
+[Usage]
+hostapd_cli -i <interface> no_beacon <value>
+ <value>
+ 0: enable beacon
+ 1: disable beacon
+
+Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
+---
+ hostapd/ctrl_iface.c              | 21 +++++++++++++++++++
+ hostapd/hostapd_cli.c             |  7 +++++++
+ src/ap/ap_drv_ops.c               |  8 ++++++++
+ src/ap/ap_drv_ops.h               |  1 +
+ src/common/mtk_vendor.h           | 12 +++++++++++
+ src/drivers/driver.h              |  7 +++++++
+ src/drivers/driver_nl80211.c      | 34 +++++++++++++++++++++++++++++++
+ src/drivers/driver_nl80211.h      |  1 +
+ src/drivers/driver_nl80211_capa.c |  3 +++
+ 9 files changed, 94 insertions(+)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index 64bab0228..7406aef38 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -4301,6 +4301,24 @@ hostapd_ctrl_iface_get_pp(struct hostapd_data *hapd, char *cmd, char *buf,
+ 	}
+ }
+ 
++static int
++hostapd_ctrl_iface_disable_beacon(struct hostapd_data *hapd, char *value,
++				  char *buf, size_t buflen)
++{
++	int disable_beacon = atoi(value);
++
++	if (disable_beacon < 0) {
++		wpa_printf(MSG_ERROR, "Invalid value for beacon ctrl");
++		return -1;
++	}
++
++	if (hostapd_drv_beacon_ctrl(hapd, !disable_beacon) == 0)
++		return os_snprintf(buf, buflen, "OK\n");
++	else
++		return -1;
++
++}
++
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+ 					      int reply_size,
+@@ -4904,6 +4922,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "SET_BACKGROUND_RADAR_MODE", 25) == 0) {
+ 		reply_len = hostapd_ctrl_iface_set_background_radar_mode(hapd, buf + 25,
+ 									 reply, reply_size);
++	} else if (os_strncmp(buf, "NO_BEACON ", 10) == 0) {
++		reply_len = hostapd_ctrl_iface_disable_beacon(hapd, buf + 10, reply,
++							      reply_size);
+ 	} else {
+ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ 		reply_len = 16;
+diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
+index 363a6bb93..d5b6d59f3 100644
+--- a/hostapd/hostapd_cli.c
++++ b/hostapd/hostapd_cli.c
+@@ -1422,6 +1422,11 @@ static int hostapd_cli_cmd_get_mu(struct wpa_ctrl *ctrl, int argc,
+ 	return hostapd_cli_cmd(ctrl, "GET_MU", 0, NULL, NULL);
+ }
+ 
++static int hostapd_cli_cmd_disable_beacon(struct wpa_ctrl *ctrl, int argc,
++					   char *argv[])
++{
++	return hostapd_cli_cmd(ctrl, "NO_BEACON", 1, argc, argv);
++}
+ 
+ #ifdef CONFIG_DPP
+ 
+@@ -1799,6 +1804,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
+ 		"<value> [0-15] bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0)"},
+ 	{ "get_mu", hostapd_cli_cmd_get_mu, NULL,
+ 		" = show mu onoff value in 0-15 bitmap"},
++	{ "no_beacon", hostapd_cli_cmd_disable_beacon, NULL,
++		"<value> 0: Enable beacon, 1: Disable beacon"},
+ #ifdef CONFIG_DPP
+ 	{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
+ 	  "report a scanned DPP URI from a QR Code" },
+diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
+index d0d8279e2..073c05de8 100644
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -1280,3 +1280,11 @@ int hostapd_drv_pp_mode_set(struct hostapd_data *hapd)
+ 	return hapd->driver->pp_mode_set(hapd->drv_priv,
+ 					 hapd->iconf->pp_mode);
+ }
++
++int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode)
++{
++	if (!hapd->driver || !hapd->driver->beacon_ctrl)
++		return 0;
++	return hapd->driver->beacon_ctrl(hapd->drv_priv, beacon_mode);
++}
++
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index e4c2827bf..6b9e454de 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -164,6 +164,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
+ int hostapd_drv_amnt_set(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_sta_mac);
+ int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_buf);
+ int hostapd_drv_pp_mode_set(struct hostapd_data *hapd);
++int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode);
+ 
+ #include "drivers/driver.h"
+ 
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index 6275c141d..5531802b8 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -18,6 +18,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ 	MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
+ 	MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
++	MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL = 0xcd,
+ };
+ 
+ enum mtk_vendor_attr_edcca_ctrl {
+@@ -268,6 +269,17 @@ enum mtk_vendor_attr_pp_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_PP_CTRL - 1
+ };
+ 
++enum mtk_vendor_attr_beacon_ctrl {
++	MTK_VENDOR_ATTR_BEACON_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_BEACON_CTRL_MODE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_BEACON_CTRL,
++	MTK_VENDOR_ATTR_BEACON_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_BEACON_CTRL - 1
++};
++
+ #define CSI_MAX_COUNT 256
+ #define ETH_ALEN 6
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index fb463aaac..40f6150d7 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -5128,6 +5128,13 @@ struct wpa_driver_ops {
+ 	 int (*mu_ctrl)(void *priv, u8 mode, void *config);
+ 	 int (*mu_dump)(void *priv, u8 *mu_onoff);
+ 
++	/**
++	 * beacon_ctrl - ctrl on off for beacon
++	 * @priv: Private driver interface data
++	 *
++	 */
++	int (*beacon_ctrl)(void *priv, u8 beacon_mode);
++
+ 	/**
+ 	 * three_wire_ctrl - set three_wire_ctrl mode
+ 	 * @priv: Private driver interface data
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index cbe793cc6..9a10a93f0 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -13827,6 +13827,39 @@ static int nl80211_mu_dump(void *priv, u8 *mu_onoff)
+ 
+ 	return ret;
+ }
++static int nl80211_beacon_ctrl(void *priv, u8 beacon_mode)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data;
++	int ret;
++
++	if (!drv->mtk_beacon_ctrl_vendor_cmd_avail) {
++		wpa_printf(MSG_ERROR,
++			   "nl80211: Driver does not support setting beacon control");
++		return 0;
++	}
++
++	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL) ||
++		!(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
++		nla_put_u8(msg, MTK_VENDOR_ATTR_BEACON_CTRL_MODE, beacon_mode)) {
++		nlmsg_free(msg);
++		return -ENOBUFS;
++	}
++
++	nla_nest_end(msg, data);
++
++	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
++
++	if (ret)
++		wpa_printf(MSG_ERROR, "Failed to set beacon_ctrl. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++}
++
+ #endif /* CONFIG_IEEE80211AX */
+ 
+ 
+@@ -14972,6 +15005,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.set_4addr_mode = nl80211_set_4addr_mode,
+ 	.mu_ctrl = nl80211_mu_ctrl,
+ 	.mu_dump = nl80211_mu_dump,
++	.beacon_ctrl = nl80211_beacon_ctrl,
+ #ifdef CONFIG_DPP
+ 	.dpp_listen = nl80211_dpp_listen,
+ #endif /* CONFIG_DPP */
+diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
+index 1bba5b14e..300c0d11a 100644
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -212,6 +212,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_amnt_vendor_cmd_avail:1;
+ 	unsigned int mtk_background_radar_vendor_cmd_avail:1;
+ 	unsigned int mtk_pp_vendor_cmd_avail:1;
++	unsigned int mtk_beacon_ctrl_vendor_cmd_avail:1;
+ 
+ 	u64 vendor_scan_cookie;
+ 	u64 remain_on_chan_cookie;
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index 0e044b03c..2f844053d 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1143,6 +1143,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+ 				case MTK_NL80211_VENDOR_SUBCMD_PP_CTRL:
+ 					drv->mtk_pp_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL :
++					drv->mtk_beacon_ctrl_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0052-mtk-hostapd-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
similarity index 75%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0052-mtk-hostapd-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
index d2b117c..f5b5c24 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0052-mtk-hostapd-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
@@ -1,7 +1,8 @@
-From 88f5a4c1c67f8fc40c8294c498faa72e1ceea470 Mon Sep 17 00:00:00 2001
+From 1f6c4857cb55c8ba81a50f3fe0a1465efee10513 Mon Sep 17 00:00:00 2001
 From: "fancy.liu" <fancy.liu@mediatek.com>
 Date: Thu, 28 Sep 2023 18:03:08 +0800
-Subject: [PATCH] hostapd: mtk: [ACS] Add EHT320 and HT40- support, fix issue
+Subject: [PATCH 52/54] mtk: hostapd: ACS: Add EHT320 and HT40- support, fix
+ issue
 
 1. Add 6G EHT320 support;
 2. Add 2.4G HT40- support;
@@ -9,11 +10,11 @@
 
 Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
 ---
- src/ap/acs.c | 222 +++++++++++++++++++++++++++++++--------------------
- 1 file changed, 136 insertions(+), 86 deletions(-)
+ src/ap/acs.c | 191 +++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 124 insertions(+), 67 deletions(-)
 
 diff --git a/src/ap/acs.c b/src/ap/acs.c
-index af31405..ed6a47b 100644
+index af3140542..e4871921f 100644
 --- a/src/ap/acs.c
 +++ b/src/ap/acs.c
 @@ -245,6 +245,7 @@ enum bw_type {
@@ -41,20 +42,7 @@
  };
  
  
-@@ -583,12 +590,6 @@ static void acs_survey_mode_interference_factor(
- 		    iface->conf->acs_exclude_dfs)
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
--
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
- 
-@@ -775,17 +776,29 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -775,10 +782,19 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  			 struct hostapd_channel_data **ideal_chan,
  			 long double *ideal_factor)
  {
@@ -75,9 +63,8 @@
  
  	for (i = 0; i < mode->num_channels; i++) {
  		double total_weight;
- 		struct acs_bias *bias, tmp_bias;
--		bool update_best = true;
-+		bool update_best = true, has_candidate = true;
+@@ -786,6 +802,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		bool update_best = true;
  
  		best = chan = &mode->channels[i];
 +		wpa_printf(MSG_INFO,
@@ -86,25 +73,7 @@
  
  		/* Since in the current ACS implementation the first channel is
  		 * always a primary channel, skip channels not available as
-@@ -804,11 +817,12 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 		    iface->conf->acs_exclude_dfs)
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
-+		if (!is_in_chanlist(iface, chan) || !is_in_freqlist(iface, chan)) {
-+			if (is_24ghz_mode(mode->mode))
-+				continue;
-+			else
-+				has_candidate = false;
-+		}
- 
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
-@@ -817,7 +831,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -817,7 +836,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  		    iface->conf->country[2] == 0x4f)
  			continue;
  
@@ -113,7 +82,7 @@
  			wpa_printf(MSG_DEBUG,
  				   "ACS: Channel %d: BW %u is not supported",
  				   chan->chan, bw);
-@@ -838,7 +852,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -838,7 +857,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  		}
  
  		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
@@ -123,7 +92,7 @@
  			if (hostapd_get_oper_chwidth(iface->conf) ==
  			    CONF_OPER_CHWIDTH_80MHZ &&
  			    !acs_usable_bw_chan(chan, ACS_BW80)) {
-@@ -856,63 +871,89 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -856,63 +876,86 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  					   chan->chan);
  				continue;
  			}
@@ -153,12 +122,12 @@
 +				continue;
  			}
 +		}
-+
-+		factor = 0;
-+		total_weight = 0;
  
 -			if (acs_usable_chan(adj_chan)) {
 -				factor += adj_chan->interference_factor;
++		factor = 0;
++		total_weight = 0;
++
 +		if (!is_24ghz_mode(mode->mode)) {
 +			/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
 +			 * crowded primary channel if one was found in the segment */
@@ -185,12 +154,8 @@
 -				   chan->chan);
 -			continue;
 -		}
-+				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
-+					wpa_printf(MSG_DEBUG,
-+						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
-+						   chan->chan, adj_chan->chan, bw);
++				if (!is_in_chanlist(iface, adj_chan) || !is_in_freqlist(iface, adj_chan))
 +					break;
-+				}
  
 -		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
 -		 * crowded primary channel if one was found in the segment */
@@ -203,30 +168,31 @@
 -				   best->interference_factor);
 -			chan = best;
 -		}
++				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
++					wpa_printf(MSG_DEBUG,
++						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
++						   chan->chan, adj_chan->chan, bw);
++					break;
++				}
++
 +				update_best = true;
 +				if (acs_usable_chan(adj_chan)) {
 +					factor += adj_chan->interference_factor;
 +					total_weight += 1;
-+
-+					if (!is_in_chanlist(iface, adj_chan) ||
-+						!is_in_freqlist(iface, adj_chan))
-+						update_best = false;
 +				} else {
 +					update_best = false;
 +				}
-+
-+				/* find the best channel in this segment */
-+				if (update_best && (!has_candidate ||
-+					adj_chan->interference_factor < best->interference_factor)) {
-+					best = adj_chan;
-+					has_candidate = true;
-+				}
-+			}
  
 -		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
 -		 * channel interference factor. */
 -		if (is_24ghz_mode(mode->mode)) {
-+			if (j != n_chans || !has_candidate) {
++				/* find the best channel in this segment */
++				if (update_best &&
++					adj_chan->interference_factor < best->interference_factor)
++					best = adj_chan;
++			}
++
++			if (j != n_chans) {
 +				wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
 +					   chan->chan);
 +				continue;
@@ -244,7 +210,7 @@
  			for (j = 0; j < n_chans; j++) {
 +				/* Will set primary_channel / secondary_channel(40M case) weight to 1 */
 +				tmp_chan = acs_find_chan(iface, chan->freq +
-+							 (j * 20) * sec_ch_factor);
++							 (j * sec_ch_factor * 20));
 +				if (tmp_chan && acs_usable_chan(tmp_chan)) {
 +					factor += tmp_chan->interference_factor;
 +					total_weight += 1;
@@ -254,38 +220,38 @@
 +				interference factor, separately for primary/secondary channel. */
  				adj_chan = acs_find_chan(iface, chan->freq +
 -							 (j * 20) - 5);
-+							 ((j * 20) - 5) * sec_ch_factor);
++							 (j * sec_ch_factor * 20) - 5);
  				if (adj_chan && acs_usable_chan(adj_chan)) {
  					factor += ACS_ADJ_WEIGHT *
  						adj_chan->interference_factor;
-@@ -920,7 +961,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -920,7 +963,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  				}
  
  				adj_chan = acs_find_chan(iface, chan->freq +
 -							 (j * 20) - 10);
-+							 ((j * 20) - 10) * sec_ch_factor);
++							 (j * sec_ch_factor * 20) - 10);
  				if (adj_chan && acs_usable_chan(adj_chan)) {
  					factor += ACS_NEXT_ADJ_WEIGHT *
  						adj_chan->interference_factor;
-@@ -928,7 +969,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -928,7 +971,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  				}
  
  				adj_chan = acs_find_chan(iface, chan->freq +
 -							 (j * 20) + 5);
-+							 ((j * 20) + 5) * sec_ch_factor);
++							 (j * sec_ch_factor * 20) + 5);
  				if (adj_chan && acs_usable_chan(adj_chan)) {
  					factor += ACS_ADJ_WEIGHT *
  						adj_chan->interference_factor;
-@@ -936,7 +977,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -936,7 +979,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  				}
  
  				adj_chan = acs_find_chan(iface, chan->freq +
 -							 (j * 20) + 10);
-+							 ((j * 20) + 10) * sec_ch_factor);
++							 (j * sec_ch_factor * 20) + 10);
  				if (adj_chan && acs_usable_chan(adj_chan)) {
  					factor += ACS_NEXT_ADJ_WEIGHT *
  						adj_chan->interference_factor;
-@@ -945,7 +986,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -945,7 +988,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  			}
  		}
  
@@ -295,7 +261,7 @@
  
  		bias = NULL;
  		if (iface->conf->acs_chan_bias) {
-@@ -964,11 +1006,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -964,11 +1008,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  
  		if (bias) {
  			factor *= bias->bias;
@@ -309,7 +275,7 @@
  				   "ACS:  * channel %d: total interference = %Lg",
  				   chan->chan, factor);
  		}
-@@ -1021,19 +1063,12 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+@@ -1021,19 +1065,12 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
  		goto bw_selected;
  	}
  
@@ -331,7 +297,7 @@
  		switch (hostapd_get_oper_chwidth(iface->conf)) {
  		case CONF_OPER_CHWIDTH_80MHZ:
  			n_chans = 4;
-@@ -1043,6 +1078,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+@@ -1043,6 +1080,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
  			break;
  		default:
  			break;
@@ -339,7 +305,7 @@
  		}
  	}
  
-@@ -1063,7 +1099,7 @@ bw_selected:
+@@ -1063,7 +1101,7 @@ bw_selected:
  	}
  
  	if (ideal_chan) {
@@ -348,7 +314,7 @@
  			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
  
  #ifdef CONFIG_IEEE80211BE
-@@ -1078,6 +1114,21 @@ bw_selected:
+@@ -1078,6 +1116,21 @@ bw_selected:
  	return rand_chan;
  }
  
@@ -370,21 +336,16 @@
  
  static void acs_adjust_secondary(struct hostapd_iface *iface)
  {
-@@ -1104,10 +1155,11 @@ static void acs_adjust_secondary(struct hostapd_iface *iface)
- static void acs_adjust_center_freq(struct hostapd_iface *iface)
+@@ -1105,7 +1158,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
  {
  	int center;
-+ 	u8 bw = hostapd_get_oper_chwidth(iface->conf);
  
 -	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
 +	wpa_printf(MSG_DEBUG, "ACS: Adjusting center frequency");
  
--	switch (hostapd_get_oper_chwidth(iface->conf)) {
-+	switch (bw) {
+ 	switch (hostapd_get_oper_chwidth(iface->conf)) {
  	case CONF_OPER_CHWIDTH_USE_HT:
- 		if (iface->conf->secondary_channel &&
- 		    iface->freq >= 2400 && iface->freq < 2500)
-@@ -1121,6 +1173,9 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+@@ -1121,6 +1174,9 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
  	case CONF_OPER_CHWIDTH_80MHZ:
  		center = acs_get_bw_center_chan(iface->freq, ACS_BW80);
  		break;
@@ -394,7 +355,7 @@
  	case CONF_OPER_CHWIDTH_160MHZ:
  		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
  		break;
-@@ -1128,7 +1183,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+@@ -1128,7 +1184,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
  		/* TODO: How can this be calculated? Adjust
  		 * acs_find_ideal_chan() */
  		wpa_printf(MSG_INFO,
@@ -403,7 +364,7 @@
  		return;
  	}
  
-@@ -1191,7 +1246,8 @@ static void acs_study(struct hostapd_iface *iface)
+@@ -1191,7 +1247,8 @@ static void acs_study(struct hostapd_iface *iface)
  	iface->conf->punct_bitmap = ideal_chan->punct_bitmap;
  #endif /* CONFIG_IEEE80211BE */
  
@@ -413,19 +374,6 @@
  		acs_adjust_secondary(iface);
  		acs_adjust_center_freq(iface);
  	}
-@@ -1270,12 +1326,6 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
- 		     iface->conf->acs_exclude_dfs))
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
--
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
- 
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0053-mtk-hostapd-add-eht_bw320_offset-configuration-optio.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0053-mtk-hostapd-add-eht_bw320_offset-configuration-optio.patch
new file mode 100644
index 0000000..77677d0
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0053-mtk-hostapd-add-eht_bw320_offset-configuration-optio.patch
@@ -0,0 +1,190 @@
+From cb9841c4361d5c1d236b7d257e2d513ecc1c7c91 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Tue, 17 Oct 2023 11:11:40 +0800
+Subject: [PATCH 53/54] mtk: hostapd: add eht_bw320_offset configuration option
+
+This patch introduces a new configuration option, "eht_bw320_offset",
+which enables devices to specify a preferred channelization for 320 MHz
+BSSs when using automatic channel selection (ACS).
+This option is only applicable when the channel is not already decided
+and the bandwidth is set to 320 MHz.
+
+The value and meaning of the option:
+0: auto-detected by hostapd
+1: 320 MHz-1
+2: 320 MHz-2
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ hostapd/config_file.c  |  3 +++
+ hostapd/hostapd.conf   |  8 ++++++++
+ src/ap/ap_config.c     |  6 ++++++
+ src/ap/ap_config.h     | 37 +++++++++++++++++++++++++++++++++++++
+ src/ap/ctrl_iface_ap.c | 11 +++++++++++
+ src/ap/drv_callbacks.c |  2 ++
+ 6 files changed, 67 insertions(+)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index 278f6b347..721685baf 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -4822,6 +4822,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 				   line);
+ 			return 1;
+ 		}
++	} else if (os_strcmp(buf, "eht_bw320_offset") == 0) {
++		u8 val = atoi(pos);
++		conf->eht_bw320_offset = val;
+ #endif /* CONFIG_IEEE80211BE */
+ 	} else if (os_strcmp(buf, "edcca_threshold") == 0) {
+ 		if (hostapd_parse_intlist(&conf->edcca_threshold, pos) ||
+diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
+index f16e3b08d..290504317 100644
+--- a/hostapd/hostapd.conf
++++ b/hostapd/hostapd.conf
+@@ -1032,6 +1032,14 @@ wmm_ac_vo_acm=0
+ #eht_oper_chwidth (see vht_oper_chwidth)
+ #eht_oper_centr_freq_seg0_idx
+ 
++#eht_bw320_offset: For automatic channel selection (ACS) to indicate a prefered
++# 320 MHz channelization in EHT mode.
++# If the channel is decided or the bandwidth is not 320 MHz, this option is meaningless.
++# 0 = auto-detect by hostapd
++# 1 = 320 MHz-1
++# 2 = 320 MHz-2
++#eht_bw320_offset=0
++
+ # Disabled subchannel bitmap (16 bits) as per IEEE P802.11be/3.0,
+ # Figure 9-1002c (EHT Operation Information field format). Each bit corresponds
+ # to a 20 MHz channel, the lowest bit corresponds to the lowest frequency. A
+diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
+index d8dd5495a..3fb98d08f 100644
+--- a/src/ap/ap_config.c
++++ b/src/ap/ap_config.c
+@@ -304,6 +304,7 @@ struct hostapd_config * hostapd_config_defaults(void)
+ 	conf->amsdu = 1;
+ 	conf->pp_mode = PP_DISABLE;
+ 
++	hostapd_set_and_check_bw320_offset(conf, 0);
+ 	return conf;
+ }
+ 
+@@ -1515,6 +1516,7 @@ static int hostapd_config_check_cw(struct hostapd_config *conf, int queue)
+ int hostapd_config_check(struct hostapd_config *conf, int full_config)
+ {
+ 	size_t i;
++	u8 bw320_offset = 0;
+ 
+ 	if (full_config && is_6ghz_op_class(conf->op_class) &&
+ 	    !conf->hw_mode_set) {
+@@ -1566,6 +1568,8 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
+ 			   "Cannot set ieee80211be without ieee80211ax");
+ 		return -1;
+ 	}
++
++	bw320_offset = conf->eht_bw320_offset;
+ #endif /* CONFIG_IEEE80211BE */
+ 
+ 	if (full_config && conf->mbssid && !conf->ieee80211ax) {
+@@ -1574,6 +1578,8 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
+ 		return -1;
+ 	}
+ 
++	hostapd_set_and_check_bw320_offset(conf, bw320_offset);
++
+ 	for (i = 0; i < conf->num_bss; i++) {
+ 		if (hostapd_config_check_bss(conf->bss[i], conf, full_config))
+ 			return -1;
+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
+index 9e39e8285..3e0505594 100644
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -1184,6 +1184,7 @@ struct hostapd_config {
+ 	struct eht_phy_capabilities_info eht_phy_capab;
+ 	u16 punct_bitmap; /* a bitmap of disabled 20 MHz channels */
+ 	u8 punct_acs_threshold;
++	u8 eht_bw320_offset;
+ #endif /* CONFIG_IEEE80211BE */
+ 
+ 	/* EHT enable/disable config from CHAN_SWITCH */
+@@ -1355,6 +1356,42 @@ hostapd_set_oper_centr_freq_seg1_idx(struct hostapd_config *conf,
+ 	conf->vht_oper_centr_freq_seg1_idx = oper_centr_freq_seg1_idx;
+ }
+ 
++static inline u8
++hostapd_get_bw320_offset(struct hostapd_config *conf)
++{
++#ifdef CONFIG_IEEE80211BE
++	if (conf->ieee80211be && is_6ghz_op_class(conf->op_class) &&
++	    hostapd_get_oper_chwidth(conf) == CONF_OPER_CHWIDTH_320MHZ)
++		return conf->eht_bw320_offset;
++#endif /* CONFIG_IEEE80211BE */
++	return 0;
++}
++
++static inline void
++hostapd_set_and_check_bw320_offset(struct hostapd_config *conf,
++				   u8 bw320_offset)
++{
++#ifdef CONFIG_IEEE80211BE
++	if (conf->ieee80211be && is_6ghz_op_class(conf->op_class) &&
++	    hostapd_get_oper_chwidth(conf) == CONF_OPER_CHWIDTH_320MHZ) {
++		if (conf->channel) {
++			/* If the channel is set, then calculate bw320_offset
++			 * by center frequency segment 0.
++			 */
++			u8 seg0 = hostapd_get_oper_centr_freq_seg0_idx(conf);
++			conf->eht_bw320_offset = (seg0 - 31) % 64 ? 2 : 1;
++		} else {
++			/* If the channel is not set, bw320_offset indicates
++			 * prefered offset of 320 MHz.
++			 */
++			conf->eht_bw320_offset = bw320_offset;
++		}
++	} else {
++		conf->eht_bw320_offset = 0;
++	}
++#endif /* CONFIG_IEEE80211BE */
++}
++
+ #define IBF_DEFAULT_ENABLE 0
+ 
+ int hostapd_mac_comp(const void *a, const void *b);
+diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
+index 7bdefb4cf..e686fb8b7 100644
+--- a/src/ap/ctrl_iface_ap.c
++++ b/src/ap/ctrl_iface_ap.c
+@@ -831,6 +831,17 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
+ 		if (os_snprintf_error(buflen - len, ret))
+ 			return len;
+ 		len += ret;
++
++		if (is_6ghz_op_class(iface->conf->op_class) &&
++		    hostapd_get_oper_chwidth(iface->conf) ==
++		    CONF_OPER_CHWIDTH_320MHZ) {
++			ret = os_snprintf(buf + len, buflen - len,
++					  "eht_bw320_offset=%d\n",
++					  iface->conf->eht_bw320_offset);
++			if (os_snprintf_error(buflen - len, ret))
++				return len;
++			len += ret;
++		}
+ 	}
+ #endif /* CONFIG_IEEE80211BE */
+ 
+diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
+index 12419c6d4..b0d9420e8 100644
+--- a/src/ap/drv_callbacks.c
++++ b/src/ap/drv_callbacks.c
+@@ -1175,6 +1175,8 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
+ 	hostapd_set_oper_chwidth(hapd->iconf, chwidth);
+ 	hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx);
+ 	hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx);
++	/* Auto-detect new bw320_offset */
++	hostapd_set_and_check_bw320_offset(hapd->iconf, 0);
+ #ifdef CONFIG_IEEE80211BE
+ 	hapd->iconf->punct_bitmap = punct_bitmap;
+ #endif /* CONFIG_IEEE80211BE */
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0054-mtk-hostapd-WPS-added-change-to-configure-AP-PIN-loc.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0054-mtk-hostapd-WPS-added-change-to-configure-AP-PIN-loc.patch
new file mode 100644
index 0000000..fab7706
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0054-mtk-hostapd-WPS-added-change-to-configure-AP-PIN-loc.patch
@@ -0,0 +1,65 @@
+From 44d5b6d691a45b71d2e8896f3302b4b946ae4d33 Mon Sep 17 00:00:00 2001
+From: "amlendu.mishra" <amlendu.mishra@mediatek.com>
+Date: Wed, 13 Dec 2023 18:13:01 +0530
+Subject: [PATCH 54/54] mtk: hostapd: WPS added change to configure AP PIN lock
+ timout
+
+added config paramter ap_pin_lockout_time to configure
+AP PIN timeout from hosatpd.conf
+
+
+Signed-off-by: amlendu.mishra <amlendu.mishra@mediatek.com>
+---
+ hostapd/config_file.c | 2 ++
+ src/ap/ap_config.h    | 1 +
+ src/ap/wps_hostapd.c  | 9 ++++++---
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index 721685baf..9dd86e037 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -3709,6 +3709,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 		bss->wps_independent = atoi(pos);
+ 	} else if (os_strcmp(buf, "ap_setup_locked") == 0) {
+ 		bss->ap_setup_locked = atoi(pos);
++	} else if (os_strcmp(buf, "ap_pin_lockout_time") == 0) {
++		bss->ap_pin_lockout_time = atoi(pos);
+ 	} else if (os_strcmp(buf, "uuid") == 0) {
+ 		if (uuid_str2bin(pos, bss->uuid)) {
+ 			wpa_printf(MSG_ERROR, "Line %d: invalid UUID", line);
+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
+index 3e0505594..c03fa11b6 100644
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -491,6 +491,7 @@ struct hostapd_bss_config {
+ #ifdef CONFIG_WPS
+ 	int wps_independent;
+ 	int ap_setup_locked;
++	unsigned int ap_pin_lockout_time;
+ 	u8 uuid[16];
+ 	char *wps_pin_requests;
+ 	char *device_name;
+diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
+index 0c351af5f..ea2608917 100644
+--- a/src/ap/wps_hostapd.c
++++ b/src/ap/wps_hostapd.c
+@@ -768,9 +768,12 @@ static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx)
+ 		eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
+ 		wpa_printf(MSG_DEBUG, "WPS: AP PIN disabled indefinitely");
+ 	} else if (!hapd->conf->ap_setup_locked) {
+-		if (hapd->ap_pin_lockout_time == 0)
+-			hapd->ap_pin_lockout_time = 60;
+-		else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
++		if (hapd->ap_pin_lockout_time == 0) {
++			if (hapd->conf->ap_pin_lockout_time)
++				hapd->ap_pin_lockout_time = hapd->conf->ap_pin_lockout_time;
++			else
++				hapd->ap_pin_lockout_time = 60;
++		} else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
+ 			 (hapd->ap_pin_failures % 3) == 0)
+ 			hapd->ap_pin_lockout_time *= 2;
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc b/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
index 600fad1..8ad0077 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
@@ -62,53 +62,58 @@
     file://990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch \
     file://991-Fix-OpenWrt-13156.patch \
     file://992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch \
-    file://mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch \
-    file://mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch \
-    file://mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch \
-    file://mtk-0004-hostapd-mtk-Add-mtk_vendor.h.patch \
-    file://mtk-0005-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch \
-    file://mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch \
-    file://mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch \
-    file://mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch \
-    file://mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch \
-    file://mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch \
-    file://mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
-    file://mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch \
-    file://mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch \
-    file://mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch \
-    file://mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch \
-    file://mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch \
-    file://mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch \
-    file://mtk-0018-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch \
-    file://mtk-0019-hostapd-mtk-Add-available-color-bitmap.patch \
-    file://mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch \
-    file://mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch \
-    file://mtk-0022-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch \
-    file://mtk-0023-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch \
-    file://mtk-0024-hostapd-mtk-Add-muru-user-number-debug-command.patch \
-    file://mtk-0025-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch \
-    file://mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch \
-    file://mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch \
-    file://mtk-0028-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch \
-    file://mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch \
-    file://mtk-0030-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch \
-    file://mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch \
-    file://mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch \
-    file://mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch \
-    file://mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch \
-    file://mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch \
-    file://mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch \
-    file://mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch \
-    file://mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch \
-    file://mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch \
-    file://mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch \
-    file://mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch \
-    file://mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch \
-    file://mtk-1001-hostapd-mtk-update-eht-operation-element.patch \
-    file://mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch \
-    file://mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch \
-    file://mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch \
-    file://mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch \
-    file://mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch \
-    file://mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch \
+    file://mtk-0001-mtk-hostapd-Add-neighbor-report-and-BSS-Termination-.patch \
+    file://mtk-0002-mtk-hostapd-print-sae-groups-by-hostapd-ctrl.patch \
+    file://mtk-0003-mtk-hostapd-add-support-for-runtime-set-in-band-disc.patch \
+    file://mtk-0004-mtk-hostapd-Add-mtk_vendor.h.patch \
+    file://mtk-0005-mtk-hostapd-Support-EDCCA-hostapd-configuration.patch \
+    file://mtk-0006-mtk-hostapd-Add-hostapd-MU-SET-GET-control.patch \
+    file://mtk-0007-mtk-hostapd-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch \
+    file://mtk-0008-mtk-hostapd-Add-hostapd-iBF-control.patch \
+    file://mtk-0009-mtk-hostapd-Do-not-include-HE-capab-IE-if-associated.patch \
+    file://mtk-0010-mtk-hostapd-Add-DFS-detection-mode.patch \
+    file://mtk-0011-mtk-hostapd-Add-DFS-offchan-channel-switch.patch \
+    file://mtk-0012-mtk-hostapd-Add-amsdu-set-get-ctrl.patch \
+    file://mtk-0013-mtk-hostapd-Add-he_ldpc-configuration.patch \
+    file://mtk-0014-mtk-hostapd-Add-vendor-command-attribute-for-RTS-BW-.patch \
+    file://mtk-0015-mtk-hostapd-6G-band-does-not-require-DFS.patch \
+    file://mtk-0016-mtk-hostapd-Fix-sending-wrong-VHT-operation-IE-in-CS.patch \
+    file://mtk-0017-mtk-hostapd-Add-sta-assisted-DFS-state-update-mechan.patch \
+    file://mtk-0018-mtk-hostapd-Mark-DFS-channel-as-available-for-CSA.patch \
+    file://mtk-0019-mtk-hostapd-Add-available-color-bitmap.patch \
+    file://mtk-0020-mtk-hostapd-Fix-ZWDFS-issue-in-BW-160.patch \
+    file://mtk-0021-mtk-hostapd-Add-vendor-for-CAPI-certification-comman.patch \
+    file://mtk-0022-mtk-hostapd-Air-Monitor-support-in-hostapd-by-vendor.patch \
+    file://mtk-0023-mtk-hostapd-Fix-setting-wrong-seg0-index-for-5G-cent.patch \
+    file://mtk-0024-mtk-hostapd-Add-muru-user-number-debug-command.patch \
+    file://mtk-0025-mtk-hostapd-add-connac3-PHY-MURU-manual-mode-config-.patch \
+    file://mtk-0026-mtk-hostapd-Add-HE-capabilities-check.patch \
+    file://mtk-0027-mtk-hostapd-Fix-background-channel-overlapping-opera.patch \
+    file://mtk-0028-mtk-hostapd-Fix-hostapd_dfs_start_cac-log.patch \
+    file://mtk-0029-mtk-hostapd-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch \
+    file://mtk-0030-mtk-hostapd-Update-parameter_set_count-in-MU-EDCA-IE.patch \
+    file://mtk-0031-mtk-hostapd-add-extension-IE-list-for-non-inherit-IE.patch \
+    file://mtk-0032-mtk-hostapd-Fix-rnr-ie-length-when-no-need-to-report.patch \
+    file://mtk-0033-mtk-hostapd-add-back-ht-vht-cap-missing-field-before.patch \
+    file://mtk-0034-mtk-hostapd-update-op_class-when-AP-channel-switchin.patch \
+    file://mtk-0035-mtk-hostapd-Add-support-for-gtk-rekeying-in-hostapd-.patch \
+    file://mtk-0036-mtk-hostapd-Set-WMM-and-TX-queue-parameters-for-wpa_.patch \
+    file://mtk-0037-mtk-hostapd-Set-STA-TX-queue-parameters-configuratio.patch \
+    file://mtk-0038-mtk-hostapd-avoid-color-switch-when-beacon-is-not-se.patch \
+    file://mtk-0039-mtk-hostapd-6g-bss-connect-do-not-consider-ht-operat.patch \
+    file://mtk-0040-mtk-hostapd-avoid-unnecessary-beacon-update-for-6-GH.patch \
+    file://mtk-0041-mtk-hostapd-refactor-the-flow-to-create-Wide-Bandwid.patch \
+    file://mtk-0042-mtk-hostapd-Add-ACS-chanlist-info-in-get_config.patch \
+    file://mtk-0043-mtk-hostapd-Fix-RSNXE-Interop-issue-with-STA.patch \
+    file://mtk-0044-mtk-hostapd-Fix-chan_switch-to-usable-DFS-channel-fa.patch \
+    file://mtk-0045-mtk-hostapd-update-eht-operation-element.patch \
+    file://mtk-0046-mtk-hostapd-ucode-add-support-for-ucode-to-parse-BW3.patch \
+    file://mtk-0047-mtk-hostapd-synchronize-bandwidth-in-AP-STA-support.patch \
+    file://mtk-0048-mtk-hostapd-Add-support-for-updating-background-chan.patch \
+    file://mtk-0049-mtk-hostapd-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch \
+    file://mtk-0050-mtk-hostapd-add-support-enable-disable-preamble-punc.patch \
+    file://mtk-0051-mtk-hostapd-add-no_beacon-vendor-command-for-cert.patch \
+    file://mtk-0052-mtk-hostapd-ACS-Add-EHT320-and-HT40-support-fix-issu.patch \
+    file://mtk-0053-mtk-hostapd-add-eht_bw320_offset-configuration-optio.patch \
+    file://mtk-0054-mtk-hostapd-WPS-added-change-to-configure-AP-PIN-loc.patch \
     "
diff --git a/recipes-wifi/hostapd/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch b/recipes-wifi/hostapd/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch
new file mode 100644
index 0000000..be0bc74
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch
@@ -0,0 +1,172 @@
+From 8df5520f49796e4e292de6895aa0bc518978b377 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:36:59 +0200
+Subject: [PATCH 01/50] ACS: Extract bw40/80/160 freqs out of
+ acs_usable_bwXXX_chan()
+
+This extracts the 3 lists of allowed channels for 40/80/160 MHz
+bandwidth out of their respective functions. It also adds for each
+segment the frequency of the segment's last channel and the index of the
+segment's "center" channel.
+
+This is preparative work to allow selecting a channel which is not the
+first of its segment for 40/80/160 MHz. In addition, this adds the 5 GHz
+160 MHz channel defined for 5735-5895 MHz (channels 149-177).
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 107 ++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 63 insertions(+), 44 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 4a0a4c7..60c90e9 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -241,6 +241,57 @@
+  * [1] http://en.wikipedia.org/wiki/Near_and_far_field
+  */
+ 
++enum bw_type {
++	ACS_BW40,
++	ACS_BW80,
++	ACS_BW160,
++};
++
++struct bw_item {
++	int first;
++	int last;
++	int center_chan;
++};
++
++static const struct bw_item bw_40[] = {
++	{ 5180, 5200, 38 }, { 5220, 5240, 46 }, { 5260, 5280, 54 },
++	{ 5300, 5320, 62 }, { 5500, 5520, 102 }, { 5540, 5560, 110 },
++	{ 5580, 5600, 110 }, { 5620, 5640, 126}, { 5660, 5680, 134 },
++	{ 5700, 5720, 142 }, { 5745, 5765, 151 }, { 5785, 5805, 159 },
++	{ 5825, 5845, 167 }, { 5865, 5885, 175 },
++	{ 5955, 5975, 3 }, { 5995, 6015, 11 }, { 6035, 6055, 19 },
++	{ 6075, 6095, 27 }, { 6115, 6135, 35 }, { 6155, 6175, 43 },
++	{ 6195, 6215, 51 }, { 6235, 6255, 59 }, { 6275, 6295, 67 },
++	{ 6315, 6335, 75 }, { 6355, 6375, 83 }, { 6395, 6415, 91 },
++	{ 6435, 6455, 99 }, { 6475, 6495, 107 }, { 6515, 6535, 115 },
++	{ 6555, 6575, 123 }, { 6595, 6615, 131 }, { 6635, 6655, 139 },
++	{ 6675, 6695, 147 }, { 6715, 6735, 155 }, { 6755, 6775, 163 },
++	{ 6795, 6815, 171 }, { 6835, 6855, 179 }, { 6875, 6895, 187 },
++	{ 6915, 6935, 195 }, { 6955, 6975, 203 }, { 6995, 7015, 211 },
++	{ 7035, 7055, 219 }, { 7075, 7095, 227}, { -1, -1, -1 }
++};
++static const struct bw_item bw_80[] = {
++	{ 5180, 5240, 42 }, { 5260, 5320, 58 }, { 5500, 5560, 106 },
++	{ 5580, 5640, 122 }, { 5660, 5720, 138 }, { 5745, 5805, 155 },
++	{ 5825, 5885, 171},
++	{ 5955, 6015, 7 }, { 6035, 6095, 23 }, { 6115, 6175, 39 },
++	{ 6195, 6255, 55 }, { 6275, 6335, 71 }, { 6355, 6415, 87 },
++	{ 6435, 6495, 103 }, { 6515, 6575, 119 }, { 6595, 6655, 135 },
++	{ 6675, 6735, 151 }, { 6755, 6815, 167 }, { 6835, 6895, 183 },
++	{ 6915, 6975, 199 }, { 6995, 7055, 215 }, { -1, -1, -1 }
++};
++static const struct bw_item bw_160[] = {
++	{ 5180, 5320, 50 }, { 5500, 5640, 114 }, { 5745, 5885, 163 },
++	{ 5955, 6095, 15 }, { 6115, 6255, 47 }, { 6275, 6415, 79 },
++	{ 6435, 6575, 111 }, { 6595, 6735, 143 },
++	{ 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
++};
++static const struct bw_item *bw_desc[] = {
++	[ACS_BW40] = bw_40,
++	[ACS_BW80] = bw_80,
++	[ACS_BW160] = bw_160,
++};
++
+ 
+ static int acs_request_scan(struct hostapd_iface *iface);
+ static int acs_survey_is_sufficient(struct freq_survey *survey);
+@@ -370,50 +421,18 @@ acs_survey_chan_interference_factor(struct hostapd_iface *iface,
+ }
+ 
+ 
+-static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
++static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan,
++			       enum bw_type bw)
+ {
+-	const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620,
+-				5660, 5745, 5785, 4920, 4960, 5955, 5995, 6035,
+-				6075, 6115, 6155, 6195, 6235, 6275, 6315, 6355,
+-				6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675,
+-				6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995,
+-				7035, 7075 };
+-	unsigned int i;
+-
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
+-
+-	return 0;
+-}
+-
+-
+-static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
+-{
+-	const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, 6035,
+-				6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675,
+-				6755, 6835, 6915, 6995 };
+-	unsigned int i;
+-
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
+-
+-	return 0;
+-}
+-
+-
+-static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
+-{
+-	const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755,
+-				6915 };
+-	unsigned int i;
++	unsigned int i = 0;
+ 
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
++	while (bw_desc[bw][i].first != -1) {
++		if (chan->freq == bw_desc[bw][i].first)
++			return true;
++		i++;
++	}
+ 
+-	return 0;
++	return false;
+ }
+ 
+ 
+@@ -705,7 +724,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		    ((iface->conf->ieee80211n &&
+ 		      iface->conf->secondary_channel) ||
+ 		     is_6ghz_freq(chan->freq)) &&
+-		    !acs_usable_bw40_chan(chan)) {
++		    !acs_usable_bw_chan(chan, ACS_BW40)) {
+ 			wpa_printf(MSG_DEBUG,
+ 				   "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth",
+ 				   chan->chan);
+@@ -716,7 +735,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
+ 			if (hostapd_get_oper_chwidth(iface->conf) ==
+ 			    CONF_OPER_CHWIDTH_80MHZ &&
+-			    !acs_usable_bw80_chan(chan)) {
++			    !acs_usable_bw_chan(chan, ACS_BW80)) {
+ 				wpa_printf(MSG_DEBUG,
+ 					   "ACS: Channel %d: not allowed as primary channel for 80 MHz bandwidth",
+ 					   chan->chan);
+@@ -725,7 +744,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 
+ 			if (hostapd_get_oper_chwidth(iface->conf) ==
+ 			    CONF_OPER_CHWIDTH_160MHZ &&
+-			    !acs_usable_bw160_chan(chan)) {
++			    !acs_usable_bw_chan(chan, ACS_BW160)) {
+ 				wpa_printf(MSG_DEBUG,
+ 					   "ACS: Channel %d: not allowed as primary channel for 160 MHz bandwidth",
+ 					   chan->chan);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch b/recipes-wifi/hostapd/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch
new file mode 100644
index 0000000..15e8c98
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch
@@ -0,0 +1,87 @@
+From 3e2fa0f4ab02538c66e61058749272565d94d111 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:00 +0200
+Subject: [PATCH 02/50] ACS: Introduce acs_get_bw_center_chan()
+
+When using 40/80/160 MHz bandwidth, instead of computing the index of
+the segment center freq based on the selected channel, lets look it up
+in the bw_desc[] table.
+
+This is preparative work to allow selecting a primary channel which is
+not the first of the segment.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 33 +++++++++++++++++++++++++++------
+ 1 file changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 60c90e9..511200d 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -436,6 +436,21 @@ static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan,
+ }
+ 
+ 
++static int acs_get_bw_center_chan(int freq, enum bw_type bw)
++{
++	unsigned int i = 0;
++
++	while (bw_desc[bw][i].first != -1) {
++		if (freq >= bw_desc[bw][i].first &&
++		    freq <= bw_desc[bw][i].last)
++			return bw_desc[bw][i].center_chan;
++		i++;
++	}
++
++	return 0;
++}
++
++
+ static int acs_survey_is_sufficient(struct freq_survey *survey)
+ {
+ 	if (!(survey->filled & SURVEY_HAS_NF)) {
+@@ -936,19 +951,26 @@ bw_selected:
+ 
+ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ {
+-	int offset;
++	int center;
+ 
+ 	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
+ 
+ 	switch (hostapd_get_oper_chwidth(iface->conf)) {
+ 	case CONF_OPER_CHWIDTH_USE_HT:
+-		offset = 2 * iface->conf->secondary_channel;
++		if (iface->conf->secondary_channel &&
++		    iface->freq >= 2400 && iface->freq < 2500)
++			center = iface->conf->channel +
++				2 * iface->conf->secondary_channel;
++		else if (iface->conf->secondary_channel)
++			center = acs_get_bw_center_chan(iface->freq, ACS_BW40);
++		else
++			center = iface->conf->channel;
+ 		break;
+ 	case CONF_OPER_CHWIDTH_80MHZ:
+-		offset = 6;
++		center = acs_get_bw_center_chan(iface->freq, ACS_BW80);
+ 		break;
+ 	case CONF_OPER_CHWIDTH_160MHZ:
+-		offset = 14;
++		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
+ 		break;
+ 	default:
+ 		/* TODO: How can this be calculated? Adjust
+@@ -958,8 +980,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ 		return;
+ 	}
+ 
+-	hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
+-					     iface->conf->channel + offset);
++	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, center);
+ }
+ 
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch b/recipes-wifi/hostapd/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch
new file mode 100644
index 0000000..b4ac1f0
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch
@@ -0,0 +1,92 @@
+From 03dd213b918218fec270e781d284ec394fb63ef1 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:01 +0200
+Subject: [PATCH 03/50] ACS: introduce acs_adjust_secondary
+
+When using 40/80/160 MHz bandwidth on the 5 GHz or 6 GHz band, enforce
+the secondary channel to be the other channel of the corresponding 40
+MHz segment.
+
+Even if this is useless for now, this is preparatory work to allow ACS
+to select a primary channel which is not the first of its segment.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 45 insertions(+), 1 deletion(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 511200d..78d1feb 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -634,6 +634,26 @@ acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
+ }
+ 
+ 
++static enum hostapd_hw_mode
++acs_find_mode(struct hostapd_iface *iface, int freq)
++{
++	int i;
++	struct hostapd_hw_modes *mode;
++	struct hostapd_channel_data *chan;
++
++	for (i = 0; i < iface->num_hw_features; i++) {
++		mode = &iface->hw_features[i];
++		if (!hostapd_hw_skip_mode(iface, mode)) {
++			chan = acs_find_chan_mode(mode, freq);
++			if (chan)
++				return mode->mode;
++		}
++	}
++
++	return HOSTAPD_MODE_IEEE80211ANY;
++}
++
++
+ static struct hostapd_channel_data *
+ acs_find_chan(struct hostapd_iface *iface, int freq)
+ {
+@@ -949,6 +969,28 @@ bw_selected:
+ }
+ 
+ 
++static void acs_adjust_secondary(struct hostapd_iface *iface)
++{
++	unsigned int i;
++
++	/* When working with bandwidth over 20 MHz on the 5 GHz or 6 GHz band,
++	 * ACS can return a secondary channel which is not the first channel of
++	 * the segment and we need to adjust. */
++	if (!iface->conf->secondary_channel ||
++	    acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A)
++		return;
++
++	wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency");
++
++	for (i = 0; bw_desc[ACS_BW40][i].first != -1; i++) {
++		if (iface->freq == bw_desc[ACS_BW40][i].first)
++			iface->conf->secondary_channel = 1;
++		else if (iface->freq == bw_desc[ACS_BW40][i].last)
++			iface->conf->secondary_channel = -1;
++	}
++}
++
++
+ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ {
+ 	int center;
+@@ -1036,8 +1078,10 @@ static void acs_study(struct hostapd_iface *iface)
+ 	iface->conf->channel = ideal_chan->chan;
+ 	iface->freq = ideal_chan->freq;
+ 
+-	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax)
++	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
++		acs_adjust_secondary(iface);
+ 		acs_adjust_center_freq(iface);
++	}
+ 
+ 	err = 0;
+ fail:
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch b/recipes-wifi/hostapd/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch
new file mode 100644
index 0000000..8da5856
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch
@@ -0,0 +1,78 @@
+From a615aa302064919791f3912a5cf1a908390414df Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:02 +0200
+Subject: [PATCH 04/50] ACS: Allow selecting a better channel when using
+ 40/80/160 MHz
+
+When considering a channel for a bandwidth of 40/80/160 MHZ on the 5 GHz
+or 6 GHz band, allow selecting one of the other channels in the segment
+instead of the first one. This is done only if the other channel's
+interference_factor is lower than the first one's.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 78d1feb..130e135 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -712,7 +712,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			 struct hostapd_channel_data **ideal_chan,
+ 			 long double *ideal_factor)
+ {
+-	struct hostapd_channel_data *chan, *adj_chan = NULL;
++	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
+ 	long double factor;
+ 	int i, j;
+ 	unsigned int k;
+@@ -720,8 +720,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 	for (i = 0; i < mode->num_channels; i++) {
+ 		double total_weight;
+ 		struct acs_bias *bias, tmp_bias;
++		bool update_best = true;
+ 
+-		chan = &mode->channels[i];
++		best = chan = &mode->channels[i];
+ 
+ 		/* Since in the current ACS implementation the first channel is
+ 		 * always a primary channel, skip channels not available as
+@@ -807,7 +808,15 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			if (acs_usable_chan(adj_chan)) {
+ 				factor += adj_chan->interference_factor;
+ 				total_weight += 1;
++			} else {
++				update_best = false;
+ 			}
++
++			/* find the best channel in this segment */
++			if (update_best &&
++			    adj_chan->interference_factor <
++			    best->interference_factor)
++				best = adj_chan;
+ 		}
+ 
+ 		if (j != n_chans) {
+@@ -816,6 +825,18 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			continue;
+ 		}
+ 
++		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
++		 * crowded primary channel if one was found in the segment */
++		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
++		    chan != best) {
++			wpa_printf(MSG_DEBUG,
++				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
++				   best->chan, chan->chan,
++				   chan->interference_factor,
++				   best->interference_factor);
++			chan = best;
++		}
++
+ 		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
+ 		 * channel interference factor. */
+ 		if (is_24ghz_mode(mode->mode)) {
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch b/recipes-wifi/hostapd/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
index b3f4138..af6eaa5 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
@@ -1,11 +1,11 @@
-From 53a7b7af61b75ea0e3f9d12d3d6302cf40941a8a Mon Sep 17 00:00:00 2001
+From adc0d43ecd5ad2f8932c7a25c6b0e1dea336aef8 Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Tue, 9 Aug 2022 10:23:44 -0700
-Subject: [PATCH 06/37] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH] hostapd: mtk: Add hostapd MU SET/GET control
 
 ---
  hostapd/config_file.c             |   9 +++
- hostapd/ctrl_iface.c              |  62 +++++++++++++++++
+ hostapd/ctrl_iface.c              |  66 ++++++++++++++++++
  hostapd/hostapd_cli.c             |  18 +++++
  src/ap/ap_config.c                |   1 +
  src/ap/ap_config.h                |   1 +
@@ -17,7 +17,7 @@
  src/drivers/driver_nl80211.c      | 110 ++++++++++++++++++++++++++++++
  src/drivers/driver_nl80211.h      |   1 +
  src/drivers/driver_nl80211_capa.c |   3 +
- 13 files changed, 251 insertions(+)
+ 13 files changed, 255 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
 index b5024cc..62e8b33 100644
@@ -40,10 +40,10 @@
  	} else if (os_strcmp(buf, "max_listen_interval") == 0) {
  		bss->max_listen_interval = atoi(pos);
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 9c70d54..c72f336 100644
+index 9c70d54..894c47a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3441,6 +3441,63 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
+@@ -3441,6 +3441,67 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
  }
  
  
@@ -93,6 +93,10 @@
 +	pos = buf;
 +	end = buf + buflen;
 +
++	if (hapd->iface->state != HAPD_IFACE_ENABLED)
++		return os_snprintf(pos, end - pos, "Not allowed to get_mu when current state is %s\n",
++				   hostapd_state_text(hapd->iface->state));
++
 +	if (hostapd_drv_mu_dump(hapd, &mu_onoff) == 0) {
 +		hapd->iconf->mu_onoff = mu_onoff;
 +		return os_snprintf(pos, end - pos, "[hostapd_cli] = UL MU-MIMO: %d, DL MU-MIMO: %d, UL OFDMA: %d, DL OFDMA: %d\n",
@@ -107,7 +111,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -3993,6 +4050,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -3993,6 +4054,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "GET_EDCCA ", 10) == 0) {
  		reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
  							  reply_size);
@@ -156,7 +160,7 @@
  	{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
  	  "report a scanned DPP URI from a QR Code" },
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 344585a..1b0e990 100644
+index 344585a..9e5a2ec 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -280,6 +280,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -446,5 +450,5 @@
  			}
  
 -- 
-2.39.0
+2.18.0
 
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch b/recipes-wifi/hostapd/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
index aa72f2a..03793bb 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
@@ -1,7 +1,7 @@
-From 9b82b5966b57403f389759b6dfb8318dd862b480 Mon Sep 17 00:00:00 2001
+From 8b9963570219d1ba217da21d02fa193ee8aef4ae Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 16 Dec 2022 03:57:11 +0800
-Subject: [PATCH 12/35] hostapd: mtk: Add amsdu set get ctrl
+Subject: [PATCH] hostapd: mtk: Add amsdu set get ctrl
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -40,10 +40,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 37a1b2a..61c9e80 100644
+index fcbc4ae..8ed56e4 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3612,6 +3612,30 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
+@@ -3542,6 +3542,30 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
  }
  
  
@@ -74,10 +74,10 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4176,6 +4200,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4104,6 +4128,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
+ 		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
  								   reply, reply_size);
- 	} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
- 		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
 +	} else if (os_strncmp(buf, "GET_AMSDU", 9) == 0) {
 +		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
  	} else {
@@ -111,7 +111,7 @@
  };
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index df90814..24fc0f5 100644
+index c47418a..b351edb 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -299,6 +299,7 @@ struct hostapd_config * hostapd_config_defaults(void)
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch b/recipes-wifi/hostapd/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
index 1b23579..6f4425f 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
@@ -1,7 +1,7 @@
-From 9b40b6ccf6fd2f4463b389df46d38610001df04e Mon Sep 17 00:00:00 2001
+From 2e7919e5e52fefa14a48e77fd739ef05371a26c9 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Thu, 26 Jan 2023 09:16:00 +0800
-Subject: [PATCH 22/35] hostapd: mtk: Add available color bitmap
+Subject: [PATCH] hostapd: mtk: Add available color bitmap
 
 Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 ---
@@ -17,10 +17,10 @@
  9 files changed, 192 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 9ba6992..e1e9270 100644
+index 2b7ac96..549c93a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3645,6 +3645,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
+@@ -3575,6 +3575,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
  	return ret;
  }
  
@@ -97,8 +97,8 @@
  
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
-@@ -4212,6 +4282,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
+@@ -4140,6 +4210,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 								   reply, reply_size);
  	} else if (os_strncmp(buf, "GET_AMSDU", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
 +	} else if (os_strncmp(buf, "GET_BSS_COLOR", 13) == 0) {
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch b/recipes-wifi/hostapd/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch
new file mode 100644
index 0000000..d968859
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch
@@ -0,0 +1,283 @@
+From 920a20927f1537ae2a6ce9c7123ef189e83cd0a0 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Sat, 11 Nov 2023 11:42:59 +0800
+Subject: [PATCH] hostapd: mtk: ACS: Fix 2.4GHz HT40 case and channel switch
+ fail
+
+Issue#1. Add 2.4G HT40- support
+1. Add 2.4G HT40- support
+2. Fix issue: selected best channel is out of channels
+
+Issue#2. Fix chan_switch to usable DFS channel fail due to ACS
+
+Step and issue:
+1. Enable ACS in hostapd config;
+2. Bootup and then use hostapd_cli cmd switch channel to a DFS channel;
+3. Will do ACS again, and no work on channel specified in step 2.
+
+Root cause:
+When need do DFS-CAC, hostapd will do intf disable, then set the new
+channel into running config settings, and finally enable intf;
+In the test case, new DFS channel is set to runnint config settings, but
+another param "acs" is still 1 (enable), caused the ACS running when
+intf enabled.
+---
+ src/ap/acs.c     | 142 ++++++++++++++++++++++++++---------------------
+ src/ap/hostapd.c |   3 +
+ 2 files changed, 83 insertions(+), 62 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 130e135..65573b9 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -712,10 +712,19 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			 struct hostapd_channel_data **ideal_chan,
+ 			 long double *ideal_factor)
+ {
+-	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
++	struct hostapd_channel_data *chan, *adj_chan = NULL, *tmp_chan = NULL, *best;
+ 	long double factor;
+ 	int i, j;
+ 	unsigned int k;
++	int ht40_plus = 1, sec_ch_factor = 1;
++
++	if (is_24ghz_mode(mode->mode)) {
++		ht40_plus = (iface->conf->secondary_channel == -1) ? 0 : 1;
++		sec_ch_factor = (iface->conf->secondary_channel == -1) ? -1 : 1;
++	}
++
++	wpa_printf(MSG_INFO, "%s:%d, bw(%u), n_chans(%d), num_channels(%d), sec_ch(%d)",
++		__func__, __LINE__, bw, n_chans, mode->num_channels, iface->conf->secondary_channel);
+ 
+ 	for (i = 0; i < mode->num_channels; i++) {
+ 		double total_weight;
+@@ -723,6 +732,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		bool update_best = true;
+ 
+ 		best = chan = &mode->channels[i];
++		wpa_printf(MSG_INFO,
++			   "ACS: Channel[%d] %d: interference_factor %Lg",
++			   i, chan->chan, chan->interference_factor);
+ 
+ 		/* Since in the current ACS implementation the first channel is
+ 		 * always a primary channel, skip channels not available as
+@@ -747,7 +759,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		if (chan->flag & HOSTAPD_CHAN_INDOOR_ONLY && iface->conf->country[2] == 0x4f)
+ 			continue;
+ 
+-		if (!chan_bw_allowed(chan, bw, 1, 1)) {
++		if (!chan_bw_allowed(chan, bw, ht40_plus, 1)) {
+ 			wpa_printf(MSG_DEBUG,
+ 				   "ACS: Channel %d: BW %u is not supported",
+ 				   chan->chan, bw);
+@@ -789,60 +801,73 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		}
+ 
+ 		factor = 0;
+-		if (acs_usable_chan(chan))
+-			factor = chan->interference_factor;
+-		total_weight = 1;
+-
+-		for (j = 1; j < n_chans; j++) {
+-			adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
+-			if (!adj_chan)
+-				break;
++		total_weight = 0;
+ 
+-			if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
+-				wpa_printf(MSG_DEBUG,
+-					   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
+-					   chan->chan, adj_chan->chan, bw);
+-				break;
+-			}
+-
+-			if (acs_usable_chan(adj_chan)) {
+-				factor += adj_chan->interference_factor;
++		if (!is_24ghz_mode(mode->mode)) {
++			/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
++			 * crowded primary channel if one was found in the segment */
++			if (acs_usable_chan(chan)) {
++				factor += chan->interference_factor;
+ 				total_weight += 1;
+-			} else {
+-				update_best = false;
+ 			}
+ 
+-			/* find the best channel in this segment */
+-			if (update_best &&
+-			    adj_chan->interference_factor <
+-			    best->interference_factor)
+-				best = adj_chan;
+-		}
++			for (j = 1; j < n_chans; j++) {
++				adj_chan = acs_find_chan(iface, chan->freq + j * 20);
++				if (!adj_chan)
++					break;
+ 
+-		if (j != n_chans) {
+-			wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
+-				   chan->chan);
+-			continue;
+-		}
++				if (!is_in_chanlist(iface, adj_chan) || !is_in_freqlist(iface, adj_chan))
++					break;
+ 
+-		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
+-		 * crowded primary channel if one was found in the segment */
+-		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+-		    chan != best) {
+-			wpa_printf(MSG_DEBUG,
+-				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
+-				   best->chan, chan->chan,
+-				   chan->interference_factor,
+-				   best->interference_factor);
+-			chan = best;
+-		}
++				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
++					wpa_printf(MSG_DEBUG,
++						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
++						   chan->chan, adj_chan->chan, bw);
++					break;
++				}
+ 
+-		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
+-		 * channel interference factor. */
+-		if (is_24ghz_mode(mode->mode)) {
++				update_best = true;
++				if (acs_usable_chan(adj_chan)) {
++					factor += adj_chan->interference_factor;
++					total_weight += 1;
++				} else {
++					update_best = false;
++				}
++
++				/* find the best channel in this segment */
++				if (update_best &&
++					adj_chan->interference_factor < best->interference_factor)
++					best = adj_chan;
++			}
++
++			if (j != n_chans) {
++				wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
++					   chan->chan);
++				continue;
++			}
++
++			if (chan != best) {
++				wpa_printf(MSG_INFO,
++					   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
++					   best->chan, chan->chan,
++					   chan->interference_factor,
++					   best->interference_factor);
++				chan = best;
++			}
++		} else {
+ 			for (j = 0; j < n_chans; j++) {
++				/* Will set primary_channel / secondary_channel(40M case) weight to 1 */
++				tmp_chan = acs_find_chan(iface, chan->freq +
++							 (j * sec_ch_factor * 20));
++				if (tmp_chan && acs_usable_chan(tmp_chan)) {
++					factor += tmp_chan->interference_factor;
++					total_weight += 1;
++				}
++
++				/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent channel
++				interference factor, separately for primary/secondary channel. */
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) - 5);
++							  (j * sec_ch_factor * 20) - 5);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -850,7 +875,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) - 10);
++							  (j * sec_ch_factor * 20) - 10);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_NEXT_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -858,7 +883,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) + 5);
++							 (j * sec_ch_factor * 20) + 5);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -866,7 +891,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) + 10);
++							 (j * sec_ch_factor * 20) + 10);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_NEXT_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -875,7 +900,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			}
+ 		}
+ 
+-		factor /= total_weight;
++		if (total_weight)
++			factor /= total_weight;
+ 
+ 		bias = NULL;
+ 		if (iface->conf->acs_chan_bias) {
+@@ -894,11 +920,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 
+ 		if (bias) {
+ 			factor *= bias->bias;
+-			wpa_printf(MSG_DEBUG,
++			wpa_printf(MSG_INFO,
+ 				   "ACS:  * channel %d: total interference = %Lg (%f bias)",
+ 				   chan->chan, factor, bias->bias);
+ 		} else {
+-			wpa_printf(MSG_DEBUG,
++			wpa_printf(MSG_INFO,
+ 				   "ACS:  * channel %d: total interference = %Lg",
+ 				   chan->chan, factor);
+ 		}
+@@ -939,14 +965,6 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+ 		goto bw_selected;
+ 	}
+ 
+-	/* TODO: HT40- support */
+-
+-	if (iface->conf->ieee80211n &&
+-	    iface->conf->secondary_channel == -1) {
+-		wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
+-		return NULL;
+-	}
+-
+ 	if (iface->conf->ieee80211n &&
+ 	    iface->conf->secondary_channel)
+ 		n_chans = 2;
+@@ -981,7 +999,7 @@ bw_selected:
+ 	}
+ 
+ 	if (ideal_chan) {
+-		wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
++		wpa_printf(MSG_INFO, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
+ 			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
+ 		return ideal_chan;
+ 	}
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index f2eb638..250c168 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -3895,6 +3895,9 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+ 
+ 	iface->freq = freq_params->freq;
+ 	iface->conf->channel = freq_params->channel;
++	if (iface->conf->channel != 0) /* If channel not zero, will disable acs. */
++		iface->conf->acs = 0;
++
+ 	iface->conf->secondary_channel = freq_params->sec_channel_offset;
+ 	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
+ 	hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch b/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch
similarity index 90%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
rename to recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch
index c247137..1937640 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch
@@ -1,8 +1,7 @@
-From 31d7b7fe98e3d5d0e2769bd7ea22e529a7f1295d Mon Sep 17 00:00:00 2001
+From 99159b174eb245a7162fe38900971cdff017cf75 Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Thu, 13 Jul 2023 13:14:26 +0800
-Subject: [PATCH 29/38] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
- failed
+Subject: [PATCH] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF failed
 
 If ioctl returns EBUSY on command SIOCBRADDIF, the interface might
 already be bridged by others, and linux_br_add_if should not indicate an
@@ -52,5 +51,5 @@
  
  	return 0;
 -- 
-2.18.0
+2.25.1
 
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch b/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
new file mode 100644
index 0000000..82b66f4
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
@@ -0,0 +1,135 @@
+From 018d87d5b9b53b3e630032bf2cb7e6eaeae09d71 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 15 Nov 2023 15:06:00 +0800
+Subject: [PATCH 47/49] hostapd: mtk: add support for channel switching to dfs
+ with csa sent
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ hostapd/ctrl_iface.c | 26 ++------------------------
+ src/ap/beacon.c      |  5 +++++
+ src/ap/dfs.c         | 16 ++++++++++++----
+ src/ap/ieee802_11.c  |  5 +++++
+ 4 files changed, 24 insertions(+), 28 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index b521a08..0afa6a2 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -2747,7 +2747,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 	int dfs_range = 0;
+ 	unsigned int i;
+ 	int bandwidth;
+-	u8 chan;
+ 
+ 	ret = hostapd_parse_csa_settings(pos, &settings);
+ 	if (ret)
+@@ -2809,29 +2808,8 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 			iface, bandwidth, settings.freq_params.center_freq2);
+ 
+ 	if (dfs_range) {
+-		ret = ieee80211_freq_to_chan(settings.freq_params.freq, &chan);
+-		if (ret == NUM_HOSTAPD_MODES) {
+-			wpa_printf(MSG_ERROR,
+-				   "Failed to get channel for (freq=%d, sec_channel_offset=%d, bw=%d)",
+-				   settings.freq_params.freq,
+-				   settings.freq_params.sec_channel_offset,
+-				   settings.freq_params.bandwidth);
+-			return -1;
+-		}
+-
+-		settings.freq_params.channel = chan;
+-
+-		wpa_printf(MSG_DEBUG,
+-			   "DFS/CAC to (channel=%u, freq=%d, sec_channel_offset=%d, bw=%d, center_freq1=%d)",
+-			   settings.freq_params.channel,
+-			   settings.freq_params.freq,
+-			   settings.freq_params.sec_channel_offset,
+-			   settings.freq_params.bandwidth,
+-			   settings.freq_params.center_freq1);
+-
+-		/* Perform CAC and switch channel */
+-		hostapd_switch_channel_fallback(iface, &settings.freq_params);
+-		return 0;
++		settings.cs_count = 5;
++		settings.block_tx = 1;
+ 	}
+ 
+ 	for (i = 0; i < iface->num_bss; i++) {
+diff --git a/src/ap/beacon.c b/src/ap/beacon.c
+index 02f4f87..f9c4924 100644
+--- a/src/ap/beacon.c
++++ b/src/ap/beacon.c
+@@ -2027,6 +2027,11 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
+ 		return -1;
+ 	}
+ 
++	if (iface->cac_started) {
++		wpa_printf(MSG_DEBUG, "Ignore set beacons during CAC period");
++		return 0;
++	}
++
+ 	hapd->beacon_set_done = 1;
+ 
+ 	if (ieee802_11_build_ap_params(hapd, &params) < 0)
+diff --git a/src/ap/dfs.c b/src/ap/dfs.c
+index 80d3605..012050c 100644
+--- a/src/ap/dfs.c
++++ b/src/ap/dfs.c
+@@ -1255,10 +1255,10 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
+ 			 * another radio.
+ 			 */
+ 			if (iface->state != HAPD_IFACE_ENABLED &&
+-			    hostapd_is_dfs_chan_available(iface)) {
++			    hostapd_is_dfs_chan_available(iface))
+ 				hostapd_setup_interface_complete(iface, 0);
+-				iface->cac_started = 0;
+-			}
++
++			iface->cac_started = 0;
+ 
+ 			/*
+ 			 * When background radar is enabled but the CAC completion
+@@ -1272,6 +1272,13 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
+ 	} else if (hostapd_dfs_is_background_event(iface, freq)) {
+ 		iface->radar_background.cac_started = 0;
+ 		hostpad_dfs_update_background_chain(iface);
++	} else {
++		int i;
++
++		iface->cac_started = 0;
++		/* Clear all CSA flags once channel switch to DFS channel fails */
++		for (i = 0; i < iface->num_bss; i++)
++			iface->bss[i]->csa_in_progress = 0;
+ 	}
+ 
+ 	return 0;
+@@ -1646,7 +1653,8 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+ 	} else {
+ 		/* This is called when the driver indicates that an offloaded
+ 		 * DFS has started CAC. */
+-		hostapd_set_state(iface, HAPD_IFACE_DFS);
++		if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
++			hostapd_set_state(iface, HAPD_IFACE_DFS);
+ 		iface->cac_started = 1;
+ 	}
+ 	/* TODO: How to check CAC time for ETSI weather channels? */
+diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
+index 01ceb79..dd477fd 100644
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -6352,6 +6352,11 @@ int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
+ 		return 1;
+ 	}
+ 
++	if (hapd->iface->cac_started) {
++		wpa_printf(MSG_DEBUG, "MGMT: Ignore management frame during CAC");
++		return 1;
++	}
++
+ 	if (stype == WLAN_FC_STYPE_PROBE_REQ) {
+ 		handle_probe_req(hapd, mgmt, len, ssi_signal);
+ 		return 1;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch b/recipes-wifi/hostapd/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch
new file mode 100644
index 0000000..0dbdaca
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch
@@ -0,0 +1,409 @@
+From a0538a9373ec7def76048e020fcb6ecfec53f3db Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 16 Nov 2023 13:18:48 +0800
+Subject: [PATCH] hostapd: mtk: add support for channel switching with csa sent
+ when background radar is enabled
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ hostapd/ctrl_iface.c   |  82 +++++++++++++++++-----
+ src/ap/ctrl_iface_ap.c |   5 +-
+ src/ap/dfs.c           | 156 +++++++++++++++++++++++++++++++++++------
+ src/ap/dfs.h           |   9 ++-
+ 4 files changed, 212 insertions(+), 40 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index 0afa6a2..44903e0 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -2742,11 +2742,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 					  char *pos)
+ {
+ #ifdef NEED_AP_MLME
+-	struct csa_settings settings;
++	struct csa_settings settings, background_settings;
+ 	int ret;
+-	int dfs_range = 0;
++	int freq, state;
+ 	unsigned int i;
+-	int bandwidth;
++	int bandwidth, oper_chwidth;
++	bool background_radar, bw_changed, cac_required = false;
+ 
+ 	ret = hostapd_parse_csa_settings(pos, &settings);
+ 	if (ret)
+@@ -2762,21 +2763,28 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 	switch (settings.freq_params.bandwidth) {
+ 	case 40:
+ 		bandwidth = CHAN_WIDTH_40;
++		oper_chwidth = CONF_OPER_CHWIDTH_USE_HT;
+ 		break;
+ 	case 80:
+-		if (settings.freq_params.center_freq2)
++		if (settings.freq_params.center_freq2) {
+ 			bandwidth = CHAN_WIDTH_80P80;
+-		else
++			oper_chwidth = CONF_OPER_CHWIDTH_80P80MHZ;
++		} else {
+ 			bandwidth = CHAN_WIDTH_80;
++			oper_chwidth = CONF_OPER_CHWIDTH_80MHZ;
++		}
+ 		break;
+ 	case 160:
+ 		bandwidth = CHAN_WIDTH_160;
++		oper_chwidth = CONF_OPER_CHWIDTH_160MHZ;
+ 		break;
+ 	case 320:
+ 		bandwidth = CHAN_WIDTH_320;
++		oper_chwidth = CONF_OPER_CHWIDTH_320MHZ;
+ 		break;
+ 	default:
+ 		bandwidth = CHAN_WIDTH_20;
++		oper_chwidth = CONF_OPER_CHWIDTH_USE_HT;
+ 		break;
+ 	}
+ 
+@@ -2797,19 +2805,29 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 	}
+ 
+ 	if (settings.freq_params.center_freq1)
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.center_freq1);
++		freq = settings.freq_params.center_freq1;
+ 	else
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.freq);
+-
+-	if (settings.freq_params.center_freq2)
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.center_freq2);
+-
+-	if (dfs_range) {
+-		settings.cs_count = 5;
+-		settings.block_tx = 1;
++		freq = settings.freq_params.freq;
++
++	bw_changed = oper_chwidth != hostapd_get_oper_chwidth(iface->conf);
++	state = hostapd_dfs_get_target_state(iface, bandwidth, freq,
++					     settings.freq_params.center_freq2);
++	switch (state) {
++	case HOSTAPD_CHAN_DFS_USABLE:
++		cac_required = true;
++		/* fallthrough */
++	case HOSTAPD_CHAN_DFS_AVAILABLE:
++		background_radar = hostapd_dfs_handle_csa(iface, &settings,
++							  &background_settings,
++							  cac_required,
++							  bw_changed);
++		break;
++	case HOSTAPD_CHAN_DFS_UNAVAILABLE:
++		wpa_printf(MSG_INFO,
++			   "chanswitch: target channel is UNAVAILABLE, so stop switching");
++		return -1;
++	default:
++		break;
+ 	}
+ 
+ 	for (i = 0; i < iface->num_bss; i++) {
+@@ -2826,6 +2844,36 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 		}
+ 	}
+ 
++	if (background_radar) {
++		u8 seg0, seg1;
++
++		ieee80211_freq_to_chan(background_settings.freq_params.center_freq1, &seg0);
++		ieee80211_freq_to_chan(background_settings.freq_params.center_freq2, &seg1);
++		ret = hostapd_start_dfs_cac(iface, iface->conf->hw_mode,
++					    background_settings.freq_params.freq,
++					    background_settings.freq_params.channel,
++					    background_settings.freq_params.ht_enabled,
++					    background_settings.freq_params.vht_enabled,
++					    background_settings.freq_params.he_enabled,
++					    background_settings.freq_params.eht_enabled,
++					    background_settings.freq_params.sec_channel_offset,
++					    oper_chwidth, seg0, seg1, true);
++		if (ret) {
++			wpa_printf(MSG_ERROR, "Background radar start dfs cac failed, %d",
++				   ret);
++			iface->radar_background.channel = -1;
++			return -1;
++		}
++
++		/* Cache background radar parameters. */
++		iface->radar_background.channel = background_settings.freq_params.channel;
++		iface->radar_background.secondary_channel =
++			background_settings.freq_params.sec_channel_offset;
++		iface->radar_background.freq = background_settings.freq_params.freq;
++		iface->radar_background.centr_freq_seg0_idx = seg0;
++		iface->radar_background.centr_freq_seg1_idx = seg1;
++	}
++
+ 	return 0;
+ #else /* NEED_AP_MLME */
+ 	return -1;
+diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
+index 86e8729..005c9fa 100644
+--- a/src/ap/ctrl_iface_ap.c
++++ b/src/ap/ctrl_iface_ap.c
+@@ -907,6 +907,7 @@ int hostapd_parse_csa_settings(const char *pos,
+ 			       struct csa_settings *settings)
+ {
+ 	char *end;
++	int ret;
+ 
+ 	os_memset(settings, 0, sizeof(*settings));
+ 	settings->cs_count = strtol(pos, &end, 10);
+@@ -916,7 +917,9 @@ int hostapd_parse_csa_settings(const char *pos,
+ 	}
+ 
+ 	settings->freq_params.freq = atoi(end);
+-	if (settings->freq_params.freq == 0) {
++	ret = ieee80211_freq_to_chan(settings->freq_params.freq,
++				     &settings->freq_params.channel);
++	if (ret == NUM_HOSTAPD_MODES) {
+ 		wpa_printf(MSG_ERROR, "chanswitch: invalid freq provided");
+ 		return -1;
+ 	}
+diff --git a/src/ap/dfs.c b/src/ap/dfs.c
+index 012050c..5108e0a 100644
+--- a/src/ap/dfs.c
++++ b/src/ap/dfs.c
+@@ -248,14 +248,15 @@ static int is_in_chanlist(struct hostapd_iface *iface,
+  */
+ static int dfs_find_channel(struct hostapd_iface *iface,
+ 			    struct hostapd_channel_data **ret_chan,
+-			    int idx, enum dfs_channel_type type)
++			    int n_chans, int idx, enum dfs_channel_type type)
+ {
+ 	struct hostapd_hw_modes *mode;
+ 	struct hostapd_channel_data *chan;
+-	int i, channel_idx = 0, n_chans, n_chans1;
++	int i, channel_idx = 0, n_chans1;
+ 
+ 	mode = iface->current_mode;
+-	n_chans = dfs_get_used_n_chans(iface, &n_chans1);
++	if (!n_chans)
++		n_chans = dfs_get_used_n_chans(iface, &n_chans1);
+ 
+ 	wpa_printf(MSG_DEBUG, "DFS new chan checking %d channels", n_chans);
+ 	for (i = 0; i < mode->num_channels; i++) {
+@@ -548,7 +549,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		return NULL;
+ 
+ 	/* Get the count first */
+-	num_available_chandefs = dfs_find_channel(iface, NULL, 0, type);
++	num_available_chandefs = dfs_find_channel(iface, NULL, 0, 0, type);
+ 	wpa_printf(MSG_DEBUG, "DFS: num_available_chandefs=%d",
+ 		   num_available_chandefs);
+ 	if (num_available_chandefs == 0)
+@@ -569,7 +570,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		return NULL;
+ 
+ 	chan_idx = _rand % num_available_chandefs;
+-	dfs_find_channel(iface, &chan, chan_idx, type);
++	dfs_find_channel(iface, &chan, 0, chan_idx, type);
+ 	if (!chan) {
+ 		wpa_printf(MSG_DEBUG, "DFS: no random channel found");
+ 		return NULL;
+@@ -599,7 +600,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		for (i = 0; i < num_available_chandefs - 1; i++) {
+ 			/* start from chan_idx + 1, end when chan_idx - 1 */
+ 			chan_idx2 = (chan_idx + 1 + i) % num_available_chandefs;
+-			dfs_find_channel(iface, &chan2, chan_idx2, type);
++			dfs_find_channel(iface, &chan2, 0, chan_idx2, type);
+ 			if (chan2 && abs(chan2->chan - chan->chan) > 12) {
+ 				/* two channels are not adjacent */
+ 				sec_chan_idx_80p80 = chan2->chan;
+@@ -1302,6 +1303,9 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq,
+ 	set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width,
+ 		      cf1, cf2, HOSTAPD_CHAN_DFS_USABLE);
+ 
++	if (dfs_use_radar_background(iface) && iface->radar_background.channel == -1)
++		hostpad_dfs_update_background_chain(iface);
++
+ 	return 0;
+ }
+ 
+@@ -1715,14 +1719,15 @@ int hostapd_handle_dfs_offload(struct hostapd_iface *iface)
+ }
+ 
+ 
+-int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+-			   int center_freq)
++int hostapd_dfs_get_target_state(struct hostapd_iface *iface, enum chan_width width,
++				 int center_freq, int center_freq2)
+ {
+ 	struct hostapd_channel_data *chan;
+ 	struct hostapd_hw_modes *mode = iface->current_mode;
+-	int half_width;
+-	int res = 0;
++	int half_width, chan_state, state = 0;
++	int upper, lower;
+ 	int i;
++	bool in_range;
+ 
+ 	if (!iface->conf->ieee80211h || !mode ||
+ 	    mode->mode != HOSTAPD_MODE_IEEE80211A)
+@@ -1755,18 +1760,129 @@ int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+ 		if (!(chan->flag & HOSTAPD_CHAN_RADAR))
+ 			continue;
+ 
+-		if ((chan->flag & HOSTAPD_CHAN_DFS_MASK) ==
+-		    HOSTAPD_CHAN_DFS_AVAILABLE)
+-			continue;
++		upper = chan->freq + half_width;
++		lower = chan->freq - half_width;
++		in_range = (lower < center_freq && center_freq < upper) ||
++			   (center_freq2 && (lower < center_freq2 && center_freq2 < upper));
++		if (in_range) {
++			chan_state = chan->flag & HOSTAPD_CHAN_DFS_MASK;
++			switch (chan_state) {
++			case HOSTAPD_CHAN_DFS_USABLE:
++				state = HOSTAPD_CHAN_DFS_USABLE;
++				break;
++			case HOSTAPD_CHAN_DFS_AVAILABLE:
++				if (state != HOSTAPD_CHAN_DFS_USABLE)
++					state = HOSTAPD_CHAN_DFS_AVAILABLE;
++				break;
++			case HOSTAPD_CHAN_DFS_UNKNOWN:
++				wpa_printf(MSG_WARNING, "chan %d DFS state: UNKNOWN",
++					   chan->freq);
++				/* fallthrough */
++			case HOSTAPD_CHAN_DFS_UNAVAILABLE:
++			default:
++				return HOSTAPD_CHAN_DFS_UNAVAILABLE;
++			}
++		}
++	}
+ 
+-		if (center_freq - chan->freq < half_width &&
+-		    chan->freq - center_freq < half_width)
+-			res++;
++	wpa_printf(MSG_DEBUG, "freq range (%d, %d) has DFS state %d",
++		   center_freq - half_width, center_freq + half_width, state);
++
++	return state;
++}
++
++
++static struct hostapd_channel_data *
++dfs_get_csa_channel(struct hostapd_iface *iface,
++		    int n_chans, int cur_center,
++		    enum dfs_channel_type type)
++{
++	struct hostapd_channel_data *chan;
++	int avail_chan_num;
++	u32 _rand, idx;
++
++	if (os_get_random((u8 *)&_rand, sizeof(_rand)) < 0)
++		return NULL;
++
++	avail_chan_num = dfs_find_channel(iface, NULL, n_chans, 0, type);
++	if (!avail_chan_num)
++		return NULL;
++
++	idx = _rand % avail_chan_num;
++	dfs_find_channel(iface, &chan, n_chans, idx, type);
++	if (cur_center == chan->freq + (n_chans - 1) * 10) {
++		if (avail_chan_num == 1)
++			return NULL;
++
++		/* Get the next channel if the found channel is same as current channel */
++		idx = (idx + 1) % avail_chan_num;
++		dfs_find_channel(iface, &chan, n_chans, idx, type);
+ 	}
+ 
+-	wpa_printf(MSG_DEBUG, "DFS CAC required: (%d, %d): in range: %s",
+-		   center_freq - half_width, center_freq + half_width,
+-		   res ? "yes" : "no");
++	return chan;
++}
+ 
+-	return res;
++
++/*
++ * DFS handler for CSA
++ * 1  - update background radar with the filled setting
++ * 0  - background radar is not enabled / background radar remain at the same channel /
++ *	disable background radar
++ */
++int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
++			   struct csa_settings *settings,
++			   struct csa_settings *background_settings,
++			   bool cac_required, bool bw_changed)
++{
++	struct hostapd_channel_data *chan;
++	struct hostapd_freq_params *freq_params = &settings->freq_params;
++	int center = settings->freq_params.center_freq1;
++	int background_center = 5000 + iface->radar_background.centr_freq_seg0_idx * 5;
++	int n_chans = settings->freq_params.bandwidth / 20;
++	bool update_background = false;
++
++	if (!dfs_use_radar_background(iface)) {
++		settings->cs_count = 5;
++		settings->block_tx = cac_required;
++		return 0;
++	}
++
++	if (!cac_required) {
++		if (!bw_changed && center != background_center)
++			return 0;
++		/* Update background radar due to bw change or channel overlapping */
++		update_background = true;
++	} else {
++		/*
++		* Get available channel for main channel.
++		* If no available channel for main channel, then perform
++		* the CAC of target channel on the main channel, and select
++		* an usable channel for background radar.
++		*/
++		iface->radar_background.temp_ch = 1;
++		chan = dfs_get_csa_channel(iface, n_chans, 0, DFS_AVAILABLE);
++		if (!chan)
++			update_background = true;
++	}
++
++	if (update_background) {
++		chan = dfs_get_csa_channel(iface, n_chans, center, DFS_NO_CAC_YET);
++		if (!chan)
++			goto bkg_disable;
++		freq_params = &background_settings->freq_params;
++		iface->radar_background.temp_ch = 0;
++	}
++
++	memcpy(background_settings, settings, sizeof(*settings));
++	freq_params->freq = chan->freq;
++	freq_params->channel = chan->chan;
++	freq_params->sec_channel_offset = 1;
++	freq_params->center_freq1 = chan->freq + (n_chans - 1) * 10;
++	freq_params->center_freq2 = 0;
++
++	return 1;
++
++bkg_disable:
++	iface->radar_background.channel = -1;
++	return 0;
+ }
+diff --git a/src/ap/dfs.h b/src/ap/dfs.h
+index 1a0791f..0a7c25d 100644
+--- a/src/ap/dfs.h
++++ b/src/ap/dfs.h
+@@ -33,7 +33,12 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+ 			  int ht_enabled, int chan_offset, int chan_width,
+ 			  int cf1, int cf2);
+ int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
+-int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+-			   int center_freq);
++int hostapd_dfs_get_target_state(struct hostapd_iface *iface, enum chan_width width,
++				 int center_freq, int center_freq2);
++int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
++			   struct csa_settings *settings,
++			   struct csa_settings *background_settings,
++			   bool cac_required, bool bw_changed);
++
+ 
+ #endif /* DFS_H */
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch b/recipes-wifi/hostapd/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
similarity index 80%
rename from recipes-wifi/hostapd/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
rename to recipes-wifi/hostapd/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
index 69f3fa2..bfd66a3 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
@@ -1,7 +1,7 @@
-From b087dbc78f6911b16c9c00ac0a9246a89871225f Mon Sep 17 00:00:00 2001
+From 49f5a5c4430e59dec7dc135773636da2e889ce05 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 14:56:55 +0800
-Subject: [PATCH 11/35] hostapd: mtk: Add DFS offchan channel switch
+Subject: [PATCH 49/49] hostapd: mtk: Add DFS offchan channel switch
 
 Add DFS background chain channel switch command for testing purpose.
 This feature is implemented via hostapd_cli command.
@@ -12,17 +12,17 @@
 ---
  hostapd/ctrl_iface.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
  src/ap/dfs.c         | 25 ++++++---------
- src/ap/dfs.h         | 15 +++++++++
- 3 files changed, 96 insertions(+), 16 deletions(-)
+ src/ap/dfs.h         | 16 +++++++++-
+ 3 files changed, 96 insertions(+), 17 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index fcbc4ae..37a1b2a 100644
+index 328f7c2..97d807a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3542,6 +3542,76 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
+@@ -3951,6 +3951,76 @@ hostapd_ctrl_iface_dump_amnt(struct hostapd_data *hapd, char *cmd,
+ 		return pos - buf;
  }
  
- 
 +static int
 +hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
 +				    char *buf, size_t buflen)
@@ -48,9 +48,9 @@
 +	else
 +		return -1;
 +
-+	num_available_chandefs = dfs_find_channel(iface, NULL, 0, type);
++	num_available_chandefs = dfs_find_channel(iface, NULL, 0, 0, type);
 +	for (i = 0; i < num_available_chandefs; i++) {
-+		dfs_find_channel(iface, &chan, i, type);
++		dfs_find_channel(iface, &chan, 0, i, type);
 +		if (chan->chan == channel) {
 +			chan_found = true;
 +			break;
@@ -96,17 +96,17 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4104,6 +4174,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
- 		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
- 								   reply, reply_size);
+@@ -4529,6 +4599,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
+ 		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
+ 							reply, reply_size);
 +	} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
 +		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
  	} else {
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 5cb7799..1c3f678 100644
+index a558d4e..bb5702b 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -19,13 +19,6 @@
@@ -123,20 +123,20 @@
  static struct hostapd_channel_data *
  dfs_downgrade_bandwidth(struct hostapd_iface *iface, int *secondary_channel,
  			u8 *oper_centr_freq_seg0_idx,
-@@ -238,9 +231,9 @@ static int is_in_chanlist(struct hostapd_iface *iface,
+@@ -246,9 +239,9 @@ static int is_in_chanlist(struct hostapd_iface *iface,
   *  - hapd->vht/he_oper_centr_freq_seg0_idx
   *  - hapd->vht/he_oper_centr_freq_seg1_idx
   */
 -static int dfs_find_channel(struct hostapd_iface *iface,
 -			    struct hostapd_channel_data **ret_chan,
--			    int idx, enum dfs_channel_type type)
+-			    int n_chans, int idx, enum dfs_channel_type type)
 +int dfs_find_channel(struct hostapd_iface *iface,
 +		     struct hostapd_channel_data **ret_chan,
-+		     int idx, enum dfs_channel_type type)
++		     int n_chans, int idx, enum dfs_channel_type type)
  {
  	struct hostapd_hw_modes *mode;
  	struct hostapd_channel_data *chan;
-@@ -299,12 +292,12 @@ static int dfs_find_channel(struct hostapd_iface *iface,
+@@ -308,12 +301,12 @@ static int dfs_find_channel(struct hostapd_iface *iface,
  }
  
  
@@ -156,7 +156,7 @@
  	if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax)
  		return;
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index 606c1b3..c2556d2 100644
+index 0a7c25d..e88ea24 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -9,6 +9,12 @@
@@ -172,13 +172,14 @@
  int hostapd_handle_dfs(struct hostapd_iface *iface);
  
  int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
-@@ -32,5 +38,14 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
- int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
- int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
- 			   int center_freq);
+@@ -39,6 +45,14 @@ int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
+ 			   struct csa_settings *settings,
+ 			   struct csa_settings *background_settings,
+ 			   bool cac_required, bool bw_changed);
+-
 +int dfs_find_channel(struct hostapd_iface *iface,
 +		     struct hostapd_channel_data **ret_chan,
-+		     int idx, enum dfs_channel_type type);
++		     int n_chans, int idx, enum dfs_channel_type type);
 +void dfs_adjust_center_freq(struct hostapd_iface *iface,
 +			    struct hostapd_channel_data *chan,
 +			    int secondary_channel,
diff --git a/recipes-wifi/hostapd/files/patches/patches.inc b/recipes-wifi/hostapd/files/patches/patches.inc
index 9121a2f..0a397fe 100644
--- a/recipes-wifi/hostapd/files/patches/patches.inc
+++ b/recipes-wifi/hostapd/files/patches/patches.inc
@@ -62,6 +62,10 @@
     file://800-acs-don-t-select-indoor-channel-on-outdoor-operation.patch \
     file://990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch \
     file://992-openssl-include-rsa.patch \
+    file://bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch \
+    file://bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch \
+    file://bp-0003-ACS-introduce-acs_adjust_secondary.patch \
+    file://bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch \
     file://mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch \
     file://mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch \
     file://mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch \
@@ -72,7 +76,6 @@
     file://mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch \
     file://mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch \
     file://mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch \
-    file://mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
     file://mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch \
     file://mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch \
     file://mtk-0014-hostapd-mtk-Add-the-broadcast-destination-address-of.patch \
@@ -107,4 +110,9 @@
     file://mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch \
     file://mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch \
     file://mtk-0045-hostapd-mtk-add-log-in-extender-mode.patch \
+    file://mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch \
+    file://mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch \
+    file://mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch \
+    file://mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch \
+    file://mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
     "
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/common.uc b/recipes-wifi/hostapd/files/src-2.10.3/common.uc
new file mode 100644
index 0000000..4c33779
--- /dev/null
+++ b/recipes-wifi/hostapd/files/src-2.10.3/common.uc
@@ -0,0 +1,373 @@
+import * as nl80211 from "nl80211";
+import * as rtnl from "rtnl";
+import { readfile, glob, basename, readlink } from "fs";
+
+const iftypes = {
+	ap: nl80211.const.NL80211_IFTYPE_AP,
+	mesh: nl80211.const.NL80211_IFTYPE_MESH_POINT,
+	sta: nl80211.const.NL80211_IFTYPE_STATION,
+	adhoc: nl80211.const.NL80211_IFTYPE_ADHOC,
+	monitor: nl80211.const.NL80211_IFTYPE_MONITOR,
+};
+
+const mesh_params = {
+	mesh_retry_timeout: "retry_timeout",
+	mesh_confirm_timeout: "confirm_timeout",
+	mesh_holding_timeout: "holding_timeout",
+	mesh_max_peer_links: "max_peer_links",
+	mesh_max_retries: "max_retries",
+	mesh_ttl: "ttl",
+	mesh_element_ttl: "element_ttl",
+	mesh_auto_open_plinks: "auto_open_plinks",
+	mesh_hwmp_max_preq_retries: "hwmp_max_preq_retries",
+	mesh_path_refresh_time: "path_refresh_time",
+	mesh_min_discovery_timeout: "min_discovery_timeout",
+	mesh_hwmp_active_path_timeout: "hwmp_active_path_timeout",
+	mesh_hwmp_preq_min_interval: "hwmp_preq_min_interval",
+	mesh_hwmp_net_diameter_traversal_time: "hwmp_net_diam_trvs_time",
+	mesh_hwmp_rootmode: "hwmp_rootmode",
+	mesh_hwmp_rann_interval: "hwmp_rann_interval",
+	mesh_gate_announcements: "gate_announcements",
+	mesh_sync_offset_max_neighor: "sync_offset_max_neighbor",
+	mesh_rssi_threshold: "rssi_threshold",
+	mesh_hwmp_active_path_to_root_timeout: "hwmp_path_to_root_timeout",
+	mesh_hwmp_root_interval: "hwmp_root_interval",
+	mesh_hwmp_confirmation_interval: "hwmp_confirmation_interval",
+	mesh_awake_window: "awake_window",
+	mesh_plink_timeout: "plink_timeout",
+	mesh_fwding: "forwarding",
+	mesh_power_mode: "power_mode",
+	mesh_nolearn: "nolearn"
+};
+
+function wdev_remove(name)
+{
+	nl80211.request(nl80211.const.NL80211_CMD_DEL_INTERFACE, 0, { dev: name });
+}
+
+function __phy_is_fullmac(phyidx)
+{
+	let data = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, 0, { wiphy: phyidx });
+
+	return !data.software_iftypes.ap_vlan;
+}
+
+function phy_is_fullmac(phy)
+{
+	let phyidx = int(trim(readfile(`/sys/class/ieee80211/${phy}/index`)));
+
+	return __phy_is_fullmac(phyidx);
+}
+
+function find_reusable_wdev(phyidx)
+{
+	if (!__phy_is_fullmac(phyidx))
+		return null;
+
+	let data = nl80211.request(
+		nl80211.const.NL80211_CMD_GET_INTERFACE,
+		nl80211.const.NLM_F_DUMP,
+		{ wiphy: phyidx });
+	for (let res in data)
+		if (trim(readfile(`/sys/class/net/${res.ifname}/operstate`)) == "down")
+			return res.ifname;
+	return null;
+}
+
+function wdev_create(phy, name, data)
+{
+	let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`));
+
+	wdev_remove(name);
+
+	if (!iftypes[data.mode])
+		return `Invalid mode: ${data.mode}`;
+
+	let req = {
+		wiphy: phyidx,
+		ifname: name,
+		iftype: iftypes[data.mode],
+	};
+
+	if (data["4addr"])
+		req["4addr"] = data["4addr"];
+	if (data.macaddr)
+		req.mac = data.macaddr;
+
+	nl80211.error();
+
+	let reuse_ifname = find_reusable_wdev(phyidx);
+	if (reuse_ifname &&
+	    (reuse_ifname == name ||
+	     rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false))
+		nl80211.request(
+			nl80211.const.NL80211_CMD_SET_INTERFACE, 0, {
+				wiphy: phyidx,
+				dev: name,
+				iftype: iftypes[data.mode],
+			});
+	else
+		nl80211.request(
+			nl80211.const.NL80211_CMD_NEW_INTERFACE,
+			nl80211.const.NLM_F_CREATE,
+			req);
+
+	let error = nl80211.error();
+	if (error)
+		return error;
+
+	if (data.powersave != null) {
+		nl80211.request(nl80211.const.NL80211_CMD_SET_POWER_SAVE, 0,
+			{ dev: name, ps_state: data.powersave ? 1 : 0});
+	}
+
+	return null;
+}
+
+function wdev_set_mesh_params(name, data)
+{
+	let mesh_cfg = {};
+
+	for (let key in mesh_params) {
+		let val = data[key];
+		if (val == null)
+			continue;
+		mesh_cfg[mesh_params[key]] = int(val);
+	}
+
+	if (!length(mesh_cfg))
+		return null;
+
+	nl80211.request(nl80211.const.NL80211_CMD_SET_MESH_CONFIG, 0,
+		{ dev: name, mesh_params: mesh_cfg });
+
+	return nl80211.error();
+}
+
+function wdev_set_up(name, up)
+{
+	rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: name, change: 1, flags: up ? 1 : 0 });
+}
+
+function phy_sysfs_file(phy, name)
+{
+	return trim(readfile(`/sys/class/ieee80211/${phy}/${name}`));
+}
+
+function macaddr_split(str)
+{
+	return map(split(str, ":"), (val) => hex(val));
+}
+
+function macaddr_join(addr)
+{
+	return join(":", map(addr, (val) => sprintf("%02x", val)));
+}
+
+function wdev_macaddr(wdev)
+{
+	return trim(readfile(`/sys/class/net/${wdev}/address`));
+}
+
+const phy_proto = {
+	macaddr_init: function(used, options) {
+		this.macaddr_options = options ?? {};
+		this.macaddr_list = {};
+
+		if (type(used) == "object")
+			for (let addr in used)
+				this.macaddr_list[addr] = used[addr];
+		else
+			for (let addr in used)
+				this.macaddr_list[addr] = -1;
+
+		this.for_each_wdev((wdev) => {
+			let macaddr = wdev_macaddr(wdev);
+			this.macaddr_list[macaddr] ??= -1;
+		});
+
+		return this.macaddr_list;
+	},
+
+	macaddr_generate: function(data) {
+		let phy = this.name;
+		let idx = int(data.id ?? 0);
+		let mbssid = int(data.mbssid ?? 0) > 0;
+		let num_global = int(data.num_global ?? 1);
+		let use_global = !mbssid && idx < num_global;
+
+		let base_addr = phy_sysfs_file(phy, "macaddress");
+		if (!base_addr)
+			return null;
+
+		if (!idx && !mbssid)
+			return base_addr;
+
+		let base_mask = phy_sysfs_file(phy, "address_mask");
+		if (!base_mask)
+			return null;
+
+		if (base_mask == "00:00:00:00:00:00" && idx >= num_global) {
+			let addrs = split(phy_sysfs_file(phy, "addresses"), "\n");
+
+			if (idx < length(addrs))
+				return addrs[idx];
+
+			base_mask = "ff:ff:ff:ff:ff:ff";
+		}
+
+		let addr = macaddr_split(base_addr);
+		let mask = macaddr_split(base_mask);
+		let type;
+
+		if (mbssid)
+			type = "b5";
+		else if (use_global)
+			type = "add";
+		else if (mask[0] > 0)
+			type = "b1";
+		else if (mask[5] < 0xff)
+			type = "b5";
+		else
+			type = "add";
+
+		switch (type) {
+		case "b1":
+			if (!(addr[0] & 2))
+				idx--;
+			addr[0] |= 2;
+			addr[0] ^= idx << 2;
+			break;
+		case "b5":
+			if (mbssid)
+				addr[0] |= 2;
+			addr[5] ^= idx;
+			break;
+		default:
+			for (let i = 5; i > 0; i--) {
+				addr[i] += idx;
+				if (addr[i] < 256)
+					break;
+				addr[i] %= 256;
+			}
+			break;
+		}
+
+		return macaddr_join(addr);
+	},
+
+	macaddr_next: function(val) {
+		let data = this.macaddr_options ?? {};
+		let list = this.macaddr_list;
+
+		for (let i = 0; i < 32; i++) {
+			data.id = i;
+
+			let mac = this.macaddr_generate(data);
+			if (!mac)
+				return null;
+
+			if (list[mac] != null)
+				continue;
+
+			list[mac] = val != null ? val : -1;
+			return mac;
+		}
+	},
+
+	for_each_wdev: function(cb) {
+		let wdevs = glob(`/sys/class/ieee80211/${this.name}/device/net/*`);
+		wdevs = map(wdevs, (arg) => basename(arg));
+		for (let wdev in wdevs) {
+			if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != this.name)
+				continue;
+
+			cb(wdev);
+		}
+	}
+};
+
+function phy_open(phy)
+{
+	let phyidx = readfile(`/sys/class/ieee80211/${phy}/index`);
+	if (!phyidx)
+		return null;
+
+	return proto({
+		name: phy,
+		idx: int(phyidx)
+	}, phy_proto);
+}
+
+const vlist_proto = {
+	update: function(values, arg) {
+		let data = this.data;
+		let cb = this.cb;
+		let seq = { };
+		let new_data = {};
+		let old_data = {};
+
+		this.data = new_data;
+
+		if (type(values) == "object") {
+			for (let key in values) {
+				old_data[key] = data[key];
+				new_data[key] = values[key];
+				delete data[key];
+			}
+		} else {
+			for (let val in values) {
+				let cur_key = val[0];
+				let cur_obj = val[1];
+
+				old_data[cur_key] = data[cur_key];
+				new_data[cur_key] = val[1];
+				delete data[cur_key];
+			}
+		}
+
+		for (let key in data) {
+			cb(null, data[key], arg);
+			delete data[key];
+		}
+		for (let key in new_data)
+			cb(new_data[key], old_data[key], arg);
+	}
+};
+
+function is_equal(val1, val2) {
+	let t1 = type(val1);
+
+	if (t1 != type(val2))
+		return false;
+
+	if (t1 == "array") {
+		if (length(val1) != length(val2))
+			return false;
+
+		for (let i = 0; i < length(val1); i++)
+			if (!is_equal(val1[i], val2[i]))
+				return false;
+
+		return true;
+	} else if (t1 == "object") {
+		for (let key in val1)
+			if (!is_equal(val1[key], val2[key]))
+				return false;
+		for (let key in val2)
+			if (val1[key] == null)
+				return false;
+		return true;
+	} else {
+		return val1 == val2;
+	}
+}
+
+function vlist_new(cb) {
+	return proto({
+			cb: cb,
+			data: {}
+		}, vlist_proto);
+}
+
+export { wdev_remove, wdev_create, wdev_set_mesh_params, wdev_set_up, is_equal, vlist_new, phy_is_fullmac, phy_open };
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/hostapd.uc b/recipes-wifi/hostapd/files/src-2.10.3/hostapd.uc
new file mode 100644
index 0000000..b85f523
--- /dev/null
+++ b/recipes-wifi/hostapd/files/src-2.10.3/hostapd.uc
@@ -0,0 +1,814 @@
+let libubus = require("ubus");
+import { open, readfile } from "fs";
+import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open } from "common";
+
+let ubus = libubus.connect();
+
+hostapd.data.config = {};
+
+hostapd.data.file_fields = {
+	vlan_file: true,
+	wpa_psk_file: true,
+	accept_mac_file: true,
+	deny_mac_file: true,
+	eap_user_file: true,
+	ca_cert: true,
+	server_cert: true,
+	server_cert2: true,
+	private_key: true,
+	private_key2: true,
+	dh_file: true,
+	eap_sim_db: true,
+};
+
+function iface_remove(cfg)
+{
+	if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
+		return;
+
+	for (let bss in cfg.bss)
+		wdev_remove(bss.ifname);
+}
+
+function iface_gen_config(phy, config, start_disabled)
+{
+	let str = `data:
+${join("\n", config.radio.data)}
+channel=${config.radio.channel}
+`;
+
+	for (let i = 0; i < length(config.bss); i++) {
+		let bss = config.bss[i];
+		let type = i > 0 ? "bss" : "interface";
+		let nasid = bss.nasid ?? replace(bss.bssid, ":", "");
+
+		str += `
+${type}=${bss.ifname}
+bssid=${bss.bssid}
+${join("\n", bss.data)}
+nas_identifier=${nasid}
+`;
+		if (start_disabled)
+			str += `
+start_disabled=1
+`;
+	}
+
+	return str;
+}
+
+function iface_freq_info(iface, config, params)
+{
+	let freq = params.frequency;
+	if (!freq)
+		return null;
+
+	let sec_offset = params.sec_chan_offset;
+	if (sec_offset != -1 && sec_offset != 1)
+		sec_offset = 0;
+
+	let width = 0;
+	for (let line in config.radio.data) {
+		if (!sec_offset && match(line, /^ht_capab=.*HT40/)) {
+			sec_offset = null; // auto-detect
+			continue;
+		}
+
+		let val = match(line, /^(vht_oper_chwidth|he_oper_chwidth)=(\d+)/);
+		if (!val)
+			continue;
+
+		val = int(val[2]);
+		if (val > width)
+			width = val;
+	}
+
+	if (freq < 4000)
+		width = 0;
+
+	return hostapd.freq_info(freq, sec_offset, width);
+}
+
+function iface_add(phy, config, phy_status)
+{
+	let config_inline = iface_gen_config(phy, config, !!phy_status);
+
+	let bss = config.bss[0];
+	let ret = hostapd.add_iface(`bss_config=${phy}:${config_inline}`);
+	if (ret < 0)
+		return false;
+
+	if (!phy_status)
+		return true;
+
+	let iface = hostapd.interfaces[phy];
+	if (!iface)
+		return false;
+
+	let freq_info = iface_freq_info(iface, config, phy_status);
+
+	return iface.start(freq_info) >= 0;
+}
+
+function iface_config_macaddr_list(config)
+{
+	let macaddr_list = {};
+	for (let i = 0; i < length(config.bss); i++) {
+		let bss = config.bss[i];
+		if (!bss.default_macaddr)
+			macaddr_list[bss.bssid] = i;
+	}
+
+	return macaddr_list;
+}
+
+function iface_update_supplicant_macaddr(phy, config)
+{
+	let macaddr_list = [];
+	for (let i = 0; i < length(config.bss); i++)
+		push(macaddr_list, config.bss[i].bssid);
+	ubus.call("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
+}
+
+function iface_restart(phydev, config, old_config)
+{
+	let phy = phydev.name;
+
+	hostapd.remove_iface(phy);
+	iface_remove(old_config);
+	iface_remove(config);
+
+	if (!config.bss || !config.bss[0]) {
+		hostapd.printf(`No bss for phy ${phy}`);
+		return;
+	}
+
+	phydev.macaddr_init(iface_config_macaddr_list(config));
+	for (let i = 0; i < length(config.bss); i++) {
+		let bss = config.bss[i];
+		if (bss.default_macaddr)
+			bss.bssid = phydev.macaddr_next();
+	}
+
+	iface_update_supplicant_macaddr(phy, config);
+
+	let bss = config.bss[0];
+	let err = wdev_create(phy, bss.ifname, { mode: "ap" });
+	if (err)
+		hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
+
+	let ubus = hostapd.data.ubus;
+	let phy_status = ubus.call("wpa_supplicant", "phy_status", { phy: phy });
+	if (phy_status && phy_status.state == "COMPLETED") {
+		if (iface_add(phy, config, phy_status))
+			return;
+
+		hostapd.printf(`Failed to bring up phy ${phy} ifname=${bss.ifname} with supplicant provided frequency`);
+	}
+
+	ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true });
+	if (!iface_add(phy, config))
+		hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
+	ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false });
+}
+
+function array_to_obj(arr, key, start)
+{
+	let obj = {};
+
+	start ??= 0;
+	for (let i = start; i < length(arr); i++) {
+		let cur = arr[i];
+		obj[cur[key]] = cur;
+	}
+
+	return obj;
+}
+
+function find_array_idx(arr, key, val)
+{
+	for (let i = 0; i < length(arr); i++)
+		if (arr[i][key] == val)
+			return i;
+
+	return -1;
+}
+
+function bss_reload_psk(bss, config, old_config)
+{
+	if (is_equal(old_config.hash.wpa_psk_file, config.hash.wpa_psk_file))
+		return;
+
+	old_config.hash.wpa_psk_file = config.hash.wpa_psk_file;
+	if (!is_equal(old_config, config))
+		return;
+
+	let ret = bss.ctrl("RELOAD_WPA_PSK");
+	ret ??= "failed";
+
+	hostapd.printf(`Reload WPA PSK file for bss ${config.ifname}: ${ret}`);
+}
+
+function remove_file_fields(config)
+{
+	return filter(config, (line) => !hostapd.data.file_fields[split(line, "=")[0]]);
+}
+
+function bss_remove_file_fields(config)
+{
+	let new_cfg = {};
+
+	for (let key in config)
+		new_cfg[key] = config[key];
+	new_cfg.data = remove_file_fields(new_cfg.data);
+	new_cfg.hash = {};
+	for (let key in config.hash)
+		new_cfg.hash[key] = config.hash[key];
+	delete new_cfg.hash.wpa_psk_file;
+	delete new_cfg.hash.vlan_file;
+
+	return new_cfg;
+}
+
+function bss_config_hash(config)
+{
+	return hostapd.sha1(remove_file_fields(config) + "");
+}
+
+function bss_find_existing(config, prev_config, prev_hash)
+{
+	let hash = bss_config_hash(config.data);
+
+	for (let i = 0; i < length(prev_config.bss); i++) {
+		if (!prev_hash[i] || hash != prev_hash[i])
+			continue;
+
+		prev_hash[i] = null;
+		return i;
+	}
+
+	return -1;
+}
+
+function get_config_bss(config, idx)
+{
+	if (!config.bss[idx]) {
+		hostapd.printf(`Invalid bss index ${idx}`);
+		return null;
+	}
+
+	let ifname = config.bss[idx].ifname;
+	if (!ifname)
+		hostapd.printf(`Could not find bss ${config.bss[idx].ifname}`);
+
+	return hostapd.bss[ifname];
+}
+
+function iface_reload_config(phydev, config, old_config)
+{
+	let phy = phydev.name;
+
+	if (!old_config || !is_equal(old_config.radio, config.radio))
+		return false;
+
+	if (is_equal(old_config.bss, config.bss))
+		return true;
+
+	if (!old_config.bss || !old_config.bss[0])
+		return false;
+
+	let iface = hostapd.interfaces[phy];
+	let iface_name = old_config.bss[0].ifname;
+	if (!iface) {
+		hostapd.printf(`Could not find previous interface ${iface_name}`);
+		return false;
+	}
+
+	let first_bss = hostapd.bss[iface_name];
+	if (!first_bss) {
+		hostapd.printf(`Could not find bss of previous interface ${iface_name}`);
+		return false;
+	}
+
+	let macaddr_list = iface_config_macaddr_list(config);
+	let bss_list = [];
+	let bss_list_cfg = [];
+	let prev_bss_hash = [];
+
+	for (let bss in old_config.bss) {
+		let hash = bss_config_hash(bss.data);
+		push(prev_bss_hash, bss_config_hash(bss.data));
+	}
+
+	// Step 1: find (possibly renamed) interfaces with the same config
+	// and store them in the new order (with gaps)
+	for (let i = 0; i < length(config.bss); i++) {
+		let prev;
+
+		// For fullmac devices, the first interface needs to be preserved,
+		// since it's treated as the master
+		if (!i && phy_is_fullmac(phy)) {
+			prev = 0;
+			prev_bss_hash[0] = null;
+		} else {
+			prev = bss_find_existing(config.bss[i], old_config, prev_bss_hash);
+		}
+		if (prev < 0)
+			continue;
+
+		let cur_config = config.bss[i];
+		let prev_config = old_config.bss[prev];
+
+		let prev_bss = get_config_bss(old_config, prev);
+		if (!prev_bss)
+			return false;
+
+		// try to preserve MAC address of this BSS by reassigning another
+		// BSS if necessary
+		if (cur_config.default_macaddr &&
+		    !macaddr_list[prev_config.bssid]) {
+			macaddr_list[prev_config.bssid] = i;
+			cur_config.bssid = prev_config.bssid;
+		}
+
+		bss_list[i] = prev_bss;
+		bss_list_cfg[i] = old_config.bss[prev];
+	}
+
+	if (config.mbssid && !bss_list_cfg[0]) {
+		hostapd.printf("First BSS changed with MBSSID enabled");
+		return false;
+	}
+
+	// Step 2: if none were found, rename and preserve the first one
+	if (length(bss_list) == 0) {
+		// can't change the bssid of the first bss
+		if (config.bss[0].bssid != old_config.bss[0].bssid) {
+			if (!config.bss[0].default_macaddr) {
+				hostapd.printf(`BSSID of first interface changed: ${lc(old_config.bss[0].bssid)} -> ${lc(config.bss[0].bssid)}`);
+				return false;
+			}
+
+			config.bss[0].bssid = old_config.bss[0].bssid;
+		}
+
+		let prev_bss = get_config_bss(old_config, 0);
+		if (!prev_bss)
+			return false;
+
+		macaddr_list[config.bss[0].bssid] = 0;
+		bss_list[0] = prev_bss;
+		bss_list_cfg[0] = old_config.bss[0];
+		prev_bss_hash[0] = null;
+	}
+
+	// Step 3: delete all unused old interfaces
+	for (let i = 0; i < length(prev_bss_hash); i++) {
+		if (!prev_bss_hash[i])
+			continue;
+
+		let prev_bss = get_config_bss(old_config, i);
+		if (!prev_bss)
+			return false;
+
+		let ifname = old_config.bss[i].ifname;
+		hostapd.printf(`Remove bss '${ifname}' on phy '${phy}'`);
+		prev_bss.delete();
+		wdev_remove(ifname);
+	}
+
+	// Step 4: rename preserved interfaces, use temporary name on duplicates
+	let rename_list = [];
+	for (let i = 0; i < length(bss_list); i++) {
+		if (!bss_list[i])
+			continue;
+
+		let old_ifname = bss_list_cfg[i].ifname;
+		let new_ifname = config.bss[i].ifname;
+		if (old_ifname == new_ifname)
+			continue;
+
+		if (hostapd.bss[new_ifname]) {
+			new_ifname = "tmp_" + substr(hostapd.sha1(new_ifname), 0, 8);
+			push(rename_list, i);
+		}
+
+		hostapd.printf(`Rename bss ${old_ifname} to ${new_ifname}`);
+		if (!bss_list[i].rename(new_ifname)) {
+			hostapd.printf(`Failed to rename bss ${old_ifname} to ${new_ifname}`);
+			return false;
+		}
+
+		bss_list_cfg[i].ifname = new_ifname;
+	}
+
+	// Step 5: rename interfaces with temporary names
+	for (let i in rename_list) {
+		let new_ifname = config.bss[i].ifname;
+		if (!bss_list[i].rename(new_ifname)) {
+			hostapd.printf(`Failed to rename bss to ${new_ifname}`);
+			return false;
+		}
+		bss_list_cfg[i].ifname = new_ifname;
+	}
+
+	// Step 6: assign BSSID for newly created interfaces
+	let macaddr_data = {
+		num_global: config.num_global_macaddr ?? 1,
+		mbssid: config.mbssid ?? 0,
+	};
+	macaddr_list = phydev.macaddr_init(macaddr_list, macaddr_data);
+	for (let i = 0; i < length(config.bss); i++) {
+		if (bss_list[i])
+			continue;
+		let bsscfg = config.bss[i];
+
+		let mac_idx = macaddr_list[bsscfg.bssid];
+		if (mac_idx < 0)
+			macaddr_list[bsscfg.bssid] = i;
+		if (mac_idx == i)
+			continue;
+
+		// statically assigned bssid of the new interface is in conflict
+		// with the bssid of a reused interface. reassign the reused interface
+		if (!bsscfg.default_macaddr) {
+			// can't update bssid of the first BSS, need to restart
+			if (!mac_idx < 0)
+				return false;
+
+			bsscfg = config.bss[mac_idx];
+		}
+
+		let addr = phydev.macaddr_next(i);
+		if (!addr) {
+			hostapd.printf(`Failed to generate mac address for phy ${phy}`);
+			return false;
+		}
+		bsscfg.bssid = addr;
+	}
+
+	let config_inline = iface_gen_config(phy, config);
+
+	// Step 7: fill in the gaps with new interfaces
+	for (let i = 0; i < length(config.bss); i++) {
+		let ifname = config.bss[i].ifname;
+		let bss = bss_list[i];
+
+		if (bss)
+			continue;
+
+		hostapd.printf(`Add bss ${ifname} on phy ${phy}`);
+		bss_list[i] = iface.add_bss(config_inline, i);
+		if (!bss_list[i]) {
+			hostapd.printf(`Failed to add new bss ${ifname} on phy ${phy}`);
+			return false;
+		}
+	}
+
+	// Step 8: update interface bss order
+	if (!iface.set_bss_order(bss_list)) {
+		hostapd.printf(`Failed to update BSS order on phy '${phy}'`);
+		return false;
+	}
+
+	// Step 9: update config
+	for (let i = 0; i < length(config.bss); i++) {
+		if (!bss_list_cfg[i])
+			continue;
+
+		let ifname = config.bss[i].ifname;
+		let bss = bss_list[i];
+
+		if (is_equal(config.bss[i], bss_list_cfg[i]))
+			continue;
+
+		if (is_equal(bss_remove_file_fields(config.bss[i]),
+		             bss_remove_file_fields(bss_list_cfg[i]))) {
+			hostapd.printf(`Update config data files for bss ${ifname}`);
+			if (bss.set_config(config_inline, i, true) < 0) {
+				hostapd.printf(`Could not update config data files for bss ${ifname}`);
+				return false;
+			} else {
+				bss.ctrl("RELOAD_WPA_PSK");
+				continue;
+			}
+		}
+
+		bss_reload_psk(bss, config.bss[i], bss_list_cfg[i]);
+		if (is_equal(config.bss[i], bss_list_cfg[i]))
+			continue;
+
+		hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`);
+		if (bss.set_config(config_inline, i) < 0) {
+			hostapd.printf(`Failed to set config for bss ${ifname}`);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+function iface_set_config(phy, config)
+{
+	let old_config = hostapd.data.config[phy];
+
+	hostapd.data.config[phy] = config;
+
+	if (!config) {
+		hostapd.remove_iface(phy);
+		return iface_remove(old_config);
+	}
+
+	let phydev = phy_open(phy);
+	if (!phydev) {
+		hostapd.printf(`Failed to open phy ${phy}`);
+		return false;
+	}
+
+	try {
+		let ret = iface_reload_config(phydev, config, old_config);
+		if (ret) {
+			iface_update_supplicant_macaddr(phy, config);
+			hostapd.printf(`Reloaded settings for phy ${phy}`);
+			return 0;
+		}
+	} catch (e) {
+			hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`);
+	}
+
+	hostapd.printf(`Restart interface for phy ${phy}`);
+	let ret = iface_restart(phydev, config, old_config);
+
+	return ret;
+}
+
+function config_add_bss(config, name)
+{
+	let bss = {
+		ifname: name,
+		data: [],
+		hash: {}
+	};
+
+	push(config.bss, bss);
+
+	return bss;
+}
+
+function iface_load_config(filename)
+{
+	let f = open(filename, "r");
+	if (!f)
+		return null;
+
+	let config = {
+		radio: {
+			data: []
+		},
+		bss: [],
+		orig_file: filename,
+	};
+
+	let bss;
+	let line;
+	while ((line = rtrim(f.read("line"), "\n")) != null) {
+		let val = split(line, "=", 2);
+		if (!val[0])
+			continue;
+
+		if (val[0] == "interface") {
+			bss = config_add_bss(config, val[1]);
+			break;
+		}
+
+		if (val[0] == "channel") {
+			config.radio.channel = val[1];
+			continue;
+		}
+
+		if (val[0] == "#num_global_macaddr" ||
+		    val[0] == "mbssid")
+			config[val[0]] = int(val[1]);
+
+		push(config.radio.data, line);
+	}
+
+	while ((line = rtrim(f.read("line"), "\n")) != null) {
+		if (line == "#default_macaddr")
+			bss.default_macaddr = true;
+
+		let val = split(line, "=", 2);
+		if (!val[0])
+			continue;
+
+		if (val[0] == "bssid") {
+			bss.bssid = lc(val[1]);
+			continue;
+		}
+
+		if (val[0] == "nas_identifier")
+			bss.nasid = val[1];
+
+		if (val[0] == "bss") {
+			bss = config_add_bss(config, val[1]);
+			continue;
+		}
+
+		if (hostapd.data.file_fields[val[0]])
+			bss.hash[val[0]] = hostapd.sha1(readfile(val[1]));
+
+		push(bss.data, line);
+	}
+	f.close();
+
+	return config;
+}
+
+function ex_wrap(func) {
+	return (req) => {
+		try {
+			let ret = func(req);
+			return ret;
+		} catch(e) {
+			hostapd.printf(`Exception in ubus function: ${e}\n${e.stacktrace[0].context}`);
+		}
+		return libubus.STATUS_UNKNOWN_ERROR;
+	};
+}
+
+let main_obj = {
+	reload: {
+		args: {
+			phy: "",
+		},
+		call: ex_wrap(function(req) {
+			let phy_list = req.args.phy ? [ req.args.phy ] : keys(hostapd.data.config);
+			for (let phy_name in phy_list) {
+				let phy = hostapd.data.config[phy_name];
+				let config = iface_load_config(phy.orig_file);
+				iface_set_config(phy_name, config);
+			}
+
+			return 0;
+		})
+	},
+	apsta_state: {
+		args: {
+			phy: "",
+			up: true,
+			frequency: 0,
+			sec_chan_offset: 0,
+			csa: true,
+			csa_count: 0,
+		},
+		call: ex_wrap(function(req) {
+			if (req.args.up == null || !req.args.phy)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			let phy = req.args.phy;
+			let config = hostapd.data.config[phy];
+			if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname)
+				return 0;
+
+			let iface = hostapd.interfaces[phy];
+			if (!iface)
+				return 0;
+
+			if (!req.args.up) {
+				iface.stop();
+				return 0;
+			}
+
+			if (!req.args.frequency)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			let freq_info = iface_freq_info(iface, config, req.args);
+			if (!freq_info)
+				return libubus.STATUS_UNKNOWN_ERROR;
+
+			let ret;
+			if (req.args.csa) {
+				freq_info.csa_count = req.args.csa_count ?? 10;
+				ret = iface.switch_channel(freq_info);
+			} else {
+				ret = iface.start(freq_info);
+			}
+			if (!ret)
+				return libubus.STATUS_UNKNOWN_ERROR;
+
+			return 0;
+		})
+	},
+	config_get_macaddr_list: {
+		args: {
+			phy: ""
+		},
+		call: ex_wrap(function(req) {
+			let phy = req.args.phy;
+			if (!phy)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			let ret = {
+				macaddr: [],
+			};
+
+			let config = hostapd.data.config[phy];
+			if (!config)
+				return ret;
+
+			ret.macaddr = map(config.bss, (bss) => bss.bssid);
+			return ret;
+		})
+	},
+	config_set: {
+		args: {
+			phy: "",
+			config: "",
+			prev_config: "",
+		},
+		call: ex_wrap(function(req) {
+			let phy = req.args.phy;
+			let file = req.args.config;
+			let prev_file = req.args.prev_config;
+
+			if (!phy)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			if (prev_file && !hostapd.data.config[phy]) {
+				let config = iface_load_config(prev_file);
+				if (config)
+					config.radio.data = [];
+				hostapd.data.config[phy] = config;
+			}
+
+			let config = iface_load_config(file);
+
+			hostapd.printf(`Set new config for phy ${phy}: ${file}`);
+			iface_set_config(phy, config);
+
+			return {
+				pid: hostapd.getpid()
+			};
+		})
+	},
+	config_add: {
+		args: {
+			iface: "",
+			config: "",
+		},
+		call: ex_wrap(function(req) {
+			if (!req.args.iface || !req.args.config)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			if (hostapd.add_iface(`bss_config=${req.args.iface}:${req.args.config}`) < 0)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			return {
+				pid: hostapd.getpid()
+			};
+		})
+	},
+	config_remove: {
+		args: {
+			iface: ""
+		},
+		call: ex_wrap(function(req) {
+			if (!req.args.iface)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			hostapd.remove_iface(req.args.iface);
+			return 0;
+		})
+	},
+};
+
+hostapd.data.ubus = ubus;
+hostapd.data.obj = ubus.publish("hostapd", main_obj);
+hostapd.udebug_set("hostapd", hostapd.data.ubus);
+
+function bss_event(type, name, data) {
+	let ubus = hostapd.data.ubus;
+
+	data ??= {};
+	data.name = name;
+	hostapd.data.obj.notify(`bss.${type}`, data, null, null, null, -1);
+	ubus.call("service", "event", { type: `hostapd.${name}.${type}`, data: {} });
+}
+
+return {
+	shutdown: function() {
+		for (let phy in hostapd.data.config)
+			iface_set_config(phy, null);
+		hostapd.udebug_set(null);
+		hostapd.ubus.disconnect();
+	},
+	bss_add: function(name, obj) {
+		bss_event("add", name);
+	},
+	bss_reload: function(name, obj, reconf) {
+		bss_event("reload", name, { reconf: reconf != 0 });
+	},
+	bss_remove: function(name, obj) {
+		bss_event("remove", name);
+	}
+};
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/src/ap/ucode.c b/recipes-wifi/hostapd/files/src-2.10.3/src/ap/ucode.c
index af97091..16d1b51 100644
--- a/recipes-wifi/hostapd/files/src-2.10.3/src/ap/ucode.c
+++ b/recipes-wifi/hostapd/files/src-2.10.3/src/ap/ucode.c
@@ -711,6 +711,7 @@
 		{ "freq_info", uc_wpa_freq_info },
 		{ "add_iface", uc_hostapd_add_iface },
 		{ "remove_iface", uc_hostapd_remove_iface },
+		{ "udebug_set", uc_wpa_udebug_set },
 	};
 	static const uc_function_list_t bss_fns[] = {
 		{ "ctrl", uc_hostapd_bss_ctrl },
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/src/utils/ucode.c b/recipes-wifi/hostapd/files/src-2.10.3/src/utils/ucode.c
index 2beeb9a..29c753c 100644
--- a/recipes-wifi/hostapd/files/src-2.10.3/src/utils/ucode.c
+++ b/recipes-wifi/hostapd/files/src-2.10.3/src/utils/ucode.c
@@ -4,12 +4,71 @@
 #include "crypto/crypto.h"
 #include "crypto/sha1.h"
 #include "common/ieee802_11_common.h"
+#include <linux/netlink.h>
+#include <linux/genetlink.h>
+#include <linux/nl80211.h>
 #include <libubox/uloop.h>
 #include <ucode/compiler.h>
+#include <udebug.h>
 
 static uc_value_t *registry;
 static uc_vm_t vm;
 static struct uloop_timeout gc_timer;
+static struct udebug ud;
+static struct udebug_buf ud_log, ud_nl[3];
+static const struct udebug_buf_meta meta_log = {
+	.name = "wpa_log",
+	.format = UDEBUG_FORMAT_STRING,
+};
+static const struct udebug_buf_meta meta_nl_ll = {
+	.name = "wpa_nl_ctrl",
+	.format = UDEBUG_FORMAT_PACKET,
+	.sub_format = UDEBUG_DLT_NETLINK,
+};
+static const struct udebug_buf_meta meta_nl_tx = {
+	.name = "wpa_nl_tx",
+	.format = UDEBUG_FORMAT_PACKET,
+	.sub_format = UDEBUG_DLT_NETLINK,
+};
+#define UDEBUG_FLAG_RX_FRAME	(1ULL << 0)
+static const struct udebug_buf_flag rx_flags[] = {
+	{  "rx_frame", UDEBUG_FLAG_RX_FRAME },
+};
+static const struct udebug_buf_meta meta_nl_rx = {
+	.name = "wpa_nl_rx",
+	.format = UDEBUG_FORMAT_PACKET,
+	.sub_format = UDEBUG_DLT_NETLINK,
+	.flags = rx_flags,
+	.n_flags = ARRAY_SIZE(rx_flags),
+};
+static struct udebug_ubus_ring udebug_rings[] = {
+	{
+		.buf = &ud_log,
+		.meta = &meta_log,
+		.default_entries = 1024,
+		.default_size = 64 * 1024
+	},
+	{
+		.buf = &ud_nl[0],
+		.meta = &meta_nl_rx,
+		.default_entries = 1024,
+		.default_size = 256 * 1024,
+	},
+	{
+		.buf = &ud_nl[1],
+		.meta = &meta_nl_tx,
+		.default_entries = 1024,
+		.default_size = 64 * 1024,
+	},
+	{
+		.buf = &ud_nl[2],
+		.meta = &meta_nl_ll,
+		.default_entries = 1024,
+		.default_size = 32 * 1024,
+	}
+};
+char *udebug_service;
+struct udebug_ubus ud_ubus;
 
 static void uc_gc_timer(struct uloop_timeout *timeout)
 {
@@ -251,6 +310,114 @@
 	return 0;
 }
 
+static void udebug_printf_hook(int level, const char *fmt, va_list ap)
+{
+	udebug_entry_init(&ud_log);
+	udebug_entry_vprintf(&ud_log, fmt, ap);
+	udebug_entry_add(&ud_log);
+}
+
+static void udebug_hexdump_hook(int level, const char *title,
+                const void *data, size_t len)
+{
+	char *buf;
+
+	udebug_entry_init(&ud_log);
+	udebug_entry_printf(&ud_log, "%s - hexdump:", title);
+	buf = udebug_entry_append(&ud_log, NULL, 3 * len);
+	for (size_t i = 0; i < len; i++)
+		buf += sprintf(buf, " %02x", *(uint8_t *)(data + i));
+	udebug_entry_add(&ud_log);
+}
+
+static void udebug_netlink_hook(int tx, const void *data, size_t len)
+{
+	struct {
+		uint16_t pkttype;
+		uint16_t arphdr;
+		uint16_t _pad[5];
+		uint16_t proto;
+	} hdr = {
+		.pkttype = host_to_be16(tx ? 7 : 6),
+		.arphdr = host_to_be16(824),
+		.proto = host_to_be16(16),
+	};
+	const struct nlmsghdr *nlh = data;
+	const struct genlmsghdr *gnlh = data + NLMSG_HDRLEN;
+	struct udebug_buf *buf = &ud_nl[!!tx];
+
+	if (nlh->nlmsg_type == 0x10)
+		buf = &ud_nl[2];
+	else if (!tx && gnlh->cmd == NL80211_CMD_FRAME &&
+	         !(udebug_buf_flags(buf) & UDEBUG_FLAG_RX_FRAME))
+		return;
+
+	if (!udebug_buf_valid(buf))
+		return;
+
+	udebug_entry_init(buf);
+	udebug_entry_append(buf, &hdr, sizeof(hdr));
+	udebug_entry_append(buf, data, len);
+	udebug_entry_add(buf);
+}
+
+static void
+wpa_udebug_config(struct udebug_ubus *ctx, struct blob_attr *data,
+		  bool enabled)
+{
+	udebug_ubus_apply_config(&ud, udebug_rings, ARRAY_SIZE(udebug_rings),
+				 data, enabled);
+
+	if (udebug_buf_valid(&ud_log)) {
+		wpa_printf_hook = udebug_printf_hook;
+		wpa_hexdump_hook = udebug_hexdump_hook;
+	} else {
+		wpa_printf_hook = NULL;
+		wpa_hexdump_hook = NULL;
+	}
+
+	if (udebug_buf_valid(&ud_nl[0]) ||
+	    udebug_buf_valid(&ud_nl[1]) ||
+	    udebug_buf_valid(&ud_nl[2]))
+		wpa_netlink_hook = udebug_netlink_hook;
+	else
+		wpa_netlink_hook = NULL;
+}
+
+uc_value_t *uc_wpa_udebug_set(uc_vm_t *vm, size_t nargs)
+{
+	uc_value_t *name = uc_fn_arg(0);
+	uc_value_t *ubus = uc_fn_arg(1);
+	static bool enabled = false;
+	struct ubus_context *ctx;
+	bool cur_en;
+
+	cur_en = ucv_type(name) == UC_STRING;
+	ctx = ucv_resource_data(ubus, "ubus.connection");
+	if (!ctx)
+		cur_en = false;
+
+	if (enabled == cur_en)
+		return ucv_boolean_new(true);
+
+	enabled = cur_en;
+	if (enabled) {
+		udebug_service = strdup(ucv_string_get(name));
+		udebug_init(&ud);
+		udebug_auto_connect(&ud, NULL);
+		udebug_ubus_init(&ud_ubus, ctx, udebug_service, wpa_udebug_config);
+	} else {
+		udebug_ubus_free(&ud_ubus);
+		for (size_t i = 0; i < ARRAY_SIZE(udebug_rings); i++)
+			if (udebug_buf_valid(udebug_rings[i].buf))
+				udebug_buf_free(udebug_rings[i].buf);
+		udebug_free(&ud);
+		free(udebug_service);
+	}
+
+	return ucv_boolean_new(true);
+}
+
 uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type)
 {
 	uc_value_t *global = uc_resource_new(global_type, NULL);
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/src/utils/ucode.h b/recipes-wifi/hostapd/files/src-2.10.3/src/utils/ucode.h
index 2c18869..c083241 100644
--- a/recipes-wifi/hostapd/files/src-2.10.3/src/utils/ucode.h
+++ b/recipes-wifi/hostapd/files/src-2.10.3/src/utils/ucode.h
@@ -21,6 +21,7 @@
 uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx);
 uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx);
 
+uc_value_t *uc_wpa_udebug_set(uc_vm_t *vm, size_t nargs);
 uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs);
 uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs);
 uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs);
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/wdev.uc b/recipes-wifi/hostapd/files/src-2.10.3/wdev.uc
new file mode 100644
index 0000000..ff4d629
--- /dev/null
+++ b/recipes-wifi/hostapd/files/src-2.10.3/wdev.uc
@@ -0,0 +1,185 @@
+#!/usr/bin/env ucode
+'use strict';
+import { vlist_new, is_equal, wdev_create, wdev_set_mesh_params, wdev_remove, wdev_set_up, phy_open } from "/usr/share/hostap/common.uc";
+import { readfile, writefile, basename, readlink, glob } from "fs";
+let libubus = require("ubus");
+
+let keep_devices = {};
+let phy = shift(ARGV);
+let command = shift(ARGV);
+let phydev;
+
+function iface_stop(wdev)
+{
+	if (keep_devices[wdev.ifname])
+		return;
+
+	wdev_remove(wdev.ifname);
+}
+
+function iface_start(wdev)
+{
+	let ifname = wdev.ifname;
+
+	if (readfile(`/sys/class/net/${ifname}/ifindex`)) {
+		wdev_set_up(ifname, false);
+		wdev_remove(ifname);
+	}
+	let wdev_config = {};
+	for (let key in wdev)
+		wdev_config[key] = wdev[key];
+	if (!wdev_config.macaddr && wdev.mode != "monitor")
+		wdev_config.macaddr = phydev.macaddr_next();
+	wdev_create(phy, ifname, wdev_config);
+	wdev_set_up(ifname, true);
+	if (wdev.freq)
+		system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`);
+	if (wdev.mode == "adhoc") {
+		let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, wdev.htmode, "fixed-freq" ];
+		if (wdev.bssid)
+			push(cmd, wdev.bssid);
+		for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ])
+			if (wdev[key])
+				push(cmd, key, wdev[key]);
+		system(cmd);
+	} else if (wdev.mode == "mesh") {
+		let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, wdev.htmode ];
+		for (let key in [ "mcast-rate", "beacon-interval" ])
+			if (wdev[key])
+				push(cmd, key, wdev[key]);
+		system(cmd);
+
+		wdev_set_mesh_params(ifname, wdev);
+	}
+}
+
+function iface_cb(new_if, old_if)
+{
+	if (old_if && new_if && is_equal(old_if, new_if))
+		return;
+
+	if (old_if)
+		iface_stop(old_if);
+	if (new_if)
+		iface_start(new_if);
+}
+
+function drop_inactive(config)
+{
+	for (let key in config) {
+		if (!readfile(`/sys/class/net/${key}/ifindex`))
+			delete config[key];
+	}
+}
+
+function add_ifname(config)
+{
+	for (let key in config)
+		config[key].ifname = key;
+}
+
+function delete_ifname(config)
+{
+	for (let key in config)
+		delete config[key].ifname;
+}
+
+function add_existing(phy, config)
+{
+	let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`);
+	wdevs = map(wdevs, (arg) => basename(arg));
+	for (let wdev in wdevs) {
+		if (config[wdev])
+			continue;
+
+		if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy)
+			continue;
+
+		if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down")
+			config[wdev] = {};
+	}
+}
+
+function usage()
+{
+	warn(`Usage: ${basename(sourcepath())} <phy> <command> [<arguments>]
+
+Commands:
+	set_config <config> [<device]...] - set phy configuration
+	get_macaddr <id>		  - get phy MAC address for vif index <id>
+`);
+	exit(1);
+}
+
+const commands = {
+	set_config: function(args) {
+		let statefile = `/var/run/wdev-${phy}.json`;
+
+		let new_config = shift(args);
+		for (let dev in ARGV)
+			keep_devices[dev] = true;
+
+		if (!new_config)
+			usage();
+
+		new_config = json(new_config);
+		if (!new_config) {
+			warn("Invalid configuration\n");
+			exit(1);
+		}
+
+		let old_config = readfile(statefile);
+		if (old_config)
+			old_config = json(old_config);
+
+		let config = vlist_new(iface_cb);
+		if (type(old_config) == "object")
+			config.data = old_config;
+
+		add_existing(phy, config.data);
+		add_ifname(config.data);
+		drop_inactive(config.data);
+
+		let ubus = libubus.connect();
+		let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phy });
+		let macaddr_list = [];
+		if (type(data) == "object" && data.macaddr)
+			macaddr_list = data.macaddr;
+		ubus.disconnect();
+		phydev.macaddr_init(macaddr_list);
+
+		add_ifname(new_config);
+		config.update(new_config);
+
+		drop_inactive(config.data);
+		delete_ifname(config.data);
+		writefile(statefile, sprintf("%J", config.data));
+	},
+	get_macaddr: function(args) {
+		let data = {};
+
+		for (let arg in args) {
+			arg = split(arg, "=", 2);
+			data[arg[0]] = arg[1];
+		}
+
+		let macaddr = phydev.macaddr_generate(data);
+		if (!macaddr) {
+			warn(`Could not get MAC address for phy ${phy}\n`);
+			exit(1);
+		}
+
+		print(macaddr + "\n");
+	},
+};
+
+if (!phy || !command | !commands[command])
+	usage();
+
+phydev = phy_open(phy);
+if (!phydev) {
+	warn(`PHY ${phy} does not exist\n`);
+	exit(1);
+}
+
+commands[command](ARGV);
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant.uc b/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant.uc
new file mode 100644
index 0000000..1709bb0
--- /dev/null
+++ b/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant.uc
@@ -0,0 +1,349 @@
+let libubus = require("ubus");
+import { open, readfile } from "fs";
+import { wdev_create, wdev_set_mesh_params, wdev_remove, is_equal, wdev_set_up, vlist_new, phy_open } from "common";
+
+let ubus = libubus.connect();
+
+wpas.data.config = {};
+wpas.data.iface_phy = {};
+wpas.data.macaddr_list = {};
+
+function iface_stop(iface)
+{
+	let ifname = iface.config.iface;
+
+	if (!iface.running)
+		return;
+
+	delete wpas.data.iface_phy[ifname];
+	wpas.remove_iface(ifname);
+	wdev_remove(ifname);
+	iface.running = false;
+}
+
+function iface_start(phydev, iface, macaddr_list)
+{
+	let phy = phydev.name;
+
+	if (iface.running)
+		return;
+
+	let ifname = iface.config.iface;
+	let wdev_config = {};
+	for (let field in iface.config)
+		wdev_config[field] = iface.config[field];
+	if (!wdev_config.macaddr)
+		wdev_config.macaddr = phydev.macaddr_next();
+
+	wpas.data.iface_phy[ifname] = phy;
+	wdev_remove(ifname);
+	let ret = wdev_create(phy, ifname, wdev_config);
+	if (ret)
+		wpas.printf(`Failed to create device ${ifname}: ${ret}`);
+	wdev_set_up(ifname, true);
+	wpas.add_iface(iface.config);
+	iface.running = true;
+}
+
+function iface_cb(new_if, old_if)
+{
+	if (old_if && new_if && is_equal(old_if.config, new_if.config)) {
+		new_if.running = old_if.running;
+		return;
+	}
+
+	if (new_if && old_if)
+		wpas.printf(`Update configuration for interface ${old_if.config.iface}`);
+	else if (old_if)
+		wpas.printf(`Remove interface ${old_if.config.iface}`);
+
+	if (old_if)
+		iface_stop(old_if);
+}
+
+function prepare_config(config)
+{
+	config.config_data = readfile(config.config);
+
+	return { config: config };
+}
+
+function set_config(phy_name, config_list)
+{
+	let phy = wpas.data.config[phy_name];
+
+	if (!phy) {
+		phy = vlist_new(iface_cb, false);
+		wpas.data.config[phy_name] = phy;
+	}
+
+	let values = [];
+	for (let config in config_list)
+		push(values, [ config.iface, prepare_config(config) ]);
+
+	phy.update(values);
+}
+
+function start_pending(phy_name)
+{
+	let phy = wpas.data.config[phy_name];
+	let ubus = wpas.data.ubus;
+
+	if (!phy || !phy.data)
+		return;
+
+	let phydev = phy_open(phy_name);
+	if (!phydev) {
+		wpas.printf(`Could not open phy ${phy_name}`);
+		return;
+	}
+
+	let macaddr_list = wpas.data.macaddr_list[phy_name];
+	phydev.macaddr_init(macaddr_list);
+
+	for (let ifname in phy.data)
+		iface_start(phydev, phy.data[ifname]);
+}
+
+let main_obj = {
+	phy_set_state: {
+		args: {
+			phy: "",
+			stop: true,
+		},
+		call: function(req) {
+			if (!req.args.phy || req.args.stop == null)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			let phy = wpas.data.config[req.args.phy];
+			if (!phy)
+				return libubus.STATUS_NOT_FOUND;
+
+			try {
+				if (req.args.stop) {
+					for (let ifname in phy.data)
+						iface_stop(phy.data[ifname]);
+				} else {
+					start_pending(req.args.phy);
+				}
+			} catch (e) {
+				wpas.printf(`Error chaging state: ${e}\n${e.stacktrace[0].context}`);
+				return libubus.STATUS_INVALID_ARGUMENT;
+			}
+			return 0;
+		}
+	},
+	phy_set_macaddr_list: {
+		args: {
+			phy: "",
+			macaddr: [],
+		},
+		call: function(req) {
+			let phy = req.args.phy;
+			if (!phy)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			wpas.data.macaddr_list[phy] = req.args.macaddr;
+			return 0;
+		}
+	},
+	phy_status: {
+		args: {
+			phy: ""
+		},
+		call: function(req) {
+			if (!req.args.phy)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			let phy = wpas.data.config[req.args.phy];
+			if (!phy)
+				return libubus.STATUS_NOT_FOUND;
+
+			for (let ifname in phy.data) {
+				try {
+					let iface = wpas.interfaces[ifname];
+					if (!iface)
+						continue;
+
+					let status = iface.status();
+					if (!status)
+						continue;
+
+					if (status.state == "INTERFACE_DISABLED")
+						continue;
+
+					status.ifname = ifname;
+					return status;
+				} catch (e) {
+					continue;
+				}
+			}
+
+			return libubus.STATUS_NOT_FOUND;
+		}
+	},
+	config_set: {
+		args: {
+			phy: "",
+			config: [],
+			defer: true,
+		},
+		call: function(req) {
+			if (!req.args.phy)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			wpas.printf(`Set new config for phy ${req.args.phy}`);
+			try {
+				if (req.args.config)
+					set_config(req.args.phy, req.args.config);
+
+				if (!req.args.defer)
+					start_pending(req.args.phy);
+			} catch (e) {
+				wpas.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`);
+				return libubus.STATUS_INVALID_ARGUMENT;
+			}
+
+			return {
+				pid: wpas.getpid()
+			};
+		}
+	},
+	config_add: {
+		args: {
+			driver: "",
+			iface: "",
+			bridge: "",
+			hostapd_ctrl: "",
+			ctrl: "",
+			config: "",
+		},
+		call: function(req) {
+			if (!req.args.iface || !req.args.config)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			if (wpas.add_iface(req.args) < 0)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			return {
+				pid: wpas.getpid()
+			};
+		}
+	},
+	config_remove: {
+		args: {
+			iface: ""
+		},
+		call: function(req) {
+			if (!req.args.iface)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			wpas.remove_iface(req.args.iface);
+			return 0;
+		}
+	},
+};
+
+wpas.data.ubus = ubus;
+wpas.data.obj = ubus.publish("wpa_supplicant", main_obj);
+wpas.udebug_set("wpa_supplicant", wpas.data.ubus);
+
+function iface_event(type, name, data) {
+	let ubus = wpas.data.ubus;
+
+	data ??= {};
+	data.name = name;
+	wpas.data.obj.notify(`iface.${type}`, data, null, null, null, -1);
+	ubus.call("service", "event", { type: `wpa_supplicant.${name}.${type}`, data: {} });
+}
+
+function iface_hostapd_notify(phy, ifname, iface, state)
+{
+	let ubus = wpas.data.ubus;
+	let status = iface.status();
+	let msg = { phy: phy };
+
+	switch (state) {
+	case "DISCONNECTED":
+	case "AUTHENTICATING":
+	case "SCANNING":
+		msg.up = false;
+		break;
+	case "INTERFACE_DISABLED":
+	case "INACTIVE":
+		msg.up = true;
+		break;
+	case "COMPLETED":
+		msg.up = true;
+		msg.frequency = status.frequency;
+		msg.sec_chan_offset = status.sec_chan_offset;
+		break;
+	default:
+		return;
+	}
+
+	ubus.call("hostapd", "apsta_state", msg);
+}
+
+function iface_channel_switch(phy, ifname, iface, info)
+{
+	let msg = {
+		phy: phy,
+		up: true,
+		csa: true,
+		csa_count: info.csa_count ? info.csa_count - 1 : 0,
+		frequency: info.frequency,
+		sec_chan_offset: info.sec_chan_offset,
+	};
+	ubus.call("hostapd", "apsta_state", msg);
+}
+
+return {
+	shutdown: function() {
+		for (let phy in wpas.data.config)
+			set_config(phy, []);
+		wpas.ubus.disconnect();
+	},
+	iface_add: function(name, obj) {
+		iface_event("add", name);
+	},
+	iface_remove: function(name, obj) {
+		iface_event("remove", name);
+	},
+	state: function(ifname, iface, state) {
+		let phy = wpas.data.iface_phy[ifname];
+		if (!phy) {
+			wpas.printf(`no PHY for ifname ${ifname}`);
+			return;
+		}
+
+		iface_hostapd_notify(phy, ifname, iface, state);
+
+		if (state != "COMPLETED")
+			return;
+
+		let phy_data = wpas.data.config[phy];
+		if (!phy_data)
+			return;
+
+		let iface_data = phy_data.data[ifname];
+		if (!iface_data)
+			return;
+
+		let wdev_config = iface_data.config;
+		if (!wdev_config || wdev_config.mode != "mesh")
+			return;
+
+		wdev_set_mesh_params(ifname, wdev_config);
+	},
+	event: function(ifname, iface, ev, info) {
+		let phy = wpas.data.iface_phy[ifname];
+		if (!phy) {
+			wpas.printf(`no PHY for ifname ${ifname}`);
+			return;
+		}
+
+		if (ev == "CH_SWITCH_STARTED")
+			iface_channel_switch(phy, ifname, iface, info);
+	}
+};
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant/ucode.c b/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant/ucode.c
index 6cba73d..397f85b 100644
--- a/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant/ucode.c
+++ b/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant/ucode.c
@@ -262,6 +262,7 @@
 		{ "getpid", uc_wpa_getpid },
 		{ "add_iface", uc_wpas_add_iface },
 		{ "remove_iface", uc_wpas_remove_iface },
+		{ "udebug_set", uc_wpa_udebug_set },
 	};
 	static const uc_function_list_t iface_fns[] = {
 		{ "status", uc_wpas_iface_status },
diff --git a/recipes-wifi/hostapd/hostapd_2.10.3.bb b/recipes-wifi/hostapd/hostapd_2.10.3.bb
index 60a40d9..02af874 100644
--- a/recipes-wifi/hostapd/hostapd_2.10.3.bb
+++ b/recipes-wifi/hostapd/hostapd_2.10.3.bb
@@ -4,7 +4,7 @@
 LICENSE = "BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://hostapd/README;md5=c905478466c90f1cefc0df987c40e172"
 
-DEPENDS = "libnl-tiny openssl ubus ucode"
+DEPENDS = "libnl-tiny openssl ubus ucode udebug"
 DEPENDS_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'telemetry2_0', 'telemetry', '', d)}"
 LDFLAGS_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'telemetry2_0', ' -ltelemetry_msgsender ', '', d)}"
 RDEPENDS_${PN} += "gawk ucode"
diff --git a/recipes-wifi/libnl-tiny/libnl-tiny_git.bb b/recipes-wifi/libnl-tiny/libnl-tiny_git.bb
index d2a127b..1989e9a 100644
--- a/recipes-wifi/libnl-tiny/libnl-tiny_git.bb
+++ b/recipes-wifi/libnl-tiny/libnl-tiny_git.bb
@@ -5,7 +5,7 @@
 SECTION = "libs"
 
 SRC_URI = "git://git.openwrt.org/project/libnl-tiny.git"
-SRCREV = "bc92a280186f9becc53c0f17e4e43cfbdeec7e7b"
+SRCREV = "965c4bf49658342ced0bd6e7cb069571b4a1ddff"
 PV = "git${SRCPV}"
 
 inherit cmake pkgconfig
diff --git a/recipes-wifi/libubox/libubox_git.bbappend b/recipes-wifi/libubox/libubox_git.bbappend
index 5bc09d3..ad9df96 100644
--- a/recipes-wifi/libubox/libubox_git.bbappend
+++ b/recipes-wifi/libubox/libubox_git.bbappend
@@ -1,3 +1,6 @@
 SRC_URI_remove = "file://0001-blobmsg-fix-array-out-of-bounds-GCC-10-warning.patch"
 
-SRCREV = "75a3b870cace1171faf57bd55e5a9a2f1564f757"
+wifi6_ver = "b14c4688612c05c78ce984d7bde633bce8703b1e"
+wifi7_ver = "ca3f6d0cdb1e588283c42d039779ceab303ceef2"
+
+SRCREV = "${@bb.utils.contains('DISTRO_FEATURES', 'wifi_eht', '${wifi7_ver}', '${wifi6_ver}', d)}"
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/220-list-don-t-backport-list_count_nodes.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/220-list-don-t-backport-list_count_nodes.patch
new file mode 100644
index 0000000..6d30002
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/220-list-don-t-backport-list_count_nodes.patch
@@ -0,0 +1,26 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Fri, 15 Dec 2023 10:17:21 +0100
+Subject: [PATCH] list: don't backport list_count_nodes()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It's redundant in OpenWrt as it backports it on its own. This fixes:
+backport-include/linux/list.h:11:22: error: redefinition of 'list_count_nodes'
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+ backport-include/linux/list.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- 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/recipes-wifi/linux-mac80211/files/patches-6.x/build/build.inc b/recipes-wifi/linux-mac80211/files/patches-6.x/build/build.inc
index fc9e402..5a294e9 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/build/build.inc
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/build.inc
@@ -16,4 +16,5 @@
     file://130-iommu_backport.patch \
     file://200-Revert-wifi-iwlwifi-Use-generic-thermal_zone_get_tri.patch \
     file://210-revert-split-op.patch \
+    file://220-list-don-t-backport-list_count_nodes.patch \
     "
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0001-Revert-mac80211-use-the-new-drop-reasons-infrastruct.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0001-backports-Revert-mac80211-use-the-new-drop-reasons-i.patch
similarity index 94%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0001-Revert-mac80211-use-the-new-drop-reasons-infrastruct.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0001-backports-Revert-mac80211-use-the-new-drop-reasons-i.patch
index 8e924dc..f57a7ad 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0001-Revert-mac80211-use-the-new-drop-reasons-infrastruct.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0001-backports-Revert-mac80211-use-the-new-drop-reasons-i.patch
@@ -1,7 +1,8 @@
-From e6a3cf0e4fd98f36be9352b92d40cfeb79993fc9 Mon Sep 17 00:00:00 2001
+From db3959a15f33f3e37d263c4b148fce338fb9fbc3 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Mon, 21 Aug 2023 14:20:49 +0800
-Subject: [PATCH] Revert mac80211: use the new drop reasons infrastructure
+Subject: [PATCH 01/40] backports: Revert mac80211: use the new drop reasons
+ infrastructure
 
 ---
  net/mac80211/drop.h        | 56 --------------------------------------
@@ -75,7 +76,7 @@
 -
 -#endif /* MAC80211_DROP_H */
 diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
-index 9fdfd11..7ca2482 100644
+index 06eb64e..be3fa32 100644
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
 @@ -33,7 +33,6 @@
@@ -86,7 +87,7 @@
  
  extern const struct cfg80211_ops mac80211_config_ops;
  
-@@ -171,6 +170,13 @@ struct ieee80211_tx_data {
+@@ -173,6 +172,13 @@ struct ieee80211_tx_data {
  	unsigned int flags;
  };
  
@@ -101,7 +102,7 @@
   * enum ieee80211_packet_rx_flags - packet RX flags
   * @IEEE80211_RX_AMSDU: a-MSDU packet
 diff --git a/net/mac80211/main.c b/net/mac80211/main.c
-index c2f25a4..e2f7ae5 100644
+index ec4a930..6fec8ff 100644
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
 @@ -22,7 +22,6 @@
@@ -112,7 +113,7 @@
  #include <net/cfg80211.h>
  #include <net/addrconf.h>
  
-@@ -1544,28 +1543,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
+@@ -1523,28 +1522,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
  }
  EXPORT_SYMBOL(ieee80211_free_hw);
  
@@ -141,7 +142,7 @@
  static int __init ieee80211_init(void)
  {
  	struct sk_buff *skb;
-@@ -1583,11 +1560,6 @@ static int __init ieee80211_init(void)
+@@ -1562,11 +1539,6 @@ static int __init ieee80211_init(void)
  	if (ret)
  		goto err_netdev;
  
@@ -153,7 +154,7 @@
  	return 0;
   err_netdev:
  	rc80211_minstrel_exit();
-@@ -1603,9 +1575,6 @@ static void __exit ieee80211_exit(void)
+@@ -1582,9 +1554,6 @@ static void __exit ieee80211_exit(void)
  
  	ieee80211_iface_exit();
  
@@ -164,7 +165,7 @@
  }
  
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 491047d..8ffe90d 100644
+index e9f73cb..d1a834d 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
 @@ -1828,7 +1828,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
@@ -194,7 +195,7 @@
  		if (rx->link_sta) {
  			if (ieee80211_is_group_privacy_action(skb) &&
  			    test_sta_flag(rx->sta, WLAN_STA_MFP))
-@@ -3981,8 +3981,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
+@@ -3988,8 +3988,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
  }
  
  static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
@@ -204,7 +205,7 @@
  {
  	struct ieee80211_sub_if_data *sdata;
  	struct ieee80211_local *local = rx->local;
-@@ -4046,38 +4045,42 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
+@@ -4053,38 +4052,42 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
  	}
  
   out_free_skb:
@@ -377,5 +378,5 @@
  		kfree(mic);
  	}
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0002-backports-update-kernel-version-check-for-eth_hw_add.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0002-backports-update-kernel-version-check-for-eth_hw_add.patch
index 5d91314..77071e5 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0002-backports-update-kernel-version-check-for-eth_hw_add.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0002-backports-update-kernel-version-check-for-eth_hw_add.patch
@@ -1,14 +1,13 @@
-From 085740016672333854d07d4ae266b6fa15103936 Mon Sep 17 00:00:00 2001
+From aa09e81d195b255f89ab46f2b4455ce4de29fee1 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] backports: update kernel version check for eth_hw_addr_set()
+Subject: [PATCH 02/40] 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.
 
-CR-Id: WCNCR00238098
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: I708aabbe51de9d480932ce03b30d004bf1d67ebd
 ---
  backport-include/linux/etherdevice.h | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
@@ -36,4 +35,5 @@
  #if LINUX_VERSION_IS_LESS(5,16,0)
  static inline int backport_device_get_mac_address(struct device *dev, char *addr)
 -- 
-2.18.0
\ No newline at end of file
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0003-backports-Revert-cfg80211-allow-grace-period-for-DFS.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0003-backports-Revert-cfg80211-allow-grace-period-for-DFS.patch
new file mode 100644
index 0000000..85ed645
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0003-backports-Revert-cfg80211-allow-grace-period-for-DFS.patch
@@ -0,0 +1,177 @@
+From e8e5a4977e817047060b36827e835bc26194b5c1 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 19 Oct 2023 09:59:24 +0800
+Subject: [PATCH 03/40] backports: Revert cfg80211: allow grace period for DFS
+ available after beacon shutdown
+
+revert 320-cfg80211-allow-grace-period-for-DFS-available-after-.patch
+This patch will lead to channel switch fail when background radar is
+enabled.
+When AP channel switch to USABLE DFS channel,
+1. AP will restart, and the DFS state of the previously operated DFS channel
+   will not be cleared immediately if this patch is applied.
+2. Background radar will perform CAC on the specified DFS channel for AP.
+3. AP will choose an AVAILABLE channel to operate on.
+Therefore, AP might select those DFS channels whose DFS state would be
+cleared after the grace period, resulting in channel switch failure.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h |  3 ---
+ net/wireless/ap.c      |  6 +++---
+ net/wireless/chan.c    | 45 ------------------------------------------
+ net/wireless/core.h    |  2 --
+ net/wireless/mlme.c    |  7 +++----
+ 5 files changed, 6 insertions(+), 57 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 45068d6..7676475 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -175,8 +175,6 @@ 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.
+- * @dfs_state_last_available: timestamp (jiffies) of the last time when the
+- *	channel was available.
+  * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
+  */
+ struct ieee80211_channel {
+@@ -193,7 +191,6 @@ struct ieee80211_channel {
+ 	int orig_mag, orig_mpwr;
+ 	enum nl80211_dfs_state dfs_state;
+ 	unsigned long dfs_state_entered;
+-	unsigned long dfs_state_last_available;
+ 	unsigned int dfs_cac_ms;
+ };
+ 
+diff --git a/net/wireless/ap.c b/net/wireless/ap.c
+index 63641aa..0962770 100644
+--- a/net/wireless/ap.c
++++ b/net/wireless/ap.c
+@@ -30,9 +30,6 @@ static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
+ 	if (!wdev->links[link_id].ap.beacon_interval)
+ 		return -ENOENT;
+ 
+-	cfg80211_update_last_available(wdev->wiphy,
+-				       &wdev->links[link_id].ap.chandef);
+-
+ 	err = rdev_stop_ap(rdev, dev, link_id);
+ 	if (!err) {
+ 		wdev->conn_owner_nlportid = 0;
+@@ -44,6 +41,9 @@ static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
+ 		if (notify)
+ 			nl80211_send_ap_stopped(wdev, link_id);
+ 
++		/* Should we apply the grace period during beaconing interface
++		 * shutdown also?
++		 */
+ 		cfg80211_sched_dfs_chan_update(rdev);
+ 	}
+ 
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index 3750cb9..37ed7c6 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -461,8 +461,6 @@ static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
+ 
+ 		c->dfs_state = dfs_state;
+ 		c->dfs_state_entered = jiffies;
+-		if (dfs_state == NL80211_DFS_AVAILABLE)
+-			c->dfs_state_last_available = jiffies;
+ 	}
+ }
+ 
+@@ -875,49 +873,6 @@ static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
+ 	return true;
+ }
+ 
+-static void
+-__cfg80211_update_last_available(struct wiphy *wiphy,
+-					 u32 center_freq,
+-					 u32 bandwidth)
+-{
+-	struct ieee80211_channel *c;
+-	u32 freq, start_freq, end_freq;
+-
+-	start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
+-	end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+-
+-	/*
+-	 * Check entire range of channels for the bandwidth.
+-	 * If any channel in between is disabled or has not
+-	 * had gone through CAC return false
+-	 */
+-	for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+-		c = ieee80211_get_channel_khz(wiphy, freq);
+-		if (!c)
+-			return;
+-
+-		c->dfs_state_last_available = jiffies;
+-	}
+-}
+-
+-void cfg80211_update_last_available(struct wiphy *wiphy,
+-				    const struct cfg80211_chan_def *chandef)
+-{
+-	int width;
+-
+-	width = cfg80211_chandef_get_width(chandef);
+-	if (width < 0)
+-		return;
+-
+-	__cfg80211_update_last_available(wiphy, MHZ_TO_KHZ(chandef->center_freq1),
+-						 width);
+-	if (chandef->width != NL80211_CHAN_WIDTH_80P80)
+-	    return;
+-
+-	__cfg80211_update_last_available(wiphy, MHZ_TO_KHZ(chandef->center_freq2),
+-						 width);
+-}
+-
+ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
+ 				const struct cfg80211_chan_def *chandef)
+ {
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index a8da284..70fc2e6 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -487,8 +487,6 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
+ 			    enum nl80211_dfs_state dfs_state);
+ 
+ void cfg80211_dfs_channels_update_work(struct work_struct *work);
+-void cfg80211_update_last_available(struct wiphy *wiphy,
+-				    const struct cfg80211_chan_def *chandef);
+ 
+ unsigned int
+ cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index f6e2c2d..8b87bc9 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -915,8 +915,6 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
+ 			if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
+ 				time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
+ 				radar_event = NL80211_RADAR_NOP_FINISHED;
+-				timeout = c->dfs_state_entered +
+-					  msecs_to_jiffies(time_dfs_update);
+ 			} else {
+ 				if (regulatory_pre_cac_allowed(wiphy) ||
+ 				    cfg80211_any_wiphy_oper_chan(wiphy, c))
+@@ -924,10 +922,11 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
+ 
+ 				time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
+ 				radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
+-				timeout = c->dfs_state_last_available +
+-					  msecs_to_jiffies(time_dfs_update);
+ 			}
+ 
++			timeout = c->dfs_state_entered +
++				  msecs_to_jiffies(time_dfs_update);
++
+ 			if (time_after_eq(jiffies, timeout)) {
+ 				c->dfs_state = NL80211_DFS_USABLE;
+ 				c->dfs_state_entered = jiffies;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0001-mac80211-mtk-do-not-setup-twt-when-twt-responder-is-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0001-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch
similarity index 67%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0001-mac80211-mtk-do-not-setup-twt-when-twt-responder-is-.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0001-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch
index c52c759..31d3017 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0001-mac80211-mtk-do-not-setup-twt-when-twt-responder-is-.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0001-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch
@@ -1,7 +1,7 @@
-From 5369b107bbb17d2152f7690f3fc91a135f05a88c Mon Sep 17 00:00:00 2001
+From f85b69219664d26546f95885c7466d4fa08fb08c 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 01/21] mac80211: mtk: do not setup twt when twt responder is
+Subject: [PATCH 01/37] 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 8ffe90d..56abe67 100644
+index d1a834d..15bb653 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3416,6 +3416,9 @@ ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
+@@ -3423,6 +3423,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/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch
similarity index 89%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch
index 2a60dc4..a59fc0b 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch
@@ -1,7 +1,7 @@
-From 9b4ed2d99cc24c50bef088ee2bc48047d4e17c97 Mon Sep 17 00:00:00 2001
+From 22f7b334932cbab63060ba390e917a57cc7779f8 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 02/21] cfg80211: mtk: extend CAC time for weather radar
+Subject: [PATCH 02/37] mtk: cfg80211: extend CAC time for weather radar
  channels
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
@@ -13,7 +13,7 @@
  3 files changed, 11 insertions(+)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 3e0a190..32df498 100644
+index 7676475..d9a7828 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
 @@ -149,6 +149,7 @@ enum ieee80211_channel_flags {
@@ -25,7 +25,7 @@
  
  /**
 diff --git a/net/wireless/chan.c b/net/wireless/chan.c
-index d5ed976..caa5acc 100644
+index 37ed7c6..e250830 100644
 --- a/net/wireless/chan.c
 +++ b/net/wireless/chan.c
 @@ -931,6 +931,13 @@ static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
@@ -43,7 +43,7 @@
  			dfs_cac_ms = c->dfs_cac_ms;
  	}
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 6d62c81..3ec073a 100644
+index 8a6e2c0..12943c7 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
 @@ -9992,6 +9992,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
@@ -57,5 +57,5 @@
  	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/mtk-0003-mac80211-mtk-it-s-invalid-case-when-frag_threshold-i.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0003-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch
similarity index 79%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0003-mac80211-mtk-it-s-invalid-case-when-frag_threshold-i.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0003-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch
index a68441f..e0d44a7 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0003-mac80211-mtk-it-s-invalid-case-when-frag_threshold-i.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0003-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch
@@ -1,7 +1,7 @@
-From 395e1cebc680455965b24fe771efaae400439acc Mon Sep 17 00:00:00 2001
+From c81bb69d6904835e4e5601c150dedc9743d2e58b 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 03/21] mac80211: mtk: it's invalid case when frag_threshold is
+Subject: [PATCH 03/37] mtk: mac80211: it's invalid case when frag_threshold is
  greater than 2346
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 3 insertions(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 3ec073a..e0ee534 100644
+index 12943c7..4a12891 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
 @@ -3650,6 +3650,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
@@ -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/mtk-0004-mac80211-mtk-airtime_flags-depends-on-NL80211_EXT_FE.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0004-mac80211-mtk-airtime_flags-depends-on-NL80211_EXT_FE.patch
deleted file mode 100644
index 5eb6ee7..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0004-mac80211-mtk-airtime_flags-depends-on-NL80211_EXT_FE.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 7b34ccae1fef44bc222e9ff6313fa6c57f962b92 Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Wed, 19 Oct 2022 13:42:43 +0800
-Subject: [PATCH 04/21] mac80211: mtk: airtime_flags depends on
- NL80211_EXT_FEATURE
-
-Signed-off-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
----
- net/mac80211/main.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/net/mac80211/main.c b/net/mac80211/main.c
-index e2f7ae5..0188e6a 100644
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -798,8 +798,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
- 			IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H;
- 		atomic_set(&local->aql_ac_pending_airtime[i], 0);
- 	}
--
--	local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
-+	if (wiphy_ext_feature_isset(local->hw.wiphy,
-+			NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
-+		local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
- 	local->aql_threshold = IEEE80211_AQL_THRESHOLD;
- 	atomic_set(&local->aql_total_pending_airtime, 0);
- 
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0005-mac80211-mtk-add-support-for-runtime-set-inband-disc.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0004-mtk-mac80211-add-support-for-runtime-set-inband-disc.patch
similarity index 95%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0005-mac80211-mtk-add-support-for-runtime-set-inband-disc.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0004-mtk-mac80211-add-support-for-runtime-set-inband-disc.patch
index 66a784d..9b8b212 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0005-mac80211-mtk-add-support-for-runtime-set-inband-disc.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0004-mtk-mac80211-add-support-for-runtime-set-inband-disc.patch
@@ -1,7 +1,8 @@
-From f6907ff7ff3669e73f64f802de10346bfd1d24d8 Mon Sep 17 00:00:00 2001
+From b3f657e7a0ce98c986b3b803a963820d98d82c7f Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Wed, 19 Oct 2022 13:45:42 +0800
-Subject: [PATCH] mac80211: mtk: add support for runtime set inband discovery
+Subject: [PATCH 04/37] mtk: mac80211: add support for runtime set inband
+ discovery
 
 Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
 ---
@@ -13,10 +14,10 @@
  5 files changed, 60 insertions(+), 6 deletions(-)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 072a787..02e342e 100644
+index d9a7828..204d1a4 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -1309,6 +1309,7 @@ struct cfg80211_fils_discovery {
+@@ -1355,6 +1355,7 @@ struct cfg80211_fils_discovery {
  	u32 max_interval;
  	size_t tmpl_len;
  	const u8 *tmpl;
@@ -106,7 +107,7 @@
  	return 0;
  }
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index e0ee534..ff8afa5 100644
+index 4a12891..680511a 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
 @@ -423,6 +423,7 @@ nl80211_fils_discovery_policy[NL80211_FILS_DISCOVERY_ATTR_MAX + 1] = {
@@ -178,5 +179,5 @@
  }
  
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0006-cfg80211-mtk-implement-DFS-status-show-cac-and-nop-s.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0005-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch
similarity index 97%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0006-cfg80211-mtk-implement-DFS-status-show-cac-and-nop-s.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0005-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch
index b2408ad..5a839f2 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0006-cfg80211-mtk-implement-DFS-status-show-cac-and-nop-s.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0005-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch
@@ -1,7 +1,7 @@
-From cbb9327b27651e375f72783e9c2453a2474f3ad3 Mon Sep 17 00:00:00 2001
+From 1217977018874b810cc295ea631684876b108a4b 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 06/21] cfg80211: mtk: implement DFS status show, cac and nop
+Subject: [PATCH 05/37] mtk: cfg80211: implement DFS status show, cac and nop
  skip command via debugfs
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,10 +16,10 @@
  7 files changed, 360 insertions(+), 7 deletions(-)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 7ba5fe9..cd0ec8a 100644
+index 204d1a4..0c9bb5c 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -4768,6 +4768,7 @@ struct cfg80211_ops {
+@@ -4817,6 +4817,7 @@ 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);
@@ -28,10 +28,10 @@
  
  /*
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index a78ee52..8033b2f 100644
+index baff0e6..0e67d89 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -5049,6 +5049,25 @@ static int ieee80211_set_hw_timestamp(struct wiphy *wiphy,
+@@ -5048,6 +5048,25 @@ static int ieee80211_set_hw_timestamp(struct wiphy *wiphy,
  	return local->ops->set_hw_timestamp(&local->hw, &sdata->vif, hwts);
  }
  
@@ -57,7 +57,7 @@
  const struct cfg80211_ops mac80211_config_ops = {
  	.add_virtual_intf = ieee80211_add_iface,
  	.del_virtual_intf = ieee80211_del_iface,
-@@ -5161,4 +5180,5 @@ const struct cfg80211_ops mac80211_config_ops = {
+@@ -5160,4 +5179,5 @@ 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,
@@ -496,5 +496,5 @@
  
  #undef TRACE_INCLUDE_PATH
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0007-mac80211-mtk-Set-TWT-Information-Frame-Disabled-bit-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0006-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch
similarity index 85%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0007-mac80211-mtk-Set-TWT-Information-Frame-Disabled-bit-.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0006-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch
index 5276b39..bfc573f 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0007-mac80211-mtk-Set-TWT-Information-Frame-Disabled-bit-.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0006-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch
@@ -1,7 +1,7 @@
-From c1fac970b782b1d6786f3ec59abc995d84374ceb Mon Sep 17 00:00:00 2001
+From 4a5ee80eab091e6481f2ebd05cb736eaba82c936 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 07/21] mac80211: mtk: Set TWT Information Frame Disabled bit
+Subject: [PATCH 06/37] 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/mtk-0008-mac80211-mtk-check-the-control-channel-before-downgr.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0007-mtk-mac80211-check-the-control-channel-before-downgr.patch
similarity index 91%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0008-mac80211-mtk-check-the-control-channel-before-downgr.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0007-mtk-mac80211-check-the-control-channel-before-downgr.patch
index 6c614fe..458d245 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0008-mac80211-mtk-check-the-control-channel-before-downgr.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0007-mtk-mac80211-check-the-control-channel-before-downgr.patch
@@ -1,7 +1,7 @@
-From cc5889f25d7d72cf4ecbaefbe885ad654d50e730 Mon Sep 17 00:00:00 2001
+From 5a69533bf3617ac9fad84e0759c06868552bc35b 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 08/21] mac80211: mtk: check the control channel before
+Subject: [PATCH 07/37] mtk: mac80211: check the control channel before
  downgrading the bandwidth
 
 ---
@@ -50,5 +50,5 @@
  		*conn_flags |=
  			ieee80211_chandef_downgrade(&chandef);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0009-mac80211-mtk-fix-tx-amsdu-aggregation.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0008-mtk-mac80211-fix-tx-amsdu-aggregation.patch
similarity index 93%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0009-mac80211-mtk-fix-tx-amsdu-aggregation.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0008-mtk-mac80211-fix-tx-amsdu-aggregation.patch
index a505811..b23d498 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0009-mac80211-mtk-fix-tx-amsdu-aggregation.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0008-mtk-mac80211-fix-tx-amsdu-aggregation.patch
@@ -1,7 +1,7 @@
-From 3a7bbbffc4870e413856f3f3d7e54066117d13ed Mon Sep 17 00:00:00 2001
+From a547f34675e8b65dabdd8ef438633cd4e467b550 Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Wed, 14 Dec 2022 00:26:50 -0800
-Subject: [PATCH 09/21] mac80211: mtk: fix tx amsdu aggregation
+Subject: [PATCH 08/37] mtk: mac80211: fix tx amsdu aggregation
 
 ---
  include/net/mac80211.h | 7 +++++++
@@ -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/mtk-0010-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-id.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0009-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch
similarity index 96%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0010-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-id.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0009-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch
index d121c4f..fdec67c 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0010-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-id.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0009-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch
@@ -1,7 +1,7 @@
-From 66fbfef0e7ae77359c9609aeec93a31463af59b4 Mon Sep 17 00:00:00 2001
+From 02b742ba338449626cd3435bddb5cfe7219d0ce8 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 10/21] mac80211: mtk: add fill receive path ops to get wed idx
+Subject: [PATCH 09/37] mtk: mac80211: add fill receive path ops to get wed idx
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
@@ -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/mtk-0011-mac80211-mtk-fix-build-error-on-Linux-Kernel-5.4.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0010-mtk-mac80211-fix-build-error-on-Linux-Kernel-5.4.patch
similarity index 95%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0011-mac80211-mtk-fix-build-error-on-Linux-Kernel-5.4.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0010-mtk-mac80211-fix-build-error-on-Linux-Kernel-5.4.patch
index a75e19c..750d038 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0011-mac80211-mtk-fix-build-error-on-Linux-Kernel-5.4.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0010-mtk-mac80211-fix-build-error-on-Linux-Kernel-5.4.patch
@@ -1,7 +1,7 @@
-From d0528e1e6fffdb620314bb7934cdab4971e02e77 Mon Sep 17 00:00:00 2001
+From f647704869b94f0fba01631043b733edc48c6e74 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Tue, 13 Dec 2022 09:04:49 +0800
-Subject: [PATCH 11/21] mac80211: mtk: fix build error on Linux Kernel 5.4
+Subject: [PATCH 10/37] mtk: mac80211: fix build error on Linux Kernel 5.4
 
 ---
  include/linux/ieee80211.h          |  8 +++-----
@@ -30,7 +30,7 @@
  	u8 addr4[ETH_ALEN];
  } __packed __aligned(2);
 diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
-index e916130..c09147f 100644
+index 3562903..3768947 100644
 --- a/net/mac80211/rc80211_minstrel_ht.c
 +++ b/net/mac80211/rc80211_minstrel_ht.c
 @@ -10,7 +10,9 @@
@@ -66,7 +66,7 @@
  
  
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index ff8afa5..0ed3f51 100644
+index 680511a..15e3eeb 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
 @@ -461,11 +461,6 @@ nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
@@ -115,5 +115,5 @@
  	.resv_start_op = NL80211_CMD_REMOVE_LINK_STA + 1,
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0012-mac80211-mtk-track-obss-color-bitmap.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0011-mtk-mac80211-track-obss-color-bitmap.patch
similarity index 90%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0012-mac80211-mtk-track-obss-color-bitmap.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0011-mtk-mac80211-track-obss-color-bitmap.patch
index 31811d3..0e77267 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0012-mac80211-mtk-track-obss-color-bitmap.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0011-mtk-mac80211-track-obss-color-bitmap.patch
@@ -1,7 +1,7 @@
-From 529ea5156b39398b24801eabcb3f1531ca53d3ca Mon Sep 17 00:00:00 2001
+From 5b3511b6e6820f608082df886bf2bdb9cc0c429b 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 12/21] mac80211: mtk: track obss color bitmap
+Subject: [PATCH 11/37] mtk: mac80211: track obss color bitmap
 
 Track OBSS BSS color when receive their beacon.
 
@@ -27,10 +27,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 56abe67..cf41b93 100644
+index 15bb653..65ff365 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3349,9 +3349,13 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
+@@ -3356,9 +3356,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);
@@ -78,5 +78,5 @@
  
  #undef TRACE_INCLUDE_PATH
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0013-mac80211-mtk-ageout-color-bitmap.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0012-mtk-mac80211-ageout-color-bitmap.patch
similarity index 91%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0013-mac80211-mtk-ageout-color-bitmap.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0012-mtk-mac80211-ageout-color-bitmap.patch
index 4531d85..d55f44f 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0013-mac80211-mtk-ageout-color-bitmap.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0012-mtk-mac80211-ageout-color-bitmap.patch
@@ -1,7 +1,7 @@
-From 31b5d2289d106c9d0f55ea501182080ca1d52a72 Mon Sep 17 00:00:00 2001
+From 5137077a48ee6eff2910863341d137b4448a6382 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Mon, 13 Mar 2023 05:36:59 +0800
-Subject: [PATCH 13/21] mac80211: mtk: ageout color bitmap
+Subject: [PATCH 12/37] mtk: mac80211: ageout color bitmap
 
 Adding a periodic work which runs once per second to check BSS color.
 OBSS BSS Color will be ageout if not seen for 10 seconds.
@@ -27,10 +27,10 @@
  	u32 unsol_bcast_probe_resp_interval;
  	struct cfg80211_bitrate_mask beacon_tx_rate;
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 8033b2f..177409d 100644
+index 0e67d89..22bff46 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -4881,6 +4881,36 @@ out:
+@@ -4880,6 +4880,36 @@ out:
  	return err;
  }
  
@@ -68,10 +68,10 @@
  ieee80211_set_radar_background(struct wiphy *wiphy,
  			       struct cfg80211_chan_def *chandef)
 diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
-index 7ca2482..1fa9641 100644
+index be3fa32..35452b0 100644
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -996,6 +996,7 @@ struct ieee80211_link_data {
+@@ -998,6 +998,7 @@ struct ieee80211_link_data {
  
  	struct work_struct color_change_finalize_work;
  	struct delayed_work color_collision_detect_work;
@@ -79,7 +79,7 @@
  	u64 color_bitmap;
  
  	/* context reservation -- protected with chanctx_mtx */
-@@ -1993,9 +1994,13 @@ void ieee80211_csa_finalize_work(struct work_struct *work);
+@@ -1995,9 +1996,13 @@ void ieee80211_csa_finalize_work(struct work_struct *work);
  int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
  			     struct cfg80211_csa_settings *params);
  
@@ -130,10 +130,10 @@
  	if (!deflink) {
  		switch (sdata->vif.type) {
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index cf41b93..e245f31 100644
+index 65ff365..a3b4cac 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3351,6 +3351,7 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
+@@ -3358,6 +3358,7 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
  				      IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
  
  		bss_conf->used_color_bitmap |= BIT_ULL(color);
@@ -142,5 +142,5 @@
  		// trace_bss_color_bitmap(color, bss_conf->used_color_bitmap);
  		if (color == bss_conf->he_bss_color.color)
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0013-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0013-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch
new file mode 100644
index 0000000..5d0beff
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0013-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch
@@ -0,0 +1,39 @@
+From 5deaec7265ca0cf5f25168996dd1a779b747f9c7 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Fri, 14 Apr 2023 05:05:17 +0800
+Subject: [PATCH 13/37] mtk: mac80211: update max_bssid_indicator based on real
+ BSS numbers
+
+---
+ net/mac80211/cfg.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 22bff46..916332c 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1183,9 +1183,11 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+ 	/* copy in optional mbssid_ies */
+ 	if (mbssid) {
+ 		u8 *pos = new->tail + new->tail_len;
++		u8 *bssid_indicator;
+ 
+ 		new->mbssid_ies = (void *)pos;
+ 		pos += struct_size(new->mbssid_ies, elem, mbssid->cnt);
++		bssid_indicator = pos + 2;
+ 		pos += ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies,
+ 						    mbssid);
+ 		if (rnr) {
+@@ -1194,8 +1196,7 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+ 			ieee80211_copy_rnr_beacon(pos, new->rnr_ies, rnr);
+ 		}
+ 		/* update bssid_indicator */
+-		link_conf->bssid_indicator =
+-			ilog2(__roundup_pow_of_two(mbssid->cnt + 1));
++		sdata->vif.bss_conf.bssid_indicator = *(bssid_indicator);
+ 	}
+ 
+ 	if (csa) {
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0014-mac80211-mtk-update-max_bssid_indicator-based-on-rea.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0014-mac80211-mtk-update-max_bssid_indicator-based-on-rea.patch
deleted file mode 100644
index 8d2b34d..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0014-mac80211-mtk-update-max_bssid_indicator-based-on-rea.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 928dff74ea4777892a48de4d9a8e1385bf4cab81 Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Fri, 14 Apr 2023 05:05:17 +0800
-Subject: [PATCH 14/21] mac80211: mtk: update max_bssid_indicator based on real
- BSS numbers
-
----
- net/mac80211/cfg.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 177409d..9724258 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1194,8 +1194,7 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
- 			ieee80211_copy_rnr_beacon(pos, new->rnr_ies, rnr);
- 		}
- 		/* update bssid_indicator */
--		link_conf->bssid_indicator =
--			ilog2(__roundup_pow_of_two(mbssid->cnt + 1));
-+		sdata->vif.bss_conf.bssid_indicator = *(pos + 2);
- 	}
- 
- 	if (csa) {
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-support-configurable-addba-resp-time.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0014-mtk-mac80211-support-configurable-addba-resp-time.patch
similarity index 89%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-support-configurable-addba-resp-time.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0014-mtk-mac80211-support-configurable-addba-resp-time.patch
index de32d4e..ed85667 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-support-configurable-addba-resp-time.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0014-mtk-mac80211-support-configurable-addba-resp-time.patch
@@ -1,7 +1,7 @@
-From 41a81ced950b4f97331f964b8ad67b773b5dcd7a Mon Sep 17 00:00:00 2001
+From 579cfe869588f2d21ed98428b976242c6b7e63a1 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 15/21] support configurable addba resp time.
+Subject: [PATCH 14/37] mtk: mac80211: support configurable addba resp time.
 
 ---
  net/mac80211/agg-tx.c | 8 +++++++-
@@ -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/mtk-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch
similarity index 94%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch
index 945a5bd..7067429 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch
@@ -1,7 +1,7 @@
-From e2aa2e712fbebfbbb2338debd632d83157d72e92 Mon Sep 17 00:00:00 2001
+From f4e731440b86297124dd8ef41eb8d78820cf2200 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 16/21] mac80211: mtk: add sta-assisted DFS state update
+Subject: [PATCH 15/37] mtk: mac80211: add sta-assisted DFS state update
  mechanism
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -13,10 +13,10 @@
  4 files changed, 92 insertions(+)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index cd0ec8a..2c51c3e 100644
+index 0c9bb5c..085ad51 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -8430,6 +8430,20 @@ void cfg80211_cac_event(struct net_device *netdev,
+@@ -8479,6 +8479,20 @@ void cfg80211_cac_event(struct net_device *netdev,
  			const struct cfg80211_chan_def *chandef,
  			enum nl80211_radar_event event, gfp_t gfp);
  
@@ -99,7 +99,7 @@
  		info.success = 1;
  	}
 diff --git a/net/wireless/chan.c b/net/wireless/chan.c
-index caa5acc..a7e597d 100644
+index e250830..a19cb61 100644
 --- a/net/wireless/chan.c
 +++ b/net/wireless/chan.c
 @@ -14,6 +14,7 @@
@@ -110,7 +110,7 @@
  
  static bool cfg80211_valid_60g_freq(u32 freq)
  {
-@@ -1437,6 +1438,65 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
+@@ -1436,6 +1437,65 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
  }
  EXPORT_SYMBOL(cfg80211_any_usable_channels);
  
@@ -177,5 +177,5 @@
  				       unsigned int link_id)
  {
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0016-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch
similarity index 80%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0016-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch
index 92686c5..ede955e 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0016-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch
@@ -1,14 +1,14 @@
-From 532a2d6aacdd960d8f9f046f5862cae740b160b5 Mon Sep 17 00:00:00 2001
+From c4358cc7577fec9fc477e178ac974aca8252ea0b 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 17/21] nl80211: mtk: Mark DFS channel as available for CSA.
+Subject: [PATCH 16/37] 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 0ed3f51..d8e4d0f 100644
+index 15e3eeb..8a86723 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
 @@ -10250,6 +10250,11 @@ skip_beacons:
@@ -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/mtk-0018-cfg80211-mtk-fix-early-return-in-cfg80211_stop_backg.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch
similarity index 86%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0018-cfg80211-mtk-fix-early-return-in-cfg80211_stop_backg.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch
index 810054d..dedfcd6 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0018-cfg80211-mtk-fix-early-return-in-cfg80211_stop_backg.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch
@@ -1,7 +1,7 @@
-From ca445932b19fb346ea7cb33a5d23d94f979a2603 Mon Sep 17 00:00:00 2001
+From fb9c880c91cef6dd8434ca079b572dbc922b26d0 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 18/21] cfg80211: mtk: fix early return in
+Subject: [PATCH 17/37] mtk: cfg80211: fix early return in
  cfg80211_stop_background_radar_detection
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -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/mtk-0019-cfg80211-mtk-add-background-radar-stop-when-backgrou.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0018-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch
similarity index 83%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0019-cfg80211-mtk-add-background-radar-stop-when-backgrou.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0018-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch
index a07ea82..26bd623 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0019-cfg80211-mtk-add-background-radar-stop-when-backgrou.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0018-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch
@@ -1,7 +1,7 @@
-From a97cd11f1654844ed431aa359eca83fa844883c0 Mon Sep 17 00:00:00 2001
+From 0cdc99a767548427a60c761b1bb115c3fa88b68e 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 19/21] cfg80211: mtk: add background radar stop when
+Subject: [PATCH 18/37] mtk: cfg80211: add background radar stop when
  background channel is overlapped with operating channel
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index d8e4d0f..4692480 100644
+index 8a86723..5f64b63 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
 @@ -10021,6 +10021,10 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
@@ -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/mtk-0020-mac80211-mtk-avoid-kernel-warning-of-check_flush_dep.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0019-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch
similarity index 72%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0020-mac80211-mtk-avoid-kernel-warning-of-check_flush_dep.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0019-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch
index 3ac2f2c..62234ee 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0020-mac80211-mtk-avoid-kernel-warning-of-check_flush_dep.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0019-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch
@@ -1,7 +1,7 @@
-From f386c3a87f050489992ca66b8b17e970dc4a1ec1 Mon Sep 17 00:00:00 2001
+From 8703d77b8337ebd8df417fc4a6d95dde0c06de5f 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 20/21] mac80211: mtk: avoid kernel warning of
+Subject: [PATCH 19/37] 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 0188e6a..ba133fa 100644
+index 6fec8ff..e64a864 100644
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
-@@ -1291,7 +1291,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+@@ -1287,7 +1287,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/mtk-0021-mac80211-mtk-avoid-calling-switch_vif_chanctx-when-u.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0020-mtk-mac80211-avoid-calling-switch_vif_chanctx-when-u.patch
similarity index 89%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0021-mac80211-mtk-avoid-calling-switch_vif_chanctx-when-u.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0020-mtk-mac80211-avoid-calling-switch_vif_chanctx-when-u.patch
index 11bc559..7dc8973 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0021-mac80211-mtk-avoid-calling-switch_vif_chanctx-when-u.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0020-mtk-mac80211-avoid-calling-switch_vif_chanctx-when-u.patch
@@ -1,7 +1,7 @@
-From 244189a8c4412ac16301678a7683f4eb2545d657 Mon Sep 17 00:00:00 2001
+From 3402e771b7a2d912e8d77ff4644d8ae10ca07703 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 21/21] mac80211: mtk: avoid calling switch_vif_chanctx when
+Subject: [PATCH 20/37] mtk: mac80211: avoid calling switch_vif_chanctx when
  use_chanctx is false
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -36,5 +36,5 @@
  
  	list_move(&link->assigned_chanctx_list, &new_ctx->assigned_links);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0021-mtk-mac80211-Add-utilities-for-converting-op_class.patch
similarity index 96%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0021-mtk-mac80211-Add-utilities-for-converting-op_class.patch
index e32ba2f..d7c1f63 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0021-mtk-mac80211-Add-utilities-for-converting-op_class.patch
@@ -1,7 +1,7 @@
-From 979c688e54a73cfedb8757881a95c4f6c795023a Mon Sep 17 00:00:00 2001
+From d8ef7d680fd8c973d8352cf56d41ab404e083e70 Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Mon, 14 Aug 2023 18:03:29 +0800
-Subject: mac80211: mtk: Add utilities for converting op_class
+Subject: [PATCH 21/37] mtk: mac80211: Add utilities for converting op_class
 
 These utilities include converting op_class to nl80211 channel width and
 center frequency.
@@ -13,10 +13,10 @@
  2 files changed, 154 insertions(+), 1 deletion(-)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index cfaa3d6..bea7d25 100644
+index 085ad51..138c67c 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -8693,6 +8693,31 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev,
+@@ -8676,6 +8676,31 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev,
  bool ieee80211_operating_class_to_band(u8 operating_class,
  				       enum nl80211_band *band);
  
@@ -197,5 +197,5 @@
  					  u8 *op_class)
  {
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0023-mac80211-mtk-change-STA-CSA-parsing-flows.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0022-mtk-mac80211-refactor-STA-CSA-parsing-flows.patch
similarity index 99%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0023-mac80211-mtk-change-STA-CSA-parsing-flows.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0022-mtk-mac80211-refactor-STA-CSA-parsing-flows.patch
index 54b59e1..f831e1e 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0023-mac80211-mtk-change-STA-CSA-parsing-flows.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0022-mtk-mac80211-refactor-STA-CSA-parsing-flows.patch
@@ -1,7 +1,7 @@
-From e7247da28b7d7e90abd9ced10438df1cbe59af7e Mon Sep 17 00:00:00 2001
+From 720315c7e94190098346fb41d79f44ca705d063e Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Thu, 28 Sep 2023 09:28:50 +0800
-Subject: mac80211: mtk: refactor STA CSA parsing flows
+Subject: [PATCH 22/37] mtk: mac80211: refactor STA CSA parsing flows
 
 This patch changes the flows when STA parses csa IE:
 
@@ -594,5 +594,5 @@
  		csa_ie->max_switch_time =
  			(elems->max_channel_switch_time[0] << 0) |
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1000-mac80211-mtk-add-EHT-BA1024-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0023-mtk-mac80211-add-EHT-BA1024-support.patch
similarity index 96%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1000-mac80211-mtk-add-EHT-BA1024-support.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0023-mtk-mac80211-add-EHT-BA1024-support.patch
index 41d3d2f..fadd0ce 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1000-mac80211-mtk-add-EHT-BA1024-support.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0023-mtk-mac80211-add-EHT-BA1024-support.patch
@@ -1,7 +1,7 @@
-From 1a54516b2d934f80a80c6e1bb0fe824ceb63cd3b Mon Sep 17 00:00:00 2001
+From 9e7ab898f2a2688d58b339235bb38ac4594903ad 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 1000/1006] mac80211: mtk: add EHT BA1024 support
+Subject: [PATCH 23/37] mtk: mac80211: add EHT BA1024 support
 
 ---
  include/linux/ieee80211.h |  2 ++
@@ -110,5 +110,5 @@
  
  	txq = sta->sta.txq[tid];
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0024-mtk-mac80211-add-rate-duration-for-EHT-rate.patch
similarity index 98%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0024-mtk-mac80211-add-rate-duration-for-EHT-rate.patch
index d94b942..f66aa79 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0024-mtk-mac80211-add-rate-duration-for-EHT-rate.patch
@@ -1,7 +1,7 @@
-From 732eee694af50c9854755e4bcecf3a37f762a932 Mon Sep 17 00:00:00 2001
+From f8d6814a152ee0a51bd0265bf9af5c6919a9cda7 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 1001/1006] mac80211: mtk: add rate duration for EHT rate.
+Subject: [PATCH 24/37] 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/mtk-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0025-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch
similarity index 80%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0025-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch
index a8ecdb7..13a06a0 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0025-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch
@@ -1,8 +1,8 @@
-From 962ea174654c240aacc4e83b2000846c796cf1fc Mon Sep 17 00:00:00 2001
+From 8a15deedea82333fc2b0a4aeeffed6364ebb1edd 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 1002/1006] mac80211: mtk: add send bar action when recieve
- addba rsp
+Subject: [PATCH 25/37] mtk: mac80211: add send bar action when recieve addba
+ rsp
 
 Signed-off-by: ye he <ye.he@mediatek.com>
 ---
@@ -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/mtk-1003-mac80211-mtk-inrease-beacon-loss-count.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0026-mtk-mac80211-inrease-beacon-loss-count.patch
similarity index 86%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1003-mac80211-mtk-inrease-beacon-loss-count.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0026-mtk-mac80211-inrease-beacon-loss-count.patch
index 559b91d..a81f4a0 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1003-mac80211-mtk-inrease-beacon-loss-count.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0026-mtk-mac80211-inrease-beacon-loss-count.patch
@@ -1,7 +1,7 @@
-From 6e12a9af43178a46e573e8ee92520ec502562bb5 Mon Sep 17 00:00:00 2001
+From 2cf6dd719d5f5c095ae7790430fac9468a7568c0 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 1003/1006] mac80211: mtk: inrease beacon loss count
+Subject: [PATCH 26/37] mtk: mac80211: inrease beacon loss count
 
 as per eagle code beacone loss time out is
 4 seconds.
@@ -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/mtk-1004-cfg80211-mtk-add-support-for-updating-background-cha.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0027-mtk-cfg80211-add-support-for-updating-background-cha.patch
similarity index 92%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-cfg80211-mtk-add-support-for-updating-background-cha.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0027-mtk-cfg80211-add-support-for-updating-background-cha.patch
index b52511a..5a668c6 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-cfg80211-mtk-add-support-for-updating-background-cha.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0027-mtk-cfg80211-add-support-for-updating-background-cha.patch
@@ -1,7 +1,7 @@
-From f0e42c5a5ea3491be2d7c61c798dffe126eabd2b Mon Sep 17 00:00:00 2001
+From e07ead7c1b4cca5c31903895aab84295fc78256c 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 1004/1006] cfg80211: mtk: add support for updating background
+Subject: [PATCH 27/37] 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 2c51c3e..46c477a 100644
+index 138c67c..1e8ce82 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -8444,6 +8444,20 @@ void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
+@@ -8493,6 +8493,20 @@ void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
  				   const struct cfg80211_chan_def *csa_chandef,
  				   bool associated);
  
@@ -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/mtk-1005-mac80211-mtk-Allow-STA-interface-to-set-TX-queue-par.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0028-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch
similarity index 79%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1005-mac80211-mtk-Allow-STA-interface-to-set-TX-queue-par.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0028-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch
index 83fb948..b344c4d 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1005-mac80211-mtk-Allow-STA-interface-to-set-TX-queue-par.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0028-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch
@@ -1,7 +1,7 @@
-From 345695bc97c9a69aa9717e2fceb2e42701a63486 Mon Sep 17 00:00:00 2001
+From 1add4148216d25e1523e872badbb9ad23fe5fc72 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 1005/1006] mac80211: mtk: Allow STA interface to set TX queue
+Subject: [PATCH 28/37] mtk: mac80211: Allow STA interface to set TX queue
  parameters
 
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 1 insertion(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 4692480..e098263 100644
+index 5f64b63..6eb1bba 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
 @@ -3497,6 +3497,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
@@ -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/mtk-1006-mac80211-mtk-export-ieee80211_tpt_led_trig_tx-rx-for.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0029-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch
similarity index 91%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1006-mac80211-mtk-export-ieee80211_tpt_led_trig_tx-rx-for.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0029-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch
index 825a8dc..f95ab99 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1006-mac80211-mtk-export-ieee80211_tpt_led_trig_tx-rx-for.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0029-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch
@@ -1,8 +1,8 @@
-From 8fb30028bd630b37840d023029aa6aa4791f7697 Mon Sep 17 00:00:00 2001
+From 9d85abfd21151dd60583a80a7fdf34c837e9996f 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 1006/1006] mac80211: mtk: export ieee80211_tpt_led_trig_tx/rx
- for driver
+Subject: [PATCH 29/37] 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,
 mac80211 is not aware of the traffic. Consequently, the LED does not
@@ -111,10 +111,10 @@
 -#endif
 -}
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index e245f31..a44381b 100644
+index a3b4cac..fb3d2e4 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -5394,7 +5394,7 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+@@ -5401,7 +5401,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 d816c36..4925fab 100644
+index 3b8e548..0ed18d5 100644
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -4320,7 +4320,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
+@@ -4321,7 +4321,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
  	len = 0;
   out:
  	if (len)
@@ -136,7 +136,7 @@
  	rcu_read_unlock();
  }
  
-@@ -4646,7 +4646,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
+@@ -4647,7 +4647,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/mtk-1007-mac80211-mtk-add-packet-count-input-for-dev_sw_netst.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0030-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch
similarity index 97%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1007-mac80211-mtk-add-packet-count-input-for-dev_sw_netst.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0030-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch
index 9a4f9ce..7d5877e 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1007-mac80211-mtk-add-packet-count-input-for-dev_sw_netst.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0030-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch
@@ -1,7 +1,7 @@
-From 26a73e67325cd28ff295afacfb875c14ea8e1988 Mon Sep 17 00:00:00 2001
+From 63bbe30ccac3b6839bddaec3226b06e9a3f73a1d 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 1/2] mac80211: mtk: add packet count input for
+Subject: [PATCH 30/37] mtk: mac80211: add packet count input for
  dev_sw_netstat_rx_add
 
 ---
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1008-mac80211-mtk-add-per-bss-flag-to-support-vendors-cou.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0031-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch
similarity index 95%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1008-mac80211-mtk-add-per-bss-flag-to-support-vendors-cou.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0031-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch
index 4cb182c..68a2543 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1008-mac80211-mtk-add-per-bss-flag-to-support-vendors-cou.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0031-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch
@@ -1,7 +1,7 @@
-From 7ef885cff2d628c84b83eb4b697106b781495fa5 Mon Sep 17 00:00:00 2001
+From de77510ea0bd145fe2d93321d14755b74c95bde3 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 2/2] mac80211: mtk: add per-bss flag to support vendors
+Subject: [PATCH 31/37] mtk: mac80211: add per-bss flag to support vendors
  counter
 
 ---
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0032-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0032-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch
new file mode 100644
index 0000000..3c649f5
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0032-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch
@@ -0,0 +1,26 @@
+From 217bb748ec05993d39a85aff28f45dd8e8320f82 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 32/37] mtk: mac80211: set eht_support to false when AP is not
+ in EHT mode
+
+Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
+---
+ net/mac80211/cfg.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 916332c..2072a7a 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1375,6 +1375,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;
++		link_conf->eht_support = false;
+ 	}
+ 
+ 	if (sdata->vif.type == NL80211_IFTYPE_AP &&
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0033-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0033-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch
new file mode 100644
index 0000000..7ec384e
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0033-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch
@@ -0,0 +1,120 @@
+From 45e2564bd74224196b9495ea520ccf7186d9074a 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 33/37] 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.
+
+Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
+---
+ include/net/mac80211.h |  6 ++++++
+ net/mac80211/agg-tx.c  |  5 ++++-
+ net/mac80211/debugfs.c | 49 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 59 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 345c323..cef6577 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -2907,8 +2907,14 @@ struct ieee80211_hw {
+ 	u32 max_mtu;
+ 	const s8 *tx_power_levels;
+ 	u8 max_txpwr_levels_idx;
++	bool cert_mode;
+ };
+ 
++static inline bool ieee80211_is_cert_mode(struct ieee80211_hw *hw)
++{
++	return hw->cert_mode;
++}
++
+ 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 285433a..a2f1e14 100644
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -1108,7 +1108,10 @@ next:
+ 		tid_tx->timeout =
+ 			le16_to_cpu(mgmt->u.action.u.addba_resp.timeout);
+ 
+-		if (tid_tx->timeout) {
++		/* In the case of certification env, testbed STA cannot accept frequent DelBA.
++		 * Therefore, we remove the session timer check here to avoid crashing testbed STA.
++		 */
++		if (tid_tx->timeout && !ieee80211_is_cert_mode(&local->hw)) {
+ 			mod_timer(&tid_tx->session_timer,
+ 				  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 aa04167..9424243 100644
+--- a/net/mac80211/debugfs.c
++++ b/net/mac80211/debugfs.c
+@@ -440,6 +440,54 @@ static const struct file_operations reset_ops = {
+ };
+ #endif
+ 
++static ssize_t cert_mode_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), "cert_mode: %d\n",
++			local->hw.cert_mode);
++
++	return simple_read_from_buffer(user_buf, count, ppos,
++				       buf, len);
++}
++
++static ssize_t cert_mode_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.cert_mode))
++		return -EINVAL;
++
++	return count;
++}
++
++static const struct file_operations cert_mode_ops = {
++	.write = cert_mode_write,
++	.read = cert_mode_read,
++	.open = simple_open,
++	.llseek = noop_llseek,
++};
++
+ static const char *hw_flag_names[] = {
+ #define FLAG(F)	[IEEE80211_HW_##F] = #F
+ 	FLAG(HAS_RATE_CONTROL),
+@@ -671,6 +719,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
+ 	debugfs_create_u32("aql_threshold", 0600,
+ 			   phyd, &local->aql_threshold);
+ 
++	DEBUGFS_ADD_MODE(cert_mode, 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/mtk-0034-mtk-mac80211-Fix-he_6ghz_oper-NULL-pointer-access.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0034-mtk-mac80211-Fix-he_6ghz_oper-NULL-pointer-access.patch
new file mode 100644
index 0000000..c109064
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0034-mtk-mac80211-Fix-he_6ghz_oper-NULL-pointer-access.patch
@@ -0,0 +1,33 @@
+From 2ae2bae36bb0fb44107f6f01fff4c6f03f5db754 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Tue, 21 Nov 2023 10:16:31 +0800
+Subject: [PATCH 34/37] mtk: mac80211: Fix he_6ghz_oper NULL pointer access
+
+Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
+---
+ include/linux/ieee80211.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
+index 3308e85..a23ec4c 100644
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -2671,12 +2671,14 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
+ static inline const struct ieee80211_he_6ghz_oper *
+ ieee80211_he_6ghz_oper(const struct ieee80211_he_operation *he_oper)
+ {
+-	const u8 *ret = (const void *)&he_oper->optional;
++	const u8 *ret;
+ 	u32 he_oper_params;
+ 
+ 	if (!he_oper)
+ 		return NULL;
+ 
++	ret = (const void *)&he_oper->optional;
++
+ 	he_oper_params = le32_to_cpu(he_oper->he_oper_params);
+ 
+ 	if (!(he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO))
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0035-mtk-mac80211-ACS-channel-time-is-reset-by-ch_restore.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0035-mtk-mac80211-ACS-channel-time-is-reset-by-ch_restore.patch
new file mode 100644
index 0000000..35a9d0d
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0035-mtk-mac80211-ACS-channel-time-is-reset-by-ch_restore.patch
@@ -0,0 +1,66 @@
+From c4c3bfb8d2c7e986bd16ae589fdb25711550adc2 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 35/37] 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
+scan.
+
+Root cause:
+The chan_stat may be reset when restore to duty channel.
+Mac80211 will notify to hostapd when scan done and then restore to duty
+channel.
+And mt76 will clear scan flag after restore done.
+If hostapd get the chan_stat before channel_restore, will get the
+correct channel time;
+If hostapd get the chan_stat after channel_restore, will get zero
+channel time;
+
+Solution:
+When channel switch, will check the mac80211 scan state but not the mt76 scan flag.
+Mac80211 scan state will be set in scanning, and will be reset after
+scan done and before restore to duty channel.
+
+Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
+---
+ include/net/mac80211.h | 7 +++++++
+ net/mac80211/util.c    | 9 +++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index cef6577..2e4b66e 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -7482,4 +7482,11 @@ int ieee80211_set_active_links(struct ieee80211_vif *vif, u16 active_links);
+ void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
+ 				      u16 active_links);
+ 
++/**
++ * ieee80211_get_scanning - get scanning bitmask
++ *
++ * @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/util.c b/net/mac80211/util.c
+index 3650dcd..5bd40c6 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -5155,3 +5155,12 @@ void ieee80211_fragment_element(struct sk_buff *skb, u8 *len_pos, u8 frag_id)
+ 
+ 	*len_pos = elem_len;
+ }
++
++unsigned long ieee80211_get_scanning(struct ieee80211_hw *hw)
++{
++	struct ieee80211_local *local = hw_to_local(hw);
++
++	return local->scanning;
++}
++EXPORT_SYMBOL(ieee80211_get_scanning);
++
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0036-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0036-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch
new file mode 100644
index 0000000..e9cc850
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0036-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch
@@ -0,0 +1,43 @@
+From e2a94c3ec7aa8f578b1b81b1f5225a631bf6a53f 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 36/37] 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
+frame section.
+
+Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
+---
+ net/mac80211/rx.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 07dddcd..d431f57 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -3494,9 +3494,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
+ 
+ 	switch (mgmt->u.action.category) {
+ 	case WLAN_CATEGORY_HT:
+-		/* reject HT action frames from stations not supporting HT */
+-		if (!rx->link_sta->pub->ht_cap.ht_supported)
+-			goto invalid;
+ 
+ 		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ 		    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
+@@ -3515,6 +3512,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
+ 			enum ieee80211_smps_mode smps_mode;
+ 			struct sta_opmode_info sta_opmode = {};
+ 
++			if (rx->link_sta->pub->he_cap.has_he &&
++			    !(rx->link_sta->pub->he_cap.he_cap_elem.mac_cap_info[5] &
++			    IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS))
++				goto invalid;
++
+ 			if (sdata->vif.type != NL80211_IFTYPE_AP &&
+ 			    sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
+ 				goto handled;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0037-mtk-mac80211-Add-CSA-action-frame-tx-when-channel-sw.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0037-mtk-mac80211-Add-CSA-action-frame-tx-when-channel-sw.patch
new file mode 100644
index 0000000..8a8f4b1
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0037-mtk-mac80211-Add-CSA-action-frame-tx-when-channel-sw.patch
@@ -0,0 +1,117 @@
+From 488e67b3592e6e36622e12a212739d4d74710a56 Mon Sep 17 00:00:00 2001
+From: "fancy.liu" <fancy.liu@mediatek.com>
+Date: Thu, 30 Nov 2023 16:42:59 +0800
+Subject: [PATCH 37/37] mtk: mac80211: Add CSA action frame tx when channel
+ switch on AP
+
+Description:
+To meet spec requirement.
+
+802.11-2020
+11.8.8.2 Selecting and advertising a new channel in a non-DMG infrastructure BSS
+11.8.8.6 Selecting and advertising a new channel in a DMG BSS
+-
+An AP shall inform associated STAs that the AP is moving to a new channel and shall maintain the association by advertising the switch using Channel Switch Announcement elements in Beacon frames, Probe Response frames, and Channel Switch Announcement frames until the intended channel switch time.
+
+Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
+---
+ net/mac80211/cfg.c  | 28 ++++++++++++++--------------
+ net/mac80211/util.c | 10 +++++++---
+ 2 files changed, 21 insertions(+), 17 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 2072a7a..1554849 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3790,15 +3790,7 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ 		 * immediately too.  If we would delay the switch
+ 		 * until the next TBTT, we would have to set the probe
+ 		 * response here.
+-		 *
+-		 * TODO: A channel switch with count <= 1 without
+-		 * sending a CSA action frame is kind of useless,
+-		 * because the clients won't know we're changing
+-		 * channels.  The action frame must be implemented
+-		 * either here or in the userspace.
+ 		 */
+-		if (params->count <= 1)
+-			break;
+ 
+ 		if ((params->n_counter_offsets_beacon >
+ 		     IEEE80211_MAX_CNTDWN_COUNTERS_NUM) ||
+@@ -3814,14 +3806,20 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ 		csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
+ 		csa.count = params->count;
+ 
+-		err = ieee80211_assign_beacon(sdata, &sdata->deflink,
+-					      &params->beacon_csa, &csa,
+-					      NULL, changed);
+-		if (err < 0) {
+-			ieee80211_free_next_beacon(&sdata->deflink);
+-			return err;
++		/* see comments in the NL80211_IFTYPE_AP block */
++		if (params->count > 1) {
++			err = ieee80211_assign_beacon(sdata, &sdata->deflink,
++							  &params->beacon_csa, &csa,
++							  NULL, changed);
++
++			if (err < 0) {
++				ieee80211_free_next_beacon(&sdata->deflink);
++				return err;
++			}
+ 		}
+ 
++		ieee80211_send_action_csa(sdata, params);
++
+ 		break;
+ 	case NL80211_IFTYPE_ADHOC:
+ 		if (!sdata->vif.cfg.ibss_joined)
+@@ -3893,6 +3891,7 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ 		}
+ #endif
+ 	default:
++		sdata_info(sdata, "Won't send CSA for vif.type:%d.\n", sdata->vif.type);
+ 		return -EOPNOTSUPP;
+ 	}
+ 
+@@ -3982,6 +3981,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ 
+ 	err = ieee80211_set_csa_beacon(sdata, params, &changed);
+ 	if (err) {
++		sdata_info(sdata, "failed to set csa in beacon.\n");
+ 		ieee80211_link_unreserve_chanctx(&sdata->deflink);
+ 		goto out;
+ 	}
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 5bd40c6..f36a5c0 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -4515,8 +4515,11 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
+ 	u8 *pos;
+ 
+ 	if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+-	    sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
++	    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
++	    sdata->vif.type != NL80211_IFTYPE_AP) {
++		sdata_info(sdata, "Not allow csa action on vif.type:%d.\n", sdata->vif.type);
+ 		return -EOPNOTSUPP;
++	}
+ 
+ 	skb = dev_alloc_skb(local->tx_headroom + hdr_len +
+ 			    5 + /* channel switch announcement element */
+@@ -4533,9 +4536,10 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
+ 
+ 	eth_broadcast_addr(mgmt->da);
+ 	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+-	if (ieee80211_vif_is_mesh(&sdata->vif)) {
++	if (sdata->vif.type == NL80211_IFTYPE_AP ||
++	    sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
+ 		memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+-	} else {
++	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ 		struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+ 		memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
+ 	}
+-- 
+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 14a1121..09537c4 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
@@ -16,38 +16,44 @@
     file://320-cfg80211-allow-grace-period-for-DFS-available-after-.patch \
     file://400-allow-ibss-mixed.patch \
     file://782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch \
-    file://bp-0001-Revert-mac80211-use-the-new-drop-reasons-infrastruct.patch \
+    file://bp-0001-backports-Revert-mac80211-use-the-new-drop-reasons-i.patch \
     file://bp-0002-backports-update-kernel-version-check-for-eth_hw_add.patch \
-    file://mtk-0001-mac80211-mtk-do-not-setup-twt-when-twt-responder-is-.patch \
-    file://mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch \
-    file://mtk-0003-mac80211-mtk-it-s-invalid-case-when-frag_threshold-i.patch \
-    file://mtk-0004-mac80211-mtk-airtime_flags-depends-on-NL80211_EXT_FE.patch \
-    file://mtk-0005-mac80211-mtk-add-support-for-runtime-set-inband-disc.patch \
-    file://mtk-0006-cfg80211-mtk-implement-DFS-status-show-cac-and-nop-s.patch \
-    file://mtk-0007-mac80211-mtk-Set-TWT-Information-Frame-Disabled-bit-.patch \
-    file://mtk-0008-mac80211-mtk-check-the-control-channel-before-downgr.patch \
-    file://mtk-0009-mac80211-mtk-fix-tx-amsdu-aggregation.patch \
-    file://mtk-0010-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-id.patch \
-    file://mtk-0011-mac80211-mtk-fix-build-error-on-Linux-Kernel-5.4.patch \
-    file://mtk-0012-mac80211-mtk-track-obss-color-bitmap.patch \
-    file://mtk-0013-mac80211-mtk-ageout-color-bitmap.patch \
-    file://mtk-0014-mac80211-mtk-update-max_bssid_indicator-based-on-rea.patch \
-    file://mtk-0015-support-configurable-addba-resp-time.patch \
-    file://mtk-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch \
-    file://mtk-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch \
-    file://mtk-0018-cfg80211-mtk-fix-early-return-in-cfg80211_stop_backg.patch \
-    file://mtk-0019-cfg80211-mtk-add-background-radar-stop-when-backgrou.patch \
-    file://mtk-0020-mac80211-mtk-avoid-kernel-warning-of-check_flush_dep.patch \
-    file://mtk-0021-mac80211-mtk-avoid-calling-switch_vif_chanctx-when-u.patch \
-    file://mtk-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch \
-    file://mtk-0023-mac80211-mtk-change-STA-CSA-parsing-flows.patch \
-    file://mtk-1000-mac80211-mtk-add-EHT-BA1024-support.patch \
-    file://mtk-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch \
-    file://mtk-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch \
-    file://mtk-1003-mac80211-mtk-inrease-beacon-loss-count.patch \
-    file://mtk-1004-cfg80211-mtk-add-support-for-updating-background-cha.patch \
-    file://mtk-1005-mac80211-mtk-Allow-STA-interface-to-set-TX-queue-par.patch \
-    file://mtk-1006-mac80211-mtk-export-ieee80211_tpt_led_trig_tx-rx-for.patch \
-    file://mtk-1007-mac80211-mtk-add-packet-count-input-for-dev_sw_netst.patch \
-    file://mtk-1008-mac80211-mtk-add-per-bss-flag-to-support-vendors-cou.patch \
+    file://bp-0003-backports-Revert-cfg80211-allow-grace-period-for-DFS.patch \
+    file://mtk-0001-mtk-mac80211-do-not-setup-twt-when-twt-responder-is-.patch \
+    file://mtk-0002-mtk-cfg80211-extend-CAC-time-for-weather-radar-chann.patch \
+    file://mtk-0003-mtk-mac80211-it-s-invalid-case-when-frag_threshold-i.patch \
+    file://mtk-0004-mtk-mac80211-add-support-for-runtime-set-inband-disc.patch \
+    file://mtk-0005-mtk-cfg80211-implement-DFS-status-show-cac-and-nop-s.patch \
+    file://mtk-0006-mtk-mac80211-Set-TWT-Information-Frame-Disabled-bit-.patch \
+    file://mtk-0007-mtk-mac80211-check-the-control-channel-before-downgr.patch \
+    file://mtk-0008-mtk-mac80211-fix-tx-amsdu-aggregation.patch \
+    file://mtk-0009-mtk-mac80211-add-fill-receive-path-ops-to-get-wed-id.patch \
+    file://mtk-0010-mtk-mac80211-fix-build-error-on-Linux-Kernel-5.4.patch \
+    file://mtk-0011-mtk-mac80211-track-obss-color-bitmap.patch \
+    file://mtk-0012-mtk-mac80211-ageout-color-bitmap.patch \
+    file://mtk-0013-mtk-mac80211-update-max_bssid_indicator-based-on-rea.patch \
+    file://mtk-0014-mtk-mac80211-support-configurable-addba-resp-time.patch \
+    file://mtk-0015-mtk-mac80211-add-sta-assisted-DFS-state-update-mecha.patch \
+    file://mtk-0016-mtk-nl80211-Mark-DFS-channel-as-available-for-CSA.patch \
+    file://mtk-0017-mtk-cfg80211-fix-early-return-in-cfg80211_stop_backg.patch \
+    file://mtk-0018-mtk-cfg80211-add-background-radar-stop-when-backgrou.patch \
+    file://mtk-0019-mtk-mac80211-avoid-kernel-warning-of-check_flush_dep.patch \
+    file://mtk-0020-mtk-mac80211-avoid-calling-switch_vif_chanctx-when-u.patch \
+    file://mtk-0021-mtk-mac80211-Add-utilities-for-converting-op_class.patch \
+    file://mtk-0022-mtk-mac80211-refactor-STA-CSA-parsing-flows.patch \
+    file://mtk-0023-mtk-mac80211-add-EHT-BA1024-support.patch \
+    file://mtk-0024-mtk-mac80211-add-rate-duration-for-EHT-rate.patch \
+    file://mtk-0025-mtk-mac80211-add-send-bar-action-when-recieve-addba-.patch \
+    file://mtk-0026-mtk-mac80211-inrease-beacon-loss-count.patch \
+    file://mtk-0027-mtk-cfg80211-add-support-for-updating-background-cha.patch \
+    file://mtk-0028-mtk-mac80211-Allow-STA-interface-to-set-TX-queue-par.patch \
+    file://mtk-0029-mtk-mac80211-export-ieee80211_tpt_led_trig_tx-rx-for.patch \
+    file://mtk-0030-mtk-mac80211-add-packet-count-input-for-dev_sw_netst.patch \
+    file://mtk-0031-mtk-mac80211-add-per-bss-flag-to-support-vendors-cou.patch \
+    file://mtk-0032-mtk-mac80211-set-eht_support-to-false-when-AP-is-not.patch \
+    file://mtk-0033-mtk-mac80211-Add-cert-mode-to-disable-ba-timeout.patch \
+    file://mtk-0034-mtk-mac80211-Fix-he_6ghz_oper-NULL-pointer-access.patch \
+    file://mtk-0035-mtk-mac80211-ACS-channel-time-is-reset-by-ch_restore.patch \
+    file://mtk-0036-mtk-mac80211-Fix-SMPS-action-frame-cap-check.patch \
+    file://mtk-0037-mtk-mac80211-Add-CSA-action-frame-tx-when-channel-sw.patch \
     "
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0024-mac80211-mtk-ACS-channel-time-is-reset-by-ch_restore.patch b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0024-mac80211-mtk-ACS-channel-time-is-reset-by-ch_restore.patch
new file mode 100644
index 0000000..b7c1982
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0024-mac80211-mtk-ACS-channel-time-is-reset-by-ch_restore.patch
@@ -0,0 +1,65 @@
+From e86b89d026fa963ff6c789747b9b373884956157 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Fri, 1 Dec 2023 08:48:35 +0800
+Subject: [PATCH] mac80211: mtk: ACS channel time is reset by ch_restore
+
+Issue:
+There's a chance that the channel time for duty channel is zero in ACS
+scan.
+
+Root cause:
+The chan_stat may be reset when restore to duty channel.
+Mac80211 will notify to hostapd when scan done and then restore to duty
+channel.
+And mt76 will clear scan flag after restore done.
+If hostapd get the chan_stat before channel_restore, will get the
+correct channel time;
+If hostapd get the chan_stat after channel_restore, will get zero
+channel time;
+
+Solution:
+When channel switch, will check the mac80211 scan state but not the mt76 scan flag.
+Mac80211 scan state will be set in scanning, and will be reset after
+scan done and before restore to duty channel.
+
+Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
+---
+ include/net/mac80211.h | 6 ++++++
+ net/mac80211/util.c    | 8 ++++++++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 91affd5..2da55d8 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -6929,4 +6929,10 @@ static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
+ 	       ieee80211_is_data(hdr->frame_control);
+ }
+ 
++/**
++ * ieee80211_get_scanning - get scanning bitmask
++ *
++ * @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/util.c b/net/mac80211/util.c
+index 8d36b05..26cd627 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -4627,3 +4627,11 @@ u16 ieee80211_encode_usf(int listen_interval)
+ 
+ 	return (u16) listen_interval;
+ }
++
++unsigned long ieee80211_get_scanning(struct ieee80211_hw *hw)
++{
++	struct ieee80211_local *local = hw_to_local(hw);
++
++	return local->scanning;
++}
++EXPORT_SYMBOL(ieee80211_get_scanning);
+\ No newline at end of file
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0024-mac80211-mtk-add-DFS-CAC-countdown-in-CSA-flow.patch b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0024-mac80211-mtk-add-DFS-CAC-countdown-in-CSA-flow.patch
new file mode 100644
index 0000000..4a2dfea
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0024-mac80211-mtk-add-DFS-CAC-countdown-in-CSA-flow.patch
@@ -0,0 +1,300 @@
+From 022bf2702e0dd6f67690ac2860aa465efb4bff07 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 15 Nov 2023 15:05:17 +0800
+Subject: [PATCH] mac80211: mtk: add DFS CAC countdown in CSA flow
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h  | 32 +++++++++++++++++++
+ net/mac80211/cfg.c      | 34 +++++++++++++++++++-
+ net/mac80211/mlme.c     |  6 +++-
+ net/mac80211/util.c     | 11 ++++++-
+ net/wireless/chan.c     | 71 +++++++++++++++++++++++++++++++++++++++++
+ net/wireless/nl80211.c  |  5 +--
+ net/wireless/rdev-ops.h | 17 ++++++++++
+ 7 files changed, 171 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 03f072f..a443b0d 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4308,6 +4308,10 @@ struct cfg80211_ops {
+ 					 struct net_device *dev,
+ 					 struct cfg80211_chan_def *chandef,
+ 					 u32 cac_time_ms);
++	int	(*start_radar_detection_post_csa)(struct wiphy *wiphy,
++						  struct net_device *dev,
++						  struct cfg80211_chan_def *chandef,
++						  u32 cac_time_ms);
+ 	void	(*end_cac)(struct wiphy *wiphy,
+ 				struct net_device *dev);
+ 	int	(*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
+@@ -7796,6 +7800,34 @@ bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
+ 				   struct cfg80211_chan_def *chandef,
+ 				   enum nl80211_iftype iftype);
+ 
++/**
++ * 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
++ * @chandef: the channel definition to start radar detection on
++ */
++int cfg80211_start_radar_detection_post_csa(struct wiphy *wiphy,
++					    struct wireless_dev *wdev,
++					    struct cfg80211_chan_def *chandef);
++
+ /*
+  * cfg80211_ch_switch_notify - update wdev channel and notify userspace
+  * @dev: the device which switched channels
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 56381f8..8a0833b 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3328,6 +3328,28 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ 	return 0;
+ }
+ 
++static int ieee80211_start_radar_detection_post_csa(struct wiphy *wiphy,
++						    struct net_device *dev,
++						    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;
++
++	if (!list_empty(&local->roc_list) || local->scanning)
++		return -EBUSY;
++
++	/* whatever, but channel contexts should not complain about that one */
++	sdata->smps_mode = IEEE80211_SMPS_OFF;
++	sdata->needed_rx_chains = local->rx_chains;
++
++	ieee80211_queue_delayed_work(&sdata->local->hw,
++				     &sdata->dfs_cac_timer_work,
++				     msecs_to_jiffies(cac_time_ms));
++
++	return 1;
++}
++
+ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
+ {
+ 	struct ieee80211_local *local = sdata->local;
+@@ -3361,6 +3383,11 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
+ 					&sdata->csa_chandef))
+ 		return -EINVAL;
+ 
++	err = cfg80211_start_radar_detection_post_csa(local->hw.wiphy, &sdata->wdev,
++						      &sdata->vif.bss_conf.chandef);
++	if (err)
++		return err > 0 ? 0 : err;
++
+ 	sdata->vif.csa_active = false;
+ 
+ 	err = ieee80211_set_after_csa_beacon(sdata, &changed);
+@@ -4538,7 +4565,11 @@ ieee80211_skip_cac(struct wireless_dev *wdev)
+ 
+ 	cancel_delayed_work(&sdata->dfs_cac_timer_work);
+ 	if (wdev->cac_started) {
+-		ieee80211_vif_release_channel(sdata);
++		if (sdata->vif.csa_active)
++			ieee80211_queue_work(&sdata->local->hw,
++					     &sdata->csa_finalize_work);
++		else
++			ieee80211_vif_release_channel(sdata);
+ 		cac_time_ms = wdev->cac_time_ms;
+ 		wdev->cac_start_time = jiffies -
+ 				       msecs_to_jiffies(cac_time_ms + 1);
+@@ -4630,6 +4661,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/mlme.c b/net/mac80211/mlme.c
+index 48053e4..e9ec32d 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1870,7 +1870,11 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work)
+ 
+ 	mutex_lock(&sdata->local->mtx);
+ 	if (sdata->wdev.cac_started) {
+-		ieee80211_vif_release_channel(sdata);
++		if (sdata->vif.csa_active)
++			ieee80211_queue_work(&sdata->local->hw,
++					     &sdata->csa_finalize_work);
++		else
++			ieee80211_vif_release_channel(sdata);
+ 		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 8d36b05..5360fae 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3873,7 +3873,16 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
+ 
+ 		if (sdata->wdev.cac_started) {
+ 			chandef = sdata->vif.bss_conf.chandef;
+-			ieee80211_vif_release_channel(sdata);
++			if (sdata->vif.csa_active) {
++				sdata->vif.csa_active = false;
++				if (sdata->u.ap.next_beacon) {
++					kfree(sdata->u.ap.next_beacon->mbssid_ies);
++					kfree(sdata->u.ap.next_beacon);
++					sdata->u.ap.next_beacon = NULL;
++				}
++			} else {
++				ieee80211_vif_release_channel(sdata);
++			}
+ 			cfg80211_cac_event(sdata->dev,
+ 					   &chandef,
+ 					   NL80211_RADAR_CAC_ABORTED,
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index 9f651f9..88dd69e 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -1262,6 +1262,77 @@ bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
+ }
+ EXPORT_SYMBOL(cfg80211_reg_can_beacon_relax);
+ 
++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,
++					    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;
++
++	flush_delayed_work(&rdev->dfs_update_channels_wk);
++
++	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, chandef, cac_time_ms);
++	if (ret > 0) {
++		wdev->chandef = *chandef;
++		wdev->cac_started = true;
++		wdev->cac_start_time = jiffies;
++		wdev->cac_time_ms = cac_time_ms;
++		if (rdev->background_cac_started &&
++		    cfg80211_is_sub_chan(chandef, rdev->background_radar_chandef.chan)) {
++			cfg80211_stop_background_radar_detection(rdev->background_radar_wdev);
++		}
++		cfg80211_cac_event(wdev->netdev, chandef, NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
++	}
++
++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 97c2833..4883b1f 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -9625,8 +9625,9 @@ skip_beacons:
+ 		cfg80211_set_dfs_state(&rdev->wiphy, &params.chandef, NL80211_DFS_AVAILABLE);
+ 	}
+ 
+-	if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
+-					   wdev->iftype)) {
++	/* handle DFS CAC after CSA is sent */
++	if (!cfg80211_reg_can_beacon_dfs_relax(&rdev->wiphy, &params.chandef,
++					       wdev->iftype)) {
+ 		err = -EINVAL;
+ 		goto free;
+ 	}
+diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
+index 26f4604..f4d050b 100644
+--- a/net/wireless/rdev-ops.h
++++ b/net/wireless/rdev-ops.h
+@@ -1190,6 +1190,23 @@ 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,
++				    struct cfg80211_chan_def *chandef,
++				    u32 cac_time_ms)
++{
++	int ret = -EOPNOTSUPP;
++
++	trace_rdev_start_radar_detection(&rdev->wiphy, dev, chandef,
++					 cac_time_ms);
++	if (rdev->ops->start_radar_detection_post_csa)
++		ret = rdev->ops->start_radar_detection_post_csa(&rdev->wiphy, dev,
++								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)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc b/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
index 0000f77..9bb77d3 100644
--- a/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
+++ b/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
@@ -79,6 +79,8 @@
     file://mtk-0021-cfg80211-mtk-add-background-radar-stop-when-backgrou.patch \
     file://mtk-0022-mac80211-mtk-avoid-kernel-warning-of-check_flush_dep.patch \
     file://mtk-0023-mac80211-mtk-avoid-calling-switch_vif_chanctx-when-u.patch \
+    file://mtk-0024-mac80211-mtk-ACS-channel-time-is-reset-by-ch_restore.patch \
+    file://mtk-0024-mac80211-mtk-add-DFS-CAC-countdown-in-CSA-flow.patch \
     file://mtk-9900-mac80211-mtk-mask-kernel-version-limitation-and-fill.patch \
     file://mtk-9901-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-id.patch \
     file://mtk-9902-mac80211-mtk-add-support-for-letting-drivers-registe.patch \
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0001-mtk-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
similarity index 80%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0001-mtk-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
index bef1050..634f7b5 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0001-mtk-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
@@ -1,7 +1,8 @@
-From 455955959ceaabf80454570c2dfaa3128d524791 Mon Sep 17 00:00:00 2001
+From 79c8a28d435df3a9b0da8145675ea8d70a4de463 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 19 Sep 2023 11:21:23 +0800
-Subject: [PATCH 01/98] Revert "wifi: mt76: mt7996: fill txd by host driver"
+Subject: [PATCH 01/23] mtk: Revert "wifi: mt76: mt7996: fill txd by host
+ driver"
 
 This reverts commit 325a0c4931990d553487024c4f76c776492bdcc2.
 ---
@@ -9,10 +10,10 @@
  1 file changed, 9 insertions(+), 4 deletions(-)
 
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index c43839a..1a1e218 100644
+index 53258488..db06a982 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -967,8 +967,11 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -937,8 +937,11 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
  		return id;
  
  	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
@@ -26,7 +27,7 @@
  
  	txp = (struct mt76_connac_txp_common *)(txwi + MT_TXD_SIZE);
  	for (i = 0; i < nbuf; i++) {
-@@ -977,8 +980,10 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -955,8 +958,10 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
  	}
  	txp->fw.nbuf = nbuf;
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0002-mtk-wifi-mt76-connac-use-peer-address-for-station-BM.patch
similarity index 79%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0002-mtk-wifi-mt76-connac-use-peer-address-for-station-BM.patch
index 575b7db..bb26142 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0002-mtk-wifi-mt76-connac-use-peer-address-for-station-BM.patch
@@ -1,14 +1,13 @@
-From 1b0bafc1cfb554b6150eb2ea3e1a5100ef1b0a24 Mon Sep 17 00:00:00 2001
+From b7325781bb79f1ffa9d3f5a9ea9f79a59aa92e41 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 24 Aug 2023 18:38:11 +0800
-Subject: [PATCH 22/98] wifi: mt76: connac: use peer address for station BMC
- entry
+Subject: [PATCH 02/23] mtk: wifi: mt76: connac: use peer address for station
+ BMC entry
 
 Set peer address and aid for the BMC wtbl of station interface. For some
 functions such as parsing MU_EDCA parameters from beacon, firmware will
 need peer address to do the correct mapping.
 
-Change-Id: I0e812312fe730f69f8e431215b8e591c5faec06a
 Reported-by: Howard Hsu <howard-yh.hsu@mediatek.com>
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 ---
@@ -17,10 +16,10 @@
  2 files changed, 11 insertions(+), 1 deletion(-)
 
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 68de525..bb570f2 100644
+index 96494ba2..0d05404f 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -391,7 +391,14 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -389,7 +389,14 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  
  	if (!sta) {
  		basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
@@ -37,10 +36,10 @@
  	}
  
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 832b861..0e51fe0 100644
+index 51deea84..be914ced 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -582,6 +582,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
+@@ -595,6 +595,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
  	if ((changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) ||
  	    (changed & BSS_CHANGED_ASSOC && vif->cfg.assoc) ||
  	    (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon)) {
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-wed-sync-to-wed-upstream.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-wed-sync-to-wed-upstream.patch
deleted file mode 100644
index 25dfc5d..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-wed-sync-to-wed-upstream.patch
+++ /dev/null
@@ -1,2740 +0,0 @@
-From 4709ca02ba0332508ac6885acbc779bdfac3f0be Mon Sep 17 00:00:00 2001
-From: mtk27745 <rex.lu@mediatek.com>
-Date: Fri, 6 Oct 2023 21:20:25 +0800
-Subject: [PATCH] wifi: mt76: wed: sync to wed upstream
-
----
- dma.c             | 219 +++++++++++++++++++++++++++------------
- dma.h             |  12 +++
- mac80211.c        |  19 +++-
- mmio.c            |  97 +++++++++++++++++
- mt76.h            | 102 ++++++++++++++++--
- mt7603/dma.c      |   9 +-
- mt7615/dma.c      |   6 +-
- mt76_connac.h     |   3 +-
- mt76_connac_mac.c |   5 +-
- mt76x02_mmio.c    |   5 +-
- mt7915/dma.c      |  18 ++--
- mt7915/main.c     |  16 +--
- mt7915/mmio.c     | 107 +------------------
- mt7921/pci.c      |   2 +-
- mt7925/pci.c      |   2 +-
- mt7996/dma.c      | 258 ++++++++++++++++++++++++++++++++++++++++++----
- mt7996/init.c     | 156 ++++++++++++++++++++++++++--
- mt7996/mac.c      |  72 +++++++++++--
- mt7996/main.c     |  42 ++++++++
- mt7996/mcu.c      |  13 ++-
- mt7996/mmio.c     | 208 +++++++++++++++++++++++++++++++++----
- mt7996/mt7996.h   |  67 +++++++++++-
- mt7996/pci.c      |  72 ++++++++++---
- mt7996/regs.h     |  65 +++++++++++-
- 24 files changed, 1276 insertions(+), 299 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 643e18e..dd20271 100644
---- a/dma.c
-+++ b/dma.c
-@@ -9,11 +9,11 @@
- 
- #if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)
- 
--#define Q_READ(_dev, _q, _field) ({					\
-+#define Q_READ(_q, _field) ({						\
- 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
- 	u32 _val;							\
- 	if ((_q)->flags & MT_QFLAG_WED)					\
--		_val = mtk_wed_device_reg_read(&(_dev)->mmio.wed,	\
-+		_val = mtk_wed_device_reg_read((_q)->wed,		\
- 					       ((_q)->wed_regs +	\
- 					        _offset));		\
- 	else								\
-@@ -21,10 +21,10 @@
- 	_val;								\
- })
- 
--#define Q_WRITE(_dev, _q, _field, _val)	do {				\
-+#define Q_WRITE(_q, _field, _val)	do {				\
- 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
- 	if ((_q)->flags & MT_QFLAG_WED)					\
--		mtk_wed_device_reg_write(&(_dev)->mmio.wed,		\
-+		mtk_wed_device_reg_write((_q)->wed,			\
- 					 ((_q)->wed_regs + _offset),	\
- 					 _val);				\
- 	else								\
-@@ -33,8 +33,8 @@
- 
- #else
- 
--#define Q_READ(_dev, _q, _field)	readl(&(_q)->regs->_field)
--#define Q_WRITE(_dev, _q, _field, _val)	writel(_val, &(_q)->regs->_field)
-+#define Q_READ(_q, _field)		readl(&(_q)->regs->_field)
-+#define Q_WRITE(_q, _field, _val)	writel(_val, &(_q)->regs->_field)
- 
- #endif
- 
-@@ -188,40 +188,63 @@ EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
- static void
- mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
- {
--	Q_WRITE(dev, q, desc_base, q->desc_dma);
--	Q_WRITE(dev, q, ring_size, q->ndesc);
--	q->head = Q_READ(dev, q, dma_idx);
-+	Q_WRITE(q, desc_base, q->desc_dma);
-+	if (q->flags & MT_QFLAG_WED_RRO_EN)
-+		Q_WRITE(q, ring_size, MT_DMA_RRO_EN | q->ndesc);
-+	else
-+		Q_WRITE(q, ring_size, q->ndesc);
-+	q->head = Q_READ(q, dma_idx);
- 	q->tail = q->head;
- }
- 
- static void
--mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
-+__mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
-+		       bool reset_idx)
- {
--	int i;
--
- 	if (!q || !q->ndesc)
- 		return;
- 
--	/* clear descriptors */
--	for (i = 0; i < q->ndesc; i++)
--		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
-+	if (!mt76_queue_is_wed_rro_ind(q)) {
-+		int i;
- 
--	Q_WRITE(dev, q, cpu_idx, 0);
--	Q_WRITE(dev, q, dma_idx, 0);
-+		/* clear descriptors */
-+		for (i = 0; i < q->ndesc; i++)
-+			q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
-+	}
-+
-+	if (reset_idx) {
-+		Q_WRITE(q, cpu_idx, 0);
-+		Q_WRITE(q, dma_idx, 0);
-+	}
- 	mt76_dma_sync_idx(dev, q);
- }
- 
-+static void
-+mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
-+{
-+	__mt76_dma_queue_reset(dev, q, true);
-+}
-+
- static int
- mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 		    struct mt76_queue_buf *buf, void *data)
- {
--	struct mt76_desc *desc = &q->desc[q->head];
- 	struct mt76_queue_entry *entry = &q->entry[q->head];
- 	struct mt76_txwi_cache *txwi = NULL;
-+	struct mt76_desc *desc;
- 	u32 buf1 = 0, ctrl;
- 	int idx = q->head;
- 	int rx_token;
- 
-+	if (mt76_queue_is_wed_rro_ind(q)) {
-+		struct mt76_wed_rro_desc *rro_desc;
-+
-+		rro_desc = (struct mt76_wed_rro_desc *)q->desc;
-+		data = &rro_desc[q->head];
-+		goto done;
-+	}
-+
-+	desc = &q->desc[q->head];
- 	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
- 
- 	if (mt76_queue_is_wed_rx(q)) {
-@@ -244,6 +267,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 	WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
- 	WRITE_ONCE(desc->info, 0);
- 
-+done:
- 	entry->dma_addr[0] = buf->addr;
- 	entry->dma_len[0] = buf->len;
- 	entry->txwi = txwi;
-@@ -343,7 +367,7 @@ static void
- mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q)
- {
- 	wmb();
--	Q_WRITE(dev, q, cpu_idx, q->head);
-+	Q_WRITE(q, cpu_idx, q->head);
- }
- 
- static void
-@@ -359,7 +383,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
- 	if (flush)
- 		last = -1;
- 	else
--		last = Q_READ(dev, q, dma_idx);
-+		last = Q_READ(q, dma_idx);
- 
- 	while (q->queued > 0 && q->tail != last) {
- 		mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
-@@ -371,7 +395,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
- 		}
- 
- 		if (!flush && q->tail == last)
--			last = Q_READ(dev, q, dma_idx);
-+			last = Q_READ(q, dma_idx);
- 	}
- 	spin_unlock_bh(&q->cleanup_lock);
- 
-@@ -392,10 +416,14 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- {
- 	struct mt76_queue_entry *e = &q->entry[idx];
- 	struct mt76_desc *desc = &q->desc[idx];
--	void *buf;
-+	void *buf = e->buf;
-+	u32 ctrl;
- 
-+	if (mt76_queue_is_wed_rro_ind(q))
-+		goto done;
-+
-+	ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
- 	if (len) {
--		u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
- 		*len = FIELD_GET(MT_DMA_CTL_SD_LEN0, ctrl);
- 		*more = !(ctrl & MT_DMA_CTL_LAST_SEC0);
- 	}
-@@ -403,6 +431,12 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 	if (info)
- 		*info = le32_to_cpu(desc->info);
- 
-+	if (drop) {
-+		*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A | MT_DMA_CTL_DROP));
-+		if (ctrl & MT_DMA_CTL_VER_MASK)
-+			*drop = !!(ctrl & MT_DMA_CTL_PN_CHK_FAIL);
-+	}
-+
- 	if (mt76_queue_is_wed_rx(q)) {
- 		u32 buf1 = le32_to_cpu(desc->buf1);
- 		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
-@@ -420,23 +454,16 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 		t->ptr = NULL;
- 
- 		mt76_put_rxwi(dev, t);
--
--		if (drop) {
--			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
--
--			*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A |
--					   MT_DMA_CTL_DROP));
--
-+		if (drop)
- 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
--		}
- 	} else {
--		buf = e->buf;
--		e->buf = NULL;
- 		dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0],
- 				SKB_WITH_OVERHEAD(q->buf_size),
- 				page_pool_get_dma_dir(q->page_pool));
- 	}
- 
-+done:
-+	e->buf = NULL;
- 	return buf;
- }
- 
-@@ -450,11 +477,16 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
- 	if (!q->queued)
- 		return NULL;
- 
--	if (flush)
--		q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
--	else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)))
-+	if (mt76_queue_is_wed_rro_data(q))
- 		return NULL;
- 
-+	if (!mt76_queue_is_wed_rro_ind(q)) {
-+		if (flush)
-+			q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
-+		else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)))
-+			return NULL;
-+	}
-+
- 	q->tail = (q->tail + 1) % q->ndesc;
- 	q->queued--;
- 
-@@ -606,11 +638,14 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
- 	spin_lock_bh(&q->lock);
- 
- 	while (q->queued < q->ndesc - 1) {
-+		struct mt76_queue_buf qbuf = {};
- 		enum dma_data_direction dir;
--		struct mt76_queue_buf qbuf;
- 		dma_addr_t addr;
- 		int offset;
--		void *buf;
-+		void *buf = NULL;
-+
-+		if (mt76_queue_is_wed_rro_ind(q))
-+			goto done;
- 
- 		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
- 		if (!buf)
-@@ -621,6 +656,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
- 		dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
- 
- 		qbuf.addr = addr + q->buf_offset;
-+done:
- 		qbuf.len = len - q->buf_offset;
- 		qbuf.skip_unmap = false;
- 		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
-@@ -630,7 +666,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
- 		frames++;
- 	}
- 
--	if (frames)
-+	if (frames || mt76_queue_is_wed_rx(q))
- 		mt76_dma_kick_queue(dev, q);
- 
- 	spin_unlock_bh(&q->lock);
-@@ -641,15 +677,14 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
- int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
- {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
--	struct mtk_wed_device *wed = &dev->mmio.wed;
--	int ret, type, ring;
--	u8 flags;
-+	int ret = 0, type, ring;
-+	u16 flags;
- 
- 	if (!q || !q->ndesc)
- 		return -EINVAL;
- 
- 	flags = q->flags;
--	if (!mtk_wed_device_active(wed))
-+	if (!q->wed || !mtk_wed_device_active(q->wed))
- 		q->flags &= ~MT_QFLAG_WED;
- 
- 	if (!(q->flags & MT_QFLAG_WED))
-@@ -660,29 +695,52 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
- 
- 	switch (type) {
- 	case MT76_WED_Q_TX:
--		ret = mtk_wed_device_tx_ring_setup(wed, ring, q->regs, reset);
-+		ret = mtk_wed_device_tx_ring_setup(q->wed, ring, q->regs,
-+						   reset);
- 		if (!ret)
--			q->wed_regs = wed->tx_ring[ring].reg_base;
-+			q->wed_regs = q->wed->tx_ring[ring].reg_base;
- 		break;
- 	case MT76_WED_Q_TXFREE:
- 		/* WED txfree queue needs ring to be initialized before setup */
- 		q->flags = 0;
- 		mt76_dma_queue_reset(dev, q);
- 		mt76_dma_rx_fill(dev, q, false);
--		q->flags = flags;
- 
--		ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
-+		ret = mtk_wed_device_txfree_ring_setup(q->wed, q->regs);
- 		if (!ret)
--			q->wed_regs = wed->txfree_ring.reg_base;
-+			q->wed_regs = q->wed->txfree_ring.reg_base;
- 		break;
- 	case MT76_WED_Q_RX:
--		ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
-+		ret = mtk_wed_device_rx_ring_setup(q->wed, ring, q->regs,
-+						   reset);
- 		if (!ret)
--			q->wed_regs = wed->rx_ring[ring].reg_base;
-+			q->wed_regs = q->wed->rx_ring[ring].reg_base;
-+		break;
-+	case MT76_WED_RRO_Q_DATA:
-+		q->flags &= ~MT_QFLAG_WED;
-+		__mt76_dma_queue_reset(dev, q, false);
-+		mtk_wed_device_rro_rx_ring_setup(q->wed, ring, q->regs);
-+		q->head = q->ndesc - 1;
-+		q->queued = q->head;
-+		break;
-+	case MT76_WED_RRO_Q_MSDU_PG:
-+		q->flags &= ~MT_QFLAG_WED;
-+		__mt76_dma_queue_reset(dev, q, false);
-+		mtk_wed_device_msdu_pg_rx_ring_setup(q->wed, ring, q->regs);
-+		q->head = q->ndesc - 1;
-+		q->queued = q->head;
-+		break;
-+	case MT76_WED_RRO_Q_IND:
-+		q->flags &= ~MT_QFLAG_WED;
-+		mt76_dma_queue_reset(dev, q);
-+		mt76_dma_rx_fill(dev, q, false);
-+		mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
- 		break;
- 	default:
- 		ret = -EINVAL;
-+		break;
- 	}
-+	q->flags = flags;
- 
- 	return ret;
- #else
-@@ -706,11 +764,26 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- 	q->buf_size = bufsize;
- 	q->hw_idx = idx;
- 
--	size = q->ndesc * sizeof(struct mt76_desc);
--	q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
-+	size = mt76_queue_is_wed_rro_ind(q) ? sizeof(struct mt76_wed_rro_desc)
-+					    : sizeof(struct mt76_desc);
-+	q->desc = dmam_alloc_coherent(dev->dma_dev, q->ndesc * size,
-+				      &q->desc_dma, GFP_KERNEL);
- 	if (!q->desc)
- 		return -ENOMEM;
- 
-+	if (mt76_queue_is_wed_rro_ind(q)) {
-+		struct mt76_wed_rro_desc *rro_desc;
-+		int i;
-+
-+		rro_desc = (struct mt76_wed_rro_desc *)q->desc;
-+		for (i = 0; i < q->ndesc; i++) {
-+			struct mt76_wed_rro_ind *cmd;
-+
-+			cmd = (struct mt76_wed_rro_ind *)&rro_desc[i];
-+			cmd->magic_cnt = MT_DMA_WED_IND_CMD_CNT - 1;
-+		}
-+	}
-+
- 	size = q->ndesc * sizeof(*q->entry);
- 	q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
- 	if (!q->entry)
-@@ -724,8 +797,13 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- 	if (ret)
- 		return ret;
- 
--	if (q->flags != MT_WED_Q_TXFREE)
--		mt76_dma_queue_reset(dev, q);
-+	if (mtk_wed_device_active(&dev->mmio.wed)) {
-+		if ((mtk_wed_get_rx_capa(&dev->mmio.wed) && mt76_queue_is_wed_rro(q)) ||
-+		    mt76_queue_is_wed_tx_free(q))
-+			return 0;
-+	}
-+
-+	mt76_dma_queue_reset(dev, q);
- 
- 	return 0;
- }
-@@ -746,7 +824,8 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
- 		if (!buf)
- 			break;
- 
--		mt76_put_page_pool_buf(buf, false);
-+		if (!mt76_queue_is_wed_rro(q))
-+			mt76_put_page_pool_buf(buf, false);
- 	} while (1);
- 
- 	if (q->rx_head) {
-@@ -761,19 +840,22 @@ static void
- mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
- {
- 	struct mt76_queue *q = &dev->q_rx[qid];
--	int i;
- 
- 	if (!q->ndesc)
- 		return;
- 
--	for (i = 0; i < q->ndesc; i++)
--		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
-+	if (!mt76_queue_is_wed_rro_ind(q)) {
-+		int i;
-+
-+		for (i = 0; i < q->ndesc; i++)
-+			q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
-+	}
- 
- 	mt76_dma_rx_cleanup(dev, q);
- 
- 	/* reset WED rx queues */
- 	mt76_dma_wed_setup(dev, q, true);
--	if (q->flags != MT_WED_Q_TXFREE) {
-+	if (!mt76_queue_is_wed_tx_free(q)) {
- 		mt76_dma_sync_idx(dev, q);
- 		mt76_dma_rx_fill(dev, q, false);
- 	}
-@@ -816,8 +898,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
- 	bool more;
- 
- 	if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
--	    q->flags == MT_WED_Q_TXFREE) {
--		dma_idx = Q_READ(dev, q, dma_idx);
-+	    mt76_queue_is_wed_tx_free(q)) {
-+		dma_idx = Q_READ(q, dma_idx);
- 		check_ddone = true;
- 	}
- 
-@@ -827,7 +909,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
- 
- 		if (check_ddone) {
- 			if (q->tail == dma_idx)
--				dma_idx = Q_READ(dev, q, dma_idx);
-+				dma_idx = Q_READ(q, dma_idx);
- 
- 			if (q->tail == dma_idx)
- 				break;
-@@ -979,16 +1061,23 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
- 	mt76_for_each_q_rx(dev, i) {
- 		struct mt76_queue *q = &dev->q_rx[i];
- 
-+		if (mtk_wed_device_active(&dev->mmio.wed) &&
-+		    mt76_queue_is_wed_rro(q))
-+			continue;
-+
- 		netif_napi_del(&dev->napi[i]);
- 		mt76_dma_rx_cleanup(dev, q);
- 
- 		page_pool_destroy(q->page_pool);
- 	}
- 
--	mt76_free_pending_txwi(dev);
--	mt76_free_pending_rxwi(dev);
--
- 	if (mtk_wed_device_active(&dev->mmio.wed))
- 		mtk_wed_device_detach(&dev->mmio.wed);
-+
-+	if (mtk_wed_device_active(&dev->mmio.wed_hif2))
-+		mtk_wed_device_detach(&dev->mmio.wed_hif2);
-+
-+	mt76_free_pending_txwi(dev);
-+	mt76_free_pending_rxwi(dev);
- }
- EXPORT_SYMBOL_GPL(mt76_dma_cleanup);
-diff --git a/dma.h b/dma.h
-index 1b090d7..22b79d5 100644
---- a/dma.h
-+++ b/dma.h
-@@ -25,6 +25,13 @@
- #define MT_DMA_PPE_ENTRY		GENMASK(30, 16)
- #define MT_DMA_INFO_PPE_VLD		BIT(31)
- 
-+#define MT_DMA_CTL_PN_CHK_FAIL		BIT(13)
-+#define MT_DMA_CTL_VER_MASK		BIT(7)
-+
-+#define MT_DMA_RRO_EN		BIT(13)
-+
-+#define MT_DMA_WED_IND_CMD_CNT		8
-+
- #define MT_DMA_HDR_LEN			4
- #define MT_RX_INFO_LEN			4
- #define MT_FCE_INFO_LEN			4
-@@ -37,6 +44,11 @@ struct mt76_desc {
- 	__le32 info;
- } __packed __aligned(4);
- 
-+struct mt76_wed_rro_desc {
-+	__le32 buf0;
-+	__le32 buf1;
-+} __packed __aligned(4);
-+
- enum mt76_qsel {
- 	MT_QSEL_MGMT,
- 	MT_QSEL_HCCA,
-diff --git a/mac80211.c b/mac80211.c
-index 12fcb2b..cd102dd 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -1726,7 +1726,7 @@ EXPORT_SYMBOL_GPL(mt76_get_antenna);
- 
- struct mt76_queue *
- mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
--		int ring_base, u32 flags)
-+		int ring_base, void *wed, u32 flags)
- {
- 	struct mt76_queue *hwq;
- 	int err;
-@@ -1736,6 +1736,7 @@ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
- 		return ERR_PTR(-ENOMEM);
- 
- 	hwq->flags = flags;
-+	hwq->wed = wed;
- 
- 	err = dev->queue_ops->alloc(dev, hwq, idx, n_desc, 0, ring_base);
- 	if (err < 0)
-@@ -1843,3 +1844,19 @@ enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy)
- 	return MT_DFS_STATE_ACTIVE;
- }
- EXPORT_SYMBOL_GPL(mt76_phy_dfs_state);
-+
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+int mt76_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+		      struct net_device *netdev, enum tc_setup_type type,
-+		      void *type_data)
-+{
-+	struct mt76_phy *phy = hw->priv;
-+	struct mtk_wed_device *wed = &phy->dev->mmio.wed;
-+
-+	if (!mtk_wed_device_active(wed))
-+		return -EOPNOTSUPP;
-+
-+	return mtk_wed_device_setup_tc(wed, netdev, type, type_data);
-+}
-+EXPORT_SYMBOL_GPL(mt76_net_setup_tc);
-+#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
-diff --git a/mmio.c b/mmio.c
-index 86e3d2a..c346249 100644
---- a/mmio.c
-+++ b/mmio.c
-@@ -4,6 +4,7 @@
-  */
- 
- #include "mt76.h"
-+#include "dma.h"
- #include "trace.h"
- 
- static u32 mt76_mmio_rr(struct mt76_dev *dev, u32 offset)
-@@ -84,6 +85,102 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr,
- }
- EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
- 
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
-+{
-+	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
-+	int i;
-+
-+	for (i = 0; i < dev->rx_token_size; i++) {
-+		struct mt76_txwi_cache *t;
-+
-+		t = mt76_rx_token_release(dev, i);
-+		if (!t || !t->ptr)
-+			continue;
-+
-+		mt76_put_page_pool_buf(t->ptr, false);
-+		t->ptr = NULL;
-+
-+		mt76_put_rxwi(dev, t);
-+	}
-+
-+	mt76_free_pending_rxwi(dev);
-+}
-+EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
-+
-+u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
-+{
-+	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
-+	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
-+	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
-+	int i, len = SKB_WITH_OVERHEAD(q->buf_size);
-+	struct mt76_txwi_cache *t = NULL;
-+
-+	for (i = 0; i < size; i++) {
-+		enum dma_data_direction dir;
-+		dma_addr_t addr;
-+		u32 offset;
-+		int token;
-+		void *buf;
-+
-+		t = mt76_get_rxwi(dev);
-+		if (!t)
-+			goto unmap;
-+
-+		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
-+		if (!buf)
-+			goto unmap;
-+
-+		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
-+		dir = page_pool_get_dma_dir(q->page_pool);
-+		dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
-+
-+		desc->buf0 = cpu_to_le32(addr);
-+		token = mt76_rx_token_consume(dev, buf, t, addr);
-+		if (token < 0) {
-+			mt76_put_page_pool_buf(buf, false);
-+			goto unmap;
-+		}
-+
-+		desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
-+						      token));
-+		desc++;
-+	}
-+
-+	return 0;
-+
-+unmap:
-+	if (t)
-+		mt76_put_rxwi(dev, t);
-+	mt76_mmio_wed_release_rx_buf(wed);
-+
-+	return -ENOMEM;
-+}
-+EXPORT_SYMBOL_GPL(mt76_mmio_wed_init_rx_buf);
-+
-+int mt76_mmio_wed_offload_enable(struct mtk_wed_device *wed)
-+{
-+	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
-+
-+	spin_lock_bh(&dev->token_lock);
-+	dev->token_size = wed->wlan.token_start;
-+	spin_unlock_bh(&dev->token_lock);
-+
-+	return !wait_event_timeout(dev->tx_wait, !dev->wed_token_count, HZ);
-+}
-+EXPORT_SYMBOL_GPL(mt76_mmio_wed_offload_enable);
-+
-+void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed)
-+{
-+	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
-+
-+	spin_lock_bh(&dev->token_lock);
-+	dev->token_size = dev->drv->token_size;
-+	spin_unlock_bh(&dev->token_lock);
-+}
-+EXPORT_SYMBOL_GPL(mt76_mmio_wed_offload_disable);
-+#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
-+
- void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs)
- {
- 	static const struct mt76_bus_ops mt76_mmio_ops = {
-diff --git a/mt76.h b/mt76.h
-index a238216..7f93210 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -28,15 +28,22 @@
- #define MT76_TOKEN_FREE_THR	64
- 
- #define MT_QFLAG_WED_RING	GENMASK(1, 0)
--#define MT_QFLAG_WED_TYPE	GENMASK(3, 2)
--#define MT_QFLAG_WED		BIT(4)
-+#define MT_QFLAG_WED_TYPE	GENMASK(4, 2)
-+#define MT_QFLAG_WED		BIT(5)
-+#define MT_QFLAG_WED_RRO	BIT(6)
-+#define MT_QFLAG_WED_RRO_EN	BIT(7)
- 
- #define __MT_WED_Q(_type, _n)	(MT_QFLAG_WED | \
- 				 FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
- 				 FIELD_PREP(MT_QFLAG_WED_RING, _n))
-+#define __MT_WED_RRO_Q(_type, _n)	(MT_QFLAG_WED_RRO | __MT_WED_Q(_type, _n))
-+
- #define MT_WED_Q_TX(_n)		__MT_WED_Q(MT76_WED_Q_TX, _n)
- #define MT_WED_Q_RX(_n)		__MT_WED_Q(MT76_WED_Q_RX, _n)
- #define MT_WED_Q_TXFREE		__MT_WED_Q(MT76_WED_Q_TXFREE, 0)
-+#define MT_WED_RRO_Q_DATA(_n)	__MT_WED_RRO_Q(MT76_WED_RRO_Q_DATA, _n)
-+#define MT_WED_RRO_Q_MSDU_PG(_n)	__MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n)
-+#define MT_WED_RRO_Q_IND	__MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0)
- 
- struct mt76_dev;
- struct mt76_phy;
-@@ -58,6 +65,9 @@ enum mt76_wed_type {
- 	MT76_WED_Q_TX,
- 	MT76_WED_Q_TXFREE,
- 	MT76_WED_Q_RX,
-+	MT76_WED_RRO_Q_DATA,
-+	MT76_WED_RRO_Q_MSDU_PG,
-+	MT76_WED_RRO_Q_IND,
- };
- 
- struct mt76_bus_ops {
-@@ -106,6 +116,16 @@ enum mt76_rxq_id {
- 	MT_RXQ_MAIN_WA,
- 	MT_RXQ_BAND2,
- 	MT_RXQ_BAND2_WA,
-+	MT_RXQ_RRO_BAND0,
-+	MT_RXQ_RRO_BAND1,
-+	MT_RXQ_RRO_BAND2,
-+	MT_RXQ_MSDU_PAGE_BAND0,
-+	MT_RXQ_MSDU_PAGE_BAND1,
-+	MT_RXQ_MSDU_PAGE_BAND2,
-+	MT_RXQ_TXFREE_BAND0,
-+	MT_RXQ_TXFREE_BAND1,
-+	MT_RXQ_TXFREE_BAND2,
-+	MT_RXQ_RRO_IND,
- 	__MT_RXQ_MAX
- };
- 
-@@ -183,6 +203,7 @@ struct mt76_queue {
- 	spinlock_t lock;
- 	spinlock_t cleanup_lock;
- 	struct mt76_queue_entry *entry;
-+	struct mt76_rro_desc *rro_desc;
- 	struct mt76_desc *desc;
- 
- 	u16 first;
-@@ -196,8 +217,9 @@ struct mt76_queue {
- 
- 	u8 buf_offset;
- 	u8 hw_idx;
--	u8 flags;
-+	u16 flags;
- 
-+	struct mtk_wed_device *wed;
- 	u32 wed_regs;
- 
- 	dma_addr_t desc_dma;
-@@ -352,6 +374,17 @@ struct mt76_txq {
- 	bool aggr;
- };
- 
-+struct mt76_wed_rro_ind {
-+	u32 se_id	: 12;
-+	u32 rsv		: 4;
-+	u32 start_sn	: 12;
-+	u32 ind_reason	: 4;
-+	u32 ind_cnt	: 13;
-+	u32 win_sz	: 3;
-+	u32 rsv2	: 13;
-+	u32 magic_cnt	: 3;
-+};
-+
- struct mt76_txwi_cache {
- 	struct list_head list;
- 	dma_addr_t dma_addr;
-@@ -602,6 +635,7 @@ struct mt76_mmio {
- 	u32 irqmask;
- 
- 	struct mtk_wed_device wed;
-+	struct mtk_wed_device wed_hif2;
- 	struct completion wed_reset;
- 	struct completion wed_reset_complete;
- };
-@@ -1046,6 +1080,12 @@ bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
- void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs);
- void mt76_pci_disable_aspm(struct pci_dev *pdev);
- 
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+int mt76_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+		      struct net_device *netdev, enum tc_setup_type type,
-+		      void *type_data);
-+#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
-+
- static inline u16 mt76_chip(struct mt76_dev *dev)
- {
- 	return dev->rev >> 16;
-@@ -1056,6 +1096,13 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
- 	return dev->rev & 0xffff;
- }
- 
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size);
-+void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed);
-+int mt76_mmio_wed_offload_enable(struct mtk_wed_device *wed);
-+void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed);
-+#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
-+
- #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76))
- #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76))
- 
-@@ -1105,15 +1152,16 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len);
- 
- struct mt76_queue *
- mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
--		int ring_base, u32 flags);
-+		int ring_base, void *wed, u32 flags);
- u16 mt76_calculate_default_rate(struct mt76_phy *phy,
- 				struct ieee80211_vif *vif, int rateidx);
- static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx,
--				     int n_desc, int ring_base, u32 flags)
-+				     int n_desc, int ring_base, void *wed,
-+				     u32 flags)
- {
- 	struct mt76_queue *q;
- 
--	q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, flags);
-+	q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, wed, flags);
- 	if (IS_ERR(q))
- 		return PTR_ERR(q);
- 
-@@ -1127,7 +1175,7 @@ static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx,
- {
- 	struct mt76_queue *q;
- 
--	q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, 0);
-+	q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, NULL, 0);
- 	if (IS_ERR(q))
- 		return PTR_ERR(q);
- 
-@@ -1541,10 +1589,38 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
- 			      struct mt76_power_limits *dest,
- 			      s8 target_power);
- 
--static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
-+static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q)
- {
- 	return (q->flags & MT_QFLAG_WED) &&
--	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
-+	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
-+}
-+
-+static inline bool mt76_queue_is_wed_rro(struct mt76_queue *q)
-+{
-+	return q->flags & MT_QFLAG_WED_RRO;
-+}
-+
-+static inline bool mt76_queue_is_wed_rro_ind(struct mt76_queue *q)
-+{
-+	return mt76_queue_is_wed_rro(q) &&
-+	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_IND;
-+}
-+
-+static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q)
-+{
-+	return mt76_queue_is_wed_rro(q) &&
-+	       (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA ||
-+		FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG);
-+}
-+
-+static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
-+{
-+	if (!(q->flags & MT_QFLAG_WED))
-+		return false;
-+
-+	return FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX ||
-+	       mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q);
-+
- }
- 
- struct mt76_txwi_cache *
-@@ -1584,10 +1660,14 @@ static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
- static inline int
- mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
- {
--	int token;
-+	int token, start = 0;
-+
-+	if (mtk_wed_device_active(&dev->mmio.wed))
-+		start = dev->mmio.wed.wlan.nbuf;
- 
- 	spin_lock_bh(&dev->token_lock);
--	token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC);
-+	token = idr_alloc(&dev->token, *ptxwi, start, start + dev->token_size,
-+			  GFP_ATOMIC);
- 	spin_unlock_bh(&dev->token_lock);
- 
- 	return token;
-diff --git a/mt7603/dma.c b/mt7603/dma.c
-index 03ba11a..7a2f5d3 100644
---- a/mt7603/dma.c
-+++ b/mt7603/dma.c
-@@ -173,13 +173,14 @@ int mt7603_dma_init(struct mt7603_dev *dev)
- 
- 	for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
- 		ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
--					 MT7603_TX_RING_SIZE, MT_TX_RING_BASE, 0);
-+					 MT7603_TX_RING_SIZE, MT_TX_RING_BASE,
-+					 NULL, 0);
- 		if (ret)
- 			return ret;
- 	}
- 
- 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
--				 MT7603_PSD_RING_SIZE, MT_TX_RING_BASE, 0);
-+				 MT7603_PSD_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
- 	if (ret)
- 		return ret;
- 
-@@ -189,12 +190,12 @@ int mt7603_dma_init(struct mt7603_dev *dev)
- 		return ret;
- 
- 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_BEACON, MT_TX_HW_QUEUE_BCN,
--				 MT_MCU_RING_SIZE, MT_TX_RING_BASE, 0);
-+				 MT_MCU_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
- 	if (ret)
- 		return ret;
- 
- 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_CAB, MT_TX_HW_QUEUE_BMC,
--				 MT_MCU_RING_SIZE, MT_TX_RING_BASE, 0);
-+				 MT_MCU_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
- 	if (ret)
- 		return ret;
- 
-diff --git a/mt7615/dma.c b/mt7615/dma.c
-index 0ce01cc..e7135b2 100644
---- a/mt7615/dma.c
-+++ b/mt7615/dma.c
-@@ -26,14 +26,14 @@ mt7622_init_tx_queues_multi(struct mt7615_dev *dev)
- 	for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
- 		ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
- 					 MT7615_TX_RING_SIZE / 2,
--					 MT_TX_RING_BASE, 0);
-+					 MT_TX_RING_BASE, NULL, 0);
- 		if (ret)
- 			return ret;
- 	}
- 
- 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT7622_TXQ_MGMT,
- 				 MT7615_TX_MGMT_RING_SIZE,
--				 MT_TX_RING_BASE, 0);
-+				 MT_TX_RING_BASE, NULL, 0);
- 	if (ret)
- 		return ret;
- 
-@@ -55,7 +55,7 @@ mt7615_init_tx_queues(struct mt7615_dev *dev)
- 		return mt7622_init_tx_queues_multi(dev);
- 
- 	ret = mt76_connac_init_tx_queues(&dev->mphy, 0, MT7615_TX_RING_SIZE,
--					 MT_TX_RING_BASE, 0);
-+					 MT_TX_RING_BASE, NULL, 0);
- 	if (ret)
- 		return ret;
- 
-diff --git a/mt76_connac.h b/mt76_connac.h
-index 1f29d8c..e5ebde1 100644
---- a/mt76_connac.h
-+++ b/mt76_connac.h
-@@ -391,7 +391,8 @@ mt76_connac_mutex_release(struct mt76_dev *dev, struct mt76_connac_pm *pm)
- 
- void mt76_connac_gen_ppe_thresh(u8 *he_ppet, int nss);
- int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
--			       int ring_base, u32 flags);
-+			       int ring_base, void *wed, u32 flags);
-+
- void mt76_connac_write_hw_txp(struct mt76_dev *dev,
- 			      struct mt76_tx_info *tx_info,
- 			      void *txp_ptr, u32 id);
-diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index 93402d2..c791464 100644
---- a/mt76_connac_mac.c
-+++ b/mt76_connac_mac.c
-@@ -256,11 +256,12 @@ void mt76_connac_txp_skb_unmap(struct mt76_dev *dev,
- EXPORT_SYMBOL_GPL(mt76_connac_txp_skb_unmap);
- 
- int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
--			       int ring_base, u32 flags)
-+			       int ring_base, void *wed, u32 flags)
- {
- 	int i, err;
- 
--	err = mt76_init_tx_queue(phy, 0, idx, n_desc, ring_base, flags);
-+	err = mt76_init_tx_queue(phy, 0, idx, n_desc, ring_base,
-+				 wed, flags);
- 	if (err < 0)
- 		return err;
- 
-diff --git a/mt76x02_mmio.c b/mt76x02_mmio.c
-index 9b5e3fb..e5ad635 100644
---- a/mt76x02_mmio.c
-+++ b/mt76x02_mmio.c
-@@ -199,13 +199,14 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
- 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- 		ret = mt76_init_tx_queue(&dev->mphy, i, mt76_ac_to_hwq(i),
- 					 MT76x02_TX_RING_SIZE,
--					 MT_TX_RING_BASE, 0);
-+					 MT_TX_RING_BASE, NULL, 0);
- 		if (ret)
- 			return ret;
- 	}
- 
- 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
--				 MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE, 0);
-+				 MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE,
-+				 NULL, 0);
- 	if (ret)
- 		return ret;
- 
-diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 59a44d7..1bceeb5 100644
---- a/mt7915/dma.c
-+++ b/mt7915/dma.c
-@@ -9,18 +9,20 @@ static int
- mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc, int ring_base)
- {
- 	struct mt7915_dev *dev = phy->dev;
-+	struct mtk_wed_device *wed = NULL;
- 
--	if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
- 		if (is_mt798x(&dev->mt76))
- 			ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
- 		else
- 			ring_base = MT_WED_TX_RING_BASE;
- 
- 		idx -= MT_TXQ_ID(0);
-+		wed = &dev->mt76.mmio.wed;
- 	}
- 
- 	return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc, ring_base,
--					  MT_WED_Q_TX(idx));
-+					  wed, MT_WED_Q_TX(idx));
- }
- 
- static int mt7915_poll_tx(struct napi_struct *napi, int budget)
-@@ -492,7 +494,8 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
- 	if (mtk_wed_device_active(&mdev->mmio.wed) && is_mt7915(mdev)) {
- 		wa_rx_base = MT_WED_RX_RING_BASE;
- 		wa_rx_idx = MT7915_RXQ_MCU_WA;
--		dev->mt76.q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE;
-+		mdev->q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE;
-+		mdev->q_rx[MT_RXQ_MCU_WA].wed = &mdev->mmio.wed;
- 	} else {
- 		wa_rx_base = MT_RXQ_RING_BASE(MT_RXQ_MCU_WA);
- 		wa_rx_idx = MT_RXQ_ID(MT_RXQ_MCU_WA);
-@@ -507,9 +510,10 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
- 	if (!dev->phy.mt76->band_idx) {
- 		if (mtk_wed_device_active(&mdev->mmio.wed) &&
- 		    mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
--			dev->mt76.q_rx[MT_RXQ_MAIN].flags =
-+			mdev->q_rx[MT_RXQ_MAIN].flags =
- 				MT_WED_Q_RX(MT7915_RXQ_BAND0);
- 			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
-+			mdev->q_rx[MT_RXQ_MAIN].wed = &mdev->mmio.wed;
- 		}
- 
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
-@@ -528,6 +532,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
- 
- 		if (mtk_wed_device_active(&mdev->mmio.wed)) {
- 			mdev->q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
-+			mdev->q_rx[MT_RXQ_MAIN_WA].wed = &mdev->mmio.wed;
- 			if (is_mt7916(mdev)) {
- 				wa_rx_base =  MT_WED_RX_RING_BASE;
- 				wa_rx_idx = MT7915_RXQ_MCU_WA;
-@@ -544,9 +549,10 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
- 	if (dev->dbdc_support || dev->phy.mt76->band_idx) {
- 		if (mtk_wed_device_active(&mdev->mmio.wed) &&
- 		    mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
--			dev->mt76.q_rx[MT_RXQ_BAND1].flags =
-+			mdev->q_rx[MT_RXQ_BAND1].flags =
- 				MT_WED_Q_RX(MT7915_RXQ_BAND1);
- 			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
-+			mdev->q_rx[MT_RXQ_BAND1].wed = &mdev->mmio.wed;
- 		}
- 
- 		/* rx data queue for band1 */
-@@ -643,7 +649,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
- 		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
- 
- 	mt76_for_each_q_rx(&dev->mt76, i) {
--		if (dev->mt76.q_rx[i].flags == MT_WED_Q_TXFREE)
-+		if (mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i]))
- 			continue;
- 
- 		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
-diff --git a/mt7915/main.c b/mt7915/main.c
-index a3fd54c..ba34c8e 100644
---- a/mt7915/main.c
-+++ b/mt7915/main.c
-@@ -1653,20 +1653,6 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
- 
- 	return 0;
- }
--
--static int
--mt7915_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
--		    struct net_device *netdev, enum tc_setup_type type,
--		    void *type_data)
--{
--	struct mt7915_dev *dev = mt7915_hw_dev(hw);
--	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
--
--	if (!mtk_wed_device_active(wed))
--		return -EOPNOTSUPP;
--
--	return mtk_wed_device_setup_tc(wed, netdev, type, type_data);
--}
- #endif
- 
- const struct ieee80211_ops mt7915_ops = {
-@@ -1721,6 +1707,6 @@ const struct ieee80211_ops mt7915_ops = {
- 	.set_radar_background = mt7915_set_radar_background,
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- 	.net_fill_forward_path = mt7915_net_fill_forward_path,
--	.net_setup_tc = mt7915_net_setup_tc,
-+	.net_setup_tc = mt76_net_setup_tc,
- #endif
- };
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index fc7ace6..85cb3fe 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -542,105 +542,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
- }
- 
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
--static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
--{
--	struct mt7915_dev *dev;
--
--	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
--
--	spin_lock_bh(&dev->mt76.token_lock);
--	dev->mt76.token_size = wed->wlan.token_start;
--	spin_unlock_bh(&dev->mt76.token_lock);
--
--	return !wait_event_timeout(dev->mt76.tx_wait,
--				   !dev->mt76.wed_token_count, HZ);
--}
--
--static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
--{
--	struct mt7915_dev *dev;
--
--	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
--
--	spin_lock_bh(&dev->mt76.token_lock);
--	dev->mt76.token_size = MT7915_TOKEN_SIZE;
--	spin_unlock_bh(&dev->mt76.token_lock);
--}
--
--static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
--{
--	struct mt7915_dev *dev;
--	int i;
--
--	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
--	for (i = 0; i < dev->mt76.rx_token_size; i++) {
--		struct mt76_txwi_cache *t;
--
--		t = mt76_rx_token_release(&dev->mt76, i);
--		if (!t || !t->ptr)
--			continue;
--
--		mt76_put_page_pool_buf(t->ptr, false);
--		t->ptr = NULL;
--
--		mt76_put_rxwi(&dev->mt76, t);
--	}
--
--	mt76_free_pending_rxwi(&dev->mt76);
--}
--
--static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
--{
--	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
--	struct mt76_txwi_cache *t = NULL;
--	struct mt7915_dev *dev;
--	struct mt76_queue *q;
--	int i, len;
--
--	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
--	q = &dev->mt76.q_rx[MT_RXQ_MAIN];
--	len = SKB_WITH_OVERHEAD(q->buf_size);
--
--	for (i = 0; i < size; i++) {
--		enum dma_data_direction dir;
--		dma_addr_t addr;
--		u32 offset;
--		int token;
--		void *buf;
--
--		t = mt76_get_rxwi(&dev->mt76);
--		if (!t)
--			goto unmap;
--
--		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
--		if (!buf)
--			goto unmap;
--
--		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
--		dir = page_pool_get_dma_dir(q->page_pool);
--		dma_sync_single_for_device(dev->mt76.dma_dev, addr, len, dir);
--
--		desc->buf0 = cpu_to_le32(addr);
--		token = mt76_rx_token_consume(&dev->mt76, buf, t, addr);
--		if (token < 0) {
--			mt76_put_page_pool_buf(buf, false);
--			goto unmap;
--		}
--
--		desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
--						      token));
--		desc++;
--	}
--
--	return 0;
--
--unmap:
--	if (t)
--		mt76_put_rxwi(&dev->mt76, t);
--	mt7915_mmio_wed_release_rx_buf(wed);
--	return -ENOMEM;
--}
--
- static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
- 					    struct mtk_wed_wo_rx_stats *stats)
- {
-@@ -778,10 +679,10 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
- 	}
- 
- 	wed->wlan.init_buf = mt7915_wed_init_buf;
--	wed->wlan.offload_enable = mt7915_mmio_wed_offload_enable;
--	wed->wlan.offload_disable = mt7915_mmio_wed_offload_disable;
--	wed->wlan.init_rx_buf = mt7915_mmio_wed_init_rx_buf;
--	wed->wlan.release_rx_buf = mt7915_mmio_wed_release_rx_buf;
-+	wed->wlan.offload_enable = mt76_mmio_wed_offload_enable;
-+	wed->wlan.offload_disable = mt76_mmio_wed_offload_disable;
-+	wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
-+	wed->wlan.release_rx_buf = mt76_mmio_wed_release_rx_buf;
- 	wed->wlan.update_wo_rx_stats = mt7915_mmio_wed_update_rx_stats;
- 	wed->wlan.reset = mt7915_mmio_wed_reset;
- 	wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete;
-diff --git a/mt7921/pci.c b/mt7921/pci.c
-index 9647e4b..9ea7e0c 100644
---- a/mt7921/pci.c
-+++ b/mt7921/pci.c
-@@ -171,7 +171,7 @@ static int mt7921_dma_init(struct mt792x_dev *dev)
- 	/* init tx queue */
- 	ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0,
- 					 MT7921_TX_RING_SIZE,
--					 MT_TX_RING_BASE, 0);
-+					 MT_TX_RING_BASE, NULL, 0);
- 	if (ret)
- 		return ret;
- 
-diff --git a/mt7925/pci.c b/mt7925/pci.c
-index 08ef75e..734f31e 100644
---- a/mt7925/pci.c
-+++ b/mt7925/pci.c
-@@ -218,7 +218,7 @@ static int mt7925_dma_init(struct mt792x_dev *dev)
- 	/* init tx queue */
- 	ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7925_TXQ_BAND0,
- 					 MT7925_TX_RING_SIZE,
--					 MT_TX_RING_BASE, 0);
-+					 MT_TX_RING_BASE, NULL, 0);
- 	if (ret)
- 		return ret;
- 
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 586e247..2221d22 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -7,6 +7,26 @@
- #include "../dma.h"
- #include "mac.h"
- 
-+int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx, int n_desc,
-+			  int ring_base, struct mtk_wed_device *wed)
-+{
-+	struct mt7996_dev *dev = phy->dev;
-+	u32 flags = 0;
-+
-+	if (mtk_wed_device_active(wed)) {
-+		ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
-+		idx -= MT_TXQ_ID(0);
-+
-+		if (phy->mt76->band_idx == MT_BAND2)
-+			flags = MT_WED_Q_TX(0);
-+		else
-+			flags = MT_WED_Q_TX(idx);
-+	}
-+
-+	return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc,
-+					  ring_base, wed, flags);
-+}
-+
- static int mt7996_poll_tx(struct napi_struct *napi, int budget)
- {
- 	struct mt7996_dev *dev;
-@@ -45,6 +65,29 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
- 	RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
- 	RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
- 
-+	if (dev->has_rro) {
-+		/* band0 */
-+		RXQ_CONFIG(MT_RXQ_RRO_BAND0, WFDMA0, MT_INT_RX_DONE_RRO_BAND0,
-+			   MT7996_RXQ_RRO_BAND0);
-+		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND0, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND0,
-+			   MT7996_RXQ_MSDU_PG_BAND0);
-+		RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0, MT_INT_RX_TXFREE_MAIN,
-+			   MT7996_RXQ_TXFREE0);
-+		/* band1 */
-+		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND1,
-+			   MT7996_RXQ_MSDU_PG_BAND1);
-+		/* band2 */
-+		RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0, MT_INT_RX_DONE_RRO_BAND2,
-+			   MT7996_RXQ_RRO_BAND2);
-+		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND2,
-+			   MT7996_RXQ_MSDU_PG_BAND2);
-+		RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0, MT_INT_RX_TXFREE_TRI,
-+			   MT7996_RXQ_TXFREE2);
-+
-+		RXQ_CONFIG(MT_RXQ_RRO_IND, WFDMA0, MT_INT_RX_DONE_RRO_IND,
-+			   MT7996_RXQ_RRO_IND);
-+	}
-+
- 	/* data tx queue */
- 	TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7996_TXQ_BAND0);
- 	TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
-@@ -73,6 +116,24 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x1a0, 0x10));
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x2a0, 0x10));
- 
-+	if (dev->has_rro) {
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
-+			PREFETCH(0x3a0, 0x10));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
-+			PREFETCH(0x4a0, 0x10));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND0) + ofs,
-+			PREFETCH(0x5a0, 0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND1) + ofs,
-+			PREFETCH(0x5e0, 0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND2) + ofs,
-+			PREFETCH(0x620, 0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND0) + ofs,
-+			PREFETCH(0x660, 0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
-+			PREFETCH(0x6a0, 0x4));
-+	}
-+#undef PREFETCH
-+
- 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
- }
- 
-@@ -128,8 +189,9 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
- 	}
- }
- 
--void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
-+void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
- {
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 	u32 hif1_ofs = 0;
- 	u32 irq_mask;
- 
-@@ -138,11 +200,16 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
- 
- 	/* enable WFDMA Tx/Rx */
- 	if (!reset) {
--		mt76_set(dev, MT_WFDMA0_GLO_CFG,
--			 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
--			 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
--			 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
--			 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-+		if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed))
-+			mt76_set(dev, MT_WFDMA0_GLO_CFG,
-+				 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+				 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO);
-+		else
-+			mt76_set(dev, MT_WFDMA0_GLO_CFG,
-+				 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+				 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-+				 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-+				 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
- 
- 		if (dev->hif2)
- 			mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
-@@ -153,11 +220,7 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
- 	}
- 
- 	/* enable interrupts for TX/RX rings */
--	irq_mask = MT_INT_MCU_CMD;
--	if (reset)
--		goto done;
--
--	irq_mask = MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
-+	irq_mask = MT_INT_MCU_CMD | MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
- 
- 	if (!dev->mphy.band_idx)
- 		irq_mask |= MT_INT_BAND0_RX_DONE;
-@@ -168,7 +231,16 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
- 	if (dev->tbtc_support)
- 		irq_mask |= MT_INT_BAND2_RX_DONE;
- 
--done:
-+	if (mtk_wed_device_active(wed) && wed_reset) {
-+		u32 wed_irq_mask = irq_mask;
-+
-+		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
-+		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
-+		mtk_wed_device_start(wed, wed_irq_mask);
-+	}
-+
-+	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
-+
- 	mt7996_irq_enable(dev, irq_mask);
- 	mt7996_irq_disable(dev, 0);
- }
-@@ -241,17 +313,90 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
- 		/* fix hardware limitation, pcie1's rx ring3 is not available
- 		 * so, redirect pcie0 rx ring3 interrupt to pcie1
- 		 */
--		mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
--			 MT_WFDMA0_RX_INT_SEL_RING3);
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    dev->has_rro)
-+			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
-+				 MT_WFDMA0_RX_INT_SEL_RING6);
-+		else
-+			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
-+				 MT_WFDMA0_RX_INT_SEL_RING3);
-+	}
-+
-+	mt7996_dma_start(dev, reset, true);
-+}
-+
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+int mt7996_dma_rro_init(struct mt7996_dev *dev)
-+{
-+	struct mt76_dev *mdev = &dev->mt76;
-+	u32 irq_mask;
-+	int ret;
-+
-+	/* ind cmd */
-+	mdev->q_rx[MT_RXQ_RRO_IND].flags = MT_WED_RRO_Q_IND;
-+	mdev->q_rx[MT_RXQ_RRO_IND].wed = &mdev->mmio.wed;
-+	ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_RRO_IND],
-+			       MT_RXQ_ID(MT_RXQ_RRO_IND),
-+			       MT7996_RX_RING_SIZE,
-+			       0, MT_RXQ_RRO_IND_RING_BASE);
-+	if (ret)
-+		return ret;
- 
--		/* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
-+	/* rx msdu page queue for band0 */
-+	mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags =
-+		MT_WED_RRO_Q_MSDU_PG(0) | MT_QFLAG_WED_RRO_EN;
-+	mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0].wed = &mdev->mmio.wed;
-+	ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0],
-+			       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND0),
-+			       MT7996_RX_RING_SIZE,
-+			       MT7996_RX_MSDU_PAGE_SIZE,
-+			       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND0));
-+	if (ret)
-+		return ret;
-+
-+	if (dev->dbdc_support) {
-+		/* rx msdu page queue for band1 */
-+		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags =
-+			MT_WED_RRO_Q_MSDU_PG(1) | MT_QFLAG_WED_RRO_EN;
-+		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].wed = &mdev->mmio.wed;
-+		ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1],
-+				       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND1),
-+				       MT7996_RX_RING_SIZE,
-+				       MT7996_RX_MSDU_PAGE_SIZE,
-+				       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND1));
-+		if (ret)
-+			return ret;
-+	}
-+
-+	if (dev->tbtc_support) {
-+		/* rx msdu page queue for band2 */
-+		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags =
-+			MT_WED_RRO_Q_MSDU_PG(2) | MT_QFLAG_WED_RRO_EN;
-+		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].wed = &mdev->mmio.wed;
-+		ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2],
-+				       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND2),
-+				       MT7996_RX_RING_SIZE,
-+				       MT7996_RX_MSDU_PAGE_SIZE,
-+				       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND2));
-+		if (ret)
-+			return ret;
- 	}
- 
--	mt7996_dma_start(dev, reset);
-+	irq_mask = mdev->mmio.irqmask | MT_INT_RRO_RX_DONE |
-+		   MT_INT_TX_DONE_BAND2;
-+	mt76_wr(dev, MT_INT_MASK_CSR, irq_mask);
-+	mtk_wed_device_start_hw_rro(&mdev->mmio.wed, irq_mask, false);
-+	mt7996_irq_enable(dev, irq_mask);
-+
-+	return 0;
- }
-+#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
- 
- int mt7996_dma_init(struct mt7996_dev *dev)
- {
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
-+	u32 rx_base;
- 	u32 hif1_ofs = 0;
- 	int ret;
- 
-@@ -265,10 +410,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 	mt7996_dma_disable(dev, true);
- 
- 	/* init tx queue */
--	ret = mt76_connac_init_tx_queues(dev->phy.mt76,
--					 MT_TXQ_ID(dev->mphy.band_idx),
--					 MT7996_TX_RING_SIZE,
--					 MT_TXQ_RING_BASE(0), 0);
-+	ret = mt7996_init_tx_queues(&dev->phy,
-+				    MT_TXQ_ID(dev->mphy.band_idx),
-+				    MT7996_TX_RING_SIZE,
-+				    MT_TXQ_RING_BASE(0),
-+				    wed);
- 	if (ret)
- 		return ret;
- 
-@@ -315,6 +461,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 		return ret;
- 
- 	/* rx data queue for band0 and band1 */
-+	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed)) {
-+		dev->mt76.q_rx[MT_RXQ_MAIN].flags = MT_WED_Q_RX(0);
-+		dev->mt76.q_rx[MT_RXQ_MAIN].wed = wed;
-+	}
-+
- 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
- 			       MT_RXQ_ID(MT_RXQ_MAIN),
- 			       MT7996_RX_RING_SIZE,
-@@ -324,6 +475,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 		return ret;
- 
- 	/* tx free notify event from WA for band0 */
-+	if (mtk_wed_device_active(wed) && !dev->has_rro) {
-+		dev->mt76.q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
-+		dev->mt76.q_rx[MT_RXQ_MAIN_WA].wed = wed;
-+	}
-+
- 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN_WA],
- 			       MT_RXQ_ID(MT_RXQ_MAIN_WA),
- 			       MT7996_RX_MCU_RING_SIZE,
-@@ -334,17 +490,23 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 
- 	if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
- 		/* rx data queue for band2 */
-+		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
- 				       MT_RXQ_ID(MT_RXQ_BAND2),
- 				       MT7996_RX_RING_SIZE,
- 				       MT_RX_BUF_SIZE,
--				       MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs);
-+				       rx_base);
- 		if (ret)
- 			return ret;
- 
- 		/* tx free notify event from WA for band2
- 		 * use pcie0's rx ring3, but, redirect pcie0 rx ring3 interrupt to pcie1
- 		 */
-+		if (mtk_wed_device_active(wed_hif2) && !dev->has_rro) {
-+			dev->mt76.q_rx[MT_RXQ_BAND2_WA].flags = MT_WED_Q_TXFREE;
-+			dev->mt76.q_rx[MT_RXQ_BAND2_WA].wed = wed_hif2;
-+		}
-+
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2_WA],
- 				       MT_RXQ_ID(MT_RXQ_BAND2_WA),
- 				       MT7996_RX_MCU_RING_SIZE,
-@@ -354,6 +516,60 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 			return ret;
- 	}
- 
-+	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed) &&
-+	    dev->has_rro) {
-+		/* rx rro data queue for band0 */
-+		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags =
-+			MT_WED_RRO_Q_DATA(0) | MT_QFLAG_WED_RRO_EN;
-+		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].wed = wed;
-+		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
-+				       MT_RXQ_ID(MT_RXQ_RRO_BAND0),
-+				       MT7996_RX_RING_SIZE,
-+				       MT7996_RX_BUF_SIZE,
-+				       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND0));
-+		if (ret)
-+			return ret;
-+
-+		/* tx free notify event from WA for band0 */
-+		dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
-+		dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].wed = wed;
-+
-+		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
-+				       MT_RXQ_ID(MT_RXQ_TXFREE_BAND0),
-+				       MT7996_RX_MCU_RING_SIZE,
-+				       MT7996_RX_BUF_SIZE,
-+				       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND0));
-+		if (ret)
-+			return ret;
-+
-+		if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
-+			/* rx rro data queue for band2 */
-+			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags =
-+				MT_WED_RRO_Q_DATA(1) | MT_QFLAG_WED_RRO_EN;
-+			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].wed = wed;
-+			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
-+					       MT_RXQ_ID(MT_RXQ_RRO_BAND2),
-+					       MT7996_RX_RING_SIZE,
-+					       MT7996_RX_BUF_SIZE,
-+					       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND2) + hif1_ofs);
-+			if (ret)
-+				return ret;
-+
-+			/* tx free notify event from MAC for band2 */
-+			if (mtk_wed_device_active(wed_hif2)) {
-+				dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].flags = MT_WED_Q_TXFREE;
-+				dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].wed = wed_hif2;
-+			}
-+			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2],
-+					       MT_RXQ_ID(MT_RXQ_TXFREE_BAND2),
-+					       MT7996_RX_MCU_RING_SIZE,
-+					       MT7996_RX_BUF_SIZE,
-+					       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND2) + hif1_ofs);
-+			if (ret)
-+				return ret;
-+		}
-+	}
-+
- 	ret = mt76_init_queues(dev, mt76_dma_rx_poll);
- 	if (ret < 0)
- 		return ret;
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 12c2513..d335b58 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -155,7 +155,7 @@ mt7996_regd_notifier(struct wiphy *wiphy,
- }
- 
- static void
--mt7996_init_wiphy(struct ieee80211_hw *hw)
-+mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
- {
- 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
- 	struct mt76_dev *mdev = &phy->dev->mt76;
-@@ -167,6 +167,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
- 	hw->max_rx_aggregation_subframes = max_subframes;
- 	hw->max_tx_aggregation_subframes = max_subframes;
- 	hw->netdev_features = NETIF_F_RXCSUM;
-+	if (mtk_wed_device_active(wed))
-+		hw->netdev_features |= NETIF_F_HW_TC;
- 
- 	hw->radiotap_timestamp.units_pos =
- 		IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
-@@ -312,8 +314,13 @@ void mt7996_mac_init(struct mt7996_dev *dev)
- 
- 	/* rro module init */
- 	mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
--	mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
--	mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
-+	if (dev->has_rro) {
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 1);
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 0);
-+	} else {
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
-+	}
- 
- 	mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
- 			  MCU_WA_PARAM_HW_PATH_HIF_VER,
-@@ -350,6 +357,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	struct mt76_phy *mphy;
- 	u32 mac_ofs, hif1_ofs = 0;
- 	int ret;
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 
- 	if (band != MT_BAND1 && band != MT_BAND2)
- 		return 0;
-@@ -361,8 +369,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	if (phy)
- 		return 0;
- 
--	if (band == MT_BAND2 && dev->hif2)
-+	if (band == MT_BAND2 && dev->hif2) {
- 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+		wed = &dev->mt76.mmio.wed_hif2;
-+	}
- 
- 	mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7996_ops, band);
- 	if (!mphy)
-@@ -395,11 +405,12 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	mt76_eeprom_override(mphy);
- 
- 	/* init wiphy according to mphy and phy */
--	mt7996_init_wiphy(mphy->hw);
--	ret = mt76_connac_init_tx_queues(phy->mt76,
--					 MT_TXQ_ID(band),
--					 MT7996_TX_RING_SIZE,
--					 MT_TXQ_RING_BASE(band) + hif1_ofs, 0);
-+	mt7996_init_wiphy(mphy->hw, wed);
-+	ret = mt7996_init_tx_queues(mphy->priv,
-+				    MT_TXQ_ID(band),
-+				    MT7996_TX_RING_SIZE,
-+				    MT_TXQ_RING_BASE(band) + hif1_ofs,
-+				    wed);
- 	if (ret)
- 		goto error;
- 
-@@ -412,6 +423,13 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	if (ret)
- 		goto error;
- 
-+	if (wed == &dev->mt76.mmio.wed_hif2 && mtk_wed_device_active(wed)) {
-+		u32 irq_mask = dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2;
-+
-+		mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask);
-+		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask);
-+	}
-+
- 	return 0;
- 
- error:
-@@ -456,6 +474,120 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
- 	msleep(20);
- }
- 
-+static int mt7996_wed_rro_init(struct mt7996_dev *dev)
-+{
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	u32 reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;
-+	struct mt7996_wed_rro_addr *addr;
-+	void *ptr;
-+	int i;
-+
-+	if (!dev->has_rro)
-+		return 0;
-+
-+	if (!mtk_wed_device_active(wed))
-+		return 0;
-+
-+	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.ba_bitmap); i++) {
-+		ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
-+					  MT7996_RRO_BA_BITMAP_CR_SIZE,
-+					  &dev->wed_rro.ba_bitmap[i].phy_addr,
-+					  GFP_KERNEL);
-+		if (!ptr)
-+			return -ENOMEM;
-+
-+		dev->wed_rro.ba_bitmap[i].ptr = ptr;
-+	}
-+
-+	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
-+		int j;
-+
-+		ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
-+				MT7996_RRO_WINDOW_MAX_SIZE * sizeof(*addr),
-+				&dev->wed_rro.addr_elem[i].phy_addr,
-+				GFP_KERNEL);
-+		if (!ptr)
-+			return -ENOMEM;
-+
-+		dev->wed_rro.addr_elem[i].ptr = ptr;
-+		memset(dev->wed_rro.addr_elem[i].ptr, 0,
-+		       MT7996_RRO_WINDOW_MAX_SIZE * sizeof(*addr));
-+
-+		addr = dev->wed_rro.addr_elem[i].ptr;
-+		for (j = 0; j < MT7996_RRO_WINDOW_MAX_SIZE; j++) {
-+			addr->signature = 0xff;
-+			addr++;
-+		}
-+
-+		wed->wlan.ind_cmd.addr_elem_phys[i] =
-+			dev->wed_rro.addr_elem[i].phy_addr;
-+	}
-+
-+	ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
-+				  MT7996_RRO_WINDOW_MAX_LEN * sizeof(*addr),
-+				  &dev->wed_rro.session.phy_addr,
-+				  GFP_KERNEL);
-+	if (!ptr)
-+		return -ENOMEM;
-+
-+	dev->wed_rro.session.ptr = ptr;
-+	addr = dev->wed_rro.session.ptr;
-+	for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {
-+		addr->signature = 0xff;
-+		addr++;
-+	}
-+
-+	/* rro hw init */
-+	/* TODO: remove line after WM has set */
-+	mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
-+
-+	/* setup BA bitmap cache address */
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
-+		dev->wed_rro.ba_bitmap[0].phy_addr);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
-+		dev->wed_rro.ba_bitmap[1].phy_addr);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
-+
-+	/* setup Address element address */
-+	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
-+		mt76_wr(dev, reg, dev->wed_rro.addr_elem[i].phy_addr >> 4);
-+		reg += 4;
-+	}
-+
-+	/* setup Address element address - separate address segment mode */
-+	mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
-+		MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
-+
-+	wed->wlan.ind_cmd.win_size = ffs(MT7996_RRO_WINDOW_MAX_LEN) - 6;
-+	wed->wlan.ind_cmd.particular_sid = MT7996_RRO_MAX_SESSION;
-+	wed->wlan.ind_cmd.particular_se_phys = dev->wed_rro.session.phy_addr;
-+	wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_LEN;
-+	wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
-+
-+	mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
-+	mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
-+		 MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
-+
-+	/* particular session configure */
-+	/* use max session idx + 1 as particular session id */
-+	mt76_wr(dev, MT_RRO_PARTICULAR_CFG0, dev->wed_rro.session.phy_addr);
-+	mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
-+		MT_RRO_PARTICULAR_CONFG_EN |
-+		FIELD_PREP(MT_RRO_PARTICULAR_SID, MT7996_RRO_MAX_SESSION));
-+
-+	/* interrupt enable */
-+	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
-+		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
-+
-+	/* rro ind cmd queue init */
-+	return mt7996_dma_rro_init(dev);
-+#else
-+	return 0;
-+#endif
-+}
-+
- static int mt7996_init_hardware(struct mt7996_dev *dev)
- {
- 	int ret, idx;
-@@ -477,6 +609,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
-+	ret = mt7996_wed_rro_init(dev);
-+	if (ret)
-+		return ret;
-+
- 	ret = mt7996_eeprom_init(dev);
- 	if (ret < 0)
- 		return ret;
-@@ -884,7 +1020,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
--	mt7996_init_wiphy(hw);
-+	mt7996_init_wiphy(hw, &dev->mt76.mmio.wed);
- 
- 	ret = mt76_register_device(&dev->mt76, true, mt76_rates,
- 				   ARRAY_SIZE(mt76_rates));
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 1a1e218..4be5410 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -449,8 +449,36 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
- 	return 0;
- }
- 
-+static void
-+mt7996_wed_check_ppe(struct mt7996_dev *dev, struct mt76_queue *q,
-+		     struct mt7996_sta *msta, struct sk_buff *skb,
-+		     u32 info)
-+{
-+	struct ieee80211_vif *vif;
-+	struct wireless_dev *wdev;
-+
-+	if (!msta || !msta->vif)
-+		return;
-+
-+	if (!mt76_queue_is_wed_rx(q))
-+		return;
-+
-+	if (!(info & MT_DMA_INFO_PPE_VLD))
-+		return;
-+
-+	vif = container_of((void *)msta->vif, struct ieee80211_vif,
-+			   drv_priv);
-+	wdev = ieee80211_vif_to_wdev(vif);
-+	skb->dev = wdev->netdev;
-+
-+	mtk_wed_device_ppe_check(&dev->mt76.mmio.wed, skb,
-+				 FIELD_GET(MT_DMA_PPE_CPU_REASON, info),
-+				 FIELD_GET(MT_DMA_PPE_ENTRY, info));
-+}
-+
- static int
--mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
-+mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
-+		   struct sk_buff *skb, u32 *info)
- {
- 	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
- 	struct mt76_phy *mphy = &dev->mt76.phy;
-@@ -475,7 +503,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- 	u16 seq_ctrl = 0;
- 	__le16 fc = 0;
- 	int idx;
-+	u8 hw_aggr = false;
-+	struct mt7996_sta *msta = NULL;
- 
-+	hw_aggr = status->aggr;
- 	memset(status, 0, sizeof(*status));
- 
- 	band_idx = FIELD_GET(MT_RXD1_NORMAL_BAND_IDX, rxd1);
-@@ -502,8 +533,6 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- 	status->wcid = mt7996_rx_get_wcid(dev, idx, unicast);
- 
- 	if (status->wcid) {
--		struct mt7996_sta *msta;
--
- 		msta = container_of(status->wcid, struct mt7996_sta, wcid);
- 		spin_lock_bh(&dev->mt76.sta_poll_lock);
- 		if (list_empty(&msta->wcid.poll_list))
-@@ -708,12 +737,14 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- 		}
- 	} else {
- 		status->flag |= RX_FLAG_8023;
-+		mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
-+				     *info);
- 	}
- 
- 	if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
- 		mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode);
- 
--	if (!status->wcid || !ieee80211_is_data_qos(fc))
-+	if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr)
- 		return 0;
- 
- 	status->aggr = unicast &&
-@@ -1010,6 +1041,29 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- 	return 0;
- }
- 
-+u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
-+{
-+	struct mt76_connac_fw_txp *txp = ptr + MT_TXD_SIZE;
-+	__le32 *txwi = ptr;
-+	u32 val;
-+
-+	memset(ptr, 0, MT_TXD_SIZE + sizeof(*txp));
-+
-+	val = FIELD_PREP(MT_TXD0_TX_BYTES, MT_TXD_SIZE) |
-+	      FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CT);
-+	txwi[0] = cpu_to_le32(val);
-+
-+	val = BIT(31) |
-+	      FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3);
-+	txwi[1] = cpu_to_le32(val);
-+
-+	txp->token = cpu_to_le16(token_id);
-+	txp->nbuf = 1;
-+	txp->buf[0] = cpu_to_le32(phys + MT_TXD_SIZE + sizeof(*txp));
-+
-+	return MT_TXD_SIZE + sizeof(*txp);
-+}
-+
- static void
- mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
- {
-@@ -1388,6 +1442,12 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 
- 	switch (type) {
- 	case PKT_TYPE_TXRX_NOTIFY:
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2) &&
-+		    q == MT_RXQ_TXFREE_BAND2) {
-+			dev_kfree_skb(skb);
-+			break;
-+		}
-+
- 		mt7996_mac_tx_free(dev, skb->data, skb->len);
- 		napi_consume_skb(skb, 1);
- 		break;
-@@ -1404,7 +1464,7 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 		dev_kfree_skb(skb);
- 		break;
- 	case PKT_TYPE_NORMAL:
--		if (!mt7996_mac_fill_rx(dev, skb)) {
-+		if (!mt7996_mac_fill_rx(dev, q, skb, info)) {
- 			mt76_rx(&dev->mt76, q, skb);
- 			return;
- 		}
-@@ -1862,7 +1922,7 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 	mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
- 
- 	/* enable DMA Tx/Tx and interrupt */
--	mt7996_dma_start(dev, false);
-+	mt7996_dma_start(dev, false, false);
- 
- 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
- 	clear_bit(MT76_RESET, &dev->mphy.state);
-diff --git a/mt7996/main.c b/mt7996/main.c
-index a2ab668..ae4f0ce 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -1368,6 +1368,44 @@ out:
- 	return ret;
- }
- 
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+static int
-+mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
-+			     struct ieee80211_vif *vif,
-+			     struct ieee80211_sta *sta,
-+			     struct net_device_path_ctx *ctx,
-+			     struct net_device_path *path)
-+{
-+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
-+	struct mt7996_dev *dev = mt7996_hw_dev(hw);
-+	struct mt7996_phy *phy = mt7996_hw_phy(hw);
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+
-+	if (phy != &dev->phy && phy->mt76->band_idx == MT_BAND2)
-+		wed = &dev->mt76.mmio.wed_hif2;
-+
-+	if (!mtk_wed_device_active(wed))
-+		return -ENODEV;
-+
-+	if (msta->wcid.idx > MT7996_WTBL_STA)
-+		return -EIO;
-+
-+	path->type = DEV_PATH_MTK_WDMA;
-+	path->dev = ctx->dev;
-+	path->mtk_wdma.wdma_idx = wed->wdma_idx;
-+	path->mtk_wdma.bss = mvif->mt76.idx;
-+	path->mtk_wdma.queue = 0;
-+	path->mtk_wdma.wcid = msta->wcid.idx;
-+
-+	path->mtk_wdma.amsdu = mtk_wed_is_amsdu_supported(wed);
-+	ctx->dev = NULL;
-+
-+	return 0;
-+}
-+
-+#endif
-+
- const struct ieee80211_ops mt7996_ops = {
- 	.tx = mt7996_tx,
- 	.start = mt7996_start,
-@@ -1412,4 +1450,8 @@ const struct ieee80211_ops mt7996_ops = {
- 	.sta_add_debugfs = mt7996_sta_add_debugfs,
- #endif
- 	.set_radar_background = mt7996_set_radar_background,
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+	.net_fill_forward_path = mt7996_net_fill_forward_path,
-+	.net_setup_tc = mt76_net_setup_tc,
-+#endif
- };
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 12bf4e5..3ff70c6 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -912,7 +912,7 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
- }
- 
- static int
--mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
-+mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif *mvif,
- 		  struct ieee80211_ampdu_params *params,
- 		  bool enable, bool tx)
- {
-@@ -921,7 +921,7 @@ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
- 	struct sk_buff *skb;
- 	struct tlv *tlv;
- 
--	skb = __mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid,
-+	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, mvif, wcid,
- 					      MT7996_STA_UPDATE_MAX_SIZE);
- 	if (IS_ERR(skb))
- 		return PTR_ERR(skb);
-@@ -935,8 +935,9 @@ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
- 	ba->ba_en = enable << params->tid;
- 	ba->amsdu = params->amsdu;
- 	ba->tid = params->tid;
-+	ba->ba_rdd_rro = !tx && enable && dev->has_rro;
- 
--	return mt76_mcu_skb_send_msg(dev, skb,
-+	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
- 				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
- }
- 
-@@ -951,8 +952,7 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
- 	if (enable && !params->amsdu)
- 		msta->wcid.amsdu = false;
- 
--	return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
--				 enable, true);
-+	return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, true);
- }
- 
- int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
-@@ -962,8 +962,7 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
- 	struct mt7996_sta *msta = (struct mt7996_sta *)params->sta->drv_priv;
- 	struct mt7996_vif *mvif = msta->vif;
- 
--	return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
--				 enable, false);
-+	return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, false);
- }
- 
- static void
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 3a591a7..c7b6d4b 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -10,6 +10,10 @@
- #include "mt7996.h"
- #include "mac.h"
- #include "../trace.h"
-+#include "../dma.h"
-+
-+static bool wed_enable;
-+module_param(wed_enable, bool, 0644);
- 
- static const struct __base mt7996_reg_base[] = {
- 	[WF_AGG_BASE]		= { { 0x820e2000, 0x820f2000, 0x830e2000 } },
-@@ -191,6 +195,143 @@ static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
- 	return dev->bus_ops->rmw(mdev, __mt7996_reg_addr(dev, offset), mask, val);
- }
- 
-+int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
-+			 bool hif2, int *irq)
-+{
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct pci_dev *pci_dev = pdev_ptr;
-+	u32 hif1_ofs = 0;
-+	int ret;
-+
-+	if (!wed_enable)
-+		return 0;
-+
-+	dev->has_rro = true;
-+
-+	hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+	if (hif2)
-+		wed = &dev->mt76.mmio.wed_hif2;
-+
-+	wed->wlan.pci_dev = pci_dev;
-+	wed->wlan.bus_type = MTK_WED_BUS_PCIE;
-+
-+	wed->wlan.base = devm_ioremap(dev->mt76.dev,
-+				      pci_resource_start(pci_dev, 0),
-+				      pci_resource_len(pci_dev, 0));
-+	wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
-+
-+	if (hif2) {
-+		wed->wlan.wpdma_int = wed->wlan.phy_base +
-+				      MT_INT_PCIE1_SOURCE_CSR_EXT;
-+		wed->wlan.wpdma_mask = wed->wlan.phy_base +
-+				       MT_INT_PCIE1_MASK_CSR;
-+		wed->wlan.wpdma_tx = wed->wlan.phy_base + hif1_ofs +
-+					     MT_TXQ_RING_BASE(0) +
-+					     MT7996_TXQ_BAND2 * MT_RING_SIZE;
-+		if (dev->has_rro) {
-+			wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
-+						 MT_RXQ_RING_BASE(0) +
-+						 MT7996_RXQ_TXFREE2 * MT_RING_SIZE;
-+			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_EXT) - 1;
-+		} else {
-+			wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
-+						 MT_RXQ_RING_BASE(0) +
-+						 MT7996_RXQ_MCU_WA_TRI * MT_RING_SIZE;
-+			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
-+		}
-+
-+		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
-+		wed->wlan.wpdma_rx = wed->wlan.phy_base + hif1_ofs +
-+				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
-+				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
-+
-+		wed->wlan.id = 0x7991;
-+		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
-+	} else {
-+		wed->wlan.hw_rro = dev->has_rro; /* default on */
-+		wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
-+		wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
-+		wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
-+				     MT7996_TXQ_BAND0 * MT_RING_SIZE;
-+
-+		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
-+
-+		wed->wlan.wpdma_rx = wed->wlan.phy_base +
-+				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
-+				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
-+
-+		wed->wlan.wpdma_rx_rro[0] = wed->wlan.phy_base +
-+					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND0) +
-+					    MT7996_RXQ_RRO_BAND0 * MT_RING_SIZE;
-+		wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
-+					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
-+					    MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
-+		wed->wlan.wpdma_rx_pg = wed->wlan.phy_base +
-+					MT_RXQ_RING_BASE(MT7996_RXQ_MSDU_PG_BAND0) +
-+					MT7996_RXQ_MSDU_PG_BAND0 * MT_RING_SIZE;
-+
-+		wed->wlan.rx_nbuf = 65536;
-+		wed->wlan.rx_npkt = dev->hif2 ? 32768 : 24576;
-+		wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
-+
-+		wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
-+		wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
-+
-+		wed->wlan.rro_rx_tbit[0] = ffs(MT_INT_RX_DONE_RRO_BAND0) - 1;
-+		wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND2) - 1;
-+
-+		wed->wlan.rx_pg_tbit[0] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND0) - 1;
-+		wed->wlan.rx_pg_tbit[1] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND1) - 1;
-+		wed->wlan.rx_pg_tbit[2] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND2) - 1;
-+
-+		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
-+		wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
-+		if (dev->has_rro) {
-+			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
-+						 MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
-+			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
-+		} else {
-+			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
-+			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
-+						  MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
-+		}
-+		dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
-+	}
-+
-+	wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE;
-+	wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf;
-+
-+	wed->wlan.amsdu_max_subframes = 8;
-+	wed->wlan.amsdu_max_len = 1536;
-+
-+	wed->wlan.init_buf = mt7996_wed_init_buf;
-+	wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
-+	wed->wlan.release_rx_buf = mt76_mmio_wed_release_rx_buf;
-+	wed->wlan.offload_enable = mt76_mmio_wed_offload_enable;
-+	wed->wlan.offload_disable = mt76_mmio_wed_offload_disable;
-+
-+	if (mtk_wed_device_attach(wed))
-+		return 0;
-+
-+	*irq = wed->irq;
-+	dev->mt76.dma_dev = wed->dev;
-+
-+	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
-+	if (ret)
-+		return ret;
-+
-+	ret = dma_set_coherent_mask(wed->dev, DMA_BIT_MASK(32));
-+	if (ret)
-+		return ret;
-+
-+	return 1;
-+#else
-+	return 0;
-+#endif
-+}
-+
- static int mt7996_mmio_init(struct mt76_dev *mdev,
- 			    void __iomem *mem_base,
- 			    u32 device_id)
-@@ -241,8 +382,17 @@ void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
- 	mdev->mmio.irqmask |= set;
- 
- 	if (write_reg) {
--		mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
--		mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
-+		if (mtk_wed_device_active(&mdev->mmio.wed)) {
-+			mtk_wed_device_irq_set_mask(&mdev->mmio.wed,
-+						    mdev->mmio.irqmask);
-+			if (mtk_wed_device_active(&mdev->mmio.wed_hif2)) {
-+				mtk_wed_device_irq_set_mask(&mdev->mmio.wed_hif2,
-+							    mdev->mmio.irqmask);
-+			}
-+		} else {
-+			mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
-+			mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
-+		}
- 	}
- 
- 	spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);
-@@ -260,22 +410,36 @@ static void mt7996_rx_poll_complete(struct mt76_dev *mdev,
- static void mt7996_irq_tasklet(struct tasklet_struct *t)
- {
- 	struct mt7996_dev *dev = from_tasklet(dev, t, mt76.irq_tasklet);
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
- 	u32 i, intr, mask, intr1;
- 
--	mt76_wr(dev, MT_INT_MASK_CSR, 0);
--	if (dev->hif2)
--		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
--
--	intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
--	intr &= dev->mt76.mmio.irqmask;
--	mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
--
--	if (dev->hif2) {
--		intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
--		intr1 &= dev->mt76.mmio.irqmask;
--		mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
-+	if (dev->hif2 && mtk_wed_device_active(wed_hif2)) {
-+		mtk_wed_device_irq_set_mask(wed_hif2, 0);
-+		intr1 = mtk_wed_device_irq_get(wed_hif2,
-+					       dev->mt76.mmio.irqmask);
-+		if (intr1 & MT_INT_RX_TXFREE_EXT)
-+			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
-+	}
- 
--		intr |= intr1;
-+	if (mtk_wed_device_active(wed)) {
-+		mtk_wed_device_irq_set_mask(wed, 0);
-+		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
-+		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
-+	} else {
-+		mt76_wr(dev, MT_INT_MASK_CSR, 0);
-+		if (dev->hif2)
-+			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
-+
-+		intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
-+		intr &= dev->mt76.mmio.irqmask;
-+		mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
-+		if (dev->hif2) {
-+			intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
-+			intr1 &= dev->mt76.mmio.irqmask;
-+			mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
-+			intr |= intr1;
-+		}
- 	}
- 
- 	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
-@@ -308,9 +472,17 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
- {
- 	struct mt7996_dev *dev = dev_instance;
- 
--	mt76_wr(dev, MT_INT_MASK_CSR, 0);
--	if (dev->hif2)
--		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed, 0);
-+	else
-+		mt76_wr(dev, MT_INT_MASK_CSR, 0);
-+
-+	if (dev->hif2) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
-+			mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed_hif2, 0);
-+		else
-+			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
-+	}
- 
- 	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
- 		return IRQ_NONE;
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 7354e5c..c541eaa 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -37,6 +37,7 @@
- #define MT7996_EEPROM_SIZE		7680
- #define MT7996_EEPROM_BLOCK_SIZE	16
- #define MT7996_TOKEN_SIZE		16384
-+#define MT7996_HW_TOKEN_SIZE		8192
- 
- #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
- #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
-@@ -49,6 +50,22 @@
- #define MT7996_BASIC_RATES_TBL		11
- #define MT7996_BEACON_RATES_TBL		25
- 
-+#define MT7996_RRO_MAX_SESSION		1024
-+#define MT7996_RRO_WINDOW_MAX_LEN	1024
-+#define MT7996_RRO_ADDR_ELEM_LEN	128
-+#define MT7996_RRO_BA_BITMAP_LEN	2
-+#define MT7996_RRO_BA_BITMAP_CR_SIZE	((MT7996_RRO_MAX_SESSION * 128) /	\
-+					 MT7996_RRO_BA_BITMAP_LEN)
-+#define MT7996_RRO_BA_BITMAP_SESSION_SIZE	(MT7996_RRO_MAX_SESSION /	\
-+						 MT7996_RRO_ADDR_ELEM_LEN)
-+#define MT7996_RRO_WINDOW_MAX_SIZE	(MT7996_RRO_WINDOW_MAX_LEN *		\
-+					 MT7996_RRO_BA_BITMAP_SESSION_SIZE)
-+
-+#define MT7996_RX_BUF_SIZE		(1800 + \
-+					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
-+#define MT7996_RX_MSDU_PAGE_SIZE	(128 + \
-+					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
-+
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -78,6 +95,16 @@ enum mt7996_rxq_id {
- 	MT7996_RXQ_BAND0 = 4,
- 	MT7996_RXQ_BAND1 = 4,/* unused */
- 	MT7996_RXQ_BAND2 = 5,
-+	MT7996_RXQ_RRO_BAND0 = 8,
-+	MT7996_RXQ_RRO_BAND1 = 8,/* unused */
-+	MT7996_RXQ_RRO_BAND2 = 6,
-+	MT7996_RXQ_MSDU_PG_BAND0 = 10,
-+	MT7996_RXQ_MSDU_PG_BAND1 = 11,
-+	MT7996_RXQ_MSDU_PG_BAND2 = 12,
-+	MT7996_RXQ_TXFREE0 = 9,
-+	MT7996_RXQ_TXFREE1 = 9,
-+	MT7996_RXQ_TXFREE2 = 7,
-+	MT7996_RXQ_RRO_IND = 0,
- };
- 
- struct mt7996_twt_flow {
-@@ -147,6 +174,15 @@ struct mt7996_hif {
- 	int irq;
- };
- 
-+struct mt7996_wed_rro_addr {
-+	u32 head_low;
-+	u32 head_high : 4;
-+	u32 count: 11;
-+	u32 oor: 1;
-+	u32 rsv : 8;
-+	u32 signature : 8;
-+};
-+
- struct mt7996_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7996_dev *dev;
-@@ -226,6 +262,22 @@ struct mt7996_dev {
- 	bool tbtc_support:1;
- 	bool flash_mode:1;
- 	bool has_eht:1;
-+	bool has_rro:1;
-+
-+	struct {
-+		struct {
-+			void *ptr;
-+			dma_addr_t phy_addr;
-+		} ba_bitmap[MT7996_RRO_BA_BITMAP_LEN];
-+		struct {
-+			void *ptr;
-+			dma_addr_t phy_addr;
-+		} addr_elem[MT7996_RRO_ADDR_ELEM_LEN];
-+		struct {
-+			void *ptr;
-+			dma_addr_t phy_addr;
-+		} session;
-+	} wed_rro;
- 
- 	bool ibf;
- 	u8 fw_debug_wm;
-@@ -335,7 +387,9 @@ int mt7996_dma_init(struct mt7996_dev *dev);
- void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
- void mt7996_dma_prefetch(struct mt7996_dev *dev);
- void mt7996_dma_cleanup(struct mt7996_dev *dev);
--void mt7996_dma_start(struct mt7996_dev *dev, bool reset);
-+void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset);
-+int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
-+			  int n_desc, int ring_base, struct mtk_wed_device *wed);
- void mt7996_init_txpower(struct mt7996_dev *dev,
- 			 struct ieee80211_supported_band *sband);
- int mt7996_txbf_init(struct mt7996_dev *dev);
-@@ -495,5 +549,16 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
- void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			    struct ieee80211_sta *sta, struct dentry *dir);
- #endif
-+int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
-+			 bool hif2, int *irq);
-+u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
-+
-+#ifdef CONFIG_MTK_DEBUG
-+int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
-+#endif
-+
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+int mt7996_dma_rro_init(struct mt7996_dev *dev);
-+#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
- 
- #endif
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index c530105..92869ca 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -125,15 +125,26 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 	mt7996_wfsys_reset(dev);
- 	hif2 = mt7996_pci_init_hif2(pdev);
- 
--	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
-+	ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
- 	if (ret < 0)
--		goto free_device;
-+		goto free_wed_or_irq_vector;
- 
--	irq = pdev->irq;
--	ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
-+	if (!ret) {
-+		ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
-+		if (ret < 0)
-+			goto free_device;
-+	}
-+	ret = devm_request_irq(mdev->dev, pdev->irq, mt7996_irq_handler,
- 			       IRQF_SHARED, KBUILD_MODNAME, dev);
- 	if (ret)
--		goto free_irq_vector;
-+		goto free_wed_or_irq_vector;
-+
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
-+		ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
-+				       IRQF_SHARED, KBUILD_MODNAME "-wed", dev);
-+		if (ret)
-+			goto free_irq;
-+	}
- 
- 	mt76_wr(dev, MT_INT_MASK_CSR, 0);
- 	/* master switch of PCIe tnterrupt enable */
-@@ -143,16 +154,30 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 		hif2_dev = container_of(hif2->dev, struct pci_dev, dev);
- 		dev->hif2 = hif2;
- 
--		ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
-+		ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &irq);
- 		if (ret < 0)
--			goto free_hif2;
-+			goto free_irq;
-+
-+		if (!ret) {
-+			ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
-+			if (ret < 0)
-+				goto free_hif2;
- 
--		dev->hif2->irq = hif2_dev->irq;
--		ret = devm_request_irq(mdev->dev, dev->hif2->irq,
--				       mt7996_irq_handler, IRQF_SHARED,
--				       KBUILD_MODNAME "-hif", dev);
-+			dev->hif2->irq = hif2_dev->irq;
-+		}
-+
-+		ret = devm_request_irq(mdev->dev, hif2_dev->irq, mt7996_irq_handler,
-+				       IRQF_SHARED, KBUILD_MODNAME "-hif", dev);
- 		if (ret)
--			goto free_hif2_irq_vector;
-+			goto free_hif2;
-+
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) {
-+			ret = devm_request_irq(mdev->dev, irq,
-+					       mt7996_irq_handler, IRQF_SHARED,
-+					       KBUILD_MODNAME "-wed-hif", dev);
-+			if (ret)
-+				goto free_hif2_irq_vector;
-+		}
- 
- 		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
- 		/* master switch of PCIe tnterrupt enable */
-@@ -168,15 +193,28 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- free_hif2_irq:
- 	if (dev->hif2)
- 		devm_free_irq(mdev->dev, dev->hif2->irq, dev);
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
-+		devm_free_irq(mdev->dev, dev->mt76.mmio.wed_hif2.irq, dev);
- free_hif2_irq_vector:
--	if (dev->hif2)
--		pci_free_irq_vectors(hif2_dev);
-+	if (dev->hif2) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
-+			mtk_wed_device_detach(&dev->mt76.mmio.wed_hif2);
-+		else
-+			pci_free_irq_vectors(hif2_dev);
-+	}
- free_hif2:
- 	if (dev->hif2)
- 		put_device(dev->hif2->dev);
--	devm_free_irq(mdev->dev, irq, dev);
--free_irq_vector:
--	pci_free_irq_vectors(pdev);
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		devm_free_irq(mdev->dev, dev->mt76.mmio.wed.irq, dev);
-+free_irq:
-+	devm_free_irq(mdev->dev, pdev->irq, dev);
-+free_wed_or_irq_vector:
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		mtk_wed_device_detach(&dev->mt76.mmio.wed);
-+	else
-+		pci_free_irq_vectors(pdev);
-+
- free_device:
- 	mt76_free_device(&dev->mt76);
- 
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 5702290..854390d 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -39,6 +39,38 @@ enum base_rev {
- 
- #define __BASE(_id, _band)			(dev->reg.base[(_id)].band_base[(_band)])
- 
-+/* RRO TOP */
-+#define MT_RRO_TOP_BASE				0xA000
-+#define MT_RRO_TOP(ofs)				(MT_RRO_TOP_BASE + (ofs))
-+
-+#define MT_RRO_BA_BITMAP_BASE0			MT_RRO_TOP(0x8)
-+#define MT_RRO_BA_BITMAP_BASE1			MT_RRO_TOP(0xC)
-+#define WF_RRO_AXI_MST_CFG			MT_RRO_TOP(0xB8)
-+#define WF_RRO_AXI_MST_CFG_DIDX_OK		BIT(12)
-+#define MT_RRO_ADDR_ARRAY_BASE1			MT_RRO_TOP(0x34)
-+#define MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE	BIT(31)
-+
-+#define MT_RRO_IND_CMD_SIGNATURE_BASE0		MT_RRO_TOP(0x38)
-+#define MT_RRO_IND_CMD_SIGNATURE_BASE1		MT_RRO_TOP(0x3C)
-+#define MT_RRO_IND_CMD_0_CTRL0			MT_RRO_TOP(0x40)
-+#define MT_RRO_IND_CMD_SIGNATURE_BASE1_EN	BIT(31)
-+
-+#define MT_RRO_PARTICULAR_CFG0			MT_RRO_TOP(0x5C)
-+#define MT_RRO_PARTICULAR_CFG1			MT_RRO_TOP(0x60)
-+#define MT_RRO_PARTICULAR_CONFG_EN		BIT(31)
-+#define MT_RRO_PARTICULAR_SID			GENMASK(30, 16)
-+
-+#define MT_RRO_BA_BITMAP_BASE_EXT0		MT_RRO_TOP(0x70)
-+#define MT_RRO_BA_BITMAP_BASE_EXT1		MT_RRO_TOP(0x74)
-+#define MT_RRO_HOST_INT_ENA			MT_RRO_TOP(0x204)
-+#define MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA   BIT(0)
-+
-+#define MT_RRO_ADDR_ELEM_SEG_ADDR0		MT_RRO_TOP(0x400)
-+
-+#define MT_RRO_ACK_SN_CTRL			MT_RRO_TOP(0x50)
-+#define MT_RRO_ACK_SN_CTRL_SN_MASK		GENMASK(27, 16)
-+#define MT_RRO_ACK_SN_CTRL_SESSION_MASK		GENMASK(11, 0)
-+
- #define MT_MCU_INT_EVENT			0x2108
- #define MT_MCU_INT_EVENT_DMA_STOPPED		BIT(0)
- #define MT_MCU_INT_EVENT_DMA_INIT		BIT(1)
-@@ -323,6 +355,7 @@ enum base_rev {
- 
- #define MT_WFDMA0_RX_INT_PCIE_SEL		MT_WFDMA0(0x154)
- #define MT_WFDMA0_RX_INT_SEL_RING3		BIT(3)
-+#define MT_WFDMA0_RX_INT_SEL_RING6		BIT(6)
- 
- #define MT_WFDMA0_MCU_HOST_INT_ENA		MT_WFDMA0(0x1f4)
- 
-@@ -367,6 +400,9 @@ enum base_rev {
- #define MT_WFDMA0_PCIE1_BASE			0xd8000
- #define MT_WFDMA0_PCIE1(ofs)			(MT_WFDMA0_PCIE1_BASE + (ofs))
- 
-+#define MT_INT_PCIE1_SOURCE_CSR_EXT		MT_WFDMA0_PCIE1(0x118)
-+#define MT_INT_PCIE1_MASK_CSR			MT_WFDMA0_PCIE1(0x11c)
-+
- #define MT_WFDMA0_PCIE1_BUSY_ENA		MT_WFDMA0_PCIE1(0x13c)
- #define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0	BIT(0)
- #define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1	BIT(1)
-@@ -387,6 +423,7 @@ enum base_rev {
- #define MT_MCUQ_RING_BASE(q)			(MT_Q_BASE(q) + 0x300)
- #define MT_TXQ_RING_BASE(q)			(MT_Q_BASE(__TXQ(q)) + 0x300)
- #define MT_RXQ_RING_BASE(q)			(MT_Q_BASE(__RXQ(q)) + 0x500)
-+#define MT_RXQ_RRO_IND_RING_BASE		MT_RRO_TOP(0x40)
- 
- #define MT_MCUQ_EXT_CTRL(q)			(MT_Q_BASE(q) +	0x600 +	\
- 						 MT_MCUQ_ID(q) * 0x4)
-@@ -412,6 +449,15 @@ enum base_rev {
- #define MT_INT_RX_TXFREE_MAIN			BIT(17)
- #define MT_INT_RX_TXFREE_TRI			BIT(15)
- #define MT_INT_MCU_CMD				BIT(29)
-+#define MT_INT_RX_TXFREE_EXT			BIT(26)
-+
-+#define MT_INT_RX_DONE_RRO_BAND0		BIT(16)
-+#define MT_INT_RX_DONE_RRO_BAND1		BIT(16)
-+#define MT_INT_RX_DONE_RRO_BAND2		BIT(14)
-+#define MT_INT_RX_DONE_RRO_IND			BIT(11)
-+#define MT_INT_RX_DONE_MSDU_PG_BAND0		BIT(18)
-+#define MT_INT_RX_DONE_MSDU_PG_BAND1		BIT(19)
-+#define MT_INT_RX_DONE_MSDU_PG_BAND2		BIT(23)
- 
- #define MT_INT_RX(q)				(dev->q_int_mask[__RXQ(q)])
- #define MT_INT_TX_MCU(q)			(dev->q_int_mask[(q)])
-@@ -420,20 +466,31 @@ enum base_rev {
- 						 MT_INT_RX(MT_RXQ_MCU_WA))
- 
- #define MT_INT_BAND0_RX_DONE			(MT_INT_RX(MT_RXQ_MAIN) |	\
--						 MT_INT_RX(MT_RXQ_MAIN_WA))
-+						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
-+						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
- 
- #define MT_INT_BAND1_RX_DONE			(MT_INT_RX(MT_RXQ_BAND1) |	\
- 						 MT_INT_RX(MT_RXQ_BAND1_WA) |	\
--						 MT_INT_RX(MT_RXQ_MAIN_WA))
-+						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
-+						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
- 
- #define MT_INT_BAND2_RX_DONE			(MT_INT_RX(MT_RXQ_BAND2) |	\
- 						 MT_INT_RX(MT_RXQ_BAND2_WA) |	\
--						 MT_INT_RX(MT_RXQ_MAIN_WA))
-+						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
-+						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
-+
-+#define MT_INT_RRO_RX_DONE			(MT_INT_RX(MT_RXQ_RRO_BAND0) |		\
-+						 MT_INT_RX(MT_RXQ_RRO_BAND1) |		\
-+						 MT_INT_RX(MT_RXQ_RRO_BAND2) |		\
-+						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND0) |	\
-+						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND1) |	\
-+						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND2))
- 
- #define MT_INT_RX_DONE_ALL			(MT_INT_RX_DONE_MCU |		\
- 						 MT_INT_BAND0_RX_DONE |		\
- 						 MT_INT_BAND1_RX_DONE |		\
--						 MT_INT_BAND2_RX_DONE)
-+						 MT_INT_BAND2_RX_DONE |		\
-+						 MT_INT_RRO_RX_DONE)
- 
- #define MT_INT_TX_DONE_FWDL			BIT(26)
- #define MT_INT_TX_DONE_MCU_WM			BIT(27)
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0003-mtk-wifi-mt76-mt7996-disable-rx-header-translation-f.patch
similarity index 72%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0003-mtk-wifi-mt76-mt7996-disable-rx-header-translation-f.patch
index 1494376..955382e 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0003-mtk-wifi-mt76-mt7996-disable-rx-header-translation-f.patch
@@ -1,20 +1,19 @@
-From cb01c8f9cef451d5e478d8498902d52a92ca4b55 Mon Sep 17 00:00:00 2001
+From 70f582db962c977a71d3d618081f894c0e658046 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 5 Sep 2023 17:31:49 +0800
-Subject: [PATCH 23/98] wifi: mt76: mt7996: disable rx header translation for
- BMC entry
+Subject: [PATCH 03/23] mtk: wifi: mt76: mt7996: disable rx header translation
+ for BMC entry
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: Ia98bb775af528fe1002590fa25bb8855945cfc4b
 ---
  mt7996/mcu.c | 9 +++++----
  1 file changed, 5 insertions(+), 4 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index c190067..39f76a0 100644
+index 3c729b56..5a2e2d12 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1719,10 +1719,10 @@ mt7996_mcu_sta_hdr_trans_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+@@ -1769,10 +1769,10 @@ mt7996_mcu_sta_hdr_trans_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
  	else
  		hdr_trans->from_ds = true;
  
@@ -27,7 +26,7 @@
  	hdr_trans->dis_rx_hdr_tran = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags);
  	if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
  		hdr_trans->to_ds = true;
-@@ -2095,6 +2095,9 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2145,6 +2145,9 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  	if (!enable)
  		goto out;
  
@@ -36,8 +35,8 @@
 +
  	/* tag order is in accordance with firmware dependency. */
  	if (sta) {
- 		/* starec phy */
-@@ -2121,8 +2124,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ 		/* starec hdrt mode */
+@@ -2169,8 +2172,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  		mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta);
  		/* starec bfee */
  		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
deleted file mode 100644
index c657c5b..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From 0d8aff6fa4ee351350dda83f8cc7ca2b557322ac Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Fri, 14 Apr 2023 16:51:59 +0800
-Subject: [PATCH 03/98] wifi: mt76: mt7996: add support for auxiliary path
-
-Add support to correctly configure the setting of variants that have
-additional TX or RX path.
-
-Change-Id: I1312c193beab5e16aae7161a7e3bdda100b72f8d
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/eeprom.c | 21 +++++++++++++++++----
- mt7996/eeprom.h |  3 +++
- mt7996/mcu.c    |  2 +-
- mt7996/mt7996.h | 14 ++++++++++++++
- 4 files changed, 35 insertions(+), 5 deletions(-)
-
-diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 544b6c6..9db7e53 100644
---- a/mt7996/eeprom.c
-+++ b/mt7996/eeprom.c
-@@ -148,36 +148,49 @@ static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
- 
- int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
- {
--	u8 path, nss, band_idx = phy->mt76->band_idx;
-+	u8 path, rx_path, nss, band_idx = phy->mt76->band_idx;
- 	u8 *eeprom = dev->mt76.eeprom.data;
- 	struct mt76_phy *mphy = phy->mt76;
-+	int max_path = 5, max_nss = 4;
- 	int ret;
- 
- 	switch (band_idx) {
- 	case MT_BAND1:
- 		path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND1,
- 				 eeprom[MT_EE_WIFI_CONF + 2]);
-+		rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND1,
-+				    eeprom[MT_EE_WIFI_CONF + 3]);
- 		nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND1,
- 				eeprom[MT_EE_WIFI_CONF + 5]);
- 		break;
- 	case MT_BAND2:
- 		path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND2,
- 				 eeprom[MT_EE_WIFI_CONF + 2]);
-+		rx_path = FIELD_GET(MT_EE_WIFI_CONF4_RX_PATH_BAND2,
-+				    eeprom[MT_EE_WIFI_CONF + 4]);
- 		nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND2,
- 				eeprom[MT_EE_WIFI_CONF + 5]);
- 		break;
- 	default:
- 		path = FIELD_GET(MT_EE_WIFI_CONF1_TX_PATH_BAND0,
- 				 eeprom[MT_EE_WIFI_CONF + 1]);
-+		rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND0,
-+				    eeprom[MT_EE_WIFI_CONF + 3]);
- 		nss = FIELD_GET(MT_EE_WIFI_CONF4_STREAM_NUM_BAND0,
- 				eeprom[MT_EE_WIFI_CONF + 4]);
- 		break;
- 	}
- 
--	if (!path || path > 4)
--		path = 4;
-+	if (!path || path > max_path)
-+		path = max_path;
- 
--	nss = min_t(u8, min_t(u8, 4, nss), path);
-+	if (!nss || nss > max_nss)
-+		nss = max_nss;
-+
-+	nss = min_t(u8, nss, path);
-+
-+	if (path != rx_path)
-+		phy->has_aux_rx = true;
- 
- 	mphy->antenna_mask = BIT(nss) - 1;
- 	mphy->chainmask = (BIT(path) - 1) << dev->chainshift[band_idx];
-diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 0c74977..412d6e2 100644
---- a/mt7996/eeprom.h
-+++ b/mt7996/eeprom.h
-@@ -33,6 +33,9 @@ enum mt7996_eeprom_field {
- #define MT_EE_WIFI_CONF1_TX_PATH_BAND0		GENMASK(5, 3)
- #define MT_EE_WIFI_CONF2_TX_PATH_BAND1		GENMASK(2, 0)
- #define MT_EE_WIFI_CONF2_TX_PATH_BAND2		GENMASK(5, 3)
-+#define MT_EE_WIFI_CONF3_RX_PATH_BAND0		GENMASK(2, 0)
-+#define MT_EE_WIFI_CONF3_RX_PATH_BAND1		GENMASK(5, 3)
-+#define MT_EE_WIFI_CONF4_RX_PATH_BAND2		GENMASK(2, 0)
- #define MT_EE_WIFI_CONF4_STREAM_NUM_BAND0	GENMASK(5, 3)
- #define MT_EE_WIFI_CONF5_STREAM_NUM_BAND1	GENMASK(2, 0)
- #define MT_EE_WIFI_CONF5_STREAM_NUM_BAND2	GENMASK(5, 3)
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 3ff70c6..328bea9 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -3178,7 +3178,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
- 		.center_ch = ieee80211_frequency_to_channel(freq1),
- 		.bw = mt76_connac_chan_bw(chandef),
- 		.tx_path_num = hweight16(phy->mt76->chainmask),
--		.rx_path = phy->mt76->chainmask >> dev->chainshift[band_idx],
-+		.rx_path = mt7996_rx_chainmask(phy) >> dev->chainshift[band_idx],
- 		.band_idx = band_idx,
- 		.channel_band = ch_band[chandef->chan->band],
- 	};
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index c541eaa..ef84173 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -206,6 +206,8 @@ struct mt7996_phy {
- 
- 	struct mt76_mib_stats mib;
- 	struct mt76_channel_state state_ts;
-+
-+	bool has_aux_rx;
- };
- 
- struct mt7996_dev {
-@@ -491,6 +493,18 @@ static inline void mt7996_irq_disable(struct mt7996_dev *dev, u32 mask)
- void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
- 			  size_t len);
- 
-+static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy)
-+{
-+	int max_nss = hweight8(phy->mt76->hw->wiphy->available_antennas_tx);
-+	int cur_nss = hweight8(phy->mt76->antenna_mask);
-+	u16 tx_chainmask = phy->mt76->chainmask;
-+
-+	if (cur_nss != max_nss)
-+		return tx_chainmask;
-+
-+	return tx_chainmask | (BIT(fls(tx_chainmask)) * phy->has_aux_rx);
-+}
-+
- void mt7996_mac_init(struct mt7996_dev *dev);
- u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw);
- bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0004-mtk-wifi-mt76-check-txs-format-before-getting-skb-by.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0004-mtk-wifi-mt76-check-txs-format-before-getting-skb-by.patch
new file mode 100644
index 0000000..314c0b3
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0004-mtk-wifi-mt76-check-txs-format-before-getting-skb-by.patch
@@ -0,0 +1,57 @@
+From 87a3fa3c38e1b840cebe5f3b088a0ff67e5920f0 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Thu, 7 Dec 2023 11:17:56 +0800
+Subject: [PATCH 04/23] mtk: wifi: mt76: check txs format before getting skb by
+ pid
+
+The PPDU TxS does not include the error bit so it cannot use to report
+status to mac80211.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt76_connac3_mac.h | 5 +++++
+ mt7996/mac.c       | 6 ++++--
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
+index 83dcd964..8cfd479a 100644
+--- a/mt76_connac3_mac.h
++++ b/mt76_connac3_mac.h
+@@ -18,6 +18,11 @@ enum {
+ 	MT_LMAC_PSMP0,
+ };
+ 
++enum {
++	MT_TXS_MPDU_FMT = 0,
++	MT_TXS_PPDU_FMT = 2,
++};
++
+ #define MT_CT_PARSE_LEN			72
+ #define MT_CT_DMA_BUF_NUM		2
+ 
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index db06a982..ff7e0753 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1193,14 +1193,16 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
+ 	struct ieee80211_tx_info *info;
+ 	struct sk_buff_head list;
+ 	struct rate_info rate = {};
+-	struct sk_buff *skb;
++	struct sk_buff *skb = NULL;
+ 	bool cck = false;
+ 	u32 txrate, txs, mode, stbc;
+ 
+ 	txs = le32_to_cpu(txs_data[0]);
+ 
+ 	mt76_tx_status_lock(mdev, &list);
+-	skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
++
++	if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) == MT_TXS_MPDU_FMT)
++		skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
+ 
+ 	if (skb) {
+ 		info = IEEE80211_SKB_CB(skb);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
deleted file mode 100644
index bb8761d..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From f6b0399c4e70fb8fa521d53e59bc933e491271c3 Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Thu, 20 Apr 2023 16:34:47 +0800
-Subject: [PATCH 04/98] wifi: mt76: mt7996: add eht mode tx stats
-
-Add eht mode bf fbk stats and bw320 through debugfs tx_stats command
-
-Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
----
- mt7996/debugfs.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 4d40ec7..9bd9535 100644
---- a/mt7996/debugfs.c
-+++ b/mt7996/debugfs.c
-@@ -476,7 +476,7 @@ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
- {
- 	struct mt76_mib_stats *mib = &phy->mib;
- 	static const char * const bw[] = {
--		"BW20", "BW40", "BW80", "BW160"
-+		"BW20", "BW40", "BW80", "BW160", "BW320"
- 	};
- 
- 	/* Tx Beamformer monitor */
-@@ -489,8 +489,9 @@ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
- 	/* Tx Beamformer Rx feedback monitor */
- 	seq_puts(s, "Tx Beamformer Rx feedback statistics: ");
- 
--	seq_printf(s, "All: %d, HE: %d, VHT: %d, HT: %d, ",
-+	seq_printf(s, "All: %d, EHT: %d, HE: %d, VHT: %d, HT: %d, ",
- 		   mib->tx_bf_rx_fb_all_cnt,
-+		   mib->tx_bf_rx_fb_eht_cnt,
- 		   mib->tx_bf_rx_fb_he_cnt,
- 		   mib->tx_bf_rx_fb_vht_cnt,
- 		   mib->tx_bf_rx_fb_ht_cnt);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0005-mtk-wifi-mt76-mt7996-fix-some-twt-issues.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0005-mtk-wifi-mt76-mt7996-fix-some-twt-issues.patch
new file mode 100644
index 0000000..c2dc2f2
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0005-mtk-wifi-mt76-mt7996-fix-some-twt-issues.patch
@@ -0,0 +1,129 @@
+From 651d207a15f2bc281edf3c92236b88853fc41006 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Wed, 8 Nov 2023 10:17:10 +0800
+Subject: [PATCH 05/23] mtk: wifi: mt76: mt7996: fix some twt issues
+
+1. Reject twt flows with the same parameters to prevent potential issues
+causing by duplicated establishment.
+2. mt7996 can support 16 twt stations so modify the table_mask to u16.
+3. The minimum twt duration supported by mt7996 is 64 according to hardware
+design. Reply station with TWT_SETUP_CMD_DICTATE if the min_twt_dur smaller
+than 64.
+4. Fix possible unaligned pointer.
+5. Remove TWT_CONTROL_WAKE_DUR_UNIT flag because mt7996 does not support it.
+
+---
+ mt7996/mac.c    | 53 +++++++++++++++++++++++++++++++++++++++++--------
+ mt7996/mt7996.h |  3 ++-
+ 2 files changed, 47 insertions(+), 9 deletions(-)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index ff7e0753..e6583427 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -2534,6 +2534,34 @@ static int mt7996_mac_check_twt_req(struct ieee80211_twt_setup *twt)
+ 	return 0;
+ }
+ 
++static bool
++mt7996_mac_twt_param_equal(struct mt7996_sta *msta,
++			   struct ieee80211_twt_params *twt_agrt)
++{
++	u16 type = le16_to_cpu(twt_agrt->req_type);
++	u8 exp;
++	int i;
++
++	exp = FIELD_GET(IEEE80211_TWT_REQTYPE_WAKE_INT_EXP, type);
++	for (i = 0; i < MT7996_MAX_STA_TWT_AGRT; i++) {
++		struct mt7996_twt_flow *f;
++
++		if (!(msta->twt.flowid_mask & BIT(i)))
++			continue;
++
++		f = &msta->twt.flow[i];
++		if (f->duration == twt_agrt->min_twt_dur &&
++		    f->mantissa == twt_agrt->mantissa &&
++		    f->exp == exp &&
++		    f->protection == !!(type & IEEE80211_TWT_REQTYPE_PROTECTION) &&
++		    f->flowtype == !!(type & IEEE80211_TWT_REQTYPE_FLOWTYPE) &&
++		    f->trigger == !!(type & IEEE80211_TWT_REQTYPE_TRIGGER))
++			return true;
++	}
++
++	return false;
++}
++
+ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
+ 			      struct ieee80211_sta *sta,
+ 			      struct ieee80211_twt_setup *twt)
+@@ -2545,8 +2573,7 @@ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
+ 	enum ieee80211_twt_setup_cmd sta_setup_cmd;
+ 	struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ 	struct mt7996_twt_flow *flow;
+-	int flowid, table_id;
+-	u8 exp;
++	u8 flowid, table_id, exp;
+ 
+ 	if (mt7996_mac_check_twt_req(twt))
+ 		goto out;
+@@ -2559,9 +2586,19 @@ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
+ 	if (hweight8(msta->twt.flowid_mask) == ARRAY_SIZE(msta->twt.flow))
+ 		goto unlock;
+ 
++	if (twt_agrt->min_twt_dur < MT7996_MIN_TWT_DUR) {
++		setup_cmd = TWT_SETUP_CMD_DICTATE;
++		twt_agrt->min_twt_dur = MT7996_MIN_TWT_DUR;
++		goto unlock;
++	}
++
++	if (mt7996_mac_twt_param_equal(msta, twt_agrt))
++		goto unlock;
++
+ 	flowid = ffs(~msta->twt.flowid_mask) - 1;
+-	le16p_replace_bits(&twt_agrt->req_type, flowid,
+-			   IEEE80211_TWT_REQTYPE_FLOWID);
++	twt_agrt->req_type &= ~cpu_to_le16(IEEE80211_TWT_REQTYPE_FLOWID);
++	twt_agrt->req_type |= le16_encode_bits(flowid,
++					       IEEE80211_TWT_REQTYPE_FLOWID);
+ 
+ 	table_id = ffs(~dev->twt.table_mask) - 1;
+ 	exp = FIELD_GET(IEEE80211_TWT_REQTYPE_WAKE_INT_EXP, req_type);
+@@ -2608,10 +2645,10 @@ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
+ unlock:
+ 	mutex_unlock(&dev->mt76.mutex);
+ out:
+-	le16p_replace_bits(&twt_agrt->req_type, setup_cmd,
+-			   IEEE80211_TWT_REQTYPE_SETUP_CMD);
+-	twt->control = (twt->control & IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT) |
+-		       (twt->control & IEEE80211_TWT_CONTROL_RX_DISABLED);
++	twt_agrt->req_type &= ~cpu_to_le16(IEEE80211_TWT_REQTYPE_SETUP_CMD);
++	twt_agrt->req_type |=
++		le16_encode_bits(setup_cmd, IEEE80211_TWT_REQTYPE_SETUP_CMD);
++	twt->control = twt->control & IEEE80211_TWT_CONTROL_RX_DISABLED;
+ }
+ 
+ void mt7996_mac_twt_teardown_flow(struct mt7996_dev *dev,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index bc73bcb4..8154ad37 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -53,6 +53,7 @@
+ 
+ #define MT7996_MAX_TWT_AGRT		16
+ #define MT7996_MAX_STA_TWT_AGRT		8
++#define MT7996_MIN_TWT_DUR		64
+ #define MT7996_MAX_QUEUE		(__MT_RXQ_MAX +	__MT_MCUQ_MAX + 3)
+ 
+ /* NOTE: used to map mt76_rates. idx may change if firmware expands table */
+@@ -320,7 +321,7 @@ struct mt7996_dev {
+ 	struct rchan *relay_fwlog;
+ 
+ 	struct {
+-		u8 table_mask;
++		u16 table_mask;
+ 		u8 n_agrt;
+ 	} twt;
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-add-thermal-protection-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-add-thermal-protection-support.patch
deleted file mode 100644
index 9d85c7c..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-add-thermal-protection-support.patch
+++ /dev/null
@@ -1,434 +0,0 @@
-From c4d8ad5eb5f4d9929e923fa2c0683a2e24d8ca0c Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Thu, 2 Feb 2023 21:20:31 +0800
-Subject: [PATCH 05/98] wifi: mt76: mt7996: add thermal protection support
-
-This commit includes the following changes:
-1. implement MTK thermal protection driver API
-2. support Linux cooling device control
-
-Change-Id: I8fecc28f5b17ee50ae4644d1dd17d188dd694731
----
- mt76_connac_mcu.h |   1 +
- mt7996/init.c     | 103 +++++++++++++++++++++++++++++++++++++++++++++
- mt7996/main.c     |   8 ++++
- mt7996/mcu.c      | 105 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      |  44 +++++++++++++++++++
- mt7996/mt7996.h   |  15 +++++++
- 6 files changed, 276 insertions(+)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 6064973..99077f1 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1021,6 +1021,7 @@ enum {
- 	MCU_UNI_EVENT_RDD_REPORT = 0x11,
- 	MCU_UNI_EVENT_ROC = 0x27,
- 	MCU_UNI_EVENT_TX_DONE = 0x2d,
-+	MCU_UNI_EVENT_THERMAL = 0x35,
- 	MCU_UNI_EVENT_NIC_CAPAB = 0x43,
- };
- 
-diff --git a/mt7996/init.c b/mt7996/init.c
-index d335b58..610d80e 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -42,6 +42,98 @@ static const struct ieee80211_iface_combination if_comb[] = {
- 	}
- };
- 
-+static int
-+mt7996_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
-+				      unsigned long *state)
-+{
-+	*state = MT7996_CDEV_THROTTLE_MAX;
-+
-+	return 0;
-+}
-+
-+static int
-+mt7996_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,
-+				      unsigned long *state)
-+{
-+	struct mt7996_phy *phy = cdev->devdata;
-+
-+	*state = phy->cdev_state;
-+
-+	return 0;
-+}
-+
-+static int
-+mt7996_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,
-+				      unsigned long state)
-+{
-+	struct mt7996_phy *phy = cdev->devdata;
-+	u8 throttling = MT7996_THERMAL_THROTTLE_MAX - state;
-+	int ret;
-+
-+	if (state > MT7996_CDEV_THROTTLE_MAX) {
-+		dev_err(phy->dev->mt76.dev,
-+			"please specify a valid throttling state\n");
-+		return -EINVAL;
-+	}
-+
-+	if (state == phy->cdev_state)
-+		return 0;
-+
-+	/*
-+	 * cooling_device convention: 0 = no cooling, more = more cooling
-+	 * mcu convention: 1 = max cooling, more = less cooling
-+	 */
-+	ret = mt7996_mcu_set_thermal_throttling(phy, throttling);
-+	if (ret)
-+		return ret;
-+
-+	phy->cdev_state = state;
-+
-+	return 0;
-+}
-+
-+static const struct thermal_cooling_device_ops mt7996_thermal_ops = {
-+	.get_max_state = mt7996_thermal_get_max_throttle_state,
-+	.get_cur_state = mt7996_thermal_get_cur_throttle_state,
-+	.set_cur_state = mt7996_thermal_set_cur_throttle_state,
-+};
-+
-+static void mt7996_unregister_thermal(struct mt7996_phy *phy)
-+{
-+	struct wiphy *wiphy = phy->mt76->hw->wiphy;
-+
-+	if (!phy->cdev)
-+	    return;
-+
-+	sysfs_remove_link(&wiphy->dev.kobj, "cooling_device");
-+	thermal_cooling_device_unregister(phy->cdev);
-+}
-+
-+static int mt7996_thermal_init(struct mt7996_phy *phy)
-+{
-+	struct wiphy *wiphy = phy->mt76->hw->wiphy;
-+	struct thermal_cooling_device *cdev;
-+	const char *name;
-+
-+	name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7996_%s",
-+			      wiphy_name(wiphy));
-+
-+	cdev = thermal_cooling_device_register(name, phy, &mt7996_thermal_ops);
-+	if (!IS_ERR(cdev)) {
-+		if (sysfs_create_link(&wiphy->dev.kobj, &cdev->device.kobj,
-+				      "cooling_device") < 0)
-+			thermal_cooling_device_unregister(cdev);
-+		else
-+			phy->cdev = cdev;
-+	}
-+
-+	/* initialize critical/maximum high temperature */
-+	phy->throttle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP;
-+	phy->throttle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP;
-+
-+	return 0;
-+}
-+
- static void mt7996_led_set_config(struct led_classdev *led_cdev,
- 				  u8 delay_on, u8 delay_off)
- {
-@@ -419,6 +511,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	if (ret)
- 		goto error;
- 
-+	ret = mt7996_thermal_init(phy);
-+	if (ret)
-+		goto error;
-+
- 	ret = mt7996_init_debugfs(phy);
- 	if (ret)
- 		goto error;
-@@ -446,6 +542,8 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
- 	if (!phy)
- 		return;
- 
-+	mt7996_unregister_thermal(phy);
-+
- 	mphy = phy->dev->mt76.phys[band];
- 	mt76_unregister_phy(mphy);
- 	ieee80211_free_hw(mphy->hw);
-@@ -1027,6 +1125,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
-+	ret = mt7996_thermal_init(&dev->phy);
-+	if (ret)
-+		return ret;
-+
- 	ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
- 
- 	ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
-@@ -1050,6 +1152,7 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
- {
- 	mt7996_unregister_phy(mt7996_phy3(dev), MT_BAND2);
- 	mt7996_unregister_phy(mt7996_phy2(dev), MT_BAND1);
-+	mt7996_unregister_thermal(&dev->phy);
- 	mt7996_coredump_unregister(dev);
- 	mt76_unregister_device(&dev->mt76);
- 	mt7996_mcu_exit(dev);
-diff --git a/mt7996/main.c b/mt7996/main.c
-index ae4f0ce..280120b 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -51,6 +51,14 @@ int mt7996_run(struct ieee80211_hw *hw)
- 	if (ret)
- 		goto out;
- 
-+	ret = mt7996_mcu_set_thermal_throttling(phy, MT7996_THERMAL_THROTTLE_MAX);
-+	if (ret)
-+		goto out;
-+
-+	ret = mt7996_mcu_set_thermal_protect(phy, true);
-+	if (ret)
-+		goto out;
-+
- 	set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
- 
- 	ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 328bea9..5310f9b 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -449,6 +449,34 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
- 	}
- }
- 
-+static void
-+mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
-+{
-+#define THERMAL_NOTIFY_TAG 0x4
-+#define THERMAL_NOTIFY 0x2
-+	struct mt76_phy *mphy = &dev->mt76.phy;
-+	struct mt7996_mcu_thermal_notify *n;
-+	struct mt7996_phy *phy;
-+
-+	n = (struct mt7996_mcu_thermal_notify *)skb->data;
-+
-+	if (n->tag != THERMAL_NOTIFY_TAG)
-+		return;
-+
-+	if (n->event_id != THERMAL_NOTIFY)
-+		return;
-+
-+	if (n->band_idx > MT_BAND2)
-+		return;
-+
-+	mphy = dev->mt76.phys[n->band_idx];
-+	if (!mphy)
-+		return;
-+
-+	phy = (struct mt7996_phy *)mphy->priv;
-+	phy->throttle_state = n->duty_percent;
-+}
-+
- static void
- mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb)
- {
-@@ -493,6 +521,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
- 	case MCU_UNI_EVENT_RDD_REPORT:
- 		mt7996_mcu_rx_radar_detected(dev, skb);
- 		break;
-+	case MCU_UNI_EVENT_THERMAL:
-+		mt7996_mcu_rx_thermal_notify(dev, skb);
-+		break;
- 	default:
- 		break;
- 	}
-@@ -3450,6 +3481,80 @@ out:
- 	return 0;
- }
- 
-+
-+int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state)
-+{
-+	struct {
-+		u8 _rsv[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+
-+		struct mt7996_mcu_thermal_ctrl ctrl;
-+	} __packed req = {
-+		.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG),
-+		.len = cpu_to_le16(sizeof(req) - 4),
-+		.ctrl = {
-+			.band_idx = phy->mt76->band_idx,
-+		},
-+	};
-+	int level, ret;
-+
-+	/* set duty cycle and level */
-+	for (level = 0; level < 4; level++) {
-+		req.ctrl.duty.duty_level = level;
-+		req.ctrl.duty.duty_cycle = state;
-+		state /= 2;
-+
-+		ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
-+					&req, sizeof(req), false);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	return 0;
-+}
-+
-+int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable)
-+{
-+#define SUSTAIN_PERIOD		10
-+	struct {
-+		u8 _rsv[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+
-+		struct mt7996_mcu_thermal_ctrl ctrl;
-+		struct mt7996_mcu_thermal_enable enable;
-+	} __packed req = {
-+		.len = cpu_to_le16(sizeof(req) - 4 - sizeof(req.enable)),
-+		.ctrl = {
-+			.band_idx = phy->mt76->band_idx,
-+			.type.protect_type = 1,
-+			.type.trigger_type = 1,
-+		},
-+	};
-+	int ret;
-+
-+	req.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_DISABLE);
-+
-+	ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
-+				&req, sizeof(req) - sizeof(req.enable), false);
-+	if (ret || !enable)
-+		return ret;
-+
-+	/* set high-temperature trigger threshold */
-+	req.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_ENABLE);
-+	req.enable.restore_temp = cpu_to_le32(phy->throttle_temp[0]);
-+	req.enable.trigger_temp = cpu_to_le32(phy->throttle_temp[1]);
-+	req.enable.sustain_time = cpu_to_le16(SUSTAIN_PERIOD);
-+
-+	req.len = cpu_to_le16(sizeof(req) - 4);
-+
-+	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
-+				 &req, sizeof(req), false);
-+}
-+
- int mt7996_mcu_set_ser(struct mt7996_dev *dev, u8 action, u8 val, u8 band)
- {
- 	struct {
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index e4b3122..f1528df 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -30,6 +30,28 @@ struct mt7996_mcu_uni_event {
- 	__le32 status; /* 0: success, others: fail */
- } __packed;
- 
-+struct mt7996_mcu_thermal_ctrl {
-+	u8 ctrl_id;
-+	u8 band_idx;
-+	union {
-+		struct {
-+			u8 protect_type; /* 1: duty admit, 2: radio off */
-+			u8 trigger_type; /* 0: low, 1: high */
-+		} __packed type;
-+		struct {
-+			u8 duty_level;	/* level 0~3 */
-+			u8 duty_cycle;
-+		} __packed duty;
-+	};
-+} __packed;
-+
-+struct mt7996_mcu_thermal_enable {
-+	__le32 trigger_temp;
-+	__le32 restore_temp;
-+	__le16 sustain_time;
-+	u8 rsv[2];
-+} __packed;
-+
- struct mt7996_mcu_csa_notify {
- 	struct mt7996_mcu_rxd rxd;
- 
-@@ -153,6 +175,22 @@ struct mt7996_mcu_mib {
- 	__le64 data;
- } __packed;
- 
-+struct mt7996_mcu_thermal_notify {
-+	struct mt7996_mcu_rxd rxd;
-+
-+	u8 __rsv1[4];
-+
-+	__le16 tag;
-+	__le16 len;
-+
-+	u8 event_id;
-+	u8 band_idx;
-+	u8 level_idx;
-+	u8 duty_percent;
-+	__le32 restore_temp;
-+	u8 __rsv2[4];
-+} __packed;
-+
- enum mt7996_chan_mib_offs {
- 	UNI_MIB_OBSS_AIRTIME = 26,
- 	UNI_MIB_NON_WIFI_TIME = 27,
-@@ -656,6 +694,12 @@ enum{
- 	UNI_CMD_SR_SET_SIGA = 0xd0,
- };
- 
-+enum {
-+	UNI_CMD_THERMAL_PROTECT_ENABLE = 0x6,
-+	UNI_CMD_THERMAL_PROTECT_DISABLE,
-+	UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG,
-+};
-+
- enum {
- 	UNI_CMD_ACCESS_REG_BASIC = 0x0,
- 	UNI_CMD_ACCESS_RF_REG_BASIC,
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index ef84173..e1972e9 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -50,6 +50,13 @@
- #define MT7996_BASIC_RATES_TBL		11
- #define MT7996_BEACON_RATES_TBL		25
- 
-+#define MT7996_THERMAL_THROTTLE_MAX	100
-+#define MT7996_CDEV_THROTTLE_MAX	99
-+#define MT7996_CRIT_TEMP_IDX		0
-+#define MT7996_MAX_TEMP_IDX		1
-+#define MT7996_CRIT_TEMP		110
-+#define MT7996_MAX_TEMP			120
-+
- #define MT7996_RRO_MAX_SESSION		1024
- #define MT7996_RRO_WINDOW_MAX_LEN	1024
- #define MT7996_RRO_ADDR_ELEM_LEN	128
-@@ -191,6 +198,11 @@ struct mt7996_phy {
- 
- 	struct ieee80211_vif *monitor_vif;
- 
-+	struct thermal_cooling_device *cdev;
-+	u8 cdev_state;
-+	u8 throttle_state;
-+	u32 throttle_temp[2]; /* 0: critical high, 1: maximum */
-+
- 	u32 rxfilter;
- 	u64 omac_mask;
- 
-@@ -445,6 +457,9 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
- int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
- int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif);
- int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);
-+int mt7996_mcu_get_temperature(struct mt7996_phy *phy);
-+int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state);
-+int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable);
- int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
- 		       u8 rx_sel, u8 val);
- int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0006-mtk-wifi-mt76-mt7996-disable-AMSDU-for-non-data-fram.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0006-mtk-wifi-mt76-mt7996-disable-AMSDU-for-non-data-fram.patch
new file mode 100644
index 0000000..6b813fd
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0006-mtk-wifi-mt76-mt7996-disable-AMSDU-for-non-data-fram.patch
@@ -0,0 +1,39 @@
+From abd4da501a5b6d4159f8ef3dbcfc9f646ecc8a40 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Mon, 6 Nov 2023 20:17:16 +0800
+Subject: [PATCH 06/23] mtk: wifi: mt76: mt7996: disable AMSDU for non-data
+ frames
+
+Mgmt. frames with amsdu may lead to unexpected errors.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt7996/mac.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index e6583427..19b34066 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -732,6 +732,9 @@ mt7996_mac_write_txwi_8023(struct mt7996_dev *dev, __le32 *txwi,
+ 	      FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype);
+ 
+ 	txwi[2] |= cpu_to_le32(val);
++
++	if (wcid->amsdu)
++		txwi[3] |= cpu_to_le32(MT_TXD3_HW_AMSDU);
+ }
+ 
+ static void
+@@ -862,8 +865,6 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ 		val |= MT_TXD3_PROTECT_FRAME;
+ 	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ 		val |= MT_TXD3_NO_ACK;
+-	if (wcid->amsdu)
+-		val |= MT_TXD3_HW_AMSDU;
+ 
+ 	txwi[3] = cpu_to_le32(val);
+ 	txwi[4] = 0;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
deleted file mode 100644
index a4338f3..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
+++ /dev/null
@@ -1,185 +0,0 @@
-From 3bf4da3eba0f082ec3be1c0ee603cbae3e9d9fbb Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Thu, 2 Feb 2023 20:53:42 +0800
-Subject: [PATCH 06/98] wifi: mt76: mt7996: add thermal sensor device support
-
----
- mt7996/init.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.c  | 41 ++++++++++++++++++++++++
- 2 files changed, 129 insertions(+)
-
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 610d80e..de4a5f7 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -4,6 +4,8 @@
-  */
- 
- #include <linux/etherdevice.h>
-+#include <linux/hwmon.h>
-+#include <linux/hwmon-sysfs.h>
- #include <linux/thermal.h>
- #include "mt7996.h"
- #include "mac.h"
-@@ -42,6 +44,82 @@ static const struct ieee80211_iface_combination if_comb[] = {
- 	}
- };
- 
-+static ssize_t mt7996_thermal_temp_show(struct device *dev,
-+					struct device_attribute *attr,
-+					char *buf)
-+{
-+	struct mt7996_phy *phy = dev_get_drvdata(dev);
-+	int i = to_sensor_dev_attr(attr)->index;
-+	int temperature;
-+
-+	switch (i) {
-+	case 0:
-+		temperature = mt7996_mcu_get_temperature(phy);
-+		if (temperature < 0)
-+			return temperature;
-+		/* display in millidegree celcius */
-+		return sprintf(buf, "%u\n", temperature * 1000);
-+	case 1:
-+	case 2:
-+		return sprintf(buf, "%u\n",
-+			       phy->throttle_temp[i - 1] * 1000);
-+	case 3:
-+		return sprintf(buf, "%hhu\n", phy->throttle_state);
-+	default:
-+		return -EINVAL;
-+	}
-+}
-+
-+static ssize_t mt7996_thermal_temp_store(struct device *dev,
-+					 struct device_attribute *attr,
-+					 const char *buf, size_t count)
-+{
-+	struct mt7996_phy *phy = dev_get_drvdata(dev);
-+	int ret, i = to_sensor_dev_attr(attr)->index;
-+	long val;
-+
-+	ret = kstrtol(buf, 10, &val);
-+	if (ret < 0)
-+		return ret;
-+
-+	mutex_lock(&phy->dev->mt76.mutex);
-+	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 40, 130);
-+
-+	/* add a safety margin ~10 */
-+	if ((i - 1 == MT7996_CRIT_TEMP_IDX &&
-+	     val > phy->throttle_temp[MT7996_MAX_TEMP_IDX] - 10) ||
-+	    (i - 1 == MT7996_MAX_TEMP_IDX &&
-+	     val - 10 < phy->throttle_temp[MT7996_CRIT_TEMP_IDX])) {
-+		dev_err(phy->dev->mt76.dev,
-+			"temp1_max shall be 10 degrees higher than temp1_crit.");
-+		mutex_unlock(&phy->dev->mt76.mutex);
-+		return -EINVAL;
-+	}
-+
-+	phy->throttle_temp[i - 1] = val;
-+	mutex_unlock(&phy->dev->mt76.mutex);
-+
-+	ret = mt7996_mcu_set_thermal_protect(phy, true);
-+	if (ret)
-+		return ret;
-+
-+	return count;
-+}
-+
-+static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7996_thermal_temp, 0);
-+static SENSOR_DEVICE_ATTR_RW(temp1_crit, mt7996_thermal_temp, 1);
-+static SENSOR_DEVICE_ATTR_RW(temp1_max, mt7996_thermal_temp, 2);
-+static SENSOR_DEVICE_ATTR_RO(throttle1, mt7996_thermal_temp, 3);
-+
-+static struct attribute *mt7996_hwmon_attrs[] = {
-+	&sensor_dev_attr_temp1_input.dev_attr.attr,
-+	&sensor_dev_attr_temp1_crit.dev_attr.attr,
-+	&sensor_dev_attr_temp1_max.dev_attr.attr,
-+	&sensor_dev_attr_throttle1.dev_attr.attr,
-+	NULL,
-+};
-+ATTRIBUTE_GROUPS(mt7996_hwmon);
-+
- static int
- mt7996_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
- 				      unsigned long *state)
-@@ -113,6 +191,7 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
- {
- 	struct wiphy *wiphy = phy->mt76->hw->wiphy;
- 	struct thermal_cooling_device *cdev;
-+	struct device *hwmon;
- 	const char *name;
- 
- 	name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7996_%s",
-@@ -131,6 +210,15 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
- 	phy->throttle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP;
- 	phy->throttle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP;
- 
-+	if (!IS_REACHABLE(CONFIG_HWMON))
-+		return 0;
-+
-+	hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,
-+						       mt7996_hwmon_groups);
-+
-+	if (IS_ERR(hwmon))
-+		return PTR_ERR(hwmon);
-+
- 	return 0;
- }
- 
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 5310f9b..8320c8c 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -3481,6 +3481,47 @@ out:
- 	return 0;
- }
- 
-+int mt7996_mcu_get_temperature(struct mt7996_phy *phy)
-+{
-+#define TEMPERATURE_QUERY 0
-+#define GET_TEMPERATURE 0
-+	struct {
-+		u8 _rsv[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+
-+		u8 rsv1;
-+		u8 action;
-+		u8 band_idx;
-+		u8 rsv2;
-+	} req = {
-+		.tag = cpu_to_le16(TEMPERATURE_QUERY),
-+		.len = cpu_to_le16(sizeof(req) - 4),
-+		.action = GET_TEMPERATURE,
-+		.band_idx = phy->mt76->band_idx,
-+	};
-+	struct mt7996_mcu_thermal {
-+		u8 _rsv[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+
-+		__le32 rsv;
-+		__le32 temperature;
-+	} __packed *res;
-+	struct sk_buff *skb;
-+	int ret;
-+
-+	ret = mt76_mcu_send_and_get_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
-+					&req, sizeof(req), true, &skb);
-+	if (ret)
-+		return ret;
-+
-+	res = (void *)skb->data;
-+
-+	return le32_to_cpu(res->temperature);
-+}
- 
- int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state)
- {
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0007-mtk-wifi-mt76-mt7996-fix-incorrect-interpretation-of.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0007-mtk-wifi-mt76-mt7996-fix-incorrect-interpretation-of.patch
new file mode 100644
index 0000000..36cd7ee
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0007-mtk-wifi-mt76-mt7996-fix-incorrect-interpretation-of.patch
@@ -0,0 +1,72 @@
+From 27ad6ee9498d3293dca55d04af1fba221460d74c Mon Sep 17 00:00:00 2001
+From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Date: Mon, 4 Dec 2023 15:39:00 +0800
+Subject: [PATCH 07/23] mtk: wifi: mt76: mt7996: fix incorrect interpretation
+ of EHT MCS and NSS capabilities
+
+The EHT-MCS Map (20 MHz-Only Non-AP STA) subfield of the Supported EHT-MCS And NSS Set field in the EHT Capabilities element is not present for AP. Therefore, STA should not parse the subfield.
+Moreover, AP should parse the subfield only if STA is 20 MHz-Only, which is confirmed by checking the Supported Channel Width Set subfield in the HE Capabilities element.
+
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+---
+ mt7996/mcu.c | 33 +++++++++++++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 5a2e2d12..8c033030 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -1237,9 +1237,32 @@ mt7996_mcu_sta_he_6g_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+ 	he_6g->capa = sta->deflink.he_6ghz_capa.capa;
+ }
+ 
++static bool
++mt7996_mcu_sta_only_20mhz(struct ieee80211_sta *sta)
++{
++	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
++	u8 bw = sta->deflink.he_cap.he_cap_elem.phy_cap_info[0];
++	u8 band_idx = msta->vif->mt76.band_idx;
++
++	if (band_idx == MT_BAND0) {
++		if (!(bw & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G))
++			return true;
++	} else {
++		if (!(bw & (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
++		            IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
++		            IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)))
++			return true;
++	}
++
++	return false;
++}
++
+ static void
+ mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+ {
++	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
++	struct ieee80211_vif *vif = container_of((void *)msta->vif,
++	                                         struct ieee80211_vif, drv_priv);
+ 	struct ieee80211_eht_mcs_nss_supp *mcs_map;
+ 	struct ieee80211_eht_cap_elem_fixed *elem;
+ 	struct sta_rec_eht *eht;
+@@ -1259,11 +1282,13 @@ mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+ 	eht->phy_cap = cpu_to_le64(*(u64 *)elem->phy_cap_info);
+ 	eht->phy_cap_ext = cpu_to_le64(elem->phy_cap_info[8]);
+ 
+-	if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
++	if (vif->type != NL80211_IFTYPE_STATION && mt7996_mcu_sta_only_20mhz(sta))
+ 		memcpy(eht->mcs_map_bw20, &mcs_map->only_20mhz, sizeof(eht->mcs_map_bw20));
+-	memcpy(eht->mcs_map_bw80, &mcs_map->bw._80, sizeof(eht->mcs_map_bw80));
+-	memcpy(eht->mcs_map_bw160, &mcs_map->bw._160, sizeof(eht->mcs_map_bw160));
+-	memcpy(eht->mcs_map_bw320, &mcs_map->bw._320, sizeof(eht->mcs_map_bw320));
++	else {
++		memcpy(eht->mcs_map_bw80, &mcs_map->bw._80, sizeof(eht->mcs_map_bw80));
++		memcpy(eht->mcs_map_bw160, &mcs_map->bw._160, sizeof(eht->mcs_map_bw160));
++		memcpy(eht->mcs_map_bw320, &mcs_map->bw._320, sizeof(eht->mcs_map_bw320));
++	}
+ }
+ 
+ static void
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-mt7996-make-band-capability-init-flexible.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
deleted file mode 100644
index 873029f..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From 3fdeeee1f24b09fc0d08b6a386e06c6146e83d9c Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 23 May 2023 15:49:03 +0800
-Subject: [PATCH 07/98] wifi: mt76: mt7996: make band capability init flexible
-
-There're some variations of mt7996 chipset which only support two-band,
-so parse the adie combination to correctly set band capability.
-
-Change-Id: Ifcb49504f02f5cc6a23c626e30b4f0e1360fe157
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/dma.c    | 14 +++++++-------
- mt7996/init.c   | 29 ++++++++++++++++++-----------
- mt7996/mcu.c    | 13 +++++--------
- mt7996/mt7996.h | 11 +++++++++++
- mt7996/regs.h   |  3 +++
- 5 files changed, 44 insertions(+), 26 deletions(-)
-
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 2221d22..3d04470 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -222,13 +222,13 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
- 	/* enable interrupts for TX/RX rings */
- 	irq_mask = MT_INT_MCU_CMD | MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
- 
--	if (!dev->mphy.band_idx)
-+	if (mt7996_band_valid(dev, MT_BAND0))
- 		irq_mask |= MT_INT_BAND0_RX_DONE;
- 
--	if (dev->dbdc_support)
-+	if (mt7996_band_valid(dev, MT_BAND1))
- 		irq_mask |= MT_INT_BAND1_RX_DONE;
- 
--	if (dev->tbtc_support)
-+	if (mt7996_band_valid(dev, MT_BAND2))
- 		irq_mask |= MT_INT_BAND2_RX_DONE;
- 
- 	if (mtk_wed_device_active(wed) && wed_reset) {
-@@ -354,7 +354,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
--	if (dev->dbdc_support) {
-+	if (mt7996_band_valid(dev, MT_BAND1)) {
- 		/* rx msdu page queue for band1 */
- 		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags =
- 			MT_WED_RRO_Q_MSDU_PG(1) | MT_QFLAG_WED_RRO_EN;
-@@ -368,7 +368,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
- 			return ret;
- 	}
- 
--	if (dev->tbtc_support) {
-+	if (mt7996_band_valid(dev, MT_BAND2)) {
- 		/* rx msdu page queue for band2 */
- 		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags =
- 			MT_WED_RRO_Q_MSDU_PG(2) | MT_QFLAG_WED_RRO_EN;
-@@ -488,7 +488,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
--	if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
-+	if (mt7996_band_valid(dev, MT_BAND2)) {
- 		/* rx data queue for band2 */
- 		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
-@@ -542,7 +542,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 		if (ret)
- 			return ret;
- 
--		if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
-+		if (mt7996_band_valid(dev, MT_BAND2)) {
- 			/* rx rro data queue for band2 */
- 			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags =
- 				MT_WED_RRO_Q_DATA(1) | MT_QFLAG_WED_RRO_EN;
-diff --git a/mt7996/init.c b/mt7996/init.c
-index de4a5f7..2e6efc5 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -539,11 +539,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	int ret;
- 	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 
--	if (band != MT_BAND1 && band != MT_BAND2)
--		return 0;
--
--	if ((band == MT_BAND1 && !dev->dbdc_support) ||
--	    (band == MT_BAND2 && !dev->tbtc_support))
-+	if (!mt7996_band_valid(dev, band) || band == MT_BAND0)
- 		return 0;
- 
- 	if (phy)
-@@ -782,8 +778,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
- 
- 	INIT_WORK(&dev->init_work, mt7996_init_work);
- 
--	dev->dbdc_support = true;
--	dev->tbtc_support = true;
-+	dev->dbdc_support = mt7996_band_valid(dev, MT_BAND1) ||
-+			    mt7996_band_valid(dev, MT_BAND2);
-+	dev->tbtc_support = mt7996_band_valid(dev, MT_BAND1) &&
-+			    mt7996_band_valid(dev, MT_BAND2);
- 
- 	ret = mt7996_dma_init(dev);
- 	if (ret)
-@@ -1217,8 +1215,6 @@ int mt7996_register_device(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
--	ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
--
- 	ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
- 	if (ret)
- 		return ret;
-@@ -1227,13 +1223,24 @@ int mt7996_register_device(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
-+	ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
-+
- 	dev->recovery.hw_init_done = true;
- 
- 	ret = mt7996_init_debugfs(&dev->phy);
- 	if (ret)
--		return ret;
-+		goto error;
- 
--	return mt7996_coredump_register(dev);
-+	ret = mt7996_coredump_register(dev);
-+	if (ret)
-+		goto error;
-+
-+	return 0;
-+
-+error:
-+	cancel_work_sync(&dev->init_work);
-+
-+	return ret;
- }
- 
- void mt7996_unregister_device(struct mt7996_dev *dev)
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 8320c8c..84f362b 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2767,7 +2767,7 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
- {
- 	struct uni_header hdr = {};
- 	struct sk_buff *skb;
--	int len, num;
-+	int len, num, i;
- 
- 	num = 2 + 2 * (dev->dbdc_support + dev->tbtc_support);
- 	len = sizeof(hdr) + num * sizeof(struct vow_rx_airtime);
-@@ -2777,13 +2777,10 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
- 
- 	skb_put_data(skb, &hdr, sizeof(hdr));
- 
--	mt7996_add_rx_airtime_tlv(skb, dev->mt76.phy.band_idx);
--
--	if (dev->dbdc_support)
--		mt7996_add_rx_airtime_tlv(skb, MT_BAND1);
--
--	if (dev->tbtc_support)
--		mt7996_add_rx_airtime_tlv(skb, MT_BAND2);
-+	for (i = 0; i < __MT_MAX_BAND; i++) {
-+		if (mt7996_band_valid(dev, i))
-+			mt7996_add_rx_airtime_tlv(skb, i);
-+	}
- 
- 	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
- 				     MCU_WM_UNI_CMD(VOW), true);
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index e1972e9..137d5a2 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -381,6 +381,17 @@ mt7996_phy3(struct mt7996_dev *dev)
- 	return __mt7996_phy(dev, MT_BAND2);
- }
- 
-+static inline bool
-+mt7996_band_valid(struct mt7996_dev *dev, u8 band)
-+{
-+	/* tri-band support */
-+	if (band <= MT_BAND2 &&
-+	    mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1)
-+		return true;
-+
-+	return band == MT_BAND0 || band == MT_BAND2;
-+}
-+
- extern const struct ieee80211_ops mt7996_ops;
- extern struct pci_driver mt7996_pci_driver;
- extern struct pci_driver mt7996_hif_driver;
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 854390d..a4d5ad8 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -602,6 +602,9 @@ enum base_rev {
- #define MT_TOP_MISC				MT_TOP(0xf0)
- #define MT_TOP_MISC_FW_STATE			GENMASK(2, 0)
- 
-+#define MT_PAD_GPIO				0x700056f0
-+#define MT_PAD_GPIO_ADIE_COMB			GENMASK(16, 15)
-+
- #define MT_HW_REV				0x70010204
- #define MT_WF_SUBSYS_RST			0x70028600
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0008-mtk-wifi-mt76-mt7992-add-TLV-sanity-check.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0008-mtk-wifi-mt76-mt7992-add-TLV-sanity-check.patch
new file mode 100644
index 0000000..110888b
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0008-mtk-wifi-mt76-mt7992-add-TLV-sanity-check.patch
@@ -0,0 +1,74 @@
+From 6bef1f8c48baa71a2c7b4bc22e30915fe0651b92 Mon Sep 17 00:00:00 2001
+From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Date: Thu, 9 Nov 2023 10:35:13 +0800
+Subject: [PATCH 08/23] mtk: wifi: mt76: mt7992: add TLV sanity check
+
+If TLV involves beacon content, its length might not be 4-byte aligned.
+Therefore, 4-byte alignment check and padding, if necessary, are performed before sending TLV to FW.
+
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+---
+ mt7996/mcu.c | 14 +++++---------
+ mt7996/mcu.h |  4 ++--
+ 2 files changed, 7 insertions(+), 11 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 8c033030..071a9ec2 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -732,13 +732,10 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ static struct tlv *
+ mt7996_mcu_add_uni_tlv(struct sk_buff *skb, u16 tag, u16 len)
+ {
+-	struct tlv *ptlv, tlv = {
+-		.tag = cpu_to_le16(tag),
+-		.len = cpu_to_le16(len),
+-	};
++	struct tlv *ptlv = skb_put(skb, len);
+ 
+-	ptlv = skb_put(skb, len);
+-	memcpy(ptlv, &tlv, sizeof(tlv));
++	ptlv->tag = cpu_to_le16(tag);
++	ptlv->len = cpu_to_le16(len);
+ 
+ 	return ptlv;
+ }
+@@ -2536,7 +2533,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
+ 	info = IEEE80211_SKB_CB(skb);
+ 	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
+ 
+-	len = sizeof(*bcn) + MT_TXD_SIZE + skb->len;
++	len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + skb->len, 4);
+ 	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len);
+ 	bcn = (struct bss_bcn_content_tlv *)tlv;
+ 	bcn->enable = en;
+@@ -2605,8 +2602,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+ 	info->band = band;
+ 	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
+ 
+-	len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
+-
++	len = ALIGN(sizeof(*discov) + MT_TXD_SIZE + skb->len, 4);
+ 	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, len);
+ 
+ 	discov = (struct bss_inband_discovery_tlv *)tlv;
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 3e013b20..a9ba63d1 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -800,10 +800,10 @@ enum {
+ 					 sizeof(struct sta_rec_hdr_trans) +	\
+ 					 sizeof(struct tlv))
+ 
+-#define MT7996_MAX_BEACON_SIZE		1342
++#define MT7996_MAX_BEACON_SIZE		1338
+ #define MT7996_BEACON_UPDATE_SIZE	(sizeof(struct bss_req_hdr) +		\
+ 					 sizeof(struct bss_bcn_content_tlv) +	\
+-					 MT_TXD_SIZE +				\
++					 4 + MT_TXD_SIZE +			\
+ 					 sizeof(struct bss_bcn_cntdwn_tlv) +	\
+ 					 sizeof(struct bss_bcn_mbss_tlv))
+ #define MT7996_MAX_BSS_OFFLOAD_SIZE	(MT7996_MAX_BEACON_SIZE +		\
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
deleted file mode 100644
index a5b808a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
+++ /dev/null
@@ -1,237 +0,0 @@
-From 8f93c158b307ee75e622a5897499f5837c0d3446 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 12 May 2023 16:24:53 +0800
-Subject: [PATCH 08/98] wifi: mt76: mt7996: add beacon duplicate tx mode
- support
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt76_connac_mcu.h |  1 +
- mt7996/init.c     |  6 ++++--
- mt7996/mac.c      | 11 -----------
- mt7996/main.c     | 18 +++++++++---------
- mt7996/mcu.c      | 30 ++++++++++++++++++++++++++++++
- mt7996/mcu.h      | 20 ++++++++++++++++++++
- mt7996/mt7996.h   |  8 +++++---
- 7 files changed, 69 insertions(+), 25 deletions(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 99077f1..90c08d2 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1239,6 +1239,7 @@ enum {
- 	MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
- 	MCU_UNI_CMD_THERMAL = 0x35,
- 	MCU_UNI_CMD_VOW = 0x37,
-+	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
- 	MCU_UNI_CMD_RRO = 0x57,
- 	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
- 	MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 2e6efc5..17a4abd 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -354,6 +354,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
- 		IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
- 
- 	phy->slottime = 9;
-+	phy->beacon_rate = -1;
- 
- 	hw->sta_data_size = sizeof(struct mt7996_sta);
- 	hw->vif_data_size = sizeof(struct mt7996_vif);
-@@ -463,11 +464,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
- 
- 	for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
- 		u16 rate = mt76_rates[i].hw_value;
--		u16 idx = MT7996_BASIC_RATES_TBL + i;
-+		/* odd index for driver, even index for firmware */
-+		u16 idx = MT7996_BASIC_RATES_TBL + 2 * i;
- 
- 		rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |
- 		       FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));
--		mt7996_mac_set_fixed_rate_table(dev, idx, rate);
-+		mt7996_mcu_set_fixed_rate_table(&dev->phy, idx, rate, false);
- 	}
- }
- 
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 4be5410..6688186 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -248,17 +248,6 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
- 		mt76_clear(dev, addr, BIT(5));
- }
- 
--void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
--				     u8 tbl_idx, u16 rate_idx)
--{
--	u32 ctrl = MT_WTBL_ITCR_WR | MT_WTBL_ITCR_EXEC | tbl_idx;
--
--	mt76_wr(dev, MT_WTBL_ITDR0, rate_idx);
--	/* use wtbl spe idx */
--	mt76_wr(dev, MT_WTBL_ITDR1, MT_WTBL_SPE_IDX_SEL);
--	mt76_wr(dev, MT_WTBL_ITCR, ctrl);
--}
--
- /* The HW does not translate the mac header to 802.3 for mesh point */
- static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
- {
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 280120b..41f0fa1 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -522,24 +522,25 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
- 	struct mt76_phy *mphy = hw->priv;
- 	u16 rate;
--	u8 i, idx, ht;
-+	u8 i, idx;
- 
- 	rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, mcast);
--	ht = FIELD_GET(MT_TX_RATE_MODE, rate) > MT_PHY_TYPE_OFDM;
- 
--	if (beacon && ht) {
--		struct mt7996_dev *dev = mt7996_hw_dev(hw);
-+	if (beacon) {
-+		struct mt7996_phy *phy = mt7996_hw_phy(hw);
-+
-+		/* odd index for driver, even index for firmware */
-+		idx = MT7996_BEACON_RATES_TBL + 2 * phy->mt76->band_idx;
-+		if (phy->beacon_rate != rate)
-+			mt7996_mcu_set_fixed_rate_table(phy, idx, rate, beacon);
- 
--		/* must odd index */
--		idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->idx % 20);
--		mt7996_mac_set_fixed_rate_table(dev, idx, rate);
- 		return idx;
- 	}
- 
- 	idx = FIELD_GET(MT_TX_RATE_IDX, rate);
- 	for (i = 0; i < ARRAY_SIZE(mt76_rates); i++)
- 		if ((mt76_rates[i].hw_value & GENMASK(7, 0)) == idx)
--			return MT7996_BASIC_RATES_TBL + i;
-+			return MT7996_BASIC_RATES_TBL + 2 * i;
- 
- 	return mvif->basic_rates_idx;
- }
-@@ -966,7 +967,6 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
- 	mt7996_set_stream_vht_txbf_caps(phy);
- 	mt7996_set_stream_he_eht_caps(phy);
- 
--	/* TODO: update bmc_wtbl spe_idx when antenna changes */
- 	mutex_unlock(&dev->mt76.mutex);
- 
- 	return 0;
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 84f362b..dbb3ceb 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -4055,6 +4055,36 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
- 				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
- }
- 
-+int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
-+				    u16 rate_idx, bool beacon)
-+{
-+#define UNI_FIXED_RATE_TABLE_SET	0
-+#define SPE_IXD_SELECT_TXD		0
-+#define SPE_IXD_SELECT_BMC_WTBL		1
-+	struct mt7996_dev *dev = phy->dev;
-+	struct fixed_rate_table_ctrl req = {
-+		.tag = cpu_to_le16(UNI_FIXED_RATE_TABLE_SET),
-+		.len = cpu_to_le16(sizeof(req) - 4),
-+		.table_idx = table_idx,
-+		.rate_idx = cpu_to_le16(rate_idx),
-+		.gi = 1,
-+		.he_ltf = 1,
-+	};
-+	u8 band_idx = phy->mt76->band_idx;
-+
-+	if (beacon) {
-+		req.spe_idx_sel = SPE_IXD_SELECT_TXD;
-+		req.spe_idx = 24 + band_idx;
-+		phy->beacon_rate = rate_idx;
-+	} else {
-+		req.spe_idx_sel = SPE_IXD_SELECT_BMC_WTBL;
-+		req.spe_idx = 0;
-+	}
-+
-+	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(FIXED_RATE_TABLE),
-+				 &req, sizeof(req), false);
-+}
-+
- int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
- {
- 	struct {
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index f1528df..c20a947 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -738,4 +738,24 @@ enum {
- #define MT7996_SEC_KEY_IDX		GENMASK(2, 1)
- #define MT7996_SEC_IV			BIT(3)
- 
-+struct fixed_rate_table_ctrl {
-+	u8 _rsv[4];
-+
-+	__le16 tag;
-+	__le16 len;
-+
-+	u8 table_idx;
-+	u8 antenna_idx;
-+	__le16 rate_idx;
-+	u8 spe_idx_sel;
-+	u8 spe_idx;
-+	u8 gi;
-+	u8 he_ltf;
-+	bool ldpc;
-+	bool txbf;
-+	bool dynamic_bw;
-+
-+	u8 rsv[1];
-+} __packed;
-+
- #endif
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 137d5a2..21ad51d 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -47,7 +47,7 @@
- #define MT7996_MAX_QUEUE		(__MT_RXQ_MAX +	__MT_MCUQ_MAX + 3)
- 
- /* NOTE: used to map mt76_rates. idx may change if firmware expands table */
--#define MT7996_BASIC_RATES_TBL		11
-+#define MT7996_BASIC_RATES_TBL		31
- #define MT7996_BEACON_RATES_TBL		25
- 
- #define MT7996_THERMAL_THROTTLE_MAX	100
-@@ -213,6 +213,8 @@ struct mt7996_phy {
- 
- 	u8 rdd_state;
- 
-+	u16 beacon_rate;
-+
- 	u32 rx_ampdu_ts;
- 	u32 ampdu_ref;
- 
-@@ -475,6 +477,8 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
- 		       u8 rx_sel, u8 val);
- int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
- 				     struct cfg80211_chan_def *chandef);
-+int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
-+				    u16 rate_idx, bool beacon);
- int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
- int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
- int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
-@@ -539,8 +543,6 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
- void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
- void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
- 			      struct ieee80211_vif *vif, bool enable);
--void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
--				     u8 tbl_idx, u16 rate_idx);
- void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
- 			   struct sk_buff *skb, struct mt76_wcid *wcid,
- 			   struct ieee80211_key_conf *key, int pid,
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0009-mtk-wifi-mt76-mt7996-fix-HE-beamformer-phy-cap-for-s.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0009-mtk-wifi-mt76-mt7996-fix-HE-beamformer-phy-cap-for-s.patch
new file mode 100644
index 0000000..8f6f7ad
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0009-mtk-wifi-mt76-mt7996-fix-HE-beamformer-phy-cap-for-s.patch
@@ -0,0 +1,36 @@
+From cf403f86913aa78ea951d0dc11b89409f257c01b Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Thu, 23 Nov 2023 20:06:26 +0800
+Subject: [PATCH 09/23] mtk: wifi: mt76: mt7996: fix HE beamformer phy cap for
+ station vif
+
+Without this commit, station mode will not set all needed bit in HE Phy
+capabilities IE as 1.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt7996/init.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 1a9aa48c..50dcce9f 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -1011,11 +1011,12 @@ mt7996_set_stream_he_txbf_caps(struct mt7996_phy *phy,
+ 	/* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */
+ 	elem->phy_cap_info[7] |= min_t(int, sts - 1, 2) << 3;
+ 
+-	if (vif != NL80211_IFTYPE_AP)
++	if (!(vif == NL80211_IFTYPE_AP || vif == NL80211_IFTYPE_STATION))
+ 		return;
+ 
+ 	elem->phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
+-	elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
++	if (vif == NL80211_IFTYPE_AP)
++		elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
+ 
+ 	c = FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
+ 		       sts - 1) |
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
deleted file mode 100644
index b151c94..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 3e4d68091c7b74769481acdf1b305fd1edb15d4d Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Tue, 30 May 2023 11:27:01 +0800
-Subject: [PATCH 09/98] wifi: mt76: mt7996: fix bss rate tlv to sync firmware
- change
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- mt7996/mcu.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index c20a947..78ecd75 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -259,7 +259,7 @@ struct bss_rate_tlv {
- 	u8 short_preamble;
- 	u8 bc_fixed_rate;
- 	u8 mc_fixed_rate;
--	u8 __rsv2[1];
-+	u8 __rsv2[9];
- } __packed;
- 
- struct bss_ra_tlv {
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0010-mtk-wifi-mt76-mt7996-Let-MAC80211-handles-GCMP-IGTK.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0010-mtk-wifi-mt76-mt7996-Let-MAC80211-handles-GCMP-IGTK.patch
new file mode 100644
index 0000000..96ee97d
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0010-mtk-wifi-mt76-mt7996-Let-MAC80211-handles-GCMP-IGTK.patch
@@ -0,0 +1,34 @@
+From e154e95bd733a456c5551ae89ef5673d57941b2a Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Fri, 8 Dec 2023 16:23:37 +0800
+Subject: [PATCH 10/23] mtk: wifi: mt76: mt7996: Let MAC80211 handles GCMP IGTK
+
+Because the FW does not support IGTK in GCMP mode, mt76 returns "not
+support" to mac80211, and mac80211 will handle the integrity calculation
+and validation.
+
+---
+ mt7996/main.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/mt7996/main.c b/mt7996/main.c
+index be914ced..6e88420e 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -350,9 +350,12 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ 	case WLAN_CIPHER_SUITE_GCMP:
+ 	case WLAN_CIPHER_SUITE_GCMP_256:
+ 	case WLAN_CIPHER_SUITE_SMS4:
++		break;
+ 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-		break;
++		if (key->keyidx == 6 || key->keyidx == 7)
++			break;
++		fallthrough;
+ 	case WLAN_CIPHER_SUITE_WEP40:
+ 	case WLAN_CIPHER_SUITE_WEP104:
+ 	default:
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
deleted file mode 100644
index ca966b6..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-From e1ddb78f4185559bc6f9be1d1b302f9f52899f94 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Tue, 13 Jun 2023 09:04:43 +0800
-Subject: [PATCH 10/98] wifi: mt76: mt7996: adjust wfdma setting to enhance
- throughput
-
-1. Set band 1 traffic to pcie1.
-2. Refactor dma prefetch and enlarge txd prefetch size.
-3. Update pdma setting.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt7996/dma.c  | 70 +++++++++++++++++++++++++++++++++++----------------
- mt7996/regs.h |  9 +++++++
- 2 files changed, 58 insertions(+), 21 deletions(-)
-
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 3d04470..1ed91da 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -99,38 +99,49 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
- 	MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA0, MT_INT_TX_DONE_FWDL, MT7996_TXQ_FWDL);
- }
- 
-+static u32 __mt7996_dma_prefetch_base(u16 *base, u8 depth)
-+{
-+	u32 ret = *base << 16 | depth;
-+
-+	*base = *base + (depth << 4);
-+
-+	return ret;
-+}
-+
- static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
- {
--#define PREFETCH(_base, _depth)	((_base) << 16 | (_depth))
-+	u16 base = 0;
-+
-+#define PREFETCH(_depth)	(__mt7996_dma_prefetch_base(&base, (_depth)))
- 	/* prefetch SRAM wrapping boundary for tx/rx ring. */
--	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_FWDL) + ofs, PREFETCH(0x0, 0x2));
--	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WM) + ofs, PREFETCH(0x20, 0x2));
--	mt76_wr(dev, MT_TXQ_EXT_CTRL(0) + ofs, PREFETCH(0x40, 0x4));
--	mt76_wr(dev, MT_TXQ_EXT_CTRL(1) + ofs, PREFETCH(0x80, 0x4));
--	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, PREFETCH(0xc0, 0x2));
--	mt76_wr(dev, MT_TXQ_EXT_CTRL(2) + ofs, PREFETCH(0xe0, 0x4));
--	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, PREFETCH(0x120, 0x2));
--	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, PREFETCH(0x140, 0x2));
--	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, PREFETCH(0x160, 0x2));
--	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x180, 0x2));
--	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x1a0, 0x10));
--	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x2a0, 0x10));
-+	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_FWDL) + ofs, PREFETCH(0x2));
-+	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WM) + ofs, PREFETCH(0x2));
-+	mt76_wr(dev, MT_TXQ_EXT_CTRL(0) + ofs, PREFETCH(0x8));
-+	mt76_wr(dev, MT_TXQ_EXT_CTRL(1) + ofs, PREFETCH(0x8));
-+	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, PREFETCH(0x2));
-+	mt76_wr(dev, MT_TXQ_EXT_CTRL(2) + ofs, PREFETCH(0x8));
-+	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, PREFETCH(0x2));
-+	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, PREFETCH(0x2));
-+	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, PREFETCH(0x2));
-+	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x2));
-+	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x10));
-+	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x10));
- 
- 	if (dev->has_rro) {
- 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
--			PREFETCH(0x3a0, 0x10));
-+			PREFETCH(0x10));
- 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
--			PREFETCH(0x4a0, 0x10));
-+			PREFETCH(0x10));
- 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND0) + ofs,
--			PREFETCH(0x5a0, 0x4));
-+			PREFETCH(0x4));
- 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND1) + ofs,
--			PREFETCH(0x5e0, 0x4));
-+			PREFETCH(0x4));
- 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND2) + ofs,
--			PREFETCH(0x620, 0x4));
-+			PREFETCH(0x4));
- 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND0) + ofs,
--			PREFETCH(0x660, 0x4));
-+			PREFETCH(0x4));
- 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
--			PREFETCH(0x6a0, 0x4));
-+			PREFETCH(0x4));
- 	}
- #undef PREFETCH
- 
-@@ -295,6 +306,12 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
- 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1,
- 		 WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
- 
-+	/* WFDMA rx threshold */
-+	mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_45_TH, 0xc000c);
-+	mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_67_TH, 0x10008);
-+	mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_89_TH, 0x10008);
-+	mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_RRO_TH, 0x20);
-+
- 	if (dev->hif2) {
- 		/* GLO_CFG_EXT0 */
- 		mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
-@@ -306,7 +323,18 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
- 			 WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
- 
- 		mt76_set(dev, MT_WFDMA_HOST_CONFIG,
--			 MT_WFDMA_HOST_CONFIG_PDMA_BAND);
-+			 MT_WFDMA_HOST_CONFIG_PDMA_BAND |
-+			 MT_WFDMA_HOST_CONFIG_BAND2_PCIE1);
-+
-+		/* AXI read outstanding number */
-+		mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL,
-+			 MT_WFDMA_AXI_R2A_CTRL_OUTSTAND_MASK, 0x14);
-+
-+		/* WFDMA rx threshold */
-+		mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_45_TH + hif1_ofs, 0xc000c);
-+		mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_67_TH + hif1_ofs, 0x10008);
-+		mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_89_TH + hif1_ofs, 0x10008);
-+		mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_RRO_TH + hif1_ofs, 0x20);
- 	}
- 
- 	if (dev->hif2) {
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index a4d5ad8..f7c99cd 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -366,6 +366,11 @@ enum base_rev {
- #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO		BIT(27)
- #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2	BIT(21)
- 
-+#define MT_WFDMA0_PAUSE_RX_Q_45_TH		MT_WFDMA0(0x268)
-+#define MT_WFDMA0_PAUSE_RX_Q_67_TH		MT_WFDMA0(0x26c)
-+#define MT_WFDMA0_PAUSE_RX_Q_89_TH		MT_WFDMA0(0x270)
-+#define MT_WFDMA0_PAUSE_RX_Q_RRO_TH		MT_WFDMA0(0x27c)
-+
- #define WF_WFDMA0_GLO_CFG_EXT0			MT_WFDMA0(0x2b0)
- #define WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD	BIT(18)
- #define WF_WFDMA0_GLO_CFG_EXT0_WED_MERGE_MODE	BIT(14)
-@@ -388,10 +393,14 @@ enum base_rev {
- 
- #define MT_WFDMA_HOST_CONFIG			MT_WFDMA_EXT_CSR(0x30)
- #define MT_WFDMA_HOST_CONFIG_PDMA_BAND		BIT(0)
-+#define MT_WFDMA_HOST_CONFIG_BAND2_PCIE1	BIT(22)
- 
- #define MT_WFDMA_EXT_CSR_HIF_MISC		MT_WFDMA_EXT_CSR(0x44)
- #define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY		BIT(0)
- 
-+#define MT_WFDMA_AXI_R2A_CTRL			MT_WFDMA_EXT_CSR(0x500)
-+#define MT_WFDMA_AXI_R2A_CTRL_OUTSTAND_MASK	GENMASK(4, 0)
-+
- #define MT_PCIE_RECOG_ID			0xd7090
- #define MT_PCIE_RECOG_ID_MASK			GENMASK(30, 0)
- #define MT_PCIE_RECOG_ID_SEM			BIT(31)
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0011-mtk-wifi-mt76-mt7996-fix-efuse-read-issue.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0011-mtk-wifi-mt76-mt7996-fix-efuse-read-issue.patch
new file mode 100644
index 0000000..b24231f
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0011-mtk-wifi-mt76-mt7996-fix-efuse-read-issue.patch
@@ -0,0 +1,30 @@
+From 68cbc6f4aa32410876f18d54f053b4f928b4b981 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 29 Nov 2023 10:55:15 +0800
+Subject: [PATCH 11/23] mtk: wifi: mt76: mt7996: fix efuse read issue
+
+The efuse data starts at 48 bytes instead of 64 bytes in the returned
+skb.
+This patch should be upstreamed.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/mcu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 071a9ec2..98ea9c20 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3561,7 +3561,7 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset)
+ 		u32 addr = le32_to_cpu(*(__le32 *)(skb->data + 12));
+ 		u8 *buf = (u8 *)dev->mt76.eeprom.data + addr;
+ 
+-		skb_pull(skb, 64);
++		skb_pull(skb, 48);
+ 		memcpy(buf, skb->data, MT7996_EEPROM_BLOCK_SIZE);
+ 	}
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch
deleted file mode 100644
index d32dea5..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From bae9e0c386cd710bdf414b0e0e097ea95812673e Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Wed, 6 Sep 2023 14:51:00 +0800
-Subject: [PATCH 11/98] wifi: mt76: mt7996: fill txd bandwidth filed value for
- fixed rate frame
-
-Fill bw field value for fixed rate enabled frame to keep it be sent by bw20.
-Without this change, the bw of fixed rate enabled frame will be decided
-by hardware.
-
-Reported-by: Chank Chen <chank.chen@mediatek.com>
-Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
----
- mt76_connac3_mac.h | 1 +
- mt7996/mac.c       | 3 ++-
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
-index 87bfa44..df6b02a 100644
---- a/mt76_connac3_mac.h
-+++ b/mt76_connac3_mac.h
-@@ -239,6 +239,7 @@ enum tx_mgnt_type {
- 
- #define MT_TXD6_TX_SRC			GENMASK(31, 30)
- #define MT_TXD6_VTA			BIT(28)
-+#define MT_TXD6_FIXED_BW		BIT(25)
- #define MT_TXD6_BW			GENMASK(25, 22)
- #define MT_TXD6_TX_RATE			GENMASK(21, 16)
- #define MT_TXD6_TIMESTAMP_OFS_EN	BIT(15)
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 6688186..2c6bee4 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -943,7 +943,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
- 				idx = mvif->basic_rates_idx;
- 		}
- 
--		txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE, idx));
-+		val = FIELD_PREP(MT_TXD6_TX_RATE, idx) | MT_TXD6_FIXED_BW;
-+		txwi[6] |= cpu_to_le32(val);
- 		txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
- 	}
- }
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0012-mtk-wifi-mt76-mt7996-enable-ser-query.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0012-mtk-wifi-mt76-mt7996-enable-ser-query.patch
new file mode 100644
index 0000000..2ca9151
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0012-mtk-wifi-mt76-mt7996-enable-ser-query.patch
@@ -0,0 +1,29 @@
+From ca4d4dc688f96320065b35c9b473e378dddef56b Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Mon, 30 Oct 2023 20:19:41 +0800
+Subject: [PATCH 12/23] mtk: wifi: mt76: mt7996: enable ser query
+
+Do not return -EINVAL when action is UNI_CMD_SER_QUERY for user
+to dump SER information from FW.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt7996/mcu.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 98ea9c20..8c756b31 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3852,6 +3852,8 @@ int mt7996_mcu_set_ser(struct mt7996_dev *dev, u8 action, u8 val, u8 band)
+ 	};
+ 
+ 	switch (action) {
++	case UNI_CMD_SER_QUERY:
++		break;
+ 	case UNI_CMD_SER_SET:
+ 		req.set.mask = cpu_to_le32(val);
+ 		break;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0012-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0012-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch
deleted file mode 100644
index 3a49f34..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0012-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 2d7f3506aa6759fa1a7667d53bf88eb543035c33 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Mon, 24 Jul 2023 16:32:03 +0800
-Subject: [PATCH 12/98] wifi: mt76: mt7996: add IEEE80211_RC_SMPS_CHANGED
- handler
-
-Send mcu command to firmware to handle smps mode.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt7996/mac.c    | 4 +++-
- mt7996/mcu.c    | 8 +++++---
- mt7996/mt7996.h | 2 ++
- 3 files changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 2c6bee4..ccb7b22 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -2222,7 +2222,9 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
- 			       IEEE80211_RC_BW_CHANGED))
- 			mt7996_mcu_add_rate_ctrl(dev, vif, sta, true);
- 
--		/* TODO: smps change */
-+		if (changed & IEEE80211_RC_SMPS_CHANGED)
-+			mt7996_mcu_set_fixed_field(dev, vif, sta, NULL,
-+						   RATE_PARAM_MMPS_UPDATE);
- 
- 		spin_lock_bh(&dev->mt76.sta_poll_lock);
- 	}
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index dbb3ceb..18c3f34 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -1679,9 +1679,8 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
- 				     MCU_WM_UNI_CMD(RA), true);
- }
- 
--static int
--mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
--			   struct ieee80211_sta *sta, void *data, u32 field)
-+int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-+			       struct ieee80211_sta *sta, void *data, u32 field)
- {
- 	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
- 	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
-@@ -1709,6 +1708,9 @@ mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- 		if (phy)
- 			ra->phy = *phy;
- 		break;
-+	case RATE_PARAM_MMPS_UPDATE:
-+		ra->mmps_mode = mt7996_mcu_get_mmps_mode(sta->deflink.smps_mode);
-+		break;
- 	default:
- 		break;
- 	}
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 21ad51d..c8e7a33 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -451,6 +451,8 @@ int mt7996_mcu_add_obss_spr(struct mt7996_phy *phy, struct ieee80211_vif *vif,
- int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- 			     struct ieee80211_sta *sta, bool changed);
- int mt7996_set_channel(struct mt7996_phy *phy);
-+int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-+			       struct ieee80211_sta *sta, void *data, u32 field);
- int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag);
- int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif);
- int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0013-mtk-wifi-mt76-mt7996-init-rcpi-to-use-better-init-mc.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0013-mtk-wifi-mt76-mt7996-init-rcpi-to-use-better-init-mc.patch
new file mode 100644
index 0000000..8eded5f
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0013-mtk-wifi-mt76-mt7996-init-rcpi-to-use-better-init-mc.patch
@@ -0,0 +1,35 @@
+From c59e5d1ee99fbe46418efb2eacb6755db54b8e57 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Mon, 13 Nov 2023 20:15:39 +0800
+Subject: [PATCH 13/23] mtk: wifi: mt76: mt7996: init rcpi to use better init
+ mcs
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt7996/mcu.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 8c756b31..48a1e822 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -1981,6 +1981,7 @@ static void
+ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
+ 			     struct ieee80211_vif *vif, struct ieee80211_sta *sta)
+ {
++#define INIT_RCPI 180
+ 	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ 	struct mt76_phy *mphy = mvif->phy->mt76;
+ 	struct cfg80211_chan_def *chandef = &mphy->chandef;
+@@ -2078,6 +2079,8 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
+ 					       IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
+ 	}
+ 	ra->sta_cap = cpu_to_le32(cap);
++
++	memset(ra->rx_rcpi, INIT_RCPI, sizeof(ra->rx_rcpi));
+ }
+ 
+ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0013-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0013-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch
deleted file mode 100644
index 5f85886..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0013-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch
+++ /dev/null
@@ -1,154 +0,0 @@
-From 8c79e229decdc24af9e95e6396699b3723f7efc4 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Fri, 7 Jul 2023 10:35:05 +0800
-Subject: [PATCH 13/98] wifi: mt76: mt7996: fix mcu command format to align
- firmware
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt7996/mcu.c | 12 ++++-----
- mt7996/mcu.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 75 insertions(+), 8 deletions(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 18c3f34..ee1915c 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -1684,8 +1684,8 @@ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif
- {
- 	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
- 	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
--	struct sta_phy *phy = data;
--	struct sta_rec_ra_fixed *ra;
-+	struct sta_phy_uni *phy = data;
-+	struct sta_rec_ra_fixed_uni *ra;
- 	struct sk_buff *skb;
- 	struct tlv *tlv;
- 
-@@ -1696,7 +1696,7 @@ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif
- 		return PTR_ERR(skb);
- 
- 	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
--	ra = (struct sta_rec_ra_fixed *)tlv;
-+	ra = (struct sta_rec_ra_fixed_uni *)tlv;
- 
- 	switch (field) {
- 	case RATE_PARAM_AUTO:
-@@ -1728,7 +1728,7 @@ mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev, struct ieee80211_vif *vif
- 	struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
- 	struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
- 	enum nl80211_band band = chandef->chan->band;
--	struct sta_phy phy = {};
-+	struct sta_phy_uni phy = {};
- 	int ret, nrates = 0;
- 
- #define __sta_phy_bitrate_mask_check(_mcs, _gi, _ht, _he)			\
-@@ -1816,13 +1816,13 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
- 	struct cfg80211_chan_def *chandef = &mphy->chandef;
- 	struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
- 	enum nl80211_band band = chandef->chan->band;
--	struct sta_rec_ra *ra;
-+	struct sta_rec_ra_uni *ra;
- 	struct tlv *tlv;
- 	u32 supp_rate = sta->deflink.supp_rates[band];
- 	u32 cap = sta->wme ? STA_CAP_WMM : 0;
- 
- 	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra));
--	ra = (struct sta_rec_ra *)tlv;
-+	ra = (struct sta_rec_ra_uni *)tlv;
- 
- 	ra->valid = true;
- 	ra->auto_rate = true;
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 78ecd75..05785cb 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -433,6 +433,73 @@ struct sta_rec_sec_uni {
- 	struct sec_key_uni key[2];
- } __packed;
- 
-+struct sta_phy_uni {
-+	u8 type;
-+	u8 flag;
-+	u8 stbc;
-+	u8 sgi;
-+	u8 bw;
-+	u8 ldpc;
-+	u8 mcs;
-+	u8 nss;
-+	u8 he_ltf;
-+	u8 rsv[3];
-+};
-+
-+struct sta_rec_ra_uni {
-+	__le16 tag;
-+	__le16 len;
-+
-+	u8 valid;
-+	u8 auto_rate;
-+	u8 phy_mode;
-+	u8 channel;
-+	u8 bw;
-+	u8 disable_cck;
-+	u8 ht_mcs32;
-+	u8 ht_gf;
-+	u8 ht_mcs[4];
-+	u8 mmps_mode;
-+	u8 gband_256;
-+	u8 af;
-+	u8 auth_wapi_mode;
-+	u8 rate_len;
-+
-+	u8 supp_mode;
-+	u8 supp_cck_rate;
-+	u8 supp_ofdm_rate;
-+	__le32 supp_ht_mcs;
-+	__le16 supp_vht_mcs[4];
-+
-+	u8 op_mode;
-+	u8 op_vht_chan_width;
-+	u8 op_vht_rx_nss;
-+	u8 op_vht_rx_nss_type;
-+
-+	__le32 sta_cap;
-+
-+	struct sta_phy_uni phy;
-+	u8 rx_rcpi[4];
-+} __packed;
-+
-+struct sta_rec_ra_fixed_uni {
-+	__le16 tag;
-+	__le16 len;
-+
-+	__le32 field;
-+	u8 op_mode;
-+	u8 op_vht_chan_width;
-+	u8 op_vht_rx_nss;
-+	u8 op_vht_rx_nss_type;
-+
-+	struct sta_phy_uni phy;
-+
-+	u8 spe_idx;
-+	u8 short_preamble;
-+	u8 is_5g;
-+	u8 mmps_mode;
-+} __packed;
-+
- struct sta_rec_hdrt {
- 	__le16 tag;
- 	__le16 len;
-@@ -616,9 +683,9 @@ enum {
- 					 sizeof(struct sta_rec_amsdu) +		\
- 					 sizeof(struct sta_rec_bfee) +		\
- 					 sizeof(struct sta_rec_phy) +		\
--					 sizeof(struct sta_rec_ra) +		\
-+					 sizeof(struct sta_rec_ra_uni) +	\
- 					 sizeof(struct sta_rec_sec) +		\
--					 sizeof(struct sta_rec_ra_fixed) +	\
-+					 sizeof(struct sta_rec_ra_fixed_uni) +	\
- 					 sizeof(struct sta_rec_he_6g_capa) +	\
- 					 sizeof(struct sta_rec_eht) +		\
- 					 sizeof(struct sta_rec_hdrt) +		\
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0014-mtk-wifi-mt76-mt7996-Fix-TGax-HE-4.51.1_24G-fail.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0014-mtk-wifi-mt76-mt7996-Fix-TGax-HE-4.51.1_24G-fail.patch
new file mode 100644
index 0000000..5d24464
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0014-mtk-wifi-mt76-mt7996-Fix-TGax-HE-4.51.1_24G-fail.patch
@@ -0,0 +1,34 @@
+From 73aed7092e7da26eaf17b1e29bdb94222e073e94 Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Fri, 17 Nov 2023 11:01:04 +0800
+Subject: [PATCH 14/23] mtk: wifi: mt76: mt7996: Fix TGax HE-4.51.1_24G fail
+
+According to sta capability to decide to enable/disable wed pao when create ppe entry.
+without this patch, TGax HE-4.51.1_24G will test fail
+
+Signed-off-by: mtk27745 <rex.lu@mediatek.com>
+---
+ mt7996/main.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 6e88420e..4db8899c 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1447,7 +1447,12 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
+ 	path->mtk_wdma.queue = 0;
+ 	path->mtk_wdma.wcid = msta->wcid.idx;
+ 
+-	path->mtk_wdma.amsdu = mtk_wed_is_amsdu_supported(wed);
++	if (ieee80211_hw_check(hw, SUPPORTS_AMSDU_IN_AMPDU) &&
++	    mtk_wed_is_amsdu_supported(wed))
++		path->mtk_wdma.amsdu = msta->wcid.amsdu;
++	else
++		path->mtk_wdma.amsdu = 0;
++
+ 	ctx->dev = NULL;
+ 
+ 	return 0;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0015-mtk-wifi-mt76-mt7996-add-eagle-default-bin-of-differ.patch
similarity index 62%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0015-mtk-wifi-mt76-mt7996-add-eagle-default-bin-of-differ.patch
index dbef00c..b7decbf 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0015-mtk-wifi-mt76-mt7996-add-eagle-default-bin-of-differ.patch
@@ -1,8 +1,8 @@
-From 10df4848e7a7116529e1f596e06d0d03891f502e Mon Sep 17 00:00:00 2001
+From 776233df7a3216546d93bdaf6160390736452f2a Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 20 Jul 2023 17:27:22 +0800
-Subject: [PATCH 37/98] wifi: mt76: mt7996: add eagle default bin of different
- sku variants
+Subject: [PATCH 15/23] mtk: wifi: mt76: mt7996: add eagle default bin of
+ different sku variants
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,46 +12,46 @@
  3 files changed, 32 insertions(+), 2 deletions(-)
 
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 7fd318c..3276740 100644
+index 4a823711..7505a8b7 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -30,6 +30,8 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
- 	/* reserve for future variants */
- 	if (dev->testmode_enable)
- 		return MT7996_EEPROM_DEFAULT_TM;
-+	else if (dev->chip_sku == MT7996_SKU_404)
-+		return MT7996_EEPROM_DEFAULT_404;
- 	else
+@@ -26,6 +26,8 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ {
+ 	switch (mt76_chip(&dev->mt76)) {
+ 	case 0x7990:
++		if (dev->chip_sku == MT7996_SKU_404)
++			return MT7996_EEPROM_DEFAULT_404;
  		return MT7996_EEPROM_DEFAULT;
- }
+ 	case 0x7992:
+ 		return MT7992_EEPROM_DEFAULT;
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 6d39c3c..fed74d0 100644
+index 50dcce9f..d8946a86 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -789,6 +789,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
- 
- 	INIT_WORK(&dev->init_work, mt7996_init_work);
+@@ -902,6 +902,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+ 	INIT_LIST_HEAD(&dev->wed_rro.poll_list);
+ 	spin_lock_init(&dev->wed_rro.lock);
  
 +	ret = mt7996_get_chip_sku(dev);
 +	if (ret)
 +		return ret;
 +
- 	dev->dbdc_support = mt7996_band_valid(dev, MT_BAND1) ||
- 			    mt7996_band_valid(dev, MT_BAND2);
- 	dev->tbtc_support = mt7996_band_valid(dev, MT_BAND1) &&
+ 	ret = mt7996_dma_init(dev);
+ 	if (ret)
+ 		return ret;
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 3964035..efdcff7 100644
+index 8154ad37..eab96139 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -36,6 +36,7 @@
- #define MT7996_ROM_PATCH		"mediatek/mt7996/mt7996_rom_patch.bin"
+@@ -40,6 +40,7 @@
+ #define MT7992_ROM_PATCH		"mediatek/mt7996/mt7992_rom_patch.bin"
  
  #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
 +#define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
- #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
+ #define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom.bin"
  #define MT7996_EEPROM_SIZE		7680
  #define MT7996_EEPROM_BLOCK_SIZE	16
-@@ -83,6 +84,11 @@ struct mt7996_sta;
+@@ -88,6 +89,11 @@ struct mt7996_sta;
  struct mt7996_dfs_pulse;
  struct mt7996_dfs_pattern;
  
@@ -62,8 +62,8 @@
 +
  enum mt7996_ram_type {
  	MT7996_RAM_TYPE_WM,
- 	MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
-@@ -264,6 +270,8 @@ struct mt7996_dev {
+ 	MT7996_RAM_TYPE_WA,
+@@ -257,6 +263,8 @@ struct mt7996_dev {
  	struct cfg80211_chan_def rdd2_chandef;
  	struct mt7996_phy *rdd2_phy;
  
@@ -72,7 +72,7 @@
  	u16 chainmask;
  	u8 chainshift[__MT_MAX_BAND];
  	u32 hif_idx;
-@@ -417,6 +425,23 @@ mt7996_phy3(struct mt7996_dev *dev)
+@@ -399,6 +407,23 @@ mt7996_phy3(struct mt7996_dev *dev)
  	return __mt7996_phy(dev, MT_BAND2);
  }
  
@@ -96,7 +96,7 @@
  static inline bool
  mt7996_band_valid(struct mt7996_dev *dev, u8 band)
  {
-@@ -424,8 +449,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
+@@ -406,8 +431,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
  		return band <= MT_BAND1;
  
  	/* tri-band support */
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0016-mtk-wifi-mt76-mt7996-add-kite-fw-default-bin-for-dif.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0016-mtk-wifi-mt76-mt7996-add-kite-fw-default-bin-for-dif.patch
new file mode 100644
index 0000000..7c38f4b
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0016-mtk-wifi-mt76-mt7996-add-kite-fw-default-bin-for-dif.patch
@@ -0,0 +1,308 @@
+From dac8a0fc54f9b171dbb57e7559db7c5245e52bbf Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 21 Jul 2023 10:41:28 +0800
+Subject: [PATCH 16/23] mtk: wifi: mt76: mt7996: add kite fw & default bin for
+ different sku variants
+
+Add fem type (2i5i, 2i5e, 2e5e, ...)
+Add Kite default bin for each fem type since loading wrong default bin
+will fail to setup interface
+Add eeprom fem type check
+
+Add adie 7976c efuse check
+Efuse offset 0x470 will be set to 0xc after final test if 7976c adie is used
+Chip manufactoring factories may transfer, which leads to different adie chip versions,
+so we add this efuse check to avoid 7976c recognition failure.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c | 35 +++++++++++++++++++++++++++--
+ mt7996/eeprom.h |  1 +
+ mt7996/init.c   | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.c    |  7 +++++-
+ mt7996/mt7996.h | 49 ++++++++++++++++++++++++++---------------
+ mt7996/regs.h   |  7 ++++++
+ 6 files changed, 136 insertions(+), 21 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 7505a8b7..c8fa87ef 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -9,14 +9,30 @@
+ 
+ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+ {
++#define FEM_INT				0
++#define FEM_EXT				3
+ 	u8 *eeprom = dev->mt76.eeprom.data;
++	u8 i, fem[__MT_MAX_BAND], fem_type;
+ 	u16 val = get_unaligned_le16(eeprom);
+ 
++	for (i = 0; i < __MT_MAX_BAND; i++)
++		fem[i] = eeprom[MT_EE_WIFI_CONF + 6 + i] & MT_EE_WIFI_PA_LNA_CONFIG;
++
+ 	switch (val) {
+ 	case 0x7990:
+ 		return is_mt7996(&dev->mt76) ? 0 : -EINVAL;
+ 	case 0x7992:
+-		return is_mt7992(&dev->mt76) ? 0 : -EINVAL;
++		if (fem[0] == FEM_EXT && fem[1] == FEM_EXT)
++			fem_type = MT7996_FEM_EXT;
++		else if (fem[0] == FEM_INT && fem[1] == FEM_INT)
++			fem_type = MT7996_FEM_INT;
++		else if (fem[0] == FEM_INT && fem[1] == FEM_EXT)
++			fem_type = MT7996_FEM_MIX;
++		else
++			return -EINVAL;
++
++		return (is_mt7992(&dev->mt76) ? 0 : -EINVAL) |
++		       (dev->fem_type == fem_type ? 0 : -EINVAL);
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -30,7 +46,18 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ 			return MT7996_EEPROM_DEFAULT_404;
+ 		return MT7996_EEPROM_DEFAULT;
+ 	case 0x7992:
+-		return MT7992_EEPROM_DEFAULT;
++		if (dev->chip_sku == MT7992_SKU_23) {
++			if (dev->fem_type == MT7996_FEM_INT)
++				return MT7992_EEPROM_DEFAULT_23;
++			return MT7992_EEPROM_DEFAULT_23_EXT;
++		} else if (dev->chip_sku == MT7992_SKU_44) {
++			if (dev->fem_type == MT7996_FEM_INT)
++				return MT7992_EEPROM_DEFAULT;
++			else if (dev->fem_type == MT7996_FEM_MIX)
++				return MT7992_EEPROM_DEFAULT_MIX;
++			return MT7992_EEPROM_DEFAULT_EXT;
++		}
++		return MT7992_EEPROM_DEFAULT_24;
+ 	default:
+ 		return MT7996_EEPROM_DEFAULT;
+ 	}
+@@ -221,6 +248,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+ {
+ 	int ret;
+ 
++	ret = mt7996_get_chip_sku(dev);
++	if (ret)
++		return ret;
++
+ 	ret = mt7996_eeprom_load(dev);
+ 	if (ret < 0) {
+ 		if (ret != -EINVAL)
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 412d6e2f..72c38ad3 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -29,6 +29,7 @@ enum mt7996_eeprom_field {
+ #define MT_EE_WIFI_CONF0_BAND_SEL		GENMASK(2, 0)
+ #define MT_EE_WIFI_CONF1_BAND_SEL		GENMASK(5, 3)
+ #define MT_EE_WIFI_CONF2_BAND_SEL		GENMASK(2, 0)
++#define MT_EE_WIFI_PA_LNA_CONFIG		GENMASK(1, 0)
+ 
+ #define MT_EE_WIFI_CONF1_TX_PATH_BAND0		GENMASK(5, 3)
+ #define MT_EE_WIFI_CONF2_TX_PATH_BAND1		GENMASK(2, 0)
+diff --git a/mt7996/init.c b/mt7996/init.c
+index d8946a86..dae640e9 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -887,6 +887,64 @@ out:
+ #endif
+ }
+ 
++int mt7996_get_chip_sku(struct mt7996_dev *dev)
++{
++#define MT7976C_CHIP_VER	0x8a10
++#define MT7976C_HL_CHIP_VER	0x8b00
++#define MT7976C_PS_CHIP_VER	0x8c10
++#define MT7976C_EFUSE_OFFSET	0x470
++#define MT7976C_EFUSE_VALUE	0xc
++	u32 regval, val = mt76_rr(dev, MT_PAD_GPIO);
++	u16 adie_chip_id, adie_chip_ver;
++	u8 adie_comb, adie_num, adie_idx = 0;
++
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7990:
++		adie_comb = FIELD_GET(MT_PAD_GPIO_ADIE_COMB, val);
++		if (adie_comb <= 1)
++			dev->chip_sku = MT7996_SKU_444;
++		else
++			dev->chip_sku = MT7996_SKU_404;
++		break;
++	case 0x7992:
++		adie_comb = FIELD_GET(MT_PAD_GPIO_ADIE_COMB_7992, val);
++		adie_num = FIELD_GET(MT_PAD_GPIO_ADIE_NUM_7992, val);
++		adie_idx = !!adie_comb;
++		if (adie_comb)
++			dev->chip_sku = MT7992_SKU_44;
++		else if (adie_num)
++			dev->chip_sku = MT7992_SKU_23;
++		else
++			dev->chip_sku = MT7992_SKU_24;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) {
++		u8 buf[MT7996_EEPROM_BLOCK_SIZE];
++		u8 idx = MT7976C_EFUSE_OFFSET % MT7996_EEPROM_BLOCK_SIZE;
++		bool is_7976c;
++
++		mt7996_mcu_rf_regval(dev, MT_ADIE_CHIP_ID(adie_idx), &regval, false);
++		adie_chip_id = FIELD_GET(MT_ADIE_CHIP_ID_MASK, regval);
++		adie_chip_ver = FIELD_GET(MT_ADIE_VERSION_MASK, regval);
++		mt7996_mcu_get_eeprom(dev, MT7976C_EFUSE_OFFSET, buf);
++		is_7976c = (adie_chip_ver == MT7976C_CHIP_VER) ||
++			   (adie_chip_ver == MT7976C_HL_CHIP_VER) ||
++			   (adie_chip_ver == MT7976C_PS_CHIP_VER) ||
++			   (buf[idx] == MT7976C_EFUSE_VALUE);
++		if (adie_chip_id == 0x7975 || (adie_chip_id == 0x7976 && is_7976c))
++			dev->fem_type = MT7996_FEM_INT;
++		else if (adie_chip_id == 0x7977 && adie_comb == 1)
++			dev->fem_type = MT7996_FEM_MIX;
++		else
++			dev->fem_type = MT7996_FEM_EXT;
++	}
++
++	return 0;
++}
++
+ static int mt7996_init_hardware(struct mt7996_dev *dev)
+ {
+ 	int ret, idx;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 48a1e822..8a3b9f81 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -14,7 +14,12 @@
+ 	char *_fw;						\
+ 	switch (mt76_chip(&(_dev)->mt76)) {			\
+ 	case 0x7992:						\
+-		_fw = MT7992_##name;				\
++		if ((_dev)->chip_sku == MT7992_SKU_23)		\
++			_fw = MT7992_##name##_23;		\
++		else if ((_dev)->chip_sku == MT7992_SKU_24)	\
++			_fw = MT7992_##name##_24;		\
++		else						\
++			_fw = MT7992_##name;			\
+ 		break;						\
+ 	case 0x7990:						\
+ 	default:						\
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index eab96139..c34cb76b 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -39,9 +39,24 @@
+ #define MT7992_FIRMWARE_DSP		"mediatek/mt7996/mt7992_dsp.bin"
+ #define MT7992_ROM_PATCH		"mediatek/mt7996/mt7992_rom_patch.bin"
+ 
++#define MT7992_FIRMWARE_WA_24		"mediatek/mt7996/mt7992_wa_24.bin"
++#define MT7992_FIRMWARE_WM_24		"mediatek/mt7996/mt7992_wm_24.bin"
++#define MT7992_FIRMWARE_DSP_24		"mediatek/mt7996/mt7992_dsp_24.bin"
++#define MT7992_ROM_PATCH_24		"mediatek/mt7996/mt7992_rom_patch_24.bin"
++
++#define MT7992_FIRMWARE_WA_23		"mediatek/mt7996/mt7992_wa_23.bin"
++#define MT7992_FIRMWARE_WM_23		"mediatek/mt7996/mt7992_wm_23.bin"
++#define MT7992_FIRMWARE_DSP_23		"mediatek/mt7996/mt7992_dsp_23.bin"
++#define MT7992_ROM_PATCH_23		"mediatek/mt7996/mt7992_rom_patch_23.bin"
++
+ #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
+ #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
+-#define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom.bin"
++#define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom_2i5i.bin"
++#define MT7992_EEPROM_DEFAULT_EXT	"mediatek/mt7996/mt7992_eeprom_2e5e.bin"
++#define MT7992_EEPROM_DEFAULT_MIX	"mediatek/mt7996/mt7992_eeprom_2i5e.bin"
++#define MT7992_EEPROM_DEFAULT_24	"mediatek/mt7996/mt7992_eeprom_24_2i5i.bin"
++#define MT7992_EEPROM_DEFAULT_23	"mediatek/mt7996/mt7992_eeprom_23_2i5i.bin"
++#define MT7992_EEPROM_DEFAULT_23_EXT	"mediatek/mt7996/mt7992_eeprom_23_2e5e.bin"
+ #define MT7996_EEPROM_SIZE		7680
+ #define MT7996_EEPROM_BLOCK_SIZE	16
+ #define MT7996_TOKEN_SIZE		16384
+@@ -89,11 +104,24 @@ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+ struct mt7996_dfs_pattern;
+ 
++enum mt7996_fem_type {
++	MT7996_FEM_UNSET,
++	MT7996_FEM_EXT,
++	MT7996_FEM_INT,
++	MT7996_FEM_MIX,
++};
++
+ enum mt7996_sku_type {
+ 	MT7996_SKU_404,
+ 	MT7996_SKU_444,
+ };
+ 
++enum mt7992_sku_type {
++	MT7992_SKU_23,
++	MT7992_SKU_24,
++	MT7992_SKU_44,
++};
++
+ enum mt7996_ram_type {
+ 	MT7996_RAM_TYPE_WM,
+ 	MT7996_RAM_TYPE_WA,
+@@ -264,6 +292,7 @@ struct mt7996_dev {
+ 	struct mt7996_phy *rdd2_phy;
+ 
+ 	u8 chip_sku;
++	u8 fem_type;
+ 
+ 	u16 chainmask;
+ 	u8 chainshift[__MT_MAX_BAND];
+@@ -407,23 +436,6 @@ mt7996_phy3(struct mt7996_dev *dev)
+ 	return __mt7996_phy(dev, MT_BAND2);
+ }
+ 
+-static inline int
+-mt7996_get_chip_sku(struct mt7996_dev *dev)
+-{
+-	u32 val = mt76_rr(dev, MT_PAD_GPIO);
+-
+-	/* reserve for future variants */
+-	switch (mt76_chip(&dev->mt76)) {
+-	case 0x7990:
+-		dev->chip_sku = FIELD_GET(MT_PAD_GPIO_ADIE_COMB, val) <= 1;
+-		break;
+-	default:
+-		return -EINVAL;
+-	}
+-
+-	return 0;
+-}
+-
+ static inline bool
+ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
+ {
+@@ -462,6 +474,7 @@ int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
+ 			  int n_desc, int ring_base, struct mtk_wed_device *wed);
+ void mt7996_init_txpower(struct mt7996_phy *phy);
+ int mt7996_txbf_init(struct mt7996_dev *dev);
++int mt7996_get_chip_sku(struct mt7996_dev *dev);
+ void mt7996_reset(struct mt7996_dev *dev);
+ int mt7996_run(struct ieee80211_hw *hw);
+ int mt7996_mcu_init(struct mt7996_dev *dev);
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 47b429d8..cf12c5e0 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -662,6 +662,13 @@ enum offs_rev {
+ 
+ #define MT_PAD_GPIO				0x700056f0
+ #define MT_PAD_GPIO_ADIE_COMB			GENMASK(16, 15)
++#define MT_PAD_GPIO_ADIE_COMB_7992		GENMASK(17, 16)
++#define MT_PAD_GPIO_ADIE_NUM_7992		BIT(15)
++
++/* ADIE */
++#define MT_ADIE_CHIP_ID(_idx)                  (0x0f00002c + ((_idx) << 28))
++#define MT_ADIE_VERSION_MASK                   GENMASK(15, 0)
++#define MT_ADIE_CHIP_ID_MASK                   GENMASK(31, 16)
+ 
+ #define MT_HW_REV				0x70010204
+ #define MT_HW_REV1				0x8a00
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0017-mtk-wifi-mt76-mt7996-add-lock-for-indirect-register-.patch
similarity index 85%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0017-mtk-wifi-mt76-mt7996-add-lock-for-indirect-register-.patch
index 1a93d0b..0569291 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0017-mtk-wifi-mt76-mt7996-add-lock-for-indirect-register-.patch
@@ -1,24 +1,23 @@
-From 6a8359a808df29b708b2fd2aa84c0a369be7a7d5 Mon Sep 17 00:00:00 2001
+From f6787ee5ac1f581217a0177d830c395c23183046 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Mon, 3 Jul 2023 22:38:43 +0800
-Subject: [PATCH 14/98] wifi: mt76: mt7996: add lock for indirect register
+Subject: [PATCH 17/23] mtk: wifi: mt76: mt7996: add lock for indirect register
  access
 
 Some races were observed during indirect register access, fix this
 by adding reg_lock and reworking l1/l2 remap flow.
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: I0de2cd27df9ccb7f9a7d9ce265e869175b1ca7f1
 ---
  mt7996/mmio.c   | 69 +++++++++++++++++++++++++++++++++----------------
  mt7996/mt7996.h |  3 +--
  2 files changed, 48 insertions(+), 24 deletions(-)
 
 diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index c7b6d4b..ab088a2 100644
+index c50d89a4..d3d34f04 100644
 --- a/mt7996/mmio.c
 +++ b/mt7996/mmio.c
-@@ -86,7 +86,6 @@ static u32 mt7996_reg_map_l1(struct mt7996_dev *dev, u32 addr)
+@@ -140,7 +140,6 @@ static u32 mt7996_reg_map_l1(struct mt7996_dev *dev, u32 addr)
  	u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr);
  	u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr);
  
@@ -26,7 +25,7 @@
  	dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L1,
  			  MT_HIF_REMAP_L1_MASK,
  			  FIELD_PREP(MT_HIF_REMAP_L1_MASK, base));
-@@ -101,7 +100,6 @@ static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
+@@ -155,7 +154,6 @@ static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
  	u32 offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET, addr);
  	u32 base = FIELD_GET(MT_HIF_REMAP_L2_BASE, addr);
  
@@ -34,7 +33,7 @@
  	dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2,
  			  MT_HIF_REMAP_L2_MASK,
  			  FIELD_PREP(MT_HIF_REMAP_L2_MASK, base));
-@@ -111,26 +109,10 @@ static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
+@@ -165,26 +163,10 @@ static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
  	return MT_HIF_REMAP_BASE_L2 + offset;
  }
  
@@ -61,7 +60,7 @@
  	if (addr < 0x100000)
  		return addr;
  
-@@ -147,6 +129,11 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
+@@ -201,6 +183,11 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
  		return dev->reg.map[i].mapped + ofs;
  	}
  
@@ -73,7 +72,7 @@
  	if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) ||
  	    (addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) ||
  	    (addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END))
-@@ -171,28 +158,65 @@ void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
+@@ -225,28 +212,65 @@ void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
  {
  	u32 addr = __mt7996_reg_addr(dev, offset);
  
@@ -142,8 +141,8 @@
 +	return val;
  }
  
- int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
-@@ -341,6 +365,7 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+@@ -421,6 +445,7 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
  
  	dev = container_of(mdev, struct mt7996_dev, mt76);
  	mt76_mmio_init(&dev->mt76, mem_base);
@@ -152,10 +151,10 @@
  	switch (device_id) {
  	case 0x7990:
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index c8e7a33..c0ceef0 100644
+index c34cb76b..7e5ec212 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -309,8 +309,7 @@ struct mt7996_dev {
+@@ -362,8 +362,7 @@ struct mt7996_dev {
  		u8 n_agrt;
  	} twt;
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch
deleted file mode 100644
index 54d32c3..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From ff0611f9ade6ea4e9d84b7bd852ff745c609500b Mon Sep 17 00:00:00 2001
-From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
-Date: Wed, 28 Jun 2023 07:51:38 +0800
-Subject: [PATCH 17/98] wifi: mt76: mt7996: get tx_retries and tx_failed from
- txfree for both wed on and wed off
-
----
- mt76_connac3_mac.h |  4 ++--
- mt7996/mac.c       | 21 ++++++++++++++++-----
- mt7996/main.c      |  6 ++++++
- 3 files changed, 24 insertions(+), 7 deletions(-)
-
-diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
-index df6b02a..20a2fe9 100644
---- a/mt76_connac3_mac.h
-+++ b/mt76_connac3_mac.h
-@@ -272,11 +272,11 @@ enum tx_mgnt_type {
- #define MT_TXFREE0_MSDU_CNT		GENMASK(25, 16)
- #define MT_TXFREE0_RX_BYTE		GENMASK(15, 0)
- 
--#define MT_TXFREE1_VER			GENMASK(18, 16)
-+#define MT_TXFREE1_VER			GENMASK(19, 16)
- 
- #define MT_TXFREE_INFO_PAIR		BIT(31)
- #define MT_TXFREE_INFO_HEADER		BIT(30)
--#define MT_TXFREE_INFO_WLAN_ID		GENMASK(23, 12)
-+#define MT_TXFREE_INFO_MLD_ID		GENMASK(23, 12)
- #define MT_TXFREE_INFO_MSDU_ID		GENMASK(14, 0)
- #define MT_TXFREE_INFO_COUNT		GENMASK(27, 24)
- #define MT_TXFREE_INFO_STAT		GENMASK(29, 28)
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 066955e..bdc90a0 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1119,6 +1119,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
- 	struct mt76_phy *phy3 = mdev->phys[MT_BAND2];
- 	struct mt76_txwi_cache *txwi;
- 	struct ieee80211_sta *sta = NULL;
-+	struct mt76_wcid *wcid;
- 	LIST_HEAD(free_list);
- 	struct sk_buff *skb, *tmp;
- 	void *end = data + len;
-@@ -1137,7 +1138,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
- 		mt76_queue_tx_cleanup(dev, phy3->q_tx[MT_TXQ_BE], false);
- 	}
- 
--	if (WARN_ON_ONCE(le32_get_bits(tx_free[1], MT_TXFREE1_VER) < 4))
-+	if (WARN_ON_ONCE(le32_get_bits(tx_free[1], MT_TXFREE1_VER) < 5))
- 		return;
- 
- 	total = le32_get_bits(tx_free[0], MT_TXFREE0_MSDU_CNT);
-@@ -1153,10 +1154,9 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
- 		info = le32_to_cpu(*cur_info);
- 		if (info & MT_TXFREE_INFO_PAIR) {
- 			struct mt7996_sta *msta;
--			struct mt76_wcid *wcid;
- 			u16 idx;
- 
--			idx = FIELD_GET(MT_TXFREE_INFO_WLAN_ID, info);
-+			idx = FIELD_GET(MT_TXFREE_INFO_MLD_ID, info);
- 			wcid = rcu_dereference(dev->mt76.wcid[idx]);
- 			sta = wcid_to_sta(wcid);
- 			if (!sta)
-@@ -1169,10 +1169,21 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
- 					      &mdev->sta_poll_list);
- 			spin_unlock_bh(&mdev->sta_poll_lock);
- 			continue;
--		}
-+		} else if (info & MT_TXFREE_INFO_HEADER) {
-+			u32 tx_retries = 0, tx_failed = 0;
-+
-+			if (!wcid)
-+				continue;
-+
-+			tx_retries =
-+				FIELD_GET(MT_TXFREE_INFO_COUNT, info) - 1;
-+			tx_failed = tx_retries +
-+				!!FIELD_GET(MT_TXFREE_INFO_STAT, info);
- 
--		if (info & MT_TXFREE_INFO_HEADER)
-+			wcid->stats.tx_retries += tx_retries;
-+			wcid->stats.tx_failed += tx_failed;
- 			continue;
-+		}
- 
- 		for (i = 0; i < 2; i++) {
- 			msdu = (info >> (15 * i)) & MT_TXFREE_INFO_MSDU_ID;
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 41f0fa1..f152e76 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -997,6 +997,12 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
- 	sinfo->txrate.flags = txrate->flags;
- 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
- 
-+	sinfo->tx_failed = msta->wcid.stats.tx_failed;
-+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
-+
-+	sinfo->tx_retries = msta->wcid.stats.tx_retries;
-+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
-+
- 	sinfo->ack_signal = (s8)msta->ack_signal;
- 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0018-mtk-wifi-mt76-connac-set-correct-muar_idx-for-connac.patch
similarity index 72%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0018-mtk-wifi-mt76-connac-set-correct-muar_idx-for-connac.patch
index 381c929..53c8e6d 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0018-mtk-wifi-mt76-connac-set-correct-muar_idx-for-connac.patch
@@ -1,24 +1,23 @@
-From 09a1b2d9ad49d3bea1bdd8d4f7326af6a65a3dbb Mon Sep 17 00:00:00 2001
+From 1049c0632347ba53ab8ba1d9f195377e135c9856 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 16 Feb 2023 13:53:14 +0800
-Subject: [PATCH 15/98] wifi: mt76: connac: set correct muar_idx for connac3
- chipset
+Subject: [PATCH 18/23] mtk: wifi: mt76: connac: set correct muar_idx for
+ connac3 chipset
 
 Set the muar_idx to 0xe for the hw bcast/mcast station entry of connac3
 chipset.
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: I7054c3b3c64ec447cc280ea810f4958afdfa9e02
 ---
  mt76_connac.h     | 5 +++++
  mt76_connac_mcu.c | 3 +++
  2 files changed, 8 insertions(+)
 
 diff --git a/mt76_connac.h b/mt76_connac.h
-index e5ebde1..c6726ab 100644
+index fdde3d70..b1ec8d46 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
-@@ -245,6 +245,11 @@ static inline bool is_connac_v1(struct mt76_dev *dev)
+@@ -250,6 +250,11 @@ static inline bool is_connac_v1(struct mt76_dev *dev)
  	return is_mt7615(dev) || is_mt7663(dev) || is_mt7622(dev);
  }
  
@@ -31,10 +30,10 @@
  {
  	switch (mt76_chip(dev)) {
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index bcd6c20..68de525 100644
+index 0d05404f..8dd61f86 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -282,6 +282,9 @@ __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
+@@ -283,6 +283,9 @@ __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
  	};
  	struct sk_buff *skb;
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch
deleted file mode 100644
index 5110644..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From 63501a3e941097581dcee61a0149ee5bc944c579 Mon Sep 17 00:00:00 2001
-From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
-Date: Wed, 28 Jun 2023 08:10:25 +0800
-Subject: [PATCH 18/98] wifi: mt76: mt7996: Add mcu commands for getting sta tx
- statistic
-
-Per peer Tx/Rx statistic can only be obtained by querying WM when WED is
-on. This patch switches to periodic event reporting in the case of WED
-being enabled.
----
- mt76_connac_mcu.h | 15 +++++++++++
- mt7996/mac.c      |  5 ++++
- mt7996/main.c     | 15 +++++++++++
- mt7996/mcu.c      | 68 +++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      | 26 ++++++++++++++++++
- mt7996/mt7996.h   |  1 +
- 6 files changed, 130 insertions(+)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 90c08d2..e9dd9aa 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1023,6 +1023,8 @@ enum {
- 	MCU_UNI_EVENT_TX_DONE = 0x2d,
- 	MCU_UNI_EVENT_THERMAL = 0x35,
- 	MCU_UNI_EVENT_NIC_CAPAB = 0x43,
-+	MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
-+	MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
- };
- 
- #define MCU_UNI_CMD_EVENT			BIT(1)
-@@ -1242,6 +1244,8 @@ enum {
- 	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
- 	MCU_UNI_CMD_RRO = 0x57,
- 	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
-+	MCU_UNI_CMD_PER_STA_INFO = 0x6d,
-+	MCU_UNI_CMD_ALL_STA_INFO = 0x6e,
- 	MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
- };
- 
-@@ -1322,6 +1326,17 @@ enum {
- 	UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
- };
- 
-+enum UNI_ALL_STA_INFO_TAG {
-+	UNI_ALL_STA_TX_RATE,
-+	UNI_ALL_STA_TX_STAT,
-+	UNI_ALL_STA_TXRX_ADM_STAT,
-+	UNI_ALL_STA_TXRX_AIR_TIME,
-+	UNI_ALL_STA_DATA_TX_RETRY_COUNT,
-+	UNI_ALL_STA_GI_MODE,
-+	UNI_ALL_STA_TXRX_MSDU_COUNT,
-+	UNI_ALL_STA_MAX_NUM
-+};
-+
- enum {
- 	MT_NIC_CAP_TX_RESOURCE,
- 	MT_NIC_CAP_TX_EFUSE_ADDR,
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index bdc90a0..4828f10 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -2272,6 +2272,11 @@ void mt7996_mac_work(struct work_struct *work)
- 		mphy->mac_work_count = 0;
- 
- 		mt7996_mac_update_stats(phy);
-+
-+		if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
-+			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
-+			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
-+		};
- 	}
- 
- 	mutex_unlock(&mphy->dev->mutex);
-diff --git a/mt7996/main.c b/mt7996/main.c
-index f152e76..e9e1fd9 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -977,6 +977,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
- 				  struct ieee80211_sta *sta,
- 				  struct station_info *sinfo)
- {
-+	struct mt7996_phy *phy = mt7996_hw_phy(hw);
- 	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
- 	struct rate_info *txrate = &msta->wcid.rate;
- 
-@@ -1008,6 +1009,20 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
- 
- 	sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal);
- 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);
-+
-+	if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
-+		sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
-+		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
-+
-+		sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
-+		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
-+
-+		sinfo->tx_packets = msta->wcid.stats.tx_packets;
-+		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
-+
-+		sinfo->rx_packets = msta->wcid.stats.rx_packets;
-+		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
-+	}
- }
- 
- static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 2c611e7..652a600 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -477,6 +477,54 @@ mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
- 	phy->throttle_state = n->duty_percent;
- }
- 
-+static void
-+mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
-+{
-+	struct mt7996_mcu_all_sta_info_event *res;
-+	u16 i;
-+
-+	skb_pull(skb, sizeof(struct mt7996_mcu_rxd));
-+
-+	res = (struct mt7996_mcu_all_sta_info_event *)skb->data;
-+
-+	for (i = 0; i < le16_to_cpu(res->sta_num); i++) {
-+		u8 ac;
-+		u16 wlan_idx;
-+		struct mt76_wcid *wcid;
-+
-+		switch (le16_to_cpu(res->tag)) {
-+		case UNI_ALL_STA_TXRX_ADM_STAT:
-+			wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx);
-+			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-+
-+			if (!wcid)
-+				break;
-+
-+			for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-+				wcid->stats.tx_bytes +=
-+					le32_to_cpu(res->adm_stat[i].tx_bytes[ac]);
-+				wcid->stats.rx_bytes +=
-+					le32_to_cpu(res->adm_stat[i].rx_bytes[ac]);
-+			}
-+			break;
-+		case UNI_ALL_STA_TXRX_MSDU_COUNT:
-+			wlan_idx = le16_to_cpu(res->msdu_cnt[i].wlan_idx);
-+			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-+
-+			if (!wcid)
-+				break;
-+
-+			wcid->stats.tx_packets +=
-+				le32_to_cpu(res->msdu_cnt[i].tx_msdu_cnt);
-+			wcid->stats.rx_packets +=
-+				le32_to_cpu(res->msdu_cnt[i].rx_msdu_cnt);
-+			break;
-+		default:
-+			break;
-+		}
-+	}
-+}
-+
- static void
- mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb)
- {
-@@ -524,6 +572,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
- 	case MCU_UNI_EVENT_THERMAL:
- 		mt7996_mcu_rx_thermal_notify(dev, skb);
- 		break;
-+	case MCU_UNI_EVENT_ALL_STA_INFO:
-+		mt7996_mcu_rx_all_sta_info_event(dev, skb);
-+		break;
- 	default:
- 		break;
- 	}
-@@ -4192,3 +4243,20 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
- 	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO), &req,
- 				 sizeof(req), true);
- }
-+
-+int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
-+{
-+	struct mt7996_dev *dev = phy->dev;
-+	struct {
-+		u8 _rsv[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+	} __packed req = {
-+		.tag = cpu_to_le16(tag),
-+		.len = cpu_to_le16(sizeof(req) - 4),
-+	};
-+
-+	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO),
-+				 &req, sizeof(req), false);
-+}
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 05785cb..97151d1 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -191,6 +191,32 @@ struct mt7996_mcu_thermal_notify {
- 	u8 __rsv2[4];
- } __packed;
- 
-+struct mt7996_mcu_all_sta_info_event {
-+	u8 rsv[4];
-+	__le16 tag;
-+	__le16 len;
-+        u8 more;
-+        u8 rsv2;
-+        __le16 sta_num;
-+        u8 rsv3[2];
-+
-+	union {
-+		struct {
-+			__le16 wlan_idx;
-+			u8 rsv[2];
-+			__le32 tx_bytes[IEEE80211_NUM_ACS];
-+			__le32 rx_bytes[IEEE80211_NUM_ACS];
-+		} adm_stat[0];
-+
-+		struct {
-+			__le16 wlan_idx;
-+			u8 rsv[2];
-+			__le32 tx_msdu_cnt;
-+			__le32 rx_msdu_cnt;
-+		} msdu_cnt[0];
-+	};
-+} __packed;
-+
- enum mt7996_chan_mib_offs {
- 	UNI_MIB_OBSS_AIRTIME = 26,
- 	UNI_MIB_NON_WIFI_TIME = 27,
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 0bb20a9..420d113 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -494,6 +494,7 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
- int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
- void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
- void mt7996_mcu_exit(struct mt7996_dev *dev);
-+int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
- 
- static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
- {
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0019-mtk-wifi-mt76-mt7996-ACS-channel-time-too-long-on-du.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0019-mtk-wifi-mt76-mt7996-ACS-channel-time-too-long-on-du.patch
new file mode 100644
index 0000000..4cf6472
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0019-mtk-wifi-mt76-mt7996-ACS-channel-time-too-long-on-du.patch
@@ -0,0 +1,68 @@
+From ce1d4b6bce414015a9e889f28eafc06a57c4e1a7 Mon Sep 17 00:00:00 2001
+From: "fancy.liu" <fancy.liu@mediatek.com>
+Date: Tue, 14 Nov 2023 10:13:24 +0800
+Subject: [PATCH 19/23] mtk: wifi: mt76: mt7996: ACS channel time too long on
+ duty channel
+
+Step and issue:
+1. Set channel to 36 in hostapd config;
+2. Bootup;
+3. Enable ACS through UCI command and reload;
+4. Check hostapd log, channel 36 channel_time is much longer than other channels.
+
+Root cause:
+The reset chan_stat condition missed duty channel.
+
+Solution:
+When scan start, need to reset chan_stat in each channel switch.
+
+Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
+
+Issue:
+There's a chance that the channel time for duty channel is zero in ACS
+scan.
+
+Root cause:
+The chan_stat may be reset when restore to duty channel.
+Mac80211 will notify to hostapd when scan done and then restore to duty
+channel.
+And mt76 will clear scan flag after restore done.
+If hostapd get the chan_stat before channel_restore, will get the
+correct channel time;
+If hostapd get the chan_stat after channel_restore, will get zero
+channel time;
+
+Solution:
+When channel switch, will check the mac80211 scan state but not the mt76 scan flag.
+Mac80211 scan state will be set in scanning, and will be reset after
+scan done and before restore to duty channel.
+
+Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
+---
+ mac80211.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/mac80211.c b/mac80211.c
+index cc9e9ff1..6c5b4f55 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -928,6 +928,7 @@ void mt76_set_channel(struct mt76_phy *phy)
+ 	struct cfg80211_chan_def *chandef = &hw->conf.chandef;
+ 	bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
+ 	int timeout = HZ / 5;
++	unsigned long was_scanning = ieee80211_get_scanning(hw);
+ 
+ 	wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout);
+ 	mt76_update_survey(phy);
+@@ -942,7 +943,7 @@ void mt76_set_channel(struct mt76_phy *phy)
+ 	if (!offchannel)
+ 		phy->main_chan = chandef->chan;
+ 
+-	if (chandef->chan != phy->main_chan)
++	if (chandef->chan != phy->main_chan || was_scanning)
+ 		memset(phy->chan_state, 0, sizeof(*phy->chan_state));
+ }
+ EXPORT_SYMBOL_GPL(mt76_set_channel);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch
deleted file mode 100644
index 6505422..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-From 85c7ec658b8ea1ee4ca7525f21c28d2f456e0b95 Mon Sep 17 00:00:00 2001
-From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
-Date: Wed, 28 Jun 2023 08:34:21 +0800
-Subject: [PATCH 19/98] wifi: mt76: mt7996: enable PPDU-TxS to host
-
-Enable PPDU-TxS by default no matter WED on or WED off
-PPDU-TxS is also capable of getting tx_bytes and tx_retries,
-but we'll get that from mcu command and TxFree instead.
----
- mt76_connac3_mac.h | 22 +++++++++++++++++++++-
- mt7996/init.c      |  5 +++++
- mt7996/mac.c       | 45 +++++++++++++++++++++++++++------------------
- mt7996/regs.h      |  7 +++++++
- 4 files changed, 60 insertions(+), 19 deletions(-)
-
-diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
-index 20a2fe9..7402de2 100644
---- a/mt76_connac3_mac.h
-+++ b/mt76_connac3_mac.h
-@@ -281,6 +281,12 @@ enum tx_mgnt_type {
- #define MT_TXFREE_INFO_COUNT		GENMASK(27, 24)
- #define MT_TXFREE_INFO_STAT		GENMASK(29, 28)
- 
-+enum {
-+	MT_TXS_MPDU_FM0,
-+	MT_TXS_MPDU_FM1,
-+	MT_TXS_PPDU_FM
-+};
-+
- #define MT_TXS0_BW			GENMASK(31, 29)
- #define MT_TXS0_TID			GENMASK(28, 26)
- #define MT_TXS0_AMPDU			BIT(25)
-@@ -306,7 +312,7 @@ enum tx_mgnt_type {
- 
- #define MT_TXS2_BF_STATUS		GENMASK(31, 30)
- #define MT_TXS2_BAND			GENMASK(29, 28)
--#define MT_TXS2_WCID			GENMASK(27, 16)
-+#define MT_TXS2_MLD_ID			GENMASK(27, 16)
- #define MT_TXS2_TX_DELAY		GENMASK(15, 0)
- 
- #define MT_TXS3_PID			GENMASK(31, 24)
-@@ -318,6 +324,7 @@ enum tx_mgnt_type {
- 
- #define MT_TXS4_TIMESTAMP		GENMASK(31, 0)
- 
-+/* MPDU based TXS */
- #define MT_TXS5_F0_FINAL_MPDU		BIT(31)
- #define MT_TXS5_F0_QOS			BIT(30)
- #define MT_TXS5_F0_TX_COUNT		GENMASK(29, 25)
-@@ -339,4 +346,17 @@ enum tx_mgnt_type {
- #define MT_TXS7_F1_MPDU_RETRY_COUNT	GENMASK(31, 24)
- #define MT_TXS7_F1_MPDU_RETRY_BYTES	GENMASK(23, 0)
- 
-+/* PPDU based TXS */
-+#define MT_TXS5_MPDU_TX_CNT		GENMASK(30, 20)
-+#define MT_TXS5_MPDU_TX_BYTE_SCALE	BIT(15)
-+#define MT_TXS5_MPDU_TX_BYTE		GENMASK(14, 0)
-+
-+#define MT_TXS6_MPDU_FAIL_CNT		GENMASK(30, 20)
-+#define MT_TXS6_MPDU_FAIL_BYTE_SCALE	BIT(15)
-+#define MT_TXS6_MPDU_FAIL_BYTE		GENMASK(14, 0)
-+
-+#define MT_TXS7_MPDU_RETRY_CNT		GENMASK(30, 20)
-+#define MT_TXS7_MPDU_RETRY_BYTE_SCALE	BIT(15)
-+#define MT_TXS7_MPDU_RETRY_BYTE		GENMASK(14, 0)
-+
- #endif /* __MT76_CONNAC3_MAC_H */
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 17a4abd..3656b89 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -456,6 +456,11 @@ mt7996_mac_init_band(struct mt7996_dev *dev, u8 band)
- 	set = FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_MODE, 0) |
- 	      FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_PARAM, 0x3);
- 	mt76_rmw(dev, MT_WTBLOFF_RSCR(band), mask, set);
-+
-+	/* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
-+	 * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
-+	 */
-+	mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);
- }
- 
- static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 4828f10..7512147 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1227,22 +1227,35 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
- 	bool cck = false;
- 	u32 txrate, txs, mode, stbc;
- 
-+	txs = le32_to_cpu(txs_data[0]);
-+
- 	mt76_tx_status_lock(mdev, &list);
- 	skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
--	if (!skb)
--		goto out_no_skb;
- 
--	txs = le32_to_cpu(txs_data[0]);
-+	if (skb) {
-+		info = IEEE80211_SKB_CB(skb);
-+		if (!(txs & MT_TXS0_ACK_ERROR_MASK))
-+			info->flags |= IEEE80211_TX_STAT_ACK;
- 
--	info = IEEE80211_SKB_CB(skb);
--	if (!(txs & MT_TXS0_ACK_ERROR_MASK))
--		info->flags |= IEEE80211_TX_STAT_ACK;
-+		info->status.ampdu_len = 1;
-+		info->status.ampdu_ack_len = !!(info->flags &
-+				IEEE80211_TX_STAT_ACK);
-+
-+		info->status.rates[0].idx = -1;
-+	}
- 
--	info->status.ampdu_len = 1;
--	info->status.ampdu_ack_len = !!(info->flags &
--					IEEE80211_TX_STAT_ACK);
-+	/* PPDU based reporting */
-+	if (FIELD_GET(MT_TXS0_TXS_FORMAT,txs) == MT_TXS_PPDU_FM) {
-+		if (wcid->sta) {
-+			struct ieee80211_sta *sta;
-+			u8 tid;
- 
--	info->status.rates[0].idx = -1;
-+			sta = container_of((void *)wcid, struct ieee80211_sta,
-+					drv_priv);
-+			tid = FIELD_GET(MT_TXS0_TID, txs);
-+			ieee80211_refresh_tx_agg_session_timer(sta, tid);
-+		}
-+	}
- 
- 	txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
- 
-@@ -1342,9 +1355,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
- 	wcid->rate = rate;
- 
- out:
--	mt76_tx_status_skb_done(mdev, skb, &list);
--
--out_no_skb:
-+	if (skb)
-+		mt76_tx_status_skb_done(mdev, skb, &list);
- 	mt76_tx_status_unlock(mdev, &list);
- 
- 	return !!skb;
-@@ -1358,13 +1370,10 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
- 	u16 wcidx;
- 	u8 pid;
- 
--	if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) > 1)
--		return;
--
--	wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID);
-+	wcidx = le32_get_bits(txs_data[2], MT_TXS2_MLD_ID);
- 	pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
- 
--	if (pid < MT_PACKET_ID_FIRST)
-+	if (pid < MT_PACKET_ID_WED)
- 		return;
- 
- 	if (wcidx >= mt7996_wtbl_size(dev))
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index bd0eb51..865e005 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -275,6 +275,13 @@ enum base_rev {
- 						 FIELD_PREP(MT_WTBL_LMAC_ID, _id) | \
- 						 FIELD_PREP(MT_WTBL_LMAC_DW, _dw))
- 
-+/* AGG: band 0(0x820e2000), band 1(0x820f2000), band 2(0x830e2000) */
-+#define MT_WF_AGG_BASE(_band)		__BASE(WF_AGG_BASE, (_band))
-+#define MT_WF_AGG(_band, ofs)		(MT_WF_AGG_BASE(_band) + (ofs))
-+
-+#define MT_AGG_ACR4(_band)		MT_WF_AGG(_band, 0x3c)
-+#define MT_AGG_ACR_PPDU_TXS2H		BIT(1)
-+
- /* ARB: band 0(0x820e3000), band 1(0x820f3000), band 2(0x830e3000) */
- #define MT_WF_ARB_BASE(_band)			__BASE(WF_ARB_BASE, (_band))
- #define MT_WF_ARB(_band, ofs)			(MT_WF_ARB_BASE(_band) + (ofs))
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0020-mtk-wifi-mt76-mt7996-Fixed-null-pointer-dereference-.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0020-mtk-wifi-mt76-mt7996-Fixed-null-pointer-dereference-.patch
new file mode 100644
index 0000000..8a6dad9
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0020-mtk-wifi-mt76-mt7996-Fixed-null-pointer-dereference-.patch
@@ -0,0 +1,42 @@
+From 7de61119663e923bc39f777545f39b489f9f4715 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Thu, 26 Oct 2023 10:08:10 +0800
+Subject: [PATCH 20/23] mtk: wifi: mt76: mt7996: Fixed null pointer dereference
+ issue
+
+Without this patch, when the station is still in Authentication stage and
+sends a "Notify bandwidth change action frame" to AP at the same time,
+there will be a race condition that causes a crash to occur because the AP
+access "msta->vif" that has not been fully initialized.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+Signed-off-by: Money Wang <money.wang@mediatek.com>
+Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
+---
+ mt7996/main.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 4db8899c..9fbd87d5 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1063,9 +1063,16 @@ static void mt7996_sta_rc_update(struct ieee80211_hw *hw,
+ 				 struct ieee80211_sta *sta,
+ 				 u32 changed)
+ {
++	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ 	struct mt7996_dev *dev = phy->dev;
+ 
++	if (!msta->vif) {
++		dev_warn(dev->mt76.dev, "Un-initialized STA %pM wcid %d in rc_work\n",
++			 sta->addr, msta->wcid.idx);
++		return;
++	}
++
+ 	mt7996_sta_rc_work(&changed, sta);
+ 	ieee80211_queue_work(hw, &dev->rc_work);
+ }
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch
deleted file mode 100644
index 5cee6a0..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch
+++ /dev/null
@@ -1,233 +0,0 @@
-From e66867f6acc33faa75e9e301ad64e0903cffd7be Mon Sep 17 00:00:00 2001
-From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
-Date: Fri, 14 Jul 2023 09:43:53 +0800
-Subject: [PATCH 20/98] wifi: mt76: mt7996: fix incorrect report of TX GI
-
----
- mt76_connac_mcu.h |  2 +-
- mt7996/mac.c      | 48 +++--------------------------------------------
- mt7996/main.c     |  1 +
- mt7996/mcu.c      | 47 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      | 22 ++++++++++++++++++++++
- 5 files changed, 74 insertions(+), 46 deletions(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index e9dd9aa..8562ca4 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1327,7 +1327,7 @@ enum {
- };
- 
- enum UNI_ALL_STA_INFO_TAG {
--	UNI_ALL_STA_TX_RATE,
-+	UNI_ALL_STA_TXRX_RATE,
- 	UNI_ALL_STA_TX_STAT,
- 	UNI_ALL_STA_TXRX_ADM_STAT,
- 	UNI_ALL_STA_TXRX_AIR_TIME,
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 7512147..06c9a14 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -102,7 +102,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
- 	};
- 	struct ieee80211_sta *sta;
- 	struct mt7996_sta *msta;
--	struct rate_info *rate;
- 	u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
- 	LIST_HEAD(sta_poll_list);
- 	int i;
-@@ -118,7 +117,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
- 		u32 addr, val;
- 		u16 idx;
- 		s8 rssi[4];
--		u8 bw;
- 
- 		spin_lock_bh(&dev->mt76.sta_poll_lock);
- 		if (list_empty(&sta_poll_list)) {
-@@ -174,49 +172,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
- 			ieee80211_sta_register_airtime(sta, tid, tx_cur, rx_cur);
- 		}
- 
--		/* We don't support reading GI info from txs packets.
--		 * For accurate tx status reporting and AQL improvement,
--		 * we need to make sure that flags match so polling GI
--		 * from per-sta counters directly.
--		 */
--		rate = &msta->wcid.rate;
--
--		switch (rate->bw) {
--		case RATE_INFO_BW_320:
--			bw = IEEE80211_STA_RX_BW_320;
--			break;
--		case RATE_INFO_BW_160:
--			bw = IEEE80211_STA_RX_BW_160;
--			break;
--		case RATE_INFO_BW_80:
--			bw = IEEE80211_STA_RX_BW_80;
--			break;
--		case RATE_INFO_BW_40:
--			bw = IEEE80211_STA_RX_BW_40;
--			break;
--		default:
--			bw = IEEE80211_STA_RX_BW_20;
--			break;
--		}
--
--		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 6);
--		val = mt76_rr(dev, addr);
--		if (rate->flags & RATE_INFO_FLAGS_EHT_MCS) {
--			addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 5);
--			val = mt76_rr(dev, addr);
--			rate->eht_gi = FIELD_GET(GENMASK(25, 24), val);
--		} else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) {
--			u8 offs = 24 + 2 * bw;
--
--			rate->he_gi = (val & (0x3 << offs)) >> offs;
--		} else if (rate->flags &
--			   (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_MCS)) {
--			if (val & BIT(12 + bw))
--				rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
--			else
--				rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
--		}
--
- 		/* get signal strength of resp frames (CTS/BA/ACK) */
- 		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
- 		val = mt76_rr(dev, addr);
-@@ -1303,6 +1258,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
- 			goto out;
- 
- 		rate.flags = RATE_INFO_FLAGS_VHT_MCS;
-+		if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
-+			rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- 		break;
- 	case MT_PHY_TYPE_HE_SU:
- 	case MT_PHY_TYPE_HE_EXT_SU:
-@@ -2282,6 +2239,7 @@ void mt7996_mac_work(struct work_struct *work)
- 
- 		mt7996_mac_update_stats(phy);
- 
-+		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_RATE);
- 		if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
- 			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
- 			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
-diff --git a/mt7996/main.c b/mt7996/main.c
-index e9e1fd9..0b3f8c8 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -991,6 +991,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
- 			sinfo->txrate.he_gi = txrate->he_gi;
- 			sinfo->txrate.he_dcm = txrate->he_dcm;
- 			sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
-+			sinfo->txrate.eht_gi = txrate->eht_gi;
- 		}
- 		sinfo->txrate.flags = txrate->flags;
- 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 652a600..c190067 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -477,6 +477,43 @@ mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
- 	phy->throttle_state = n->duty_percent;
- }
- 
-+static int
-+mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rate)
-+{
-+	switch (mcu_rate->tx_mode) {
-+	case MT_PHY_TYPE_CCK:
-+	case MT_PHY_TYPE_OFDM:
-+		break;
-+	case MT_PHY_TYPE_HT:
-+	case MT_PHY_TYPE_HT_GF:
-+	case MT_PHY_TYPE_VHT:
-+		if (mcu_rate->tx_gi)
-+			rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
-+		else
-+			rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
-+		break;
-+	case MT_PHY_TYPE_HE_SU:
-+	case MT_PHY_TYPE_HE_EXT_SU:
-+	case MT_PHY_TYPE_HE_TB:
-+	case MT_PHY_TYPE_HE_MU:
-+		if (mcu_rate->tx_gi > NL80211_RATE_INFO_HE_GI_3_2)
-+			return -EINVAL;
-+		rate->he_gi = mcu_rate->tx_gi;
-+		break;
-+	case MT_PHY_TYPE_EHT_SU:
-+	case MT_PHY_TYPE_EHT_TRIG:
-+	case MT_PHY_TYPE_EHT_MU:
-+		if (mcu_rate->tx_gi > NL80211_RATE_INFO_EHT_GI_3_2)
-+			return -EINVAL;
-+		rate->eht_gi = mcu_rate->tx_gi;
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
- static void
- mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
- {
-@@ -493,6 +530,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
- 		struct mt76_wcid *wcid;
- 
- 		switch (le16_to_cpu(res->tag)) {
-+		case UNI_ALL_STA_TXRX_RATE:
-+			wlan_idx = le16_to_cpu(res->rate[i].wlan_idx);
-+			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-+
-+			if (!wcid)
-+				break;
-+
-+			if (mt7996_mcu_update_tx_gi(&wcid->rate, &res->rate[i]))
-+				dev_err(dev->mt76.dev, "Failed to update TX GI\n");
-+			break;
- 		case UNI_ALL_STA_TXRX_ADM_STAT:
- 			wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx);
- 			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 97151d1..376931e 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -191,6 +191,27 @@ struct mt7996_mcu_thermal_notify {
- 	u8 __rsv2[4];
- } __packed;
- 
-+struct all_sta_trx_rate {
-+	__le16 wlan_idx;
-+	u8 __rsv1[2];
-+	u8 tx_mode;
-+	u8 flags;
-+	u8 tx_stbc;
-+	u8 tx_gi;
-+	u8 tx_bw;
-+	u8 tx_ldpc;
-+	u8 tx_mcs;
-+	u8 tx_nss;
-+	u8 rx_rate;
-+	u8 rx_mode;
-+	u8 rx_nsts;
-+	u8 rx_gi;
-+	u8 rx_coding;
-+	u8 rx_stbc;
-+	u8 rx_bw;
-+	u8 __rsv2;
-+} __packed;
-+
- struct mt7996_mcu_all_sta_info_event {
- 	u8 rsv[4];
- 	__le16 tag;
-@@ -201,6 +222,7 @@ struct mt7996_mcu_all_sta_info_event {
-         u8 rsv3[2];
- 
- 	union {
-+		struct all_sta_trx_rate rate[0];
- 		struct {
- 			__le16 wlan_idx;
- 			u8 rsv[2];
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0021-mtk-wifi-mt76-add-sanity-check-to-prevent-kernel-cra.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0021-mtk-wifi-mt76-add-sanity-check-to-prevent-kernel-cra.patch
new file mode 100644
index 0000000..b12d5ed
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0021-mtk-wifi-mt76-add-sanity-check-to-prevent-kernel-cra.patch
@@ -0,0 +1,36 @@
+From 56cd8feb0565b8eedfae7c42dba8b5e374dc71a8 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Mon, 30 Oct 2023 11:06:19 +0800
+Subject: [PATCH 21/23] mtk: wifi: mt76: add sanity check to prevent kernel
+ crash
+
+wcid may not be initialized when mac80211 calls mt76.tx and it would lead to
+kernel crash.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ tx.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/tx.c b/tx.c
+index 1809b032..4596b367 100644
+--- a/tx.c
++++ b/tx.c
+@@ -345,6 +345,14 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
+ 
+ 	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->band_idx);
+ 
++	if (!wcid->tx_pending.prev || !wcid->tx_pending.next) {
++		dev_warn(phy->dev->dev, "Un-initialized STA %pM wcid %d in mt76_tx\n",
++			 sta->addr, wcid->idx);
++
++		ieee80211_free_txskb(phy->hw, skb);
++		return;
++	}
++
+ 	spin_lock_bh(&wcid->tx_pending.lock);
+ 	__skb_queue_tail(&wcid->tx_pending, skb);
+ 	spin_unlock_bh(&wcid->tx_pending.lock);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch
deleted file mode 100644
index a5a8417..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From e6830d67bbbc38036cd077badd5a605b8f257752 Mon Sep 17 00:00:00 2001
-From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
-Date: Thu, 27 Jul 2023 14:00:30 +0800
-Subject: [PATCH 21/98] wifi: mt76: mt7996: remove periodic MPDU TXS request
-
----
- mt7996/mac.c    | 39 ++++++++++++++++++++++-----------------
- mt7996/main.c   |  1 -
- mt7996/mt7996.h |  1 -
- 3 files changed, 22 insertions(+), 19 deletions(-)
-
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 06c9a14..32c52fc 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -926,15 +926,6 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- 	if (!wcid)
- 		wcid = &dev->mt76.global_wcid;
- 
--	if (sta) {
--		struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
--
--		if (time_after(jiffies, msta->jiffies + HZ / 4)) {
--			info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
--			msta->jiffies = jiffies;
--		}
--	}
--
- 	t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
- 	t->skb = tx_info->skb;
- 
-@@ -1010,22 +1001,36 @@ u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
- }
- 
- static void
--mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
-+mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
- {
- 	struct mt7996_sta *msta;
-+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+	bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
- 	u16 fc, tid;
--	u32 val;
- 
- 	if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
- 		return;
- 
--	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
-+	tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
- 	if (tid >= 6) /* skip VO queue */
- 		return;
- 
--	val = le32_to_cpu(txwi[2]);
--	fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
--	     FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
-+	if (is_8023)
-+		fc = IEEE80211_FTYPE_DATA |
-+		     (sta->wme ? IEEE80211_STYPE_QOS_DATA
-+		               : IEEE80211_STYPE_DATA);
-+	else {
-+		/* No need to get precise TID for Action/Management Frame,
-+		 * since it will not meet the following Frame Control
-+		 * condition anyway.
-+		 */
-+
-+		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+
-+		fc = le16_to_cpu(hdr->frame_control) &
-+		     (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
-+	}
-+
- 	if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
- 		return;
- 
-@@ -1053,7 +1058,7 @@ mt7996_txwi_free(struct mt7996_dev *dev, struct mt76_txwi_cache *t,
- 		wcid_idx = wcid->idx;
- 
- 		if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
--			mt7996_tx_check_aggr(sta, txwi);
-+			mt7996_tx_check_aggr(sta, t->skb);
- 	} else {
- 		wcid_idx = le32_get_bits(txwi[9], MT_TXD9_WLAN_IDX);
- 	}
-@@ -1330,7 +1335,7 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
- 	wcidx = le32_get_bits(txs_data[2], MT_TXS2_MLD_ID);
- 	pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
- 
--	if (pid < MT_PACKET_ID_WED)
-+	if (pid < MT_PACKET_ID_NO_SKB)
- 		return;
- 
- 	if (wcidx >= mt7996_wtbl_size(dev))
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 0b3f8c8..832b861 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -666,7 +666,6 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- 	msta->wcid.idx = idx;
- 	msta->wcid.phy_idx = band_idx;
- 	msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
--	msta->jiffies = jiffies;
- 
- 	ewma_avg_signal_init(&msta->avg_ack_signal);
- 
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 420d113..f268773 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -147,7 +147,6 @@ struct mt7996_sta {
- 	struct ewma_avg_signal avg_ack_signal;
- 
- 	unsigned long changed;
--	unsigned long jiffies;
- 
- 	struct mt76_connac_sta_key_conf bip;
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0022-mtk-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0022-mtk-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
index a850a6c..5f22e8e 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0022-mtk-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
@@ -1,10 +1,9 @@
-From 4d055393b680ce616cb96f75cca154016cfb9a68 Mon Sep 17 00:00:00 2001
+From 8795ba8431696203ecd0b5bbf37ad64302250a29 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Fri, 19 May 2023 14:16:50 +0800
-Subject: [PATCH 16/98] wifi: mt76: mt7996: add firmware WA's coredump.
+Subject: [PATCH 22/23] mtk: wifi: mt76: mt7996: add firmware WA's coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Change-Id: I51f115b4ae15bc0f871f93652570d72511dbf880
 ---
  mt7996/coredump.c | 180 ++++++++++++++++++++++++++++++----------------
  mt7996/coredump.h |  35 ++++++---
@@ -15,7 +14,7 @@
  6 files changed, 182 insertions(+), 83 deletions(-)
 
 diff --git a/mt7996/coredump.c b/mt7996/coredump.c
-index ccab0d7..60b8808 100644
+index ccab0d7b..60b88085 100644
 --- a/mt7996/coredump.c
 +++ b/mt7996/coredump.c
 @@ -7,11 +7,11 @@
@@ -336,7 +335,7 @@
  }
  
 diff --git a/mt7996/coredump.h b/mt7996/coredump.h
-index af2ba21..01ed373 100644
+index af2ba219..01ed3731 100644
 --- a/mt7996/coredump.h
 +++ b/mt7996/coredump.h
 @@ -6,10 +6,13 @@
@@ -429,10 +428,10 @@
  	return NULL;
  }
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index ccb7b22..066955e 100644
+index 19b34066..adbfd23f 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -1962,28 +1962,25 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -2001,28 +2001,25 @@ void mt7996_mac_reset_work(struct work_struct *work)
  }
  
  /* firmware coredump */
@@ -465,7 +464,7 @@
  	if (!mem_region || !crash_data->memdump_buf_len) {
  		mutex_unlock(&dev->dump_mutex);
  		goto skip_memdump;
-@@ -1993,6 +1990,9 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2032,6 +2029,9 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	buf_len = crash_data->memdump_buf_len;
  
  	/* dumping memory content... */
@@ -475,7 +474,7 @@
  	memset(buf, 0, buf_len);
  	for (i = 0; i < num; i++) {
  		if (mem_region->len > buf_len) {
-@@ -2009,6 +2009,7 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2048,6 +2048,7 @@ void mt7996_mac_dump_work(struct work_struct *work)
  		mt7996_memcpy_fromio(dev, buf, mem_region->start,
  				     mem_region->len);
  
@@ -483,7 +482,7 @@
  		hdr->start = mem_region->start;
  		hdr->len = mem_region->len;
  
-@@ -2025,8 +2026,20 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2064,8 +2065,20 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	mutex_unlock(&dev->dump_mutex);
  
  skip_memdump:
@@ -507,10 +506,10 @@
  }
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index ee1915c..2c611e7 100644
+index 8a3b9f81..475a5e18 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2458,6 +2458,8 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
+@@ -2697,6 +2697,8 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
  
  	dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
  		 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
@@ -519,7 +518,7 @@
  
  	for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
  		struct mt7996_patch_sec *sec;
-@@ -2584,6 +2586,9 @@ static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
+@@ -2823,6 +2825,9 @@ static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
  	}
  
  	hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
@@ -530,10 +529,10 @@
  		 fw_type, hdr->fw_ver, hdr->build_date);
  
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index c0ceef0..0bb20a9 100644
+index 7e5ec212..e1610d3b 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -57,6 +57,8 @@
+@@ -83,6 +83,8 @@
  #define MT7996_CRIT_TEMP		110
  #define MT7996_MAX_TEMP			120
  
@@ -542,7 +541,7 @@
  #define MT7996_RRO_MAX_SESSION		1024
  #define MT7996_RRO_WINDOW_MAX_LEN	1024
  #define MT7996_RRO_ADDR_ELEM_LEN	128
-@@ -82,6 +84,7 @@ enum mt7996_ram_type {
+@@ -126,6 +128,7 @@ enum mt7996_ram_type {
  	MT7996_RAM_TYPE_WM,
  	MT7996_RAM_TYPE_WA,
  	MT7996_RAM_TYPE_DSP,
@@ -550,7 +549,7 @@
  };
  
  enum mt7996_txq_id {
-@@ -265,9 +268,11 @@ struct mt7996_dev {
+@@ -316,9 +319,11 @@ struct mt7996_dev {
  	struct mutex dump_mutex;
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
@@ -564,10 +563,10 @@
  	struct list_head sta_rc_list;
  	struct list_head twt_list;
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index f7c99cd..bd0eb51 100644
+index cf12c5e0..4c20a67d 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -548,7 +548,8 @@ enum base_rev {
+@@ -597,7 +597,8 @@ enum offs_rev {
  
  /* FW MODE SYNC */
  #define MT_FW_ASSERT_CNT			0x02208274
@@ -577,7 +576,7 @@
  
  #define MT_SWDEF_BASE				0x00401400
  
-@@ -656,11 +657,15 @@ enum base_rev {
+@@ -714,11 +715,15 @@ enum offs_rev {
  #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR		BIT(29)
  
  /* CONN MCU EXCP CON */
@@ -592,7 +591,7 @@
 +#define MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS	GENMASK(20, 16)
  #define MT_MCU_WM_EXCP_LR_LOG			MT_MCU_WM_EXCP(0x204)
  
- #endif
+ /* CONN AFE CTL CON */
 -- 
 2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0023-mtk-wifi-mt76-mt7996-add-preamble-puncture-support-f.patch
similarity index 78%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0023-mtk-wifi-mt76-mt7996-add-preamble-puncture-support-f.patch
index 7b88df9..9e70644 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0023-mtk-wifi-mt76-mt7996-add-preamble-puncture-support-f.patch
@@ -1,8 +1,8 @@
-From ee2e6d4d137cadf56c1c102d73761f76fd97a6ea Mon Sep 17 00:00:00 2001
+From d83b800e9615b4d861fd79c5f71e26cd8d0c4141 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Fri, 22 Sep 2023 10:32:37 +0800
-Subject: [PATCH 29/98] wifi: mt76: mt7996: add preamble puncture support for
- mt7996
+Subject: [PATCH 23/23] mtk: wifi: mt76: mt7996: add preamble puncture support
+ for mt7996
 
 Add support configure preamble puncture feature through mcu commands.
 
@@ -15,10 +15,10 @@
  4 files changed, 37 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 8562ca4..6fac67b 100644
+index 84e77fa0..823b3626 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1241,6 +1241,7 @@ enum {
+@@ -1259,6 +1259,7 @@ enum {
  	MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
  	MCU_UNI_CMD_THERMAL = 0x35,
  	MCU_UNI_CMD_VOW = 0x37,
@@ -27,12 +27,12 @@
  	MCU_UNI_CMD_RRO = 0x57,
  	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 39f76a0..60af1d4 100644
+index 475a5e18..deabdb1f 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -4308,3 +4308,33 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
- 	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO),
- 				 &req, sizeof(req), false);
+@@ -4534,3 +4534,33 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ 	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ 				     MCU_WM_UNI_CMD(TXPOWER), true);
  }
 +
 +int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, bool auto_mode,
@@ -65,10 +65,10 @@
 +				 &req, sizeof(req), false);
 +}
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 376931e..296acbd 100644
+index a9ba63d1..238c4c53 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -845,6 +845,10 @@ enum {
+@@ -923,6 +923,10 @@ enum {
  	MT7996_SEC_MODE_MAX,
  };
  
@@ -80,10 +80,10 @@
  #define MT7996_PATCH_SCRAMBLE_KEY	GENMASK(15, 8)
  #define MT7996_PATCH_AES_KEY		GENMASK(7, 0)
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 31fa2b5..c4d74a0 100644
+index e1610d3b..4176e51a 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -598,6 +598,8 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
+@@ -654,6 +654,8 @@ int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif
  int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
  				     struct ieee80211_vif *vif,
  				     struct ieee80211_sta *sta);
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-mt7996-add-kite-pci-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-mt7996-add-kite-pci-support.patch
deleted file mode 100644
index d3c12af..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-mt7996-add-kite-pci-support.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 140d3c7139e37efcdc097b1b23be635da683e773 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Mon, 22 May 2023 09:30:28 +0800
-Subject: [PATCH 24/98] wifi: mt76: mt7996: add kite pci support
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt76_connac.h | 5 +++++
- mt7996/mmio.c | 1 +
- mt7996/pci.c  | 8 ++++++--
- 3 files changed, 12 insertions(+), 2 deletions(-)
-
-diff --git a/mt76_connac.h b/mt76_connac.h
-index c6726ab..b1ec8d4 100644
---- a/mt76_connac.h
-+++ b/mt76_connac.h
-@@ -222,6 +222,11 @@ static inline bool is_mt7996(struct mt76_dev *dev)
- 	return mt76_chip(dev) == 0x7990;
- }
- 
-+static inline bool is_mt7992(struct mt76_dev *dev)
-+{
-+	return mt76_chip(dev) == 0x7992;
-+}
-+
- static inline bool is_mt7622(struct mt76_dev *dev)
- {
- 	if (!IS_ENABLED(CONFIG_MT7622_WMAC))
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index ab088a2..567f930 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -369,6 +369,7 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
- 
- 	switch (device_id) {
- 	case 0x7990:
-+	case 0x7992:
- 		dev->reg.base = mt7996_reg_base;
- 		dev->reg.map = mt7996_reg_map;
- 		dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index 92869ca..e8edf77 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -17,11 +17,13 @@ static u32 hif_idx;
- 
- static const struct pci_device_id mt7996_pci_device_table[] = {
- 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7990) },
-+	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7992) },
- 	{ },
- };
- 
- static const struct pci_device_id mt7996_hif_device_table[] = {
- 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7991) },
-+	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x799a) },
- 	{ },
- };
- 
-@@ -60,7 +62,9 @@ static void mt7996_put_hif2(struct mt7996_hif *hif)
- static struct mt7996_hif *mt7996_pci_init_hif2(struct pci_dev *pdev)
- {
- 	hif_idx++;
--	if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL))
-+
-+	if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL) &&
-+	    !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x799a, NULL))
- 		return NULL;
- 
- 	writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
-@@ -113,7 +117,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 
- 	mt76_pci_disable_aspm(pdev);
- 
--	if (id->device == 0x7991)
-+	if (id->device == 0x7991 || id->device == 0x799a)
- 		return mt7996_pci_hif2_probe(pdev);
- 
- 	dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0025-wifi-mt76-mt7996-add-kite-wtbl-size-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0025-wifi-mt76-mt7996-add-kite-wtbl-size-support.patch
deleted file mode 100644
index 7ce6401..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0025-wifi-mt76-mt7996-add-kite-wtbl-size-support.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 12f123f46ccce46990ce98d05a3a9db3b20b5459 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Wed, 14 Jun 2023 17:47:11 +0800
-Subject: [PATCH 25/98] wifi: mt76: mt7996: add kite wtbl size support
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/eeprom.c | 3 ++-
- mt7996/mt7996.h | 6 ++++--
- 2 files changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 9db7e53..ca0e9d0 100644
---- a/mt7996/eeprom.c
-+++ b/mt7996/eeprom.c
-@@ -103,7 +103,8 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
- 		dev->wtbl_size_group = u32_get_bits(cap, WTBL_SIZE_GROUP);
- 	}
- 
--	if (dev->wtbl_size_group < 2 || dev->wtbl_size_group > 4)
-+	if (dev->wtbl_size_group < 2 || dev->wtbl_size_group > 4 ||
-+	    is_mt7992(&dev->mt76))
- 		dev->wtbl_size_group = 2; /* set default */
- 
- 	return 0;
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index f268773..6a31819 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -13,6 +13,7 @@
- 
- #define MT7996_MAX_INTERFACES		19	/* per-band */
- #define MT7996_MAX_WMM_SETS		4
-+#define MT7996_WTBL_EXTEND_SIZE		(is_mt7992(&dev->mt76) ? 32 : 64)
- #define MT7996_WTBL_RESERVED		(mt7996_wtbl_size(dev) - 1)
- #define MT7996_WTBL_STA			(MT7996_WTBL_RESERVED - \
- 					 mt7996_max_interface_num(dev))
-@@ -497,12 +498,13 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
- 
- static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
- {
--	return MT7996_MAX_INTERFACES * (1 + dev->dbdc_support + dev->tbtc_support);
-+	return min(MT7996_MAX_INTERFACES * (1 + dev->dbdc_support + dev->tbtc_support),
-+		   MT7996_WTBL_EXTEND_SIZE);
- }
- 
- static inline u16 mt7996_wtbl_size(struct mt7996_dev *dev)
- {
--	return (dev->wtbl_size_group << 8) + 64;
-+	return (dev->wtbl_size_group << 8) + MT7996_WTBL_EXTEND_SIZE;
- }
- 
- void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-accommodate-MT7992-with-different-c.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-accommodate-MT7992-with-different-c.patch
deleted file mode 100644
index d494783..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-accommodate-MT7992-with-different-c.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From f364ba42a956ba321876c2ac3798811cd8ea88f3 Mon Sep 17 00:00:00 2001
-From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
-Date: Wed, 7 Jun 2023 10:21:09 +0800
-Subject: [PATCH 26/98] wifi: mt76: mt7996: accommodate MT7992 with different
- capability
-
-Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
----
- mt7996/mt7996.h | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 6a31819..31fa2b5 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -390,6 +390,9 @@ mt7996_phy3(struct mt7996_dev *dev)
- static inline bool
- mt7996_band_valid(struct mt7996_dev *dev, u8 band)
- {
-+	if (is_mt7992(&dev->mt76))
-+		return band <= MT_BAND1;
-+
- 	/* tri-band support */
- 	if (band <= MT_BAND2 &&
- 	    mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1)
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-add-AFE-pll-enable-before-driver-ow.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-add-AFE-pll-enable-before-driver-ow.patch
deleted file mode 100644
index 3f5cfe7..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-add-AFE-pll-enable-before-driver-ow.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 41ae938fe5d3df6b40e2b1cd5baaf8ea59bd2c46 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Wed, 12 Jul 2023 23:00:29 +0800
-Subject: [PATCH 27/98] wifi: mt76: mt7996: add AFE pll enable before driver
- own
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
----
- mt7996/init.c | 4 ++++
- mt7996/regs.h | 7 +++++++
- 2 files changed, 11 insertions(+)
-
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 3656b89..273d1e7 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -782,6 +782,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
- 	int ret, idx;
- 
- 	mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
-+	if (is_mt7992(&dev->mt76)) {
-+		mt76_rmw(dev, MT_AFE_CTL_BAND_PLL_03(MT_BAND0), MT_AFE_CTL_BAND_PLL_03_MSB_EN, 0);
-+		mt76_rmw(dev, MT_AFE_CTL_BAND_PLL_03(MT_BAND1), MT_AFE_CTL_BAND_PLL_03_MSB_EN, 0);
-+	}
- 
- 	INIT_WORK(&dev->init_work, mt7996_init_work);
- 
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 865e005..e76dae6 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -675,4 +675,11 @@ enum base_rev {
- #define MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS	GENMASK(20, 16)
- #define MT_MCU_WM_EXCP_LR_LOG			MT_MCU_WM_EXCP(0x204)
- 
-+/* CONN AFE CTL CON */
-+#define MT_AFE_CTL_BASE				0x18043000
-+#define MT_AFE_CTL_BAND(_band, ofs)		(MT_AFE_CTL_BASE + \
-+						 ((_band) * 0x1000) + (ofs))
-+#define MT_AFE_CTL_BAND_PLL_03(_band)		MT_AFE_CTL_BAND(_band, 0x2c)
-+#define MT_AFE_CTL_BAND_PLL_03_MSB_EN		BIT(1)
-+
- #endif
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-kite-eagle-CR-offset-revision.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-kite-eagle-CR-offset-revision.patch
deleted file mode 100644
index 9d0f02b..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-kite-eagle-CR-offset-revision.patch
+++ /dev/null
@@ -1,232 +0,0 @@
-From df9f668cf78a4c8dbc505f5fc0fb27a14e94f4c1 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 14 Jul 2023 17:29:35 +0800
-Subject: [PATCH 28/98] wifi: mt76: mt7996: add kite & eagle CR offset revision
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/mmio.c | 58 +++++++++++++++++++++++++++++++++++++++
- mt7996/regs.h | 76 +++++++++++++++++++++++++++++++++++----------------
- 2 files changed, 111 insertions(+), 23 deletions(-)
-
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 567f930..2132b2e 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -28,6 +28,58 @@ static const struct __base mt7996_reg_base[] = {
- 	[WF_RATE_BASE]		= { { 0x820ee000, 0x820fe000, 0x830ee000 } },
- };
- 
-+static const u32 mt7996_offs[] = {
-+	[MIB_RVSR0]		= 0x720,
-+	[MIB_RVSR1]		= 0x724,
-+	[MIB_BTSCR5]		= 0x788,
-+	[MIB_BTSCR6]		= 0x798,
-+	[MIB_RSCR1]		= 0x7ac,
-+	[MIB_RSCR27]		= 0x954,
-+	[MIB_RSCR28]		= 0x958,
-+	[MIB_RSCR29]		= 0x95c,
-+	[MIB_RSCR30]		= 0x960,
-+	[MIB_RSCR31]		= 0x964,
-+	[MIB_RSCR33]		= 0x96c,
-+	[MIB_RSCR35]		= 0x974,
-+	[MIB_RSCR36]		= 0x978,
-+	[MIB_BSCR0]		= 0x9cc,
-+	[MIB_BSCR1]		= 0x9d0,
-+	[MIB_BSCR2]		= 0x9d4,
-+	[MIB_BSCR3]		= 0x9d8,
-+	[MIB_BSCR4]		= 0x9dc,
-+	[MIB_BSCR5]		= 0x9e0,
-+	[MIB_BSCR6]		= 0x9e4,
-+	[MIB_BSCR7]		= 0x9e8,
-+	[MIB_BSCR17]		= 0xa10,
-+	[MIB_TRDR1]		= 0xa28,
-+};
-+
-+static const u32 mt7992_offs[] = {
-+	[MIB_RVSR0]		= 0x760,
-+	[MIB_RVSR1]		= 0x764,
-+	[MIB_BTSCR5]		= 0x7c8,
-+	[MIB_BTSCR6]		= 0x7d8,
-+	[MIB_RSCR1]		= 0x7f0,
-+	[MIB_RSCR27]		= 0x998,
-+	[MIB_RSCR28]		= 0x99c,
-+	[MIB_RSCR29]		= 0x9a0,
-+	[MIB_RSCR30]		= 0x9a4,
-+	[MIB_RSCR31]		= 0x9a8,
-+	[MIB_RSCR33]		= 0x9b0,
-+	[MIB_RSCR35]		= 0x9b8,
-+	[MIB_RSCR36]		= 0x9bc,
-+	[MIB_BSCR0]		= 0xac8,
-+	[MIB_BSCR1]		= 0xacc,
-+	[MIB_BSCR2]		= 0xad0,
-+	[MIB_BSCR3]		= 0xad4,
-+	[MIB_BSCR4]		= 0xad8,
-+	[MIB_BSCR5]		= 0xadc,
-+	[MIB_BSCR6]		= 0xae0,
-+	[MIB_BSCR7]		= 0xae4,
-+	[MIB_BSCR17]		= 0xb0c,
-+	[MIB_TRDR1]		= 0xb24,
-+};
-+
- static const struct __map mt7996_reg_map[] = {
- 	{ 0x54000000, 0x02000, 0x1000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */
- 	{ 0x55000000, 0x03000, 0x1000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */
-@@ -369,8 +421,14 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
- 
- 	switch (device_id) {
- 	case 0x7990:
-+		dev->reg.base = mt7996_reg_base;
-+		dev->reg.offs_rev = mt7996_offs;
-+		dev->reg.map = mt7996_reg_map;
-+		dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
-+		break;
- 	case 0x7992:
- 		dev->reg.base = mt7996_reg_base;
-+		dev->reg.offs_rev = mt7992_offs;
- 		dev->reg.map = mt7996_reg_map;
- 		dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
- 		break;
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index e76dae6..de5df91 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -19,6 +19,7 @@ struct __base {
- /* used to differentiate between generations */
- struct mt7996_reg_desc {
- 	const struct __base *base;
-+	const u32 *offs_rev;
- 	const struct __map *map;
- 	u32 map_size;
- };
-@@ -39,6 +40,35 @@ enum base_rev {
- 
- #define __BASE(_id, _band)			(dev->reg.base[(_id)].band_base[(_band)])
- 
-+enum offs_rev {
-+	MIB_RVSR0,
-+	MIB_RVSR1,
-+	MIB_BTSCR5,
-+	MIB_BTSCR6,
-+	MIB_RSCR1,
-+	MIB_RSCR27,
-+	MIB_RSCR28,
-+	MIB_RSCR29,
-+	MIB_RSCR30,
-+	MIB_RSCR31,
-+	MIB_RSCR33,
-+	MIB_RSCR35,
-+	MIB_RSCR36,
-+	MIB_BSCR0,
-+	MIB_BSCR1,
-+	MIB_BSCR2,
-+	MIB_BSCR3,
-+	MIB_BSCR4,
-+	MIB_BSCR5,
-+	MIB_BSCR6,
-+	MIB_BSCR7,
-+	MIB_BSCR17,
-+	MIB_TRDR1,
-+	__MT_OFFS_MAX,
-+};
-+
-+#define __OFFS(id)			(dev->reg.offs_rev[(id)])
-+
- /* RRO TOP */
- #define MT_RRO_TOP_BASE				0xA000
- #define MT_RRO_TOP(ofs)				(MT_RRO_TOP_BASE + (ofs))
-@@ -172,32 +202,32 @@ enum base_rev {
- #define MT_WF_MIB_BASE(_band)			__BASE(WF_MIB_BASE, (_band))
- #define MT_WF_MIB(_band, ofs)			(MT_WF_MIB_BASE(_band) + (ofs))
- 
--#define MT_MIB_BSCR0(_band)			MT_WF_MIB(_band, 0x9cc)
--#define MT_MIB_BSCR1(_band)			MT_WF_MIB(_band, 0x9d0)
--#define MT_MIB_BSCR2(_band)			MT_WF_MIB(_band, 0x9d4)
--#define MT_MIB_BSCR3(_band)			MT_WF_MIB(_band, 0x9d8)
--#define MT_MIB_BSCR4(_band)			MT_WF_MIB(_band, 0x9dc)
--#define MT_MIB_BSCR5(_band)			MT_WF_MIB(_band, 0x9e0)
--#define MT_MIB_BSCR6(_band)			MT_WF_MIB(_band, 0x9e4)
--#define MT_MIB_BSCR7(_band)			MT_WF_MIB(_band, 0x9e8)
--#define MT_MIB_BSCR17(_band)			MT_WF_MIB(_band, 0xa10)
-+#define MT_MIB_BSCR0(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR0))
-+#define MT_MIB_BSCR1(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR1))
-+#define MT_MIB_BSCR2(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR2))
-+#define MT_MIB_BSCR3(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR3))
-+#define MT_MIB_BSCR4(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR4))
-+#define MT_MIB_BSCR5(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR5))
-+#define MT_MIB_BSCR6(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR6))
-+#define MT_MIB_BSCR7(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR7))
-+#define MT_MIB_BSCR17(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR17))
- 
- #define MT_MIB_TSCR5(_band)			MT_WF_MIB(_band, 0x6c4)
- #define MT_MIB_TSCR6(_band)			MT_WF_MIB(_band, 0x6c8)
- #define MT_MIB_TSCR7(_band)			MT_WF_MIB(_band, 0x6d0)
- 
--#define MT_MIB_RSCR1(_band)			MT_WF_MIB(_band, 0x7ac)
-+#define MT_MIB_RSCR1(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR1))
- /* rx mpdu counter, full 32 bits */
--#define MT_MIB_RSCR31(_band)			MT_WF_MIB(_band, 0x964)
--#define MT_MIB_RSCR33(_band)			MT_WF_MIB(_band, 0x96c)
-+#define MT_MIB_RSCR31(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR31))
-+#define MT_MIB_RSCR33(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR33))
- 
- #define MT_MIB_SDR6(_band)			MT_WF_MIB(_band, 0x020)
- #define MT_MIB_SDR6_CHANNEL_IDL_CNT_MASK	GENMASK(15, 0)
- 
--#define MT_MIB_RVSR0(_band)			MT_WF_MIB(_band, 0x720)
-+#define MT_MIB_RVSR0(_band)			MT_WF_MIB(_band, __OFFS(MIB_RVSR0))
- 
--#define MT_MIB_RSCR35(_band)			MT_WF_MIB(_band, 0x974)
--#define MT_MIB_RSCR36(_band)			MT_WF_MIB(_band, 0x978)
-+#define MT_MIB_RSCR35(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR35))
-+#define MT_MIB_RSCR36(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR36))
- 
- /* tx ampdu cnt, full 32 bits */
- #define MT_MIB_TSCR0(_band)			MT_WF_MIB(_band, 0x6b0)
-@@ -210,16 +240,16 @@ enum base_rev {
- #define MT_MIB_TSCR4(_band)			MT_WF_MIB(_band, 0x6c0)
- 
- /* rx ampdu count, 32-bit */
--#define MT_MIB_RSCR27(_band)			MT_WF_MIB(_band, 0x954)
-+#define MT_MIB_RSCR27(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR27))
- 
- /* rx ampdu bytes count, 32-bit */
--#define MT_MIB_RSCR28(_band)			MT_WF_MIB(_band, 0x958)
-+#define MT_MIB_RSCR28(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR28))
- 
- /* rx ampdu valid subframe count */
--#define MT_MIB_RSCR29(_band)			MT_WF_MIB(_band, 0x95c)
-+#define MT_MIB_RSCR29(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR29))
- 
- /* rx ampdu valid subframe bytes count, 32bits */
--#define MT_MIB_RSCR30(_band)			MT_WF_MIB(_band, 0x960)
-+#define MT_MIB_RSCR30(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR30))
- 
- /* remaining windows protected stats */
- #define MT_MIB_SDR27(_band)			MT_WF_MIB(_band, 0x080)
-@@ -228,18 +258,18 @@ enum base_rev {
- #define MT_MIB_SDR28(_band)			MT_WF_MIB(_band, 0x084)
- #define MT_MIB_SDR28_TX_RWP_NEED_CNT		GENMASK(15, 0)
- 
--#define MT_MIB_RVSR1(_band)			MT_WF_MIB(_band, 0x724)
-+#define MT_MIB_RVSR1(_band)			MT_WF_MIB(_band, __OFFS(MIB_RVSR1))
- 
- /* rx blockack count, 32 bits */
- #define MT_MIB_TSCR1(_band)			MT_WF_MIB(_band, 0x6b4)
- 
- #define MT_MIB_BTSCR0(_band)			MT_WF_MIB(_band, 0x5e0)
--#define MT_MIB_BTSCR5(_band)			MT_WF_MIB(_band, 0x788)
--#define MT_MIB_BTSCR6(_band)			MT_WF_MIB(_band, 0x798)
-+#define MT_MIB_BTSCR5(_band)			MT_WF_MIB(_band, __OFFS(MIB_BTSCR5))
-+#define MT_MIB_BTSCR6(_band)			MT_WF_MIB(_band, __OFFS(MIB_BTSCR6))
- 
- #define MT_MIB_BFTFCR(_band)			MT_WF_MIB(_band, 0x5d0)
- 
--#define MT_TX_AGG_CNT(_band, n)			MT_WF_MIB(_band, 0xa28 + ((n) << 2))
-+#define MT_TX_AGG_CNT(_band, n)			MT_WF_MIB(_band, __OFFS(MIB_TRDR1) + ((n) << 2))
- #define MT_MIB_ARNG(_band, n)			MT_WF_MIB(_band, 0x0b0 + ((n) << 2))
- #define MT_MIB_ARNCR_RANGE(val, n)		(((val) >> ((n) << 4)) & GENMASK(9, 0))
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0030-wifi-mt76-mt7996-fix-all-sta-info-struct-alignment.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0030-wifi-mt76-mt7996-fix-all-sta-info-struct-alignment.patch
deleted file mode 100644
index 0789ad2..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0030-wifi-mt76-mt7996-fix-all-sta-info-struct-alignment.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From b1d7c2518edfcf9fe96a0231132449c2f924d1d6 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 6 Oct 2023 16:39:39 +0800
-Subject: [PATCH 30/98] wifi: mt76: mt7996: fix all sta info struct alignment
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/mcu.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 296acbd..af7cd18 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -219,7 +219,7 @@ struct mt7996_mcu_all_sta_info_event {
-         u8 more;
-         u8 rsv2;
-         __le16 sta_num;
--        u8 rsv3[2];
-+        u8 rsv3[4];
- 
- 	union {
- 		struct all_sta_trx_rate rate[0];
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-refine-ampdu-factor.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-refine-ampdu-factor.patch
deleted file mode 100644
index 8e716a0..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-refine-ampdu-factor.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From 274d96dc00990390f4e830452d9032471deacf33 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Fri, 6 Oct 2023 11:44:03 +0800
-Subject: [PATCH 31/98] wifi: mt76: mt7996: refine ampdu factor
-
-Firmware would parse ht/vht/he/eht cap to get correct ampdu parameters.
----
- mt76_connac_mcu.h |  4 +++-
- mt7996/mcu.c      | 44 ++++----------------------------------------
- mt7996/mcu.h      |  1 -
- 3 files changed, 7 insertions(+), 42 deletions(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 6fac67b..ca2e573 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -298,7 +298,9 @@ struct sta_rec_ht {
- 	__le16 tag;
- 	__le16 len;
- 	__le16 ht_cap;
--	u16 rsv;
-+	__le16 ht_cap_ext;
-+	u8 ampdu_param;
-+	u8 _rsv[3];
- } __packed;
- 
- struct sta_rec_vht {
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 60af1d4..8b81644 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -1195,6 +1195,10 @@ mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
- 
- 	ht = (struct sta_rec_ht *)tlv;
- 	ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap);
-+	ht->ampdu_param = u8_encode_bits(sta->deflink.ht_cap.ampdu_factor,
-+					 IEEE80211_HT_AMPDU_PARM_FACTOR) |
-+			  u8_encode_bits(sta->deflink.ht_cap.ampdu_density,
-+					 IEEE80211_HT_AMPDU_PARM_DENSITY);
- }
- 
- static void
-@@ -1651,44 +1655,6 @@ mt7996_mcu_sta_bfee_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
- 	bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);
- }
- 
--static void
--mt7996_mcu_sta_phy_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
--		       struct ieee80211_vif *vif, struct ieee80211_sta *sta)
--{
--	struct sta_rec_phy *phy;
--	struct tlv *tlv;
--	u8 af = 0, mm = 0;
--
--	if (!sta->deflink.ht_cap.ht_supported && !sta->deflink.he_6ghz_capa.capa)
--		return;
--
--	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
--
--	phy = (struct sta_rec_phy *)tlv;
--	if (sta->deflink.ht_cap.ht_supported) {
--		af = sta->deflink.ht_cap.ampdu_factor;
--		mm = sta->deflink.ht_cap.ampdu_density;
--	}
--
--	if (sta->deflink.vht_cap.vht_supported) {
--		u8 vht_af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
--				      sta->deflink.vht_cap.cap);
--
--		af = max_t(u8, af, vht_af);
--	}
--
--	if (sta->deflink.he_6ghz_capa.capa) {
--		af = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
--				   IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
--		mm = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
--				   IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
--	}
--
--	phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR, af) |
--		     FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, mm);
--	phy->max_ampdu_len = af;
--}
--
- static void
- mt7996_mcu_sta_hdrt_tlv(struct mt7996_dev *dev, struct sk_buff *skb)
- {
-@@ -2100,8 +2066,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- 
- 	/* tag order is in accordance with firmware dependency. */
- 	if (sta) {
--		/* starec phy */
--		mt7996_mcu_sta_phy_tlv(dev, skb, vif, sta);
- 		/* starec hdrt mode */
- 		mt7996_mcu_sta_hdrt_tlv(dev, skb);
- 		/* starec bfer */
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index af7cd18..ca16336 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -730,7 +730,6 @@ enum {
- 					 sizeof(struct sta_rec_uapsd) + 	\
- 					 sizeof(struct sta_rec_amsdu) +		\
- 					 sizeof(struct sta_rec_bfee) +		\
--					 sizeof(struct sta_rec_phy) +		\
- 					 sizeof(struct sta_rec_ra_uni) +	\
- 					 sizeof(struct sta_rec_sec) +		\
- 					 sizeof(struct sta_rec_ra_fixed_uni) +	\
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0999-wifi-mt76-mt7996-for-build-pass.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0999-mtk-wifi-mt76-mt7996-for-build-pass.patch
similarity index 82%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0999-wifi-mt76-mt7996-for-build-pass.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0999-mtk-wifi-mt76-mt7996-for-build-pass.patch
index 48ca34e..f414f45 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0999-wifi-mt76-mt7996-for-build-pass.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0999-mtk-wifi-mt76-mt7996-for-build-pass.patch
@@ -1,9 +1,8 @@
-From fd11038a011cf006ee347a48d880c38a2ad20c75 Mon Sep 17 00:00:00 2001
+From bb8cbd2687b9601b8970cb9be1cfd356f285997e Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 3 Nov 2022 00:27:17 +0800
-Subject: [PATCH 32/98] wifi: mt76: mt7996: for build pass
+Subject: [PATCH 0999/1041] mtk: wifi: mt76: mt7996: for build pass
 
-Change-Id: Ieb44c33ee6e6a2e6058c1ef528404c1a1cbcfdaf
 ---
  debugfs.c         | 3 +++
  dma.c             | 2 +-
@@ -18,7 +17,7 @@
  10 files changed, 19 insertions(+), 4 deletions(-)
 
 diff --git a/debugfs.c b/debugfs.c
-index c4649ba..ac5207e 100644
+index c4649ba0..ac5207e5 100644
 --- a/debugfs.c
 +++ b/debugfs.c
 @@ -33,8 +33,11 @@ mt76_napi_threaded_set(void *data, u64 val)
@@ -34,10 +33,10 @@
  	return 0;
  }
 diff --git a/dma.c b/dma.c
-index dd20271..bb995e2 100644
+index 00230f10..12f0e2fd 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -943,7 +943,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -960,7 +960,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		    !(dev->drv->rx_check(dev, data, len)))
  			goto free_frag;
  
@@ -47,10 +46,10 @@
  			goto free_frag;
  
 diff --git a/eeprom.c b/eeprom.c
-index 2558788..a07ca84 100644
+index 0bc66cc1..7d5cf28f 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -161,9 +161,15 @@ void
+@@ -163,9 +163,15 @@ void
  mt76_eeprom_override(struct mt76_phy *phy)
  {
  	struct mt76_dev *dev = phy->dev;
@@ -68,7 +67,7 @@
  	if (!is_valid_ether_addr(phy->macaddr)) {
  		eth_random_addr(phy->macaddr);
 diff --git a/mcu.c b/mcu.c
-index a8cafa3..fa4b054 100644
+index a8cafa39..fa4b0544 100644
 --- a/mcu.c
 +++ b/mcu.c
 @@ -4,6 +4,7 @@
@@ -80,7 +79,7 @@
  struct sk_buff *
  __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data,
 diff --git a/mt7615/mcu.c b/mt7615/mcu.c
-index 955974a..db337aa 100644
+index ae34d019..c9444c6d 100644
 --- a/mt7615/mcu.c
 +++ b/mt7615/mcu.c
 @@ -10,6 +10,7 @@
@@ -92,7 +91,7 @@
  static bool prefer_offload_fw = true;
  module_param(prefer_offload_fw, bool, 0644);
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index bb570f2..236cfea 100644
+index 8dd61f86..52237583 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -4,6 +4,7 @@
@@ -104,7 +103,7 @@
  int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
  {
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index b6fba1a..dee01e0 100644
+index 09badb16..2718ba52 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -6,6 +6,7 @@
@@ -116,10 +115,10 @@
  #define fw_name(_dev, name, ...)	({			\
  	char *_fw;						\
 diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 1ed91da..23f6f16 100644
+index 483ad81b..8e29ab06 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -602,8 +602,8 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -640,8 +640,8 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  	if (ret < 0)
  		return ret;
  
@@ -131,10 +130,10 @@
  
  	mt7996_dma_enable(dev, false);
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index ca0e9d0..7ae92e1 100644
+index c8fa87ef..7d07c1b1 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -98,6 +98,7 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
+@@ -135,6 +135,7 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -143,7 +142,7 @@
  		dev->has_eht = !(cap & MODE_HE_ONLY);
  		dev->wtbl_size_group = u32_get_bits(cap, WTBL_SIZE_GROUP);
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 8b81644..fdc4fb4 100644
+index deabdb1f..3ecdde86 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -5,6 +5,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1000-mtk-wifi-mt76-mt7996-add-debug-tool.patch
similarity index 93%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1000-mtk-wifi-mt76-mt7996-add-debug-tool.patch
index d29a90b..033ca0b 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1000-mtk-wifi-mt76-mt7996-add-debug-tool.patch
@@ -1,29 +1,71 @@
-From 393f2e0f06e9a6ead8ffd64c904b6e24ff6c92f1 Mon Sep 17 00:00:00 2001
+From a4b26d99f6d02c2b4e7ebff9a07acbdd7ec5185b Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Fri, 24 Mar 2023 14:02:32 +0800
-Subject: [PATCH 33/98] wifi: mt76: mt7996: add debug tool
+Subject: [PATCH 1000/1041] mtk: wifi: mt76: mt7996: add debug tool
 
-Change-Id: Ie10390b01f17db893dbfbf3221bf63a4bd1fe38f
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Add PSM bit in sta_info
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+
+Remove the duplicate function in mtk_debugfs.c & mtk_debug_i.c
+Only enable mt7996_mcu_fw_log_2_host function in mcu.c
+
+Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
+
+Support more ids category NDPA/NDP TXD/FBK and debug log recommended by
+CTD members.
+
+This commit equals to run the follwoing commands on Logan driver:
+command:
+1. iwpriv ra0 set fw_dbg=1:84
+2. iwpriv ra0 set fw_dbg=2:84
+3. iwpriv ra0 set fw_dbg=1:101
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+
+mtk: wifi: mt76: mt7996: add wtbl_info support for mt7992
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+mtk: wifi: mt76: mt7996: add mt7992 & mt7996 CR debug offset revision
+
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
+ mt76.h               |    2 +
  mt7996/Makefile      |    4 +
  mt7996/coredump.c    |   10 +-
  mt7996/coredump.h    |    7 +
- mt7996/debugfs.c     |   34 +-
- mt7996/mt7996.h      |   10 +
- mt7996/mtk_debug.h   | 2147 ++++++++++++++++++++++++++++++++++++++
- mt7996/mtk_debugfs.c | 2379 ++++++++++++++++++++++++++++++++++++++++++
+ mt7996/debugfs.c     |   66 +-
+ mt7996/mac.c         |    3 +
+ mt7996/mt7996.h      |   11 +
+ mt7996/mtk_debug.h   | 2286 ++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_debugfs.c | 2484 ++++++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.c     |   18 +
  mt7996/mtk_mcu.h     |   16 +
  tools/fwlog.c        |   25 +-
- 10 files changed, 4630 insertions(+), 20 deletions(-)
+ 12 files changed, 4907 insertions(+), 25 deletions(-)
  create mode 100644 mt7996/mtk_debug.h
  create mode 100644 mt7996/mtk_debugfs.c
  create mode 100644 mt7996/mtk_mcu.c
  create mode 100644 mt7996/mtk_mcu.h
 
+diff --git a/mt76.h b/mt76.h
+index d2ead585..de0021e4 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -393,6 +393,8 @@ struct mt76_txwi_cache {
+ 		struct sk_buff *skb;
+ 		void *ptr;
+ 	};
++
++	unsigned long jiffies;
+ };
+ 
+ struct mt76_rx_tid {
 diff --git a/mt7996/Makefile b/mt7996/Makefile
-index 07c8b55..a056b40 100644
+index 07c8b555..a056b40e 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
 @@ -1,4 +1,6 @@
@@ -40,7 +82,7 @@
 +
 +mt7996e-y += mtk_debugfs.o mtk_mcu.o
 diff --git a/mt7996/coredump.c b/mt7996/coredump.c
-index 60b8808..a7f91b5 100644
+index 60b88085..a7f91b56 100644
 --- a/mt7996/coredump.c
 +++ b/mt7996/coredump.c
 @@ -195,7 +195,7 @@ mt7996_coredump_fw_stack(struct mt7996_dev *dev, u8 type, struct mt7996_coredump
@@ -89,7 +131,7 @@
  		dev_warn(dev->mt76.dev, "no crash dump data found\n");
  		return -ENODATA;
 diff --git a/mt7996/coredump.h b/mt7996/coredump.h
-index 01ed373..93cd84a 100644
+index 01ed3731..93cd84a0 100644
 --- a/mt7996/coredump.h
 +++ b/mt7996/coredump.h
 @@ -75,6 +75,7 @@ struct mt7996_mem_region {
@@ -114,22 +156,42 @@
  mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type)
  {
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 9bd9535..92aa164 100644
+index 9bd95358..c4b82cb2 100644
 --- a/mt7996/debugfs.c
 +++ b/mt7996/debugfs.c
-@@ -290,11 +290,20 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
+@@ -290,11 +290,39 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
  		DEBUG_SPL,
  		DEBUG_RPT_RX,
  		DEBUG_RPT_RA = 68,
+-	} debug;
++		DEBUG_IDS_SND = 84,
 +		DEBUG_IDS_PP = 93,
 +		DEBUG_IDS_RA = 94,
 +		DEBUG_IDS_BF = 95,
 +		DEBUG_IDS_SR = 96,
 +		DEBUG_IDS_RU = 97,
 +		DEBUG_IDS_MUMIMO = 98,
- 	} debug;
++		DEBUG_IDS_ERR_LOG = 101,
++	};
++	u8 debug_category[] = {
++		DEBUG_TXCMD,
++		DEBUG_CMD_RPT_TX,
++		DEBUG_CMD_RPT_TRIG,
++		DEBUG_SPL,
++		DEBUG_RPT_RX,
++		DEBUG_RPT_RA,
++		DEBUG_IDS_SND,
++		DEBUG_IDS_PP,
++		DEBUG_IDS_RA,
++		DEBUG_IDS_BF,
++		DEBUG_IDS_SR,
++		DEBUG_IDS_RU,
++		DEBUG_IDS_MUMIMO,
++		DEBUG_IDS_ERR_LOG,
++	};
  	bool tx, rx, en;
  	int ret;
++	u8 i;
  
  	dev->fw_debug_wm = val ? MCU_FW_LOG_TO_HOST : 0;
 +#ifdef CONFIG_MTK_DEBUG
@@ -138,18 +200,35 @@
  
  	if (dev->fw_debug_bin)
  		val = MCU_FW_LOG_RELAY;
-@@ -309,8 +318,8 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
+@@ -309,18 +337,21 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
  	if (ret)
  		return ret;
  
 -	for (debug = DEBUG_TXCMD; debug <= DEBUG_RPT_RA; debug++) {
 -		if (debug == 67)
-+	for (debug = DEBUG_TXCMD; debug <= DEBUG_IDS_MUMIMO; debug++) {
-+		if (debug == 67 || (debug > DEBUG_RPT_RA && debug < DEBUG_IDS_PP))
- 			continue;
+-			continue;
+-
+-		if (debug == DEBUG_RPT_RX)
++	for (i = 0; i < ARRAY_SIZE(debug_category); i++) {
++		if (debug_category[i] == DEBUG_RPT_RX)
+ 			val = en && rx;
+ 		else
+ 			val = en && tx;
  
- 		if (debug == DEBUG_RPT_RX)
-@@ -401,11 +410,12 @@ mt7996_fw_debug_bin_set(void *data, u64 val)
+-		ret = mt7996_mcu_fw_dbg_ctrl(dev, debug, val);
++		ret = mt7996_mcu_fw_dbg_ctrl(dev, debug_category[i], val);
+ 		if (ret)
+ 			return ret;
++
++		if (debug_category[i] == DEBUG_IDS_SND && en) {
++			ret = mt7996_mcu_fw_dbg_ctrl(dev, debug_category[i], 2);
++			if (ret)
++				return ret;
++		}
+ 	}
+ 
+ 	return 0;
+@@ -401,11 +432,12 @@ mt7996_fw_debug_bin_set(void *data, u64 val)
  	};
  	struct mt7996_dev *dev = data;
  
@@ -165,7 +244,7 @@
  
  	dev->fw_debug_bin = val;
  
-@@ -819,6 +829,11 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
+@@ -819,6 +851,11 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
  	if (phy == &dev->phy)
  		dev->debugfs_dir = dir;
  
@@ -177,7 +256,7 @@
  	return 0;
  }
  
-@@ -831,6 +846,12 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
+@@ -831,6 +868,12 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
  	void *dest;
  
  	spin_lock_irqsave(&lock, flags);
@@ -190,7 +269,7 @@
  	dest = relay_reserve(dev->relay_fwlog, hdrlen + len + 4);
  	if (dest) {
  		*(u32 *)dest = hdrlen + len;
-@@ -863,9 +884,6 @@ void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int
+@@ -863,9 +906,6 @@ void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int
  		.msg_type = cpu_to_le16(PKT_TYPE_RX_FW_MONITOR),
  	};
  
@@ -200,11 +279,25 @@
  	hdr.serial_id = cpu_to_le16(dev->fw_debug_seq++);
  	hdr.timestamp = cpu_to_le32(mt76_rr(dev, MT_LPON_FRCR(0)));
  	hdr.len = *(__le16 *)data;
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index adbfd23f..ce6759e0 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -936,6 +936,9 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	id = mt76_token_consume(mdev, &t);
+ 	if (id < 0)
+ 		return id;
++#ifdef CONFIG_MTK_DEBUG
++	t->jiffies = jiffies;
++#endif
+ 
+ 	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+ 	memset(txwi_ptr, 0, MT_TXD_SIZE);
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index c4d74a0..8801956 100644
+index 4176e51a..34159f97 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -317,6 +317,16 @@ struct mt7996_dev {
+@@ -370,6 +370,17 @@ struct mt7996_dev {
  	spinlock_t reg_lock;
  
  	u8 wtbl_size_group;
@@ -217,16 +310,17 @@
 +		u8 fw_dbg_lv;
 +		u32 bcn_total_cnt[__MT_MAX_BAND];
 +	} dbg;
++	const struct mt7996_dbg_reg_desc *dbg_reg;
 +#endif
  };
  
  enum {
 diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
 new file mode 100644
-index 0000000..368f0bc
+index 00000000..27d8f1cb
 --- /dev/null
 +++ b/mt7996/mtk_debug.h
-@@ -0,0 +1,2147 @@
+@@ -0,0 +1,2286 @@
 +#ifndef __MTK_DEBUG_H
 +#define __MTK_DEBUG_H
 +
@@ -239,6 +333,123 @@
 +		(((_reg) & (_field##_MASK)) >> (_field##_SHIFT));	\
 +	})
 +
++#define __DBG_OFFS(id)		(dev->dbg_reg->offs_rev[(id)])
++
++enum dbg_offs_rev {
++	AGG_AALCR2,
++	AGG_AALCR3,
++	AGG_AALCR4,
++	AGG_AALCR5,
++	AGG_AALCR6,
++	AGG_AALCR7,
++	MIB_TDRCR0,
++	MIB_TDRCR1,
++	MIB_TDRCR2,
++	MIB_TDRCR3,
++	MIB_TDRCR4,
++	MIB_RSCR26,
++	MIB_TSCR18,
++	MIB_TRDR0,
++	MIB_TRDR2,
++	MIB_TRDR3,
++	MIB_TRDR4,
++	MIB_TRDR5,
++	MIB_TRDR6,
++	MIB_TRDR7,
++	MIB_TRDR8,
++	MIB_TRDR9,
++	MIB_TRDR10,
++	MIB_TRDR11,
++	MIB_TRDR12,
++	MIB_TRDR13,
++	MIB_TRDR14,
++	MIB_TRDR15,
++	MIB_MSR0,
++	MIB_MSR1,
++	MIB_MSR2,
++	MIB_MCTR5,
++	MIB_MCTR6,
++	__MT_DBG_OFFS_REV_MAX,
++};
++
++static const u32 mt7996_dbg_offs[] = {
++	[AGG_AALCR2]		= 0x128,
++	[AGG_AALCR3]		= 0x12c,
++	[AGG_AALCR4]		= 0x130,
++	[AGG_AALCR5]		= 0x134,
++	[AGG_AALCR6]		= 0x138,
++	[AGG_AALCR7]		= 0x13c,
++	[MIB_TDRCR0]		= 0x728,
++	[MIB_TDRCR1]		= 0x72c,
++	[MIB_TDRCR2]		= 0x730,
++	[MIB_TDRCR3]		= 0x734,
++	[MIB_TDRCR4]		= 0x738,
++	[MIB_RSCR26]		= 0x950,
++	[MIB_TSCR18]		= 0xa1c,
++	[MIB_TRDR0]		= 0xa24,
++	[MIB_TRDR2]		= 0xa2c,
++	[MIB_TRDR3]		= 0xa30,
++	[MIB_TRDR4]		= 0xa34,
++	[MIB_TRDR5]		= 0xa38,
++	[MIB_TRDR6]		= 0xa3c,
++	[MIB_TRDR7]		= 0xa40,
++	[MIB_TRDR8]		= 0xa44,
++	[MIB_TRDR9]		= 0xa48,
++	[MIB_TRDR10]		= 0xa4c,
++	[MIB_TRDR11]		= 0xa50,
++	[MIB_TRDR12]		= 0xa54,
++	[MIB_TRDR13]		= 0xa58,
++	[MIB_TRDR14]		= 0xa5c,
++	[MIB_TRDR15]		= 0xa60,
++	[MIB_MSR0]		= 0xa64,
++	[MIB_MSR1]		= 0xa68,
++	[MIB_MSR2]		= 0xa6c,
++	[MIB_MCTR5]		= 0xa70,
++	[MIB_MCTR6]		= 0xa74,
++};
++
++static const u32 mt7992_dbg_offs[] = {
++	[AGG_AALCR2]		= 0x12c,
++	[AGG_AALCR3]		= 0x130,
++	[AGG_AALCR4]		= 0x134,
++	[AGG_AALCR5]		= 0x138,
++	[AGG_AALCR6]		= 0x13c,
++	[AGG_AALCR7]		= 0x140,
++	[MIB_TDRCR0]		= 0x768,
++	[MIB_TDRCR1]		= 0x76c,
++	[MIB_TDRCR2]		= 0x770,
++	[MIB_TDRCR3]		= 0x774,
++	[MIB_TDRCR4]		= 0x778,
++	[MIB_RSCR26]		= 0x994,
++	[MIB_TSCR18]		= 0xb18,
++	[MIB_TRDR0]		= 0xb20,
++	[MIB_TRDR2]		= 0xb28,
++	[MIB_TRDR3]		= 0xb2c,
++	[MIB_TRDR4]		= 0xb30,
++	[MIB_TRDR5]		= 0xb34,
++	[MIB_TRDR6]		= 0xb38,
++	[MIB_TRDR7]		= 0xb3c,
++	[MIB_TRDR8]		= 0xb40,
++	[MIB_TRDR9]		= 0xb44,
++	[MIB_TRDR10]		= 0xb48,
++	[MIB_TRDR11]		= 0xb4c,
++	[MIB_TRDR12]		= 0xb50,
++	[MIB_TRDR13]		= 0xb54,
++	[MIB_TRDR14]		= 0xb58,
++	[MIB_TRDR15]		= 0xb5c,
++	[MIB_MSR0]		= 0xb60,
++	[MIB_MSR1]		= 0xb64,
++	[MIB_MSR2]		= 0xb68,
++	[MIB_MCTR5]		= 0xb6c,
++	[MIB_MCTR6]		= 0xb70,
++};
++
++/* used to differentiate between generations */
++struct mt7996_dbg_reg_desc {
++	const u32 id;
++	const u32 *offs_rev;
++};
++
 +/* AGG */
 +#define BN0_WF_AGG_TOP_BASE                                    0x820e2000
 +#define BN1_WF_AGG_TOP_BASE                                    0x820f2000
@@ -309,12 +520,12 @@
 +#define BN0_WF_AGG_TOP_TFCR_ADDR                               (BN0_WF_AGG_TOP_BASE + 0x114) // 2114
 +#define BN0_WF_AGG_TOP_MUCR0_ADDR                              (BN0_WF_AGG_TOP_BASE + 0x118) // 2118
 +#define BN0_WF_AGG_TOP_MUCR1_ADDR                              (BN0_WF_AGG_TOP_BASE + 0x11c) // 211C
-+#define BN0_WF_AGG_TOP_AALCR2_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x128) // 2128
-+#define BN0_WF_AGG_TOP_AALCR3_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x12c) // 212C
-+#define BN0_WF_AGG_TOP_AALCR4_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x130) // 2130
-+#define BN0_WF_AGG_TOP_AALCR5_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x134) // 2134
-+#define BN0_WF_AGG_TOP_AALCR6_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x138) // 2138
-+#define BN0_WF_AGG_TOP_AALCR7_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x13c) // 213C
++#define BN0_WF_AGG_TOP_AALCR2_ADDR                             (BN0_WF_AGG_TOP_BASE + __DBG_OFFS(AGG_AALCR2))
++#define BN0_WF_AGG_TOP_AALCR3_ADDR                             (BN0_WF_AGG_TOP_BASE + __DBG_OFFS(AGG_AALCR3))
++#define BN0_WF_AGG_TOP_AALCR4_ADDR                             (BN0_WF_AGG_TOP_BASE + __DBG_OFFS(AGG_AALCR4))
++#define BN0_WF_AGG_TOP_AALCR5_ADDR                             (BN0_WF_AGG_TOP_BASE + __DBG_OFFS(AGG_AALCR5))
++#define BN0_WF_AGG_TOP_AALCR6_ADDR                             (BN0_WF_AGG_TOP_BASE + __DBG_OFFS(AGG_AALCR6))
++#define BN0_WF_AGG_TOP_AALCR7_ADDR                             (BN0_WF_AGG_TOP_BASE + __DBG_OFFS(AGG_AALCR7))
 +#define BN0_WF_AGG_TOP_CSDCR0_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x150) // 2150
 +#define BN0_WF_AGG_TOP_CSDCR1_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x154) // 2154
 +#define BN0_WF_AGG_TOP_CSDCR2_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x158) // 2158
@@ -838,7 +1049,7 @@
 +#define BN0_WF_MIB_TOP_BTBCR_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x450) // D450
 +#define BN0_WF_MIB_TOP_BTDCR_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x590) // D590
 +#define BN0_WF_MIB_TOP_BTCR_ADDR                               (BN0_WF_MIB_TOP_BASE + 0x5A0) // D5A0
-+#define BN0_WF_MIB_TOP_RVSR0_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x720) // D720
++#define BN0_WF_MIB_TOP_RVSR0_ADDR                              (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_RVSR0))
 +
 +#define BN0_WF_MIB_TOP_TSCR0_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x6B0) // D6B0
 +#define BN0_WF_MIB_TOP_TSCR3_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x6BC) // D6BC
@@ -854,37 +1065,37 @@
 +#define BN0_WF_MIB_TOP_TBCR3_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x6F8) // D6F8
 +#define BN0_WF_MIB_TOP_TBCR4_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x6FC) // D6FC
 +
-+#define BN0_WF_MIB_TOP_TDRCR0_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x728) // D728
-+#define BN0_WF_MIB_TOP_TDRCR1_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x72C) // D72C
-+#define BN0_WF_MIB_TOP_TDRCR2_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x730) // D730
-+#define BN0_WF_MIB_TOP_TDRCR3_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x734) // D734
-+#define BN0_WF_MIB_TOP_TDRCR4_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x738) // D738
++#define BN0_WF_MIB_TOP_TDRCR0_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TDRCR0))
++#define BN0_WF_MIB_TOP_TDRCR1_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TDRCR1))
++#define BN0_WF_MIB_TOP_TDRCR2_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TDRCR2))
++#define BN0_WF_MIB_TOP_TDRCR3_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TDRCR3))
++#define BN0_WF_MIB_TOP_TDRCR4_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TDRCR4))
 +
 +#define BN0_WF_MIB_TOP_BTSCR0_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x5E0) // D5E0
 +#define BN0_WF_MIB_TOP_BTSCR1_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x5F0) // D5F0
 +#define BN0_WF_MIB_TOP_BTSCR2_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x600) // D600
 +#define BN0_WF_MIB_TOP_BTSCR3_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x610) // D610
 +#define BN0_WF_MIB_TOP_BTSCR4_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x620) // D620
-+#define BN0_WF_MIB_TOP_BTSCR5_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x788) // D788
-+#define BN0_WF_MIB_TOP_BTSCR6_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x798) // D798
++#define BN0_WF_MIB_TOP_BTSCR5_ADDR                             (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_BTSCR5))
++#define BN0_WF_MIB_TOP_BTSCR6_ADDR                             (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_BTSCR6))
 +
-+#define BN0_WF_MIB_TOP_RSCR1_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x7AC) // D7AC
-+#define BN0_WF_MIB_TOP_BSCR2_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9D4) // D9D4
-+#define BN0_WF_MIB_TOP_TSCR18_ADDR                             (BN0_WF_MIB_TOP_BASE + 0xA1C) // DA1C
++#define BN0_WF_MIB_TOP_RSCR1_ADDR                              (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_RSCR1))
++#define BN0_WF_MIB_TOP_BSCR2_ADDR                              (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_BSCR2))
++#define BN0_WF_MIB_TOP_TSCR18_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TSCR18))
 +
-+#define BN0_WF_MIB_TOP_MSR0_ADDR                               (BN0_WF_MIB_TOP_BASE + 0xA64) // DA64
-+#define BN0_WF_MIB_TOP_MSR1_ADDR                               (BN0_WF_MIB_TOP_BASE + 0xA68) // DA68
-+#define BN0_WF_MIB_TOP_MSR2_ADDR                               (BN0_WF_MIB_TOP_BASE + 0xA6C) // DA6C
-+#define BN0_WF_MIB_TOP_MCTR5_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA70) // DA70
-+#define BN0_WF_MIB_TOP_MCTR6_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA74) // DA74
++#define BN0_WF_MIB_TOP_MSR0_ADDR                               (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_MSR0))
++#define BN0_WF_MIB_TOP_MSR1_ADDR                               (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_MSR1))
++#define BN0_WF_MIB_TOP_MSR2_ADDR                               (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_MSR2))
++#define BN0_WF_MIB_TOP_MCTR5_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_MCTR5))
++#define BN0_WF_MIB_TOP_MCTR6_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_MCTR6))
 +
-+#define BN0_WF_MIB_TOP_RSCR26_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x950) // D950
-+#define BN0_WF_MIB_TOP_RSCR27_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x954) // D954
-+#define BN0_WF_MIB_TOP_RSCR28_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x958) // D958
-+#define BN0_WF_MIB_TOP_RSCR31_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x964) // D964
-+#define BN0_WF_MIB_TOP_RSCR33_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x96C) // D96C
-+#define BN0_WF_MIB_TOP_RSCR35_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x974) // D974
-+#define BN0_WF_MIB_TOP_RSCR36_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x978) // D978
++#define BN0_WF_MIB_TOP_RSCR26_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_RSCR26))
++#define BN0_WF_MIB_TOP_RSCR27_ADDR                             (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_RSCR27))
++#define BN0_WF_MIB_TOP_RSCR28_ADDR                             (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_RSCR28))
++#define BN0_WF_MIB_TOP_RSCR31_ADDR                             (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_RSCR31))
++#define BN0_WF_MIB_TOP_RSCR33_ADDR                             (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_RSCR33))
++#define BN0_WF_MIB_TOP_RSCR35_ADDR                             (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_RSCR35))
++#define BN0_WF_MIB_TOP_RSCR36_ADDR                             (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_RSCR36))
 +
 +#define BN0_WF_MIB_TOP_TSCR3_AMPDU_MPDU_COUNT_MASK             0xFFFFFFFF                // AMPDU_MPDU_COUNT[31..0]
 +#define BN0_WF_MIB_TOP_TSCR4_AMPDU_ACKED_COUNT_MASK            0xFFFFFFFF                // AMPDU_ACKED_COUNT[31..0]
@@ -926,22 +1137,22 @@
 +#define BN0_WF_MIB_TOP_TRARC6_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x0C8) // D0C8
 +#define BN0_WF_MIB_TOP_TRARC7_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x0CC) // D0CC
 +
-+#define BN0_WF_MIB_TOP_TRDR0_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA24) // DA24
-+#define BN0_WF_MIB_TOP_TRDR1_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA28) // DA28
-+#define BN0_WF_MIB_TOP_TRDR2_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA2C) // DA2C
-+#define BN0_WF_MIB_TOP_TRDR3_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA30) // DA30
-+#define BN0_WF_MIB_TOP_TRDR4_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA34) // DA34
-+#define BN0_WF_MIB_TOP_TRDR5_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA38) // DA38
-+#define BN0_WF_MIB_TOP_TRDR6_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA3C) // DA3C
-+#define BN0_WF_MIB_TOP_TRDR7_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA40) // DA40
-+#define BN0_WF_MIB_TOP_TRDR8_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA44) // DA44
-+#define BN0_WF_MIB_TOP_TRDR9_ADDR                              (BN0_WF_MIB_TOP_BASE + 0xA48) // DA48
-+#define BN0_WF_MIB_TOP_TRDR10_ADDR                             (BN0_WF_MIB_TOP_BASE + 0xA4C) // DA4C
-+#define BN0_WF_MIB_TOP_TRDR11_ADDR                             (BN0_WF_MIB_TOP_BASE + 0xA50) // DA50
-+#define BN0_WF_MIB_TOP_TRDR12_ADDR                             (BN0_WF_MIB_TOP_BASE + 0xA54) // DA54
-+#define BN0_WF_MIB_TOP_TRDR13_ADDR                             (BN0_WF_MIB_TOP_BASE + 0xA58) // DA58
-+#define BN0_WF_MIB_TOP_TRDR14_ADDR                             (BN0_WF_MIB_TOP_BASE + 0xA5C) // DA5C
-+#define BN0_WF_MIB_TOP_TRDR15_ADDR                             (BN0_WF_MIB_TOP_BASE + 0xA60) // DA60
++#define BN0_WF_MIB_TOP_TRDR0_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR0))
++#define BN0_WF_MIB_TOP_TRDR1_ADDR                              (BN0_WF_MIB_TOP_BASE + __OFFS(MIB_TRDR1))
++#define BN0_WF_MIB_TOP_TRDR2_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR2))
++#define BN0_WF_MIB_TOP_TRDR3_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR3))
++#define BN0_WF_MIB_TOP_TRDR4_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR4))
++#define BN0_WF_MIB_TOP_TRDR5_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR5))
++#define BN0_WF_MIB_TOP_TRDR6_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR6))
++#define BN0_WF_MIB_TOP_TRDR7_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR7))
++#define BN0_WF_MIB_TOP_TRDR8_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR8))
++#define BN0_WF_MIB_TOP_TRDR9_ADDR                              (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR9))
++#define BN0_WF_MIB_TOP_TRDR10_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR10))
++#define BN0_WF_MIB_TOP_TRDR11_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR11))
++#define BN0_WF_MIB_TOP_TRDR12_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR12))
++#define BN0_WF_MIB_TOP_TRDR13_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR13))
++#define BN0_WF_MIB_TOP_TRDR14_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR14))
++#define BN0_WF_MIB_TOP_TRDR15_ADDR                             (BN0_WF_MIB_TOP_BASE + __DBG_OFFS(MIB_TRDR15))
 +
 +#define BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_1_ADDR              BN0_WF_MIB_TOP_TRARC0_ADDR
 +#define BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_1_MASK              0x03FF0000                // AGG_RANG_SEL_1[25..16]
@@ -1063,7 +1274,7 @@
 +};
 +
 +#define LWTBL_LEN_IN_DW			36
-+#define UWTBL_LEN_IN_DW			10
++#define UWTBL_LEN_IN_DW			16
 +
 +#define MT_DBG_WTBL_BASE		0x820D8000
 +
@@ -1317,6 +1528,17 @@
 +#define WF_LWTBL_AAD_OM_MASK \
 +	0x00008000 // 15-15
 +#define WF_LWTBL_AAD_OM_SHIFT                                       15
++/* kite DW2 field bit 13-14 */
++#define WF_LWTBL_DUAL_PTEC_EN_DW                                    2
++#define WF_LWTBL_DUAL_PTEC_EN_ADDR                                  8
++#define WF_LWTBL_DUAL_PTEC_EN_MASK \
++	0x00002000 // 13-13
++#define WF_LWTBL_DUAL_PTEC_EN_SHIFT                                 13
++#define WF_LWTBL_DUAL_CTS_CAP_DW                                    2
++#define WF_LWTBL_DUAL_CTS_CAP_ADDR                                  8
++#define WF_LWTBL_DUAL_CTS_CAP_MASK \
++	0x00004000 // 14-14
++#define WF_LWTBL_DUAL_CTS_CAP_SHIFT                                 14
 +#define WF_LWTBL_CIPHER_SUIT_PGTK_DW                                2
 +#define WF_LWTBL_CIPHER_SUIT_PGTK_ADDR                              8
 +#define WF_LWTBL_CIPHER_SUIT_PGTK_MASK \
@@ -1534,6 +1756,8 @@
 +#define WF_LWTBL_AF_ADDR                                            20
 +#define WF_LWTBL_AF_MASK \
 +	0x00000007 // 2- 0
++#define WF_LWTBL_AF_MASK_7992 \
++	0x0000000f // 3- 0
 +#define WF_LWTBL_AF_SHIFT                                           0
 +#define WF_LWTBL_AF_HE_DW                                           5
 +#define WF_LWTBL_AF_HE_ADDR                                         20
@@ -1794,16 +2018,25 @@
 +#define WF_LWTBL_PRITX_SW_MODE_MASK \
 +	0x00008000 // 15-15
 +#define WF_LWTBL_PRITX_SW_MODE_SHIFT                                15
++#define WF_LWTBL_PRITX_SW_MODE_MASK_7992 \
++	0x00004000 // 14-14
++#define WF_LWTBL_PRITX_SW_MODE_SHIFT_7992                           14
 +#define WF_LWTBL_PRITX_ERSU_DW                                      9
 +#define WF_LWTBL_PRITX_ERSU_ADDR                                    36
 +#define WF_LWTBL_PRITX_ERSU_MASK \
 +	0x00010000 // 16-16
 +#define WF_LWTBL_PRITX_ERSU_SHIFT                                   16
++#define WF_LWTBL_PRITX_ERSU_MASK_7992 \
++	0x00008000 // 15-15
++#define WF_LWTBL_PRITX_ERSU_SHIFT_7992                              15
 +#define WF_LWTBL_PRITX_PLR_DW                                       9
 +#define WF_LWTBL_PRITX_PLR_ADDR                                     36
 +#define WF_LWTBL_PRITX_PLR_MASK \
 +	0x00020000 // 17-17
 +#define WF_LWTBL_PRITX_PLR_SHIFT                                    17
++#define WF_LWTBL_PRITX_PLR_MASK_7992 \
++	0x00030000 // 17-16
++#define WF_LWTBL_PRITX_PLR_SHIFT_7992                               16
 +#define WF_LWTBL_PRITX_DCM_DW                                       9
 +#define WF_LWTBL_PRITX_DCM_ADDR                                     36
 +#define WF_LWTBL_PRITX_DCM_MASK \
@@ -2376,10 +2609,10 @@
 +#endif
 diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
 new file mode 100644
-index 0000000..5aa5c94
+index 00000000..53b11d54
 --- /dev/null
 +++ b/mt7996/mtk_debugfs.c
-@@ -0,0 +1,2379 @@
+@@ -0,0 +1,2484 @@
 +// SPDX-License-Identifier: ISC
 +/*
 + * Copyright (C) 2023 MediaTek Inc.
@@ -2717,7 +2950,7 @@
 +static int mt7996_dump_version(struct seq_file *s, void *data)
 +{
 +	struct mt7996_dev *dev = dev_get_drvdata(s->private);
-+	seq_printf(s, "Version: 3.3.10.0\n");
++	seq_printf(s, "Version: 3.3.15.0\n");
 +
 +	if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
 +		return 0;
@@ -3393,7 +3626,8 @@
 +	}
 +}
 +
-+static const struct berse_wtbl_parse WTBL_LMAC_DW2[] = {
++static const struct berse_wtbl_parse *WTBL_LMAC_DW2;
++static const struct berse_wtbl_parse WTBL_LMAC_DW2_7996[] = {
 +	{"AID",                 WF_LWTBL_AID_MASK,              WF_LWTBL_AID_SHIFT,	false},
 +	{"GID_SU",              WF_LWTBL_GID_SU_MASK,           NO_SHIFT_DEFINE,	false},
 +	{"SPP_EN",              WF_LWTBL_SPP_EN_MASK,           NO_SHIFT_DEFINE,	false},
@@ -3414,6 +3648,26 @@
 +	{NULL,}
 +};
 +
++static const struct berse_wtbl_parse WTBL_LMAC_DW2_7992[] = {
++	{"AID",                 WF_LWTBL_AID_MASK,              WF_LWTBL_AID_SHIFT,	false},
++	{"GID_SU",              WF_LWTBL_GID_SU_MASK,           NO_SHIFT_DEFINE,	false},
++	{"DUAL_PTEC_EN",        WF_LWTBL_DUAL_PTEC_EN_MASK,     NO_SHIFT_DEFINE,	false},
++	{"DUAL_CTS_CAP",        WF_LWTBL_DUAL_CTS_CAP_MASK,     NO_SHIFT_DEFINE,	false},
++	{"CIPHER_PGTK",WF_LWTBL_CIPHER_SUIT_PGTK_MASK, WF_LWTBL_CIPHER_SUIT_PGTK_SHIFT,	true},
++	{"FROM_DS",             WF_LWTBL_FD_MASK,               NO_SHIFT_DEFINE,	false},
++	{"TO_DS",               WF_LWTBL_TD_MASK,               NO_SHIFT_DEFINE,	false},
++	{"SW",                  WF_LWTBL_SW_MASK,               NO_SHIFT_DEFINE,	false},
++	{"UL",                  WF_LWTBL_UL_MASK,               NO_SHIFT_DEFINE,	false},
++	{"TX_POWER_SAVE",       WF_LWTBL_TX_PS_MASK,            NO_SHIFT_DEFINE,	true},
++	{"QOS",                 WF_LWTBL_QOS_MASK,              NO_SHIFT_DEFINE,	false},
++	{"HT",                  WF_LWTBL_HT_MASK,               NO_SHIFT_DEFINE,	false},
++	{"VHT",                 WF_LWTBL_VHT_MASK,              NO_SHIFT_DEFINE,	false},
++	{"HE",                  WF_LWTBL_HE_MASK,               NO_SHIFT_DEFINE,	false},
++	{"EHT",                 WF_LWTBL_EHT_MASK,              NO_SHIFT_DEFINE,	false},
++	{"MESH",                WF_LWTBL_MESH_MASK,             NO_SHIFT_DEFINE,	true},
++	{NULL,}
++};
++
 +static void parse_fmac_lwtbl_dw2(struct seq_file *s, u8 *lwtbl)
 +{
 +	u32 *addr = 0;
@@ -3523,7 +3777,8 @@
 +	}
 +}
 +
-+static const struct berse_wtbl_parse WTBL_LMAC_DW5[] = {
++static const struct berse_wtbl_parse *WTBL_LMAC_DW5;
++static const struct berse_wtbl_parse WTBL_LMAC_DW5_7996[] = {
 +	{"AF",                  WF_LWTBL_AF_MASK,           WF_LWTBL_AF_SHIFT,	false},
 +	{"AF_HE",               WF_LWTBL_AF_HE_MASK,        WF_LWTBL_AF_HE_SHIFT,false},
 +	{"RTS",                 WF_LWTBL_RTS_MASK,          NO_SHIFT_DEFINE,	false},
@@ -3545,6 +3800,27 @@
 +	{NULL,}
 +};
 +
++static const struct berse_wtbl_parse WTBL_LMAC_DW5_7992[] = {
++	{"AF",                  WF_LWTBL_AF_MASK_7992,      WF_LWTBL_AF_SHIFT,	false},
++	{"RTS",                 WF_LWTBL_RTS_MASK,          NO_SHIFT_DEFINE,	false},
++	{"SMPS",                WF_LWTBL_SMPS_MASK,         NO_SHIFT_DEFINE,	false},
++	{"DYN_BW",              WF_LWTBL_DYN_BW_MASK,       NO_SHIFT_DEFINE,	true},
++	{"MMSS",                WF_LWTBL_MMSS_MASK,         WF_LWTBL_MMSS_SHIFT,false},
++	{"USR",                 WF_LWTBL_USR_MASK,          NO_SHIFT_DEFINE,	false},
++	{"SR_RATE",             WF_LWTBL_SR_R_MASK,         WF_LWTBL_SR_R_SHIFT,false},
++	{"SR_ABORT",            WF_LWTBL_SR_ABORT_MASK,     NO_SHIFT_DEFINE,	true},
++	{"TX_POWER_OFFSET",     WF_LWTBL_TX_POWER_OFFSET_MASK,  WF_LWTBL_TX_POWER_OFFSET_SHIFT,	false},
++	{"LTF_EHT",		WF_LWTBL_LTF_EHT_MASK,      WF_LWTBL_LTF_EHT_SHIFT, false},
++	{"GI_EHT",		WF_LWTBL_GI_EHT_MASK,       WF_LWTBL_GI_EHT_SHIFT, false},
++	{"DOPPL",               WF_LWTBL_DOPPL_MASK,        NO_SHIFT_DEFINE,	false},
++	{"TXOP_PS_CAP",         WF_LWTBL_TXOP_PS_CAP_MASK,  NO_SHIFT_DEFINE,	false},
++	{"DONOT_UPDATE_I_PSM",  WF_LWTBL_DU_I_PSM_MASK,     NO_SHIFT_DEFINE,	true},
++	{"I_PSM",               WF_LWTBL_I_PSM_MASK,        NO_SHIFT_DEFINE,	false},
++	{"PSM",                 WF_LWTBL_PSM_MASK,          NO_SHIFT_DEFINE,	false},
++	{"SKIP_TX",             WF_LWTBL_SKIP_TX_MASK,      NO_SHIFT_DEFINE,	true},
++	{NULL,}
++};
++
 +static void parse_fmac_lwtbl_dw5(struct seq_file *s, u8 *lwtbl)
 +{
 +	u32 *addr = 0;
@@ -3663,7 +3939,8 @@
 +	}
 +}
 +
-+static const struct berse_wtbl_parse WTBL_LMAC_DW9[] = {
++static const struct berse_wtbl_parse *WTBL_LMAC_DW9;
++static const struct berse_wtbl_parse WTBL_LMAC_DW9_7996[] = {
 +	{"RX_AVG_MPDU_SIZE",    WF_LWTBL_RX_AVG_MPDU_SIZE_MASK,    WF_LWTBL_RX_AVG_MPDU_SIZE_SHIFT,	false},
 +	{"PRITX_SW_MODE",       WF_LWTBL_PRITX_SW_MODE_MASK,       NO_SHIFT_DEFINE,	false},
 +	{"PRITX_ERSU",	    WF_LWTBL_PRITX_ERSU_MASK,	       NO_SHIFT_DEFINE,	false},
@@ -3677,6 +3954,20 @@
 +	{NULL,}
 +};
 +
++static const struct berse_wtbl_parse WTBL_LMAC_DW9_7992[] = {
++	{"RX_AVG_MPDU_SIZE",    WF_LWTBL_RX_AVG_MPDU_SIZE_MASK,    WF_LWTBL_RX_AVG_MPDU_SIZE_SHIFT,	false},
++	{"PRITX_SW_MODE",       WF_LWTBL_PRITX_SW_MODE_MASK_7992,       NO_SHIFT_DEFINE,	false},
++	{"PRITX_ERSU",	    WF_LWTBL_PRITX_ERSU_MASK_7992,	       NO_SHIFT_DEFINE,	false},
++	{"PRITX_PLR",           WF_LWTBL_PRITX_PLR_MASK_7992,           NO_SHIFT_DEFINE,	true},
++	{"PRITX_DCM",           WF_LWTBL_PRITX_DCM_MASK,           NO_SHIFT_DEFINE,	false},
++	{"PRITX_ER106T",        WF_LWTBL_PRITX_ER106T_MASK,        NO_SHIFT_DEFINE,	true},
++	/* {"FCAP(0:20 1:~40)",    WTBL_FCAP_20_TO_160_MHZ,	WTBL_FCAP_20_TO_160_MHZ_OFFSET}, */
++	{"MPDU_FAIL_CNT",       WF_LWTBL_MPDU_FAIL_CNT_MASK,       WF_LWTBL_MPDU_FAIL_CNT_SHIFT,	false},
++	{"MPDU_OK_CNT",         WF_LWTBL_MPDU_OK_CNT_MASK,         WF_LWTBL_MPDU_OK_CNT_SHIFT,	false},
++	{"RATE_IDX",            WF_LWTBL_RATE_IDX_MASK,            WF_LWTBL_RATE_IDX_SHIFT,	true},
++	{NULL,}
++};
++
 +char *fcap_name[] = {"20MHz", "20/40MHz", "20/40/80MHz", "20/40/80/160/80+80MHz", "20/40/80/160/80+80/320MHz"};
 +
 +static void parse_fmac_lwtbl_dw9(struct seq_file *s, u8 *lwtbl)
@@ -4694,24 +4985,69 @@
 +				     LWTBL_LEN_IN_DW, lwtbl);
 +
 +		if (lwtbl[4] || lwtbl[5] || lwtbl[6] || lwtbl[7] || lwtbl[0] || lwtbl[1]) {
-+			u32 *addr = (u32 *)&(lwtbl[WTBL_GROUP_TRX_CAP_DW_2*4]);
-+			u32 dw_value = *addr;
++			u32 *addr, dw_value;
 +
 +			seq_printf(s, "wcid:%d\tAddr: %02x:%02x:%02x:%02x:%02x:%02x",
 +					i, lwtbl[4], lwtbl[5], lwtbl[6], lwtbl[7], lwtbl[0], lwtbl[1]);
-+			seq_printf(s, "\t%s:%u\n", WTBL_LMAC_DW2[0].name,
++
++			addr = (u32 *)&(lwtbl[WTBL_GROUP_TRX_CAP_DW_2*4]);
++			dw_value = *addr;
++			seq_printf(s, "\t%s:%u", WTBL_LMAC_DW2[0].name,
 +					(dw_value & WTBL_LMAC_DW2[0].mask) >> WTBL_LMAC_DW2[0].shift);
++
++			addr = (u32 *)&(lwtbl[WTBL_GROUP_TRX_CAP_DW_5*4]);
++			dw_value = *addr;
++			seq_printf(s, "\tPSM:%u\n", !!(dw_value & WF_LWTBL_PSM_MASK));
 +		}
 +	}
 +
 +	return 0;
 +}
 +
++static int mt7996_token_read(struct seq_file *s, void *data)
++{
++	struct mt7996_dev *dev = dev_get_drvdata(s->private);
++	int msdu_id;
++	struct mt76_txwi_cache *txwi;
++
++	seq_printf(s, "Token from host:\n");
++	spin_lock_bh(&dev->mt76.token_lock);
++	idr_for_each_entry(&dev->mt76.token, txwi, msdu_id) {
++		seq_printf(s, "%4d (pending time %u ms)\n", msdu_id,
++			   jiffies_to_msecs(jiffies - txwi->jiffies));
++	}
++	spin_unlock_bh(&dev->mt76.token_lock);
++	seq_printf(s, "\n");
++
++	return 0;
++}
++
 +int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
 +{
 +	struct mt7996_dev *dev = phy->dev;
++	u32 device_id = (dev->mt76.rev) >> 16;
++	int i = 0;
++	static const struct mt7996_dbg_reg_desc dbg_reg_s[] = {
++		{ 0x7990, mt7996_dbg_offs },
++		{ 0x7992, mt7992_dbg_offs },
++	};
 +
-+	mt7996_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);
++	for (i = 0; i < ARRAY_SIZE(dbg_reg_s); i++) {
++		if (device_id == dbg_reg_s[i].id) {
++			dev->dbg_reg = &dbg_reg_s[i];
++			break;
++		}
++	}
++
++	if (is_mt7996(&dev->mt76)) {
++		WTBL_LMAC_DW2 = WTBL_LMAC_DW2_7996;
++		WTBL_LMAC_DW5 = WTBL_LMAC_DW5_7996;
++		WTBL_LMAC_DW9 = WTBL_LMAC_DW9_7996;
++	} else {
++		WTBL_LMAC_DW2 = WTBL_LMAC_DW2_7992;
++		WTBL_LMAC_DW5 = WTBL_LMAC_DW5_7992;
++		WTBL_LMAC_DW9 = WTBL_LMAC_DW9_7992;
++	}
 +
 +	/* agg */
 +	debugfs_create_devm_seqfile(dev->mt76.dev, "agg_info0", dir,
@@ -4753,6 +5089,8 @@
 +	debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
 +				    mt7996_wtbl_read);
 +
++	debugfs_create_devm_seqfile(dev->mt76.dev, "token", dir, mt7996_token_read);
++
 +	debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
 +
 +	return 0;
@@ -4761,7 +5099,7 @@
 +#endif
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
 new file mode 100644
-index 0000000..e887016
+index 00000000..e8870166
 --- /dev/null
 +++ b/mt7996/mtk_mcu.c
 @@ -0,0 +1,18 @@
@@ -4785,7 +5123,7 @@
 +#endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
 new file mode 100644
-index 0000000..e741aa2
+index 00000000..e741aa27
 --- /dev/null
 +++ b/mt7996/mtk_mcu.h
 @@ -0,0 +1,16 @@
@@ -4806,7 +5144,7 @@
 +
 +#endif
 diff --git a/tools/fwlog.c b/tools/fwlog.c
-index e5d4a10..3c6a61d 100644
+index e5d4a105..3c6a61d7 100644
 --- a/tools/fwlog.c
 +++ b/tools/fwlog.c
 @@ -26,7 +26,7 @@ static const char *debugfs_path(const char *phyname, const char *file)
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1001-mtk-wifi-mt76-mt7996-support-record-muru-algo-log-wh.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1001-mtk-wifi-mt76-mt7996-support-record-muru-algo-log-wh.patch
new file mode 100644
index 0000000..f707328
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1001-mtk-wifi-mt76-mt7996-support-record-muru-algo-log-wh.patch
@@ -0,0 +1,144 @@
+From 80a3aa92334b91d0f6f0a8793a2e70391bcd1d12 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Tue, 28 Nov 2023 16:01:33 +0800
+Subject: [PATCH 1001/1041] mtk: wifi: mt76: mt7996: support record muru algo
+ log when record fw log
+
+Support record muru algorithm debug log in firmware when we use
+chihuahua tool to record fw log. This can help us to check some key
+point of muru algorithm result, like bsrp status, airtime busy status,
+ru candidate...
+Corresponding to Logan driver, it is the same as execute the iwpriv
+command: iwpriv rax0 set muruDbgInfo=[category]-1
+
+Disable muru debug log when we stop record fwlog. Without this commit,
+if we run $ echo 2 > fw_debug_wm after recording fwlog, it will print
+out too many fw debug log.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt7996/debugfs.c | 35 +++++++++++++++++++++++++++++++++++
+ mt7996/mt7996.h  |  1 +
+ mt7996/mtk_mcu.c | 21 +++++++++++++++++++++
+ mt7996/mtk_mcu.h |  3 +++
+ 4 files changed, 60 insertions(+)
+
+diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
+index c4b82cb2..f4ce3b55 100644
+--- a/mt7996/debugfs.c
++++ b/mt7996/debugfs.c
+@@ -423,6 +423,36 @@ remove_buf_file_cb(struct dentry *f)
+ 	return 0;
+ }
+ 
++static int
++mt7996_fw_debug_muru_set(void *data)
++{
++	struct mt7996_dev *dev = data;
++	enum {
++		DEBUG_BSRP_STATUS = 256,
++		DEBUG_TX_DATA_BYTE_CONUT,
++		DEBUG_RX_DATA_BYTE_CONUT,
++		DEBUG_RX_TOTAL_BYTE_CONUT,
++		DEBUG_INVALID_TID_BSR,
++		DEBUG_UL_LONG_TERM_PPDU_TYPE,
++		DEBUG_DL_LONG_TERM_PPDU_TYPE,
++		DEBUG_PPDU_CLASS_TRIG_ONOFF,
++		DEBUG_AIRTIME_BUSY_STATUS,
++		DEBUG_UL_OFDMA_MIMO_STATUS,
++		DEBUG_RU_CANDIDATE,
++		DEBUG_MEC_UPDATE_AMSDU,
++	} debug;
++	int ret;
++
++	for (debug = DEBUG_BSRP_STATUS; debug <= DEBUG_MEC_UPDATE_AMSDU; debug++) {
++		ret = mt7996_mcu_muru_dbg_info(dev, debug,
++					       dev->fw_debug_bin & BIT(0));
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
+ static int
+ mt7996_fw_debug_bin_set(void *data, u64 val)
+ {
+@@ -431,6 +461,7 @@ mt7996_fw_debug_bin_set(void *data, u64 val)
+ 		.remove_buf_file = remove_buf_file_cb,
+ 	};
+ 	struct mt7996_dev *dev = data;
++	int ret;
+ 
+ 	if (!dev->relay_fwlog) {
+ 		dev->relay_fwlog = relay_open("fwlog_data", dev->debugfs_dir,
+@@ -443,6 +474,10 @@ mt7996_fw_debug_bin_set(void *data, u64 val)
+ 
+ 	relay_reset(dev->relay_fwlog);
+ 
++	ret = mt7996_fw_debug_muru_set(dev);
++	if (ret)
++		return ret;
++
+ 	return mt7996_fw_debug_wm_set(dev, dev->fw_debug_wm);
+ }
+ 
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 34159f97..29976860 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -677,6 +677,7 @@ u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+ 
+ #ifdef CONFIG_MTK_DEBUG
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
++int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
+ #endif
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index e8870166..c16b25ab 100644
+--- a/mt7996/mtk_mcu.c
++++ b/mt7996/mtk_mcu.c
+@@ -15,4 +15,25 @@
+ 
+ 
+ 
++int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val)
++{
++	struct {
++		u8 __rsv1[4];
++
++		__le16 tag;
++		__le16 len;
++
++		__le16 item;
++		u8 __rsv2[2];
++		__le32 value;
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_CMD_MURU_DBG_INFO),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.item = cpu_to_le16(item),
++		.value = cpu_to_le32(val),
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &req,
++				 sizeof(req), true);
++}
+ #endif
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index e741aa27..7f4d4e02 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -10,6 +10,9 @@
+ 
+ #ifdef CONFIG_MTK_DEBUG
+ 
++enum {
++	UNI_CMD_MURU_DBG_INFO = 0x18,
++};
+ 
+ #endif
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1002-mtk-wifi-mt76-mt7996-add-check-for-hostapd-config-he.patch
similarity index 66%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1002-mtk-wifi-mt76-mt7996-add-check-for-hostapd-config-he.patch
index ff8d7a8..e94c68d 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1002-mtk-wifi-mt76-mt7996-add-check-for-hostapd-config-he.patch
@@ -1,23 +1,24 @@
-From cb64d3c0b0dd79b8255caef614b13fe17f1b5b07 Mon Sep 17 00:00:00 2001
+From 9b07919cd131c27ae7507632a57767727815bbd9 Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Thu, 8 Jun 2023 17:32:33 +0800
-Subject: [PATCH 34/98] wifi: mt76: mt7996: add check for hostapd config
- he_ldpc
+Subject: [PATCH 1002/1041] mtk: wifi: mt76: mt7996: add check for hostapd
+ config he_ldpc
 
 Add check for hostapd config he_ldpc.
 This capabilities is checked in mcu_beacon_check_caps in 7915.
 
+Add check for STA LDPC cap, if STA only have BCC we should not overwrite the phy_cap with config he_ldpc.
+
 Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
-Change-Id: I6d6f59df8897e3c00f2e0a1e3c6e5701e31c5e4b
 ---
- mt7996/mcu.c | 11 ++++++++---
- 1 file changed, 8 insertions(+), 3 deletions(-)
+ mt7996/mcu.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index fdc4fb4..7d0c511 100644
+index 3ecdde86..b379b226 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1096,7 +1096,8 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
+@@ -1182,7 +1182,8 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
  }
  
  static void
@@ -27,18 +28,19 @@
  {
  	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
  	struct ieee80211_he_mcs_nss_supp mcs_map;
-@@ -1116,6 +1117,10 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -1202,6 +1203,11 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  		he->he_phy_cap[i] = elem->phy_cap_info[i];
  	}
  
-+	if (vif->type == NL80211_IFTYPE_AP)
++	if (vif->type == NL80211_IFTYPE_AP &&
++	    (elem->phy_cap_info[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD))
 +		u8p_replace_bits(&he->he_phy_cap[1], vif->bss_conf.he_ldpc,
 +				 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD);
 +
  	mcs_map = sta->deflink.he_cap.he_mcs_nss_supp;
  	switch (sta->deflink.bandwidth) {
  	case IEEE80211_STA_RX_BW_160:
-@@ -1994,7 +1999,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2108,7 +2114,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  	 * update sta_rec_he here.
  	 */
  	if (changed)
@@ -47,7 +49,7 @@
  
  	/* sta_rec_ra accommodates BW, NSS and only MCS range format
  	 * i.e 0-{7,8,9} for VHT.
-@@ -2080,7 +2085,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2194,7 +2200,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  		/* starec amsdu */
  		mt7996_mcu_sta_amsdu_tlv(dev, skb, vif, sta);
  		/* starec he */
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1003-mtk-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1003-mtk-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
index 56f85a8..ee2c2c6 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1003-mtk-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
@@ -1,7 +1,8 @@
-From e622295e18a1af30c999928701787d8c562621c3 Mon Sep 17 00:00:00 2001
+From 7ff2021958001be2941953f6295c07cdcd7728e9 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 28 Dec 2022 22:24:25 +0800
-Subject: [PATCH 35/98] wifi: mt76: testmode: add atenl support in mt7996
+Subject: [PATCH 1003/1041] mtk: wifi: mt76: testmode: add atenl support in
+ mt7996
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -10,7 +11,7 @@
  2 files changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/testmode.c b/testmode.c
-index 4644dac..5c93aa6 100644
+index 4644dace..5c93aa6a 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -613,7 +613,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
@@ -24,7 +25,7 @@
  
  	if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
 diff --git a/testmode.h b/testmode.h
-index 5e2792d..a40cd74 100644
+index 5e2792d8..a40cd74b 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -17,6 +17,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-testmode-add-basic-testmode-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1004-mtk-wifi-mt76-testmode-add-basic-testmode-support.patch
similarity index 80%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-testmode-add-basic-testmode-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1004-mtk-wifi-mt76-testmode-add-basic-testmode-support.patch
index 5b78a59..dc7d412 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-testmode-add-basic-testmode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1004-mtk-wifi-mt76-testmode-add-basic-testmode-support.patch
@@ -1,37 +1,55 @@
-From ce58ffb18be834e2f62a30a71c9d6f5805517a9e Mon Sep 17 00:00:00 2001
+From 5ada52c4318533dafc3a77110ff161849508175c Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 1 Mar 2023 11:59:16 +0800
-Subject: [PATCH 36/98] wifi: mt76: testmode: add basic testmode support
+Subject: [PATCH 1004/1041] mtk: wifi: mt76: testmode: add basic testmode
+ support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Add testmode eeprom buffer mode support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Fix power & freq offset issue for iTest power cal & tx/rx verifcation
+1. Wait for fw to tx. Otherwise, iTest testing tool cannot get the
+accurate tx power.
+2. In crystal mode, freq offset is set in 6G band and forwarded to 5G
+and 2G band. Therefore, we should avoid reseting freq offset to 0 when
+6G interface is off.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+edcca return err in testmode; therefore, bypass it when we are in testmode idle state or testmode bf is on
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
  eeprom.c          |   6 +-
  mac80211.c        |   3 +-
- mt76.h            |  35 +++
+ mt76.h            |  36 +++
  mt76_connac_mcu.h |   2 +
  mt7996/Makefile   |   1 +
  mt7996/eeprom.c   |  35 ++-
  mt7996/eeprom.h   |   1 +
  mt7996/init.c     |   8 +
  mt7996/mac.c      |   3 +-
- mt7996/main.c     |  16 ++
- mt7996/mcu.c      |  42 ++-
- mt7996/mcu.h      |  27 ++
- mt7996/mt7996.h   |  23 ++
- mt7996/testmode.c | 674 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/testmode.h | 297 ++++++++++++++++++++
- testmode.c        |  78 ++++--
- testmode.h        |  64 +++++
+ mt7996/main.c     |  26 ++
+ mt7996/mcu.c      |  59 +++-
+ mt7996/mcu.h      |  33 +++
+ mt7996/mt7996.h   |  28 +-
+ mt7996/testmode.c | 740 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/testmode.h | 299 +++++++++++++++++++
+ testmode.c        | 123 ++++++--
+ testmode.h        |  85 +++++-
  tools/fields.c    | 102 ++++++-
- 18 files changed, 1383 insertions(+), 34 deletions(-)
+ 18 files changed, 1542 insertions(+), 48 deletions(-)
  create mode 100644 mt7996/testmode.c
  create mode 100644 mt7996/testmode.h
 
 diff --git a/eeprom.c b/eeprom.c
-index a07ca84..437d8ca 100644
+index 7d5cf28f..85bd2a29 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -94,8 +94,10 @@ static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offs
+@@ -94,8 +94,10 @@ int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int l
  	}
  
  #ifdef CONFIG_NL80211_TESTMODE
@@ -45,10 +63,10 @@
  
  out_put_node:
 diff --git a/mac80211.c b/mac80211.c
-index cd102dd..f10ca90 100644
+index 6c5b4f55..d31cf9ff 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -835,7 +835,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
+@@ -846,7 +846,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
  	}
  
  #ifdef CONFIG_NL80211_TESTMODE
@@ -59,15 +77,16 @@
  		if (status->flag & RX_FLAG_FAILED_FCS_CRC)
  			phy->test.rx_stats.fcs_error[q]++;
 diff --git a/mt76.h b/mt76.h
-index 7f93210..feb861c 100644
+index de0021e4..7951b90e 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -692,14 +692,20 @@ struct mt76_testmode_ops {
+@@ -694,14 +694,21 @@ struct mt76_testmode_ops {
  	int (*set_params)(struct mt76_phy *phy, struct nlattr **tb,
  			  enum mt76_testmode_state new_state);
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
 +	void (*reset_rx_stats)(struct mt76_phy *phy);
 +	void (*tx_stop)(struct mt76_phy *phy);
++	int (*set_eeprom)(struct mt76_phy *phy, u32 offset, u8 *val, u8 action);
  };
  
 +#define MT_TM_FW_RX_COUNT	BIT(0)
@@ -83,7 +102,7 @@
  	u32 tx_count;
  	u16 tx_mpdu_len;
  
-@@ -709,6 +715,7 @@ struct mt76_testmode_data {
+@@ -711,6 +718,7 @@ struct mt76_testmode_data {
  	u8 tx_rate_sgi;
  	u8 tx_rate_ldpc;
  	u8 tx_rate_stbc;
@@ -91,7 +110,7 @@
  	u8 tx_ltf;
  
  	u8 tx_antenna_mask;
-@@ -718,6 +725,9 @@ struct mt76_testmode_data {
+@@ -720,6 +728,9 @@ struct mt76_testmode_data {
  	u32 tx_time;
  	u32 tx_ipg;
  
@@ -101,7 +120,7 @@
  	u32 freq_offset;
  
  	u8 tx_power[4];
-@@ -732,7 +742,16 @@ struct mt76_testmode_data {
+@@ -734,7 +745,16 @@ struct mt76_testmode_data {
  	struct {
  		u64 packets[__MT_RXQ_MAX];
  		u64 fcs_error[__MT_RXQ_MAX];
@@ -118,7 +137,7 @@
  };
  
  struct mt76_vif {
-@@ -1418,6 +1437,22 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
+@@ -1423,6 +1443,22 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
  int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state);
  int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len);
  
@@ -142,10 +161,10 @@
  {
  #ifdef CONFIG_NL80211_TESTMODE
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index ca2e573..4d054bd 100644
+index 823b3626..0a55a4be 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1239,12 +1239,14 @@ enum {
+@@ -1255,12 +1255,14 @@ enum {
  	MCU_UNI_CMD_EFUSE_CTRL = 0x2d,
  	MCU_UNI_CMD_RA = 0x2f,
  	MCU_UNI_CMD_MURU = 0x31,
@@ -161,7 +180,7 @@
  	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
  	MCU_UNI_CMD_PER_STA_INFO = 0x6d,
 diff --git a/mt7996/Makefile b/mt7996/Makefile
-index a056b40..7bb17f4 100644
+index a056b40e..7bb17f44 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
 @@ -8,5 +8,6 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
@@ -172,7 +191,7 @@
  
  mt7996e-y += mtk_debugfs.o mtk_mcu.o
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 7ae92e1..7fd318c 100644
+index 7d07c1b1..8fb1015e 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -6,6 +6,11 @@
@@ -187,19 +206,17 @@
  
  static int mt7996_check_eeprom(struct mt7996_dev *dev)
  {
-@@ -23,7 +28,10 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+@@ -40,6 +45,9 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+ 
  static char *mt7996_eeprom_name(struct mt7996_dev *dev)
  {
- 	/* reserve for future variants */
--	return MT7996_EEPROM_DEFAULT;
 +	if (dev->testmode_enable)
 +		return MT7996_EEPROM_DEFAULT_TM;
-+	else
-+		return MT7996_EEPROM_DEFAULT;
- }
- 
- static int
-@@ -52,21 +60,36 @@ out:
++
+ 	switch (mt76_chip(&dev->mt76)) {
+ 	case 0x7990:
+ 		if (dev->chip_sku == MT7996_SKU_404)
+@@ -89,21 +97,36 @@ out:
  	return ret;
  }
  
@@ -241,8 +258,17 @@
  		ret = mt7996_mcu_get_eeprom_free_block(dev, &free_block_num);
  		if (ret < 0)
  			return ret;
+@@ -115,7 +138,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
+ 		/* read eeprom data from efuse */
+ 		block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size);
+ 		for (i = 0; i < block_num; i++) {
+-			ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size);
++			ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size, NULL);
+ 			if (ret < 0)
+ 				return ret;
+ 		}
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 412d6e2..9ea3667 100644
+index 72c38ad3..de3ff4e2 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -14,6 +14,7 @@ enum mt7996_eeprom_field {
@@ -254,10 +280,10 @@
  	MT_EE_RATE_DELTA_2G =	0x1400,
  	MT_EE_RATE_DELTA_5G =	0x147d,
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 273d1e7..6d39c3c 100644
+index dae640e9..7bfebd38 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -800,6 +800,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -970,6 +970,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  
  	set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
  
@@ -268,7 +294,7 @@
  	ret = mt7996_mcu_init(dev);
  	if (ret)
  		return ret;
-@@ -1217,6 +1221,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1388,6 +1392,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
  
  	mt7996_init_wiphy(hw, &dev->mt76.mmio.wed);
  
@@ -280,7 +306,7 @@
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 32c52fc..637f0f6 100644
+index ce6759e0..924b05e4 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
 @@ -685,7 +685,8 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
@@ -294,7 +320,7 @@
  
  	if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr)
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 0e51fe0..226235c 100644
+index 9fbd87d5..2a93e8c2 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -23,6 +23,18 @@ static bool mt7996_dev_running(struct mt7996_dev *dev)
@@ -325,7 +351,31 @@
  	mt7996_mac_enable_nf(dev, phy->mt76->band_idx);
  
  	ret = mt7996_mcu_set_rts_thresh(phy, 0x92b);
-@@ -1478,6 +1492,8 @@ const struct ieee80211_ops mt7996_ops = {
+@@ -291,6 +305,11 @@ int mt7996_set_channel(struct mt7996_phy *phy)
+ 
+ 	mt76_set_channel(phy->mt76);
+ 
++	if (mt76_testmode_enabled(phy->mt76) || phy->mt76->test.bf_en) {
++		mt7996_tm_update_channel(phy);
++		goto out;
++	}
++
+ 	ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);
+ 	if (ret)
+ 		goto out;
+@@ -398,6 +417,11 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
+ 	int ret;
+ 
+ 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
++		if (!mt76_testmode_enabled(phy->mt76) && !phy->mt76->test.bf_en) {
++			ret = mt7996_mcu_edcca_enable(phy, true);
++			if (ret)
++				return ret;
++		}
+ 		ieee80211_stop_queues(hw);
+ 		ret = mt7996_set_channel(phy);
+ 		if (ret)
+@@ -1507,6 +1531,8 @@ const struct ieee80211_ops mt7996_ops = {
  	.sta_set_decap_offload = mt7996_sta_set_decap_offload,
  	.add_twt_setup = mt7996_mac_add_twt_setup,
  	.twt_teardown_request = mt7996_twt_teardown_request,
@@ -335,25 +385,64 @@
  	.sta_add_debugfs = mt7996_sta_add_debugfs,
  #endif
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 7d0c511..141b838 100644
+index b379b226..099ff74f 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2681,8 +2681,12 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
+@@ -2858,8 +2858,12 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
  {
  	int ret;
  
--	ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
+-	ret = __mt7996_load_ram(dev, "WM", fw_name(dev, FIRMWARE_WM),
 -				MT7996_RAM_TYPE_WM);
 +	if (dev->testmode_enable)
-+		ret = __mt7996_load_ram(dev, "WM_TM", MT7996_FIRMWARE_WM_TM,
++		ret = __mt7996_load_ram(dev, "WM_TM", fw_name(dev, FIRMWARE_WM_TM),
 +					MT7996_RAM_TYPE_WM_TM);
 +	else
-+		ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
++		ret = __mt7996_load_ram(dev, "WM", fw_name(dev, FIRMWARE_WM),
 +					MT7996_RAM_TYPE_WM);
  	if (ret)
  		return ret;
  
+@@ -3550,17 +3554,9 @@ int mt7996_mcu_set_eeprom(struct mt7996_dev *dev)
+ 				 &req, sizeof(req), true);
+ }
+ 
+-int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset)
++int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *read_buf)
+ {
+-	struct {
+-		u8 _rsv[4];
+-
+-		__le16 tag;
+-		__le16 len;
+-		__le32 addr;
+-		__le32 valid;
+-		u8 data[16];
+-	} __packed req = {
++	struct mt7996_mcu_eeprom_info req = {
+ 		.tag = cpu_to_le16(UNI_EFUSE_ACCESS),
+ 		.len = cpu_to_le16(sizeof(req) - 4),
+ 		.addr = cpu_to_le32(round_down(offset,
+@@ -3569,6 +3565,7 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset)
+ 	struct sk_buff *skb;
+ 	bool valid;
+ 	int ret;
++	u8 *buf = read_buf;
+ 
+ 	ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+ 					MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL),
+@@ -3579,7 +3576,9 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset)
+ 	valid = le32_to_cpu(*(__le32 *)(skb->data + 16));
+ 	if (valid) {
+ 		u32 addr = le32_to_cpu(*(__le32 *)(skb->data + 12));
+-		u8 *buf = (u8 *)dev->mt76.eeprom.data + addr;
++
++		if (!buf)
++			buf = (u8 *)dev->mt76.eeprom.data + addr;
+ 
-@@ -4308,3 +4312,37 @@ int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, bool auto_mode,
+ 		skb_pull(skb, 48);
+ 		memcpy(buf, skb->data, MT7996_EEPROM_BLOCK_SIZE);
+@@ -4571,3 +4570,37 @@ int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, bool auto_mode,
  	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(PP),
  				 &req, sizeof(req), false);
  }
@@ -392,10 +481,27 @@
 +				 &req, sizeof(req), false);
 +}
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index ca16336..16ffc3d 100644
+index 238c4c53..325c3c97 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -814,6 +814,33 @@ enum {
+@@ -157,6 +157,16 @@ struct mt7996_mcu_eeprom {
+ 	__le16 buf_len;
+ } __packed;
+ 
++struct mt7996_mcu_eeprom_info {
++	u8 _rsv[4];
++
++	__le16 tag;
++	__le16 len;
++	__le32 addr;
++	__le32 valid;
++	u8 data[MT7996_EEPROM_BLOCK_SIZE];
++} __packed;
++
+ struct mt7996_mcu_phy_rx_info {
+ 	u8 category;
+ 	u8 rate;
+@@ -889,8 +899,31 @@ enum {
  	UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG,
  };
  
@@ -417,35 +523,52 @@
 +	u8 rsv[1];
 +} __packed;
 +
-+enum {
+ enum {
 +	UNI_TXPOWER_SKU_POWER_LIMIT_CTRL = 0,
 +	UNI_TXPOWER_PERCENTAGE_CTRL = 1,
 +	UNI_TXPOWER_PERCENTAGE_DROP_CTRL = 2,
 +	UNI_TXPOWER_BACKOFF_POWER_LIMIT_CTRL = 3,
-+	UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4,
+ 	UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4,
 +	UNI_TXPOWER_ATE_MODE_CTRL = 6,
-+};
-+
+ };
+ 
  enum {
- 	UNI_CMD_ACCESS_REG_BASIC = 0x0,
- 	UNI_CMD_ACCESS_RF_REG_BASIC,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 8801956..3964035 100644
+index 29976860..5af55492 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -32,9 +32,11 @@
+@@ -32,25 +32,30 @@
  #define MT7996_FIRMWARE_WA		"mediatek/mt7996/mt7996_wa.bin"
  #define MT7996_FIRMWARE_WM		"mediatek/mt7996/mt7996_wm.bin"
  #define MT7996_FIRMWARE_DSP		"mediatek/mt7996/mt7996_dsp.bin"
 +#define MT7996_FIRMWARE_WM_TM		"mediatek/mt7996/mt7996_wm_tm.bin"
  #define MT7996_ROM_PATCH		"mediatek/mt7996/mt7996_rom_patch.bin"
  
+ #define MT7992_FIRMWARE_WA		"mediatek/mt7996/mt7992_wa.bin"
+ #define MT7992_FIRMWARE_WM		"mediatek/mt7996/mt7992_wm.bin"
+ #define MT7992_FIRMWARE_DSP		"mediatek/mt7996/mt7992_dsp.bin"
++#define MT7992_FIRMWARE_WM_TM		"mediatek/mt7996/mt7992_wm_tm.bin"
+ #define MT7992_ROM_PATCH		"mediatek/mt7996/mt7992_rom_patch.bin"
+ 
+ #define MT7992_FIRMWARE_WA_24		"mediatek/mt7996/mt7992_wa_24.bin"
+ #define MT7992_FIRMWARE_WM_24		"mediatek/mt7996/mt7992_wm_24.bin"
+ #define MT7992_FIRMWARE_DSP_24		"mediatek/mt7996/mt7992_dsp_24.bin"
++#define MT7992_FIRMWARE_WM_TM_24	"mediatek/mt7996/mt7992_wm_tm_24.bin"
+ #define MT7992_ROM_PATCH_24		"mediatek/mt7996/mt7992_rom_patch_24.bin"
+ 
+ #define MT7992_FIRMWARE_WA_23		"mediatek/mt7996/mt7992_wa_23.bin"
+ #define MT7992_FIRMWARE_WM_23		"mediatek/mt7996/mt7992_wm_23.bin"
+ #define MT7992_FIRMWARE_DSP_23		"mediatek/mt7996/mt7992_dsp_23.bin"
++#define MT7992_FIRMWARE_WM_TM_23	"mediatek/mt7996/mt7992_wm_tm_23.bin"
+ #define MT7992_ROM_PATCH_23		"mediatek/mt7996/mt7992_rom_patch_23.bin"
+ 
  #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
+ #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
 +#define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
- #define MT7996_EEPROM_SIZE		7680
- #define MT7996_EEPROM_BLOCK_SIZE	16
- #define MT7996_TOKEN_SIZE		16384
-@@ -83,6 +85,7 @@ struct mt7996_dfs_pattern;
+ #define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom_2i5i.bin"
+ #define MT7992_EEPROM_DEFAULT_EXT	"mediatek/mt7996/mt7992_eeprom_2e5e.bin"
+ #define MT7992_EEPROM_DEFAULT_MIX	"mediatek/mt7996/mt7992_eeprom_2i5e.bin"
+@@ -126,6 +131,7 @@ enum mt7992_sku_type {
  
  enum mt7996_ram_type {
  	MT7996_RAM_TYPE_WM,
@@ -453,7 +576,7 @@
  	MT7996_RAM_TYPE_WA,
  	MT7996_RAM_TYPE_DSP,
  	__MT7996_RAM_TYPE_MAX,
-@@ -225,6 +228,21 @@ struct mt7996_phy {
+@@ -273,6 +279,21 @@ struct mt7996_phy {
  	struct mt76_channel_state state_ts;
  
  	bool has_aux_rx;
@@ -475,8 +598,8 @@
  };
  
  struct mt7996_dev {
-@@ -300,6 +318,8 @@ struct mt7996_dev {
- 		} session;
+@@ -353,6 +374,8 @@ struct mt7996_dev {
+ 		spinlock_t lock;
  	} wed_rro;
  
 +	bool testmode_enable;
@@ -484,7 +607,7 @@
  	bool ibf;
  	u8 fw_debug_wm;
  	u8 fw_debug_wa;
-@@ -414,6 +434,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
+@@ -467,6 +490,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
  extern const struct ieee80211_ops mt7996_ops;
  extern struct pci_driver mt7996_pci_driver;
  extern struct pci_driver mt7996_hif_driver;
@@ -492,7 +615,7 @@
  
  struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
  				     void __iomem *mem_base, u32 device_id);
-@@ -423,6 +444,7 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
+@@ -476,6 +500,7 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
  int mt7996_register_device(struct mt7996_dev *dev);
  void mt7996_unregister_device(struct mt7996_dev *dev);
  int mt7996_eeprom_init(struct mt7996_dev *dev);
@@ -500,20 +623,29 @@
  int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
  int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
  				   struct ieee80211_channel *chan);
-@@ -508,6 +530,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
- void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+@@ -528,7 +553,7 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
+ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ 			       struct ieee80211_sta *sta, void *data, u32 field);
+ int mt7996_mcu_set_eeprom(struct mt7996_dev *dev);
+-int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset);
++int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *read_buf);
+ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num);
+ int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap);
+ int mt7996_mcu_set_ser(struct mt7996_dev *dev, u8 action, u8 set, u8 band);
+@@ -563,6 +588,7 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
  void mt7996_mcu_exit(struct mt7996_dev *dev);
  int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
+ int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id);
 +int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
  
  static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
  {
 diff --git a/mt7996/testmode.c b/mt7996/testmode.c
 new file mode 100644
-index 0000000..fb041c3
+index 00000000..96079c22
 --- /dev/null
 +++ b/mt7996/testmode.c
-@@ -0,0 +1,674 @@
+@@ -0,0 +1,740 @@
 +// SPDX-License-Identifier: ISC
 +/*
 + * Copyright (C) 2022 MediaTek Inc.
@@ -620,9 +752,10 @@
 +			.op.rf.param.func_data = cpu_to_le32(data),
 +		},
 +	};
++	bool wait = (data == RF_CMD(START_TX)) ? true : false;
 +
 +	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TESTMODE_CTRL), &req,
-+				 sizeof(req), false);
++				 sizeof(req), wait);
 +}
 +
 +static int
@@ -917,10 +1050,11 @@
 +{
 +	struct mt76_testmode_data *td = &phy->mt76->test;
 +	struct mt7996_dev *dev = phy->dev;
-+	bool en = td->state != MT76_TM_STATE_OFF;
 +
-+	if (changed & BIT(TM_CHANGED_FREQ_OFFSET))
-+		mt7996_tm_set(dev, SET_ID(FREQ_OFFSET), en ? td->freq_offset : 0);
++	if (changed & BIT(TM_CHANGED_FREQ_OFFSET)) {
++		mt7996_tm_set(dev, SET_ID(FREQ_OFFSET), td->freq_offset);
++		mt7996_tm_set(dev, SET_ID(FREQ_OFFSET_C2), td->freq_offset);
++	}
 +	if (changed & BIT(TM_CHANGED_TXPOWER))
 +		mt7996_tm_set(dev, SET_ID(POWER), td->tx_power[0]);
 +	if (changed & BIT(TM_CHANGED_SKU_EN)) {
@@ -1181,19 +1315,83 @@
 +	return 0;
 +}
 +
++static int
++mt7996_tm_write_back_to_efuse(struct mt7996_dev *dev)
++{
++	struct mt7996_mcu_eeprom_info req = {
++		.tag = cpu_to_le16(UNI_EFUSE_ACCESS),
++		.len = cpu_to_le16(sizeof(req) - 4),
++	};
++	u8 read_buf[MT76_TM_EEPROM_BLOCK_SIZE], *eeprom = dev->mt76.eeprom.data;
++	int i, ret = -EINVAL;
++
++	/* prevent from damaging chip id in efuse */
++	if (mt76_chip(&dev->mt76) != get_unaligned_le16(eeprom))
++		goto out;
++
++	for (i = 0; i < MT7996_EEPROM_SIZE; i += MT76_TM_EEPROM_BLOCK_SIZE) {
++		req.addr = cpu_to_le32(i);
++		memcpy(req.data, eeprom + i, MT76_TM_EEPROM_BLOCK_SIZE);
++
++		ret = mt7996_mcu_get_eeprom(dev, i, read_buf);
++		if (ret < 0)
++			return ret;
++
++		if (!memcmp(req.data, read_buf, MT76_TM_EEPROM_BLOCK_SIZE))
++			continue;
++
++		ret = mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(EFUSE_CTRL),
++					&req, sizeof(req), true);
++		if (ret)
++			return ret;
++	}
++
++out:
++	return ret;
++}
++
++static int
++mt7996_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
++{
++	struct mt7996_phy *phy = mphy->priv;
++	struct mt7996_dev *dev = phy->dev;
++	u8 *eeprom = dev->mt76.eeprom.data;
++	int ret = 0;
++
++	if (offset >= MT7996_EEPROM_SIZE)
++		return -EINVAL;
++
++	switch (action) {
++	case MT76_TM_EEPROM_ACTION_UPDATE_DATA:
++		memcpy(eeprom + offset, val, MT76_TM_EEPROM_BLOCK_SIZE);
++		break;
++	case MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE:
++		ret = mt7996_mcu_set_eeprom(dev);
++		break;
++	case MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE:
++		ret = mt7996_tm_write_back_to_efuse(dev);
++		break;
++	default:
++		break;
++	}
++
++	return ret;
++}
++
 +const struct mt76_testmode_ops mt7996_testmode_ops = {
 +	.set_state = mt7996_tm_set_state,
 +	.set_params = mt7996_tm_set_params,
 +	.dump_stats = mt7996_tm_dump_stats,
 +	.reset_rx_stats = mt7996_tm_reset_trx_stats,
 +	.tx_stop = mt7996_tm_tx_stop,
++	.set_eeprom = mt7996_tm_set_eeprom,
 +};
 diff --git a/mt7996/testmode.h b/mt7996/testmode.h
 new file mode 100644
-index 0000000..e4d55a6
+index 00000000..319ef257
 --- /dev/null
 +++ b/mt7996/testmode.h
-@@ -0,0 +1,297 @@
+@@ -0,0 +1,299 @@
 +/* SPDX-License-Identifier: ISC */
 +/* Copyright (C) 2020 MediaTek Inc. */
 +
@@ -1343,6 +1541,8 @@
 +	RF_TEST_ID_SET_RX_MU_AID = 157,
 +	RF_TEST_ID_SET_HW_TX_MODE = 167,
 +	RF_TEST_ID_SET_PUNCTURE = 168,
++	RF_TEST_ID_SET_FREQ_OFFSET_C2 = 171,
++	RF_TEST_ID_GET_FREQ_OFFSET_C2 = 172,
 +	RF_TEST_ID_SET_CFG_ON = 176,
 +	RF_TEST_ID_SET_CFG_OFF = 177,
 +	RF_TEST_ID_SET_BSSID = 189,
@@ -1492,7 +1692,7 @@
 +
 +#endif
 diff --git a/testmode.c b/testmode.c
-index 5c93aa6..bbe8230 100644
+index 5c93aa6a..db2cc255 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -2,11 +2,13 @@
@@ -1609,7 +1809,64 @@
  	}
  
  	phy->test.state = state;
-@@ -434,6 +447,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -404,6 +417,44 @@ mt76_tm_get_u8(struct nlattr *attr, u8 *dest, u8 min, u8 max)
+ 	return 0;
+ }
+ 
++static int
++mt76_testmode_set_eeprom(struct mt76_phy *phy, struct nlattr **tb)
++{
++	struct mt76_dev *dev = phy->dev;
++	u8 action, val[MT76_TM_EEPROM_BLOCK_SIZE];
++	u32 offset = 0;
++	int err = -EINVAL;
++
++	if (!dev->test_ops->set_eeprom)
++		return -EOPNOTSUPP;
++
++	if (mt76_tm_get_u8(tb[MT76_TM_ATTR_EEPROM_ACTION], &action,
++			   0, MT76_TM_EEPROM_ACTION_MAX))
++		goto out;
++
++	if (tb[MT76_TM_ATTR_EEPROM_OFFSET]) {
++		struct nlattr *cur;
++		int rem, idx = 0;
++
++		offset = nla_get_u32(tb[MT76_TM_ATTR_EEPROM_OFFSET]);
++		if (!!(offset % MT76_TM_EEPROM_BLOCK_SIZE) ||
++		    !tb[MT76_TM_ATTR_EEPROM_VAL])
++			goto out;
++
++		nla_for_each_nested(cur, tb[MT76_TM_ATTR_EEPROM_VAL], rem) {
++			if (nla_len(cur) != 1 || idx >= ARRAY_SIZE(val))
++				goto out;
++
++			val[idx++] = nla_get_u8(cur);
++		}
++	}
++
++	err = dev->test_ops->set_eeprom(phy, offset, val, action);
++
++out:
++	return err;
++}
++
+ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 		      void *data, int len)
+ {
+@@ -427,6 +478,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 
+ 	mutex_lock(&dev->mutex);
+ 
++	if (tb[MT76_TM_ATTR_EEPROM_ACTION]) {
++		err = mt76_testmode_set_eeprom(phy, tb);
++		goto out;
++	}
++
+ 	if (tb[MT76_TM_ATTR_RESET]) {
+ 		mt76_testmode_set_state(phy, MT76_TM_STATE_OFF);
+ 		memset(td, 0, sizeof(*td));
+@@ -434,6 +490,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  
  	mt76_testmode_init_defaults(phy);
  
@@ -1619,7 +1876,7 @@
  	if (tb[MT76_TM_ATTR_TX_COUNT])
  		td->tx_count = nla_get_u32(tb[MT76_TM_ATTR_TX_COUNT]);
  
-@@ -454,7 +470,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -454,7 +513,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	    mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_DUTY_CYCLE],
  			   &td->tx_duty_cycle, 0, 99) ||
  	    mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
@@ -1629,7 +1886,7 @@
  		goto out;
  
  	if (tb[MT76_TM_ATTR_TX_LENGTH]) {
-@@ -494,7 +511,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -494,7 +554,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  			    idx >= ARRAY_SIZE(td->tx_power))
  				goto out;
  
@@ -1640,7 +1897,7 @@
  		}
  	}
  
-@@ -512,6 +531,22 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -512,6 +574,22 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		}
  	}
  
@@ -1663,7 +1920,7 @@
  	if (dev->test_ops->set_params) {
  		err = dev->test_ops->set_params(phy, tb, state);
  		if (err)
-@@ -561,6 +596,9 @@ mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg)
+@@ -561,6 +639,9 @@ mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg)
  	    nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_PACKETS, rx_packets,
  			      MT76_TM_STATS_ATTR_PAD) ||
  	    nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_FCS_ERROR, rx_fcs_error,
@@ -1673,7 +1930,7 @@
  			      MT76_TM_STATS_ATTR_PAD))
  		return -EMSGSIZE;
  
-@@ -625,6 +663,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -625,6 +706,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_SGI, td->tx_rate_sgi) ||
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_LDPC, td->tx_rate_ldpc) ||
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) ||
@@ -1682,11 +1939,30 @@
  	    (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_LTF) &&
  	     nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
  	    (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
+@@ -640,7 +723,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+ 	    (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER_CONTROL) &&
+ 	     nla_put_u8(msg, MT76_TM_ATTR_TX_POWER_CONTROL, td->tx_power_control)) ||
+ 	    (mt76_testmode_param_present(td, MT76_TM_ATTR_FREQ_OFFSET) &&
+-	     nla_put_u8(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
++	     nla_put_u32(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
+ 		goto out;
+ 
+ 	if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER)) {
 diff --git a/testmode.h b/testmode.h
-index a40cd74..141bb86 100644
+index a40cd74b..96872e8c 100644
 --- a/testmode.h
 +++ b/testmode.h
-@@ -19,6 +19,7 @@
+@@ -5,7 +5,8 @@
+ #ifndef __MT76_TESTMODE_H
+ #define __MT76_TESTMODE_H
+ 
+-#define MT76_TM_TIMEOUT	10
++#define MT76_TM_TIMEOUT			10
++#define MT76_TM_EEPROM_BLOCK_SIZE	16
+ 
+ /**
+  * enum mt76_testmode_attr - testmode attributes inside NL80211_ATTR_TESTDATA
+@@ -19,6 +20,7 @@
   * @MT76_TM_ATTR_MTD_OFFSET: offset of eeprom data within the partition (u32)
   * @MT76_TM_ATTR_BAND_IDX: band idx of the chip (u8)
   *
@@ -1694,7 +1970,7 @@
   * @MT76_TM_ATTR_TX_COUNT: configured number of frames to send when setting
   *	state to MT76_TM_STATE_TX_FRAMES (u32)
   * @MT76_TM_ATTR_TX_PENDING: pending frames during MT76_TM_STATE_TX_FRAMES (u32)
-@@ -39,6 +40,11 @@
+@@ -39,6 +41,11 @@
   *
   * @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr)
   *
@@ -1706,7 +1982,7 @@
   * @MT76_TM_ATTR_TX_SPE_IDX: tx spatial extension index (u8)
   *
   * @MT76_TM_ATTR_TX_DUTY_CYCLE: packet tx duty cycle (u8)
-@@ -48,6 +54,29 @@
+@@ -48,6 +55,29 @@
   * @MT76_TM_ATTR_DRV_DATA: driver specific netlink attrs (nested)
   *
   * @MT76_TM_ATTR_MAC_ADDRS: array of nested MAC addresses (nested)
@@ -1736,7 +2012,7 @@
   */
  enum mt76_testmode_attr {
  	MT76_TM_ATTR_UNSPEC,
-@@ -59,6 +88,7 @@ enum mt76_testmode_attr {
+@@ -59,6 +89,7 @@ enum mt76_testmode_attr {
  	MT76_TM_ATTR_MTD_OFFSET,
  	MT76_TM_ATTR_BAND_IDX,
  
@@ -1744,7 +2020,7 @@
  	MT76_TM_ATTR_TX_COUNT,
  	MT76_TM_ATTR_TX_LENGTH,
  	MT76_TM_ATTR_TX_RATE_MODE,
-@@ -76,6 +106,8 @@ enum mt76_testmode_attr {
+@@ -76,6 +107,8 @@ enum mt76_testmode_attr {
  	MT76_TM_ATTR_FREQ_OFFSET,
  
  	MT76_TM_ATTR_STATS,
@@ -1753,7 +2029,7 @@
  
  	MT76_TM_ATTR_TX_SPE_IDX,
  
-@@ -86,6 +118,27 @@ enum mt76_testmode_attr {
+@@ -86,6 +119,27 @@ enum mt76_testmode_attr {
  	MT76_TM_ATTR_DRV_DATA,
  
  	MT76_TM_ATTR_MAC_ADDRS,
@@ -1781,7 +2057,7 @@
  
  	/* keep last */
  	NUM_MT76_TM_ATTRS,
-@@ -103,6 +156,8 @@ enum mt76_testmode_attr {
+@@ -103,6 +157,8 @@ enum mt76_testmode_attr {
   * @MT76_TM_STATS_ATTR_RX_FCS_ERROR: number of rx packets with FCS error (u64)
   * @MT76_TM_STATS_ATTR_LAST_RX: information about the last received packet
   *	see &enum mt76_testmode_rx_attr
@@ -1790,7 +2066,7 @@
   */
  enum mt76_testmode_stats_attr {
  	MT76_TM_STATS_ATTR_UNSPEC,
-@@ -115,6 +170,7 @@ enum mt76_testmode_stats_attr {
+@@ -115,6 +171,7 @@ enum mt76_testmode_stats_attr {
  	MT76_TM_STATS_ATTR_RX_PACKETS,
  	MT76_TM_STATS_ATTR_RX_FCS_ERROR,
  	MT76_TM_STATS_ATTR_LAST_RX,
@@ -1798,7 +2074,7 @@
  
  	/* keep last */
  	NUM_MT76_TM_STATS_ATTRS,
-@@ -127,6 +183,7 @@ enum mt76_testmode_stats_attr {
+@@ -127,6 +184,7 @@ enum mt76_testmode_stats_attr {
   *
   * @MT76_TM_RX_ATTR_FREQ_OFFSET: frequency offset (s32)
   * @MT76_TM_RX_ATTR_RCPI: received channel power indicator (array, u8)
@@ -1806,7 +2082,7 @@
   * @MT76_TM_RX_ATTR_IB_RSSI: internal inband RSSI (array, s8)
   * @MT76_TM_RX_ATTR_WB_RSSI: internal wideband RSSI (array, s8)
   * @MT76_TM_RX_ATTR_SNR: signal-to-noise ratio (u8)
-@@ -136,6 +193,7 @@ enum mt76_testmode_rx_attr {
+@@ -136,6 +194,7 @@ enum mt76_testmode_rx_attr {
  
  	MT76_TM_RX_ATTR_FREQ_OFFSET,
  	MT76_TM_RX_ATTR_RCPI,
@@ -1814,7 +2090,7 @@
  	MT76_TM_RX_ATTR_IB_RSSI,
  	MT76_TM_RX_ATTR_WB_RSSI,
  	MT76_TM_RX_ATTR_SNR,
-@@ -179,6 +237,9 @@ enum mt76_testmode_state {
+@@ -179,6 +238,9 @@ enum mt76_testmode_state {
   * @MT76_TM_TX_MODE_HE_EXT_SU: 802.11ax extended-range SU
   * @MT76_TM_TX_MODE_HE_TB: 802.11ax trigger-based
   * @MT76_TM_TX_MODE_HE_MU: 802.11ax multi-user MIMO
@@ -1824,7 +2100,7 @@
   */
  enum mt76_testmode_tx_mode {
  	MT76_TM_TX_MODE_CCK,
-@@ -189,6 +250,9 @@ enum mt76_testmode_tx_mode {
+@@ -189,12 +251,33 @@ enum mt76_testmode_tx_mode {
  	MT76_TM_TX_MODE_HE_EXT_SU,
  	MT76_TM_TX_MODE_HE_TB,
  	MT76_TM_TX_MODE_HE_MU,
@@ -1834,8 +2110,32 @@
  
  	/* keep last */
  	NUM_MT76_TM_TX_MODES,
+ 	MT76_TM_TX_MODE_MAX = NUM_MT76_TM_TX_MODES - 1,
+ };
+ 
++/**
++ * enum mt76_testmode_eeprom_action - eeprom setting actions
++ *
++ * @MT76_TM_EEPROM_ACTION_UPDATE_DATA: update rf values to specific
++ *	eeprom data block
++ * @MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE: send updated eeprom data to fw
++ * @MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE: write eeprom data back to efuse
++ */
++enum mt76_testmode_eeprom_action {
++	MT76_TM_EEPROM_ACTION_UPDATE_DATA,
++	MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE,
++	MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE,
++
++	/* keep last */
++	NUM_MT76_TM_EEPROM_ACTION,
++	MT76_TM_EEPROM_ACTION_MAX = NUM_MT76_TM_EEPROM_ACTION - 1,
++};
++
+ extern const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS];
+ 
+ #endif
 diff --git a/tools/fields.c b/tools/fields.c
-index e3f6908..055f90f 100644
+index e3f69089..055f90f3 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -10,6 +10,7 @@ static const char * const testmode_state[] = {
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1005-mtk-wifi-mt76-testmode-add-testmode-pre-calibration-.patch
similarity index 92%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1005-mtk-wifi-mt76-testmode-add-testmode-pre-calibration-.patch
index 1185d02..e1e2ecc 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1005-mtk-wifi-mt76-testmode-add-testmode-pre-calibration-.patch
@@ -1,11 +1,10 @@
-From db3b9fa4bc9c70231b7237dee2f7bcf35c6135f2 Mon Sep 17 00:00:00 2001
+From 52b8f9d42643b5103fc608fb1848e03eac88834c Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 31 Mar 2023 11:27:24 +0800
-Subject: [PATCH 43/98] wifi: mt76: testmode: add testmode pre-calibration
- support
+Subject: [PATCH 1005/1041] mtk: wifi: mt76: testmode: add testmode
+ pre-calibration support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Change-Id: If8a6cc02fa20e35f079c826e0571e8c04c3f9c7e
 ---
  mac80211.c        |  21 ---
  mt76.h            |  22 +++
@@ -22,7 +21,7 @@
  12 files changed, 632 insertions(+), 23 deletions(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index f10ca90..9c582cb 100644
+index d31cf9ff..87dcc8a3 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -7,27 +7,6 @@
@@ -54,7 +53,7 @@
  	CHAN2G(1, 2412),
  	CHAN2G(2, 2417),
 diff --git a/mt76.h b/mt76.h
-index feb861c..fc69d3e 100644
+index 7951b90e..b0897ac2 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -18,6 +18,27 @@
@@ -85,19 +84,19 @@
  #define MT_MCU_RING_SIZE	32
  #define MT_RX_BUF_SIZE		2048
  #define MT_SKB_HEAD_LEN		256
-@@ -694,6 +715,7 @@ struct mt76_testmode_ops {
- 	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
+@@ -697,6 +718,7 @@ struct mt76_testmode_ops {
  	void (*reset_rx_stats)(struct mt76_phy *phy);
  	void (*tx_stop)(struct mt76_phy *phy);
+ 	int (*set_eeprom)(struct mt76_phy *phy, u32 offset, u8 *val, u8 action);
 +	int (*dump_precal)(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int type);
  };
  
  #define MT_TM_FW_RX_COUNT	BIT(0)
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index bbf600b..d65ecf0 100644
+index 0a55a4be..3447f523 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1023,8 +1023,10 @@ enum {
+@@ -1031,8 +1031,10 @@ enum {
  	MCU_UNI_EVENT_RDD_REPORT = 0x11,
  	MCU_UNI_EVENT_ROC = 0x27,
  	MCU_UNI_EVENT_TX_DONE = 0x2d,
@@ -105,11 +104,11 @@
  	MCU_UNI_EVENT_THERMAL = 0x35,
  	MCU_UNI_EVENT_NIC_CAPAB = 0x43,
 +	MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
+ 	MCU_UNI_EVENT_WED_RRO = 0x57,
  	MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
  	MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
- };
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index e4c4b86..b88fd64 100644
+index 8fb1015e..29a245ce 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -12,6 +12,42 @@ static bool testmode_enable;
@@ -154,9 +153,9 @@
 +
  static int mt7996_check_eeprom(struct mt7996_dev *dev)
  {
- 	u8 *eeprom = dev->mt76.eeprom.data;
-@@ -36,6 +72,36 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
- 		return MT7996_EEPROM_DEFAULT;
+ #define FEM_INT				0
+@@ -71,6 +107,36 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ 	}
  }
  
 +int
@@ -193,7 +192,7 @@
  mt7996_eeprom_load_default(struct mt7996_dev *dev)
  {
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 343e65e..7ff290f 100644
+index de3ff4e2..849b8bca 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -14,6 +14,7 @@ enum mt7996_eeprom_field {
@@ -204,9 +203,9 @@
  	MT_EE_TESTMODE_EN =	0x1af,
  	MT_EE_MAC_ADDR3 =	0x2c0,
  	MT_EE_RATE_DELTA_2G =	0x1400,
-@@ -31,6 +32,52 @@ enum mt7996_eeprom_field {
- #define MT_EE_WIFI_CONF1_BAND_SEL		GENMASK(5, 3)
+@@ -32,6 +33,52 @@ enum mt7996_eeprom_field {
  #define MT_EE_WIFI_CONF2_BAND_SEL		GENMASK(2, 0)
+ #define MT_EE_WIFI_PA_LNA_CONFIG		GENMASK(1, 0)
  
 +#define MT_EE_WIFI_CAL_GROUP_2G			BIT(0)
 +#define MT_EE_WIFI_CAL_GROUP_5G			BIT(1)
@@ -258,12 +257,12 @@
  #define MT_EE_WIFI_CONF2_TX_PATH_BAND1		GENMASK(2, 0)
  #define MT_EE_WIFI_CONF2_TX_PATH_BAND2		GENMASK(5, 3)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index a008c08..d6f4e22 100644
+index 099ff74f..eb346a9c 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -623,6 +623,11 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
- 	case MCU_UNI_EVENT_ALL_STA_INFO:
- 		mt7996_mcu_rx_all_sta_info_event(dev, skb);
+@@ -712,6 +712,11 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 	case MCU_UNI_EVENT_WED_RRO:
+ 		mt7996_mcu_wed_rro_event(dev, skb);
  		break;
 +#ifdef CONFIG_NL80211_TESTMODE
 +	case MCU_UNI_EVENT_TESTMODE_CTRL:
@@ -274,7 +273,7 @@
  		break;
  	}
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 3c535be..684c254 100644
+index 5af55492..e7609c63 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
 @@ -385,6 +385,9 @@ struct mt7996_dev {
@@ -285,9 +284,9 @@
 +	u32 cur_prek_offset;
 +
  	struct {
- 		u8 table_mask;
+ 		u16 table_mask;
  		u8 n_agrt;
-@@ -521,6 +524,7 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
+@@ -505,6 +508,7 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
  int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
  				   struct ieee80211_channel *chan);
  s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band);
@@ -295,10 +294,10 @@
  int mt7996_dma_init(struct mt7996_dev *dev);
  void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
  void mt7996_dma_prefetch(struct mt7996_dev *dev);
-@@ -606,6 +610,9 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
- int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
- int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
- void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+@@ -589,6 +593,9 @@ void mt7996_mcu_exit(struct mt7996_dev *dev);
+ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
+ int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id);
+ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
 +#ifdef CONFIG_NL80211_TESTMODE
 +void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
 +#endif
@@ -306,7 +305,7 @@
  static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
  {
 diff --git a/mt7996/testmode.c b/mt7996/testmode.c
-index fb041c3..8ceea00 100644
+index 96079c22..36be0ff8 100644
 --- a/mt7996/testmode.c
 +++ b/mt7996/testmode.c
 @@ -7,6 +7,8 @@
@@ -318,7 +317,7 @@
  
  enum {
  	TM_CHANGED_TXPOWER,
-@@ -396,6 +398,436 @@ mt7996_tm_set_tx_cont(struct mt7996_phy *phy, bool en)
+@@ -397,6 +399,436 @@ mt7996_tm_set_tx_cont(struct mt7996_phy *phy, bool en)
  	}
  }
  
@@ -755,7 +754,7 @@
  static void
  mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
  {
-@@ -452,6 +884,10 @@ mt7996_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -454,6 +886,10 @@ mt7996_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
  	else if (prev_state == MT76_TM_STATE_OFF ||
  		 state == MT76_TM_STATE_OFF)
  		mt7996_tm_init(phy, !(state == MT76_TM_STATE_OFF));
@@ -766,14 +765,14 @@
  
  	if ((state == MT76_TM_STATE_IDLE &&
  	     prev_state == MT76_TM_STATE_OFF) ||
-@@ -671,4 +1107,5 @@ const struct mt76_testmode_ops mt7996_testmode_ops = {
- 	.dump_stats = mt7996_tm_dump_stats,
+@@ -737,4 +1173,5 @@ const struct mt76_testmode_ops mt7996_testmode_ops = {
  	.reset_rx_stats = mt7996_tm_reset_trx_stats,
  	.tx_stop = mt7996_tm_tx_stop,
+ 	.set_eeprom = mt7996_tm_set_eeprom,
 +	.dump_precal = mt7996_tm_dump_precal,
  };
 diff --git a/mt7996/testmode.h b/mt7996/testmode.h
-index e4d55a6..17c1456 100644
+index 319ef257..9bfb86f2 100644
 --- a/mt7996/testmode.h
 +++ b/mt7996/testmode.h
 @@ -34,6 +34,12 @@ enum bw_mapping_method {
@@ -835,10 +834,10 @@
  	RF_OPER_NORMAL,
  	RF_OPER_RF_TEST,
 diff --git a/testmode.c b/testmode.c
-index bbe8230..e66b54a 100644
+index db2cc255..7ed58a77 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -631,6 +631,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -674,6 +674,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  
  	mutex_lock(&dev->mutex);
  
@@ -858,10 +857,10 @@
  		err = -EINVAL;
  
 diff --git a/testmode.h b/testmode.h
-index 141bb86..db8ff53 100644
+index 96872e8c..d6601cdc 100644
 --- a/testmode.h
 +++ b/testmode.h
-@@ -219,6 +219,14 @@ enum mt76_testmode_state {
+@@ -220,6 +220,14 @@ enum mt76_testmode_state {
  	MT76_TM_STATE_TX_FRAMES,
  	MT76_TM_STATE_RX_FRAMES,
  	MT76_TM_STATE_TX_CONT,
@@ -877,7 +876,7 @@
  
  	/* keep last */
 diff --git a/tools/fields.c b/tools/fields.c
-index 055f90f..b012276 100644
+index 055f90f3..b0122763 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -11,6 +11,14 @@ static const char * const testmode_state[] = {
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1006-mtk-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-d.patch
similarity index 60%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1006-mtk-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-d.patch
index 78ae8ad..90ff7e8 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1006-mtk-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-d.patch
@@ -1,27 +1,29 @@
-From b02a81b168e9c42350c1f6a9b7e38c60c76cc692 Mon Sep 17 00:00:00 2001
+From d96436bbd8f0aa903bb0ee905a2654f81ebbfbff Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Mon, 8 May 2023 09:03:50 +0800
-Subject: [PATCH 38/98] wifi: mt76: mt7996: enable SCS feature for mt7996
- driver
+Subject: [PATCH 1006/1041] mtk: wifi: mt76: mt7996: enable SCS feature for
+ mt7996 driver
 
 Enable Smart Carrier Sense algorithn by default to improve performance
 in a noisy environment.
 
 Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
 ---
- mt76_connac_mcu.h |   1 +
- mt7996/init.c     |   1 +
- mt7996/main.c     |   7 +++
- mt7996/mcu.c      | 123 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      |   6 +++
- mt7996/mt7996.h   |  15 ++++++
- 6 files changed, 153 insertions(+)
+ mt76_connac_mcu.h    |   1 +
+ mt7996/init.c        |   1 +
+ mt7996/mac.c         |   2 +
+ mt7996/main.c        |   7 +++
+ mt7996/mcu.c         | 105 +++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.h         |   6 +++
+ mt7996/mt7996.h      |  15 +++++++
+ mt7996/mtk_debugfs.c |  11 +++++
+ 8 files changed, 148 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 4d054bd..fae76c9 100644
+index 3447f523..5e1b15c4 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1232,6 +1232,7 @@ enum {
+@@ -1250,6 +1250,7 @@ enum {
  	MCU_UNI_CMD_GET_STAT_INFO = 0x23,
  	MCU_UNI_CMD_SNIFFER = 0x24,
  	MCU_UNI_CMD_SR = 0x25,
@@ -30,10 +32,10 @@
  	MCU_UNI_CMD_SET_DBDC_PARMS = 0x28,
  	MCU_UNI_CMD_TXPOWER = 0x2b,
 diff --git a/mt7996/init.c b/mt7996/init.c
-index fed74d0..f393e04 100644
+index 7bfebd38..c9c7c20a 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -1211,6 +1211,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1378,6 +1378,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	dev->mt76.phy.priv = &dev->phy;
  	INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work);
  	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work);
@@ -41,8 +43,28 @@
  	INIT_LIST_HEAD(&dev->sta_rc_list);
  	INIT_LIST_HEAD(&dev->twt_list);
  
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 924b05e4..e307ddc3 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1798,6 +1798,7 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
+ 		cancel_delayed_work_sync(&phy2->mt76->mac_work);
+ 	if (phy3)
+ 		cancel_delayed_work_sync(&phy3->mt76->mac_work);
++	cancel_delayed_work_sync(&dev->scs_work);
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 	for (i = 0; i < 10; i++) {
+@@ -1833,6 +1834,7 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
+ 		ieee80211_queue_delayed_work(phy3->mt76->hw,
+ 					     &phy3->mt76->mac_work,
+ 					     MT7996_WATCHDOG_TIME);
++	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
+ }
+ 
+ void mt7996_mac_reset_work(struct work_struct *work)
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 226235c..6fa4a65 100644
+index 2a93e8c2..97f1ef8c 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -73,11 +73,17 @@ int mt7996_run(struct ieee80211_hw *hw)
@@ -72,10 +94,10 @@
  	mutex_lock(&dev->mt76.mutex);
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 141b838..6cedc39 100644
+index eb346a9c..cc417039 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -4346,3 +4346,126 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+@@ -4609,3 +4609,108 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
  	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TXPOWER),
  				 &req, sizeof(req), false);
  }
@@ -108,27 +130,7 @@
 +void mt7996_sta_rssi_work(void *data, struct ieee80211_sta *sta)
 +{
 +	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
-+	struct mt7996_dev *dev = (struct mt7996_dev *)data;
-+	struct mt7996_phy *poll_phy;
-+	u8 band_idx = msta->wcid.phy_idx;
-+
-+	switch (band_idx) {
-+	case MT_BAND0:
-+		poll_phy = dev->mphy.priv;
-+		break;
-+	case MT_BAND1:
-+		poll_phy = mt7996_phy2(dev);
-+		break;
-+	case MT_BAND2:
-+		poll_phy = mt7996_phy3(dev);
-+		break;
-+	default:
-+		poll_phy = NULL;
-+		break;
-+	}
-+
-+	if (!poll_phy->scs_ctrl.scs_enable)
-+		return;
++	struct mt7996_phy *poll_phy = (struct mt7996_phy *) data;
 +
 +	if (poll_phy->scs_ctrl.sta_min_rssi > msta->ack_signal)
 +		poll_phy->scs_ctrl.sta_min_rssi = msta->ack_signal;
@@ -141,8 +143,6 @@
 +	bool scs_enable_flag = false;
 +	u8 i;
 +
-+	ieee80211_iterate_stations_atomic(dev->mphy.hw, mt7996_sta_rssi_work, dev);
-+
 +	for (i = 0; i < __MT_MAX_BAND; i++) {
 +		struct mt7996_phy *phy;
 +
@@ -161,13 +161,17 @@
 +			break;
 +		}
 +
-+		if (phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state) &&
-+		    phy->scs_ctrl.scs_enable) {
-+			scs_enable_flag = true;
-+			if (mt7996_mcu_set_scs_stats(phy))
-+				dev_err(dev->mt76.dev, "Failed to send scs mcu cmd\n");
-+			phy->scs_ctrl.sta_min_rssi = 0;
-+		}
++		if (!phy || !test_bit(MT76_STATE_RUNNING, &phy->mt76->state) ||
++		    !phy->scs_ctrl.scs_enable)
++			continue;
++
++		ieee80211_iterate_stations_atomic(phy->mt76->hw,
++						  mt7996_sta_rssi_work, phy);
++
++		scs_enable_flag = true;
++		if (mt7996_mcu_set_scs_stats(phy))
++			dev_err(dev->mt76.dev, "Failed to send scs mcu cmd\n");
++		phy->scs_ctrl.sta_min_rssi = 0;
 +	}
 +
 +	if (scs_enable_flag)
@@ -203,10 +207,10 @@
 +				 &req, sizeof(req), false);
 +}
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 16ffc3d..ff9cc9c 100644
+index 325c3c97..4f4994d8 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -875,6 +875,12 @@ enum {
+@@ -960,6 +960,12 @@ enum {
  	UNI_CMD_PP_EN_CTRL,
  };
  
@@ -220,10 +224,10 @@
  #define MT7996_PATCH_SCRAMBLE_KEY	GENMASK(15, 8)
  #define MT7996_PATCH_AES_KEY		GENMASK(7, 0)
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index efdcff7..eb48dbd 100644
+index e7609c63..384157c8 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -193,6 +193,16 @@ struct mt7996_hif {
+@@ -233,6 +233,16 @@ struct mt7996_hif {
  	int irq;
  };
  
@@ -240,7 +244,7 @@
  struct mt7996_wed_rro_addr {
  	u32 head_low;
  	u32 head_high : 4;
-@@ -235,6 +245,8 @@ struct mt7996_phy {
+@@ -280,6 +290,8 @@ struct mt7996_phy {
  
  	bool has_aux_rx;
  
@@ -249,7 +253,7 @@
  #ifdef CONFIG_NL80211_TESTMODE
  	struct {
  		u32 *reg_backup;
-@@ -280,6 +292,7 @@ struct mt7996_dev {
+@@ -326,6 +338,7 @@ struct mt7996_dev {
  	struct work_struct rc_work;
  	struct work_struct dump_work;
  	struct work_struct reset_work;
@@ -257,15 +261,44 @@
  	wait_queue_head_t reset_wait;
  	struct {
  		u32 state;
-@@ -555,6 +568,8 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
- void mt7996_mcu_exit(struct mt7996_dev *dev);
- int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
- int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
+@@ -596,6 +609,8 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+ #ifdef CONFIG_NL80211_TESTMODE
+ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #endif
 +int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
 +void mt7996_mcu_scs_sta_poll(struct work_struct *work);
  
  static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
  {
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 53b11d54..ccb147e9 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2407,6 +2407,16 @@ static int mt7996_token_read(struct seq_file *s, void *data)
+ 	return 0;
+ }
+ 
++static int
++mt7996_scs_enable_set(void *data, u64 val)
++{
++	struct mt7996_phy *phy = data;
++
++	return mt7996_mcu_set_scs(phy, (u8) val);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_scs_enable, NULL,
++			 mt7996_scs_enable_set, "%lld\n");
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -2477,6 +2487,7 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ 	debugfs_create_devm_seqfile(dev->mt76.dev, "token", dir, mt7996_token_read);
+ 
+ 	debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
++	debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
+ 
+ 	return 0;
+ }
 -- 
 2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-mt7996-add-txpower-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1007-mtk-wifi-mt76-mt7996-add-txpower-support.patch
similarity index 91%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-mt7996-add-txpower-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1007-mtk-wifi-mt76-mt7996-add-txpower-support.patch
index 0a0d376..8244fc7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-mt7996-add-txpower-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1007-mtk-wifi-mt76-mt7996-add-txpower-support.patch
@@ -1,26 +1,25 @@
-From 1c1dd57bde8919fdf04ef914b781eb6183582562 Mon Sep 17 00:00:00 2001
+From f656a23959ac8662dbb38b079a7afd440367578c Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 24 Mar 2023 23:35:30 +0800
-Subject: [PATCH 39/98] wifi: mt76: mt7996: add txpower support
+Subject: [PATCH 1007/1041] mtk: wifi: mt76: mt7996: add txpower support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Change-Id: Ic3e7b17f3664fa7f774137572f885359fa2ec93b
 ---
  mt7996/eeprom.c      |  34 +++++++
  mt7996/eeprom.h      |  42 ++++++++
  mt7996/mcu.h         |   2 +
- mt7996/mt7996.h      |   3 +
+ mt7996/mt7996.h      |   1 +
  mt7996/mtk_debugfs.c | 229 +++++++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.c     |  23 +++++
- mt7996/mtk_mcu.h     |  78 +++++++++++++++
+ mt7996/mtk_mcu.h     |  79 +++++++++++++++
  mt7996/regs.h        |  29 +++---
- 8 files changed, 429 insertions(+), 11 deletions(-)
+ 8 files changed, 428 insertions(+), 11 deletions(-)
 
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 3276740..e4c4b86 100644
+index 29a245ce..6c1966b7 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -296,3 +296,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
+@@ -401,3 +401,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
  
  	return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
  }
@@ -59,10 +58,10 @@
 +	[SKU_EHT3x996_484] = 16,
 +};
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 9ea3667..343e65e 100644
+index 849b8bca..23d4929d 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
-@@ -75,4 +75,46 @@ mt7996_get_channel_group_6g(int channel)
+@@ -123,4 +123,46 @@ mt7996_get_channel_group_6g(int channel)
  	return DIV_ROUND_UP(channel - 29, 32);
  }
  
@@ -110,10 +109,10 @@
 +
  #endif
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index ff9cc9c..71dc165 100644
+index 4f4994d8..887d9b49 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -826,6 +826,7 @@ struct tx_power_ctrl {
+@@ -911,6 +911,7 @@ struct tx_power_ctrl {
  		bool ate_mode_enable;
  		bool percentage_ctrl_enable;
  		bool bf_backoff_enable;
@@ -121,7 +120,7 @@
  		u8 power_drop_level;
  	};
  	u8 band_idx;
-@@ -839,6 +840,7 @@ enum {
+@@ -924,6 +925,7 @@ enum {
  	UNI_TXPOWER_BACKOFF_POWER_LIMIT_CTRL = 3,
  	UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4,
  	UNI_TXPOWER_ATE_MODE_CTRL = 6,
@@ -130,33 +129,24 @@
  
  enum {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index eb48dbd..23d1614 100644
+index 384157c8..18a6a46d 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -63,6 +63,8 @@
- 
- #define MT7996_BUILD_TIME_LEN		24
- 
-+#define MT7996_SKU_RATE_NUM		417
-+
- #define MT7996_RRO_MAX_SESSION		1024
- #define MT7996_RRO_WINDOW_MAX_LEN	1024
- #define MT7996_RRO_ADDR_ELEM_LEN	128
-@@ -568,6 +570,7 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
- void mt7996_mcu_exit(struct mt7996_dev *dev);
- int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
- int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
+@@ -609,6 +609,7 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+ #ifdef CONFIG_NL80211_TESTMODE
+ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #endif
 +int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
  int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
  void mt7996_mcu_scs_sta_poll(struct work_struct *work);
  
 diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
-index 5aa5c94..57fcbab 100644
+index ccb147e9..93428851 100644
 --- a/mt7996/mtk_debugfs.c
 +++ b/mt7996/mtk_debugfs.c
-@@ -2325,6 +2325,232 @@ static int mt7996_sta_info(struct seq_file *s, void *data)
- 	return 0;
- }
+@@ -2417,6 +2417,232 @@ mt7996_scs_enable_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_scs_enable, NULL,
+ 			 mt7996_scs_enable_set, "%lld\n");
  
 +static int
 +mt7996_txpower_level_set(void *data, u64 val)
@@ -387,7 +377,7 @@
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
  {
  	struct mt7996_dev *dev = phy->dev;
-@@ -2367,6 +2593,9 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+@@ -2480,6 +2706,9 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
  
  	debugfs_create_devm_seqfile(dev->mt76.dev, "tr_info", dir,
  				    mt7996_trinfo_read);
@@ -398,10 +388,10 @@
  	debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
  				    mt7996_wtbl_read);
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
-index e887016..f772243 100644
+index c16b25ab..e56ddd8f 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
-@@ -12,7 +12,30 @@
+@@ -12,8 +12,31 @@
  
  #ifdef CONFIG_MTK_DEBUG
  
@@ -431,14 +421,15 @@
 +	return 0;
 +}
  
- #endif
+ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val)
+ {
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
-index e741aa2..beb1aba 100644
+index 7f4d4e02..1eb27831 100644
 --- a/mt7996/mtk_mcu.h
 +++ b/mt7996/mtk_mcu.h
-@@ -10,6 +10,84 @@
- 
- #ifdef CONFIG_MTK_DEBUG
+@@ -14,6 +14,85 @@ enum {
+ 	UNI_CMD_MURU_DBG_INFO = 0x18,
+ };
  
 +struct txpower_basic_info {
 +	u8 category;
@@ -518,14 +509,15 @@
 +	UNI_TXPOWER_BASIC_INFO = 0,
 +	UNI_TXPOWER_PHY_RATE_INFO = 5,
 +};
- 
++
  #endif
  
+ #endif
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index de5df91..565022a 100644
+index 4c20a67d..e94f9a90 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -672,24 +672,31 @@ enum offs_rev {
+@@ -693,24 +693,31 @@ enum offs_rev {
  						 ((_wf) << 16) + (ofs))
  #define MT_WF_PHYRX_CSD_IRPI(_band, _wf)	MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1008-mtk-wifi-mt76-mt7996-add-single-sku.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1008-mtk-wifi-mt76-mt7996-add-single-sku.patch
new file mode 100644
index 0000000..f97c32c
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1008-mtk-wifi-mt76-mt7996-add-single-sku.patch
@@ -0,0 +1,277 @@
+From 646335d03eb96579459ba8f07c2e721d77188b10 Mon Sep 17 00:00:00 2001
+From: "Allen.Ye" <allen.ye@mediatek.com>
+Date: Mon, 10 Jul 2023 19:56:16 +0800
+Subject: [PATCH 1008/1041] mtk: wifi: mt76: mt7996: add single sku
+
+Add single sku and default enable sku.
+
+Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
+---
+ eeprom.c          | 50 ++++++++++++++++++++++++++++++++++++++++++-----
+ mt76.h            |  9 +++++++++
+ mt76_connac_mcu.c |  2 +-
+ mt7996/init.c     |  2 ++
+ mt7996/main.c     |  9 +++++++++
+ mt7996/mcu.c      | 41 ++++++++++++++++++++++++++++++++++----
+ mt7996/mt7996.h   |  1 +
+ 7 files changed, 104 insertions(+), 10 deletions(-)
+
+diff --git a/eeprom.c b/eeprom.c
+index 85bd2a29..c5be2843 100644
+--- a/eeprom.c
++++ b/eeprom.c
+@@ -341,6 +341,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
+ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ 			      struct ieee80211_channel *chan,
+ 			      struct mt76_power_limits *dest,
++			      struct mt76_power_path_limits *dest_path,
+ 			      s8 target_power)
+ {
+ 	struct mt76_dev *dev = phy->dev;
+@@ -348,16 +349,20 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ 	const __be32 *val;
+ 	char name[16];
+ 	u32 mcs_rates = dev->drv->mcs_rates;
+-	u32 ru_rates = ARRAY_SIZE(dest->ru[0]);
+ 	char band;
+ 	size_t len;
+-	s8 max_power = 0;
++	s8 max_power = -127;
++	s8 max_power_backoff = -127;
+ 	s8 txs_delta;
++	int n_chains = hweight16(phy->chainmask);
++	s8 target_power_combine = target_power + mt76_tx_power_nss_delta(n_chains);
+ 
+ 	if (!mcs_rates)
+-		mcs_rates = 10;
++		mcs_rates = 12;
+ 
+ 	memset(dest, target_power, sizeof(*dest));
++	if (dest_path != NULL)
++		memset(dest_path, 0, sizeof(*dest_path));
+ 
+ 	if (!IS_ENABLED(CONFIG_OF))
+ 		return target_power;
+@@ -405,12 +410,47 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ 				     ARRAY_SIZE(dest->mcs), val, len,
+ 				     target_power, txs_delta, &max_power);
+ 
+-	val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
++	val = mt76_get_of_array(np, "rates-ru", &len, ARRAY_SIZE(dest->ru[0]) + 1);
+ 	mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
+ 				     ARRAY_SIZE(dest->ru), val, len,
+ 				     target_power, txs_delta, &max_power);
+ 
+-	return max_power;
++	val = mt76_get_of_array(np, "rates-eht", &len, ARRAY_SIZE(dest->eht[0]) + 1);
++	mt76_apply_multi_array_limit(dest->eht[0], ARRAY_SIZE(dest->eht[0]),
++				     ARRAY_SIZE(dest->eht), val, len,
++				     target_power, txs_delta, &max_power);
++
++	if (dest_path == NULL)
++		return max_power;
++
++	max_power_backoff = max_power;
++
++	val = mt76_get_of_array(np, "paths-cck", &len, ARRAY_SIZE(dest_path->cck));
++	mt76_apply_array_limit(dest_path->cck, ARRAY_SIZE(dest_path->cck), val,
++			       target_power_combine, txs_delta, &max_power_backoff);
++
++	val = mt76_get_of_array(np, "paths-ofdm", &len, ARRAY_SIZE(dest_path->ofdm));
++	mt76_apply_array_limit(dest_path->ofdm, ARRAY_SIZE(dest_path->ofdm), val,
++			       target_power_combine, txs_delta, &max_power_backoff);
++
++	val = mt76_get_of_array(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest_path->ofdm_bf));
++	mt76_apply_array_limit(dest_path->ofdm_bf, ARRAY_SIZE(dest_path->ofdm_bf), val,
++			       target_power_combine, txs_delta, &max_power_backoff);
++
++	val = mt76_get_of_array(np, "paths-ru", &len, ARRAY_SIZE(dest_path->ru[0]) + 1);
++	mt76_apply_multi_array_limit(dest_path->ru[0], ARRAY_SIZE(dest_path->ru[0]),
++				     ARRAY_SIZE(dest_path->ru), val, len,
++				     target_power_combine, txs_delta, &max_power_backoff);
++
++	val = mt76_get_of_array(np, "paths-ru-bf", &len, ARRAY_SIZE(dest_path->ru_bf[0]) + 1);
++	mt76_apply_multi_array_limit(dest_path->ru_bf[0], ARRAY_SIZE(dest_path->ru_bf[0]),
++				     ARRAY_SIZE(dest_path->ru_bf), val, len,
++				     target_power_combine, txs_delta, &max_power_backoff);
++
++	if (max_power_backoff == target_power_combine)
++		return max_power;
++
++	return max_power_backoff;
+ }
+ EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
+ 
+diff --git a/mt76.h b/mt76.h
+index b0897ac2..19c445b5 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -1053,6 +1053,14 @@ struct mt76_power_limits {
+ 	s8 eht[16][16];
+ };
+ 
++struct mt76_power_path_limits {
++	s8 cck[5];
++	s8 ofdm[5];
++	s8 ofdm_bf[4];
++	s8 ru[16][15];
++	s8 ru_bf[16][15];
++};
++
+ struct mt76_ethtool_worker_info {
+ 	u64 *data;
+ 	int idx;
+@@ -1655,6 +1663,7 @@ mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan);
+ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ 			      struct ieee80211_channel *chan,
+ 			      struct mt76_power_limits *dest,
++			      struct mt76_power_path_limits *dest_path,
+ 			      s8 target_power);
+ 
+ static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q)
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index 52237583..6cb47699 100644
+--- a/mt76_connac_mcu.c
++++ b/mt76_connac_mcu.c
+@@ -2150,7 +2150,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
+ 			sar_power = mt76_get_sar_power(phy, &chan, reg_power);
+ 
+ 			mt76_get_rate_power_limits(phy, &chan, limits,
+-						   sar_power);
++						   NULL, sar_power);
+ 
+ 			tx_power_tlv.last_msg = ch_list[idx] == last_ch;
+ 			sku_tlbv.channel = ch_list[idx];
+diff --git a/mt7996/init.c b/mt7996/init.c
+index c9c7c20a..af2f4143 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -295,6 +295,7 @@ static void __mt7996_init_txpower(struct mt7996_phy *phy,
+ 	int nss_delta = mt76_tx_power_nss_delta(nss);
+ 	int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);
+ 	struct mt76_power_limits limits;
++	struct mt76_power_path_limits limits_path;
+ 
+ 	for (i = 0; i < sband->n_channels; i++) {
+ 		struct ieee80211_channel *chan = &sband->channels[i];
+@@ -303,6 +304,7 @@ static void __mt7996_init_txpower(struct mt7996_phy *phy,
+ 		target_power += pwr_delta;
+ 		target_power = mt76_get_rate_power_limits(phy->mt76, chan,
+ 							  &limits,
++							  &limits_path,
+ 							  target_power);
+ 		target_power += nss_delta;
+ 		target_power = DIV_ROUND_UP(target_power, 2);
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 97f1ef8c..9481fc5c 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -77,6 +77,15 @@ int mt7996_run(struct ieee80211_hw *hw)
+ 	if (ret)
+ 		goto out;
+ 
++#ifdef CONFIG_MTK_DEBUG
++	ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
++					   !dev->dbg.sku_disable);
++#else
++	ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL, true);
++#endif
++	if (ret)
++		goto out;
++
+ 	set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
+ 
+ 	ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index cc417039..d8e5c220 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -4491,6 +4491,7 @@ int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id)
+ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ {
+ #define TX_POWER_LIMIT_TABLE_RATE	0
++#define TX_POWER_LIMIT_TABLE_PATH	1
+ 	struct mt7996_dev *dev = phy->dev;
+ 	struct mt76_phy *mphy = phy->mt76;
+ 	struct ieee80211_hw *hw = mphy->hw;
+@@ -4504,22 +4505,23 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ 		u8 band_idx;
+ 	} __packed req = {
+ 		.tag = cpu_to_le16(UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL),
+-		.len = cpu_to_le16(sizeof(req) + MT7996_SKU_RATE_NUM - 4),
++		.len = cpu_to_le16(sizeof(req) + MT7996_SKU_PATH_NUM - 4),
+ 		.power_ctrl_id = UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL,
+ 		.power_limit_type = TX_POWER_LIMIT_TABLE_RATE,
+ 		.band_idx = phy->mt76->band_idx,
+ 	};
+ 	struct mt76_power_limits la = {};
++	struct mt76_power_path_limits la_path = {};
+ 	struct sk_buff *skb;
+-	int i, tx_power;
++	int i, ret, tx_power;
+ 
+ 	tx_power = mt7996_get_power_bound(phy, hw->conf.power_level);
+ 	tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
+-					      &la, tx_power);
++					      &la, &la_path, tx_power);
+ 	mphy->txpower_cur = tx_power;
+ 
+ 	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
+-				 sizeof(req) + MT7996_SKU_RATE_NUM);
++				 sizeof(req) + MT7996_SKU_PATH_NUM);
+ 	if (!skb)
+ 		return -ENOMEM;
+ 
+@@ -4542,6 +4544,37 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ 	/* eht */
+ 	skb_put_data(skb, &la.eht[0], sizeof(la.eht));
+ 
++	/* padding */
++	skb_put_zero(skb, MT7996_SKU_PATH_NUM - MT7996_SKU_RATE_NUM);
++
++	ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
++				    MCU_WM_UNI_CMD(TXPOWER), true);
++	if (ret)
++		return ret;
++
++	/* only set per-path power table when it's configured */
++	if (!la_path.ofdm[0])
++		return 0;
++
++	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
++				 sizeof(req) + MT7996_SKU_PATH_NUM);
++	if (!skb)
++		return -ENOMEM;
++	req.power_limit_type = TX_POWER_LIMIT_TABLE_PATH;
++
++	skb_put_data(skb, &req, sizeof(req));
++	skb_put_data(skb, &la_path.cck, sizeof(la_path.cck));
++	skb_put_data(skb, &la_path.ofdm, sizeof(la_path.ofdm));
++	skb_put_data(skb, &la_path.ofdm_bf, sizeof(la_path.ofdm_bf));
++
++	for (i = 0; i < 32; i++) {
++		bool bf = i % 2;
++		u8 idx = i / 2;
++		s8 *buf = bf ? la_path.ru_bf[idx] : la_path.ru[idx];
++
++		skb_put_data(skb, buf, sizeof(la_path.ru[0]));
++	}
++
+ 	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ 				     MCU_WM_UNI_CMD(TXPOWER), true);
+ }
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 18a6a46d..7e3d381e 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -71,6 +71,7 @@
+ #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
+ 
+ #define MT7996_SKU_RATE_NUM		417
++#define MT7996_SKU_PATH_NUM		494
+ 
+ #define MT7996_MAX_TWT_AGRT		16
+ #define MT7996_MAX_STA_TWT_AGRT		8
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1009-mtk-wifi-mt76-mt7996-add-binfile-mode-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1009-mtk-wifi-mt76-mt7996-add-binfile-mode-support.patch
new file mode 100644
index 0000000..ad36e1a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1009-mtk-wifi-mt76-mt7996-add-binfile-mode-support.patch
@@ -0,0 +1,366 @@
+From f7bb6a600c1dfd47dfc99ca7a80dac4178ea2581 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 31 Mar 2023 11:36:34 +0800
+Subject: [PATCH 1009/1041] mtk: wifi: mt76: mt7996: add binfile mode support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Fix binfile cannot sync precal data to atenl
+Binfile is viewed as efuse mode in atenl, so atenl does not allocate
+precal memory for its eeprom file
+Use mtd offset == 0xFFFFFFFF to determine whether it is binfile or flash mode
+Add support for loading precal in binfile mode
+
+Align upstream
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ eeprom.c             |  25 +++++++++++
+ mt76.h               |   3 ++
+ mt7996/eeprom.c      | 103 ++++++++++++++++++++++++++++++++++++++++---
+ mt7996/eeprom.h      |   7 +++
+ mt7996/mt7996.h      |   4 ++
+ mt7996/mtk_debugfs.c |  41 +++++++++++++++++
+ testmode.h           |   2 +-
+ 7 files changed, 179 insertions(+), 6 deletions(-)
+
+diff --git a/eeprom.c b/eeprom.c
+index c5be2843..adb87924 100644
+--- a/eeprom.c
++++ b/eeprom.c
+@@ -161,6 +161,31 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
+ 	return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
+ }
+ 
++bool mt76_check_bin_file_mode(struct mt76_dev *dev)
++{
++	struct device_node *np = dev->dev->of_node;
++	const char *bin_file_name = NULL;
++
++	if (!np)
++		return false;
++
++	of_property_read_string(np, "bin_file_name", &bin_file_name);
++
++	dev->bin_file_name = bin_file_name;
++	if (dev->bin_file_name) {
++		dev_info(dev->dev, "Using bin file %s\n", dev->bin_file_name);
++#ifdef CONFIG_NL80211_TESTMODE
++		dev->test_mtd.name = devm_kstrdup(dev->dev, bin_file_name, GFP_KERNEL);
++		dev->test_mtd.offset = -1;
++#endif
++	}
++
++	of_node_put(np);
++
++	return dev->bin_file_name ? true : false;
++}
++EXPORT_SYMBOL_GPL(mt76_check_bin_file_mode);
++
+ void
+ mt76_eeprom_override(struct mt76_phy *phy)
+ {
+diff --git a/mt76.h b/mt76.h
+index 19c445b5..1eb5a52b 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -948,6 +948,8 @@ struct mt76_dev {
+ 		struct mt76_usb usb;
+ 		struct mt76_sdio sdio;
+ 	};
++
++	const char *bin_file_name;
+ };
+ 
+ /* per-phy stats.  */
+@@ -1204,6 +1206,7 @@ void mt76_eeprom_override(struct mt76_phy *phy);
+ int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
+ int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
+ 				const char *cell_name, int len);
++bool mt76_check_bin_file_mode(struct mt76_dev *dev);
+ 
+ struct mt76_queue *
+ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 6c1966b7..c553a0f5 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -79,10 +79,17 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+ 	}
+ }
+ 
+-static char *mt7996_eeprom_name(struct mt7996_dev *dev)
++const char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ {
+-	if (dev->testmode_enable)
+-		return MT7996_EEPROM_DEFAULT_TM;
++	if (dev->bin_file_mode)
++		return dev->mt76.bin_file_name;
++
++	if (dev->testmode_enable) {
++		if (is_mt7992(&dev->mt76))
++			return MT7992_EEPROM_DEFAULT_TM;
++		else
++			return MT7996_EEPROM_DEFAULT_TM;
++	}
+ 
+ 	switch (mt76_chip(&dev->mt76)) {
+ 	case 0x7990:
+@@ -149,7 +156,10 @@ mt7996_eeprom_load_default(struct mt7996_dev *dev)
+ 		return ret;
+ 
+ 	if (!fw || !fw->data) {
+-		dev_err(dev->mt76.dev, "Invalid default bin\n");
++		if (dev->bin_file_mode)
++			dev_err(dev->mt76.dev, "Invalid bin (bin file mode)\n");
++		else
++			dev_err(dev->mt76.dev, "Invalid default bin\n");
+ 		ret = -EINVAL;
+ 		goto out;
+ 	}
+@@ -163,18 +173,45 @@ out:
+ 	return ret;
+ }
+ 
++static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
++{
++	int ret = 1;
++
++	/* return > 0 for load success, return 0 for load failed, return < 0 for non memory */
++	dev->bin_file_mode = mt76_check_bin_file_mode(&dev->mt76);
++	if (dev->bin_file_mode) {
++		dev->mt76.eeprom.size = MT7996_EEPROM_SIZE;
++		dev->mt76.eeprom.data = devm_kzalloc(dev->mt76.dev, dev->mt76.eeprom.size,
++						     GFP_KERNEL);
++		if (!dev->mt76.eeprom.data)
++			return -ENOMEM;
++
++		if (mt7996_eeprom_load_default(dev))
++			return 0;
++
++		if (mt7996_check_eeprom(dev))
++			return 0;
++	} else {
++		ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
++	}
++
++	return ret;
++}
++
+ int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev)
+ {
+ 	u8 *eeprom;
+ 	int ret;
+ 
+ 	/* load eeprom in flash or bin file mode to determine fw mode */
+-	ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
++	ret = mt7996_eeprom_load_flash(dev);
++
+ 	if (ret < 0)
+ 		return ret;
+ 
+ 	if (ret) {
+ 		dev->flash_mode = true;
++		dev->eeprom_mode = dev->bin_file_mode ? BIN_FILE_MODE : FLASH_MODE;
+ 		eeprom = dev->mt76.eeprom.data;
+ 		/* testmode enable priority: eeprom field > module parameter */
+ 		dev->testmode_enable = !mt7996_check_eeprom(dev) ? eeprom[MT_EE_TESTMODE_EN] :
+@@ -208,6 +245,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
+ 			if (ret < 0)
+ 				return ret;
+ 		}
++		dev->eeprom_mode = EFUSE_MODE;
+ 	}
+ 
+ 	return mt7996_check_eeprom(dev);
+@@ -334,6 +372,59 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
+ 	return mt7996_eeprom_parse_band_config(phy);
+ }
+ 
++static int
++mt7996_eeprom_load_precal_binfile(struct mt7996_dev *dev, u32 offs, u32 size)
++{
++	const struct firmware *fw = NULL;
++	int ret;
++
++	ret = request_firmware(&fw, dev->mt76.bin_file_name, dev->mt76.dev);
++	if (ret)
++		return ret;
++
++	if (!fw || !fw->data) {
++		dev_err(dev->mt76.dev, "Invalid bin (bin file mode), load precal fail\n");
++		ret = -EINVAL;
++		goto out;
++	}
++
++	memcpy(dev->cal, fw->data + offs, size);
++
++out:
++	release_firmware(fw);
++
++	return ret;
++}
++
++static int mt7996_eeprom_load_precal(struct mt7996_dev *dev)
++{
++	struct mt76_dev *mdev = &dev->mt76;
++	u8 *eeprom = mdev->eeprom.data;
++	u32 offs = MT_EE_DO_PRE_CAL;
++	u32 size, val = eeprom[offs];
++	int ret;
++
++	mt7996_eeprom_init_precal(dev);
++
++	if (!dev->flash_mode || !val)
++		return 0;
++
++	size = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE;
++
++	dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
++	if (!dev->cal)
++		return -ENOMEM;
++
++	if (dev->bin_file_mode)
++		return mt7996_eeprom_load_precal_binfile(dev, MT_EE_PRECAL, size);
++
++	ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);
++	if (!ret)
++		return ret;
++
++	return mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
++}
++
+ int mt7996_eeprom_init(struct mt7996_dev *dev)
+ {
+ 	int ret;
+@@ -348,6 +439,8 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+ 			return ret;
+ 
+ 		dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
++		dev->bin_file_mode = false;
++		dev->eeprom_mode = DEFAULT_BIN_MODE;
+ 		ret = mt7996_eeprom_load_default(dev);
+ 		if (ret)
+ 			return ret;
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 23d4929d..8b555aeb 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -100,6 +100,13 @@ enum mt7996_eeprom_band {
+ 	MT_EE_BAND_SEL_6GHZ,
+ };
+ 
++enum mt7915_eeprom_mode {
++	DEFAULT_BIN_MODE,
++	EFUSE_MODE,
++	FLASH_MODE,
++	BIN_FILE_MODE,
++};
++
+ static inline int
+ mt7996_get_channel_group_5g(int channel)
+ {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 7e3d381e..2f067988 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -62,6 +62,7 @@
+ #define MT7992_EEPROM_DEFAULT_24	"mediatek/mt7996/mt7992_eeprom_24_2i5i.bin"
+ #define MT7992_EEPROM_DEFAULT_23	"mediatek/mt7996/mt7992_eeprom_23_2i5i.bin"
+ #define MT7992_EEPROM_DEFAULT_23_EXT	"mediatek/mt7996/mt7992_eeprom_23_2e5e.bin"
++#define MT7992_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7992_eeprom_tm.bin"
+ #define MT7996_EEPROM_SIZE		7680
+ #define MT7996_EEPROM_BLOCK_SIZE	16
+ #define MT7996_TOKEN_SIZE		16384
+@@ -389,6 +390,8 @@ struct mt7996_dev {
+ 	} wed_rro;
+ 
+ 	bool testmode_enable;
++	bool bin_file_mode;
++	u8 eeprom_mode;
+ 
+ 	bool ibf;
+ 	u8 fw_debug_wm;
+@@ -516,6 +519,7 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
+ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
+ int mt7996_register_device(struct mt7996_dev *dev);
+ void mt7996_unregister_device(struct mt7996_dev *dev);
++const char *mt7996_eeprom_name(struct mt7996_dev *dev);
+ int mt7996_eeprom_init(struct mt7996_dev *dev);
+ int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev);
+ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 93428851..fe6492ab 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2643,6 +2643,44 @@ static const struct file_operations mt7996_txpower_sku_fops = {
+ 	.llseek = default_llseek,
+ };
+ 
++static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
++{
++	struct mt7996_dev *dev = dev_get_drvdata(s->private);
++	struct mt76_dev *mdev = &dev->mt76;
++#ifdef CONFIG_NL80211_TESTMODE
++	const char *mtd_name = mdev->test_mtd.name;
++	u32 mtd_offset = mdev->test_mtd.offset;
++#else
++	const char *mtd_name = NULL;
++	u32 mtd_offset;
++#endif
++
++	seq_printf(s, "Current eeprom mode:\n");
++
++	switch (dev->eeprom_mode) {
++	case DEFAULT_BIN_MODE:
++		seq_printf(s, "   default bin mode\n   filename = %s\n", mt7996_eeprom_name(dev));
++		break;
++	case EFUSE_MODE:
++		seq_printf(s, "   efuse mode\n");
++		break;
++	case FLASH_MODE:
++		if (mtd_name)
++			seq_printf(s, "   flash mode\n   mtd name = %s\n   flash offset = 0x%x\n",
++				   mtd_name, mtd_offset);
++		else
++			seq_printf(s, "   flash mode\n");
++		break;
++	case BIN_FILE_MODE:
++		seq_printf(s, "   bin file mode\n   filename = %s\n", mt7996_eeprom_name(dev));
++		break;
++	default:
++		break;
++	}
++
++	return 0;
++}
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -2710,6 +2748,9 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ 	debugfs_create_file("txpower_info", 0600, dir, phy, &mt7996_txpower_info_fops);
+ 	debugfs_create_file("txpower_sku", 0600, dir, phy, &mt7996_txpower_sku_fops);
+ 
++	debugfs_create_devm_seqfile(dev->mt76.dev, "eeprom_mode", dir,
++				    mt7996_show_eeprom_mode);
++
+ 	debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
+ 				    mt7996_wtbl_read);
+ 
+diff --git a/testmode.h b/testmode.h
+index d6601cdc..5d677f8c 100644
+--- a/testmode.h
++++ b/testmode.h
+@@ -16,7 +16,7 @@
+  * @MT76_TM_ATTR_RESET: reset parameters to default (flag)
+  * @MT76_TM_ATTR_STATE: test state (u32), see &enum mt76_testmode_state
+  *
+- * @MT76_TM_ATTR_MTD_PART: mtd partition used for eeprom data (string)
++ * @MT76_TM_ATTR_MTD_PART: mtd partition or binfile used for eeprom data (string)
+  * @MT76_TM_ATTR_MTD_OFFSET: offset of eeprom data within the partition (u32)
+  * @MT76_TM_ATTR_BAND_IDX: band idx of the chip (u8)
+  *
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1010-mtk-wifi-mt76-mt7996-add-normal-mode-pre-calibration.patch
similarity index 80%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1010-mtk-wifi-mt76-mt7996-add-normal-mode-pre-calibration.patch
index 3aac8a9..487adb7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1010-mtk-wifi-mt76-mt7996-add-normal-mode-pre-calibration.patch
@@ -1,25 +1,25 @@
-From 114d3abef99827bcc848e6aef393be79a7c34e71 Mon Sep 17 00:00:00 2001
+From 6f2a22fee13ed919b2867ed08f106a4a31e8db79 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 1 Mar 2023 12:12:51 +0800
-Subject: [PATCH 45/98] wifi: mt76: mt7996: add normal mode pre-calibration
- support
+Subject: [PATCH 1010/1041] mtk: wifi: mt76: mt7996: add normal mode
+ pre-calibration support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
  mt76_connac_mcu.h |   1 +
- mt7996/eeprom.c   |  23 +++++++
+ mt7996/eeprom.c   |   4 ++
  mt7996/eeprom.h   |   2 +
  mt7996/init.c     |   6 ++
  mt7996/main.c     |   6 ++
  mt7996/mcu.c      | 166 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mt7996.h   |   2 +
- 7 files changed, 206 insertions(+)
+ mt7996/mt7996.h   |   3 +
+ 7 files changed, 188 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index d65ecf0..762ac29 100644
+index 5e1b15c4..1f0cd6e8 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1251,6 +1251,7 @@ enum {
+@@ -1266,6 +1266,7 @@ enum {
  	MCU_UNI_CMD_PP = 0x38,
  	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
  	MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
@@ -28,36 +28,10 @@
  	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
  	MCU_UNI_CMD_PER_STA_INFO = 0x6d,
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index ca91c69..56605de 100644
+index c553a0f5..372a822f 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -333,6 +333,25 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
- 	return mt7996_eeprom_parse_band_config(phy);
- }
- 
-+static int mt7996_eeprom_load_precal(struct mt7996_dev *dev)
-+{
-+	struct mt76_dev *mdev = &dev->mt76;
-+	u8 *eeprom = mdev->eeprom.data;
-+	u32 offs = MT_EE_DO_PRE_CAL;
-+	u32 size, val = eeprom[offs];
-+
-+	if (!dev->flash_mode || !val)
-+		return 0;
-+
-+	size = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE;
-+
-+	dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
-+	if (!dev->cal)
-+		return -ENOMEM;
-+
-+	return mt76_get_of_eeprom(mdev, dev->cal, MT_EE_PRECAL, size);
-+}
-+
- int mt7996_eeprom_init(struct mt7996_dev *dev)
- {
- 	int ret;
-@@ -350,6 +369,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+@@ -446,6 +446,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
  			return ret;
  	}
  
@@ -69,7 +43,7 @@
  	if (ret < 0)
  		return ret;
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 20dd877..0f3f31d 100644
+index 8b555aeb..8f0f87b6 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -25,6 +25,8 @@ enum mt7996_eeprom_field {
@@ -82,10 +56,10 @@
  
  #define MT_EE_WIFI_CONF0_TX_PATH		GENMASK(2, 0)
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 5940e41..bf3479e 100644
+index af2f4143..7cf7b0c2 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -826,6 +826,12 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -988,6 +988,12 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  	if (ret < 0)
  		return ret;
  
@@ -99,10 +73,10 @@
  	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA);
  	if (idx)
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 804c0c1..7d1bd42 100644
+index 9481fc5c..ae9484c3 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -312,6 +312,12 @@ int mt7996_set_channel(struct mt7996_phy *phy)
+@@ -321,6 +321,12 @@ int mt7996_set_channel(struct mt7996_phy *phy)
  
  	mt76_set_channel(phy->mt76);
  
@@ -112,14 +86,14 @@
 +			goto out;
 +	}
 +
- 	ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);
- 	if (ret)
+ 	if (mt76_testmode_enabled(phy->mt76) || phy->mt76->test.bf_en) {
+ 		mt7996_tm_update_channel(phy);
  		goto out;
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index d6f4e22..695d5f0 100644
+index d8e5c220..fdddf457 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -3456,6 +3456,172 @@ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
+@@ -3624,6 +3624,172 @@ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
  	return 0;
  }
  
@@ -293,18 +267,19 @@
  {
  #define NIC_CAP	3
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index cda557e..80a10bf 100644
+index 2f067988..69db055d 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -611,6 +611,8 @@ void mt7996_mcu_exit(struct mt7996_dev *dev);
+@@ -611,6 +611,9 @@ void mt7996_mcu_exit(struct mt7996_dev *dev);
  int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
+ int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id);
  int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
- int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
++int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
 +int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev);
 +int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
- int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
- void mt7996_mcu_scs_sta_poll(struct work_struct *work);
  #ifdef CONFIG_NL80211_TESTMODE
+ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #endif
 -- 
 2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1011-mtk-wifi-mt76-testmode-add-testmode-ZWDFS-verificati.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1011-mtk-wifi-mt76-testmode-add-testmode-ZWDFS-verificati.patch
index 16439d4..dfcf033 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1011-mtk-wifi-mt76-testmode-add-testmode-ZWDFS-verificati.patch
@@ -1,8 +1,8 @@
-From 9bbc79e25d5fe7c14ec520413f4fb0625af9c630 Mon Sep 17 00:00:00 2001
+From 0557d0114d56520ddf0f86312401a5a024494091 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 22 Mar 2023 11:19:52 +0800
-Subject: [PATCH 47/98] wifi: mt76: testmode: add testmode ZWDFS verification
- support
+Subject: [PATCH 1011/1041] mtk: wifi: mt76: testmode: add testmode ZWDFS
+ verification support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -15,10 +15,10 @@
  6 files changed, 326 insertions(+), 12 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 0bf0177..0096c7f 100644
+index 1eb5a52b..46fbc87e 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -774,6 +774,14 @@ struct mt76_testmode_data {
+@@ -777,6 +777,14 @@ struct mt76_testmode_data {
  	} cfg;
  
  	u8 aid;
@@ -34,10 +34,10 @@
  
  struct mt76_vif {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 9f99d13..7269076 100644
+index 69db055d..2daca449 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -272,6 +272,7 @@ struct mt7996_phy {
+@@ -289,6 +289,7 @@ struct mt7996_phy {
  
  	struct mt76_mib_stats mib;
  	struct mt76_channel_state state_ts;
@@ -46,7 +46,7 @@
  	bool has_aux_rx;
  
 diff --git a/mt7996/testmode.c b/mt7996/testmode.c
-index 8ceea00..c52bf41 100644
+index 36be0ff8..26ae5827 100644
 --- a/mt7996/testmode.c
 +++ b/mt7996/testmode.c
 @@ -17,6 +17,12 @@ enum {
@@ -105,7 +105,7 @@
  	};
  
  	if (width >= ARRAY_SIZE(width_to_bw))
-@@ -216,6 +233,9 @@ mt7996_tm_init(struct mt7996_phy *phy, bool en)
+@@ -217,6 +234,9 @@ mt7996_tm_init(struct mt7996_phy *phy, bool en)
  
  	/* use firmware counter for RX stats */
  	phy->mt76->test.flag |= MT_TM_FW_RX_COUNT;
@@ -115,7 +115,7 @@
  }
  
  static void
-@@ -828,6 +848,204 @@ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -829,6 +849,204 @@ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb)
  	}
  }
  
@@ -320,7 +320,7 @@
  static void
  mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
  {
-@@ -858,6 +1076,14 @@ mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
+@@ -860,6 +1078,14 @@ mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
  
  		mt7996_tm_set(dev, func_idx, td->cfg.type);
  	}
@@ -336,7 +336,7 @@
  
  static int
 diff --git a/mt7996/testmode.h b/mt7996/testmode.h
-index 17c1456..57fde8c 100644
+index 9bfb86f2..78662b2e 100644
 --- a/mt7996/testmode.h
 +++ b/mt7996/testmode.h
 @@ -27,9 +27,15 @@ enum {
@@ -355,7 +355,7 @@
  
  	NUM_BW_MAP,
  };
-@@ -310,4 +316,42 @@ struct mt7996_tm_rx_event {
+@@ -312,4 +318,42 @@ struct mt7996_tm_rx_event {
  	};
  } __packed;
  
@@ -399,7 +399,7 @@
 +
  #endif
 diff --git a/testmode.c b/testmode.c
-index e66b54a..bce3a9c 100644
+index 7ed58a77..805ad83c 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -27,6 +27,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
@@ -416,7 +416,7 @@
  };
  EXPORT_SYMBOL_GPL(mt76_tm_policy);
  
-@@ -456,6 +463,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -499,6 +506,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	if (tb[MT76_TM_ATTR_TX_RATE_IDX])
  		td->tx_rate_idx = nla_get_u8(tb[MT76_TM_ATTR_TX_RATE_IDX]);
  
@@ -426,7 +426,7 @@
  	if (mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_MODE], &td->tx_rate_mode,
  			   0, MT76_TM_TX_MODE_MAX) ||
  	    mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_NSS], &td->tx_rate_nss,
-@@ -471,7 +481,14 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -514,7 +524,14 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  			   &td->tx_duty_cycle, 0, 99) ||
  	    mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
  			   &td->tx_power_control, 0, 1) ||
@@ -442,7 +442,7 @@
  		goto out;
  
  	if (tb[MT76_TM_ATTR_TX_LENGTH]) {
-@@ -677,6 +694,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -720,6 +737,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) ||
  	    nla_put_u8(msg, MT76_TM_ATTR_SKU_EN, td->sku_en) ||
  	    nla_put_u8(msg, MT76_TM_ATTR_AID, td->aid) ||
@@ -453,7 +453,7 @@
  	     nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
  	    (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
 diff --git a/tools/fields.c b/tools/fields.c
-index b012276..77696ce 100644
+index b0122763..77696ce7 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -35,6 +35,15 @@ static const char * const testmode_tx_mode[] = {
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-binfile-mode-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-binfile-mode-support.patch
deleted file mode 100644
index 6d1a987..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-binfile-mode-support.patch
+++ /dev/null
@@ -1,260 +0,0 @@
-From 2cd9ab05b3a16a92fb2552102b2a9c36834d1e7d Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 31 Mar 2023 11:36:34 +0800
-Subject: [PATCH 44/98] wifi: mt76: mt7996: add binfile mode support
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- eeprom.c             | 20 ++++++++++++++++++++
- mt76.h               |  3 +++
- mt7996/eeprom.c      | 42 +++++++++++++++++++++++++++++++++++++++---
- mt7996/eeprom.h      |  7 +++++++
- mt7996/mt7996.h      |  3 +++
- mt7996/mtk_debugfs.c | 40 ++++++++++++++++++++++++++++++++++++++++
- 6 files changed, 112 insertions(+), 3 deletions(-)
-
-diff --git a/eeprom.c b/eeprom.c
-index 437d8ca..89bb913 100644
---- a/eeprom.c
-+++ b/eeprom.c
-@@ -159,6 +159,26 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
- }
- EXPORT_SYMBOL_GPL(mt76_get_of_eeprom);
- 
-+bool mt76_check_bin_file_mode(struct mt76_dev *dev)
-+{
-+	struct device_node *np = dev->dev->of_node;
-+	const char *bin_file_name = NULL;
-+
-+	if (!np)
-+		return false;
-+
-+	of_property_read_string(np, "bin_file_name", &bin_file_name);
-+
-+	dev->bin_file_name = bin_file_name;
-+	if (dev->bin_file_name)
-+		dev_info(dev->dev, "Using bin file %s\n", dev->bin_file_name);
-+
-+	of_node_put(np);
-+
-+	return dev->bin_file_name ? true : false;
-+}
-+EXPORT_SYMBOL_GPL(mt76_check_bin_file_mode);
-+
- void
- mt76_eeprom_override(struct mt76_phy *phy)
- {
-diff --git a/mt76.h b/mt76.h
-index fc69d3e..0bf0177 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -945,6 +945,8 @@ struct mt76_dev {
- 		struct mt76_usb usb;
- 		struct mt76_sdio sdio;
- 	};
-+
-+	const char *bin_file_name;
- };
- 
- /* per-phy stats.  */
-@@ -1190,6 +1192,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
- int mt76_eeprom_init(struct mt76_dev *dev, int len);
- void mt76_eeprom_override(struct mt76_phy *phy);
- int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len);
-+bool mt76_check_bin_file_mode(struct mt76_dev *dev);
- 
- struct mt76_queue *
- mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
-diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index b88fd64..ca91c69 100644
---- a/mt7996/eeprom.c
-+++ b/mt7996/eeprom.c
-@@ -61,8 +61,11 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
- 	}
- }
- 
--static char *mt7996_eeprom_name(struct mt7996_dev *dev)
-+const char *mt7996_eeprom_name(struct mt7996_dev *dev)
- {
-+	if (dev->bin_file_mode)
-+		return dev->mt76.bin_file_name;
-+
- 	/* reserve for future variants */
- 	if (dev->testmode_enable)
- 		return MT7996_EEPROM_DEFAULT_TM;
-@@ -114,7 +117,10 @@ mt7996_eeprom_load_default(struct mt7996_dev *dev)
- 		return ret;
- 
- 	if (!fw || !fw->data) {
--		dev_err(dev->mt76.dev, "Invalid default bin\n");
-+		if (dev->bin_file_mode)
-+			dev_err(dev->mt76.dev, "Invalid bin (bin file mode)\n");
-+		else
-+			dev_err(dev->mt76.dev, "Invalid default bin\n");
- 		ret = -EINVAL;
- 		goto out;
- 	}
-@@ -128,18 +134,45 @@ out:
- 	return ret;
- }
- 
-+static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
-+{
-+	int ret = 1;
-+
-+	/* return > 0 for load success, return 0 for load failed, return < 0 for non memory */
-+	dev->bin_file_mode = mt76_check_bin_file_mode(&dev->mt76);
-+	if (dev->bin_file_mode) {
-+		dev->mt76.eeprom.size = MT7996_EEPROM_SIZE;
-+		dev->mt76.eeprom.data = devm_kzalloc(dev->mt76.dev, dev->mt76.eeprom.size,
-+						     GFP_KERNEL);
-+		if (!dev->mt76.eeprom.data)
-+			return -ENOMEM;
-+
-+		if (mt7996_eeprom_load_default(dev))
-+			return 0;
-+
-+		if (mt7996_check_eeprom(dev))
-+			return 0;
-+	} else {
-+		ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
-+	}
-+
-+	return ret;
-+}
-+
- int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev)
- {
- 	u8 *eeprom;
- 	int ret;
- 
- 	/* load eeprom in flash or bin file mode to determine fw mode */
--	ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
-+	ret = mt7996_eeprom_load_flash(dev);
-+
- 	if (ret < 0)
- 		return ret;
- 
- 	if (ret) {
- 		dev->flash_mode = true;
-+		dev->eeprom_mode = dev->bin_file_mode ? BIN_FILE_MODE : FLASH_MODE;
- 		eeprom = dev->mt76.eeprom.data;
- 		/* testmode enable priority: eeprom field > module parameter */
- 		dev->testmode_enable = !mt7996_check_eeprom(dev) ? eeprom[MT_EE_TESTMODE_EN] :
-@@ -173,6 +206,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
- 			if (ret < 0)
- 				return ret;
- 		}
-+		dev->eeprom_mode = EFUSE_MODE;
- 	}
- 
- 	return mt7996_check_eeprom(dev);
-@@ -309,6 +343,8 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
- 			return ret;
- 
- 		dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
-+		dev->bin_file_mode = false;
-+		dev->eeprom_mode = DEFAULT_BIN_MODE;
- 		ret = mt7996_eeprom_load_default(dev);
- 		if (ret)
- 			return ret;
-diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 7ff290f..20dd877 100644
---- a/mt7996/eeprom.h
-+++ b/mt7996/eeprom.h
-@@ -99,6 +99,13 @@ enum mt7996_eeprom_band {
- 	MT_EE_BAND_SEL_6GHZ,
- };
- 
-+enum mt7915_eeprom_mode {
-+	DEFAULT_BIN_MODE,
-+	EFUSE_MODE,
-+	FLASH_MODE,
-+	BIN_FILE_MODE,
-+};
-+
- static inline int
- mt7996_get_channel_group_5g(int channel)
- {
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 684c254..cda557e 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -375,6 +375,8 @@ struct mt7996_dev {
- 	} wed_rro;
- 
- 	bool testmode_enable;
-+	bool bin_file_mode;
-+	u8 eeprom_mode;
- 
- 	bool ibf;
- 	u8 fw_debug_wm;
-@@ -518,6 +520,7 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
- u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
- int mt7996_register_device(struct mt7996_dev *dev);
- void mt7996_unregister_device(struct mt7996_dev *dev);
-+const char *mt7996_eeprom_name(struct mt7996_dev *dev);
- int mt7996_eeprom_init(struct mt7996_dev *dev);
- int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev);
- int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
-diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
-index 57fcbab..82b2785 100644
---- a/mt7996/mtk_debugfs.c
-+++ b/mt7996/mtk_debugfs.c
-@@ -2551,6 +2551,44 @@ static const struct file_operations mt7996_txpower_sku_fops = {
- 	.llseek = default_llseek,
- };
- 
-+static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
-+{
-+	struct mt7996_dev *dev = dev_get_drvdata(s->private);
-+	struct mt76_dev *mdev = &dev->mt76;
-+#ifdef CONFIG_NL80211_TESTMODE
-+	const char *mtd_name = mdev->test_mtd.name;
-+	u32 mtd_offset = mdev->test_mtd.offset;
-+#else
-+	const char *mtd_name = NULL;
-+	u32 mtd_offset;
-+#endif
-+
-+	seq_printf(s, "Current eeprom mode:\n");
-+
-+	switch (dev->eeprom_mode) {
-+	case DEFAULT_BIN_MODE:
-+		seq_printf(s, "   default bin mode\n   filename = %s\n", mt7996_eeprom_name(dev));
-+		break;
-+	case EFUSE_MODE:
-+		seq_printf(s, "   efuse mode\n");
-+		break;
-+	case FLASH_MODE:
-+		if (mtd_name)
-+			seq_printf(s, "   flash mode\n   mtd name = %s\n   flash offset = 0x%x\n",
-+				   mtd_name, mtd_offset);
-+		else
-+			seq_printf(s, "   flash mode\n");
-+		break;
-+	case BIN_FILE_MODE:
-+		seq_printf(s, "   bin file mode\n   filename = %s\n", mt7996_eeprom_name(dev));
-+		break;
-+	default:
-+		break;
-+	}
-+
-+	return 0;
-+}
-+
- int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
- {
- 	struct mt7996_dev *dev = phy->dev;
-@@ -2596,6 +2634,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
- 	debugfs_create_file("txpower_level", 0600, dir, phy, &fops_txpower_level);
- 	debugfs_create_file("txpower_info", 0600, dir, phy, &mt7996_txpower_info_fops);
- 	debugfs_create_file("txpower_sku", 0600, dir, phy, &mt7996_txpower_sku_fops);
-+	debugfs_create_devm_seqfile(dev->mt76.dev, "eeprom_mode", dir,
-+				    mt7996_show_eeprom_mode);
- 
- 	debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
- 				    mt7996_wtbl_read);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1012-mtk-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
similarity index 83%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1012-mtk-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
index 38754fa..322fd05 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1012-mtk-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
@@ -1,23 +1,30 @@
-From 6c7addb48070af33da842ede744264149f2a9110 Mon Sep 17 00:00:00 2001
+From 842decc15bd36d4a61f17cb8927fba77b6c58999 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 13 Dec 2022 15:17:43 +0800
-Subject: [PATCH 40/98] wifi: mt76: mt7996: add mu vendor command support
+Subject: [PATCH 1012/1041] mtk: wifi: mt76: mt7996: add mu vendor command
+ support
 
-Change-Id: I4599bd97917651aaea51d7ff186ffff73a07e4ce
+mtk: wifi: mt76: fix muru_onoff as all enabled by default
+
+Fix muru_onoff default value as 0xF, which means all MU & RU are
+enabled. The purpose of this commit is to align muru_onoff value with
+hostapd and mt76 driver
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
 ---
  mt7996/Makefile |  3 +-
- mt7996/init.c   |  8 +++++
+ mt7996/init.c   |  9 ++++++
  mt7996/mcu.c    | 37 ++++++++++++++++++---
  mt7996/mcu.h    | 12 +++++++
- mt7996/mt7996.h |  6 ++++
+ mt7996/mt7996.h |  7 ++++
  mt7996/vendor.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/vendor.h | 22 +++++++++++++
- 7 files changed, 167 insertions(+), 6 deletions(-)
+ 7 files changed, 169 insertions(+), 6 deletions(-)
  create mode 100644 mt7996/vendor.c
  create mode 100644 mt7996/vendor.h
 
 diff --git a/mt7996/Makefile b/mt7996/Makefile
-index 7bb17f4..6643c7a 100644
+index 7bb17f44..6643c7a3 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
 @@ -1,11 +1,12 @@
@@ -35,10 +42,18 @@
  mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
  mt7996e-$(CONFIG_NL80211_TESTMODE) += testmode.o
 diff --git a/mt7996/init.c b/mt7996/init.c
-index f393e04..1f4e84d 100644
+index 7cf7b0c2..c4f0ec70 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -597,6 +597,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+@@ -368,6 +368,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
+ 
+ 	phy->slottime = 9;
+ 	phy->beacon_rate = -1;
++	phy->muru_onoff = OFDMA_UL | OFDMA_DL | MUMIMO_DL | MUMIMO_UL;
+ 
+ 	hw->sta_data_size = sizeof(struct mt7996_sta);
+ 	hw->vif_data_size = sizeof(struct mt7996_vif);
+@@ -621,6 +622,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
  	if (ret)
  		goto error;
  
@@ -49,7 +64,7 @@
  	ret = mt76_register_phy(mphy, true, mt76_rates,
  				ARRAY_SIZE(mt76_rates));
  	if (ret)
-@@ -1230,6 +1234,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1405,6 +1410,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	dev->mt76.test_ops = &mt7996_testmode_ops;
  #endif
  
@@ -61,10 +76,10 @@
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 6cedc39..a008c08 100644
+index fdddf457..05fa855b 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1266,6 +1266,8 @@ static void
+@@ -1383,6 +1383,8 @@ static void
  mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
  			struct ieee80211_vif *vif, struct ieee80211_sta *sta)
  {
@@ -73,7 +88,7 @@
  	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
  	struct sta_rec_muru *muru;
  	struct tlv *tlv;
-@@ -1277,11 +1279,14 @@ mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+@@ -1394,11 +1396,14 @@ mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));
  
  	muru = (struct sta_rec_muru *)tlv;
@@ -93,7 +108,7 @@
  
  	if (sta->deflink.vht_cap.vht_supported)
  		muru->mimo_dl.vht_mu_bfee =
-@@ -4469,3 +4474,25 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
+@@ -4913,3 +4918,25 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
  	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SCS),
  				 &req, sizeof(req), false);
  }
@@ -120,10 +135,10 @@
 +}
 +#endif
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 71dc165..c5c0a44 100644
+index 887d9b49..68bf82fc 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -683,8 +683,20 @@ enum {
+@@ -754,8 +754,20 @@ enum {
  	RATE_PARAM_FIXED_MCS,
  	RATE_PARAM_FIXED_GI = 11,
  	RATE_PARAM_AUTO = 20,
@@ -145,18 +160,19 @@
  	BF_SOUNDING_ON = 1,
  	BF_HW_EN_UPDATE = 17,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 23d1614..013122f 100644
+index 2daca449..d0b425da 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -249,6 +249,7 @@ struct mt7996_phy {
+@@ -295,6 +295,8 @@ struct mt7996_phy {
  
  	struct mt7996_scs_ctrl scs_ctrl;
  
 +	u8 muru_onoff;
++
  #ifdef CONFIG_NL80211_TESTMODE
  	struct {
  		u32 *reg_backup;
-@@ -683,6 +684,11 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+@@ -733,6 +735,11 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
  			 bool hif2, int *irq);
  u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
  
@@ -167,10 +183,10 @@
 +
  #ifdef CONFIG_MTK_DEBUG
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
- #endif
+ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
 new file mode 100644
-index 0000000..b5ecbdf
+index 00000000..b5ecbdf1
 --- /dev/null
 +++ b/mt7996/vendor.c
 @@ -0,0 +1,85 @@
@@ -261,7 +277,7 @@
 +}
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
 new file mode 100644
-index 0000000..8ac3ba8
+index 00000000..8ac3ba8e
 --- /dev/null
 +++ b/mt7996/vendor.h
 @@ -0,0 +1,22 @@
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1013-mtk-wifi-mt76-mt7996-Add-air-monitor-support.patch
similarity index 95%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1013-mtk-wifi-mt76-mt7996-Add-air-monitor-support.patch
index 45f1585..5afff31 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1013-mtk-wifi-mt76-mt7996-Add-air-monitor-support.patch
@@ -1,7 +1,7 @@
-From 98127145e2f401f65029185adab6dfcb0e90dbd9 Mon Sep 17 00:00:00 2001
+From c541c6af3d962fb8eb8b844aab518702693ced12 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 26 Apr 2023 04:40:05 +0800
-Subject: [PATCH 41/98] wifi: mt76: mt7996: Add air monitor support
+Subject: [PATCH 1013/1041] mtk: wifi: mt76: mt7996: Add air monitor support
 
 ---
  mt76_connac_mcu.h |   1 +
@@ -13,10 +13,10 @@
  6 files changed, 445 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index fae76c9..bbf600b 100644
+index 1f0cd6e8..fefa2a0c 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1222,6 +1222,7 @@ enum {
+@@ -1240,6 +1240,7 @@ enum {
  	MCU_UNI_CMD_REG_ACCESS = 0x0d,
  	MCU_UNI_CMD_CHIP_CONFIG = 0x0e,
  	MCU_UNI_CMD_POWER_CTRL = 0x0f,
@@ -25,7 +25,7 @@
  	MCU_UNI_CMD_SER = 0x13,
  	MCU_UNI_CMD_TWT = 0x14,
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 637f0f6..ee17d59 100644
+index e307ddc3..f7dc8db4 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
 @@ -679,6 +679,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
@@ -40,10 +40,10 @@
  		status->flag |= RX_FLAG_8023;
  		mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 6fa4a65..804c0c1 100644
+index ae9484c3..2042edd6 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -696,6 +696,10 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -737,6 +737,10 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	mt7996_mac_wtbl_update(dev, idx,
  			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
  
@@ -55,11 +55,11 @@
  	if (ret)
  		return ret;
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 013122f..3c535be 100644
+index d0b425da..09ce3c35 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -205,6 +205,34 @@ enum {
- 	SCS_ENABLE,
+@@ -259,6 +259,34 @@ struct mt7996_wed_rro_session_id {
+ 	u16 id;
  };
  
 +#ifdef CONFIG_MTK_VENDOR
@@ -90,10 +90,10 @@
 +};
 +#endif
 +
- struct mt7996_wed_rro_addr {
- 	u32 head_low;
- 	u32 head_high : 4;
-@@ -264,6 +292,10 @@ struct mt7996_phy {
+ struct mt7996_phy {
+ 	struct mt76_phy *mt76;
+ 	struct mt7996_dev *dev;
+@@ -311,6 +339,10 @@ struct mt7996_phy {
  		u8 spe_idx;
  	} test;
  #endif
@@ -104,7 +104,7 @@
  };
  
  struct mt7996_dev {
-@@ -687,6 +719,9 @@ u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+@@ -738,6 +770,9 @@ u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
  #ifdef CONFIG_MTK_VENDOR
  void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
  void mt7996_vendor_register(struct mt7996_phy *phy);
@@ -115,7 +115,7 @@
  
  #ifdef CONFIG_MTK_DEBUG
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index b5ecbdf..f3b089d 100644
+index b5ecbdf1..f3b089d7 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
 @@ -16,6 +16,32 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
@@ -506,7 +506,7 @@
 +	spin_lock_init(&phy->amnt_lock);
  }
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index 8ac3ba8..2078caf 100644
+index 8ac3ba8e..2078cafa 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -4,6 +4,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
deleted file mode 100644
index 9a38681..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
+++ /dev/null
@@ -1,343 +0,0 @@
-From a20311a499edde8f5b8e6b4bced55bd5e0f25884 Mon Sep 17 00:00:00 2001
-From: mtk23510 <rudra.shahi@mediatek.com>
-Date: Wed, 26 Apr 2023 20:08:10 +0800
-Subject: [PATCH 46/98] wifi: mt76: mt7996: Beacon protection feature added
-
-Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
-Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
----
- mt76_connac_mcu.h |  24 ++++++++
- mt7996/main.c     |  14 +++--
- mt7996/mcu.c      | 138 +++++++++++++++++++++++++++++++++-------------
- mt7996/mcu.h      |  17 ++++++
- mt7996/mt7996.h   |   3 +-
- 5 files changed, 153 insertions(+), 43 deletions(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 762ac29..42eb64c 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -418,6 +418,14 @@ struct sta_rec_he_6g_capa {
- 	u8 rsv[2];
- } __packed;
- 
-+struct sta_rec_pn_info {
-+	__le16 tag;
-+	__le16 len;
-+	u8 pn[6];
-+	u8 tsc_type;
-+	u8 rsv;
-+} __packed;
-+
- struct sec_key {
- 	u8 cipher_id;
- 	u8 cipher_len;
-@@ -770,6 +778,7 @@ struct wtbl_raw {
- 					 sizeof(struct sta_rec_sec) +	\
- 					 sizeof(struct sta_rec_ra_fixed) + \
- 					 sizeof(struct sta_rec_he_6g_capa) + \
-+					 sizeof(struct sta_rec_pn_info) + \
- 					 sizeof(struct tlv) +		\
- 					 MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)
- 
-@@ -800,6 +809,7 @@ enum {
- 	STA_REC_HE_V2 = 0x19,
- 	STA_REC_MLD = 0x20,
- 	STA_REC_EHT = 0x22,
-+	STA_REC_PN_INFO = 0x26,
- 	STA_REC_HDRT = 0x28,
- 	STA_REC_HDR_TRANS = 0x2B,
- 	STA_REC_MAX_NUM
-@@ -1093,6 +1103,13 @@ enum mcu_cipher_type {
- 	MCU_CIPHER_GCMP_256,
- 	MCU_CIPHER_WAPI,
- 	MCU_CIPHER_BIP_CMAC_128,
-+	MCU_CIPHER_BIP_CMAC_256,
-+	MCU_CIPHER_BCN_PROT_CMAC_128,
-+	MCU_CIPHER_BCN_PROT_CMAC_256,
-+	MCU_CIPHER_BCN_PROT_GMAC_128,
-+	MCU_CIPHER_BCN_PROT_GMAC_256,
-+	MCU_CIPHER_BIP_GMAC_128,
-+	MCU_CIPHER_BIP_GMAC_256,
- };
- 
- enum {
-@@ -1319,6 +1336,7 @@ enum {
- 	UNI_BSS_INFO_RATE = 11,
- 	UNI_BSS_INFO_QBSS = 15,
- 	UNI_BSS_INFO_SEC = 16,
-+	UNI_BSS_INFO_BCN_PROT = 17,
- 	UNI_BSS_INFO_TXCMD = 18,
- 	UNI_BSS_INFO_UAPSD = 19,
- 	UNI_BSS_INFO_PS = 21,
-@@ -1779,6 +1797,12 @@ mt76_connac_mcu_get_cipher(int cipher)
- 		return MCU_CIPHER_GCMP;
- 	case WLAN_CIPHER_SUITE_GCMP_256:
- 		return MCU_CIPHER_GCMP_256;
-+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
-+		return MCU_CIPHER_BIP_GMAC_128;
-+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
-+		return MCU_CIPHER_BIP_GMAC_256;
-+	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-+		return MCU_CIPHER_BIP_CMAC_256;
- 	case WLAN_CIPHER_SUITE_SMS4:
- 		return MCU_CIPHER_WAPI;
- 	default:
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 7d1bd42..0ea006c 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -368,8 +368,10 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- 	/* fall back to sw encryption for unsupported ciphers */
- 	switch (key->cipher) {
- 	case WLAN_CIPHER_SUITE_AES_CMAC:
--		wcid_keyidx = &wcid->hw_key_idx2;
- 		key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;
-+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
-+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
-+		wcid_keyidx = &wcid->hw_key_idx2;
- 		break;
- 	case WLAN_CIPHER_SUITE_TKIP:
- 	case WLAN_CIPHER_SUITE_CCMP:
-@@ -400,9 +402,13 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- 	}
- 
- 	mt76_wcid_key_setup(&dev->mt76, wcid, key);
--	err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip,
--				 key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
--				 &msta->wcid, cmd);
-+
-+	if (key->keyidx == 6 || key->keyidx == 7)
-+		err = mt7996_mcu_bcn_prot_enable(dev, vif, key);
-+	else
-+		err = mt7996_mcu_add_key(&dev->mt76, vif, key,
-+					 MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
-+					 &msta->wcid, cmd);
- out:
- 	mutex_unlock(&dev->mt76.mutex);
- 
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 695d5f0..1a1c732 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2118,7 +2118,6 @@ out:
- 
- static int
- mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
--		       struct mt76_connac_sta_key_conf *sta_key_conf,
- 		       struct sk_buff *skb,
- 		       struct ieee80211_key_conf *key,
- 		       enum set_key_cmd cmd)
-@@ -2139,43 +2138,22 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
- 			return -EOPNOTSUPP;
- 
- 		sec_key = &sec->key[0];
-+		sec_key->wlan_idx = cpu_to_le16(wcid->idx);
-+		sec_key->mgmt_prot = 0;
-+		sec_key->cipher_id = cipher;
- 		sec_key->cipher_len = sizeof(*sec_key);
--
--		if (cipher == MCU_CIPHER_BIP_CMAC_128) {
--			sec_key->wlan_idx = cpu_to_le16(wcid->idx);
--			sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
--			sec_key->key_id = sta_key_conf->keyidx;
--			sec_key->key_len = 16;
--			memcpy(sec_key->key, sta_key_conf->key, 16);
--
--			sec_key = &sec->key[1];
--			sec_key->wlan_idx = cpu_to_le16(wcid->idx);
--			sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
--			sec_key->cipher_len = sizeof(*sec_key);
--			sec_key->key_len = 16;
--			memcpy(sec_key->key, key->key, 16);
--			sec->n_cipher = 2;
--		} else {
--			sec_key->wlan_idx = cpu_to_le16(wcid->idx);
--			sec_key->cipher_id = cipher;
--			sec_key->key_id = key->keyidx;
--			sec_key->key_len = key->keylen;
--			memcpy(sec_key->key, key->key, key->keylen);
--
--			if (cipher == MCU_CIPHER_TKIP) {
--				/* Rx/Tx MIC keys are swapped */
--				memcpy(sec_key->key + 16, key->key + 24, 8);
--				memcpy(sec_key->key + 24, key->key + 16, 8);
--			}
--
--			/* store key_conf for BIP batch update */
--			if (cipher == MCU_CIPHER_AES_CCMP) {
--				memcpy(sta_key_conf->key, key->key, key->keylen);
--				sta_key_conf->keyidx = key->keyidx;
--			}
--
--			sec->n_cipher = 1;
-+		sec_key->key_id = key->keyidx;
-+		sec_key->key_len = key->keylen;
-+		sec_key->need_resp = 0;
-+		memcpy(sec_key->key, key->key, key->keylen);
-+
-+		if (cipher == MCU_CIPHER_TKIP) {
-+			/* Rx/Tx MIC keys are swapped */
-+			memcpy(sec_key->key + 16, key->key + 24, 8);
-+			memcpy(sec_key->key + 24, key->key + 16, 8);
- 		}
-+
-+		sec->n_cipher = 1;
- 	} else {
- 		sec->n_cipher = 0;
- 	}
-@@ -2184,7 +2162,6 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
- }
- 
- int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
--		       struct mt76_connac_sta_key_conf *sta_key_conf,
- 		       struct ieee80211_key_conf *key, int mcu_cmd,
- 		       struct mt76_wcid *wcid, enum set_key_cmd cmd)
- {
-@@ -2197,13 +2174,98 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
- 	if (IS_ERR(skb))
- 		return PTR_ERR(skb);
- 
--	ret = mt7996_mcu_sta_key_tlv(wcid, sta_key_conf, skb, key, cmd);
-+	ret = mt7996_mcu_sta_key_tlv(wcid, skb, key, cmd);
- 	if (ret)
- 		return ret;
- 
- 	return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
- }
- 
-+static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-+			    u8 *pn)
-+{
-+#define TSC_TYPE_BIGTK_PN 2
-+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+	struct sta_rec_pn_info *pn_info;
-+	struct sk_buff *skb, *rskb;
-+	struct tlv *tlv;
-+	int ret;
-+
-+	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid);
-+	if (IS_ERR(skb))
-+		return PTR_ERR(skb);
-+
-+	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PN_INFO, sizeof(*pn_info));
-+	pn_info = (struct sta_rec_pn_info *)tlv;
-+
-+	pn_info->tsc_type = TSC_TYPE_BIGTK_PN;
-+	ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb,
-+				MCU_WM_UNI_CMD_QUERY(STA_REC_UPDATE), true, &rskb);
-+	if (ret)
-+		return ret;
-+
-+	skb_pull(rskb, 4);
-+
-+	pn_info = (struct sta_rec_pn_info *)rskb->data;
-+	if (le16_to_cpu(pn_info->tag) == STA_REC_PN_INFO)
-+		memcpy(pn, pn_info->pn, 6);
-+
-+	dev_kfree_skb(rskb);
-+	return 0;
-+}
-+
-+int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-+		       struct ieee80211_key_conf *key)
-+{
-+	int len = sizeof(struct bss_req_hdr) + sizeof(struct mt7996_mcu_bcn_prot_tlv);
-+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+	int ret;
-+	struct mt7996_mcu_bcn_prot_tlv *bcn_prot;
-+	struct sk_buff *skb;
-+	struct tlv *tlv;
-+	u8 pn[6] = {0};
-+
-+	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len);
-+	if (IS_ERR(skb))
-+		return PTR_ERR(skb);
-+
-+	tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BCN_PROT,
-+				sizeof(*bcn_prot));
-+
-+	bcn_prot = (struct mt7996_mcu_bcn_prot_tlv *)tlv;
-+
-+	ret = mt7996_mcu_get_pn(dev, vif, pn);
-+	if (ret) {
-+		dev_kfree_skb(skb);
-+		return ret;
-+	}
-+
-+	switch (key->cipher) {
-+	case WLAN_CIPHER_SUITE_AES_CMAC:
-+		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_128;
-+		break;
-+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
-+		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_128;
-+		break;
-+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
-+		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256;
-+		break;
-+	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-+	default:
-+		dev_err(dev->mt76.dev, "Not supported Bigtk Cipher\n");
-+		dev_kfree_skb(skb);
-+		return -EOPNOTSUPP;
-+	}
-+
-+	pn[0]++;
-+	memcpy(bcn_prot->pn, pn, 6);
-+	bcn_prot->enable = BP_SW_MODE;
-+	memcpy(bcn_prot->key, key->key, WLAN_MAX_KEY_LEN);
-+	bcn_prot->key_id = key->keyidx;
-+
-+	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-+				   MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
-+}
- int mt7996_mcu_add_dev_info(struct mt7996_phy *phy,
- 			    struct ieee80211_vif *vif, bool enable)
- {
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index c5c0a44..7808c35 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -310,6 +310,23 @@ struct bss_rate_tlv {
- 	u8 __rsv2[9];
- } __packed;
- 
-+enum {
-+	BP_DISABLE,
-+	BP_SW_MODE,
-+	BP_HW_MODE,
-+};
-+
-+struct mt7996_mcu_bcn_prot_tlv {
-+	__le16 tag;
-+	__le16 len;
-+	u8 pn[6];
-+	u8 enable;
-+	u8 cipher_id;
-+	u8 key[WLAN_MAX_KEY_LEN];
-+	u8 key_id;
-+	u8 __rsv[3];
-+} __packed;
-+
- struct bss_ra_tlv {
- 	__le16 tag;
- 	__le16 len;
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 80a10bf..9f99d13 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -712,9 +712,10 @@ int mt7996_init_debugfs(struct mt7996_phy *phy);
- void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int len);
- bool mt7996_debugfs_rx_log(struct mt7996_dev *dev, const void *data, int len);
- int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
--		       struct mt76_connac_sta_key_conf *sta_key_conf,
- 		       struct ieee80211_key_conf *key, int mcu_cmd,
- 		       struct mt76_wcid *wcid, enum set_key_cmd cmd);
-+int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-+		       struct ieee80211_key_conf *key);
- int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
- 				     struct ieee80211_vif *vif,
- 				     struct ieee80211_sta *sta);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1014-mtk-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv.patch
similarity index 74%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1014-mtk-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv.patch
index 672885d..bfecc98 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1014-mtk-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv.patch
@@ -1,8 +1,8 @@
-From 786bd792b2a62dee5e4aca8aa09ed01be1731ec4 Mon Sep 17 00:00:00 2001
+From 3532bffff8a8d5665304f6abb337305c50174de4 Mon Sep 17 00:00:00 2001
 From: mtk23510 <rudra.shahi@mediatek.com>
 Date: Fri, 24 Mar 2023 19:18:53 +0800
-Subject: [PATCH 42/98] wifi: mt76: mt7996: add driver support for wpa3 ocv and
- bp mt76
+Subject: [PATCH 1014/1041] mtk: wifi: mt76: mt7996: add driver support for
+ wpa3 ocv and bp mt76
 
 Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
 ---
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 1f4e84d..5940e41 100644
+index c4f0ec70..ab13021c 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -377,6 +377,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
+@@ -391,6 +391,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1015-mtk-wifi-mt76-mt7996-add-vendor-cmd-to-get-available.patch
similarity index 92%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1015-mtk-wifi-mt76-mt7996-add-vendor-cmd-to-get-available.patch
index 37717c3..2e4efce 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1015-mtk-wifi-mt76-mt7996-add-vendor-cmd-to-get-available.patch
@@ -1,8 +1,8 @@
-From 8d1ba9d8e0f80eedcdf14d29dbca9c3cbd8589dc Mon Sep 17 00:00:00 2001
+From 5404f25b9db5bbeff8a4288f3709606290cd16f8 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Wed, 3 May 2023 05:08:07 +0800
-Subject: [PATCH 49/98] wifi: mt76: mt7996: add vendor cmd to get available
- color bitmap
+Subject: [PATCH 1015/1041] mtk: wifi: mt76: mt7996: add vendor cmd to get
+ available color bitmap
 
 Add a vendor cmd to notify user space available color bitmap.
 The OBSS BSS color bitmap is maintained in mac80211, so mt76 will make use of that.
@@ -14,7 +14,7 @@
  2 files changed, 47 insertions(+)
 
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index f3b089d..3910157 100644
+index f3b089d7..39101577 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
 @@ -35,6 +35,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
@@ -75,7 +75,7 @@
  
  void mt7996_vendor_register(struct mt7996_phy *phy)
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index 2078caf..eec9e74 100644
+index 2078cafa..eec9e74a 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -6,6 +6,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-single-sku.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-single-sku.patch
deleted file mode 100644
index 14514e2..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-single-sku.patch
+++ /dev/null
@@ -1,355 +0,0 @@
-From d07d8b3b246b974d7ae4ad9bdfc676438cb45fec Mon Sep 17 00:00:00 2001
-From: "Allen.Ye" <allen.ye@mediatek.com>
-Date: Mon, 10 Jul 2023 19:56:16 +0800
-Subject: [PATCH 48/98] wifi: mt76: mt7996: add single sku
-
-Add single sku and default enable sku.
-
-Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
----
- eeprom.c          | 50 +++++++++++++++++++++++---
- mt76.h            |  9 +++++
- mt76_connac_mcu.c |  2 +-
- mt7996/init.c     |  2 ++
- mt7996/main.c     | 16 +++++++++
- mt7996/mcu.c      | 92 +++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      | 12 +++++++
- mt7996/mt7996.h   |  2 ++
- 8 files changed, 179 insertions(+), 6 deletions(-)
-
-diff --git a/eeprom.c b/eeprom.c
-index 89bb913..bd662dd 100644
---- a/eeprom.c
-+++ b/eeprom.c
-@@ -356,6 +356,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
- s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
- 			      struct ieee80211_channel *chan,
- 			      struct mt76_power_limits *dest,
-+			      struct mt76_power_path_limits *dest_path,
- 			      s8 target_power)
- {
- 	struct mt76_dev *dev = phy->dev;
-@@ -363,16 +364,20 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
- 	const __be32 *val;
- 	char name[16];
- 	u32 mcs_rates = dev->drv->mcs_rates;
--	u32 ru_rates = ARRAY_SIZE(dest->ru[0]);
- 	char band;
- 	size_t len;
--	s8 max_power = 0;
-+	s8 max_power = -127;
-+	s8 max_power_backoff = -127;
- 	s8 txs_delta;
-+	int n_chains = hweight8(phy->antenna_mask);
-+	s8 target_power_combine = target_power + mt76_tx_power_nss_delta(n_chains);
- 
- 	if (!mcs_rates)
--		mcs_rates = 10;
-+		mcs_rates = 12;
- 
- 	memset(dest, target_power, sizeof(*dest));
-+	if (dest_path != NULL)
-+		memset(dest_path, 0, sizeof(*dest_path));
- 
- 	if (!IS_ENABLED(CONFIG_OF))
- 		return target_power;
-@@ -420,12 +425,47 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
- 				     ARRAY_SIZE(dest->mcs), val, len,
- 				     target_power, txs_delta, &max_power);
- 
--	val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
-+	val = mt76_get_of_array(np, "rates-ru", &len, ARRAY_SIZE(dest->ru[0]) + 1);
- 	mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
- 				     ARRAY_SIZE(dest->ru), val, len,
- 				     target_power, txs_delta, &max_power);
- 
--	return max_power;
-+	val = mt76_get_of_array(np, "rates-eht", &len, ARRAY_SIZE(dest->eht[0]) + 1);
-+	mt76_apply_multi_array_limit(dest->eht[0], ARRAY_SIZE(dest->eht[0]),
-+				     ARRAY_SIZE(dest->eht), val, len,
-+				     target_power, txs_delta, &max_power);
-+
-+	if (dest_path == NULL)
-+		return max_power;
-+
-+	max_power_backoff = max_power;
-+
-+	val = mt76_get_of_array(np, "paths-cck", &len, ARRAY_SIZE(dest_path->cck));
-+	mt76_apply_array_limit(dest_path->cck, ARRAY_SIZE(dest_path->cck), val,
-+			       target_power_combine, txs_delta, &max_power_backoff);
-+
-+	val = mt76_get_of_array(np, "paths-ofdm", &len, ARRAY_SIZE(dest_path->ofdm));
-+	mt76_apply_array_limit(dest_path->ofdm, ARRAY_SIZE(dest_path->ofdm), val,
-+			       target_power_combine, txs_delta, &max_power_backoff);
-+
-+	val = mt76_get_of_array(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest_path->ofdm_bf));
-+	mt76_apply_array_limit(dest_path->ofdm_bf, ARRAY_SIZE(dest_path->ofdm_bf), val,
-+			       target_power_combine, txs_delta, &max_power_backoff);
-+
-+	val = mt76_get_of_array(np, "paths-ru", &len, ARRAY_SIZE(dest_path->ru[0]) + 1);
-+	mt76_apply_multi_array_limit(dest_path->ru[0], ARRAY_SIZE(dest_path->ru[0]),
-+				     ARRAY_SIZE(dest_path->ru), val, len,
-+				     target_power_combine, txs_delta, &max_power_backoff);
-+
-+	val = mt76_get_of_array(np, "paths-ru-bf", &len, ARRAY_SIZE(dest_path->ru_bf[0]) + 1);
-+	mt76_apply_multi_array_limit(dest_path->ru_bf[0], ARRAY_SIZE(dest_path->ru_bf[0]),
-+				     ARRAY_SIZE(dest_path->ru_bf), val, len,
-+				     target_power_combine, txs_delta, &max_power_backoff);
-+
-+	if (max_power_backoff == target_power_combine)
-+		return max_power;
-+
-+	return max_power_backoff;
- }
- EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
- 
-diff --git a/mt76.h b/mt76.h
-index 0096c7f..d59a1f5 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -1060,6 +1060,14 @@ struct mt76_power_limits {
- 	s8 eht[16][16];
- };
- 
-+struct mt76_power_path_limits {
-+	s8 cck[5];
-+	s8 ofdm[5];
-+	s8 ofdm_bf[4];
-+	s8 ru[16][15];
-+	s8 ru_bf[16][15];
-+};
-+
- struct mt76_ethtool_worker_info {
- 	u64 *data;
- 	int idx;
-@@ -1655,6 +1663,7 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
- s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
- 			      struct ieee80211_channel *chan,
- 			      struct mt76_power_limits *dest,
-+			      struct mt76_power_path_limits *dest_path,
- 			      s8 target_power);
- 
- static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q)
-diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 236cfea..214a526 100644
---- a/mt76_connac_mcu.c
-+++ b/mt76_connac_mcu.c
-@@ -2269,7 +2269,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
- 			sar_power = mt76_get_sar_power(phy, &chan, reg_power);
- 
- 			mt76_get_rate_power_limits(phy, &chan, limits,
--						   sar_power);
-+						   NULL, sar_power);
- 
- 			tx_power_tlv.last_msg = ch_list[idx] == last_ch;
- 			sku_tlbv.channel = ch_list[idx];
-diff --git a/mt7996/init.c b/mt7996/init.c
-index bf3479e..ad93927 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -295,6 +295,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
- 	int nss_delta = mt76_tx_power_nss_delta(nss);
- 	int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);
- 	struct mt76_power_limits limits;
-+	struct mt76_power_path_limits limits_path;
- 
- 	for (i = 0; i < sband->n_channels; i++) {
- 		struct ieee80211_channel *chan = &sband->channels[i];
-@@ -303,6 +304,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
- 		target_power += pwr_delta;
- 		target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
- 							  &limits,
-+							  &limits_path,
- 							  target_power);
- 		target_power += nss_delta;
- 		target_power = DIV_ROUND_UP(target_power, 2);
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 0ea006c..9e3e4ed 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -77,6 +77,15 @@ int mt7996_run(struct ieee80211_hw *hw)
- 	if (ret)
- 		goto out;
- 
-+#ifdef CONFIG_MTK_DEBUG
-+	ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
-+					   !dev->dbg.sku_disable);
-+#else
-+	ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL, true);
-+#endif
-+	if (ret)
-+		goto out;
-+
- 	set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
- 
- 	ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
-@@ -429,6 +438,12 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
- 		ieee80211_wake_queues(hw);
- 	}
- 
-+	if (changed & IEEE80211_CONF_CHANGE_POWER) {
-+		ret = mt7996_mcu_set_txpower_sku(phy);
-+		if (ret)
-+			return ret;
-+	}
-+
- 	mutex_lock(&dev->mt76.mutex);
- 
- 	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
-@@ -1005,6 +1020,7 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
- 	mt76_set_stream_caps(phy->mt76, true);
- 	mt7996_set_stream_vht_txbf_caps(phy);
- 	mt7996_set_stream_he_eht_caps(phy);
-+	mt7996_mcu_set_txpower_sku(phy);
- 
- 	mutex_unlock(&dev->mt76.mutex);
- 
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 1a1c732..c87cb1a 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -4708,6 +4708,98 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
- 				 &req, sizeof(req), false);
- }
- 
-+int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
-+{
-+#define TX_POWER_LIMIT_TABLE_RATE	0
-+#define TX_POWER_LIMIT_TABLE_PATH	1
-+	struct mt7996_dev *dev = phy->dev;
-+	struct mt76_phy *mphy = phy->mt76;
-+	struct ieee80211_hw *hw = mphy->hw;
-+	struct tx_power_limit_table_ctrl {
-+		u8 __rsv1[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+		u8 power_ctrl_id;
-+		u8 power_limit_type;
-+		u8 band_idx;
-+	} __packed req = {
-+		.tag = cpu_to_le16(UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL),
-+		.len = cpu_to_le16(sizeof(req) + MT7996_SKU_PATH_NUM - 4),
-+		.power_ctrl_id = UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL,
-+		.power_limit_type = TX_POWER_LIMIT_TABLE_RATE,
-+		.band_idx = phy->mt76->band_idx,
-+	};
-+
-+	int i, ret, tx_power;
-+	const u8 *len = mt7996_sku_group_len;
-+	struct mt76_power_limits la = {};
-+	struct mt76_power_path_limits la_path = {};
-+	struct sk_buff *skb;
-+
-+	tx_power = mt7996_get_power_bound(phy, hw->conf.power_level);
-+	tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
-+					      &la, &la_path, tx_power);
-+	mphy->txpower_cur = tx_power;
-+
-+	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
-+				 sizeof(req) + MT7996_SKU_PATH_NUM);
-+	if (!skb)
-+		return -ENOMEM;
-+
-+	skb_put_data(skb, &req, sizeof(req));
-+	skb_put_data(skb, &la.cck, len[SKU_CCK] + len[SKU_OFDM]);
-+
-+	skb_put_data(skb, &la.mcs[0], len[SKU_HT20]);
-+	skb_put_data(skb, &la.mcs[1], len[SKU_HT40]);
-+
-+	/* vht */
-+	for (i = 0; i < 4; i++) {
-+		skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));
-+		skb_put_zero(skb, 2);  /* padding */
-+	}
-+
-+	/* he */
-+	skb_put_data(skb, &la.ru[0], sizeof(la.ru));
-+
-+	/* eht */
-+	skb_put_data(skb, &la.eht[0], sizeof(la.eht));
-+
-+	/* padding */
-+	skb_put_zero(skb, MT7996_SKU_PATH_NUM - MT7996_SKU_RATE_NUM);
-+
-+	ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
-+				    MCU_WM_UNI_CMD(TXPOWER), true);
-+	if (ret)
-+		return ret;
-+
-+	/* only set per-path power table when it's configured */
-+	if (!la_path.ofdm[0])
-+		return 0;
-+
-+	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
-+				 sizeof(req) + MT7996_SKU_PATH_NUM);
-+	if (!skb)
-+		return -ENOMEM;
-+	req.power_limit_type = TX_POWER_LIMIT_TABLE_PATH;
-+
-+	skb_put_data(skb, &req, sizeof(req));
-+	skb_put_data(skb, &la_path.cck, sizeof(la_path.cck));
-+	skb_put_data(skb, &la_path.ofdm, sizeof(la_path.ofdm));
-+	skb_put_data(skb, &la_path.ofdm_bf, sizeof(la_path.ofdm_bf));
-+
-+	for (i = 0; i < 32; i++) {
-+		bool bf = i % 2;
-+		u8 idx = i / 2;
-+		s8 *buf = bf ? la_path.ru_bf[idx] : la_path.ru[idx];
-+
-+		skb_put_data(skb, buf, sizeof(la_path.ru[0]));
-+	}
-+
-+	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-+				     MCU_WM_UNI_CMD(TXPOWER), true);
-+}
-+
- #ifdef CONFIG_MTK_VENDOR
- void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
- {
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 7808c35..6fc5ab3 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -777,6 +777,18 @@ enum {
- #define MT7996_MAX_BSS_OFFLOAD_SIZE	(MT7996_MAX_BEACON_SIZE +		\
- 					 MT7996_BEACON_UPDATE_SIZE)
- 
-+static inline s8
-+mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
-+{
-+	struct mt76_phy *mphy = phy->mt76;
-+	int n_chains = hweight8(mphy->antenna_mask);
-+
-+	txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * 2);
-+	txpower -= mt76_tx_power_nss_delta(n_chains);
-+
-+	return txpower;
-+}
-+
- enum {
- 	UNI_BAND_CONFIG_RADIO_ENABLE,
- 	UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 7269076..34c8fe6 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -64,6 +64,7 @@
- #define MT7996_BUILD_TIME_LEN		24
- 
- #define MT7996_SKU_RATE_NUM		417
-+#define MT7996_SKU_PATH_NUM		494
- 
- #define MT7996_RRO_MAX_SESSION		1024
- #define MT7996_RRO_WINDOW_MAX_LEN	1024
-@@ -614,6 +615,7 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
- int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
- int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev);
- int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
-+int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
- int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
- void mt7996_mcu_scs_sta_poll(struct work_struct *work);
- #ifdef CONFIG_NL80211_TESTMODE
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1016-mtk-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
similarity index 88%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1016-mtk-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
index da8c4bd..6039a11 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1016-mtk-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
@@ -1,7 +1,8 @@
-From 7556e60ec860e301a053dad4b16b7e88ccd9baa7 Mon Sep 17 00:00:00 2001
+From fc87a548d72adf02f817bfe4327973978cc69061 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Fri, 19 May 2023 14:56:07 +0800
-Subject: [PATCH 50/98] wifi: mt76: mt7996: add debugfs for fw coredump.
+Subject: [PATCH 1016/1041] mtk: wifi: mt76: mt7996: add debugfs for fw
+ coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -12,7 +13,7 @@
  4 files changed, 56 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 92aa164..2c11837 100644
+index f4ce3b55..67c6bd09 100644
 --- a/mt7996/debugfs.c
 +++ b/mt7996/debugfs.c
 @@ -84,6 +84,8 @@ mt7996_sys_recovery_set(struct file *file, const char __user *user_buf,
@@ -64,10 +65,10 @@
  	desc += scnprintf(buff + desc, bufsz - desc,
  			  "\nlet's dump firmware SER statistics...\n");
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index ee17d59..37cc94e 100644
+index f7dc8db4..b92d7fe9 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -2021,15 +2021,36 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2083,15 +2083,36 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	struct mt7996_dev *dev;
  
  	dev = container_of(work, struct mt7996_dev, dump_work);
@@ -107,7 +108,7 @@
  void mt7996_reset(struct mt7996_dev *dev)
  {
  	if (!dev->recovery.hw_init_done)
-@@ -2047,6 +2068,7 @@ void mt7996_reset(struct mt7996_dev *dev)
+@@ -2109,6 +2130,7 @@ void mt7996_reset(struct mt7996_dev *dev)
  
  		mt7996_irq_disable(dev, MT_INT_MCU_CMD);
  		queue_work(dev->mt76.wq, &dev->dump_work);
@@ -116,10 +117,10 @@
  	}
  
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 6fc5ab3..989a2ff 100644
+index 68bf82fc..35f757dc 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -900,7 +900,11 @@ enum {
+@@ -956,7 +956,11 @@ enum {
  	UNI_CMD_SER_SET_RECOVER_L3_BF,
  	UNI_CMD_SER_SET_RECOVER_L4_MDP,
  	UNI_CMD_SER_SET_RECOVER_FULL,
@@ -132,10 +133,10 @@
  	UNI_CMD_SER_ENABLE = 1,
  	UNI_CMD_SER_SET,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 34c8fe6..9b110cf 100644
+index 09ce3c35..dd9aa9e2 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -100,6 +100,14 @@ enum mt7996_ram_type {
+@@ -139,6 +139,14 @@ enum mt7996_ram_type {
  	__MT7996_RAM_TYPE_MAX,
  };
  
@@ -150,7 +151,7 @@
  enum mt7996_txq_id {
  	MT7996_TXQ_FWDL = 16,
  	MT7996_TXQ_MCU_WM,
-@@ -342,6 +350,7 @@ struct mt7996_dev {
+@@ -388,6 +396,7 @@ struct mt7996_dev {
  
  	/* protects coredump data */
  	struct mutex dump_mutex;
@@ -158,9 +159,9 @@
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
  		struct mt7996_crash_data *crash_data[__MT7996_RAM_TYPE_MAX];
-@@ -541,6 +550,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
- 			 struct ieee80211_supported_band *sband);
+@@ -573,6 +582,7 @@ void mt7996_init_txpower(struct mt7996_phy *phy);
  int mt7996_txbf_init(struct mt7996_dev *dev);
+ int mt7996_get_chip_sku(struct mt7996_dev *dev);
  void mt7996_reset(struct mt7996_dev *dev);
 +void mt7996_coredump(struct mt7996_dev *dev, u8 state);
  int mt7996_run(struct ieee80211_hw *hw);
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1017-mtk-wifi-mt76-mt7996-add-support-for-runtime-set-in-.patch
similarity index 79%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1017-mtk-wifi-mt76-mt7996-add-support-for-runtime-set-in-.patch
index dc0b0c3..2a94253 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1017-mtk-wifi-mt76-mt7996-add-support-for-runtime-set-in-.patch
@@ -1,8 +1,8 @@
-From a928c6df5edd9920b4293de6d1216461952aec27 Mon Sep 17 00:00:00 2001
+From 0e6130e10742d6937b5f6ab69a7b0c2aea1d8b79 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 6 Jun 2023 16:57:10 +0800
-Subject: [PATCH 51/98] wifi: mt76: mt7996: add support for runtime set in-band
- discovery
+Subject: [PATCH 1017/1041] mtk: wifi: mt76: mt7996: add support for runtime
+ set in-band discovery
 
 with this patch, AP can runtime set inband discovery via hostapd_cli
 
@@ -17,10 +17,10 @@
  1 file changed, 2 insertions(+), 3 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index c87cb1a..722c435 100644
+index 05fa855b..9331abb5 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2484,8 +2484,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+@@ -2600,8 +2600,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
  	if (IS_ERR(rskb))
  		return PTR_ERR(rskb);
  
@@ -30,7 +30,7 @@
  		interval = vif->bss_conf.fils_discovery.max_interval;
  		skb = ieee80211_get_fils_discovery_tmpl(hw, vif);
  	} else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&
-@@ -2521,7 +2520,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+@@ -2636,7 +2635,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
  	discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
  	discov->tx_interval = interval;
  	discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1018-mtk-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-en.patch
similarity index 89%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1018-mtk-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-en.patch
index 06fc5e8..4714bd7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1018-mtk-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-en.patch
@@ -1,37 +1,23 @@
-From 140f810c788ffccc605fa979635c9be2db4b9748 Mon Sep 17 00:00:00 2001
+From a0ddc3b5248671258de46c7f1b4fc4e26f6cf553 Mon Sep 17 00:00:00 2001
 From: mtk27745 <rex.lu@mediatek.com>
 Date: Thu, 8 Jun 2023 20:21:04 +0800
-Subject: [PATCH 52/98] wifi: mt76: mt7996: add vendor subcmd EDCCA ctrl enable
+Subject: [PATCH 1018/1041] mtk: wifi: mt76: mt7996: add vendor subcmd EDCCA
+ ctrl enable
 
 ---
- mt7996/main.c    |   3 ++
  mt7996/mcu.h     |   2 +
  mt7996/mt7996.h  |  11 ++++
- mt7996/mtk_mcu.c |  86 ++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.c |  87 +++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.h |  15 ++++++
  mt7996/vendor.c  | 132 +++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/vendor.h  |  33 ++++++++++++
- 7 files changed, 282 insertions(+)
+ 6 files changed, 280 insertions(+)
 
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 9e3e4ed..d928564 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -431,6 +431,9 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
- 	int ret;
- 
- 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-+		ret = mt7996_mcu_edcca_enable(phy, true);
-+		if (ret)
-+			return ret;
- 		ieee80211_stop_queues(hw);
- 		ret = mt7996_set_channel(phy);
- 		if (ret)
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 989a2ff..bb876f3 100644
+index 35f757dc..34fdfb26 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -791,6 +791,8 @@ mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
+@@ -845,6 +845,8 @@ mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
  
  enum {
  	UNI_BAND_CONFIG_RADIO_ENABLE,
@@ -41,10 +27,10 @@
  };
  
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 9b110cf..8fd29d7 100644
+index dd9aa9e2..130e9b37 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -750,6 +750,17 @@ int mt7996_vendor_amnt_sta_remove(struct mt7996_phy *phy,
+@@ -785,6 +785,17 @@ int mt7996_vendor_amnt_sta_remove(struct mt7996_phy *phy,
  				  struct ieee80211_sta *sta);
  #endif
  
@@ -61,15 +47,16 @@
 +
  #ifdef CONFIG_MTK_DEBUG
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
- #endif
+ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
-index f772243..048c534 100644
+index e56ddd8f..5c54d02c 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
-@@ -38,4 +38,90 @@ int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *even
- 	return 0;
+@@ -59,4 +59,91 @@ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val)
+ 	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &req,
+ 				 sizeof(req), true);
  }
- 
++
 +int mt7996_mcu_edcca_enable(struct mt7996_phy *phy, bool enable)
 +{
 +	struct mt7996_dev *dev = phy->dev;
@@ -158,10 +145,10 @@
 +
  #endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
-index beb1aba..9c0db87 100644
+index 1eb27831..1137fe5d 100644
 --- a/mt7996/mtk_mcu.h
 +++ b/mt7996/mtk_mcu.h
-@@ -89,6 +89,21 @@ enum txpower_event {
+@@ -93,6 +93,21 @@ enum txpower_event {
  	UNI_TXPOWER_PHY_RATE_INFO = 5,
  };
  
@@ -184,7 +171,7 @@
  
  #endif
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index 3910157..9f333d0 100644
+index 39101577..9f333d0e 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
 @@ -40,6 +40,26 @@ bss_color_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL] = {
@@ -341,7 +328,7 @@
  
  void mt7996_vendor_register(struct mt7996_phy *phy)
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index eec9e74..4465bc9 100644
+index eec9e74a..4465bc9d 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -6,9 +6,42 @@
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1019-mtk-wifi-mt76-mt7996-add-support-spatial-reuse-debug.patch
similarity index 88%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1019-mtk-wifi-mt76-mt7996-add-support-spatial-reuse-debug.patch
index 142193f..a0620a7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1019-mtk-wifi-mt76-mt7996-add-support-spatial-reuse-debug.patch
@@ -1,8 +1,8 @@
-From 86906513b2597a79c26b72a6a9dc0ecf8b0ce1ed Mon Sep 17 00:00:00 2001
+From 0b992146abb735d42afa9f2fa62c077dd09879f2 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Mon, 10 Jul 2023 11:47:29 +0800
-Subject: [PATCH 54/98] wifi: mt76: mt7996: add support spatial reuse debug
- commands
+Subject: [PATCH 1019/1041] mtk: wifi: mt76: mt7996: add support spatial reuse
+ debug commands
 
 This commit adds the following debug commands in debugfs:
 1. sr_enable: enable/disable spatial reuse feature. Default is on.
@@ -15,21 +15,22 @@
 
 To learn more details of these commands, please check:
 https://wiki.mediatek.inc/display/APKB/mt76+Phy+feature+debug+Cheetsheet#mt76PhyfeaturedebugCheetsheet-SpatialReuse
+
 ---
  mt76_connac_mcu.h    |   1 +
  mt7996/main.c        |   6 +++
- mt7996/mcu.c         |   5 ++
+ mt7996/mcu.c         |   8 ++++
  mt7996/mt7996.h      |   6 +++
  mt7996/mtk_debugfs.c |  82 ++++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.c     | 111 +++++++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.h     |  56 ++++++++++++++++++++++
- 7 files changed, 267 insertions(+)
+ 7 files changed, 270 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 42eb64c..e904ebc 100644
+index fefa2a0c..b657ef39 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1031,6 +1031,7 @@ enum {
+@@ -1029,6 +1029,7 @@ enum {
  	MCU_UNI_EVENT_BSS_BEACON_LOSS = 0x0c,
  	MCU_UNI_EVENT_SCAN_DONE = 0x0e,
  	MCU_UNI_EVENT_RDD_REPORT = 0x11,
@@ -38,7 +39,7 @@
  	MCU_UNI_EVENT_TX_DONE = 0x2d,
  	MCU_UNI_EVENT_BF = 0x33,
 diff --git a/mt7996/main.c b/mt7996/main.c
-index d928564..35f8fee 100644
+index 2042edd6..c1776aeb 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -6,6 +6,9 @@
@@ -62,26 +63,29 @@
  					   !dev->dbg.sku_disable);
  #else
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 722c435..2dbec1e 100644
+index 9331abb5..718a4f8d 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -617,6 +617,11 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
- 	case MCU_UNI_EVENT_RDD_REPORT:
- 		mt7996_mcu_rx_radar_detected(dev, skb);
+@@ -712,6 +712,14 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 	case MCU_UNI_EVENT_WED_RRO:
+ 		mt7996_mcu_wed_rro_event(dev, skb);
  		break;
 +#ifdef CONFIG_MTK_DEBUG
 +	case MCU_UNI_EVENT_SR:
 +		mt7996_mcu_rx_sr_event(dev, skb);
 +		break;
 +#endif
- 	case MCU_UNI_EVENT_THERMAL:
- 		mt7996_mcu_rx_thermal_notify(dev, skb);
- 		break;
++	case MCU_UNI_EVENT_THERMAL:
++		mt7996_mcu_rx_thermal_notify(dev, skb);
++		break;
+ #ifdef CONFIG_NL80211_TESTMODE
+ 	case MCU_UNI_EVENT_TESTMODE_CTRL:
+ 		mt7996_tm_rf_test_event(dev, skb);
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 8fd29d7..1fac783 100644
+index 130e9b37..385f7218 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -306,6 +306,10 @@ struct mt7996_phy {
+@@ -351,6 +351,10 @@ struct mt7996_phy {
  	spinlock_t amnt_lock;
  	struct mt7996_air_monitor_ctrl amnt_ctrl;
  #endif
@@ -92,20 +96,20 @@
  };
  
  struct mt7996_dev {
-@@ -763,6 +767,8 @@ enum edcca_bw_id {
- 
+@@ -799,6 +803,8 @@ enum edcca_bw_id {
  #ifdef CONFIG_MTK_DEBUG
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
+ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
 +int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set);
 +void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
  #endif
  
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
 diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
-index 82b2785..f56ad88 100644
+index fe6492ab..6229739b 100644
 --- a/mt7996/mtk_debugfs.c
 +++ b/mt7996/mtk_debugfs.c
-@@ -2589,6 +2589,83 @@ static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
+@@ -2681,6 +2681,83 @@ static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
  	return 0;
  }
  
@@ -189,9 +193,9 @@
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
  {
  	struct mt7996_dev *dev = phy->dev;
-@@ -2642,6 +2719,11 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
- 
+@@ -2759,6 +2836,11 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
  	debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
+ 	debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
  
 +	debugfs_create_file("sr_enable", 0600, dir, phy, &fops_sr_enable);
 +	debugfs_create_file("sr_enhanced_enable", 0600, dir, phy, &fops_sr_enhanced_enable);
@@ -202,10 +206,10 @@
  }
  
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
-index 048c534..3256de7 100644
+index 5c54d02c..dbdf8d80 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
-@@ -124,4 +124,115 @@ int mt7996_mcu_edcca_threshold_ctrl(struct mt7996_phy *phy, u8 *value, bool set)
+@@ -146,4 +146,115 @@ int mt7996_mcu_edcca_threshold_ctrl(struct mt7996_phy *phy, u8 *value, bool set)
  	return 0;
  }
  
@@ -322,10 +326,10 @@
 +}
  #endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
-index 9c0db87..a5bdb88 100644
+index 1137fe5d..cc2de8f4 100644
 --- a/mt7996/mtk_mcu.h
 +++ b/mt7996/mtk_mcu.h
-@@ -104,6 +104,62 @@ enum {
+@@ -108,6 +108,62 @@ enum {
  	EDCCA_JAPAN = 3
  };
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1020-mtk-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
similarity index 62%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1020-mtk-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
index ac60aa8..5f2b377 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1020-mtk-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
@@ -1,24 +1,24 @@
-From d7337c25e774ed96fc8f6d1390321bfc2dcac545 Mon Sep 17 00:00:00 2001
+From 135efc5c74d7ffdb671e7a8ffe32e18879251119 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 1 Aug 2023 16:02:28 +0800
-Subject: [PATCH 55/98] wifi: mt76: mt7996: Establish BA in VO queue
+Subject: [PATCH 1020/1041] mtk: wifi: mt76: mt7996: Establish BA in VO queue
 
 ---
  mt7996/mac.c | 2 --
  1 file changed, 2 deletions(-)
 
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 37cc94e..b24f237 100644
+index b92d7fe9..618c1f40 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -1017,8 +1017,6 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
+@@ -1032,8 +1032,6 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
  		return;
  
  	tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
 -	if (tid >= 6) /* skip VO queue */
 -		return;
  
- 	if (is_8023)
+ 	if (is_8023) {
  		fc = IEEE80211_FTYPE_DATA |
 -- 
 2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch
deleted file mode 100644
index f7596bb..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From e24d476d4baca1aa3a32ac82ec0f1ea56cedf06c Mon Sep 17 00:00:00 2001
-From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
-Date: Wed, 28 Jun 2023 05:07:43 +0800
-Subject: [PATCH 53/98] wifi: mt76: mt7996: Fix incorrect UWTBL_LEN_IN_DW
- parameter
-
-The UWTBL length is 16 DW. Correct the len to 16 so that we can
-see full UWTBL when checking wtbl with debugfs.
-
-Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
----
- mt7996/mtk_debug.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
-index 368f0bc..9718c2c 100644
---- a/mt7996/mtk_debug.h
-+++ b/mt7996/mtk_debug.h
-@@ -834,7 +834,7 @@ enum cipher_suit {
- };
- 
- #define LWTBL_LEN_IN_DW			36
--#define UWTBL_LEN_IN_DW			10
-+#define UWTBL_LEN_IN_DW			16
- 
- #define MT_DBG_WTBL_BASE		0x820D8000
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1021-mtk-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-w.patch
similarity index 84%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1021-mtk-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-w.patch
index 9fbc586..169f6e0 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1021-mtk-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-w.patch
@@ -1,8 +1,8 @@
-From b69722554a27e8c13612f62c9b9cf8651a30bd8f Mon Sep 17 00:00:00 2001
+From 4dac1d1c289eccead02ec6d942aaa9d28929c484 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 10:00:17 +0800
-Subject: [PATCH 56/98] wifi: mt76: mt7996: add eagle iFEM HWITS ZWDFS SW
- workaround
+Subject: [PATCH 1021/1041] mtk: wifi: mt76: mt7996: add eagle iFEM HWITS ZWDFS
+ SW workaround
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,10 +12,10 @@
  3 files changed, 60 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 35f8fee..d27275a 100644
+index c1776aeb..36894828 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -1413,6 +1413,54 @@ mt7996_twt_teardown_request(struct ieee80211_hw *hw,
+@@ -1431,6 +1431,54 @@ mt7996_twt_teardown_request(struct ieee80211_hw *hw,
  	mutex_unlock(&dev->mt76.mutex);
  }
  
@@ -70,7 +70,7 @@
  static int
  mt7996_set_radar_background(struct ieee80211_hw *hw,
  			    struct cfg80211_chan_def *chandef)
-@@ -1421,6 +1469,7 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
+@@ -1439,6 +1487,7 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
  	struct mt7996_dev *dev = phy->dev;
  	int ret = -EINVAL;
  	bool running;
@@ -78,7 +78,7 @@
  
  	mutex_lock(&dev->mt76.mutex);
  
-@@ -1433,13 +1482,14 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
+@@ -1451,13 +1500,14 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
  		goto out;
  	}
  
@@ -95,7 +95,7 @@
  		ret = mt7996_mcu_rdd_background_enable(phy, NULL);
  		if (ret)
  			goto out;
-@@ -1448,7 +1498,9 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
+@@ -1466,7 +1516,9 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
  			goto update_phy;
  	}
  
@@ -107,10 +107,10 @@
  		goto out;
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 2dbec1e..a4f3ed9 100644
+index 718a4f8d..689f4ec5 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -350,12 +350,14 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -369,12 +369,14 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
  	if (!mphy)
  		return;
  
@@ -128,10 +128,10 @@
  }
  
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 1fac783..413fbf7 100644
+index 385f7218..5175c7fa 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -392,6 +392,7 @@ struct mt7996_dev {
+@@ -440,6 +440,7 @@ struct mt7996_dev {
  	bool testmode_enable;
  	bool bin_file_mode;
  	u8 eeprom_mode;
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1022-mtk-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_le.patch
similarity index 78%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1022-mtk-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_le.patch
index 63afb2c..9c8994c 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1022-mtk-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_le.patch
@@ -1,17 +1,18 @@
-From fd96728a963faf55b7daba46a78aa25ab0c5f147 Mon Sep 17 00:00:00 2001
+From 386da4814a8d8edd4071d0a98ac53402f18845fc Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Sat, 12 Aug 2023 04:17:22 +0800
-Subject: [PATCH 57/98] wifi: mt76: mt7996: report tx and rx byte to tpt_led
+Subject: [PATCH 1022/1041] mtk: wifi: mt76: mt7996: report tx and rx byte to
+ tpt_led
 
 ---
  mt7996/mcu.c | 15 +++++++++++----
  1 file changed, 11 insertions(+), 4 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index a4f3ed9..3a960d1 100644
+index 689f4ec5..5683b3f5 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -531,6 +531,8 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -522,6 +522,8 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  		u8 ac;
  		u16 wlan_idx;
  		struct mt76_wcid *wcid;
@@ -20,7 +21,7 @@
  
  		switch (le16_to_cpu(res->tag)) {
  		case UNI_ALL_STA_TXRX_RATE:
-@@ -550,11 +552,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -541,11 +543,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  			if (!wcid)
  				break;
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1025-wifi-mt76-mt7996-support-dup-wtbl.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1023-mtk-wifi-mt76-mt7996-support-dup-wtbl.patch
similarity index 71%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1025-wifi-mt76-mt7996-support-dup-wtbl.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1023-mtk-wifi-mt76-mt7996-support-dup-wtbl.patch
index 12cdca3..fe7894a 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1025-wifi-mt76-mt7996-support-dup-wtbl.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1023-mtk-wifi-mt76-mt7996-support-dup-wtbl.patch
@@ -1,10 +1,9 @@
-From a0baa183c16552ec874141c62ce3c6346d24c684 Mon Sep 17 00:00:00 2001
+From ea760fad749d58a54d4bbd41528a60503aa56eef Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 21 Sep 2023 00:52:46 +0800
-Subject: [PATCH 58/98] wifi: mt76: mt7996: support dup wtbl
+Subject: [PATCH 1023/1041] mtk: wifi: mt76: mt7996: support dup wtbl
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: I14ba41ace8341c23c1cfb6e9c4fbb2d5e93a5714
 ---
  mt7996/init.c    |  1 +
  mt7996/mt7996.h  |  1 +
@@ -12,23 +11,23 @@
  3 files changed, 25 insertions(+)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index ad93927..4503482 100644
+index ab13021c..b3677e03 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -660,6 +660,7 @@ static void mt7996_init_work(struct work_struct *work)
- 	mt7996_init_txpower(dev, &dev->mphy.sband_5g.sband);
- 	mt7996_init_txpower(dev, &dev->mphy.sband_6g.sband);
+@@ -680,6 +680,7 @@ static void mt7996_init_work(struct work_struct *work)
+ 	mt7996_mcu_set_eeprom(dev);
+ 	mt7996_mac_init(dev);
  	mt7996_txbf_init(dev);
 +	mt7996_mcu_set_dup_wtbl(dev);
  }
  
  void mt7996_wfsys_reset(struct mt7996_dev *dev)
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 413fbf7..766de3f 100644
+index 5175c7fa..087ab526 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -770,6 +770,7 @@ enum edcca_bw_id {
- int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
+@@ -806,6 +806,7 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
+ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
  int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set);
  void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
 +int mt7996_mcu_set_dup_wtbl(struct mt7996_dev *dev);
@@ -36,10 +35,10 @@
  
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
-index 3256de7..149694c 100644
+index dbdf8d80..ea4e5bf2 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
-@@ -235,4 +235,27 @@ void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -257,4 +257,27 @@ void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb)
  			 le16_to_cpu(event->basic.tag));
  	}
  }
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1024-mtk-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1024-mtk-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
index 354e553..eb32e88 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1024-mtk-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
@@ -1,7 +1,7 @@
-From b5d139f32d6f4f6476b82d59af7a96a1f57858a9 Mon Sep 17 00:00:00 2001
+From 4d89751738af129e90d9c77fd72308decce2fbfc Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Fri, 22 Sep 2023 09:54:49 +0800
-Subject: [PATCH 59/98] wifi: mt76: mt7996: add ibf control vendor cmd
+Subject: [PATCH 1024/1041] mtk: wifi: mt76: mt7996: add ibf control vendor cmd
 
 Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
 ---
@@ -10,7 +10,7 @@
  2 files changed, 88 insertions(+)
 
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index 9f333d0..dae3260 100644
+index 9f333d0e..dae3260a 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
 @@ -60,6 +60,11 @@ edcca_dump_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP] = {
@@ -100,7 +100,7 @@
  
  void mt7996_vendor_register(struct mt7996_phy *phy)
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index 4465bc9..49f46f2 100644
+index 4465bc9d..49f46f25 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -7,6 +7,7 @@ enum mtk_nl80211_vendor_subcmds {
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1025-mtk-wifi-mt76-try-more-times-when-send-message-timeo.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1025-mtk-wifi-mt76-try-more-times-when-send-message-timeo.patch
new file mode 100644
index 0000000..a9be456
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1025-mtk-wifi-mt76-try-more-times-when-send-message-timeo.patch
@@ -0,0 +1,231 @@
+From 2e5df04c0677add9e853c65b619bacffbfd10cf6 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Mon, 6 Nov 2023 11:10:10 +0800
+Subject: [PATCH 1025/1041] mtk: wifi: mt76: try more times when send message
+ timeout.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+---
+ dma.c        |  7 ++++--
+ mcu.c        | 65 ++++++++++++++++++++++++++++++++++++----------------
+ mt7996/mac.c | 49 ++++++++++-----------------------------
+ 3 files changed, 62 insertions(+), 59 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 12f0e2fd..be8e2aaa 100644
+--- a/dma.c
++++ b/dma.c
+@@ -506,9 +506,12 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+ {
+ 	struct mt76_queue_buf buf = {};
+ 	dma_addr_t addr;
++	int ret = -ENOMEM;
+ 
+-	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
++	if (test_bit(MT76_MCU_RESET, &dev->phy.state)) {
++		ret = -EAGAIN;
+ 		goto error;
++	}
+ 
+ 	if (q->queued + 1 >= q->ndesc - 1)
+ 		goto error;
+@@ -530,7 +533,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+ 
+ error:
+ 	dev_kfree_skb(skb);
+-	return -ENOMEM;
++	return ret;
+ }
+ 
+ static int
+diff --git a/mcu.c b/mcu.c
+index fa4b0544..2926f715 100644
+--- a/mcu.c
++++ b/mcu.c
+@@ -4,6 +4,7 @@
+  */
+ 
+ #include "mt76.h"
++#include "mt76_connac.h"
+ #include <linux/moduleparam.h>
+ 
+ struct sk_buff *
+@@ -74,35 +75,59 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
+ 				  int cmd, bool wait_resp,
+ 				  struct sk_buff **ret_skb)
+ {
++#define MT76_MSG_MAX_RETRY_CNT 3
+ 	unsigned long expires;
+-	int ret, seq;
++	int ret, seq, retry_cnt;
++	struct sk_buff *skb_tmp;
++	bool retry = wait_resp && is_mt7996(dev);
+ 
+ 	if (ret_skb)
+ 		*ret_skb = NULL;
+ 
+ 	mutex_lock(&dev->mcu.mutex);
+-
+-	ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
+-	if (ret < 0)
+-		goto out;
+-
+-	if (!wait_resp) {
+-		ret = 0;
+-		goto out;
++	retry_cnt = retry ? MT76_MSG_MAX_RETRY_CNT : 1;
++	while (retry_cnt) {
++		skb_tmp = mt76_mcu_msg_alloc(dev, skb->data, skb->len);
++		if (!skb_tmp)
++			goto out;
++
++		if (retry && retry_cnt < MT76_MSG_MAX_RETRY_CNT) {
++			if (test_bit(MT76_MCU_RESET, &dev->phy.state))
++				usleep_range(200000, 500000);
++			dev_err(dev->dev, "send message %08x timeout, try again.\n", cmd);
++		}
++
++		ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq);
++		if (ret < 0 && ret != -EAGAIN)
++			goto out;
++
++		if (!wait_resp) {
++			ret = 0;
++			goto out;
++		}
++
++		expires = jiffies + dev->mcu.timeout;
++
++		do {
++			skb_tmp = mt76_mcu_get_response(dev, expires);
++			ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb_tmp, seq);
++			if (ret == -ETIMEDOUT)
++				break;
++
++			if (!ret && ret_skb)
++				*ret_skb = skb_tmp;
++			else
++				dev_kfree_skb(skb_tmp);
++
++			if (ret != -EAGAIN)
++				goto out;
++		} while (ret == -EAGAIN);
++
++		retry_cnt--;
+ 	}
+ 
+-	expires = jiffies + dev->mcu.timeout;
+-
+-	do {
+-		skb = mt76_mcu_get_response(dev, expires);
+-		ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb, seq);
+-		if (!ret && ret_skb)
+-			*ret_skb = skb;
+-		else
+-			dev_kfree_skb(skb);
+-	} while (ret == -EAGAIN);
+-
+ out:
++	dev_kfree_skb(skb);
+ 	mutex_unlock(&dev->mcu.mutex);
+ 
+ 	return ret;
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 618c1f40..96627a58 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1662,18 +1662,6 @@ mt7996_mac_restart(struct mt7996_dev *dev)
+ 			mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0);
+ 	}
+ 
+-	set_bit(MT76_RESET, &dev->mphy.state);
+-	set_bit(MT76_MCU_RESET, &dev->mphy.state);
+-	wake_up(&dev->mt76.mcu.wait);
+-	if (phy2) {
+-		set_bit(MT76_RESET, &phy2->mt76->state);
+-		set_bit(MT76_MCU_RESET, &phy2->mt76->state);
+-	}
+-	if (phy3) {
+-		set_bit(MT76_RESET, &phy3->mt76->state);
+-		set_bit(MT76_MCU_RESET, &phy3->mt76->state);
+-	}
+-
+ 	/* lock/unlock all queues to ensure that no tx is pending */
+ 	mt76_txq_schedule_all(&dev->mphy);
+ 	if (phy2)
+@@ -1787,13 +1775,24 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
+ 	phy3 = mt7996_phy3(dev);
+ 	dev->recovery.hw_full_reset = true;
+ 
+-	wake_up(&dev->mt76.mcu.wait);
+ 	ieee80211_stop_queues(mt76_hw(dev));
+ 	if (phy2)
+ 		ieee80211_stop_queues(phy2->mt76->hw);
+ 	if (phy3)
+ 		ieee80211_stop_queues(phy3->mt76->hw);
+ 
++	set_bit(MT76_RESET, &dev->mphy.state);
++	set_bit(MT76_MCU_RESET, &dev->mphy.state);
++	wake_up(&dev->mt76.mcu.wait);
++	if (phy2) {
++		set_bit(MT76_RESET, &phy2->mt76->state);
++		set_bit(MT76_MCU_RESET, &phy2->mt76->state);
++	}
++	if (phy3) {
++		set_bit(MT76_RESET, &phy3->mt76->state);
++		set_bit(MT76_MCU_RESET, &phy3->mt76->state);
++	}
++
+ 	cancel_work_sync(&dev->wed_rro.work);
+ 	cancel_delayed_work_sync(&dev->mphy.mac_work);
+ 	if (phy2)
+@@ -1896,16 +1895,6 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 	set_bit(MT76_MCU_RESET, &dev->mphy.state);
+ 	wake_up(&dev->mt76.mcu.wait);
+ 
+-	cancel_work_sync(&dev->wed_rro.work);
+-	cancel_delayed_work_sync(&dev->mphy.mac_work);
+-	if (phy2) {
+-		set_bit(MT76_RESET, &phy2->mt76->state);
+-		cancel_delayed_work_sync(&phy2->mt76->mac_work);
+-	}
+-	if (phy3) {
+-		set_bit(MT76_RESET, &phy3->mt76->state);
+-		cancel_delayed_work_sync(&phy3->mt76->mac_work);
+-	}
+ 	mt76_worker_disable(&dev->mt76.tx_worker);
+ 	mt76_for_each_q_rx(&dev->mt76, i) {
+ 		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+@@ -1916,8 +1905,6 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 	}
+ 	napi_disable(&dev->mt76.tx_napi);
+ 
+-	mutex_lock(&dev->mt76.mutex);
+-
+ 	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_STOPPED);
+ 
+ 	if (mt7996_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) {
+@@ -1990,20 +1977,8 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 	if (phy3)
+ 		ieee80211_wake_queues(phy3->mt76->hw);
+ 
+-	mutex_unlock(&dev->mt76.mutex);
+-
+ 	mt7996_update_beacons(dev);
+ 
+-	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
+-				     MT7996_WATCHDOG_TIME);
+-	if (phy2)
+-		ieee80211_queue_delayed_work(phy2->mt76->hw,
+-					     &phy2->mt76->mac_work,
+-					     MT7996_WATCHDOG_TIME);
+-	if (phy3)
+-		ieee80211_queue_delayed_work(phy3->mt76->hw,
+-					     &phy3->mt76->mac_work,
+-					     MT7996_WATCHDOG_TIME);
+ 	dev_info(dev->mt76.dev,"\n%s L1 SER recovery completed.",
+ 		 wiphy_name(dev->mt76.hw->wiphy));
+ }
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1026-mtk-wifi-mt76-mt7996-add-SER-overlap-handle.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1026-mtk-wifi-mt76-mt7996-add-SER-overlap-handle.patch
new file mode 100644
index 0000000..5561e51
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1026-mtk-wifi-mt76-mt7996-add-SER-overlap-handle.patch
@@ -0,0 +1,95 @@
+From 4165fd47922164b4837bc5d247a82bca1a8e1b75 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Tue, 21 Nov 2023 09:55:46 +0800
+Subject: [PATCH 1026/1041] mtk: wifi: mt76: mt7996: add SER overlap handle
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+---
+ mcu.c           | 3 ++-
+ mt7996/mac.c    | 8 ++++++++
+ mt7996/mcu.c    | 8 ++++++++
+ mt7996/mt7996.h | 2 ++
+ 4 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/mcu.c b/mcu.c
+index 2926f715..a7afa2d7 100644
+--- a/mcu.c
++++ b/mcu.c
+@@ -94,7 +94,8 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
+ 		if (retry && retry_cnt < MT76_MSG_MAX_RETRY_CNT) {
+ 			if (test_bit(MT76_MCU_RESET, &dev->phy.state))
+ 				usleep_range(200000, 500000);
+-			dev_err(dev->dev, "send message %08x timeout, try again.\n", cmd);
++			dev_err(dev->dev, "send message %08x timeout, try again(%d).\n",
++				cmd, (MT76_MSG_MAX_RETRY_CNT - retry_cnt));
+ 		}
+ 
+ 		ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq);
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 96627a58..22d7dc6d 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1876,6 +1876,7 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 	if (!(READ_ONCE(dev->recovery.state) & MT_MCU_CMD_STOP_DMA))
+ 		return;
+ 
++	dev->recovery.l1_reset_last = dev->recovery.l1_reset;
+ 	dev_info(dev->mt76.dev,"\n%s L1 SER recovery start.",
+ 		 wiphy_name(dev->mt76.hw->wiphy));
+ 
+@@ -1893,6 +1894,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 
+ 	set_bit(MT76_RESET, &dev->mphy.state);
+ 	set_bit(MT76_MCU_RESET, &dev->mphy.state);
++	if (phy2)
++		set_bit(MT76_RESET, &phy2->mt76->state);
++	if (phy3)
++		set_bit(MT76_RESET, &phy3->mt76->state);
+ 	wake_up(&dev->mt76.mcu.wait);
+ 
+ 	mt76_worker_disable(&dev->mt76.tx_worker);
+@@ -2107,6 +2112,9 @@ void mt7996_reset(struct mt7996_dev *dev)
+ 		return;
+ 	}
+ 
++	if ((READ_ONCE(dev->recovery.state) & MT_MCU_CMD_STOP_DMA))
++		dev->recovery.l1_reset++;
++
+ 	queue_work(dev->mt76.wq, &dev->reset_work);
+ 	wake_up(&dev->reset_wait);
+ }
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 5683b3f5..726d2adf 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -246,6 +246,14 @@ mt7996_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
+ 	u32 val;
+ 	u8 seq;
+ 
++	if (dev->recovery.l1_reset_last != dev->recovery.l1_reset) {
++		dev_info(dev->mt76.dev,"\n%s L1 SER recovery overlap, drop message %08x.",
++			 wiphy_name(dev->mt76.hw->wiphy), cmd);
++
++		dev_kfree_skb(skb);
++		return -EPERM;
++	}
++
+ 	mdev->mcu.timeout = 20 * HZ;
+ 
+ 	seq = ++dev->mt76.mcu.msg_seq & 0xf;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 087ab526..71602b9b 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -391,6 +391,8 @@ struct mt7996_dev {
+ 	wait_queue_head_t reset_wait;
+ 	struct {
+ 		u32 state;
++		u32 l1_reset;
++		u32 l1_reset_last;
+ 		u32 wa_reset_count;
+ 		u32 wm_reset_count;
+ 		bool hw_full_reset:1;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1027-mtk-wifi-mt76-mt7996-kite-default-1-pcie-setting.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1027-mtk-wifi-mt76-mt7996-kite-default-1-pcie-setting.patch
new file mode 100644
index 0000000..95c0edf
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1027-mtk-wifi-mt76-mt7996-kite-default-1-pcie-setting.patch
@@ -0,0 +1,57 @@
+From c0b68dfc03ee90fde9ebacc07db8f3c186846dd5 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 13 Jul 2023 16:36:36 +0800
+Subject: [PATCH 1027/1041] mtk: wifi: mt76: mt7996: kite default 1-pcie
+ setting
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/pci.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index 04056181..05830c01 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -11,6 +11,9 @@
+ #include "mac.h"
+ #include "../trace.h"
+ 
++static bool hif2_enable = false;
++module_param(hif2_enable, bool, 0644);
++
+ static LIST_HEAD(hif_list);
+ static DEFINE_SPINLOCK(hif_lock);
+ static u32 hif_idx;
+@@ -63,6 +66,9 @@ static struct mt7996_hif *mt7996_pci_init_hif2(struct pci_dev *pdev)
+ {
+ 	hif_idx++;
+ 
++	if (!hif2_enable)
++		return NULL;
++
+ 	if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL) &&
+ 	    !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x799a, NULL))
+ 		return NULL;
+@@ -77,6 +83,9 @@ static int mt7996_pci_hif2_probe(struct pci_dev *pdev)
+ {
+ 	struct mt7996_hif *hif;
+ 
++	if (!hif2_enable)
++		return 0;
++
+ 	hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL);
+ 	if (!hif)
+ 		return -ENOMEM;
+@@ -101,6 +110,8 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 	int irq, hif2_irq, ret;
+ 	struct mt76_dev *mdev;
+ 
++	hif2_enable |= (id->device == 0x7990 || id->device == 0x7991);
++
+ 	ret = pcim_enable_device(pdev);
+ 	if (ret)
+ 		return ret;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1027-wifi-mt76-mt7996-add-kite-fwdl-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1027-wifi-mt76-mt7996-add-kite-fwdl-support.patch
deleted file mode 100644
index a555c23..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1027-wifi-mt76-mt7996-add-kite-fwdl-support.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From 4f5af38dbe7866b635428ebe80df29ab96bd660e Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 26 May 2023 14:41:27 +0800
-Subject: [PATCH 60/98] wifi: mt76: mt7996: add kite fwdl support
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt76_connac_mcu.c |  3 ++-
- mt7996/mcu.c      | 26 +++++++++++++++++++++-----
- mt7996/mt7996.h   |  6 ++++++
- mt7996/pci.c      |  4 ++++
- 4 files changed, 33 insertions(+), 6 deletions(-)
-
-diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 214a526..43e8ce0 100644
---- a/mt76_connac_mcu.c
-+++ b/mt76_connac_mcu.c
-@@ -68,7 +68,8 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
- 	if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
- 	    (is_mt7921(dev) && addr == 0x900000) ||
- 	    (is_mt7925(dev) && addr == 0x900000) ||
--	    (is_mt7996(dev) && addr == 0x900000))
-+	    (is_mt7996(dev) && addr == 0x900000) ||
-+	    (is_mt7992(dev) && addr == 0x900000))
- 		cmd = MCU_CMD(PATCH_START_REQ);
- 	else
- 		cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ);
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 3a960d1..255d0ba 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -11,6 +11,22 @@
- #include "mac.h"
- #include "eeprom.h"
- 
-+#define fw_name(_dev, name, ...)	({			\
-+	char *_fw;						\
-+	switch (mt76_chip(&(_dev)->mt76)) {			\
-+	case 0x7996:						\
-+		_fw = MT7996_##name;				\
-+		break;						\
-+	case 0x7992:						\
-+		_fw = MT7992_##name;				\
-+		break;						\
-+	default:						\
-+		_fw = MT7996_##name;				\
-+		break;						\
-+	}							\
-+	_fw;							\
-+})
-+
- struct mt7996_patch_hdr {
- 	char build_date[16];
- 	char platform[4];
-@@ -2598,7 +2614,7 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
- 		return -EAGAIN;
- 	}
- 
--	ret = request_firmware(&fw, MT7996_ROM_PATCH, dev->mt76.dev);
-+	ret = request_firmware(&fw, fw_name(dev, ROM_PATCH), dev->mt76.dev);
- 	if (ret)
- 		goto out;
- 
-@@ -2767,20 +2783,20 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
- 	int ret;
- 
- 	if (dev->testmode_enable)
--		ret = __mt7996_load_ram(dev, "WM_TM", MT7996_FIRMWARE_WM_TM,
-+		ret = __mt7996_load_ram(dev, "WM_TM", fw_name(dev, FIRMWARE_WM_TM),
- 					MT7996_RAM_TYPE_WM_TM);
- 	else
--		ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
-+		ret = __mt7996_load_ram(dev, "WM", fw_name(dev, FIRMWARE_WM),
- 					MT7996_RAM_TYPE_WM);
- 	if (ret)
- 		return ret;
- 
--	ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP,
-+	ret = __mt7996_load_ram(dev, "DSP", fw_name(dev, FIRMWARE_DSP),
- 				MT7996_RAM_TYPE_DSP);
- 	if (ret)
- 		return ret;
- 
--	return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA,
-+	return __mt7996_load_ram(dev, "WA", fw_name(dev, FIRMWARE_WA),
- 				 MT7996_RAM_TYPE_WA);
- }
- 
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 766de3f..eb192eb 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -35,6 +35,12 @@
- #define MT7996_FIRMWARE_WM_TM		"mediatek/mt7996/mt7996_wm_tm.bin"
- #define MT7996_ROM_PATCH		"mediatek/mt7996/mt7996_rom_patch.bin"
- 
-+#define MT7992_FIRMWARE_WA		"mediatek/mt7996/mt7992_wa.bin"
-+#define MT7992_FIRMWARE_WM		"mediatek/mt7996/mt7992_wm.bin"
-+#define MT7992_FIRMWARE_DSP		"mediatek/mt7996/mt7992_dsp.bin"
-+#define MT7992_FIRMWARE_WM_TM		"mediatek/mt7996/mt7992_wm_tm.bin"
-+#define MT7992_ROM_PATCH		"mediatek/mt7996/mt7992_rom_patch.bin"
-+
- #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
- #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
- #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index e8edf77..2bb707d 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -263,3 +263,7 @@ MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
- MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
- MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
- MODULE_FIRMWARE(MT7996_ROM_PATCH);
-+MODULE_FIRMWARE(MT7992_FIRMWARE_WA);
-+MODULE_FIRMWARE(MT7992_FIRMWARE_WM);
-+MODULE_FIRMWARE(MT7992_FIRMWARE_DSP);
-+MODULE_FIRMWARE(MT7992_ROM_PATCH);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1028-mtk-wifi-mt76-mt7996-add-debugfs-knob-for-rx_counter.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1028-mtk-wifi-mt76-mt7996-add-debugfs-knob-for-rx_counter.patch
new file mode 100644
index 0000000..5822e8c
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1028-mtk-wifi-mt76-mt7996-add-debugfs-knob-for-rx_counter.patch
@@ -0,0 +1,291 @@
+From 64832783fc40e4a4075c2ac3b9c78a81266ef988 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Fri, 28 Apr 2023 10:39:58 +0800
+Subject: [PATCH 1028/1041] mtk: wifi: mt76: mt7996: add debugfs knob for
+ rx_counters
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ agg-rx.c             |  8 ++++++++
+ mac80211.c           | 16 ++++++++++++++--
+ mt76.h               | 15 +++++++++++++++
+ mt7996/mac.c         | 18 +++++++++++++++---
+ mt7996/mtk_debugfs.c | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 94 insertions(+), 5 deletions(-)
+
+diff --git a/agg-rx.c b/agg-rx.c
+index 10cbd9e5..adb5a7d7 100644
+--- a/agg-rx.c
++++ b/agg-rx.c
+@@ -33,10 +33,13 @@ mt76_rx_aggr_release_frames(struct mt76_rx_tid *tid,
+ 			    struct sk_buff_head *frames,
+ 			    u16 head)
+ {
++	struct mt76_phy *phy = mt76_dev_phy(tid->dev, tid->band_idx);
+ 	int idx;
+ 
+ 	while (ieee80211_sn_less(tid->head, head)) {
+ 		idx = tid->head % tid->size;
++		if (!tid->reorder_buf[idx])
++			phy->rx_stats.rx_agg_miss++;
+ 		mt76_aggr_release(tid, frames, idx);
+ 	}
+ }
+@@ -151,6 +154,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
+ 	struct mt76_wcid *wcid = status->wcid;
+ 	struct ieee80211_sta *sta;
+ 	struct mt76_rx_tid *tid;
++	struct mt76_phy *phy;
+ 	bool sn_less;
+ 	u16 seqno, head, size, idx;
+ 	u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
+@@ -186,6 +190,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
+ 	head = tid->head;
+ 	seqno = status->seqno;
+ 	size = tid->size;
++	phy = mt76_dev_phy(tid->dev, tid->band_idx);
+ 	sn_less = ieee80211_sn_less(seqno, head);
+ 
+ 	if (!tid->started) {
+@@ -197,6 +202,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
+ 
+ 	if (sn_less) {
+ 		__skb_unlink(skb, frames);
++		phy->rx_stats.rx_dup_drop++;
+ 		dev_kfree_skb(skb);
+ 		goto out;
+ 	}
+@@ -223,6 +229,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
+ 
+ 	/* Discard if the current slot is already in use */
+ 	if (tid->reorder_buf[idx]) {
++		phy->rx_stats.rx_dup_drop++;
+ 		dev_kfree_skb(skb);
+ 		goto out;
+ 	}
+@@ -254,6 +261,7 @@ int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tidno,
+ 	tid->head = ssn;
+ 	tid->size = size;
+ 	tid->num = tidno;
++	tid->band_idx = wcid->phy_idx;
+ 	INIT_DELAYED_WORK(&tid->reorder_work, mt76_rx_aggr_reorder_work);
+ 	spin_lock_init(&tid->lock);
+ 
+diff --git a/mac80211.c b/mac80211.c
+index 87dcc8a3..45791f6e 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -784,6 +784,7 @@ static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
+ 		}
+ 
+ 		if (ether_addr_equal(skb->data + offset, rfc1042_header)) {
++			phy->rx_stats.rx_drop++;
+ 			dev_kfree_skb(skb);
+ 			return;
+ 		}
+@@ -1100,10 +1101,16 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
+ 
+ 	*sta = wcid_to_sta(mstat.wcid);
+ 	*hw = mt76_phy_hw(dev, mstat.phy_idx);
++
++	if ((mstat.flag & RX_FLAG_8023) || ieee80211_is_data_qos(hdr->frame_control)) {
++		struct mt76_phy *phy = mt76_dev_phy(dev, mstat.phy_idx);
++
++		phy->rx_stats.rx_mac80211++;
++	}
+ }
+ 
+ static void
+-mt76_check_ccmp_pn(struct sk_buff *skb)
++mt76_check_ccmp_pn(struct mt76_dev *dev, struct sk_buff *skb)
+ {
+ 	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+ 	struct mt76_wcid *wcid = status->wcid;
+@@ -1150,7 +1157,11 @@ skip_hdr_check:
+ 	ret = memcmp(status->iv, wcid->rx_key_pn[security_idx],
+ 		     sizeof(status->iv));
+ 	if (ret <= 0) {
++		struct mt76_phy *phy = mt76_dev_phy(dev, status->phy_idx);
++
++		phy->rx_stats.rx_pn_iv_error++;
+ 		status->flag |= RX_FLAG_ONLY_MONITOR;
++
+ 		return;
+ 	}
+ 
+@@ -1331,7 +1342,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
+ 	while ((skb = __skb_dequeue(frames)) != NULL) {
+ 		struct sk_buff *nskb = skb_shinfo(skb)->frag_list;
+ 
+-		mt76_check_ccmp_pn(skb);
++		mt76_check_ccmp_pn(dev, skb);
+ 		skb_shinfo(skb)->frag_list = NULL;
+ 		mt76_rx_convert(dev, skb, &hw, &sta);
+ 		ieee80211_rx_list(hw, sta, skb, &list);
+@@ -1354,6 +1365,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
+ 	}
+ 
+ 	list_for_each_entry_safe(skb, tmp, &list, list) {
++		dev->rx_kernel++;
+ 		skb_list_del_init(skb);
+ 		napi_gro_receive(napi, skb);
+ 	}
+diff --git a/mt76.h b/mt76.h
+index 46fbc87e..9e8848f7 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -422,6 +422,7 @@ struct mt76_rx_tid {
+ 	struct rcu_head rcu_head;
+ 
+ 	struct mt76_dev *dev;
++	u8 band_idx;
+ 
+ 	spinlock_t lock;
+ 	struct delayed_work reorder_work;
+@@ -853,6 +854,19 @@ struct mt76_phy {
+ 		bool al;
+ 		u8 pin;
+ 	} leds;
++
++	struct {
++		u32 rx_mac80211;
++
++		u32 rx_drop;
++		u32 rx_rxd_drop;
++		u32 rx_dup_drop;
++		u32 rx_agg_miss;
++		u32 rx_icv_error;
++		u32 rx_fcs_error;
++		u32 rx_tkip_mic_error;
++		u32 rx_pn_iv_error;
++	} rx_stats;
+ };
+ 
+ struct mt76_dev {
+@@ -958,6 +972,7 @@ struct mt76_dev {
+ 	};
+ 
+ 	const char *bin_file_name;
++	u32 rx_kernel;
+ };
+ 
+ /* per-phy stats.  */
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 22d7dc6d..73c66e57 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -469,8 +469,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
+ 		return -EINVAL;
+ 
+ 	/* ICV error or CCMP/BIP/WPI MIC error */
+-	if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
++	if (rxd1 & MT_RXD1_NORMAL_ICV_ERR) {
++		mphy->rx_stats.rx_icv_error++;
+ 		status->flag |= RX_FLAG_ONLY_MONITOR;
++	}
+ 
+ 	unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
+ 	idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
+@@ -501,11 +503,15 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
+ 	    !(csum_status & (BIT(0) | BIT(2) | BIT(3))))
+ 		skb->ip_summed = CHECKSUM_UNNECESSARY;
+ 
+-	if (rxd1 & MT_RXD3_NORMAL_FCS_ERR)
++	if (rxd1 & MT_RXD3_NORMAL_FCS_ERR) {
++		mphy->rx_stats.rx_fcs_error++;
+ 		status->flag |= RX_FLAG_FAILED_FCS_CRC;
++	}
+ 
+-	if (rxd1 & MT_RXD1_NORMAL_TKIP_MIC_ERR)
++	if (rxd1 & MT_RXD1_NORMAL_TKIP_MIC_ERR) {
++		mphy->rx_stats.rx_tkip_mic_error++;
+ 		status->flag |= RX_FLAG_MMIC_ERROR;
++	}
+ 
+ 	if (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2) != 0 &&
+ 	    !(rxd1 & (MT_RXD1_NORMAL_CLM | MT_RXD1_NORMAL_CM))) {
+@@ -1414,8 +1420,10 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ 			 struct sk_buff *skb, u32 *info)
+ {
+ 	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
++	struct mt76_phy *phy;
+ 	__le32 *rxd = (__le32 *)skb->data;
+ 	__le32 *end = (__le32 *)&skb->data[skb->len];
++	u8 band_idx;
+ 	enum rx_pkt_type type;
+ 
+ 	type = le32_get_bits(rxd[0], MT_RXD0_PKT_TYPE);
+@@ -1457,6 +1465,10 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ 		}
+ 		fallthrough;
+ 	default:
++		band_idx = le32_get_bits(rxd[1], MT_RXD1_NORMAL_BAND_IDX);
++		phy = mt76_dev_phy(mdev, band_idx);
++		if (likely(phy))
++			phy->rx_stats.rx_rxd_drop++;
+ 		dev_kfree_skb(skb);
+ 		break;
+ 	}
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 6229739b..e1689605 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2758,6 +2758,46 @@ mt7996_sr_scene_cond_show(struct seq_file *file, void *data)
+ }
+ DEFINE_SHOW_ATTRIBUTE(mt7996_sr_scene_cond);
+ 
++static int mt7996_rx_counters(struct seq_file *s, void *data)
++{
++	struct mt7996_dev *dev = dev_get_drvdata(s->private);
++	u32 rx_mac80211 = 0;
++	int i = 0;
++
++	for (i = 0; i < __MT_MAX_BAND; i++) {
++		struct mt76_phy *phy = mt76_dev_phy(&dev->mt76, i);
++
++		if (!phy)
++			continue;
++
++		seq_printf(s, "\n==========PHY%d==========\n", i);
++
++#define SEQ_PRINT(_str, _rx_param) do {					\
++		seq_printf(s, _str"\n", phy->rx_stats._rx_param);	\
++	} while (0)
++
++		SEQ_PRINT("Rx to mac80211: %u", rx_mac80211);
++		SEQ_PRINT("Rx drop: %u", rx_drop);
++		SEQ_PRINT("Rx drop due to RXD type error: %u", rx_rxd_drop);
++		SEQ_PRINT("Rx duplicated drop: %u", rx_dup_drop);
++		SEQ_PRINT("Rx agg miss: %u", rx_agg_miss);
++		SEQ_PRINT("Rx ICV error: %u", rx_icv_error);
++		SEQ_PRINT("Rx FCS error: %u", rx_fcs_error);
++		SEQ_PRINT("Rx TKIP MIC error: %u", rx_tkip_mic_error);
++		SEQ_PRINT("Rx PN/IV error: %u", rx_pn_iv_error);
++#undef SEQ_PRINT
++
++		rx_mac80211 += phy->rx_stats.rx_mac80211;
++	}
++
++	seq_printf(s, "\n==========SUM==========\n");
++	seq_printf(s, "Rx to kernel: %u\n", dev->mt76.rx_kernel);
++	seq_printf(s, "Rx to mac80211: %u\n", rx_mac80211);
++
++
++	return 0;
++}
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -2821,6 +2861,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ 
+ 	debugfs_create_devm_seqfile(dev->mt76.dev, "tr_info", dir,
+ 				    mt7996_trinfo_read);
++	debugfs_create_devm_seqfile(dev->mt76.dev, "rx_counters", dir,
++				    mt7996_rx_counters);
+ 	debugfs_create_file("txpower_level", 0600, dir, phy, &fops_txpower_level);
+ 	debugfs_create_file("txpower_info", 0600, dir, phy, &mt7996_txpower_info_fops);
+ 	debugfs_create_file("txpower_sku", 0600, dir, phy, &mt7996_txpower_sku_fops);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1028-wifi-mt76-mt7996-add-kite-eeprom-load-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1028-wifi-mt76-mt7996-add-kite-eeprom-load-support.patch
deleted file mode 100644
index 3556945..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1028-wifi-mt76-mt7996-add-kite-eeprom-load-support.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From dcace898314b1d369b61a0c4f7f9e325f04784dc Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 26 May 2023 14:44:04 +0800
-Subject: [PATCH 61/98] wifi: mt76: mt7996: add kite eeprom load support
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/eeprom.c | 33 ++++++++++++++++++++++-----------
- mt7996/mcu.c    |  2 +-
- mt7996/mt7996.h | 10 ++++++++++
- 3 files changed, 33 insertions(+), 12 deletions(-)
-
-diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 56605de..6605853 100644
---- a/mt7996/eeprom.c
-+++ b/mt7996/eeprom.c
-@@ -53,9 +53,12 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
- 	u8 *eeprom = dev->mt76.eeprom.data;
- 	u16 val = get_unaligned_le16(eeprom);
- 
-+#define CHECK_EEPROM_ERR(match)	(match ? 0 : -EINVAL)
- 	switch (val) {
- 	case 0x7990:
--		return 0;
-+		return CHECK_EEPROM_ERR(is_mt7996(&dev->mt76));
-+	case 0x7992:
-+		return CHECK_EEPROM_ERR(is_mt7992(&dev->mt76));
- 	default:
- 		return -EINVAL;
- 	}
-@@ -66,13 +69,20 @@ const char *mt7996_eeprom_name(struct mt7996_dev *dev)
- 	if (dev->bin_file_mode)
- 		return dev->mt76.bin_file_name;
- 
--	/* reserve for future variants */
--	if (dev->testmode_enable)
--		return MT7996_EEPROM_DEFAULT_TM;
--	else if (dev->chip_sku == MT7996_SKU_404)
--		return MT7996_EEPROM_DEFAULT_404;
--	else
-+	switch (mt76_chip(&dev->mt76)) {
-+	case 0x7990:
-+		if (dev->testmode_enable)
-+			return MT7996_EEPROM_DEFAULT_TM;
-+		else if (dev->chip_sku == MT7996_SKU_404)
-+			return MT7996_EEPROM_DEFAULT_404;
-+		else
-+			return MT7996_EEPROM_DEFAULT;
-+	case 0x7992:
-+		return dev->testmode_enable ?
-+		       MT7992_EEPROM_DEFAULT_TM : MT7992_EEPROM_DEFAULT;
-+	default:
- 		return MT7996_EEPROM_DEFAULT;
-+	}
- }
- 
- int
-@@ -125,7 +135,7 @@ mt7996_eeprom_load_default(struct mt7996_dev *dev)
- 		goto out;
- 	}
- 
--	memcpy(eeprom, fw->data, MT7996_EEPROM_SIZE);
-+	memcpy(eeprom, fw->data, mt7996_eeprom_size(dev));
- 	dev->flash_mode = true;
- 
- out:
-@@ -141,7 +151,7 @@ static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
- 	/* return > 0 for load success, return 0 for load failed, return < 0 for non memory */
- 	dev->bin_file_mode = mt76_check_bin_file_mode(&dev->mt76);
- 	if (dev->bin_file_mode) {
--		dev->mt76.eeprom.size = MT7996_EEPROM_SIZE;
-+		dev->mt76.eeprom.size = mt7996_eeprom_size(dev);
- 		dev->mt76.eeprom.data = devm_kzalloc(dev->mt76.dev, dev->mt76.eeprom.size,
- 						     GFP_KERNEL);
- 		if (!dev->mt76.eeprom.data)
-@@ -153,7 +163,7 @@ static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
- 		if (mt7996_check_eeprom(dev))
- 			return 0;
- 	} else {
--		ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
-+		ret = mt76_eeprom_init(&dev->mt76, mt7996_eeprom_size(dev));
- 	}
- 
- 	return ret;
-@@ -186,6 +196,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
- {
- 	int ret;
- 	u8 free_block_num;
-+	u16 eeprom_size = mt7996_eeprom_size(dev);
- 	u32 block_num, i;
- 	u32 eeprom_blk_size = MT7996_EEPROM_BLOCK_SIZE;
- 
-@@ -200,7 +211,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
- 			return -EINVAL;
- 
- 		/* read eeprom data from efuse */
--		block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size);
-+		block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size);
- 		for (i = 0; i < block_num; i++) {
- 			ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size);
- 			if (ret < 0)
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 255d0ba..e9088ba 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -3425,7 +3425,7 @@ static int mt7996_mcu_set_eeprom_flash(struct mt7996_dev *dev)
- 		.tag = cpu_to_le16(UNI_EFUSE_BUFFER_MODE),
- 		.buffer_mode = EE_MODE_BUFFER
- 	};
--	u16 eeprom_size = MT7996_EEPROM_SIZE;
-+	u16 eeprom_size = mt7996_eeprom_size(dev);
- 	u8 total = DIV_ROUND_UP(eeprom_size, PER_PAGE_SIZE);
- 	u8 *eep = (u8 *)dev->mt76.eeprom.data;
- 	int eep_len, i;
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index eb192eb..433d886 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -44,7 +44,12 @@
- #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
- #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
- #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
-+#define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom.bin"
-+#define MT7992_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7992_eeprom_tm.bin"
-+
- #define MT7996_EEPROM_SIZE		7680
-+#define MT7992_EEPROM_SIZE		7680
-+
- #define MT7996_EEPROM_BLOCK_SIZE	16
- #define MT7996_TOKEN_SIZE		16384
- #define MT7996_HW_TOKEN_SIZE		8192
-@@ -643,6 +648,11 @@ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
- void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
- #endif
- 
-+static inline u16 mt7996_eeprom_size(struct mt7996_dev *dev)
-+{
-+	return is_mt7996(&dev->mt76) ? MT7996_EEPROM_SIZE : MT7992_EEPROM_SIZE;
-+}
-+
- static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
- {
- 	return min(MT7996_MAX_INTERFACES * (1 + dev->dbdc_support + dev->tbtc_support),
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1029-mtk-wifi-mt76-mt7996-add-three-wire-pta-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1029-mtk-wifi-mt76-mt7996-add-three-wire-pta-support.patch
new file mode 100644
index 0000000..9902ccb
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1029-mtk-wifi-mt76-mt7996-add-three-wire-pta-support.patch
@@ -0,0 +1,133 @@
+From 1f4de166ff558ddc2803ce0661ac212dd8e7ffe2 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 24 Oct 2023 15:59:18 +0800
+Subject: [PATCH 1029/1041] mtk: wifi: mt76: mt7996: add three wire pta support
+
+three wire enable bit 0 & 1 for EXT0 & EXT1, respectively
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt76_connac_mcu.h |  1 +
+ mt7996/vendor.c   | 49 +++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h   | 12 ++++++++++++
+ 3 files changed, 62 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index b657ef39..615c42b1 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1274,6 +1274,7 @@ enum {
+ 	MCU_UNI_CMD_PER_STA_INFO = 0x6d,
+ 	MCU_UNI_CMD_ALL_STA_INFO = 0x6e,
+ 	MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
++	MCU_UNI_CMD_PTA_3WIRE_CTRL = 0x78,
+ };
+ 
+ enum {
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index dae3260a..9ba6f00a 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -60,6 +60,11 @@ edcca_dump_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP] = {
+ 	[MTK_VENDOR_ATTR_EDCCA_DUMP_SEC160_VAL] = { .type = NLA_U8 },
+ };
+ 
++static const struct nla_policy
++three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
++	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
++};
++
+ static const struct nla_policy
+ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
+ 	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
+@@ -561,6 +566,39 @@ mt7996_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+ 	return EDCCA_MAX_BW_NUM;
+ }
+ 
++static int mt7996_vendor_3wire_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev,
++				    const void *data, int data_len)
++{
++#define UNI_3WIRE_EXT_EN	0
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	struct mt7996_dev *dev = mt7996_hw_dev(hw);
++	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL];
++	struct {
++		u8 __rsv1[4];
++
++		__le16 tag;
++		__le16 len;
++		u8 three_wire_mode;
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_3WIRE_EXT_EN),
++		.len = cpu_to_le16(sizeof(req) - 4),
++	};
++	int err;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_3WIRE_CTRL_MAX, data, data_len,
++			three_wire_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	if (!tb[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE])
++		return -EINVAL;
++
++	req.three_wire_mode = nla_get_u8(tb[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE]);
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(PTA_3WIRE_CTRL), &req,
++				 sizeof(req), false);
++}
++
+ static int mt7996_vendor_ibf_ctrl(struct wiphy *wiphy,
+ 				  struct wireless_dev *wdev,
+ 				  const void *data,
+@@ -657,6 +695,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 		.policy = edcca_ctrl_policy,
+ 		.maxattr = MTK_VENDOR_ATTR_EDCCA_CTRL_MAX,
+ 	},
++	{
++		.info = {
++			.vendor_id = MTK_NL80211_VENDOR_ID,
++			.subcmd = MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++			 WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_3wire_ctrl,
++		.policy = three_wire_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_3WIRE_CTRL_MAX,
++	},
+ 	{
+ 		.info = {
+ 			.vendor_id = MTK_NL80211_VENDOR_ID,
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 49f46f25..29ccc050 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -7,6 +7,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
+ 	MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
+ 	MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
++	MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8,
+ 	MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ };
+@@ -43,6 +44,17 @@ enum mtk_vendor_attr_edcca_dump {
+ 		NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP - 1
+ };
+ 
++enum mtk_vendor_attr_3wire_ctrl {
++	MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_3WIRE_CTRL_MODE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL,
++	MTK_VENDOR_ATTR_3WIRE_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1
++};
++
+ enum mtk_vendor_attr_mu_ctrl {
+ 	MTK_VENDOR_ATTR_MU_CTRL_UNSPEC,
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1029-wifi-mt76-mt7996-add-kite-fw-default-bin-for-differe.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1029-wifi-mt76-mt7996-add-kite-fw-default-bin-for-differe.patch
deleted file mode 100644
index 8b8119a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1029-wifi-mt76-mt7996-add-kite-fw-default-bin-for-differe.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From af793eb0cf8e035760bdb595ae96e7d7534df60f Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 21 Jul 2023 10:41:28 +0800
-Subject: [PATCH 62/98] wifi: mt76: mt7996: add kite fw & default bin for
- different sku variants
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/eeprom.c | 10 ++++++++--
- mt7996/mcu.c    |  7 ++++++-
- mt7996/mt7996.h | 25 ++++++++++++++++++++++++-
- mt7996/regs.h   |  2 ++
- 4 files changed, 40 insertions(+), 4 deletions(-)
-
-diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 6605853..6eebbb3 100644
---- a/mt7996/eeprom.c
-+++ b/mt7996/eeprom.c
-@@ -78,8 +78,14 @@ const char *mt7996_eeprom_name(struct mt7996_dev *dev)
- 		else
- 			return MT7996_EEPROM_DEFAULT;
- 	case 0x7992:
--		return dev->testmode_enable ?
--		       MT7992_EEPROM_DEFAULT_TM : MT7992_EEPROM_DEFAULT;
-+		if (dev->testmode_enable)
-+			return MT7992_EEPROM_DEFAULT_TM;
-+		else if (dev->chip_sku == MT7992_SKU_23)
-+			return MT7992_EEPROM_DEFAULT_23;
-+		else if (dev->chip_sku == MT7992_SKU_24)
-+			return MT7992_EEPROM_DEFAULT_24;
-+		else
-+			return MT7992_EEPROM_DEFAULT;
- 	default:
- 		return MT7996_EEPROM_DEFAULT;
- 	}
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index e9088ba..b8d26ec 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -18,7 +18,12 @@
- 		_fw = MT7996_##name;				\
- 		break;						\
- 	case 0x7992:						\
--		_fw = MT7992_##name;				\
-+		if ((_dev)->chip_sku == MT7992_SKU_23)		\
-+			_fw = MT7992_##name##_23;		\
-+		else if ((_dev)->chip_sku == MT7992_SKU_24)	\
-+			_fw = MT7992_##name##_24;		\
-+		else						\
-+			_fw = MT7992_##name;			\
- 		break;						\
- 	default:						\
- 		_fw = MT7996_##name;				\
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 433d886..6775360 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -41,11 +41,25 @@
- #define MT7992_FIRMWARE_WM_TM		"mediatek/mt7996/mt7992_wm_tm.bin"
- #define MT7992_ROM_PATCH		"mediatek/mt7996/mt7992_rom_patch.bin"
- 
-+#define MT7992_FIRMWARE_WA_24		"mediatek/mt7996/mt7992_wa_24.bin"
-+#define MT7992_FIRMWARE_WM_24		"mediatek/mt7996/mt7992_wm_24.bin"
-+#define MT7992_FIRMWARE_DSP_24		"mediatek/mt7996/mt7992_dsp_24.bin"
-+#define MT7992_FIRMWARE_WM_TM_24	"mediatek/mt7996/mt7992_wm_tm_24.bin"
-+#define MT7992_ROM_PATCH_24		"mediatek/mt7996/mt7992_rom_patch_24.bin"
-+
-+#define MT7992_FIRMWARE_WA_23		"mediatek/mt7996/mt7992_wa_23.bin"
-+#define MT7992_FIRMWARE_WM_23		"mediatek/mt7996/mt7992_wm_23.bin"
-+#define MT7992_FIRMWARE_DSP_23		"mediatek/mt7996/mt7992_dsp_23.bin"
-+#define MT7992_FIRMWARE_WM_TM_23	"mediatek/mt7996/mt7992_wm_tm_23.bin"
-+#define MT7992_ROM_PATCH_23		"mediatek/mt7996/mt7992_rom_patch_23.bin"
-+
- #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
- #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
- #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
- #define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom.bin"
- #define MT7992_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7992_eeprom_tm.bin"
-+#define MT7992_EEPROM_DEFAULT_24	"mediatek/mt7996/mt7992_eeprom_24.bin"
-+#define MT7992_EEPROM_DEFAULT_23	"mediatek/mt7996/mt7992_eeprom_23.bin"
- 
- #define MT7996_EEPROM_SIZE		7680
- #define MT7992_EEPROM_SIZE		7680
-@@ -103,6 +117,12 @@ enum mt7996_sku_type {
- 	MT7996_SKU_444,
- };
- 
-+enum mt7992_sku_type {
-+	MT7992_SKU_23,
-+	MT7992_SKU_24,
-+	MT7992_SKU_44,
-+};
-+
- enum mt7996_ram_type {
- 	MT7996_RAM_TYPE_WM,
- 	MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
-@@ -510,11 +530,14 @@ mt7996_get_chip_sku(struct mt7996_dev *dev)
- {
- 	u32 val = mt76_rr(dev, MT_PAD_GPIO);
- 
--	/* reserve for future variants */
- 	switch (mt76_chip(&dev->mt76)) {
- 	case 0x7990:
- 		dev->chip_sku = FIELD_GET(MT_PAD_GPIO_ADIE_COMB, val) <= 1;
- 		break;
-+	case 0x7992:
-+		dev->chip_sku = !!FIELD_GET(MT_PAD_GPIO_ADIE_COMB_7992, val) +
-+				!FIELD_GET(MT_PAD_GPIO_ADIE_NUM_7992, val);
-+		break;
- 	default:
- 		return -EINVAL;
- 	}
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 565022a..d305c25 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -651,6 +651,8 @@ enum offs_rev {
- 
- #define MT_PAD_GPIO				0x700056f0
- #define MT_PAD_GPIO_ADIE_COMB			GENMASK(16, 15)
-+#define MT_PAD_GPIO_ADIE_COMB_7992		GENMASK(17, 16)
-+#define MT_PAD_GPIO_ADIE_NUM_7992		BIT(15)
- 
- #define MT_HW_REV				0x70010204
- #define MT_WF_SUBSYS_RST			0x70028600
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1030-mtk-wifi-mt76-mt7996-support-BF-MIMO-debug-commands.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1030-mtk-wifi-mt76-mt7996-support-BF-MIMO-debug-commands.patch
new file mode 100644
index 0000000..3048405
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1030-mtk-wifi-mt76-mt7996-support-BF-MIMO-debug-commands.patch
@@ -0,0 +1,1204 @@
+From 05cf83b4947264a8afca95116afd98cb4519a9d5 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Tue, 3 Jan 2023 09:42:07 +0800
+Subject: [PATCH 1030/1041] mtk: wifi: mt76: mt7996: support BF/MIMO debug
+ commands
+
+This commit includes the following commands:
+1. starec_bf_read
+2. txbf_snd_info: start/stop sounding and set sounding period
+3. fbkRptInfo
+4. fix muru rate
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+fix the wrong wlan_idx for user3
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt7996/mcu.c         |   5 +
+ mt7996/mcu.h         |   4 +
+ mt7996/mt7996.h      |   5 +
+ mt7996/mtk_debugfs.c | 120 +++++++++
+ mt7996/mtk_mcu.c     | 626 +++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.h     | 342 +++++++++++++++++++++++
+ 6 files changed, 1102 insertions(+)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 726d2adf..d3dab186 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -741,6 +741,11 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 	case MCU_UNI_EVENT_TESTMODE_CTRL:
+ 		mt7996_tm_rf_test_event(dev, skb);
+ 		break;
++#endif
++#if defined CONFIG_NL80211_TESTMODE || defined CONFIG_MTK_DEBUG
++	case MCU_UNI_EVENT_BF:
++		mt7996_mcu_rx_bf_event(dev, skb);
++		break;
+ #endif
+ 	default:
+ 		break;
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 34fdfb26..347893c8 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -770,8 +770,12 @@ enum {
+ 
+ enum {
+ 	BF_SOUNDING_ON = 1,
++	BF_PFMU_TAG_READ = 5,
++	BF_STA_REC_READ = 11,
+ 	BF_HW_EN_UPDATE = 17,
+ 	BF_MOD_EN_CTRL = 20,
++	BF_FBRPT_DBG_INFO_READ = 23,
++	BF_TXSND_INFO = 24,
+ };
+ 
+ enum {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 71602b9b..a321e8e8 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -809,6 +809,11 @@ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
+ int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set);
+ void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ int mt7996_mcu_set_dup_wtbl(struct mt7996_dev *dev);
++int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx);
++void mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb);
++int mt7996_mcu_set_muru_fixed_rate_enable(struct mt7996_dev *dev, u8 action, int val);
++int mt7996_mcu_set_muru_fixed_rate_parameter(struct mt7996_dev *dev, u8 action, void *para);
++int mt7996_mcu_set_txbf_snd_info(struct mt7996_phy *phy, void *para);
+ #endif
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index e1689605..938da645 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2798,6 +2798,117 @@ static int mt7996_rx_counters(struct seq_file *s, void *data)
+ 	return 0;
+ }
+ 
++static int
++mt7996_starec_bf_read_set(void *data, u64 wlan_idx)
++{
++	struct mt7996_phy *phy = data;
++
++	return mt7996_mcu_set_txbf_internal(phy, BF_STA_REC_READ, wlan_idx);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_starec_bf_read, NULL,
++			 mt7996_starec_bf_read_set, "%lld\n");
++
++static ssize_t
++mt7996_bf_txsnd_info_set(struct file *file,
++			 const char __user *user_buf,
++			 size_t count, loff_t *ppos)
++{
++	struct mt7996_phy *phy = file->private_data;
++	char buf[40];
++	int ret;
++
++	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';
++
++	ret = mt7996_mcu_set_txbf_snd_info(phy, buf);
++
++	if (ret) return -EFAULT;
++
++	return count;
++}
++
++static const struct file_operations fops_bf_txsnd_info = {
++	.write = mt7996_bf_txsnd_info_set,
++	.read = NULL,
++	.open = simple_open,
++	.llseek = default_llseek,
++};
++
++static int
++mt7996_bf_fbk_rpt_set(void *data, u64 wlan_idx)
++{
++	struct mt7996_phy *phy = data;
++
++	return mt7996_mcu_set_txbf_internal(phy, BF_FBRPT_DBG_INFO_READ, wlan_idx);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_bf_fbk_rpt, NULL,
++			 mt7996_bf_fbk_rpt_set, "%lld\n");
++
++static int
++mt7996_bf_pfmu_tag_read_set(void *data, u64 wlan_idx)
++{
++	struct mt7996_phy *phy = data;
++
++	return mt7996_mcu_set_txbf_internal(phy, BF_PFMU_TAG_READ, wlan_idx);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_bf_pfmu_tag_read, NULL,
++			 mt7996_bf_pfmu_tag_read_set, "%lld\n");
++
++static int
++mt7996_muru_fixed_rate_set(void *data, u64 val)
++{
++	struct mt7996_dev *dev = data;
++
++	return mt7996_mcu_set_muru_fixed_rate_enable(dev, UNI_CMD_MURU_FIXED_RATE_CTRL,
++						     val);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_fixed_rate_enable, NULL,
++			 mt7996_muru_fixed_rate_set, "%lld\n");
++
++static ssize_t
++mt7996_muru_fixed_rate_parameter_set(struct file *file,
++				     const char __user *user_buf,
++				     size_t count, loff_t *ppos)
++{
++	struct mt7996_dev *dev = file->private_data;
++	char buf[40];
++	int ret;
++
++	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';
++
++
++	ret = mt7996_mcu_set_muru_fixed_rate_parameter(dev, UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL,
++						       buf);
++
++	if (ret) return -EFAULT;
++
++	return count;
++}
++
++static const struct file_operations fops_muru_fixed_group_rate = {
++	.write = mt7996_muru_fixed_rate_parameter_set,
++	.read = NULL,
++	.open = simple_open,
++	.llseek = default_llseek,
++};
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -2883,6 +2994,15 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ 	debugfs_create_file("sr_stats", 0400, dir, phy, &mt7996_sr_stats_fops);
+ 	debugfs_create_file("sr_scene_cond", 0400, dir, phy, &mt7996_sr_scene_cond_fops);
+ 
++	debugfs_create_file("muru_fixed_rate_enable", 0600, dir, dev,
++			    &fops_muru_fixed_rate_enable);
++	debugfs_create_file("muru_fixed_group_rate", 0600, dir, dev,
++			    &fops_muru_fixed_group_rate);
++	debugfs_create_file("bf_txsnd_info", 0600, dir, phy, &fops_bf_txsnd_info);
++	debugfs_create_file("bf_starec_read", 0600, dir, phy, &fops_starec_bf_read);
++	debugfs_create_file("bf_fbk_rpt", 0600, dir, phy, &fops_bf_fbk_rpt);
++	debugfs_create_file("pfmu_tag_read", 0600, dir, phy, &fops_bf_pfmu_tag_read);
++
+ 	return 0;
+ }
+ 
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index ea4e5bf2..67419cd9 100644
+--- a/mt7996/mtk_mcu.c
++++ b/mt7996/mtk_mcu.c
+@@ -280,4 +280,630 @@ int mt7996_mcu_set_dup_wtbl(struct mt7996_dev *dev)
+ 	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(CHIP_CONFIG), &req,
+ 				 sizeof(req), true);
+ }
++
++static struct tlv *
++__mt7996_mcu_add_uni_tlv(struct sk_buff *skb, u16 tag, u16 len)
++{
++	struct tlv *ptlv, tlv = {
++		.tag = cpu_to_le16(tag),
++		.len = cpu_to_le16(len),
++	};
++
++	ptlv = skb_put(skb, len);
++	memcpy(ptlv, &tlv, sizeof(tlv));
++
++	return ptlv;
++}
++
++int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx)
++{
++	struct mt7996_dev *dev = phy->dev;
++#define MT7996_MTK_BF_MAX_SIZE	sizeof(struct bf_starec_read)
++	struct uni_header hdr;
++	struct sk_buff *skb;
++	struct tlv *tlv;
++	int len = sizeof(hdr) + MT7996_MTK_BF_MAX_SIZE;
++
++	memset(&hdr, 0, sizeof(hdr));
++
++	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);
++	if (!skb)
++		return -ENOMEM;
++
++	skb_put_data(skb, &hdr, sizeof(hdr));
++
++	switch (action) {
++	case BF_PFMU_TAG_READ: {
++		struct bf_pfmu_tag *req;
++
++		tlv = __mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req));
++		req = (struct bf_pfmu_tag *)tlv;
++#define BFER 1
++		req->pfmu_id = idx;
++		req->bfer = BFER;
++		req->band_idx = phy->mt76->band_idx;
++		break;
++	}
++	case BF_STA_REC_READ: {
++		struct bf_starec_read *req;
++
++		tlv = __mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req));
++		req = (struct bf_starec_read *)tlv;
++		req->wlan_idx = idx;
++		break;
++	}
++	case BF_FBRPT_DBG_INFO_READ: {
++		struct bf_fbk_rpt_info *req;
++
++		if (idx != 0) {
++			dev_info(dev->mt76.dev, "Invalid input");
++			return 0;
++		}
++
++		tlv = __mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req));
++		req = (struct bf_fbk_rpt_info *)tlv;
++		req->action = idx;
++		req->band_idx = phy->mt76->band_idx;
++		break;
++	}
++	default:
++		return -EINVAL;
++	}
++
++	return mt76_mcu_skb_send_msg(&phy->dev->mt76, skb, MCU_WM_UNI_CMD(BF), false);
++}
++
++int mt7996_mcu_set_txbf_snd_info(struct mt7996_phy *phy, void *para)
++{
++	char *buf = (char *)para;
++	__le16 input[5] = {0};
++	u8 recv_arg = 0;
++	struct bf_txsnd_info *req;
++	struct uni_header hdr;
++	struct sk_buff *skb;
++	struct tlv *tlv;
++	int len = sizeof(hdr) + MT7996_MTK_BF_MAX_SIZE;
++
++	memset(&hdr, 0, sizeof(hdr));
++
++	skb = mt76_mcu_msg_alloc(&phy->dev->mt76, NULL, len);
++	if (!skb)
++		return -ENOMEM;
++
++	skb_put_data(skb, &hdr, sizeof(hdr));
++
++	recv_arg = sscanf(buf, "%hx:%hx:%hx:%hx:%hx", &input[0], &input[1], &input[2],
++						      &input[3], &input[4]);
++
++	if (!recv_arg)
++		return -EINVAL;
++
++	tlv = __mt7996_mcu_add_uni_tlv(skb, BF_TXSND_INFO, sizeof(*req));
++	req = (struct bf_txsnd_info *)tlv;
++	req->action = input[0];
++
++	switch (req->action) {
++	case BF_SND_READ_INFO: {
++		req->read_clr = input[1];
++		break;
++	}
++	case BF_SND_CFG_OPT: {
++		req->vht_opt = input[1];
++		req->he_opt = input[2];
++		req->glo_opt = input[3];
++		break;
++	}
++	case BF_SND_CFG_INTV: {
++		req->wlan_idx = input[1];
++		req->snd_intv = input[2];
++		break;
++	}
++	case BF_SND_STA_STOP: {
++		req->wlan_idx = input[1];
++		req->snd_stop = input[2];
++		break;
++	}
++	case BF_SND_CFG_MAX_STA: {
++		req->max_snd_stas = input[1];
++		break;
++	}
++	case BF_SND_CFG_BFRP: {
++		req->man = input[1];
++		req->tx_time = input[2];
++		req->mcs = input[3];
++		req->ldpc = input[4];
++		break;
++	}
++	case BF_SND_CFG_INF: {
++		req->inf = input[1];
++		break;
++	}
++	case BF_SND_CFG_TXOP_SND: {
++		req->man = input[1];
++		req->ac_queue = input[2];
++		req->sxn_protect = input[3];
++		req->direct_fbk = input[4];
++		break;
++	}
++	default:
++		return -EINVAL;
++	}
++
++	return mt76_mcu_skb_send_msg(&phy->dev->mt76, skb, MCU_WM_UNI_CMD(BF), false);
++}
++
++void
++mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++#define HE_MODE 3
++	struct mt7996_mcu_bf_basic_event *event;
++
++	event = (struct mt7996_mcu_bf_basic_event *)skb->data;
++
++	dev_info(dev->mt76.dev, " bf_event tag = %d\n", event->tag);
++
++	switch (event->tag) {
++	case UNI_EVENT_BF_PFMU_TAG: {
++
++		struct mt7996_pfmu_tag_event *tag;
++		u32 *raw_t1, *raw_t2;
++
++		tag = (struct mt7996_pfmu_tag_event *) skb->data;
++
++		raw_t1 = (u32 *)&tag->t1;
++		raw_t2 = (u32 *)&tag->t2;
++
++		dev_info(dev->mt76.dev, "=================== TXBf Profile Tag1 Info ==================\n");
++		dev_info(dev->mt76.dev,
++			 "DW0 = 0x%08x, DW1 = 0x%08x, DW2 = 0x%08x\n",
++			 raw_t1[0], raw_t1[1], raw_t1[2]);
++		dev_info(dev->mt76.dev,
++			 "DW4 = 0x%08x, DW5 = 0x%08x, DW6 = 0x%08x\n\n",
++			 raw_t1[3], raw_t1[4], raw_t1[5]);
++		dev_info(dev->mt76.dev, "PFMU ID = %d              Invalid status = %d\n",
++			 tag->t1.pfmu_idx, tag->t1.invalid_prof);
++		dev_info(dev->mt76.dev, "iBf/eBf = %d\n\n", tag->t1.ebf);
++		dev_info(dev->mt76.dev, "DBW   = %d\n", tag->t1.data_bw);
++		dev_info(dev->mt76.dev, "SU/MU = %d\n", tag->t1.is_mu);
++		dev_info(dev->mt76.dev,
++			 "nrow = %d, ncol = %d, ng = %d, LM = %d, CodeBook = %d MobCalEn = %d\n",
++			 tag->t1.nr, tag->t1.nc, tag->t1.ngroup, tag->t1.lm, tag->t1.codebook,
++			 tag->t1.mob_cal_en);
++
++		if (tag->t1.lm <= HE_MODE) {
++			dev_info(dev->mt76.dev, "RU start = %d, RU end = %d\n",
++				 tag->t1.field.ru_start_id, tag->t1.field.ru_end_id);
++		} else {
++			dev_info(dev->mt76.dev, "PartialBW = %d\n",
++				 tag->t1.bw_info.partial_bw_info);
++		}
++
++		dev_info(dev->mt76.dev, "Mem Col1 = %d, Mem Row1 = %d, Mem Col2 = %d, Mem Row2 = %d\n",
++			 tag->t1.col_id1, tag->t1.row_id1, tag->t1.col_id2, tag->t1.row_id2);
++		dev_info(dev->mt76.dev, "Mem Col3 = %d, Mem Row3 = %d, Mem Col4 = %d, Mem Row4 = %d\n\n",
++			 tag->t1.col_id3, tag->t1.row_id3, tag->t1.col_id4, tag->t1.row_id4);
++		dev_info(dev->mt76.dev,
++			 "STS0_SNR = 0x%02x, STS1_SNR = 0x%02x, STS2_SNR = 0x%02x, STS3_SNR = 0x%02x\n",
++			 tag->t1.snr_sts0, tag->t1.snr_sts1, tag->t1.snr_sts2, tag->t1.snr_sts3);
++		dev_info(dev->mt76.dev,
++			 "STS4_SNR = 0x%02x, STS5_SNR = 0x%02x, STS6_SNR = 0x%02x, STS7_SNR = 0x%02x\n",
++			 tag->t1.snr_sts4, tag->t1.snr_sts5, tag->t1.snr_sts6, tag->t1.snr_sts7);
++		dev_info(dev->mt76.dev, "=============================================================\n");
++
++		dev_info(dev->mt76.dev, "=================== TXBf Profile Tag2 Info ==================\n");
++		dev_info(dev->mt76.dev,
++			 "DW0 = 0x%08x, DW1 = 0x%08x, DW2 = 0x%08x\n",
++			 raw_t2[0], raw_t2[1], raw_t2[2]);
++		dev_info(dev->mt76.dev,
++			 "DW3 = 0x%08x, DW4 = 0x%08x, DW5 = 0x%08x\n\n",
++			 raw_t2[3], raw_t2[4], raw_t2[5]);
++		dev_info(dev->mt76.dev, "Smart antenna ID = 0x%x,  SE index = %d\n",
++			 tag->t2.smart_ant, tag->t2.se_idx);
++		dev_info(dev->mt76.dev, "Timeout = 0x%x\n", tag->t2.ibf_timeout);
++		dev_info(dev->mt76.dev, "Desired BW = %d, Desired Ncol = %d, Desired Nrow = %d\n",
++			 tag->t2.ibf_data_bw, tag->t2.ibf_nc, tag->t2.ibf_nr);
++		dev_info(dev->mt76.dev, "Desired RU Allocation = %d\n", tag->t2.ibf_ru);
++		dev_info(dev->mt76.dev, "Mobility DeltaT = %d, Mobility LQ = %d\n",
++			 tag->t2.mob_delta_t, tag->t2.mob_lq_result);
++		dev_info(dev->mt76.dev, "=============================================================\n");
++		break;
++	}
++	case UNI_EVENT_BF_STAREC: {
++
++		struct mt7996_mcu_bf_starec_read *r;
++
++		r = (struct mt7996_mcu_bf_starec_read *)skb->data;
++		dev_info(dev->mt76.dev, "=================== BF StaRec ===================\n"
++					"rStaRecBf.u2PfmuId      = %d\n"
++					"rStaRecBf.fgSU_MU       = %d\n"
++					"rStaRecBf.u1TxBfCap     = %d\n"
++					"rStaRecBf.ucSoundingPhy = %d\n"
++					"rStaRecBf.ucNdpaRate    = %d\n"
++					"rStaRecBf.ucNdpRate     = %d\n"
++					"rStaRecBf.ucReptPollRate= %d\n"
++					"rStaRecBf.ucTxMode      = %d\n"
++					"rStaRecBf.ucNc          = %d\n"
++					"rStaRecBf.ucNr          = %d\n"
++					"rStaRecBf.ucCBW         = %d\n"
++					"rStaRecBf.ucMemRequire20M = %d\n"
++					"rStaRecBf.ucMemRow0     = %d\n"
++					"rStaRecBf.ucMemCol0     = %d\n"
++					"rStaRecBf.ucMemRow1     = %d\n"
++					"rStaRecBf.ucMemCol1     = %d\n"
++					"rStaRecBf.ucMemRow2     = %d\n"
++					"rStaRecBf.ucMemCol2     = %d\n"
++					"rStaRecBf.ucMemRow3     = %d\n"
++					"rStaRecBf.ucMemCol3     = %d\n",
++					r->pfmu_id,
++					r->is_su_mu,
++					r->txbf_cap,
++					r->sounding_phy,
++					r->ndpa_rate,
++					r->ndp_rate,
++					r->rpt_poll_rate,
++					r->tx_mode,
++					r->nc,
++					r->nr,
++					r->bw,
++					r->mem_require_20m,
++					r->mem_row0,
++					r->mem_col0,
++					r->mem_row1,
++					r->mem_col1,
++					r->mem_row2,
++					r->mem_col2,
++					r->mem_row3,
++					r->mem_col3);
++
++		dev_info(dev->mt76.dev, "rStaRecBf.u2SmartAnt    = 0x%x\n"
++					"rStaRecBf.ucSEIdx       = %d\n"
++					"rStaRecBf.uciBfTimeOut  = 0x%x\n"
++					"rStaRecBf.uciBfDBW      = %d\n"
++					"rStaRecBf.uciBfNcol     = %d\n"
++					"rStaRecBf.uciBfNrow     = %d\n"
++					"rStaRecBf.nr_bw160      = %d\n"
++					"rStaRecBf.nc_bw160 	  = %d\n"
++					"rStaRecBf.ru_start_idx  = %d\n"
++					"rStaRecBf.ru_end_idx 	  = %d\n"
++					"rStaRecBf.trigger_su 	  = %d\n"
++					"rStaRecBf.trigger_mu 	  = %d\n"
++					"rStaRecBf.ng16_su 	  = %d\n"
++					"rStaRecBf.ng16_mu 	  = %d\n"
++					"rStaRecBf.codebook42_su = %d\n"
++					"rStaRecBf.codebook75_mu = %d\n"
++					"rStaRecBf.he_ltf 	      = %d\n"
++					"rStaRecBf.pp_fd_val 	  = %d\n"
++					"======================================\n",
++					r->smart_ant,
++					r->se_idx,
++					r->bf_timeout,
++					r->bf_dbw,
++					r->bf_ncol,
++					r->bf_nrow,
++					r->nr_lt_bw80,
++					r->nc_lt_bw80,
++					r->ru_start_idx,
++					r->ru_end_idx,
++					r->trigger_su,
++					r->trigger_mu,
++					r->ng16_su,
++					r->ng16_mu,
++					r->codebook42_su,
++					r->codebook75_mu,
++					r->he_ltf,
++					r->pp_fd_val);
++		break;
++	}
++	case UNI_EVENT_BF_FBK_INFO: {
++		struct mt7996_mcu_txbf_fbk_info *info;
++		__le32 total, i;
++
++		info = (struct mt7996_mcu_txbf_fbk_info *)skb->data;
++
++		total = info->u4PFMUWRDoneCnt + info->u4PFMUWRFailCnt;
++		total += info->u4PFMUWRTimeoutFreeCnt + info->u4FbRptPktDropCnt;
++
++		dev_info(dev->mt76.dev, "\n");
++		dev_info(dev->mt76.dev, "\x1b[32m =================================\x1b[m\n");
++		dev_info(dev->mt76.dev, "\x1b[32m PFMUWRDoneCnt              = %u\x1b[m\n",
++			info->u4PFMUWRDoneCnt);
++		dev_info(dev->mt76.dev, "\x1b[32m PFMUWRFailCnt              = %u\x1b[m\n",
++			info->u4PFMUWRFailCnt);
++		dev_info(dev->mt76.dev, "\x1b[32m PFMUWRTimeOutCnt           = %u\x1b[m\n",
++			info->u4PFMUWRTimeOutCnt);
++		dev_info(dev->mt76.dev, "\x1b[32m PFMUWRTimeoutFreeCnt       = %u\x1b[m\n",
++			info->u4PFMUWRTimeoutFreeCnt);
++		dev_info(dev->mt76.dev, "\x1b[32m FbRptPktDropCnt            = %u\x1b[m\n",
++			info->u4FbRptPktDropCnt);
++		dev_info(dev->mt76.dev, "\x1b[32m TotalFbRptPkt              = %u\x1b[m\n", total);
++		dev_info(dev->mt76.dev, "\x1b[32m PollPFMUIntrStatTimeOut    = %u(micro-sec)\x1b[m\n",
++			info->u4PollPFMUIntrStatTimeOut);
++		dev_info(dev->mt76.dev, "\x1b[32m FbRptDeQInterval           = %u(milli-sec)\x1b[m\n",
++			info->u4DeQInterval);
++		dev_info(dev->mt76.dev, "\x1b[32m PktCntInFbRptTimeOutQ      = %u\x1b[m\n",
++			info->u4RptPktTimeOutListNum);
++		dev_info(dev->mt76.dev, "\x1b[32m PktCntInFbRptQ             = %u\x1b[m\n",
++			info->u4RptPktListNum);
++
++		// [ToDo] Check if it is valid entry
++		for (i = 0; ((i < 5) && (i < CFG_BF_STA_REC_NUM)); i++) {
++
++			// [ToDo] AID needs to be refined
++			dev_info(dev->mt76.dev,"\x1b[32m AID%u  RxFbRptCnt           = %u\x1b[m\n"
++				, i, info->au4RxPerStaFbRptCnt[i]);
++		}
++
++		break;
++	}
++	case UNI_EVENT_BF_TXSND_INFO: {
++		struct mt7996_mcu_tx_snd_info *info;
++		struct uni_event_bf_txsnd_sta_info *snd_sta_info;
++		int Idx;
++		int max_wtbl_size = mt7996_wtbl_size(dev);
++
++		info = (struct mt7996_mcu_tx_snd_info *)skb->data;
++		dev_info(dev->mt76.dev, "=================== Global Setting ===================\n");
++
++		dev_info(dev->mt76.dev, "VhtOpt = 0x%02X, HeOpt = 0x%02X, GloOpt = 0x%02X\n",
++			info->vht_opt, info->he_opt, info->glo_opt);
++
++		for (Idx = 0; Idx < BF_SND_CTRL_STA_DWORD_CNT; Idx++) {
++			dev_info(dev->mt76.dev, "SuSta[%d] = 0x%08X,", Idx,
++				 info->snd_rec_su_sta[Idx]);
++			if ((Idx & 0x03) == 0x03)
++				dev_info(dev->mt76.dev, "\n");
++		}
++
++		if ((Idx & 0x03) != 0x03)
++			dev_info(dev->mt76.dev, "\n");
++
++
++		for (Idx = 0; Idx < BF_SND_CTRL_STA_DWORD_CNT; Idx++) {
++			dev_info(dev->mt76.dev, "VhtMuSta[%d] = 0x%08X,", Idx, info->snd_rec_vht_mu_sta[Idx]);
++			if ((Idx & 0x03) == 0x03)
++				dev_info(dev->mt76.dev, "\n");
++		}
++
++		if ((Idx & 0x03) != 0x03)
++			dev_info(dev->mt76.dev, "\n");
++
++		for (Idx = 0; Idx < BF_SND_CTRL_STA_DWORD_CNT; Idx++) {
++			dev_info(dev->mt76.dev, "HeTBSta[%d] = 0x%08X,", Idx, info->snd_rec_he_tb_sta[Idx]);
++			if ((Idx & 0x03) == 0x03)
++				dev_info(dev->mt76.dev, "\n");
++		}
++
++		if ((Idx & 0x03) != 0x03)
++			dev_info(dev->mt76.dev, "\n");
++
++		for (Idx = 0; Idx < BF_SND_CTRL_STA_DWORD_CNT; Idx++) {
++			dev_info(dev->mt76.dev, "EhtTBSta[%d] = 0x%08X,", Idx, info->snd_rec_eht_tb_sta[Idx]);
++			if ((Idx & 0x03) == 0x03)
++				dev_info(dev->mt76.dev, "\n");
++		}
++
++		if ((Idx & 0x03) != 0x03)
++			dev_info(dev->mt76.dev, "\n");
++
++		for (Idx = 0; Idx < CFG_WIFI_RAM_BAND_NUM; Idx++) {
++			dev_info(dev->mt76.dev, "Band%u:\n", Idx);
++			dev_info(dev->mt76.dev, "	 Wlan Idx For VHT MC Sounding = %u\n", info->wlan_idx_for_mc_snd[Idx]);
++			dev_info(dev->mt76.dev, "	 Wlan Idx For HE TB Sounding = %u\n", info->wlan_idx_for_he_tb_snd[Idx]);
++			dev_info(dev->mt76.dev, "	 Wlan Idx For EHT TB Sounding = %u\n", info->wlan_idx_for_eht_tb_snd[Idx]);
++		}
++
++		dev_info(dev->mt76.dev, "ULLen = %d, ULMcs = %d, ULLDCP = %d\n",
++			info->ul_length, info->mcs, info->ldpc);
++
++		dev_info(dev->mt76.dev, "=================== STA Info ===================\n");
++
++		for (Idx = 1; (Idx < 5 && (Idx < CFG_BF_STA_REC_NUM)); Idx++) {
++			snd_sta_info = &info->snd_sta_info[Idx];
++			dev_info(dev->mt76.dev, "Idx%2u Interval = %d, interval counter = %d, TxCnt = %d, StopReason = 0x%02X\n",
++				Idx,
++				snd_sta_info->snd_intv,
++				snd_sta_info->snd_intv_cnt,
++				snd_sta_info->snd_tx_cnt,
++				snd_sta_info->snd_stop_reason);
++		}
++
++		dev_info(dev->mt76.dev, "=================== STA Info Connected ===================\n");
++		// [ToDo] How to iterate and get AID info of station
++		// Check UniEventBFCtrlTxSndHandle() on Logan
++
++		//hardcode max_wtbl_size as 5
++		max_wtbl_size = 5;
++		for (Idx = 1; ((Idx < max_wtbl_size) && (Idx < CFG_BF_STA_REC_NUM)); Idx++) {
++
++			// [ToDo] We do not show AID info here
++			snd_sta_info = &info->snd_sta_info[Idx];
++			dev_info(dev->mt76.dev, " Interval = %d (%u ms), interval counter = %d (%u ms), TxCnt = %d, StopReason = 0x%02X\n",
++				snd_sta_info->snd_intv,
++				snd_sta_info->snd_intv * 10,
++				snd_sta_info->snd_intv_cnt,
++				snd_sta_info->snd_intv_cnt * 10,
++				snd_sta_info->snd_tx_cnt,
++				snd_sta_info->snd_stop_reason);
++		}
++
++		dev_info(dev->mt76.dev, "======================================\n");
++
++		break;
++	}
++	default:
++		dev_info(dev->mt76.dev, "%s: unknown bf event tag %d\n",
++			 __func__, event->tag);
++	}
++
++}
++
++
++int mt7996_mcu_set_muru_fixed_rate_enable(struct mt7996_dev *dev, u8 action, int val)
++{
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++
++		__le16 value;
++		__le16 rsv;
++	} __packed data = {
++		.tag = cpu_to_le16(action),
++		.len = cpu_to_le16(sizeof(data) - 4),
++		.value = cpu_to_le16(!!val),
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &data, sizeof(data),
++				 false);
++}
++
++int mt7996_mcu_set_muru_fixed_rate_parameter(struct mt7996_dev *dev, u8 action, void *para)
++{
++	char *buf = (char *)para;
++	u8 num_user = 0, recv_arg = 0, max_mcs = 0, usr_mcs[4] = {0};
++	__le16 bw;
++	int i;
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++
++		u8 cmd_version;
++		u8 cmd_revision;
++		__le16 rsv;
++
++		struct uni_muru_mum_set_group_tbl_entry entry;
++	} __packed data = {
++		.tag = cpu_to_le16(action),
++		.len = cpu_to_le16(sizeof(data) - 4),
++	};
++
++#define __RUALLOC_TYPE_CHECK_HE(BW) ((BW == RUALLOC_BW20) || (BW == RUALLOC_BW40) || (BW == RUALLOC_BW80) || (BW == RUALLOC_BW160))
++#define __RUALLOC_TYPE_CHECK_EHT(BW) (__RUALLOC_TYPE_CHECK_HE(BW) || (BW == RUALLOC_BW320))
++	/* [Num of user] - 1~4
++	 * [RUAlloc] - BW320: 395, BW160: 137, BW80: 134, BW40: 130, BW20: 122
++	 * [LTF/GI] - For VHT, short GI: 0, Long GI: 1; 	 *
++	 * For HE/EHT, 4xLTF+3.2us: 0, 4xLTF+0.8us: 1, 2xLTF+0.8us:2
++	 * [Phy/FullBW] - VHT: 0 / HEFullBw: 1 / HEPartialBw: 2 / EHTFullBW: 3, EHTPartialBW: 4
++	 * [DL/UL] DL: 0, UL: 1, DL_UL: 2
++	 * [Wcid User0] - WCID 0
++	 * [MCS of WCID0] - For HE/VHT, 0-11: 1ss MCS0-MCS11, 12-23: 2SS MCS0-MCS11
++	 * For EHT, 0-13: 1ss MCS0-MCS13, 14-27: 2SS MCS0-MCS13
++	 * [WCID 1]
++	 * [MCS of WCID1]
++	 * [WCID 2]
++	 * [MCS of WCID2]
++	 * [WCID 3]
++	 * [MCS of WCID3]
++	 */
++
++	recv_arg = sscanf(buf, "%hhu %hu %hhu %hhu %hhu %hu %hhu %hu %hhu %hu %hhu %hu %hhu",
++			  &num_user, &bw, &data.entry.gi, &data.entry.capa, &data.entry.dl_ul,
++			  &data.entry.wlan_idx0, &usr_mcs[0],
++			  &data.entry.wlan_idx1, &usr_mcs[1],
++			  &data.entry.wlan_idx2, &usr_mcs[2],
++			  &data.entry.wlan_idx3, &usr_mcs[3]);
++
++	if (recv_arg != (5 + (2 * num_user))) {
++		dev_err(dev->mt76.dev, "The number of argument is invalid\n");
++		goto error;
++	}
++
++	if (num_user > 0 && num_user < 5)
++		data.entry.num_user = num_user - 1;
++	else {
++		dev_err(dev->mt76.dev, "The number of user count is invalid\n");
++		goto error;
++	}
++
++	/**
++	 * Older chip shall be set as HE. Refer to getHWSupportByChip() in Logan
++	 * driver to know the value for differnt chips
++	 */
++	data.cmd_version = UNI_CMD_MURU_VER_EHT;
++
++	if (data.cmd_version == UNI_CMD_MURU_VER_EHT)
++		max_mcs = UNI_MAX_MCS_SUPPORT_EHT;
++	else
++		max_mcs = UNI_MAX_MCS_SUPPORT_HE;
++
++
++	// Parameter Check
++	if (data.cmd_version != UNI_CMD_MURU_VER_EHT) {
++		if ((data.entry.capa > MAX_MODBF_HE) || (bw == RUALLOC_BW320))
++			goto error;
++	} else {
++		if ((data.entry.capa <= MAX_MODBF_HE) && (bw == RUALLOC_BW320))
++			goto error;
++	}
++
++	if (data.entry.capa <= MAX_MODBF_HE)
++		max_mcs = UNI_MAX_MCS_SUPPORT_HE;
++
++	if (__RUALLOC_TYPE_CHECK_EHT(bw)) {
++		data.entry.ru_alloc = (u8)(bw & 0xFF);
++		if (bw == RUALLOC_BW320)
++			data.entry.ru_alloc_ext = (u8)(bw >> 8);
++	} else {
++		dev_err(dev->mt76.dev, "RU_ALLOC argument is invalid\n");
++		goto error;
++	}
++
++	if ((data.entry.gi > 2) ||
++	    ((data.entry.gi > 1) && (data.entry.capa == MAX_MODBF_VHT))) {
++		dev_err(dev->mt76.dev, "GI argument is invalid\n");
++		goto error;
++	}
++
++	if (data.entry.dl_ul > 2) {
++		dev_err(dev->mt76.dev, "DL_UL argument is invalid\n");
++		goto error;
++	}
++
++#define __mcs_handler(_n)							\
++	do {									\
++		if (usr_mcs[_n] > max_mcs) {					\
++			usr_mcs[_n] -= (max_mcs + 1);				\
++			data.entry.nss##_n = 1;					\
++			if (usr_mcs[_n] > max_mcs)				\
++				usr_mcs[_n] = max_mcs;				\
++		}								\
++		if ((data.entry.dl_ul & 0x1) == 0)				\
++			data.entry.dl_mcs_user##_n = usr_mcs[_n];		\
++		if ((data.entry.dl_ul & 0x3) > 0)				\
++			data.entry.ul_mcs_user##_n = usr_mcs[_n];		\
++	}									\
++	while (0)
++
++	for (i=0; i<= data.entry.num_user; i++) {
++		switch (i) {
++			case 0:
++				__mcs_handler(0);
++				break;
++			case 1:
++				__mcs_handler(1);
++				break;
++			case 2:
++				__mcs_handler(2);
++				break;
++			case 3:
++				__mcs_handler(3);
++				break;
++			default:
++				break;
++		}
++	}
++#undef __mcs_handler
++
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &data,
++				 sizeof(data), false);
++
++error:
++	dev_err(dev->mt76.dev, "Command failed!\n");
++	return -EINVAL;
++}
++
+ #endif
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index cc2de8f4..519ffe1c 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -106,6 +106,348 @@ enum {
+ 	EDCCA_FCC = 1,
+ 	EDCCA_ETSI = 2,
+ 	EDCCA_JAPAN = 3
++
++struct bf_pfmu_tag {
++	__le16 tag;
++	__le16 len;
++
++	u8 pfmu_id;
++	bool bfer;
++	u8 band_idx;
++	u8 __rsv[5];
++	u8 buf[56];
++} __packed;
++
++struct bf_starec_read {
++	__le16 tag;
++	__le16 len;
++
++	__le16 wlan_idx;
++	u8 __rsv[2];
++} __packed;
++
++struct bf_fbk_rpt_info {
++	__le16 tag;
++	__le16 len;
++
++	__le16 wlan_idx; // Only need for dynamic_pfmu_update 0x4
++	u8 action;
++	u8 band_idx;
++	u8 __rsv[4];
++
++} __packed;
++
++struct bf_txsnd_info {
++	__le16 tag;
++	__le16 len;
++
++	u8 action;
++	u8 read_clr;
++	u8 vht_opt;
++	u8 he_opt;
++	__le16 wlan_idx;
++	u8 glo_opt;
++	u8 snd_intv;
++	u8 snd_stop;
++	u8 max_snd_stas;
++	u8 tx_time;
++	u8 mcs;
++	u8 ldpc;
++	u8 inf;
++	u8 man;
++	u8 ac_queue;
++	u8 sxn_protect;
++	u8 direct_fbk;
++	u8 __rsv[2];
++} __packed;
++
++struct mt7996_mcu_bf_basic_event {
++	struct mt7996_mcu_rxd rxd;
++
++	u8 __rsv1[4];
++
++	__le16 tag;
++	__le16 len;
++};
++
++struct mt7996_mcu_bf_starec_read {
++
++	struct mt7996_mcu_bf_basic_event event;
++
++	__le16 pfmu_id;
++	bool is_su_mu;
++	u8 txbf_cap;
++	u8 sounding_phy;
++	u8 ndpa_rate;
++	u8 ndp_rate;
++	u8 rpt_poll_rate;
++	u8 tx_mode;
++	u8 nc;
++	u8 nr;
++	u8 bw;
++	u8 total_mem_require;
++	u8 mem_require_20m;
++	u8 mem_row0;
++	u8 mem_col0:6;
++	u8 mem_row0_msb:2;
++	u8 mem_row1;
++	u8 mem_col1:6;
++	u8 mem_row1_msb:2;
++	u8 mem_row2;
++	u8 mem_col2:6;
++	u8 mem_row2_msb:2;
++	u8 mem_row3;
++	u8 mem_col3:6;
++	u8 mem_row3_msb:2;
++
++	__le16 smart_ant;
++	u8 se_idx;
++	u8 auto_sounding_ctrl;
++
++	u8 bf_timeout;
++	u8 bf_dbw;
++	u8 bf_ncol;
++	u8 bf_nrow;
++
++	u8 nr_lt_bw80;
++	u8 nc_lt_bw80;
++	u8 ru_start_idx;
++	u8 ru_end_idx;
++
++	bool trigger_su;
++	bool trigger_mu;
++
++	bool ng16_su;
++	bool ng16_mu;
++
++	bool codebook42_su;
++	bool codebook75_mu;
++
++	u8 he_ltf;
++	u8 pp_fd_val;
++};
++
++#define TXBF_PFMU_ID_NUM_MAX 48
++
++#define TXBF_PFMU_ID_NUM_MAX_TBTC_BAND0 TXBF_PFMU_ID_NUM_MAX
++#define TXBF_PFMU_ID_NUM_MAX_TBTC_BAND1 TXBF_PFMU_ID_NUM_MAX
++#define TXBF_PFMU_ID_NUM_MAX_TBTC_BAND2 TXBF_PFMU_ID_NUM_MAX
++
++/* CFG_BF_STA_REC shall be varied based on BAND Num */
++#define CFG_BF_STA_REC_NUM (TXBF_PFMU_ID_NUM_MAX_TBTC_BAND0 + TXBF_PFMU_ID_NUM_MAX_TBTC_BAND1 + TXBF_PFMU_ID_NUM_MAX_TBTC_BAND2)
++
++#define BF_SND_CTRL_STA_DWORD_CNT   ((CFG_BF_STA_REC_NUM + 0x1F) >> 5)
++
++#ifndef ALIGN_4
++	#define ALIGN_4(_value)             (((_value) + 3) & ~3u)
++#endif /* ALIGN_4 */
++
++#define CFG_WIFI_RAM_BAND_NUM 3
++
++struct uni_event_bf_txsnd_sta_info {
++	u8 snd_intv;       /* Sounding interval upper bound, unit:15ms */
++	u8 snd_intv_cnt;   /* Sounding interval counter */
++	u8 snd_tx_cnt;     /* Tx sounding count for debug */
++	u8 snd_stop_reason;  /* Bitwise reason to put in Stop Queue */
++};
++
++struct mt7996_mcu_tx_snd_info {
++
++	struct mt7996_mcu_bf_basic_event event;
++
++	u8 vht_opt;
++	u8 he_opt;
++	u8 glo_opt;
++	u8 __rsv;
++	__le32 snd_rec_su_sta[BF_SND_CTRL_STA_DWORD_CNT];
++	__le32 snd_rec_vht_mu_sta[BF_SND_CTRL_STA_DWORD_CNT];
++	__le32 snd_rec_he_tb_sta[BF_SND_CTRL_STA_DWORD_CNT];
++	__le32 snd_rec_eht_tb_sta[BF_SND_CTRL_STA_DWORD_CNT];
++	__le16 wlan_idx_for_mc_snd[ALIGN_4(CFG_WIFI_RAM_BAND_NUM)];
++	__le16 wlan_idx_for_he_tb_snd[ALIGN_4(CFG_WIFI_RAM_BAND_NUM)];
++	__le16 wlan_idx_for_eht_tb_snd[ALIGN_4(CFG_WIFI_RAM_BAND_NUM)];
++	__le16 ul_length;
++	u8 mcs;
++	u8 ldpc;
++	struct uni_event_bf_txsnd_sta_info snd_sta_info[CFG_BF_STA_REC_NUM];
++};
++
++struct mt7996_mcu_txbf_fbk_info {
++
++	struct mt7996_mcu_bf_basic_event event;
++
++	__le32 u4DeQInterval;     /* By ms */
++	__le32 u4PollPFMUIntrStatTimeOut; /* micro-sec */
++	__le32 u4RptPktTimeOutListNum;
++	__le32 u4RptPktListNum;
++	__le32 u4PFMUWRTimeOutCnt;
++	__le32 u4PFMUWRFailCnt;
++	__le32 u4PFMUWRDoneCnt;
++	__le32 u4PFMUWRTimeoutFreeCnt;
++	__le32 u4FbRptPktDropCnt;
++	__le32 au4RxPerStaFbRptCnt[CFG_BF_STA_REC_NUM];
++};
++
++struct pfmu_ru_field {
++	__le32 ru_start_id:7;
++	__le32 _rsv1:1;
++	__le32 ru_end_id:7;
++	__le32 _rsv2:1;
++} __packed;
++
++struct pfmu_partial_bw_info {
++	__le32 partial_bw_info:9;
++	__le32 _rsv1:7;
++} __packed;
++
++struct mt7996_pfmu_tag1 {
++	__le32 pfmu_idx:10;
++	__le32 ebf:1;
++	__le32 data_bw:3;
++	__le32 lm:3;
++	__le32 is_mu:1;
++	__le32 nr:3;
++	__le32 nc:3;
++	__le32 codebook:2;
++	__le32 ngroup:2;
++	__le32 invalid_prof:1;
++	__le32 _rsv:3;
++
++	__le32 col_id1:7, row_id1:9;
++	__le32 col_id2:7, row_id2:9;
++	__le32 col_id3:7, row_id3:9;
++	__le32 col_id4:7, row_id4:9;
++
++	union {
++		struct pfmu_ru_field field;
++		struct pfmu_partial_bw_info bw_info;
++	};
++	__le32 mob_cal_en:1;
++	__le32 _rsv2:3;
++	__le32 mob_ru_alloc:9;	/* EHT profile uses full 9 bit */
++	__le32 _rsv3:3;
++
++	__le32 snr_sts0:8, snr_sts1:8, snr_sts2:8, snr_sts3:8;
++	__le32 snr_sts4:8, snr_sts5:8, snr_sts6:8, snr_sts7:8;
++
++	__le32 _rsv4;
++} __packed;
++
++struct mt7996_pfmu_tag2 {
++	__le32 smart_ant:24;
++	__le32 se_idx:5;
++	__le32 _rsv:3;
++
++	__le32 _rsv1:16;
++	__le32 ibf_timeout:8;
++	__le32 _rsv2:8;
++
++	__le32 ibf_data_bw:3;
++	__le32 ibf_nc:3;
++	__le32 ibf_nr:3;
++	__le32 ibf_ru:9;
++	__le32 _rsv3:14;
++
++	__le32 mob_delta_t:8;
++	__le32 mob_lq_result:7;
++	__le32 _rsv5:1;
++	__le32 _rsv6:16;
++
++	__le32 _rsv7;
++} __packed;
++
++struct mt7996_pfmu_tag_event {
++	struct mt7996_mcu_bf_basic_event event;
++
++	u8 bfer;
++	u8 __rsv[3];
++
++	struct mt7996_pfmu_tag1 t1;
++	struct mt7996_pfmu_tag2 t2;
++};
++
++enum {
++	UNI_EVENT_BF_PFMU_TAG = 0x5,
++	UNI_EVENT_BF_PFMU_DATA = 0x7,
++	UNI_EVENT_BF_STAREC = 0xB,
++	UNI_EVENT_BF_CAL_PHASE = 0xC,
++	UNI_EVENT_BF_FBK_INFO = 0x17,
++	UNI_EVENT_BF_TXSND_INFO = 0x18,
++	UNI_EVENT_BF_PLY_INFO = 0x19,
++	UNI_EVENT_BF_METRIC_INFO = 0x1A,
++	UNI_EVENT_BF_TXCMD_CFG_INFO = 0x1B,
++	UNI_EVENT_BF_SND_CNT_INFO = 0x1D,
++	UNI_EVENT_BF_MAX_NUM
++};
++
++enum {
++	UNI_CMD_MURU_FIXED_RATE_CTRL = 0x11,
++	UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL,
++};
++
++struct uni_muru_mum_set_group_tbl_entry {
++	__le16 wlan_idx0;
++	__le16 wlan_idx1;
++	__le16 wlan_idx2;
++	__le16 wlan_idx3;
++
++	u8 dl_mcs_user0:4;
++	u8 dl_mcs_user1:4;
++	u8 dl_mcs_user2:4;
++	u8 dl_mcs_user3:4;
++	u8 ul_mcs_user0:4;
++	u8 ul_mcs_user1:4;
++	u8 ul_mcs_user2:4;
++	u8 ul_mcs_user3:4;
++
++	u8 num_user:2;
++	u8 rsv:6;
++	u8 nss0:2;
++	u8 nss1:2;
++	u8 nss2:2;
++	u8 nss3:2;
++	u8 ru_alloc;
++	u8 ru_alloc_ext;
++
++	u8 capa;
++	u8 gi;
++	u8 dl_ul;
++	u8 _rsv2;
++};
++
++enum UNI_CMD_MURU_VER_T {
++	UNI_CMD_MURU_VER_LEG = 0,
++	UNI_CMD_MURU_VER_HE,
++	UNI_CMD_MURU_VER_EHT,
++	UNI_CMD_MURU_VER_MAX
++};
++
++#define UNI_MAX_MCS_SUPPORT_HE 11
++#define UNI_MAX_MCS_SUPPORT_EHT 13
++
++enum {
++	RUALLOC_BW20 = 122,
++	RUALLOC_BW40 = 130,
++	RUALLOC_BW80 = 134,
++	RUALLOC_BW160 = 137,
++	RUALLOC_BW320 = 395,
++};
++
++enum {
++	MAX_MODBF_VHT = 0,
++	MAX_MODBF_HE = 2,
++	MAX_MODBF_EHT = 4,
++};
++
++enum {
++	BF_SND_READ_INFO = 0,
++	BF_SND_CFG_OPT,
++	BF_SND_CFG_INTV,
++	BF_SND_STA_STOP,
++	BF_SND_CFG_MAX_STA,
++	BF_SND_CFG_BFRP,
++	BF_SND_CFG_INF,
++	BF_SND_CFG_TXOP_SND
+ };
+ 
+ enum {
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1030-wifi-mt76-mt7996-add-wtbl_info-support-for-kite.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1030-wifi-mt76-mt7996-add-wtbl_info-support-for-kite.patch
deleted file mode 100644
index 3af30bf..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1030-wifi-mt76-mt7996-add-wtbl_info-support-for-kite.patch
+++ /dev/null
@@ -1,198 +0,0 @@
-From ab77df3cc660c0aa0f46060499d8704dc389a2a6 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Mon, 24 Jul 2023 16:39:22 +0800
-Subject: [PATCH 63/98] wifi: mt76: mt7996: add wtbl_info support for kite
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/mtk_debug.h   | 22 +++++++++++++
- mt7996/mtk_debugfs.c | 74 ++++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 93 insertions(+), 3 deletions(-)
-
-diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
-index 9718c2c..1611345 100644
---- a/mt7996/mtk_debug.h
-+++ b/mt7996/mtk_debug.h
-@@ -1088,6 +1088,17 @@ enum cipher_suit {
- #define WF_LWTBL_AAD_OM_MASK \
- 	0x00008000 // 15-15
- #define WF_LWTBL_AAD_OM_SHIFT                                       15
-+/* kite DW2 field bit 13-14 */
-+#define WF_LWTBL_DUAL_PTEC_EN_DW                                    2
-+#define WF_LWTBL_DUAL_PTEC_EN_ADDR                                  8
-+#define WF_LWTBL_DUAL_PTEC_EN_MASK \
-+	0x00002000 // 13-13
-+#define WF_LWTBL_DUAL_PTEC_EN_SHIFT                                 13
-+#define WF_LWTBL_DUAL_CTS_CAP_DW                                    2
-+#define WF_LWTBL_DUAL_CTS_CAP_ADDR                                  8
-+#define WF_LWTBL_DUAL_CTS_CAP_MASK \
-+	0x00004000 // 14-14
-+#define WF_LWTBL_DUAL_CTS_CAP_SHIFT                                 14
- #define WF_LWTBL_CIPHER_SUIT_PGTK_DW                                2
- #define WF_LWTBL_CIPHER_SUIT_PGTK_ADDR                              8
- #define WF_LWTBL_CIPHER_SUIT_PGTK_MASK \
-@@ -1305,6 +1316,8 @@ enum cipher_suit {
- #define WF_LWTBL_AF_ADDR                                            20
- #define WF_LWTBL_AF_MASK \
- 	0x00000007 // 2- 0
-+#define WF_LWTBL_AF_MASK_7992 \
-+	0x0000000f // 3- 0
- #define WF_LWTBL_AF_SHIFT                                           0
- #define WF_LWTBL_AF_HE_DW                                           5
- #define WF_LWTBL_AF_HE_ADDR                                         20
-@@ -1565,16 +1578,25 @@ enum cipher_suit {
- #define WF_LWTBL_PRITX_SW_MODE_MASK \
- 	0x00008000 // 15-15
- #define WF_LWTBL_PRITX_SW_MODE_SHIFT                                15
-+#define WF_LWTBL_PRITX_SW_MODE_MASK_7992 \
-+	0x00004000 // 14-14
-+#define WF_LWTBL_PRITX_SW_MODE_SHIFT_7992                           14
- #define WF_LWTBL_PRITX_ERSU_DW                                      9
- #define WF_LWTBL_PRITX_ERSU_ADDR                                    36
- #define WF_LWTBL_PRITX_ERSU_MASK \
- 	0x00010000 // 16-16
- #define WF_LWTBL_PRITX_ERSU_SHIFT                                   16
-+#define WF_LWTBL_PRITX_ERSU_MASK_7992 \
-+	0x00008000 // 15-15
-+#define WF_LWTBL_PRITX_ERSU_SHIFT_7992                              15
- #define WF_LWTBL_PRITX_PLR_DW                                       9
- #define WF_LWTBL_PRITX_PLR_ADDR                                     36
- #define WF_LWTBL_PRITX_PLR_MASK \
- 	0x00020000 // 17-17
- #define WF_LWTBL_PRITX_PLR_SHIFT                                    17
-+#define WF_LWTBL_PRITX_PLR_MASK_7992 \
-+	0x00030000 // 17-16
-+#define WF_LWTBL_PRITX_PLR_SHIFT_7992                               16
- #define WF_LWTBL_PRITX_DCM_DW                                       9
- #define WF_LWTBL_PRITX_DCM_ADDR                                     36
- #define WF_LWTBL_PRITX_DCM_MASK \
-diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
-index f56ad88..ce48664 100644
---- a/mt7996/mtk_debugfs.c
-+++ b/mt7996/mtk_debugfs.c
-@@ -1011,7 +1011,8 @@ static void parse_fmac_lwtbl_dw0_1(struct seq_file *s, u8 *lwtbl)
- 	}
- }
- 
--static const struct berse_wtbl_parse WTBL_LMAC_DW2[] = {
-+static const struct berse_wtbl_parse *WTBL_LMAC_DW2;
-+static const struct berse_wtbl_parse WTBL_LMAC_DW2_7996[] = {
- 	{"AID",                 WF_LWTBL_AID_MASK,              WF_LWTBL_AID_SHIFT,	false},
- 	{"GID_SU",              WF_LWTBL_GID_SU_MASK,           NO_SHIFT_DEFINE,	false},
- 	{"SPP_EN",              WF_LWTBL_SPP_EN_MASK,           NO_SHIFT_DEFINE,	false},
-@@ -1032,6 +1033,26 @@ static const struct berse_wtbl_parse WTBL_LMAC_DW2[] = {
- 	{NULL,}
- };
- 
-+static const struct berse_wtbl_parse WTBL_LMAC_DW2_7992[] = {
-+	{"AID",                 WF_LWTBL_AID_MASK,              WF_LWTBL_AID_SHIFT,	false},
-+	{"GID_SU",              WF_LWTBL_GID_SU_MASK,           NO_SHIFT_DEFINE,	false},
-+	{"DUAL_PTEC_EN",        WF_LWTBL_DUAL_PTEC_EN_MASK,     NO_SHIFT_DEFINE,	false},
-+	{"DUAL_CTS_CAP",        WF_LWTBL_DUAL_CTS_CAP_MASK,     NO_SHIFT_DEFINE,	false},
-+	{"CIPHER_PGTK",WF_LWTBL_CIPHER_SUIT_PGTK_MASK, WF_LWTBL_CIPHER_SUIT_PGTK_SHIFT,	true},
-+	{"FROM_DS",             WF_LWTBL_FD_MASK,               NO_SHIFT_DEFINE,	false},
-+	{"TO_DS",               WF_LWTBL_TD_MASK,               NO_SHIFT_DEFINE,	false},
-+	{"SW",                  WF_LWTBL_SW_MASK,               NO_SHIFT_DEFINE,	false},
-+	{"UL",                  WF_LWTBL_UL_MASK,               NO_SHIFT_DEFINE,	false},
-+	{"TX_POWER_SAVE",       WF_LWTBL_TX_PS_MASK,            NO_SHIFT_DEFINE,	true},
-+	{"QOS",                 WF_LWTBL_QOS_MASK,              NO_SHIFT_DEFINE,	false},
-+	{"HT",                  WF_LWTBL_HT_MASK,               NO_SHIFT_DEFINE,	false},
-+	{"VHT",                 WF_LWTBL_VHT_MASK,              NO_SHIFT_DEFINE,	false},
-+	{"HE",                  WF_LWTBL_HE_MASK,               NO_SHIFT_DEFINE,	false},
-+	{"EHT",                 WF_LWTBL_EHT_MASK,              NO_SHIFT_DEFINE,	false},
-+	{"MESH",                WF_LWTBL_MESH_MASK,             NO_SHIFT_DEFINE,	true},
-+	{NULL,}
-+};
-+
- static void parse_fmac_lwtbl_dw2(struct seq_file *s, u8 *lwtbl)
- {
- 	u32 *addr = 0;
-@@ -1141,7 +1162,8 @@ static void parse_fmac_lwtbl_dw4(struct seq_file *s, u8 *lwtbl)
- 	}
- }
- 
--static const struct berse_wtbl_parse WTBL_LMAC_DW5[] = {
-+static const struct berse_wtbl_parse *WTBL_LMAC_DW5;
-+static const struct berse_wtbl_parse WTBL_LMAC_DW5_7996[] = {
- 	{"AF",                  WF_LWTBL_AF_MASK,           WF_LWTBL_AF_SHIFT,	false},
- 	{"AF_HE",               WF_LWTBL_AF_HE_MASK,        WF_LWTBL_AF_HE_SHIFT,false},
- 	{"RTS",                 WF_LWTBL_RTS_MASK,          NO_SHIFT_DEFINE,	false},
-@@ -1163,6 +1185,27 @@ static const struct berse_wtbl_parse WTBL_LMAC_DW5[] = {
- 	{NULL,}
- };
- 
-+static const struct berse_wtbl_parse WTBL_LMAC_DW5_7992[] = {
-+	{"AF",                  WF_LWTBL_AF_MASK_7992,      WF_LWTBL_AF_SHIFT,	false},
-+	{"RTS",                 WF_LWTBL_RTS_MASK,          NO_SHIFT_DEFINE,	false},
-+	{"SMPS",                WF_LWTBL_SMPS_MASK,         NO_SHIFT_DEFINE,	false},
-+	{"DYN_BW",              WF_LWTBL_DYN_BW_MASK,       NO_SHIFT_DEFINE,	true},
-+	{"MMSS",                WF_LWTBL_MMSS_MASK,         WF_LWTBL_MMSS_SHIFT,false},
-+	{"USR",                 WF_LWTBL_USR_MASK,          NO_SHIFT_DEFINE,	false},
-+	{"SR_RATE",             WF_LWTBL_SR_R_MASK,         WF_LWTBL_SR_R_SHIFT,false},
-+	{"SR_ABORT",            WF_LWTBL_SR_ABORT_MASK,     NO_SHIFT_DEFINE,	true},
-+	{"TX_POWER_OFFSET",     WF_LWTBL_TX_POWER_OFFSET_MASK,  WF_LWTBL_TX_POWER_OFFSET_SHIFT,	false},
-+	{"LTF_EHT",		WF_LWTBL_LTF_EHT_MASK,      WF_LWTBL_LTF_EHT_SHIFT, false},
-+	{"GI_EHT",		WF_LWTBL_GI_EHT_MASK,       WF_LWTBL_GI_EHT_SHIFT, false},
-+	{"DOPPL",               WF_LWTBL_DOPPL_MASK,        NO_SHIFT_DEFINE,	false},
-+	{"TXOP_PS_CAP",         WF_LWTBL_TXOP_PS_CAP_MASK,  NO_SHIFT_DEFINE,	false},
-+	{"DONOT_UPDATE_I_PSM",  WF_LWTBL_DU_I_PSM_MASK,     NO_SHIFT_DEFINE,	true},
-+	{"I_PSM",               WF_LWTBL_I_PSM_MASK,        NO_SHIFT_DEFINE,	false},
-+	{"PSM",                 WF_LWTBL_PSM_MASK,          NO_SHIFT_DEFINE,	false},
-+	{"SKIP_TX",             WF_LWTBL_SKIP_TX_MASK,      NO_SHIFT_DEFINE,	true},
-+	{NULL,}
-+};
-+
- static void parse_fmac_lwtbl_dw5(struct seq_file *s, u8 *lwtbl)
- {
- 	u32 *addr = 0;
-@@ -1281,7 +1324,8 @@ static void parse_fmac_lwtbl_dw8(struct seq_file *s, u8 *lwtbl)
- 	}
- }
- 
--static const struct berse_wtbl_parse WTBL_LMAC_DW9[] = {
-+static const struct berse_wtbl_parse *WTBL_LMAC_DW9;
-+static const struct berse_wtbl_parse WTBL_LMAC_DW9_7996[] = {
- 	{"RX_AVG_MPDU_SIZE",    WF_LWTBL_RX_AVG_MPDU_SIZE_MASK,    WF_LWTBL_RX_AVG_MPDU_SIZE_SHIFT,	false},
- 	{"PRITX_SW_MODE",       WF_LWTBL_PRITX_SW_MODE_MASK,       NO_SHIFT_DEFINE,	false},
- 	{"PRITX_ERSU",	    WF_LWTBL_PRITX_ERSU_MASK,	       NO_SHIFT_DEFINE,	false},
-@@ -1295,6 +1339,20 @@ static const struct berse_wtbl_parse WTBL_LMAC_DW9[] = {
- 	{NULL,}
- };
- 
-+static const struct berse_wtbl_parse WTBL_LMAC_DW9_7992[] = {
-+	{"RX_AVG_MPDU_SIZE",    WF_LWTBL_RX_AVG_MPDU_SIZE_MASK,    WF_LWTBL_RX_AVG_MPDU_SIZE_SHIFT,	false},
-+	{"PRITX_SW_MODE",       WF_LWTBL_PRITX_SW_MODE_MASK_7992,       NO_SHIFT_DEFINE,	false},
-+	{"PRITX_ERSU",	    WF_LWTBL_PRITX_ERSU_MASK_7992,	       NO_SHIFT_DEFINE,	false},
-+	{"PRITX_PLR",           WF_LWTBL_PRITX_PLR_MASK_7992,           NO_SHIFT_DEFINE,	true},
-+	{"PRITX_DCM",           WF_LWTBL_PRITX_DCM_MASK,           NO_SHIFT_DEFINE,	false},
-+	{"PRITX_ER106T",        WF_LWTBL_PRITX_ER106T_MASK,        NO_SHIFT_DEFINE,	true},
-+	/* {"FCAP(0:20 1:~40)",    WTBL_FCAP_20_TO_160_MHZ,	WTBL_FCAP_20_TO_160_MHZ_OFFSET}, */
-+	{"MPDU_FAIL_CNT",       WF_LWTBL_MPDU_FAIL_CNT_MASK,       WF_LWTBL_MPDU_FAIL_CNT_SHIFT,	false},
-+	{"MPDU_OK_CNT",         WF_LWTBL_MPDU_OK_CNT_MASK,         WF_LWTBL_MPDU_OK_CNT_SHIFT,	false},
-+	{"RATE_IDX",            WF_LWTBL_RATE_IDX_MASK,            WF_LWTBL_RATE_IDX_SHIFT,	true},
-+	{NULL,}
-+};
-+
- char *fcap_name[] = {"20MHz", "20/40MHz", "20/40/80MHz", "20/40/80/160/80+80MHz", "20/40/80/160/80+80/320MHz"};
- 
- static void parse_fmac_lwtbl_dw9(struct seq_file *s, u8 *lwtbl)
-@@ -2670,6 +2728,16 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
- {
- 	struct mt7996_dev *dev = phy->dev;
- 
-+	if (is_mt7996(&dev->mt76)) {
-+		WTBL_LMAC_DW2 = WTBL_LMAC_DW2_7996;
-+		WTBL_LMAC_DW5 = WTBL_LMAC_DW5_7996;
-+		WTBL_LMAC_DW9 = WTBL_LMAC_DW9_7996;
-+	} else {
-+		WTBL_LMAC_DW2 = WTBL_LMAC_DW2_7992;
-+		WTBL_LMAC_DW5 = WTBL_LMAC_DW5_7992;
-+		WTBL_LMAC_DW9 = WTBL_LMAC_DW9_7992;
-+	}
-+
- 	mt7996_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);
- 
- 	/* agg */
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1031-mtk-wifi-mt76-mt7996-add-build-the-following-MURU-mc.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1031-mtk-wifi-mt76-mt7996-add-build-the-following-MURU-mc.patch
new file mode 100644
index 0000000..bd1a654
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1031-mtk-wifi-mt76-mt7996-add-build-the-following-MURU-mc.patch
@@ -0,0 +1,189 @@
+From 16c194f2e8eb3bbe932ef58569eefa1dfb806264 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Tue, 13 Jun 2023 14:49:02 +0800
+Subject: [PATCH 1031/1041] mtk: wifi: mt76: mt7996: add build the following
+ MURU mcu command tlvs
+
+It includes the following tlvs:
+1. MURU tlv id 0x10, 0x33, 0xC8, 0xC9, 0xCA, 0xCC, 0xCD
+2. BF tlv id 0x1c
+
+---
+ mt7996/mcu.h         |  1 +
+ mt7996/mt7996.h      |  3 ++
+ mt7996/mtk_debugfs.c | 12 +++++++
+ mt7996/mtk_mcu.c     | 78 ++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.h     | 14 ++++++++
+ 5 files changed, 108 insertions(+)
+
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 347893c8..527c9c79 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -776,6 +776,7 @@ enum {
+ 	BF_MOD_EN_CTRL = 20,
+ 	BF_FBRPT_DBG_INFO_READ = 23,
+ 	BF_TXSND_INFO = 24,
++	BF_CFG_PHY = 28,
+ };
+ 
+ enum {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index a321e8e8..9df6b25c 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -814,6 +814,9 @@ void mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ int mt7996_mcu_set_muru_fixed_rate_enable(struct mt7996_dev *dev, u8 action, int val);
+ int mt7996_mcu_set_muru_fixed_rate_parameter(struct mt7996_dev *dev, u8 action, void *para);
+ int mt7996_mcu_set_txbf_snd_info(struct mt7996_phy *phy, void *para);
++int mt7996_mcu_set_muru_cmd(struct mt7996_dev *dev, u16 action, int val);
++int mt7996_mcu_muru_set_prot_frame_thr(struct mt7996_dev *dev, u32 val);
++int mt7996_mcu_set_bypass_smthint(struct mt7996_phy *phy, u8 val);
+ #endif
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 938da645..1530ad79 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2909,6 +2909,16 @@ static const struct file_operations fops_muru_fixed_group_rate = {
+ 	.llseek = default_llseek,
+ };
+ 
++static int mt7996_muru_prot_thr_set(void *data, u64 val)
++{
++	struct mt7996_phy *phy = data;
++
++	return mt7996_mcu_muru_set_prot_frame_thr(phy->dev, (u32)val);
++}
++
++DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_prot_thr, NULL,
++			 mt7996_muru_prot_thr_set, "%lld\n");
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -3003,6 +3013,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ 	debugfs_create_file("bf_fbk_rpt", 0600, dir, phy, &fops_bf_fbk_rpt);
+ 	debugfs_create_file("pfmu_tag_read", 0600, dir, phy, &fops_bf_pfmu_tag_read);
+ 
++	debugfs_create_file("muru_prot_thr", 0200, dir, phy, &fops_muru_prot_thr);
++
+ 	return 0;
+ }
+ 
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index 67419cd9..b7d86384 100644
+--- a/mt7996/mtk_mcu.c
++++ b/mt7996/mtk_mcu.c
+@@ -906,4 +906,82 @@ error:
+ 	return -EINVAL;
+ }
+ 
++/**
++ * This function can be used to build the following commands
++ * MURU_SUTX_CTRL (0x10)
++ * SET_FORCE_MU (0x33)
++ * SET_MUDL_ACK_POLICY (0xC8)
++ * SET_TRIG_TYPE (0xC9)
++ * SET_20M_DYN_ALGO (0xCA)
++ * SET_CERT_MU_EDCA_OVERRIDE (0xCD)
++ */
++int mt7996_mcu_set_muru_cmd(struct mt7996_dev *dev, u16 action, int val)
++{
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++
++		u8 config;
++		u8 rsv[3];
++	} __packed data = {
++		.tag = cpu_to_le16(action),
++		.len = cpu_to_le16(sizeof(data) - 4),
++		.config = (u8) val,
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &data, sizeof(data),
++				 false);
++}
++
++int mt7996_mcu_muru_set_prot_frame_thr(struct mt7996_dev *dev, u32 val)
++{
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++
++		__le32 prot_frame_thr;
++	} __packed data = {
++		.tag = cpu_to_le16(UNI_CMD_MURU_PROT_FRAME_THR),
++		.len = cpu_to_le16(sizeof(data) - 4),
++		.prot_frame_thr = cpu_to_le32(val),
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &data, sizeof(data),
++				 false);
++}
++
++int mt7996_mcu_set_bypass_smthint(struct mt7996_phy *phy, u8 val)
++{
++#define BF_PHY_SMTH_INT_BYPASS 0
++#define BYPASS_VAL 1
++	struct mt7996_dev *dev = phy->dev;
++	struct {
++		u8 _rsv[4];
++
++		u16 tag;
++		u16 len;
++
++		u8 action;
++		u8 band_idx;
++		u8 smthintbypass;
++		u8 __rsv2[5];
++	} __packed data = {
++		.tag = cpu_to_le16(BF_CFG_PHY),
++		.len = cpu_to_le16(sizeof(data) - 4),
++		.action = BF_PHY_SMTH_INT_BYPASS,
++		.band_idx = phy->mt76->band_idx,
++		.smthintbypass = val,
++	};
++
++	if (val != BYPASS_VAL)
++		return -EINVAL;
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF), &data, sizeof(data),
++				 true);
++}
++
+ #endif
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index 519ffe1c..eedc3589 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -106,6 +106,20 @@ enum {
+ 	EDCCA_FCC = 1,
+ 	EDCCA_ETSI = 2,
+ 	EDCCA_JAPAN = 3
++};
++
++enum {
++	UNI_CMD_MURU_SUTX_CTRL = 0x10,
++	UNI_CMD_MURU_FIXED_RATE_CTRL,
++	UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL,
++	UNI_CMD_MURU_SET_FORCE_MU = 0x33,
++	UNI_CMD_MURU_MUNUAL_CONFIG = 0x64,
++	UNI_CMD_MURU_SET_MUDL_ACK_POLICY = 0xC9,
++	UNI_CMD_MURU_SET_TRIG_TYPE,
++	UNI_CMD_MURU_SET_20M_DYN_ALGO,
++	UNI_CMD_MURU_PROT_FRAME_THR = 0xCC,
++	UNI_CMD_MURU_SET_CERT_MU_EDCA_OVERRIDE,
++};
+ 
+ struct bf_pfmu_tag {
+ 	__le16 tag;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1032-mtk-wifi-mt76-mt7996-add-cert-patch.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1032-mtk-wifi-mt76-mt7996-add-cert-patch.patch
new file mode 100644
index 0000000..ca22864
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1032-mtk-wifi-mt76-mt7996-add-cert-patch.patch
@@ -0,0 +1,1094 @@
+From 0a36115fd164506e65bcbef9444f6664ba833c04 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Mon, 14 Aug 2023 13:36:58 +0800
+Subject: [PATCH 1032/1041] mtk: wifi: mt76: mt7996: add cert patch
+
+This patch includes TGac and TGax
+
+Commit histroy:
+
+Add vendor cmd set ap wireless rts_sigta support
+
+Signed-off-by: ye he <ye.he@mediatek.com>
+---
+ mt7996/mac.c     |   9 ++
+ mt7996/main.c    |  31 ++++++-
+ mt7996/mcu.c     |  40 +++++++++
+ mt7996/mcu.h     |   6 ++
+ mt7996/mt7996.h  |  13 +++
+ mt7996/mtk_mcu.c | 206 ++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.h | 184 +++++++++++++++++++++++++++++++++++--
+ mt7996/vendor.c  | 230 ++++++++++++++++++++++++++++++++++++++++++++++-
+ mt7996/vendor.h  |  67 ++++++++++++++
+ 9 files changed, 779 insertions(+), 7 deletions(-)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 73c66e57..27e5fb71 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -10,6 +10,7 @@
+ #include "../dma.h"
+ #include "mac.h"
+ #include "mcu.h"
++#include "vendor.h"
+ 
+ #define to_rssi(field, rcpi)	((FIELD_GET(field, rcpi) - 220) / 2)
+ 
+@@ -2272,6 +2273,14 @@ void mt7996_mac_update_stats(struct mt7996_phy *phy)
+ 	}
+ }
+ 
++void mt7996_set_wireless_amsdu(struct ieee80211_hw *hw, u8 en)
++{
++	if (en)
++		ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
++	else
++		ieee80211_hw_clear(hw, SUPPORTS_AMSDU_IN_AMPDU);
++}
++
+ void mt7996_mac_sta_rc_work(struct work_struct *work)
+ {
+ 	struct mt7996_dev *dev = container_of(work, struct mt7996_dev, rc_work);
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 36894828..5a5b549a 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -588,6 +588,7 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 		       bool beacon, bool mcast)
+ {
+ 	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
++	struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ 	struct mt76_phy *mphy = hw->priv;
+ 	u16 rate;
+ 	u8 i, idx;
+@@ -597,6 +598,9 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	if (beacon) {
+ 		struct mt7996_phy *phy = mphy->priv;
+ 
++		if (dev->cert_mode && phy->mt76->band_idx == MT_BAND2)
++			rate = 0x0200;
++
+ 		/* odd index for driver, even index for firmware */
+ 		idx = MT7996_BEACON_RATES_TBL + 2 * phy->mt76->band_idx;
+ 		if (phy->beacon_rate != rate)
+@@ -726,6 +730,10 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	u8 band_idx = mvif->phy->mt76->band_idx;
+ 	int ret, idx;
+ 
++#ifdef CONFIG_MTK_VENDOR
++	struct mt7996_phy *phy = &dev->phy;
++#endif
++
+ 	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA);
+ 	if (idx < 0)
+ 		return -ENOSPC;
+@@ -751,7 +759,28 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	if (ret)
+ 		return ret;
+ 
+-	return mt7996_mcu_add_rate_ctrl(dev, vif, sta, false);
++	ret = mt7996_mcu_add_rate_ctrl(dev, vif, sta, false);
++	if (ret)
++		return ret;
++
++#ifdef CONFIG_MTK_VENDOR
++	switch (band_idx) {
++	case MT_BAND1:
++		phy = mt7996_phy2(dev);
++		break;
++	case MT_BAND2:
++		phy = mt7996_phy3(dev);
++		break;
++	case MT_BAND0:
++	default:
++		break;
++	}
++
++	if (phy && phy->muru_onoff & MUMIMO_DL_CERT)
++		mt7996_mcu_set_mimo(phy);
++#endif
++
++	return 0;
+ }
+ 
+ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index d3dab186..7f235f91 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -1359,6 +1359,10 @@ mt7996_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+ {
+ 	struct sta_rec_vht *vht;
+ 	struct tlv *tlv;
++#ifdef CONFIG_MTK_VENDOR
++	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
++	struct mt7996_phy *phy = (struct mt7996_phy *)msta->vif->phy;
++#endif
+ 
+ 	/* For 6G band, this tlv is necessary to let hw work normally */
+ 	if (!sta->deflink.he_6ghz_capa.capa && !sta->deflink.vht_cap.vht_supported)
+@@ -1370,6 +1374,9 @@ mt7996_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+ 	vht->vht_cap = cpu_to_le32(sta->deflink.vht_cap.cap);
+ 	vht->vht_rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map;
+ 	vht->vht_tx_mcs_map = sta->deflink.vht_cap.vht_mcs.tx_mcs_map;
++#ifdef CONFIG_MTK_VENDOR
++	vht->rts_bw_sig = phy->rts_bw_sig;
++#endif
+ }
+ 
+ static void
+@@ -4445,6 +4452,27 @@ int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val)
+ 				 &req, sizeof(req), true);
+ }
+ 
++int mt7996_mcu_set_band_confg(struct mt7996_phy *phy, u16 option, bool enable)
++{
++	struct {
++		u8 band_idx;
++		u8 _rsv[3];
++
++		__le16 tag;
++		__le16 len;
++		bool enable;
++		u8 _rsv2[3];
++	} __packed req = {
++		.band_idx = phy->mt76->band_idx,
++		.tag = cpu_to_le16(option),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.enable = enable,
++	};
++
++	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
++				 &req, sizeof(req), true);
++}
++
+ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable)
+ {
+ 	struct {
+@@ -4959,6 +4987,18 @@ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+ 	val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
+ 
+ 	switch (mode) {
++	case RATE_PARAM_FIXED_OFDMA:
++		if (val == 3)
++			phy->muru_onoff = OFDMA_DL;
++		else
++			phy->muru_onoff = val;
++		break;
++	case RATE_PARAM_FIXED_MIMO:
++		if (val == 0)
++			phy->muru_onoff = MUMIMO_DL_CERT | MUMIMO_DL;
++		else
++			phy->muru_onoff = MUMIMO_UL;
++		break;
+ 	case RATE_PARAM_AUTO_MU:
+ 		if (val < 0 || val > 15) {
+ 			printk("Wrong value! The value is between 0-15.\n");
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 527c9c79..af078edd 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -755,6 +755,8 @@ enum {
+ 	RATE_PARAM_FIXED_GI = 11,
+ 	RATE_PARAM_AUTO = 20,
+ #ifdef CONFIG_MTK_VENDOR
++	RATE_PARAM_FIXED_MIMO = 30,
++	RATE_PARAM_FIXED_OFDMA = 31,
+ 	RATE_PARAM_AUTO_MU = 32,
+ #endif
+ };
+@@ -767,6 +769,7 @@ enum {
+ #define OFDMA_UL                       BIT(1)
+ #define MUMIMO_DL                      BIT(2)
+ #define MUMIMO_UL                      BIT(3)
++#define MUMIMO_DL_CERT                 BIT(4)
+ 
+ enum {
+ 	BF_SOUNDING_ON = 1,
+@@ -853,11 +856,14 @@ enum {
+ 	UNI_BAND_CONFIG_EDCCA_ENABLE = 0x05,
+ 	UNI_BAND_CONFIG_EDCCA_THRESHOLD = 0x06,
+ 	UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
++	UNI_BAND_CONFIG_RTS_SIGTA_EN = 0x09,
++	UNI_BAND_CONFIG_DIS_SECCH_CCA_DET = 0x0a,
+ };
+ 
+ enum {
+ 	UNI_WSYS_CONFIG_FW_LOG_CTRL,
+ 	UNI_WSYS_CONFIG_FW_DBG_CTRL,
++	UNI_CMD_CERT_CFG = 6,
+ };
+ 
+ enum {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 9df6b25c..e1a191ec 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -348,6 +348,7 @@ struct mt7996_phy {
+ 	} test;
+ #endif
+ #ifdef CONFIG_MTK_VENDOR
++	u8 rts_bw_sig;
+ 	spinlock_t amnt_lock;
+ 	struct mt7996_air_monitor_ctrl amnt_ctrl;
+ #endif
+@@ -475,6 +476,9 @@ struct mt7996_dev {
+ 	} dbg;
+ 	const struct mt7996_dbg_reg_desc *dbg_reg;
+ #endif
++#ifdef CONFIG_MTK_VENDOR
++	bool cert_mode;
++#endif
+ };
+ 
+ enum {
+@@ -672,6 +676,7 @@ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
+ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
+ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
++int mt7996_mcu_set_band_confg(struct mt7996_phy *phy, u16 option, bool enable);
+ 
+ static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
+ {
+@@ -790,6 +795,10 @@ void mt7996_vendor_register(struct mt7996_phy *phy);
+ void mt7996_vendor_amnt_fill_rx(struct mt7996_phy *phy, struct sk_buff *skb);
+ int mt7996_vendor_amnt_sta_remove(struct mt7996_phy *phy,
+ 				  struct ieee80211_sta *sta);
++void mt7996_set_wireless_amsdu(struct ieee80211_hw *hw, u8 en);
++void mt7996_mcu_set_mimo(struct mt7996_phy *phy);
++int mt7996_set_muru_cfg(struct mt7996_phy *phy, u8 action, u8 val);
++int mt7996_mcu_set_muru_cfg(struct mt7996_phy *phy, void *data);
+ #endif
+ 
+ int mt7996_mcu_edcca_enable(struct mt7996_phy *phy, bool enable);
+@@ -817,6 +826,10 @@ int mt7996_mcu_set_txbf_snd_info(struct mt7996_phy *phy, void *para);
+ int mt7996_mcu_set_muru_cmd(struct mt7996_dev *dev, u16 action, int val);
+ int mt7996_mcu_muru_set_prot_frame_thr(struct mt7996_dev *dev, u32 val);
+ int mt7996_mcu_set_bypass_smthint(struct mt7996_phy *phy, u8 val);
++int mt7996_mcu_set_rfeature_trig_type(struct mt7996_phy *phy, u8 enable, u8 trig_type);
++void mt7996_mcu_set_ppdu_tx_type(struct mt7996_phy *phy, u8 ppdu_type);
++void mt7996_mcu_set_nusers_ofdma(struct mt7996_phy *phy, u8 type, u8 ofdma_user_cnt);
++void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type);
+ #endif
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index b7d86384..3b8fbe42 100644
+--- a/mt7996/mtk_mcu.c
++++ b/mt7996/mtk_mcu.c
+@@ -984,4 +985,209 @@ int mt7996_mcu_set_bypass_smthint(struct mt7996_phy *phy, u8 val)
+ 				 true);
+ }
+ 
++int mt7996_mcu_set_bsrp_ctrl(struct mt7996_phy *phy, u16 interval,
++			     u16 ru_alloc, u32 trig_type, u8 trig_flow, u8 ext_cmd)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++
++		__le16 interval;
++		__le16 ru_alloc;
++		__le32 trigger_type;
++		u8 trigger_flow;
++		u8 ext_cmd_bsrp;
++		u8 band_bitmap;
++		u8 _rsv2;
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_CMD_MURU_BSRP_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.interval = cpu_to_le16(interval),
++		.ru_alloc = cpu_to_le16(ru_alloc),
++		.trigger_type = cpu_to_le32(trig_type),
++		.trigger_flow = trig_flow,
++		.ext_cmd_bsrp = ext_cmd,
++		.band_bitmap = BIT(phy->mt76->band_idx),
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &req,
++				 sizeof(req), false);
++}
++
++int mt7996_mcu_set_rfeature_trig_type(struct mt7996_phy *phy, u8 enable, u8 trig_type)
++{
++	struct mt7996_dev *dev = phy->dev;
++	int ret = 0;
++	char buf[] = "01:00:00:1B";
++
++	if (enable) {
++		ret = mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SET_TRIG_TYPE, trig_type);
++		if (ret)
++			return ret;
++	}
++
++	switch (trig_type) {
++	case CAPI_BASIC:
++		return mt7996_mcu_set_bsrp_ctrl(phy, 5, 67, 0, 0, enable);
++	case CAPI_BRP:
++		return mt7996_mcu_set_txbf_snd_info(phy, buf);
++	case CAPI_MU_BAR:
++		return mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SET_MUDL_ACK_POLICY,
++					       MU_DL_ACK_POLICY_MU_BAR);
++	case CAPI_BSRP:
++		return mt7996_mcu_set_bsrp_ctrl(phy, 5, 67, 4, 0, enable);
++	default:
++		return 0;
++	}
++}
++
++int mt7996_mcu_set_muru_cfg(struct mt7996_phy *phy, void *data)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_muru *muru;
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++
++		u8 version;
++		u8 revision;
++		u8 _rsv2[2];
++
++		struct mt7996_muru muru;
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_CMD_MURU_MUNUAL_CONFIG),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.version = UNI_CMD_MURU_VER_EHT,
++	};
++
++	muru = (struct mt7996_muru *) data;
++	memcpy(&req.muru, muru, sizeof(struct mt7996_muru));
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &req,
++				 sizeof(req), false);
++}
++
++int mt7996_set_muru_cfg(struct mt7996_phy *phy, u8 action, u8 val)
++{
++	struct mt7996_muru *muru;
++	struct mt7996_muru_dl *dl;
++	struct mt7996_muru_ul *ul;
++	struct mt7996_muru_comm *comm;
++	int ret = 0;
++
++	muru = kzalloc(sizeof(struct mt7996_muru), GFP_KERNEL);
++	dl = &muru->dl;
++	ul = &muru->ul;
++	comm = &muru->comm;
++
++	switch (action) {
++	case MU_CTRL_DL_USER_CNT:
++		dl->user_num = val;
++		comm->ppdu_format = MURU_PPDU_HE_MU;
++		comm->sch_type = MURU_OFDMA_SCH_TYPE_DL;
++		muru->cfg_comm = cpu_to_le32(MURU_COMM_SET);
++		muru->cfg_dl = cpu_to_le32(MURU_FIXED_DL_TOTAL_USER_CNT);
++		ret = mt7996_mcu_set_muru_cfg(phy, muru);
++		break;
++	case MU_CTRL_UL_USER_CNT:
++		ul->user_num = val;
++		comm->ppdu_format = MURU_PPDU_HE_TRIG;
++		comm->sch_type = MURU_OFDMA_SCH_TYPE_UL;
++		muru->cfg_comm = cpu_to_le32(MURU_COMM_SET);
++		muru->cfg_ul = cpu_to_le32(MURU_FIXED_UL_TOTAL_USER_CNT);
++		ret = mt7996_mcu_set_muru_cfg(phy, muru);
++		break;
++	default:
++		break;
++	}
++
++	kfree(muru);
++	return ret;
++}
++
++void mt7996_mcu_set_ppdu_tx_type(struct mt7996_phy *phy, u8 ppdu_type)
++{
++	struct mt7996_dev *dev = phy->dev;
++	int enable_su;
++
++	switch (ppdu_type) {
++	case CAPI_SU:
++		enable_su = 1;
++		mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SUTX_CTRL, enable_su);
++		mt7996_set_muru_cfg(phy, MU_CTRL_DL_USER_CNT, 0);
++		break;
++	case CAPI_MU:
++		enable_su = 0;
++		mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SUTX_CTRL, enable_su);
++		break;
++	default:
++		break;
++	}
++}
++
++void mt7996_mcu_set_nusers_ofdma(struct mt7996_phy *phy, u8 type, u8 user_cnt)
++{
++	struct mt7996_dev *dev = phy->dev;
++	int enable_su = 0;
++
++	mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SUTX_CTRL, enable_su);
++	mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SET_MUDL_ACK_POLICY, MU_DL_ACK_POLICY_SU_BAR);
++	mt7996_mcu_muru_set_prot_frame_thr(dev, 9999);
++
++	mt7996_set_muru_cfg(phy, type, user_cnt);
++}
++
++void mt7996_mcu_set_mimo(struct mt7996_phy *phy)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
++	int disable_ra = 1;
++	char buf[] = "2 134 0 1 0 1 2 2 2";
++	int force_mu = 1;
++
++	switch (chandef->width) {
++	case NL80211_CHAN_WIDTH_20_NOHT:
++	case NL80211_CHAN_WIDTH_20:
++		strscpy(buf, "2 122 0 1 0 1 2 2 2", sizeof(buf));
++		break;
++	case NL80211_CHAN_WIDTH_80:
++		break;
++	case NL80211_CHAN_WIDTH_160:
++		strscpy(buf, "2 137 0 1 0 1 2 2 2", sizeof(buf));
++		break;
++	default:
++		break;
++	}
++
++	mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SET_MUDL_ACK_POLICY, MU_DL_ACK_POLICY_SU_BAR);
++	mt7996_mcu_set_muru_fixed_rate_enable(dev, UNI_CMD_MURU_FIXED_RATE_CTRL, disable_ra);
++	mt7996_mcu_set_muru_fixed_rate_parameter(dev, UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL, buf);
++	mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SET_FORCE_MU, force_mu);
++}
++
++void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++		u8 action;
++		u8 _rsv2[3];
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_CMD_CERT_CFG),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.action = type, /* 1: CAPI Enable */
++	};
++
++	mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(WSYS_CONFIG), &req,
++			  sizeof(req), false);
++}
++
+ #endif
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index eedc3589..44cb0327 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -109,14 +109,15 @@ enum {
+ };
+ 
+ enum {
++	UNI_CMD_MURU_BSRP_CTRL = 0x01,
+ 	UNI_CMD_MURU_SUTX_CTRL = 0x10,
+-	UNI_CMD_MURU_FIXED_RATE_CTRL,
+-	UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL,
++	UNI_CMD_MURU_FIXED_RATE_CTRL = 0x11,
++	UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL = 0x12,
+ 	UNI_CMD_MURU_SET_FORCE_MU = 0x33,
+ 	UNI_CMD_MURU_MUNUAL_CONFIG = 0x64,
+-	UNI_CMD_MURU_SET_MUDL_ACK_POLICY = 0xC9,
+-	UNI_CMD_MURU_SET_TRIG_TYPE,
+-	UNI_CMD_MURU_SET_20M_DYN_ALGO,
++	UNI_CMD_MURU_SET_MUDL_ACK_POLICY = 0xC8,
++	UNI_CMD_MURU_SET_TRIG_TYPE = 0xC9,
++	UNI_CMD_MURU_SET_20M_DYN_ALGO = 0xCA,
+ 	UNI_CMD_MURU_PROT_FRAME_THR = 0xCC,
+ 	UNI_CMD_MURU_SET_CERT_MU_EDCA_OVERRIDE,
+ };
+@@ -520,6 +521,179 @@ struct mt7996_mcu_sr_hw_ind_event {
+ 	__le32 sr_ampdu_mpdu_cnt;
+ 	__le32 sr_ampdu_mpdu_acked_cnt;
+ };
++
++struct mt7996_muru_comm {
++	u8 pda_pol;
++	u8 band;
++	u8 spe_idx;
++	u8 proc_type;
++
++	__le16 mlo_ctrl;
++	u8 sch_type;
++	u8 ppdu_format;
++	u8 ac;
++	u8 _rsv[3];
++};
++
++struct mt7996_muru_dl {
++	u8 user_num;
++	u8 tx_mode;
++	u8 bw;
++	u8 gi;
++
++	u8 ltf;
++	u8 mcs;
++	u8 dcm;
++	u8 cmprs;
++
++	__le16 ru[16];
++
++	u8 c26[2];
++	u8 ack_policy;
++	u8 tx_power;
++
++	__le16 mu_ppdu_duration;
++	u8 agc_disp_order;
++	u8 _rsv1;
++
++	u8 agc_disp_pol;
++	u8 agc_disp_ratio;
++	__le16 agc_disp_linkMFG;
++
++	__le16 prmbl_punc_bmp;
++	u8 _rsv2[2];
++
++	struct {
++		__le16 wlan_idx;
++		u8 ru_alloc_seg;
++		u8 ru_idx;
++		u8 ldpc;
++		u8 nss;
++		u8 mcs;
++		u8 mu_group_idx;
++		u8 vht_groud_id;
++		u8 vht_up;
++		u8 he_start_stream;
++		u8 he_mu_spatial;
++		__le16 tx_power_alpha;
++		u8 ack_policy;
++		u8 ru_allo_ps160;
++	} usr[16];
++};
++
++struct mt7996_muru_ul {
++	u8 user_num;
++	u8 tx_mode;
++
++	u8 ba_type;
++	u8 _rsv;
++
++	u8 bw;
++	u8 gi_ltf;
++	__le16 ul_len;
++
++	__le16 trig_cnt;
++	u8 pad;
++	u8 trig_type;
++
++	__le16 trig_intv;
++	u8 trig_ta[ETH_ALEN];
++	__le16 ul_ru[16];
++
++	u8 c26[2];
++	__le16 agc_disp_linkMFG;
++
++	u8 agc_disp_mu_len;
++	u8 agc_disp_pol;
++	u8 agc_disp_ratio;
++	u8 agc_disp_pu_idx;
++
++	struct {
++		__le16 wlan_idx;
++		u8 ru_alloc_seg;
++		u8 ru_idx;
++		u8 ldpc;
++		u8 nss;
++		u8 mcs;
++		u8 target_rssi;
++		__le32 trig_pkt_size;
++		u8 ru_allo_ps160;
++		u8 _rsv2[3];
++	} usr[16];
++};
++
++struct mt7996_muru_dbg {
++	/* HE TB RX Debug */
++	__le32 rx_hetb_nonsf_en_bitmap;
++	__le32 rx_hetb_cfg[2];
++};
++
++struct mt7996_muru {
++	__le32 cfg_comm;
++	__le32 cfg_dl;
++	__le32 cfg_ul;
++	__le32 cfg_dbg;
++
++	struct mt7996_muru_comm comm;
++	struct mt7996_muru_dl dl;
++	struct mt7996_muru_ul ul;
++	struct mt7996_muru_dbg dbg;
++};
++
++
++#define MURU_PPDU_HE_TRIG	BIT(2)
++#define MURU_PPDU_HE_MU		BIT(3)
++
++#define MURU_OFDMA_SCH_TYPE_DL	BIT(0)
++#define MURU_OFDMA_SCH_TYPE_UL	BIT(1)
++
++/* Common Config */
++#define MURU_COMM_PPDU_FMT	BIT(0)
++#define MURU_COMM_SCH_TYPE	BIT(1)
++#define MURU_COMM_BAND		BIT(2)
++#define MURU_COMM_WMM		BIT(3)
++#define MURU_COMM_SPE_IDX	BIT(4)
++#define MURU_COMM_PROC_TYPE	BIT(5)
++#define MURU_COMM_SET		(MURU_COMM_PPDU_FMT | MURU_COMM_SCH_TYPE)
++#define MURU_COMM_SET_TM	(MURU_COMM_PPDU_FMT | MURU_COMM_BAND | \
++				 MURU_COMM_WMM | MURU_COMM_SPE_IDX)
++
++/* DL Common config */
++#define MURU_FIXED_DL_TOTAL_USER_CNT	BIT(4)
++
++/* UL Common Config */
++#define MURU_FIXED_UL_TOTAL_USER_CNT	BIT(4)
++
++enum {
++	CAPI_SU,
++	CAPI_MU,
++	CAPI_ER_SU,
++	CAPI_TB,
++	CAPI_LEGACY
++};
++
++enum {
++	CAPI_BASIC,
++	CAPI_BRP,
++	CAPI_MU_BAR,
++	CAPI_MU_RTS,
++	CAPI_BSRP,
++	CAPI_GCR_MU_BAR,
++	CAPI_BQRP,
++	CAPI_NDP_FRP,
++};
++
++enum {
++	MU_DL_ACK_POLICY_MU_BAR = 3,
++	MU_DL_ACK_POLICY_TF_FOR_ACK = 4,
++	MU_DL_ACK_POLICY_SU_BAR = 5,
++};
++
++enum muru_vendor_ctrl {
++	MU_CTRL_UPDATE,
++	MU_CTRL_DL_USER_CNT,
++	MU_CTRL_UL_USER_CNT,
++};
+ #endif
+ 
+ #endif
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 9ba6f00a..477c5c42 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -10,10 +10,31 @@
+ #include "vendor.h"
+ #include "mtk_mcu.h"
+ 
++#ifdef CONFIG_MTK_VENDOR
+ static const struct nla_policy
+ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
+ 	[MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 },
+ 	[MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_MU_CTRL_STRUCT] = {.type = NLA_BINARY },
++};
++
++static const struct nla_policy
++wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMPDU] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
++};
++
++static const struct nla_policy
++wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
++	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
+ };
+ 
+ static const struct nla_policy
+@@ -70,6 +91,17 @@ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
+ 	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
+ };
+ 
++static const struct nla_policy
++rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
++};
++
+ struct mt7996_amnt_data {
+ 	u8 idx;
+ 	u8 addr[ETH_ALEN];
+@@ -84,6 +116,8 @@ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
+ {
+ 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ 	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_MU_CTRL];
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct mt7996_muru *muru;
+ 	int err;
+ 	u8 val8;
+ 	u32 val32 = 0;
+@@ -99,9 +133,17 @@ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
+ 			 FIELD_PREP(RATE_CFG_VAL, val8);
+ 		ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+ 							   mt7996_set_wireless_vif, &val32);
++	} else if (tb[MTK_VENDOR_ATTR_MU_CTRL_STRUCT]) {
++		muru = kzalloc(sizeof(struct mt7996_muru), GFP_KERNEL);
++
++		nla_memcpy(muru, tb[MTK_VENDOR_ATTR_MU_CTRL_STRUCT],
++			   sizeof(struct mt7996_muru));
++
++		err = mt7996_mcu_set_muru_cfg(phy, muru);
++		kfree(muru);
+ 	}
+ 
+-	return 0;
++	return err;
+ }
+ 
+ static int
+@@ -124,6 +166,48 @@ mt7996_vendor_mu_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+ 	return len;
+ }
+ 
++void mt7996_set_wireless_rts_sigta(struct ieee80211_hw *hw, u8 value) {
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++
++	switch (value) {
++	case BW_SIGNALING_STATIC:
++	case BW_SIGNALING_DYNAMIC:
++		mt7996_mcu_set_band_confg(phy, UNI_BAND_CONFIG_RTS_SIGTA_EN, true);
++		mt7996_mcu_set_band_confg(phy, UNI_BAND_CONFIG_DIS_SECCH_CCA_DET, false);
++		break;
++	default:
++		value = BW_SIGNALING_DISABLE;
++		mt7996_mcu_set_band_confg(phy, UNI_BAND_CONFIG_RTS_SIGTA_EN, false);
++		mt7996_mcu_set_band_confg(phy, UNI_BAND_CONFIG_DIS_SECCH_CCA_DET, true);
++		break;
++      }
++
++	phy->rts_bw_sig = value;
++
++	/* Set RTS Threshold to a lower Value */
++	mt7996_mcu_set_rts_thresh(phy, 500);
++}
++
++static int
++mt7996_vendor_wireless_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
++				 struct sk_buff *skb, const void *data, int data_len,
++				 unsigned long *storage)
++{
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	int len = 0;
++
++	if (*storage == 1)
++		return -ENOENT;
++	*storage = 1;
++
++	if (nla_put_u8(skb, MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU,
++		       ieee80211_hw_check(hw, SUPPORTS_AMSDU_IN_AMPDU)))
++	return -ENOMEM;
++	len += 1;
++
++	return len;
++ }
++
+ void mt7996_vendor_amnt_fill_rx(struct mt7996_phy *phy, struct sk_buff *skb)
+ {
+ 	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+@@ -647,6 +731,126 @@ mt7996_vendor_ibf_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+ 	return 1;
+ }
+ 
++static int mt7996_vendor_rfeature_ctrl(struct wiphy *wiphy,
++				       struct wireless_dev *wdev,
++				       const void *data,
++				       int data_len)
++{
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct mt7996_dev *dev = phy->dev;
++	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL];
++	int err;
++	u32 val;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX, data, data_len,
++			rfeature_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	val = CAPI_RFEATURE_CHANGED;
++
++	if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG]) {
++		u8 enable, trig_type;
++		int rem;
++		struct nlattr *cur;
++
++		nla_for_each_nested(cur, tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG], rem) {
++			switch (nla_type(cur)) {
++			case MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN:
++				enable = nla_get_u8(cur);
++				break;
++			case MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE:
++				trig_type = nla_get_u8(cur);
++				break;
++			default:
++				return -EINVAL;
++			};
++		}
++
++		err = mt7996_mcu_set_rfeature_trig_type(phy, enable, trig_type);
++		if (err)
++			return err;
++	} else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY]) {
++		u8 ack_policy;
++
++		ack_policy = nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY]);
++		switch (ack_policy) {
++		case MU_DL_ACK_POLICY_TF_FOR_ACK:
++			return mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SET_MUDL_ACK_POLICY,
++						       ack_policy);
++		default:
++			return 0;
++		}
++	}
++
++	return 0;
++}
++
++static int mt7996_vendor_wireless_ctrl(struct wiphy *wiphy,
++				       struct wireless_dev *wdev,
++				       const void *data,
++				       int data_len)
++{
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct mt7996_dev *dev = phy->dev;
++	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL];
++	int err;
++	u8 val8;
++	u16 val16;
++	u32 val32;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX, data, data_len,
++			wireless_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	val32 = CAPI_WIRELESS_CHANGED;
++
++	if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA]);
++		val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_OFDMA) |
++			 FIELD_PREP(RATE_CFG_VAL, val8);
++		ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
++			mt7996_set_wireless_vif, &val32);
++		if (val8 == 3) /* DL20and80 */
++			mt7996_mcu_set_muru_cmd(dev, UNI_CMD_MURU_SET_20M_DYN_ALGO, 1);
++	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE]) {
++		val16 = nla_get_u16(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE]);
++		hw->max_tx_aggregation_subframes = val16;
++		hw->max_rx_aggregation_subframes = val16;
++	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE]);
++		mt7996_mcu_set_ppdu_tx_type(phy, val8);
++	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA]);
++		if (phy->muru_onoff & OFDMA_UL)
++			mt7996_mcu_set_nusers_ofdma(phy, MU_CTRL_UL_USER_CNT, val8);
++		else
++			mt7996_mcu_set_nusers_ofdma(phy, MU_CTRL_DL_USER_CNT, val8);
++	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO]);
++		val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_MIMO) |
++			 FIELD_PREP(RATE_CFG_VAL, val8);
++		ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
++			mt7996_set_wireless_vif, &val32);
++	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]);
++		dev->cert_mode = val8;
++		mt7996_mcu_set_cert(phy, val8);
++		mt7996_mcu_set_bypass_smthint(phy, val8);
++	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU]);
++		mt7996_set_wireless_amsdu(hw, val8);
++	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA]);
++		mt7996_set_wireless_rts_sigta(hw, val8);
++	}
++
++	return 0;
++}
++
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 	{
+ 		.info = {
+@@ -660,6 +864,18 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 		.policy = mu_ctrl_policy,
+ 		.maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX,
+ 	},
++	{
++		.info = {
++		        .vendor_id = MTK_NL80211_VENDOR_ID,
++		        .subcmd = MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++		        WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_wireless_ctrl,
++		.dumpit = mt7996_vendor_wireless_ctrl_dump,
++		.policy = wireless_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX,
++	},
+ 	{
+ 		.info = {
+ 			.vendor_id = MTK_NL80211_VENDOR_ID,
+@@ -718,6 +934,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 		.policy = ibf_ctrl_policy,
+ 		.maxattr = MTK_VENDOR_ATTR_IBF_CTRL_MAX,
+ 	},
++	{
++		.info = {
++			.vendor_id = MTK_NL80211_VENDOR_ID,
++			.subcmd = MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++			WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_rfeature_ctrl,
++		.policy = rfeature_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX,
++	},
+ };
+ 
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+@@ -727,3 +954,4 @@ void mt7996_vendor_register(struct mt7996_phy *phy)
+ 
+ 	spin_lock_init(&phy->amnt_lock);
+ }
++#endif
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 29ccc050..7011914b 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -3,8 +3,12 @@
+ 
+ #define MTK_NL80211_VENDOR_ID	0x0ce7
+ 
++#ifdef CONFIG_MTK_VENDOR
++
+ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
++	MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL = 0xc3,
++	MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
+ 	MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
+ 	MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
+ 	MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8,
+@@ -60,6 +64,7 @@ enum mtk_vendor_attr_mu_ctrl {
+ 
+ 	MTK_VENDOR_ATTR_MU_CTRL_ONOFF,
+ 	MTK_VENDOR_ATTR_MU_CTRL_DUMP,
++	MTK_VENDOR_ATTR_MU_CTRL_STRUCT,
+ 
+ 	/* keep last */
+ 	NUM_MTK_VENDOR_ATTRS_MU_CTRL,
+@@ -67,6 +72,66 @@ enum mtk_vendor_attr_mu_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_MU_CTRL - 1
+ };
+ 
++enum mtk_capi_control_changed {
++	CAPI_RFEATURE_CHANGED = BIT(16),
++	CAPI_WIRELESS_CHANGED = BIT(17),
++};
++
++enum mtk_vendor_attr_rfeature_ctrl {
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX =
++	NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL - 1
++};
++
++enum mtk_vendor_attr_wireless_ctrl {
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMPDU,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA, /* reserve */
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL - 1
++};
++
++enum mtk_vendor_attr_wireless_dump {
++	MTK_VENDOR_ATTR_WIRELESS_DUMP_UNSPEC,
++
++	MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP,
++	MTK_VENDOR_ATTR_WIRELESS_DUMP_MAX =
++		NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
++};
++
++enum bw_sig {
++	BW_SIGNALING_DISABLE,
++	BW_SIGNALING_STATIC,
++	BW_SIGNALING_DYNAMIC
++};
++
+ enum mtk_vendor_attr_mnt_ctrl {
+ 	MTK_VENDOR_ATTR_AMNT_CTRL_UNSPEC,
+ 
+@@ -138,3 +203,5 @@ enum mtk_vendor_attr_ibf_dump {
+ };
+ 
+ #endif
++
++#endif
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1033-mtk-wifi-mt76-testmode-add-testmode-bf-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1033-mtk-wifi-mt76-testmode-add-testmode-bf-support.patch
new file mode 100644
index 0000000..569965f
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1033-mtk-wifi-mt76-testmode-add-testmode-bf-support.patch
@@ -0,0 +1,1833 @@
+From 5ebdb72f481cab029434e63a70b5c16d9fd2ec64 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 6 Apr 2023 16:40:28 +0800
+Subject: [PATCH 1033/1041] mtk: wifi: mt76: testmode: add testmode bf support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Add iTest additional bf command
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+fw return Gx (5g band) ibf cal struct for both 2G and 5G ibf.
+Therefore, memcpy cannot be used for 2G ibf cal.
+https://gerrit.mediatek.inc/c/neptune/wlan_driver/logan/+/8206056
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt76.h               |   5 +
+ mt76_connac_mcu.h    |   4 +-
+ mt7996/mcu.c         |   8 +-
+ mt7996/mcu.h         |  45 ++-
+ mt7996/mt7996.h      |  12 +-
+ mt7996/mtk_debugfs.c |   6 +-
+ mt7996/mtk_mcu.c     |  79 ++++-
+ mt7996/mtk_mcu.h     | 338 +++++++++++++++++++-
+ mt7996/regs.h        |   3 +
+ mt7996/testmode.c    | 744 +++++++++++++++++++++++++++++++++++++++++--
+ mt7996/testmode.h    |  19 ++
+ testmode.c           |  60 ++++
+ testmode.h           |  53 +++
+ tools/fields.c       |  37 +++
+ 14 files changed, 1354 insertions(+), 59 deletions(-)
+
+diff --git a/mt76.h b/mt76.h
+index 9e8848f7..2a7b0ed9 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -751,6 +751,11 @@ struct mt76_testmode_data {
+ 	u32 tx_time;
+ 	u32 tx_ipg;
+ 
++	u8 txbf_act;
++	u16 txbf_param[8];
++	bool is_txbf_dut;
++	bool bf_en;
++	bool bf_ever_en;
+ 	bool ibf;
+ 	bool ebf;
+ 
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 615c42b1..306e7bee 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -488,7 +488,8 @@ struct sta_rec_bf {
+ 	bool codebook75_mu;
+ 
+ 	u8 he_ltf;
+-	u8 rsv[3];
++	u8 pp_fd_val;
++	u8 rsv[2];
+ } __packed;
+ 
+ struct sta_rec_bfee {
+@@ -1267,6 +1268,7 @@ enum {
+ 	MCU_UNI_CMD_VOW = 0x37,
+ 	MCU_UNI_CMD_PP = 0x38,
+ 	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
++	MCU_UNI_CMD_TESTMODE_TRX_PARAM = 0x42,
+ 	MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
+ 	MCU_UNI_CMD_PRECAL_RESULT = 0x47,
+ 	MCU_UNI_CMD_RRO = 0x57,
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 7f235f91..6ba9c9d5 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -1067,7 +1067,12 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ 	bss->hw_bss_idx = idx;
+ 
+ 	if (vif->type == NL80211_IFTYPE_MONITOR) {
+-		memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
++		struct mt76_testmode_data *td = &phy->test;
++
++		if (!td->bf_en)
++			memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
++		else
++			memcpy(bss->bssid, td->addr[2], ETH_ALEN);
+ 		return 0;
+ 	}
+ 
+@@ -4103,7 +4108,6 @@ int mt7996_mcu_set_ser(struct mt7996_dev *dev, u8 action, u8 val, u8 band)
+ int mt7996_mcu_set_txbf(struct mt7996_dev *dev, u8 action)
+ {
+ #define MT7996_BF_MAX_SIZE	sizeof(union bf_tag_tlv)
+-#define BF_PROCESSING	4
+ 	struct uni_header hdr;
+ 	struct sk_buff *skb;
+ 	struct tlv *tlv;
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index af078edd..054a616b 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -685,6 +685,22 @@ struct bf_sounding_on {
+ 	__le32 snd_period;
+ } __packed;
+ 
++enum sounding_mode {
++	SU_SOUNDING,
++	MU_SOUNDING,
++	SU_PERIODIC_SOUNDING,
++	MU_PERIODIC_SOUNDING,
++	BF_PROCESSING,
++	TXCMD_NONTB_SU_SOUNDING,
++	TXCMD_VHT_MU_SOUNDING,
++	TXCMD_TB_PER_BRP_SOUNDING,
++	TXCMD_TB_SOUNDING,
++
++	/* keep last */
++	NUM_SOUNDING_MODE,
++	SOUNDING_MODE_MAX = NUM_SOUNDING_MODE - 1,
++};
++
+ struct bf_hw_en_status_update {
+ 	__le16 tag;
+ 	__le16 len;
+@@ -710,6 +726,24 @@ union bf_tag_tlv {
+ 	struct bf_mod_en_ctrl bf_mod_en;
+ };
+ 
++enum {
++	BF_SOUNDING_OFF = 0,
++	BF_SOUNDING_ON = 1,
++	BF_DATA_PACKET_APPLY = 2,
++	BF_PFMU_TAG_READ = 5,
++	BF_PFMU_TAG_WRITE = 6,
++	BF_STA_REC_READ = 11,
++	BF_PHASE_CALIBRATION = 12,
++	BF_IBF_PHASE_COMP = 13,
++	BF_PROFILE_WRITE_20M_ALL = 15,
++	BF_HW_EN_UPDATE = 17,
++	BF_MOD_EN_CTRL = 20,
++	BF_FBRPT_DBG_INFO_READ = 23,
++	BF_TXSND_INFO = 24,
++	BF_CMD_TXCMD = 27,
++	BF_CFG_PHY = 28,
++};
++
+ struct ra_rate {
+ 	__le16 wlan_idx;
+ 	u8 mode;
+@@ -771,17 +805,6 @@ enum {
+ #define MUMIMO_UL                      BIT(3)
+ #define MUMIMO_DL_CERT                 BIT(4)
+ 
+-enum {
+-	BF_SOUNDING_ON = 1,
+-	BF_PFMU_TAG_READ = 5,
+-	BF_STA_REC_READ = 11,
+-	BF_HW_EN_UPDATE = 17,
+-	BF_MOD_EN_CTRL = 20,
+-	BF_FBRPT_DBG_INFO_READ = 23,
+-	BF_TXSND_INFO = 24,
+-	BF_CFG_PHY = 28,
+-};
+-
+ enum {
+ 	CMD_BAND_NONE,
+ 	CMD_BAND_24G,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index e1a191ec..b5ce4a55 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -479,6 +479,14 @@ struct mt7996_dev {
+ #ifdef CONFIG_MTK_VENDOR
+ 	bool cert_mode;
+ #endif
++
++#if defined CONFIG_NL80211_TESTMODE || defined CONFIG_MTK_DEBUG
++	struct {
++		void *txbf_phase_cal;
++		void *txbf_pfmu_data;
++		void *txbf_pfmu_tag;
++	} test;
++#endif
+ };
+ 
+ enum {
+@@ -818,7 +826,7 @@ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
+ int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set);
+ void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ int mt7996_mcu_set_dup_wtbl(struct mt7996_dev *dev);
+-int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx);
++int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx, bool bfer);
+ void mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ int mt7996_mcu_set_muru_fixed_rate_enable(struct mt7996_dev *dev, u8 action, int val);
+ int mt7996_mcu_set_muru_fixed_rate_parameter(struct mt7996_dev *dev, u8 action, void *para);
+@@ -830,10 +838,12 @@ int mt7996_mcu_set_rfeature_trig_type(struct mt7996_phy *phy, u8 enable, u8 trig
+ void mt7996_mcu_set_ppdu_tx_type(struct mt7996_phy *phy, u8 ppdu_type);
+ void mt7996_mcu_set_nusers_ofdma(struct mt7996_phy *phy, u8 type, u8 ofdma_user_cnt);
+ void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type);
++void mt7996_tm_update_channel(struct mt7996_phy *phy);
+ #endif
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ int mt7996_dma_rro_init(struct mt7996_dev *dev);
+ #endif /* CONFIG_NET_MEDIATEK_SOC_WED */
+ 
++
+ #endif
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 1530ad79..0fdb911d 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2803,7 +2803,7 @@ mt7996_starec_bf_read_set(void *data, u64 wlan_idx)
+ {
+ 	struct mt7996_phy *phy = data;
+ 
+-	return mt7996_mcu_set_txbf_internal(phy, BF_STA_REC_READ, wlan_idx);
++	return mt7996_mcu_set_txbf_internal(phy, BF_STA_REC_READ, wlan_idx, 0);
+ }
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_starec_bf_read, NULL,
+ 			 mt7996_starec_bf_read_set, "%lld\n");
+@@ -2847,7 +2847,7 @@ mt7996_bf_fbk_rpt_set(void *data, u64 wlan_idx)
+ {
+ 	struct mt7996_phy *phy = data;
+ 
+-	return mt7996_mcu_set_txbf_internal(phy, BF_FBRPT_DBG_INFO_READ, wlan_idx);
++	return mt7996_mcu_set_txbf_internal(phy, BF_FBRPT_DBG_INFO_READ, wlan_idx, 0);
+ }
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_bf_fbk_rpt, NULL,
+ 			 mt7996_bf_fbk_rpt_set, "%lld\n");
+@@ -2857,7 +2857,7 @@ mt7996_bf_pfmu_tag_read_set(void *data, u64 wlan_idx)
+ {
+ 	struct mt7996_phy *phy = data;
+ 
+-	return mt7996_mcu_set_txbf_internal(phy, BF_PFMU_TAG_READ, wlan_idx);
++	return mt7996_mcu_set_txbf_internal(phy, BF_PFMU_TAG_READ, wlan_idx, 1);
+ }
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_bf_pfmu_tag_read, NULL,
+ 			 mt7996_bf_pfmu_tag_read_set, "%lld\n");
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index 3b8fbe42..2d8b08cd 100644
+--- a/mt7996/mtk_mcu.c
++++ b/mt7996/mtk_mcu.c
+@@ -296,7 +296,7 @@ __mt7996_mcu_add_uni_tlv(struct sk_buff *skb, u16 tag, u16 len)
+ 	return ptlv;
+ }
+ 
+-int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx)
++int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx, bool bfer)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+ #define MT7996_MTK_BF_MAX_SIZE	sizeof(struct bf_starec_read)
+@@ -319,9 +319,8 @@ int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx)
+ 
+ 		tlv = __mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req));
+ 		req = (struct bf_pfmu_tag *)tlv;
+-#define BFER 1
+ 		req->pfmu_id = idx;
+-		req->bfer = BFER;
++		req->bfer = bfer;
+ 		req->band_idx = phy->mt76->band_idx;
+ 		break;
+ 	}
+@@ -433,10 +432,36 @@ int mt7996_mcu_set_txbf_snd_info(struct mt7996_phy *phy, void *para)
+ 	return mt76_mcu_skb_send_msg(&phy->dev->mt76, skb, MCU_WM_UNI_CMD(BF), false);
+ }
+ 
++static inline void
++mt7996_ibf_phase_assign(struct mt7996_dev *dev,
++			struct mt7996_ibf_cal_info *cal,
++			struct mt7996_txbf_phase *phase)
++{
++	/* fw return ibf calibrated data with
++	 * the mt7996_txbf_phase_info_5g struct for both 2G and 5G.
++	 * Therefore, memcpy cannot be used here.
++	 */
++	phase_assign(cal->group, m_t0_h, true);
++	phase_assign(cal->group, m_t1_h, true);
++	phase_assign(cal->group, m_t2_h, true);
++	phase_assign(cal->group, m_t2_h_sx2, false);
++	phase_assign_rx(cal->group, r0);
++	phase_assign_rx(cal->group, r1);
++	phase_assign_rx(cal->group, r2);
++	phase_assign_rx(cal->group, r3);
++	phase_assign_rx_g0(cal->group, r2_sx2);
++	phase_assign_rx_g0(cal->group, r3_sx2);
++	phase_assign(cal->group, r0_reserved, false);
++	phase_assign(cal->group, r1_reserved, false);
++	phase_assign(cal->group, r2_reserved, false);
++	phase_assign(cal->group, r3_reserved, false);
++	phase_assign(cal->group, r2_sx2_reserved, false);
++	phase_assign(cal->group, r3_sx2_reserved, false);
++}
++
+ void
+ mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ {
+-#define HE_MODE 3
+ 	struct mt7996_mcu_bf_basic_event *event;
+ 
+ 	event = (struct mt7996_mcu_bf_basic_event *)skb->data;
+@@ -471,13 +496,12 @@ mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 			 tag->t1.nr, tag->t1.nc, tag->t1.ngroup, tag->t1.lm, tag->t1.codebook,
+ 			 tag->t1.mob_cal_en);
+ 
+-		if (tag->t1.lm <= HE_MODE) {
++		if (tag->t1.lm <= BF_LM_HE)
+ 			dev_info(dev->mt76.dev, "RU start = %d, RU end = %d\n",
+ 				 tag->t1.field.ru_start_id, tag->t1.field.ru_end_id);
+-		} else {
++		else
+ 			dev_info(dev->mt76.dev, "PartialBW = %d\n",
+ 				 tag->t1.bw_info.partial_bw_info);
+-		}
+ 
+ 		dev_info(dev->mt76.dev, "Mem Col1 = %d, Mem Row1 = %d, Mem Col2 = %d, Mem Row2 = %d\n",
+ 			 tag->t1.col_id1, tag->t1.row_id1, tag->t1.col_id2, tag->t1.row_id2);
+@@ -731,6 +755,47 @@ mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 
+ 		break;
+ 	}
++	case UNI_EVENT_BF_CAL_PHASE: {
++		struct mt7996_ibf_cal_info *cal;
++		struct mt7996_txbf_phase_out phase_out;
++		struct mt7996_txbf_phase *phase;
++
++		cal = (struct mt7996_ibf_cal_info *)skb->data;
++		phase = (struct mt7996_txbf_phase *)dev->test.txbf_phase_cal;
++		memcpy(&phase_out, &cal->phase_out, sizeof(phase_out));
++		switch (cal->cal_type) {
++		case IBF_PHASE_CAL_NORMAL:
++		case IBF_PHASE_CAL_NORMAL_INSTRUMENT:
++			/* Only calibrate group M */
++			if (cal->group_l_m_n != GROUP_M)
++				break;
++			phase = &phase[cal->group];
++			phase->status = cal->status;
++			dev_info(dev->mt76.dev, "Calibrated result = %d\n", phase->status);
++			dev_info(dev->mt76.dev, "Group %d and Group M\n", cal->group);
++			mt7996_ibf_phase_assign(dev, cal, phase);
++			break;
++		case IBF_PHASE_CAL_VERIFY:
++		case IBF_PHASE_CAL_VERIFY_INSTRUMENT:
++			dev_info(dev->mt76.dev, "Verification result = %d\n", cal->status);
++			break;
++		default:
++			break;
++		}
++
++		dev_info(dev->mt76.dev, "c0_uh = %d, c1_uh = %d, c2_uh = %d, c3_uh = %d\n",
++			 phase_out.c0_uh, phase_out.c1_uh, phase_out.c2_uh, phase_out.c3_uh);
++		dev_info(dev->mt76.dev, "c0_h = %d, c1_h = %d, c2_h = %d, c3_h = %d\n",
++			 phase_out.c0_h, phase_out.c1_h, phase_out.c2_h, phase_out.c3_h);
++		dev_info(dev->mt76.dev, "c0_mh = %d, c1_mh = %d, c2_mh = %d, c3_mh = %d\n",
++			 phase_out.c0_mh, phase_out.c1_mh, phase_out.c2_mh, phase_out.c3_mh);
++		dev_info(dev->mt76.dev, "c0_m = %d, c1_m = %d, c2_m = %d, c3_m = %d\n",
++			 phase_out.c0_m, phase_out.c1_m, phase_out.c2_m, phase_out.c3_m);
++		dev_info(dev->mt76.dev, "c0_l = %d, c1_l = %d, c2_l = %d, c3_l = %d\n",
++			 phase_out.c0_l, phase_out.c1_l, phase_out.c2_l, phase_out.c3_l);
++
++		break;
++	}
+ 	default:
+ 		dev_info(dev->mt76.dev, "%s: unknown bf event tag %d\n",
+ 			 __func__, event->tag);
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index 44cb0327..881afef1 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -176,6 +176,164 @@ struct bf_txsnd_info {
+ 	u8 __rsv[2];
+ } __packed;
+ 
++#define MAX_PHASE_GROUP_NUM	9
++
++struct bf_phase_comp {
++	__le16 tag;
++	__le16 len;
++
++	u8 bw;
++	u8 jp_band;
++	u8 band_idx;
++	bool read_from_e2p;
++	bool disable;
++	u8 group;
++	u8 rsv[2];
++	u8 buf[44];
++} __packed;
++
++struct bf_tx_apply {
++	__le16 tag;
++	__le16 len;
++
++	__le16 wlan_idx;
++	bool ebf;
++	bool ibf;
++	bool mu_txbf;
++	bool phase_cal;
++	u8 rsv[2];
++} __packed;
++
++struct bf_phase_cal {
++	__le16 tag;
++	__le16 len;
++
++	u8 group_l_m_n;
++	u8 group;
++	u8 sx2;
++	u8 cal_type;
++	u8 lna_gain_level;
++	u8 band_idx;
++	u8 rsv[2];
++} __packed;
++
++struct bf_txcmd {
++	__le16 tag;
++	__le16 len;
++
++	u8 action;
++	u8 bf_manual;
++	u8 bf_bit;
++	u8 rsv[5];
++} __packed;
++
++struct bf_pfmu_data_all {
++	__le16 tag;
++	__le16 len;
++
++	u8 pfmu_id;
++	u8 band_idx;
++	u8 rsv[2];
++
++	u8 buf[512];
++} __packed;
++
++#define TXBF_DUT_MAC_SUBADDR		0x22
++#define TXBF_GOLDEN_MAC_SUBADDR		0x11
++
++struct mt7996_tm_bf_req {
++	u8 _rsv[4];
++
++	union {
++		struct bf_sounding_on sounding;
++		struct bf_tx_apply tx_apply;
++		struct bf_pfmu_tag pfmu_tag;
++		struct bf_pfmu_data_all pfmu_data_all;
++		struct bf_phase_cal phase_cal;
++		struct bf_phase_comp phase_comp;
++		struct bf_txcmd txcmd;
++	};
++} __packed;
++
++enum tm_trx_mac_type {
++	TM_TRX_MAC_TX = 1,
++	TM_TRX_MAC_RX,
++	TM_TRX_MAC_TXRX,
++	TM_TRX_MAC_TXRX_RXV,
++	TM_TRX_MAC_RXV,
++	TM_TRX_MAC_RX_RXV,
++};
++
++enum tm_trx_param_idx {
++	TM_TRX_PARAM_RSV,
++	/* MAC */
++	TM_TRX_PARAM_SET_TRX,
++	TM_TRX_PARAM_RX_FILTER,
++	TM_TRX_PARAM_RX_FILTER_PKT_LEN,
++	TM_TRX_PARAM_SLOT_TIME,
++	TM_TRX_PARAM_CLEAN_PERSTA_TXQUEUE,
++	TM_TRX_PARAM_AMPDU_WTBL,
++	TM_TRX_PARAM_MU_RX_AID,
++	TM_TRX_PARAM_PHY_MANUAL_TX,
++
++	/* PHY */
++	TM_TRX_PARAM_RX_PATH,
++	TM_TRX_PARAM_TX_STREAM,
++	TM_TRX_PARAM_TSSI_STATUS,
++	TM_TRX_PARAM_DPD_STATUS,
++	TM_TRX_PARAM_RATE_POWER_OFFSET_ON_OFF,
++	TM_TRX_PARAM_THERMO_COMP_STATUS,
++	TM_TRX_PARAM_FREQ_OFFSET,
++	TM_TRX_PARAM_FAGC_RSSI_PATH,
++	TM_TRX_PARAM_PHY_STATUS_COUNT,
++	TM_TRX_PARAM_RXV_INDEX,
++
++	TM_TRX_PARAM_ANTENNA_PORT,
++	TM_TRX_PARAM_THERMAL_ONOFF,
++	TM_TRX_PARAM_TX_POWER_CONTROL_ALL_RF,
++	TM_TRX_PARAM_RATE_POWER_OFFSET,
++	TM_TRX_PARAM_SLT_CMD_TEST,
++	TM_TRX_PARAM_SKU,
++	TM_TRX_PARAM_POWER_PERCENTAGE_ON_OFF,
++	TM_TRX_PARAM_BF_BACKOFF_ON_OFF,
++	TM_TRX_PARAM_POWER_PERCENTAGE_LEVEL,
++	TM_TRX_PARAM_FRTBL_CFG,
++	TM_TRX_PARAM_PREAMBLE_PUNC_ON_OFF,
++
++	TM_TRX_PARAM_MAX_NUM,
++};
++
++enum trx_action {
++	TM_TRX_ACTION_SET,
++	TM_TRX_ACTION_GET,
++};
++
++struct tm_trx_set {
++	u8 type;
++	u8 enable;
++	u8 band_idx;
++	u8 rsv;
++} __packed;
++
++struct mt7996_tm_trx_req {
++	u8 param_num;
++	u8 _rsv[3];
++
++	__le16 tag;
++	__le16 len;
++
++	__le16 param_idx;
++	u8 band_idx;
++	u8 testmode_en;
++	u8 action;
++	u8 rsv[3];
++
++	u32 data;
++	struct tm_trx_set set_trx;
++
++	u8 buf[220];
++} __packed;
++
+ struct mt7996_mcu_bf_basic_event {
+ 	struct mt7996_mcu_rxd rxd;
+ 
+@@ -381,6 +539,181 @@ struct mt7996_pfmu_tag_event {
+ 	struct mt7996_pfmu_tag2 t2;
+ };
+ 
++struct mt7996_pfmu_tag {
++	struct mt7996_pfmu_tag1 t1;
++	struct mt7996_pfmu_tag2 t2;
++};
++
++enum bf_lm_type {
++	BF_LM_LEGACY,
++	BF_LM_HT,
++	BF_LM_VHT,
++	BF_LM_HE,
++	BF_LM_EHT,
++};
++
++struct mt7996_txbf_phase_out {
++	u8 c0_l;
++	u8 c1_l;
++	u8 c2_l;
++	u8 c3_l;
++	u8 c0_m;
++	u8 c1_m;
++	u8 c2_m;
++	u8 c3_m;
++	u8 c0_mh;
++	u8 c1_mh;
++	u8 c2_mh;
++	u8 c3_mh;
++	u8 c0_h;
++	u8 c1_h;
++	u8 c2_h;
++	u8 c3_h;
++	u8 c0_uh;
++	u8 c1_uh;
++	u8 c2_uh;
++	u8 c3_uh;
++};
++
++struct mt7996_txbf_rx_phase_2g {
++	u8 rx_uh;
++	u8 rx_h;
++	u8 rx_m;
++	u8 rx_l;
++	u8 rx_ul;
++};
++
++struct mt7996_txbf_rx_phase_5g {
++	u8 rx_uh;
++	u8 rx_h;
++	u8 rx_mh;
++	u8 rx_m;
++	u8 rx_l;
++	u8 rx_ul;
++};
++
++struct mt7996_txbf_phase_info_2g {
++	struct mt7996_txbf_rx_phase_2g r0;
++	struct mt7996_txbf_rx_phase_2g r1;
++	struct mt7996_txbf_rx_phase_2g r2;
++	struct mt7996_txbf_rx_phase_2g r3;
++	struct mt7996_txbf_rx_phase_2g r2_sx2;
++	struct mt7996_txbf_rx_phase_2g r3_sx2;
++	u8 m_t0_h;
++	u8 m_t1_h;
++	u8 m_t2_h;
++	u8 m_t2_h_sx2;
++	u8 r0_reserved;
++	u8 r1_reserved;
++	u8 r2_reserved;
++	u8 r3_reserved;
++	u8 r2_sx2_reserved;
++	u8 r3_sx2_reserved;
++};
++
++struct mt7996_txbf_phase_info_5g {
++	struct mt7996_txbf_rx_phase_5g r0;
++	struct mt7996_txbf_rx_phase_5g r1;
++	struct mt7996_txbf_rx_phase_5g r2;
++	struct mt7996_txbf_rx_phase_5g r3;
++	struct mt7996_txbf_rx_phase_2g r2_sx2;	/* no middle-high in r2_sx2 */
++	struct mt7996_txbf_rx_phase_2g r3_sx2;	/* no middle-high in r3_sx2 */
++	u8 m_t0_h;
++	u8 m_t1_h;
++	u8 m_t2_h;
++	u8 m_t2_h_sx2;
++	u8 r0_reserved;
++	u8 r1_reserved;
++	u8 r2_reserved;
++	u8 r3_reserved;
++	u8 r2_sx2_reserved;
++	u8 r3_sx2_reserved;
++};
++
++struct mt7996_txbf_phase {
++	u8 status;
++	union {
++		struct mt7996_txbf_phase_info_2g phase_2g;
++		struct mt7996_txbf_phase_info_5g phase_5g;
++	};
++};
++
++#define phase_assign(group, field, dump, ...)	({						\
++	if (group) {										\
++		phase->phase_5g.field = cal->phase_5g.field;					\
++		if (dump)									\
++			dev_info(dev->mt76.dev, "%s = %d\n", #field, phase->phase_5g.field);	\
++	} else {										\
++		phase->phase_2g.field = cal->phase_5g.field;					\
++		if (dump)									\
++			dev_info(dev->mt76.dev, "%s = %d\n", #field, phase->phase_2g.field);	\
++	}											\
++})
++
++#define phase_assign_rx_g0(group, rx, ...)	({						\
++	phase_assign(group, rx.rx_uh, false);							\
++	phase_assign(group, rx.rx_h, false);							\
++	phase_assign(group, rx.rx_m, false);							\
++	phase_assign(group, rx.rx_l, false);							\
++	phase_assign(group, rx.rx_ul, false);							\
++})
++
++#define phase_assign_rx(group, rx, ...)	({							\
++	if (group) {										\
++		phase_assign(group, rx.rx_uh, true);						\
++		phase_assign(group, rx.rx_h, true);						\
++		phase->phase_5g.rx.rx_mh = cal->phase_5g.rx.rx_mh;				\
++		dev_info(dev->mt76.dev, "%s.rx_mh = %d\n", #rx, phase->phase_5g.rx.rx_mh);	\
++		phase_assign(group, rx.rx_m, true);						\
++		phase_assign(group, rx.rx_l, true);						\
++		phase_assign(group, rx.rx_ul, true);						\
++	} else {										\
++		phase_assign(group, rx.rx_uh, true);						\
++		phase_assign(group, rx.rx_h, true);						\
++		phase_assign(group, rx.rx_m, true);						\
++		phase_assign(group, rx.rx_l, true);						\
++		phase_assign(group, rx.rx_ul, true);						\
++	}											\
++})
++
++#define GROUP_L		0
++#define GROUP_M		1
++#define GROUP_H		2
++
++struct mt7996_pfmu_data {
++	__le16 subc_idx;
++	__le16 phi11;
++	__le16 phi21;
++	__le16 phi31;
++};
++
++struct mt7996_ibf_cal_info {
++	struct mt7996_mcu_bf_basic_event event;
++
++	u8 category_id;
++	u8 group_l_m_n;
++	u8 group;
++	bool sx2;
++	u8 status;
++	u8 cal_type;
++	u8 _rsv[2];
++	struct mt7996_txbf_phase_out phase_out;
++	union {
++		struct mt7996_txbf_phase_info_2g phase_2g;
++		struct mt7996_txbf_phase_info_5g phase_5g;
++	};
++} __packed;
++
++enum {
++	IBF_PHASE_CAL_UNSPEC,
++	IBF_PHASE_CAL_NORMAL,
++	IBF_PHASE_CAL_VERIFY,
++	IBF_PHASE_CAL_NORMAL_INSTRUMENT,
++	IBF_PHASE_CAL_VERIFY_INSTRUMENT,
++};
++
++#define MT7996_TXBF_SUBCAR_NUM	64
++
+ enum {
+ 	UNI_EVENT_BF_PFMU_TAG = 0x5,
+ 	UNI_EVENT_BF_PFMU_DATA = 0x7,
+@@ -395,11 +728,6 @@ enum {
+ 	UNI_EVENT_BF_MAX_NUM
+ };
+ 
+-enum {
+-	UNI_CMD_MURU_FIXED_RATE_CTRL = 0x11,
+-	UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL,
+-};
+-
+ struct uni_muru_mum_set_group_tbl_entry {
+ 	__le16 wlan_idx0;
+ 	__le16 wlan_idx1;
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index e94f9a90..aa04d8d2 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -326,6 +326,9 @@ enum offs_rev {
+ #define MT_ARB_SCR_TX_DISABLE			BIT(8)
+ #define MT_ARB_SCR_RX_DISABLE			BIT(9)
+ 
++#define MT_ARB_TQSAXM0(_band)			MT_WF_ARB(_band, 0x180)
++#define MT_ARB_TQSAXM_ALTX_START_MASK		GENMASK(12, 8)
++
+ /* RMAC: band 0(0x820e5000), band 1(0x820f5000), band 2(0x830e5000), */
+ #define MT_WF_RMAC_BASE(_band)			__BASE(WF_RMAC_BASE, (_band))
+ #define MT_WF_RMAC(_band, ofs)			(MT_WF_RMAC_BASE(_band) + (ofs))
+diff --git a/mt7996/testmode.c b/mt7996/testmode.c
+index 26ae5827..2fb36a97 100644
+--- a/mt7996/testmode.c
++++ b/mt7996/testmode.c
+@@ -23,6 +23,7 @@ enum {
+ 	TM_CHANGED_IPI_THRESHOLD,
+ 	TM_CHANGED_IPI_PERIOD,
+ 	TM_CHANGED_IPI_RESET,
++	TM_CHANGED_TXBF_ACT,
+ 
+ 	/* must be last */
+ 	NUM_TM_CHANGED
+@@ -41,25 +42,31 @@ static const u8 tm_change_map[] = {
+ 	[TM_CHANGED_IPI_THRESHOLD] = MT76_TM_ATTR_IPI_THRESHOLD,
+ 	[TM_CHANGED_IPI_PERIOD] = MT76_TM_ATTR_IPI_PERIOD,
+ 	[TM_CHANGED_IPI_RESET] = MT76_TM_ATTR_IPI_RESET,
++	[TM_CHANGED_TXBF_ACT] = MT76_TM_ATTR_TXBF_ACT,
+ };
+ 
+ static void mt7996_tm_ipi_work(struct work_struct *work);
++static int mt7996_tm_txbf_apply_tx(struct mt7996_phy *phy, u16 wlan_idx,
++				   bool ebf, bool ibf, bool phase_cal);
+ 
+ static u32 mt7996_tm_bw_mapping(enum nl80211_chan_width width, enum bw_mapping_method method)
+ {
+ 	static const u32 width_to_bw[][NUM_BW_MAP] = {
+-		[NL80211_CHAN_WIDTH_40] = {FW_CDBW_40MHZ, TM_CBW_40MHZ, 40,
++		[NL80211_CHAN_WIDTH_40] = {FW_CDBW_40MHZ, TM_CBW_40MHZ, BF_CDBW_40MHZ, 40,
+ 					   FIRST_CONTROL_CHAN_BITMAP_BW40},
+-		[NL80211_CHAN_WIDTH_80] = {FW_CDBW_80MHZ, TM_CBW_80MHZ, 80,
++		[NL80211_CHAN_WIDTH_80] = {FW_CDBW_80MHZ, TM_CBW_80MHZ, BF_CDBW_80MHZ, 80,
+ 					   FIRST_CONTROL_CHAN_BITMAP_BW80},
+-		[NL80211_CHAN_WIDTH_80P80] = {FW_CDBW_8080MHZ, TM_CBW_8080MHZ, 80, 0x0},
+-		[NL80211_CHAN_WIDTH_160] = {FW_CDBW_160MHZ, TM_CBW_160MHZ, 160,
++		[NL80211_CHAN_WIDTH_80P80] = {FW_CDBW_8080MHZ, TM_CBW_8080MHZ, BF_CDBW_8080MHZ,
++					      80, 0x0},
++		[NL80211_CHAN_WIDTH_160] = {FW_CDBW_160MHZ, TM_CBW_160MHZ, BF_CDBW_160MHZ, 160,
+ 					    FIRST_CONTROL_CHAN_BITMAP_BW160},
+-		[NL80211_CHAN_WIDTH_5] = {FW_CDBW_5MHZ, TM_CBW_5MHZ, 5, 0x0},
+-		[NL80211_CHAN_WIDTH_10] = {FW_CDBW_10MHZ, TM_CBW_10MHZ, 10, 0x0},
+-		[NL80211_CHAN_WIDTH_20] = {FW_CDBW_20MHZ, TM_CBW_20MHZ, 20, 0x0},
+-		[NL80211_CHAN_WIDTH_20_NOHT] = {FW_CDBW_20MHZ, TM_CBW_20MHZ, 20, 0x0},
+-		[NL80211_CHAN_WIDTH_320] = {FW_CDBW_320MHZ, TM_CBW_320MHZ, 320, 0x0},
++		[NL80211_CHAN_WIDTH_5] = {FW_CDBW_5MHZ, TM_CBW_5MHZ, BF_CDBW_5MHZ, 5, 0x0},
++		[NL80211_CHAN_WIDTH_10] = {FW_CDBW_10MHZ, TM_CBW_10MHZ, BF_CDBW_10MHZ, 10, 0x0},
++		[NL80211_CHAN_WIDTH_20] = {FW_CDBW_20MHZ, TM_CBW_20MHZ, BF_CDBW_20MHZ, 20, 0x0},
++		[NL80211_CHAN_WIDTH_20_NOHT] = {FW_CDBW_20MHZ, TM_CBW_20MHZ, BF_CDBW_20MHZ,
++						20, 0x0},
++		[NL80211_CHAN_WIDTH_320] = {FW_CDBW_320MHZ, TM_CBW_320MHZ, BF_CDBW_320MHZ,
++					    320, 0x0},
+ 	};
+ 
+ 	if (width >= ARRAY_SIZE(width_to_bw))
+@@ -68,26 +75,26 @@ static u32 mt7996_tm_bw_mapping(enum nl80211_chan_width width, enum bw_mapping_m
+ 	return width_to_bw[width][method];
+ }
+ 
+-static u8 mt7996_tm_rate_to_phy(u8 tx_rate_mode)
++static u8 mt7996_tm_rate_mapping(u8 tx_rate_mode, enum rate_mapping_type type)
+ {
+-	static const u8 rate_to_phy[] = {
+-		[MT76_TM_TX_MODE_CCK] = MT_PHY_TYPE_CCK,
+-		[MT76_TM_TX_MODE_OFDM] = MT_PHY_TYPE_OFDM,
+-		[MT76_TM_TX_MODE_HT] = MT_PHY_TYPE_HT,
+-		[MT76_TM_TX_MODE_VHT] = MT_PHY_TYPE_VHT,
+-		[MT76_TM_TX_MODE_HE_SU] = MT_PHY_TYPE_HE_SU,
+-		[MT76_TM_TX_MODE_HE_EXT_SU] = MT_PHY_TYPE_HE_EXT_SU,
+-		[MT76_TM_TX_MODE_HE_TB] = MT_PHY_TYPE_HE_TB,
+-		[MT76_TM_TX_MODE_HE_MU] = MT_PHY_TYPE_HE_MU,
+-		[MT76_TM_TX_MODE_EHT_SU] = MT_PHY_TYPE_EHT_SU,
+-		[MT76_TM_TX_MODE_EHT_TRIG] = MT_PHY_TYPE_EHT_TRIG,
+-		[MT76_TM_TX_MODE_EHT_MU] = MT_PHY_TYPE_EHT_MU,
++	static const u8 rate_to_phy[][NUM_RATE_MAP] = {
++		[MT76_TM_TX_MODE_CCK] = {MT_PHY_TYPE_CCK, BF_LM_LEGACY},
++		[MT76_TM_TX_MODE_OFDM] = {MT_PHY_TYPE_OFDM, BF_LM_LEGACY},
++		[MT76_TM_TX_MODE_HT] = {MT_PHY_TYPE_HT, BF_LM_HT},
++		[MT76_TM_TX_MODE_VHT] = {MT_PHY_TYPE_VHT, BF_LM_VHT},
++		[MT76_TM_TX_MODE_HE_SU] = {MT_PHY_TYPE_HE_SU, BF_LM_HE},
++		[MT76_TM_TX_MODE_HE_EXT_SU] = {MT_PHY_TYPE_HE_EXT_SU, BF_LM_HE},
++		[MT76_TM_TX_MODE_HE_TB] = {MT_PHY_TYPE_HE_TB, BF_LM_HE},
++		[MT76_TM_TX_MODE_HE_MU] = {MT_PHY_TYPE_HE_MU, BF_LM_HE},
++		[MT76_TM_TX_MODE_EHT_SU] = {MT_PHY_TYPE_EHT_SU, BF_LM_EHT},
++		[MT76_TM_TX_MODE_EHT_TRIG] = {MT_PHY_TYPE_EHT_TRIG, BF_LM_EHT},
++		[MT76_TM_TX_MODE_EHT_MU] = {MT_PHY_TYPE_EHT_MU, BF_LM_EHT},
+ 	};
+ 
+ 	if (tx_rate_mode > MT76_TM_TX_MODE_MAX)
+ 		return -EINVAL;
+ 
+-	return rate_to_phy[tx_rate_mode];
++	return rate_to_phy[tx_rate_mode][type];
+ }
+ 
+ static int
+@@ -239,7 +246,7 @@ mt7996_tm_init(struct mt7996_phy *phy, bool en)
+ 		INIT_DELAYED_WORK(&phy->ipi_work, mt7996_tm_ipi_work);
+ }
+ 
+-static void
++void
+ mt7996_tm_update_channel(struct mt7996_phy *phy)
+ {
+ #define CHAN_FREQ_BW_80P80_TAG		(SET_ID(CHAN_FREQ) | BIT(16))
+@@ -303,7 +310,8 @@ mt7996_tm_set_tx_frames(struct mt7996_phy *phy, bool en)
+ 		mt7996_tm_set(dev, SET_ID(MAC_HEADER), FRAME_CONTROL);
+ 		mt7996_tm_set(dev, SET_ID(SEQ_CTRL), 0);
+ 		mt7996_tm_set(dev, SET_ID(TX_COUNT), td->tx_count);
+-		mt7996_tm_set(dev, SET_ID(TX_MODE), mt7996_tm_rate_to_phy(td->tx_rate_mode));
++		mt7996_tm_set(dev, SET_ID(TX_MODE),
++			      mt7996_tm_rate_mapping(td->tx_rate_mode, RATE_MODE_TO_PHY));
+ 		mt7996_tm_set(dev, SET_ID(TX_RATE), td->tx_rate_idx);
+ 
+ 		if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER))
+@@ -331,7 +339,8 @@ mt7996_tm_set_tx_frames(struct mt7996_phy *phy, bool en)
+ 
+ 		mt7996_tm_set(dev, SET_ID(MAX_PE), 2);
+ 		mt7996_tm_set(dev, SET_ID(HW_TX_MODE), 0);
+-		mt7996_tm_update_channel(phy);
++		if (!td->bf_en)
++			mt7996_tm_update_channel(phy);
+ 
+ 		/* trigger firmware to start TX */
+ 		mt7996_tm_set(dev, SET_ID(COMMAND), RF_CMD(START_TX));
+@@ -373,7 +382,8 @@ mt7996_tm_set_rx_frames(struct mt7996_phy *phy, bool en)
+ 			return;
+ 		}
+ 
+-		mt7996_tm_update_channel(phy);
++		if (!td->bf_en)
++			mt7996_tm_update_channel(phy);
+ 
+ 		if (td->tx_rate_mode >= MT76_TM_TX_MODE_HE_MU) {
+ 			if (td->aid)
+@@ -381,7 +391,8 @@ mt7996_tm_set_rx_frames(struct mt7996_phy *phy, bool en)
+ 			else
+ 				ret = mt7996_tm_set(dev, SET_ID(RX_MU_AID), RX_MU_DISABLE);
+ 		}
+-		mt7996_tm_set(dev, SET_ID(TX_MODE), mt7996_tm_rate_to_phy(td->tx_rate_mode));
++		mt7996_tm_set(dev, SET_ID(TX_MODE),
++			      mt7996_tm_rate_mapping(td->tx_rate_mode, RATE_MODE_TO_PHY));
+ 		mt7996_tm_set(dev, SET_ID(GI), td->tx_rate_sgi);
+ 		mt7996_tm_set_antenna(phy, SET_ID(RX_PATH));
+ 		mt7996_tm_set(dev, SET_ID(MAX_PE), 2);
+@@ -405,7 +416,8 @@ mt7996_tm_set_tx_cont(struct mt7996_phy *phy, bool en)
+ 
+ 	if (en) {
+ 		mt7996_tm_update_channel(phy);
+-		mt7996_tm_set(dev, SET_ID(TX_MODE), mt7996_tm_rate_to_phy(td->tx_rate_mode));
++		mt7996_tm_set(dev, SET_ID(TX_MODE),
++			      mt7996_tm_rate_mapping(td->tx_rate_mode, RATE_MODE_TO_PHY));
+ 		mt7996_tm_set(dev, SET_ID(TX_RATE), td->tx_rate_idx);
+ 		/* fix payload is OFDM */
+ 		mt7996_tm_set(dev, SET_ID(CONT_WAVE_MODE), CONT_WAVE_MODE_OFDM);
+@@ -1047,6 +1059,678 @@ mt7996_tm_set_ipi(struct mt7996_phy *phy)
+ 	return 0;
+ }
+ 
++static int
++mt7996_tm_set_trx_mac(struct mt7996_phy *phy, u8 type, bool en)
++{
++#define UNI_TM_TRX_CTRL 0
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_tm_trx_req req = {
++		.param_num = 1,
++		.tag = cpu_to_le16(UNI_TM_TRX_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.param_idx = cpu_to_le16(TM_TRX_PARAM_SET_TRX),
++		.band_idx = phy->mt76->band_idx,
++		.testmode_en = 1,
++		.action = TM_TRX_ACTION_SET,
++		.set_trx = {
++			.type = type,
++			.enable = en,
++			.band_idx = phy->mt76->band_idx,
++		}
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TESTMODE_TRX_PARAM),
++				 &req, sizeof(req), false);
++}
++
++static int
++mt7996_tm_txbf_init(struct mt7996_phy *phy, u16 *val)
++{
++#define EBF_BBP_RX_OFFSET	0x10280
++#define EBF_BBP_RX_ENABLE	(BIT(0) | BIT(15))
++	struct mt7996_dev *dev = phy->dev;
++	struct mt76_testmode_data *td = &phy->mt76->test;
++	bool enable = val[0];
++	void *phase_cal, *pfmu_data, *pfmu_tag;
++	u8 nss, band_idx = phy->mt76->band_idx;
++	enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20;
++	u8 sub_addr = td->is_txbf_dut ? TXBF_DUT_MAC_SUBADDR : TXBF_GOLDEN_MAC_SUBADDR;
++	u8 peer_addr = td->is_txbf_dut ? TXBF_GOLDEN_MAC_SUBADDR : TXBF_DUT_MAC_SUBADDR;
++	u8 bss_addr = TXBF_DUT_MAC_SUBADDR;
++	u8 addr[ETH_ALEN] = {0x00, sub_addr, sub_addr, sub_addr, sub_addr, sub_addr};
++	u8 bssid[ETH_ALEN] = {0x00, bss_addr, bss_addr, bss_addr, bss_addr, bss_addr};
++	u8 peer_addrs[ETH_ALEN] = {0x00, peer_addr, peer_addr, peer_addr, peer_addr, peer_addr};
++	struct mt7996_vif *mvif = (struct mt7996_vif *)phy->monitor_vif->drv_priv;
++
++	if (!enable) {
++		td->bf_en = false;
++		return 0;
++	}
++
++	if (!dev->test.txbf_phase_cal) {
++		phase_cal = devm_kzalloc(dev->mt76.dev,
++					 sizeof(struct mt7996_txbf_phase) *
++					 MAX_PHASE_GROUP_NUM,
++					 GFP_KERNEL);
++		if (!phase_cal)
++			return -ENOMEM;
++
++		dev->test.txbf_phase_cal = phase_cal;
++	}
++
++	if (!dev->test.txbf_pfmu_data) {
++		pfmu_data = devm_kzalloc(dev->mt76.dev,
++					 sizeof(struct mt7996_pfmu_data) *
++					 MT7996_TXBF_SUBCAR_NUM,
++					 GFP_KERNEL);
++		if (!pfmu_data)
++			return -ENOMEM;
++
++		dev->test.txbf_pfmu_data = pfmu_data;
++	}
++
++	if (!dev->test.txbf_pfmu_tag) {
++		pfmu_tag = devm_kzalloc(dev->mt76.dev,
++					sizeof(struct mt7996_pfmu_tag), GFP_KERNEL);
++		if (!pfmu_tag)
++			return -ENOMEM;
++
++		dev->test.txbf_pfmu_tag = pfmu_tag;
++	}
++
++	td->bf_en = true;
++	dev->ibf = td->ibf;
++	memcpy(td->addr[0], peer_addrs, ETH_ALEN);
++	memcpy(td->addr[1], addr, ETH_ALEN);
++	memcpy(td->addr[2], bssid, ETH_ALEN);
++	memcpy(phy->monitor_vif->addr, addr, ETH_ALEN);
++	mt7996_tm_set_mac_addr(dev, td->addr[0], SET_ID(DA));
++	mt7996_tm_set_mac_addr(dev, td->addr[1], SET_ID(SA));
++	mt7996_tm_set_mac_addr(dev, td->addr[2], SET_ID(BSSID));
++
++	/* bss idx & omac idx should be set to band idx for ibf cal */
++	mvif->mt76.idx = band_idx;
++	dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);
++	mvif->mt76.omac_idx = band_idx;
++	phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
++
++	mt7996_mcu_add_dev_info(phy, phy->monitor_vif, true);
++	mt7996_mcu_add_bss_info(phy, phy->monitor_vif, true);
++
++	if (td->ibf) {
++		if (td->is_txbf_dut) {
++			/* Enable ITxBF Capability */
++			mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);
++			mt7996_tm_set_trx_mac(phy, TM_TRX_MAC_TX, true);
++
++			td->tx_ipg = 999;
++			td->tx_mpdu_len = 1024;
++			td->tx_antenna_mask = phy->mt76->chainmask >> dev->chainshift[band_idx];
++			nss = hweight8(td->tx_antenna_mask);
++			if (nss > 1 && nss <= 4)
++				td->tx_rate_idx = 15 + 8 * (nss - 2);
++			else
++				td->tx_rate_idx = 31;
++		} else {
++			td->tx_antenna_mask = 1;
++			td->tx_mpdu_len = 1024;
++			td->tx_rate_idx = 0;
++			mt76_set(dev, EBF_BBP_RX_OFFSET, EBF_BBP_RX_ENABLE);
++			dev_info(dev->mt76.dev, "Set BBP RX CR = %x\n",
++				 mt76_rr(dev, EBF_BBP_RX_OFFSET));
++		}
++
++		td->tx_rate_mode = MT76_TM_TX_MODE_HT;
++		td->tx_rate_sgi = 0;
++	} else {
++		if (td->is_txbf_dut) {
++			/* Enable ETxBF Capability */
++			mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);
++			td->tx_antenna_mask = phy->mt76->chainmask >> dev->chainshift[band_idx];
++			td->tx_spe_idx = 24 + phy->mt76->band_idx;
++			if (td->tx_rate_mode == MT76_TM_TX_MODE_VHT ||
++			    td->tx_rate_mode == MT76_TM_TX_MODE_HE_SU)
++				mt7996_tm_set(dev, SET_ID(NSS), td->tx_rate_nss);
++
++			mt7996_tm_set(dev, SET_ID(ENCODE_MODE), td->tx_rate_ldpc);
++			mt7996_tm_set(dev, SET_ID(TX_COUNT), td->tx_count);
++		} else {
++			/* Turn On BBP CR for RX */
++			mt76_set(dev, EBF_BBP_RX_OFFSET, EBF_BBP_RX_ENABLE);
++			dev_info(dev->mt76.dev, "Set BBP RX CR = %x\n",
++				 mt76_rr(dev, EBF_BBP_RX_OFFSET));
++
++			td->tx_antenna_mask = 1;
++		}
++		width = phy->mt76->chandef.width;
++
++		if (td->tx_rate_mode == MT76_TM_TX_MODE_EHT_MU)
++			td->tx_rate_mode = MT76_TM_TX_MODE_EHT_SU;
++	}
++	mt76_testmode_param_set(td, MT76_TM_ATTR_TX_ANTENNA);
++
++	mt7996_tm_set(dev, SET_ID(TX_MODE),
++		      mt7996_tm_rate_mapping(td->tx_rate_mode, RATE_MODE_TO_PHY));
++	mt7996_tm_set(dev, SET_ID(TX_RATE), td->tx_rate_idx);
++	mt7996_tm_set(dev, SET_ID(GI), td->tx_rate_sgi);
++	mt7996_tm_set(dev, SET_ID(CBW),
++		      mt7996_tm_bw_mapping(width, BW_MAP_NL_TO_FW));
++	mt7996_tm_set(dev, SET_ID(DBW),
++		      mt7996_tm_bw_mapping(width, BW_MAP_NL_TO_FW));
++	mt7996_tm_set_antenna(phy, SET_ID(TX_PATH));
++	mt7996_tm_set_antenna(phy, SET_ID(RX_PATH));
++	mt7996_tm_set(dev, SET_ID(IPG), td->tx_ipg);
++	mt7996_tm_set(dev, SET_ID(TX_LEN), td->tx_mpdu_len);
++	mt7996_tm_set(dev, SET_ID(TX_TIME), 0);
++	mt7996_tm_set(dev, SET_ID(COMMAND), RF_CMD(TX_COMMIT));
++
++	return 0;
++}
++
++static int
++mt7996_tm_txbf_phase_comp(struct mt7996_phy *phy, u16 *val)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_tm_bf_req req = {
++		.phase_comp = {
++			.tag = cpu_to_le16(BF_IBF_PHASE_COMP),
++			.len = cpu_to_le16(sizeof(req.phase_comp)),
++			.bw = val[0],
++			.jp_band = (val[2] == 1) ? 1 : 0,
++			.band_idx = phy->mt76->band_idx,
++			.read_from_e2p = val[3],
++			.disable = val[4],
++			.group = val[2],
++		}
++	};
++	struct mt7996_txbf_phase *phase = (struct mt7996_txbf_phase *)dev->test.txbf_phase_cal;
++
++	wait_event_timeout(dev->mt76.tx_wait, phase[val[2]].status != 0, HZ);
++	if (val[2])
++		memcpy(req.phase_comp.buf, &phase[val[2]].phase_5g, sizeof(req.phase_comp.buf));
++	else
++		memcpy(req.phase_comp.buf, &phase[val[2]].phase_2g, sizeof(req.phase_comp.buf));
++
++	pr_info("ibf cal process: phase comp info\n");
++	print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1,
++		       &req, sizeof(req), 0);
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF), &req,
++				 sizeof(req), false);
++}
++
++static int
++mt7996_tm_txbf_profile_tag_write(struct mt7996_phy *phy, u8 pfmu_idx, struct mt7996_pfmu_tag *tag)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_tm_bf_req req = {
++		.pfmu_tag = {
++			.tag = cpu_to_le16(BF_PFMU_TAG_WRITE),
++			.len = cpu_to_le16(sizeof(req.pfmu_tag)),
++			.pfmu_id = pfmu_idx,
++			.bfer = true,
++			.band_idx = phy->mt76->band_idx,
++		}
++	};
++
++	memcpy(req.pfmu_tag.buf, tag, sizeof(*tag));
++	wait_event_timeout(dev->mt76.tx_wait, tag->t1.pfmu_idx != 0, HZ);
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF), &req,
++				 sizeof(req), false);
++}
++
++static int
++mt7996_tm_add_txbf_sta(struct mt7996_phy *phy, u8 pfmu_idx, u8 nr, u8 nc, bool ebf)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct mt76_testmode_data *td = &phy->mt76->test;
++	struct {
++		struct sta_req_hdr hdr;
++		struct sta_rec_bf bf;
++	} __packed req = {
++		.hdr = {
++			.bss_idx = phy->mt76->band_idx,
++			.wlan_idx_lo = to_wcid_lo(phy->mt76->band_idx + 1),
++			.tlv_num = 1,
++			.is_tlv_append = 1,
++			.muar_idx = 0,
++			.wlan_idx_hi = to_wcid_hi(phy->mt76->band_idx + 1),
++		},
++		.bf = {
++			.tag = cpu_to_le16(STA_REC_BF),
++			.len = cpu_to_le16(sizeof(req.bf)),
++			.pfmu = cpu_to_le16(pfmu_idx),
++			.sounding_phy = 1,
++			.bf_cap = ebf,
++			.ncol = nc,
++			.nrow = nr,
++			.ibf_timeout = 0xff,
++			.tx_mode = mt7996_tm_rate_mapping(td->tx_rate_mode, RATE_MODE_TO_PHY),
++		},
++	};
++	u8 ndp_rate, ndpa_rate, rept_poll_rate, bf_bw;
++
++	if (td->tx_rate_mode == MT76_TM_TX_MODE_HE_SU ||
++	    td->tx_rate_mode == MT76_TM_TX_MODE_EHT_SU) {
++		rept_poll_rate = 0x49;
++		ndpa_rate = 0x49;
++		ndp_rate = 0;
++	} else if (td->tx_rate_mode == MT76_TM_TX_MODE_VHT) {
++		rept_poll_rate = 0x9;
++		ndpa_rate = 0x9;
++		ndp_rate = 0;
++	} else {
++		rept_poll_rate = 0;
++		ndpa_rate = 0;
++		if (nr == 1)
++			ndp_rate = 8;
++		else if (nr == 2)
++			ndp_rate = 16;
++		else
++			ndp_rate = 24;
++	}
++
++	bf_bw = mt7996_tm_bw_mapping(phy->mt76->chandef.width, BW_MAP_NL_TO_BF);
++	req.bf.ndp_rate = ndp_rate;
++	req.bf.ndpa_rate = ndpa_rate;
++	req.bf.rept_poll_rate = rept_poll_rate;
++	req.bf.bw = bf_bw;
++	req.bf.tx_mode = (td->tx_rate_mode == MT76_TM_TX_MODE_EHT_SU) ? 0xf : req.bf.tx_mode;
++
++	if (ebf) {
++		req.bf.mem[0].row = 0;
++		req.bf.mem[1].row = 1;
++		req.bf.mem[2].row = 2;
++		req.bf.mem[3].row = 3;
++	} else {
++		req.bf.mem[0].row = 4;
++		req.bf.mem[1].row = 5;
++		req.bf.mem[2].row = 6;
++		req.bf.mem[3].row = 7;
++	}
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(STA_REC_UPDATE), &req,
++				 sizeof(req), true);
++}
++
++static int
++mt7996_tm_txbf_profile_update(struct mt7996_phy *phy, u16 *val, bool ebf)
++{
++#define MT_ARB_IBF_ENABLE			(BIT(0) | GENMASK(9, 8))
++	struct mt76_testmode_data *td = &phy->mt76->test;
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
++	u8 pfmu_idx = val[0], nc = val[2], nr;
++	int ret;
++	bool is_atenl = val[5];
++
++	if (td->tx_antenna_mask == 3)
++		nr = 1;
++	else if (td->tx_antenna_mask == 7)
++		nr = 2;
++	else
++		nr = 3;
++
++	memset(tag, 0, sizeof(*tag));
++	tag->t1.pfmu_idx = pfmu_idx;
++	tag->t1.ebf = ebf;
++	tag->t1.nr = nr;
++	tag->t1.nc = nc;
++	tag->t1.invalid_prof = true;
++	tag->t1.data_bw = mt7996_tm_bw_mapping(phy->mt76->chandef.width, BW_MAP_NL_TO_BF);
++	tag->t2.se_idx = td->tx_spe_idx;
++
++	if (ebf) {
++		tag->t1.row_id1 = 0;
++		tag->t1.row_id2 = 1;
++		tag->t1.row_id3 = 2;
++		tag->t1.row_id4 = 3;
++		tag->t1.lm = mt7996_tm_rate_mapping(td->tx_rate_mode, RATE_MODE_TO_LM);
++	} else {
++		tag->t1.row_id1 = 4;
++		tag->t1.row_id2 = 5;
++		tag->t1.row_id3 = 6;
++		tag->t1.row_id4 = 7;
++		tag->t1.lm = mt7996_tm_rate_mapping(MT76_TM_TX_MODE_OFDM, RATE_MODE_TO_LM);
++
++		tag->t2.ibf_timeout = 0xff;
++		tag->t2.ibf_nr = nr;
++		tag->t2.ibf_nc = nc;
++	}
++
++	ret = mt7996_tm_txbf_profile_tag_write(phy, pfmu_idx, tag);
++	if (ret)
++		return ret;
++
++	ret = mt7996_tm_add_txbf_sta(phy, pfmu_idx, nr, nc, ebf);
++	if (ret)
++		return ret;
++
++	if (!is_atenl && !td->ibf) {
++		mt76_set(dev, MT_ARB_TQSAXM0(phy->mt76->band_idx), MT_ARB_TQSAXM_ALTX_START_MASK);
++		dev_info(dev->mt76.dev, "Set TX queue start CR for AX management (0x%x) = 0x%x\n",
++			 MT_ARB_TQSAXM0(phy->mt76->band_idx),
++			 mt76_rr(dev, MT_ARB_TQSAXM0(phy->mt76->band_idx)));
++	} else if (!is_atenl && td->ibf && ebf) {
++		/* iBF's ebf profile update */
++		mt76_set(dev, MT_ARB_TQSAXM0(phy->mt76->band_idx), MT_ARB_IBF_ENABLE);
++		dev_info(dev->mt76.dev, "Set TX queue start CR for AX management (0x%x) = 0x%x\n",
++			 MT_ARB_TQSAXM0(phy->mt76->band_idx),
++			 mt76_rr(dev, MT_ARB_TQSAXM0(phy->mt76->band_idx)));
++	}
++
++	if (!ebf && is_atenl)
++		return mt7996_tm_txbf_apply_tx(phy, 1, false, true, true);
++
++	return 0;
++}
++
++static int
++mt7996_tm_txbf_phase_cal(struct mt7996_phy *phy, u16 *val)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_tm_bf_req req = {
++		.phase_cal = {
++			.tag = cpu_to_le16(BF_PHASE_CALIBRATION),
++			.len = cpu_to_le16(sizeof(req.phase_cal)),
++			.group = val[0],
++			.group_l_m_n = val[1],
++			.sx2 = val[2],
++			.cal_type = val[3],
++			.lna_gain_level = val[4],
++			.band_idx = phy->mt76->band_idx,
++		},
++	};
++	struct mt7996_txbf_phase *phase = (struct mt7996_txbf_phase *)dev->test.txbf_phase_cal;
++
++	/* reset phase status before update phase cal data */
++	phase[req.phase_cal.group].status = 0;
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF), &req,
++				 sizeof(req), false);
++}
++
++static int
++mt7996_tm_txbf_profile_update_all(struct mt7996_phy *phy, u16 *val)
++{
++#define MT7996_TXBF_PFMU_DATA_LEN	(MT7996_TXBF_SUBCAR_NUM * sizeof(struct mt7996_pfmu_data))
++	struct mt76_testmode_data *td = &phy->mt76->test;
++	u8 nss = hweight8(td->tx_antenna_mask);
++	u16 pfmu_idx = val[0];
++	u16 subc_id = val[1];
++	u16 angle11 = val[2];
++	u16 angle21 = val[3];
++	u16 angle31 = val[4];
++	u16 angle41 = val[5];
++	s16 phi11 = 0, phi21 = 0, phi31 = 0;
++	struct mt7996_pfmu_data *pfmu_data;
++
++	if (subc_id > MT7996_TXBF_SUBCAR_NUM - 1)
++		return -EINVAL;
++
++	if (nss == 2) {
++		phi11 = (s16)(angle21 - angle11);
++	} else if (nss == 3) {
++		phi11 = (s16)(angle31 - angle11);
++		phi21 = (s16)(angle31 - angle21);
++	} else {
++		phi11 = (s16)(angle41 - angle11);
++		phi21 = (s16)(angle41 - angle21);
++		phi31 = (s16)(angle41 - angle31);
++	}
++
++	pfmu_data = (struct mt7996_pfmu_data *)phy->dev->test.txbf_pfmu_data;
++	pfmu_data = &pfmu_data[subc_id];
++
++	if (subc_id < 32)
++		pfmu_data->subc_idx = cpu_to_le16(subc_id + 224);
++	else
++		pfmu_data->subc_idx = cpu_to_le16(subc_id - 32);
++
++	pfmu_data->phi11 = cpu_to_le16(phi11);
++	pfmu_data->phi21 = cpu_to_le16(phi21);
++	pfmu_data->phi31 = cpu_to_le16(phi31);
++	if (subc_id == MT7996_TXBF_SUBCAR_NUM - 1) {
++		struct mt7996_dev *dev = phy->dev;
++		struct mt7996_tm_bf_req req = {
++			.pfmu_data_all = {
++				.tag = cpu_to_le16(BF_PROFILE_WRITE_20M_ALL),
++				.len = cpu_to_le16(sizeof(req.pfmu_data_all)),
++				.pfmu_id = pfmu_idx,
++				.band_idx = phy->mt76->band_idx,
++			},
++		};
++
++		memcpy(req.pfmu_data_all.buf, dev->test.txbf_pfmu_data, MT7996_TXBF_PFMU_DATA_LEN);
++
++		return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF),
++					 &req, sizeof(req), true);
++	}
++
++	return 0;
++}
++
++static int
++mt7996_tm_txbf_e2p_update(struct mt7996_phy *phy)
++{
++#define TXBF_PHASE_EEPROM_START_OFFSET		0xc00
++#define TXBF_PHASE_GROUP_EEPROM_OFFSET		0x2e
++	struct mt7996_txbf_phase *phase, *p;
++	struct mt7996_dev *dev = phy->dev;
++	u8 *eeprom = dev->mt76.eeprom.data;
++	u16 offset;
++	int i;
++
++	offset = TXBF_PHASE_EEPROM_START_OFFSET;
++	phase = (struct mt7996_txbf_phase *)dev->test.txbf_phase_cal;
++	for (i = 0; i < MAX_PHASE_GROUP_NUM; i++) {
++		p = &phase[i];
++
++		if (!p->status)
++			continue;
++
++		/* copy phase cal data to eeprom */
++		if (i)
++			memcpy(eeprom + offset, &p->phase_5g, sizeof(p->phase_5g));
++		else
++			memcpy(eeprom + offset, &p->phase_2g, sizeof(p->phase_2g));
++		offset += TXBF_PHASE_GROUP_EEPROM_OFFSET;
++	}
++
++	return 0;
++}
++
++static int
++mt7996_tm_txbf_apply_tx(struct mt7996_phy *phy, u16 wlan_idx, bool ebf,
++			bool ibf, bool phase_cal)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_tm_bf_req req = {
++		.tx_apply = {
++			.tag = cpu_to_le16(BF_DATA_PACKET_APPLY),
++			.len = cpu_to_le16(sizeof(req.tx_apply)),
++			.wlan_idx = cpu_to_le16(wlan_idx),
++			.ebf = ebf,
++			.ibf = ibf,
++			.phase_cal = phase_cal,
++		},
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF), &req, sizeof(req), false);
++}
++
++static int
++mt7996_tm_txbf_set_tx(struct mt7996_phy *phy, u16 *val)
++{
++	bool bf_on = val[0], update = val[3];
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
++	struct mt76_testmode_data *td = &phy->mt76->test;
++
++	if (bf_on) {
++		mt7996_tm_set_rx_frames(phy, false);
++		mt7996_tm_set_tx_frames(phy, false);
++		mt7996_mcu_set_txbf_internal(phy, BF_PFMU_TAG_READ, 2, true);
++		tag->t1.invalid_prof = false;
++		mt7996_tm_txbf_profile_tag_write(phy, 2, tag);
++		td->bf_ever_en = true;
++
++		if (update)
++			mt7996_tm_txbf_apply_tx(phy, 1, 0, 1, 1);
++	} else {
++		if (!td->bf_ever_en) {
++			mt7996_tm_set_rx_frames(phy, false);
++			mt7996_tm_set_tx_frames(phy, false);
++			td->ibf = false;
++			td->ebf = false;
++
++			if (update)
++				mt7996_tm_txbf_apply_tx(phy, 1, 0, 0, 0);
++		} else {
++			td->bf_ever_en = false;
++
++			mt7996_mcu_set_txbf_internal(phy, BF_PFMU_TAG_READ, 2, true);
++			tag->t1.invalid_prof = true;
++			mt7996_tm_txbf_profile_tag_write(phy, 2, tag);
++		}
++	}
++
++	return 0;
++}
++
++static int
++mt7996_tm_trigger_sounding(struct mt7996_phy *phy, u16 *val, bool en)
++{
++	struct mt7996_dev *dev = phy->dev;
++	u8 sounding_mode = val[0];
++	u8 sta_num = val[1];
++	u32 sounding_interval = (u32)val[2] << 2;	/* input unit: 4ms */
++	u16 tag = en ? BF_SOUNDING_ON : BF_SOUNDING_OFF;
++	struct mt7996_tm_bf_req req = {
++		.sounding = {
++			.tag = cpu_to_le16(tag),
++			.len = cpu_to_le16(sizeof(req.sounding)),
++			.snd_mode = sounding_mode,
++			.sta_num = sta_num,
++			.wlan_id = {
++				cpu_to_le16(val[3]),
++				cpu_to_le16(val[4]),
++				cpu_to_le16(val[5]),
++				cpu_to_le16(val[6])
++			},
++			.snd_period = cpu_to_le32(sounding_interval),
++		},
++	};
++
++	if (sounding_mode > SOUNDING_MODE_MAX)
++		return -EINVAL;
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF),
++				 &req, sizeof(req), false);
++}
++
++static int
++mt7996_tm_txbf_txcmd(struct mt7996_phy *phy, u16 *val)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct mt7996_tm_bf_req req = {
++		.txcmd = {
++			.tag = cpu_to_le16(BF_CMD_TXCMD),
++			.len = cpu_to_le16(sizeof(req.txcmd)),
++			.action = val[0],
++			.bf_manual = val[1],
++			.bf_bit = val[2],
++		},
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF), &req, sizeof(req), false);
++}
++
++static int
++mt7996_tm_set_txbf(struct mt7996_phy *phy)
++{
++#define TXBF_IS_DUT_MASK	BIT(0)
++#define TXBF_IBF_MASK		BIT(1)
++	struct mt76_testmode_data *td = &phy->mt76->test;
++	u16 *val = td->txbf_param;
++
++	dev_info(phy->dev->mt76.dev,
++		 "ibf cal process: act = %u, val = %u, %u, %u, %u, %u, %u, %u, %u\n",
++		 td->txbf_act, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]);
++
++	switch (td->txbf_act) {
++	case MT76_TM_TXBF_ACT_GOLDEN_INIT:
++	case MT76_TM_TXBF_ACT_INIT:
++	case MT76_TM_TX_EBF_ACT_GOLDEN_INIT:
++	case MT76_TM_TX_EBF_ACT_INIT:
++		td->ibf = !u32_get_bits(td->txbf_act, TXBF_IBF_MASK);
++		td->ebf = true;
++		td->is_txbf_dut = !!u32_get_bits(td->txbf_act, TXBF_IS_DUT_MASK);
++		return mt7996_tm_txbf_init(phy, val);
++	case MT76_TM_TXBF_ACT_UPDATE_CH:
++		mt7996_tm_update_channel(phy);
++		break;
++	case MT76_TM_TXBF_ACT_PHASE_COMP:
++		return mt7996_tm_txbf_phase_comp(phy, val);
++	case MT76_TM_TXBF_ACT_TX_PREP:
++		return mt7996_tm_txbf_set_tx(phy, val);
++	case MT76_TM_TXBF_ACT_IBF_PROF_UPDATE:
++		return mt7996_tm_txbf_profile_update(phy, val, false);
++	case MT76_TM_TXBF_ACT_EBF_PROF_UPDATE:
++		return mt7996_tm_txbf_profile_update(phy, val, true);
++	case MT76_TM_TXBF_ACT_PHASE_CAL:
++		return mt7996_tm_txbf_phase_cal(phy, val);
++	case MT76_TM_TXBF_ACT_PROF_UPDATE_ALL_CMD:
++	case MT76_TM_TXBF_ACT_PROF_UPDATE_ALL:
++		return mt7996_tm_txbf_profile_update_all(phy, val);
++	case MT76_TM_TXBF_ACT_E2P_UPDATE:
++		return mt7996_tm_txbf_e2p_update(phy);
++	case MT76_TM_TXBF_ACT_APPLY_TX: {
++		u16 wlan_idx = val[0];
++		bool ebf = !!val[1], ibf = !!val[2], phase_cal = !!val[4];
++
++		return mt7996_tm_txbf_apply_tx(phy, wlan_idx, ebf, ibf, phase_cal);
++	}
++	case MT76_TM_TXBF_ACT_TRIGGER_SOUNDING:
++		return mt7996_tm_trigger_sounding(phy, val, true);
++	case MT76_TM_TXBF_ACT_STOP_SOUNDING:
++		memset(val, 0, sizeof(td->txbf_param));
++		return mt7996_tm_trigger_sounding(phy, val, false);
++	case MT76_TM_TXBF_ACT_PROFILE_TAG_READ:
++	case MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE:
++	case MT76_TM_TXBF_ACT_PROFILE_TAG_INVALID: {
++		u8 pfmu_idx = val[0];
++		bool bfer = !!val[1];
++		struct mt7996_dev *dev = phy->dev;
++		struct mt7996_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
++
++		if (!tag) {
++			dev_err(dev->mt76.dev,
++				"pfmu tag is not initialized!\n");
++			return 0;
++		}
++
++		if (td->txbf_act == MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE)
++			return mt7996_tm_txbf_profile_tag_write(phy, pfmu_idx, tag);
++		else if (td->txbf_act == MT76_TM_TXBF_ACT_PROFILE_TAG_READ)
++			return mt7996_mcu_set_txbf_internal(phy, BF_PFMU_TAG_READ, pfmu_idx, bfer);
++
++		tag->t1.invalid_prof = !!val[0];
++
++		return 0;
++	}
++	case MT76_TM_TXBF_ACT_STA_REC_READ:
++		return mt7996_mcu_set_txbf_internal(phy, BF_STA_REC_READ, val[0], 0);
++	case MT76_TM_TXBF_ACT_TXCMD:
++		return mt7996_tm_txbf_txcmd(phy, val);
++	default:
++		break;
++	};
++
++	return 0;
++}
++
+ static void
+ mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
+ {
+@@ -1086,6 +1770,8 @@ mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
+ 		mt7996_tm_set_ipi(phy);
+ 	if (changed & BIT(TM_CHANGED_IPI_RESET))
+ 		mt7996_tm_ipi_hist_ctrl(phy, NULL, RDD_SET_IPI_HIST_RESET);
++	if (changed & BIT(TM_CHANGED_TXBF_ACT))
++		mt7996_tm_set_txbf(phy);
+ }
+ 
+ static int
+diff --git a/mt7996/testmode.h b/mt7996/testmode.h
+index 78662b2e..f97ccb26 100644
+--- a/mt7996/testmode.h
++++ b/mt7996/testmode.h
+@@ -27,6 +27,17 @@ enum {
+ 	FW_CDBW_8080MHZ,
+ };
+ 
++enum {
++	BF_CDBW_20MHZ,
++	BF_CDBW_40MHZ,
++	BF_CDBW_80MHZ,
++	BF_CDBW_160MHZ,
++	BF_CDBW_320MHZ,
++	BF_CDBW_10MHZ = BF_CDBW_320MHZ,
++	BF_CDBW_5MHZ,
++	BF_CDBW_8080MHZ,
++};
++
+ #define FIRST_CONTROL_CHAN_BITMAP_BW40		0x5555555
+ #define FIRST_CONTROL_CHAN_BITMAP_BW80		0x111111
+ #define FIRST_CONTROL_CHAN_BITMAP_BW160		0x100101
+@@ -34,12 +45,20 @@ enum {
+ enum bw_mapping_method {
+ 	BW_MAP_NL_TO_FW,
+ 	BW_MAP_NL_TO_TM,
++	BW_MAP_NL_TO_BF,
+ 	BW_MAP_NL_TO_MHZ,
+ 	BW_MAP_NL_TO_CONTROL_BITMAP_5G,
+ 
+ 	NUM_BW_MAP,
+ };
+ 
++enum rate_mapping_type {
++	RATE_MODE_TO_PHY,
++	RATE_MODE_TO_LM,
++
++	NUM_RATE_MAP,
++};
++
+ struct tm_cal_param {
+ 	__le32 func_data;
+ 	u8 band_idx;
+diff --git a/testmode.c b/testmode.c
+index 805ad83c..7b8f9e66 100644
+--- a/testmode.c
++++ b/testmode.c
+@@ -462,6 +462,42 @@ out:
+ 	return err;
+ }
+ 
++static int
++mt76_testmode_txbf_profile_update_all_cmd(struct mt76_phy *phy, struct nlattr **tb, u32 state)
++{
++#define PARAM_UNIT	5
++	static u8 pfmu_idx;
++	struct mt76_testmode_data *td = &phy->test;
++	struct mt76_dev *dev = phy->dev;
++	struct nlattr *cur;
++	u16 tmp_val[PARAM_UNIT], *val = td->txbf_param;
++	int idx, rem, ret, i = 0;
++
++	memset(td->txbf_param, 0, sizeof(td->txbf_param));
++	nla_for_each_nested(cur, tb[MT76_TM_ATTR_TXBF_PARAM], rem) {
++		if (nla_len(cur) != 2)
++			return -EINVAL;
++		idx = i % PARAM_UNIT;
++		tmp_val[idx] = nla_get_u16(cur);
++		if (idx == 1 && (tmp_val[idx] == 0xf0 || tmp_val[idx] == 0xff)) {
++			pfmu_idx = tmp_val[0];
++			return 0;
++		}
++		if (idx == PARAM_UNIT - 1) {
++			val[0] = pfmu_idx;
++			memcpy(val + 1, tmp_val, sizeof(tmp_val));
++			if (dev->test_ops->set_params) {
++				ret = dev->test_ops->set_params(phy, tb, state);
++				if (ret)
++					return ret;
++			}
++		}
++		i++;
++	}
++
++	return 0;
++}
++
+ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 		      void *data, int len)
+ {
+@@ -607,6 +643,30 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 		}
+ 	}
+ 
++	if (tb[MT76_TM_ATTR_TXBF_ACT]) {
++		struct nlattr *cur;
++		int rem, idx = 0;
++
++		if (!tb[MT76_TM_ATTR_TXBF_PARAM] ||
++		    mt76_tm_get_u8(tb[MT76_TM_ATTR_TXBF_ACT], &td->txbf_act,
++				   0, MT76_TM_TXBF_ACT_MAX))
++			goto out;
++
++		if (td->txbf_act == MT76_TM_TXBF_ACT_PROF_UPDATE_ALL_CMD) {
++			err = mt76_testmode_txbf_profile_update_all_cmd(phy, tb, state);
++			goto out;
++		}
++
++		memset(td->txbf_param, 0, sizeof(td->txbf_param));
++		nla_for_each_nested(cur, tb[MT76_TM_ATTR_TXBF_PARAM], rem) {
++			if (nla_len(cur) != 2 ||
++			    idx >= ARRAY_SIZE(td->txbf_param))
++				goto out;
++
++			td->txbf_param[idx++] = nla_get_u16(cur);
++		}
++	}
++
+ 	if (dev->test_ops->set_params) {
+ 		err = dev->test_ops->set_params(phy, tb, state);
+ 		if (err)
+diff --git a/testmode.h b/testmode.h
+index 5d677f8c..bda7624a 100644
+--- a/testmode.h
++++ b/testmode.h
+@@ -286,6 +286,59 @@ enum mt76_testmode_eeprom_action {
+ 	MT76_TM_EEPROM_ACTION_MAX = NUM_MT76_TM_EEPROM_ACTION - 1,
+ };
+ 
++/**
++ * enum mt76_testmode_txbf_act - txbf action
++ *
++ * @MT76_TM_TXBF_ACT_GOLDEN_INIT: init ibf setting for golden device
++ * @MT76_TM_TXBF_ACT_INIT: init ibf setting for DUT
++ * @MT76_TM_TX_EBF_ACT_GOLDEN_INIT: init ebf setting for golden device
++ * @MT76_TM_TX_EBF_ACT_INIT: init ebf setting for DUT
++ * @MT76_TM_TXBF_ACT_UPDATE_CH: update channel info
++ * @MT76_TM_TXBF_ACT_PHASE_COMP: txbf phase compensation
++ * @MT76_TM_TXBF_ACT_TX_PREP: TX preparation for txbf
++ * @MT76_TM_TXBF_ACT_IBF_PROF_UPDATE: update ibf profile (pfmu tag, bf sta record)
++ * @MT76_TM_TXBF_ACT_EBF_PROF_UPDATE: update ebf profile
++ * @MT76_TM_TXBF_ACT_APPLY_TX: apply TX setting for txbf
++ * @MT76_TM_TXBF_ACT_PHASE_CAL: perform txbf phase calibration
++ * @MT76_TM_TXBF_ACT_PROF_UPDATE_ALL: update bf profile via instrument
++ * @MT76_TM_TXBF_ACT_PROF_UPDATE_ALL_CMD: update bf profile via instrument
++ * @MT76_TM_TXBF_ACT_E2P_UPDATE: write back txbf calibration result to eeprom
++ * @MT76_TM_TXBF_ACT_TRIGGER_SOUNDING: trigger beamformer to send sounding packet
++ * @MT76_TM_TXBF_ACT_STOP_SOUNDING: stop sending sounding packet
++ * @MT76_TM_TXBF_ACT_PROFILE_TAG_READ: read pfmu tag
++ * @MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE: update pfmu tag
++ * @MT76_TM_TXBF_ACT_PROFILE_TAG_INVALID: invalidate pfmu tag
++ * @MT76_TM_TXBF_ACT_STA_REC_READ: read bf sta record
++ * @MT76_TM_TXBF_ACT_TXCMD: configure txcmd bf bit manually
++ */
++enum mt76_testmode_txbf_act {
++	MT76_TM_TXBF_ACT_GOLDEN_INIT,
++	MT76_TM_TXBF_ACT_INIT,
++	MT76_TM_TX_EBF_ACT_GOLDEN_INIT,
++	MT76_TM_TX_EBF_ACT_INIT,
++	MT76_TM_TXBF_ACT_UPDATE_CH,
++	MT76_TM_TXBF_ACT_PHASE_COMP,
++	MT76_TM_TXBF_ACT_TX_PREP,
++	MT76_TM_TXBF_ACT_IBF_PROF_UPDATE,
++	MT76_TM_TXBF_ACT_EBF_PROF_UPDATE,
++	MT76_TM_TXBF_ACT_APPLY_TX,
++	MT76_TM_TXBF_ACT_PHASE_CAL,
++	MT76_TM_TXBF_ACT_PROF_UPDATE_ALL,
++	MT76_TM_TXBF_ACT_PROF_UPDATE_ALL_CMD,
++	MT76_TM_TXBF_ACT_E2P_UPDATE,
++	MT76_TM_TXBF_ACT_TRIGGER_SOUNDING,
++	MT76_TM_TXBF_ACT_STOP_SOUNDING,
++	MT76_TM_TXBF_ACT_PROFILE_TAG_READ,
++	MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE,
++	MT76_TM_TXBF_ACT_PROFILE_TAG_INVALID,
++	MT76_TM_TXBF_ACT_STA_REC_READ,
++	MT76_TM_TXBF_ACT_TXCMD,
++
++	/* keep last */
++	NUM_MT76_TM_TXBF_ACT,
++	MT76_TM_TXBF_ACT_MAX = NUM_MT76_TM_TXBF_ACT - 1,
++};
++
+ extern const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS];
+ 
+ #endif
+diff --git a/tools/fields.c b/tools/fields.c
+index 77696ce7..f793d1a5 100644
+--- a/tools/fields.c
++++ b/tools/fields.c
+@@ -44,6 +44,30 @@ static const char * const testmode_offchan_bw[] = {
+ 	[NL80211_CHAN_WIDTH_160] = "160",
+ };
+ 
++static const char * const testmode_txbf_act[] = {
++	[MT76_TM_TXBF_ACT_GOLDEN_INIT] = "golden_init",
++	[MT76_TM_TXBF_ACT_INIT] = "init",
++	[MT76_TM_TX_EBF_ACT_GOLDEN_INIT] = "ebf_golden_init",
++	[MT76_TM_TX_EBF_ACT_INIT] = "ebf_init",
++	[MT76_TM_TXBF_ACT_UPDATE_CH] = "update_ch",
++	[MT76_TM_TXBF_ACT_PHASE_COMP] = "phase_comp",
++	[MT76_TM_TXBF_ACT_TX_PREP] = "tx_prep",
++	[MT76_TM_TXBF_ACT_IBF_PROF_UPDATE] = "ibf_prof_update",
++	[MT76_TM_TXBF_ACT_EBF_PROF_UPDATE] = "ebf_prof_update",
++	[MT76_TM_TXBF_ACT_APPLY_TX] = "apply_tx",
++	[MT76_TM_TXBF_ACT_PHASE_CAL] = "phase_cal",
++	[MT76_TM_TXBF_ACT_PROF_UPDATE_ALL] = "prof_update",
++	[MT76_TM_TXBF_ACT_PROF_UPDATE_ALL_CMD] = "prof_update_all",
++	[MT76_TM_TXBF_ACT_E2P_UPDATE] = "e2p_update",
++	[MT76_TM_TXBF_ACT_TRIGGER_SOUNDING] = "trigger_sounding",
++	[MT76_TM_TXBF_ACT_STOP_SOUNDING] = "stop_sounding",
++	[MT76_TM_TXBF_ACT_PROFILE_TAG_READ] = "pfmu_tag_read",
++	[MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE] = "pfmu_tag_write",
++	[MT76_TM_TXBF_ACT_PROFILE_TAG_INVALID] = "set_invalid_prof",
++	[MT76_TM_TXBF_ACT_STA_REC_READ] = "sta_rec_read",
++	[MT76_TM_TXBF_ACT_TXCMD] = "txcmd",
++};
++
+ static void print_enum(const struct tm_field *field, struct nlattr *attr)
+ {
+ 	unsigned int i = nla_get_u8(attr);
+@@ -94,6 +118,17 @@ static void print_s8(const struct tm_field *field, struct nlattr *attr)
+ 	printf("%d", (int8_t)nla_get_u8(attr));
+ }
+ 
++static bool parse_u16_hex(const struct tm_field *field, int idx,
++			  struct nl_msg *msg, const char *val)
++{
++	return !nla_put_u16(msg, idx, strtoul(val, NULL, 16));
++}
++
++static void print_u16_hex(const struct tm_field *field, struct nlattr *attr)
++{
++	printf("%d", nla_get_u16(attr));
++}
++
+ static bool parse_u32(const struct tm_field *field, int idx,
+ 		      struct nl_msg *msg, const char *val)
+ {
+@@ -399,6 +434,8 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+ 	FIELD(u8, AID, "aid"),
+ 	FIELD(u8, RU_ALLOC, "ru_alloc"),
+ 	FIELD(u8, RU_IDX, "ru_idx"),
++	FIELD_ENUM(TXBF_ACT, "txbf_act", testmode_txbf_act),
++	FIELD_ARRAY(u16_hex, TXBF_PARAM, "txbf_param"),
+ 	FIELD(u8, OFF_CH_SCAN_CH, "offchan_ch"),
+ 	FIELD(u8, OFF_CH_SCAN_CENTER_CH, "offchan_center_ch"),
+ 	FIELD_ENUM(OFF_CH_SCAN_BW, "offchan_bw", testmode_offchan_bw),
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1034-mtk-wifi-mt76-mt7996-add-zwdfs-cert-mode.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1034-mtk-wifi-mt76-mt7996-add-zwdfs-cert-mode.patch
new file mode 100644
index 0000000..45a2131
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1034-mtk-wifi-mt76-mt7996-add-zwdfs-cert-mode.patch
@@ -0,0 +1,221 @@
+From b7bac1d2e4c144961ffd4b96a7fe9c5ea56bb1f3 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 22 Sep 2023 12:33:06 +0800
+Subject: [PATCH 1034/1041] mtk: wifi: mt76: mt7996: add zwdfs cert mode
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/mcu.c    | 44 ++++++++++++++++++++++++++++++++------------
+ mt7996/mcu.h    | 14 ++++++++++++++
+ mt7996/mt7996.h |  5 +++++
+ mt7996/vendor.c | 37 +++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h | 12 ++++++++++++
+ 5 files changed, 100 insertions(+), 12 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 6ba9c9d5..55e8cb1e 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -4501,18 +4501,7 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable)
+ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+ 		       u8 rx_sel, u8 val)
+ {
+-	struct {
+-		u8 _rsv[4];
+-
+-		__le16 tag;
+-		__le16 len;
+-
+-		u8 ctrl;
+-		u8 rdd_idx;
+-		u8 rdd_rx_sel;
+-		u8 val;
+-		u8 rsv[4];
+-	} __packed req = {
++	struct mt7996_rdd_ctrl req = {
+ 		.tag = cpu_to_le16(UNI_RDD_CTRL_PARM),
+ 		.len = cpu_to_le16(sizeof(req) - 4),
+ 		.ctrl = cmd,
+@@ -4525,6 +4514,37 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+ 				 &req, sizeof(req), true);
+ }
+ 
++int mt7996_mcu_rdd_background_disable_timer(struct mt7996_dev *dev, bool disable_timer)
++{
++	struct mt7996_rdd_ctrl req = {
++		.tag = cpu_to_le16(UNI_RDD_CTRL_PARM),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.ctrl = RDD_DISABLE_ZW_TIMER,
++		.rdd_idx = MT_RX_SEL2,
++		.disable_timer = disable_timer,
++	};
++
++	if (!is_mt7996(&dev->mt76) ||
++	    (mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) % 2))
++		return 0;
++
++	switch (dev->mt76.region) {
++	case NL80211_DFS_ETSI:
++		req.val = 0;
++		break;
++	case NL80211_DFS_JP:
++		req.val = 2;
++		break;
++	case NL80211_DFS_FCC:
++	default:
++		req.val = 1;
++		break;
++	}
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RDD_CTRL),
++				 &req, sizeof(req), true);
++}
++
+ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+ 				     struct ieee80211_vif *vif,
+ 				     struct ieee80211_sta *sta)
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 054a616b..398bf3d2 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -119,6 +119,20 @@ struct mt7996_mcu_rdd_report {
+ 	} hw_pulse[32];
+ } __packed;
+ 
++struct mt7996_rdd_ctrl {
++	u8 _rsv[4];
++
++	__le16 tag;
++	__le16 len;
++
++	u8 ctrl;
++	u8 rdd_idx;
++	u8 rdd_rx_sel;
++	u8 val;
++	u8 disable_timer;
++	u8 rsv[3];
++} __packed;
++
+ struct mt7996_mcu_background_chain_ctrl {
+ 	u8 _rsv[4];
+ 
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index b5ce4a55..339d9890 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -516,8 +516,11 @@ enum mt7996_rdd_cmd {
+ 	RDD_READ_PULSE,
+ 	RDD_RESUME_BF,
+ 	RDD_IRQ_OFF,
++	RDD_DISABLE_ZW_TIMER,
+ };
+ 
++#define RDD_ZW_TIMER_OFF	BIT(31)
++
+ static inline struct mt7996_phy *
+ mt7996_hw_phy(struct ieee80211_hw *hw)
+ {
+@@ -659,6 +662,8 @@ int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable);
+ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
+ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+ 		       u8 rx_sel, u8 val);
++int mt7996_mcu_rdd_background_disable_timer(struct mt7996_dev *dev,
++					    bool disable_timer);
+ int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
+ 				     struct cfg80211_chan_def *chandef);
+ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 477c5c42..c7fd3278 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -102,6 +102,11 @@ rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
+ 	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
+ };
+ 
++static const struct nla_policy
++background_radar_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL] = {
++	[MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MODE] = {.type = NLA_U8 },
++};
++
+ struct mt7996_amnt_data {
+ 	u8 idx;
+ 	u8 addr[ETH_ALEN];
+@@ -851,6 +856,27 @@ static int mt7996_vendor_wireless_ctrl(struct wiphy *wiphy,
+ 	return 0;
+ }
+ 
++static int mt7996_vendor_background_radar_mode_ctrl(struct wiphy *wiphy,
++						    struct wireless_dev *wdev,
++						    const void *data,
++						    int data_len)
++{
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	struct mt7996_dev *dev = mt7996_hw_dev(hw);
++	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL];
++	int err;
++	u8 background_radar_mode;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MAX, data, data_len,
++			background_radar_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	background_radar_mode = nla_get_u8(tb[MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MODE]);
++
++	return mt7996_mcu_rdd_background_disable_timer(dev, !!background_radar_mode);
++}
++
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 	{
+ 		.info = {
+@@ -945,6 +971,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 		.policy = rfeature_ctrl_policy,
+ 		.maxattr = MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX,
+ 	},
++	{
++		.info = {
++			.vendor_id = MTK_NL80211_VENDOR_ID,
++			.subcmd = MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++			WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_background_radar_mode_ctrl,
++		.policy = background_radar_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MAX,
++	},
+ };
+ 
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 7011914b..920b6e6a 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -14,6 +14,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8,
+ 	MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
++	MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
+ };
+ 
+ enum mtk_vendor_attr_edcca_ctrl {
+@@ -126,6 +127,17 @@ enum mtk_vendor_attr_wireless_dump {
+ 		NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
+ };
+ 
++enum mtk_vendor_attr_background_radar_ctrl {
++	MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MODE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL,
++	MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL - 1
++};
++
+ enum bw_sig {
+ 	BW_SIGNALING_DISABLE,
+ 	BW_SIGNALING_STATIC,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1035-mtk-wifi-mt76-testmode-add-channel-68-96.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1035-mtk-wifi-mt76-testmode-add-channel-68-96.patch
new file mode 100644
index 0000000..ada50df
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1035-mtk-wifi-mt76-testmode-add-channel-68-96.patch
@@ -0,0 +1,248 @@
+From 1df8b15784e507963fa58fd3ebd81af2f3953f7d Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Mon, 11 Sep 2023 14:43:07 +0800
+Subject: [PATCH 1035/1041] mtk: wifi: mt76: testmode: add channel 68 & 96
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Add all the channel between 68 & 96 since ibf 5g channel group 3 will use channel 84.
+Also, "mtk: wifi: mt76: testmode: add channel 68 & 96" can be
+merged into to "mtk: wifi: mt76: testmode: add basic testmode support"
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Fix 5g channel list size
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mac80211.c        |  9 +++++++++
+ mt7996/eeprom.c   | 49 +++++++++++++++++++++++++++++++++++++++++++++--
+ mt7996/eeprom.h   |  2 ++
+ mt7996/mcu.c      | 10 +++++++++-
+ mt7996/testmode.c | 15 ++++++++++++---
+ mt7996/testmode.h |  6 +++---
+ 6 files changed, 82 insertions(+), 9 deletions(-)
+
+diff --git a/mac80211.c b/mac80211.c
+index 45791f6e..f74f6e85 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -35,6 +35,15 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
+ 	CHAN5G(60, 5300),
+ 	CHAN5G(64, 5320),
+ 
++	CHAN5G(68, 5340),
++	CHAN5G(72, 5360),
++	CHAN5G(76, 5380),
++	CHAN5G(80, 5400),
++	CHAN5G(84, 5420),
++	CHAN5G(88, 5440),
++	CHAN5G(92, 5460),
++	CHAN5G(96, 5480),
++
+ 	CHAN5G(100, 5500),
+ 	CHAN5G(104, 5520),
+ 	CHAN5G(108, 5540),
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 372a822f..cff1b875 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -18,6 +18,17 @@ const struct ieee80211_channel dpd_2g_ch_list_bw20[] = {
+ 	CHAN2G(11, 2462)
+ };
+ 
++const struct ieee80211_channel dpd_5g_skip_ch_list[] = {
++	CHAN5G(68, 5340),
++	CHAN5G(72, 5360),
++	CHAN5G(76, 5380),
++	CHAN5G(80, 5400),
++	CHAN5G(84, 5420),
++	CHAN5G(88, 5440),
++	CHAN5G(92, 5460),
++	CHAN5G(96, 5480)
++};
++
+ const struct ieee80211_channel dpd_5g_ch_list_bw160[] = {
+ 	CHAN5G(50, 5250),
+ 	CHAN5G(114, 5570),
+@@ -44,6 +55,7 @@ const struct ieee80211_channel dpd_6g_ch_list_bw320[] = {
+ };
+ 
+ const u32 dpd_2g_bw20_ch_num = ARRAY_SIZE(dpd_2g_ch_list_bw20);
++const u32 dpd_5g_skip_ch_num = ARRAY_SIZE(dpd_5g_skip_ch_list);
+ const u32 dpd_5g_bw160_ch_num = ARRAY_SIZE(dpd_5g_ch_list_bw160);
+ const u32 dpd_6g_bw160_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw160);
+ const u32 dpd_6g_bw320_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw320);
+@@ -135,8 +147,8 @@ mt7996_get_dpd_per_band_size(struct mt7996_dev *dev, enum nl80211_band band)
+ 	if (band == NL80211_BAND_2GHZ)
+ 		dpd_size = dpd_2g_bw20_ch_num * DPD_PER_CH_BW20_SIZE;
+ 	else if (band == NL80211_BAND_5GHZ)
+-		dpd_size = mphy->sband_5g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
+-			   dpd_5g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
++		dpd_size = (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
++			   DPD_PER_CH_BW20_SIZE + dpd_5g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+ 	else
+ 		dpd_size = mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
+ 			   (dpd_6g_bw160_ch_num + dpd_6g_bw320_ch_num) * DPD_PER_CH_GT_BW20_SIZE;
+@@ -396,6 +408,39 @@ out:
+ 	return ret;
+ }
+ 
++static void mt7996_eeprom_init_precal(struct mt7996_dev *dev)
++{
++#define MT76_CHANNELS_5GHZ_SIZE		36	/* ARRAY_SIZE(mt76_channels_5ghz) */
++#define MT76_CHANNELS_6GHZ_SIZE		59	/* ARRAY_SIZE(mt76_channels_6ghz) */
++
++	dev->prek.dpd_ch_num[DPD_CH_NUM_BW20_2G] = ARRAY_SIZE(dpd_2g_ch_list_bw20);
++	dev->prek.dpd_ch_num[DPD_CH_NUM_BW20_5G_SKIP] = ARRAY_SIZE(dpd_5g_skip_ch_list);
++	dev->prek.dpd_ch_num[DPD_CH_NUM_BW20_5G] = MT76_CHANNELS_5GHZ_SIZE -
++						   DPD_CH_NUM(BW20_5G_SKIP);
++	dev->prek.dpd_ch_num[DPD_CH_NUM_BW160_5G] = ARRAY_SIZE(dpd_5g_ch_list_bw160);
++	dev->prek.dpd_ch_num[DPD_CH_NUM_BW20_6G] = MT76_CHANNELS_6GHZ_SIZE;
++	dev->prek.dpd_ch_num[DPD_CH_NUM_BW160_6G] = ARRAY_SIZE(dpd_6g_ch_list_bw160);
++
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7990:
++		dev->prek.rev = mt7996_prek_rev;
++		/* 5g & 6g bw 80 dpd channel list is not used */
++		dev->prek.dpd_ch_num[DPD_CH_NUM_BW320_6G] = ARRAY_SIZE(dpd_6g_ch_list_bw320);
++		break;
++	case 0x7992:
++		dev->prek.rev  = mt7992_prek_rev;
++		dev->prek.dpd_ch_num[DPD_CH_NUM_BW80_5G] = ARRAY_SIZE(dpd_5g_ch_list_bw80);
++		/* 6g is not used in current sku */
++		dev->prek.dpd_ch_num[DPD_CH_NUM_BW20_6G] = 0;
++		dev->prek.dpd_ch_num[DPD_CH_NUM_BW80_6G] = 0;
++		dev->prek.dpd_ch_num[DPD_CH_NUM_BW160_6G] = 0;
++		break;
++	default:
++		dev->prek.rev  = mt7996_prek_rev;
++		break;
++	}
++}
++
+ static int mt7996_eeprom_load_precal(struct mt7996_dev *dev)
+ {
+ 	struct mt76_dev *mdev = &dev->mt76;
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 8f0f87b6..3e9992a3 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -67,6 +67,8 @@ enum mt7996_eeprom_field {
+ 
+ extern const struct ieee80211_channel dpd_2g_ch_list_bw20[];
+ extern const u32 dpd_2g_bw20_ch_num;
++extern const struct ieee80211_channel dpd_5g_skip_ch_list[];
++extern const u32 dpd_5g_skip_ch_num;
+ extern const struct ieee80211_channel dpd_5g_ch_list_bw160[];
+ extern const u32 dpd_5g_bw160_ch_num;
+ extern const struct ieee80211_channel dpd_6g_ch_list_bw160[];
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 55e8cb1e..4598d815 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3775,7 +3775,8 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ 		chan_list_size = mphy->sband_5g.sband.n_channels;
+ 		base_offset += dpd_size_2g;
+ 		if (bw == NL80211_CHAN_WIDTH_160) {
+-			base_offset += mphy->sband_5g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
++			base_offset += (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
++				       DPD_PER_CH_BW20_SIZE;
+ 			per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
+ 			cal_id = RF_DPD_FLAT_5G_MEM_CAL;
+ 			chan_list = dpd_5g_ch_list_bw160;
+@@ -3784,6 +3785,9 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ 			/* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */
+ 			channel -= 2;
+ 		}
++		if (channel >= dpd_5g_skip_ch_list[0].hw_value &&
++		    channel <= dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
++			return 0;
+ 		break;
+ 	case NL80211_BAND_6GHZ:
+ 		dpd_mask = MT_EE_WIFI_CAL_DPD_6G;
+@@ -3823,6 +3827,10 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ 	if (idx == chan_list_size)
+ 		return -EINVAL;
+ 
++	if (band == NL80211_BAND_5GHZ && bw != NL80211_CHAN_WIDTH_160 &&
++	    channel > dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
++		idx -= dpd_5g_skip_ch_num;
++
+ 	cal += MT_EE_CAL_GROUP_SIZE + base_offset + idx * per_chan_size;
+ 
+ 	for (i = 0; i < per_chan_size / MT_EE_CAL_UNIT; i++) {
+diff --git a/mt7996/testmode.c b/mt7996/testmode.c
+index 2fb36a97..0dc6629d 100644
+--- a/mt7996/testmode.c
++++ b/mt7996/testmode.c
+@@ -531,6 +531,11 @@ mt7996_tm_dpd_prek_send_req(struct mt7996_phy *phy, struct mt7996_tm_req *req,
+ 	memcpy(&chandef_backup, chandef, sizeof(struct cfg80211_chan_def));
+ 
+ 	for (i = 0; i < channel_size; i++) {
++		if (chan_list[i].band == NL80211_BAND_5GHZ &&
++		    chan_list[i].hw_value >= dpd_5g_skip_ch_list[0].hw_value &&
++		    chan_list[i].hw_value <= dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
++			continue;
++
+ 		memcpy(chandef->chan, &chan_list[i], sizeof(struct ieee80211_channel));
+ 		chandef->width = width;
+ 
+@@ -612,7 +617,8 @@ mt7996_tm_dpd_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ 						  NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_5G_CAL);
+ 		if (ret)
+ 			return ret;
+-		wait_on_prek_offset += mphy->sband_5g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
++		wait_on_prek_offset += (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
++				       DPD_PER_CH_BW20_SIZE;
+ 		wait_event_timeout(mdev->mcu.wait,
+ 				   dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
+ 
+@@ -868,6 +874,7 @@ mt7996_tm_get_center_chan(struct mt7996_phy *phy, struct cfg80211_chan_def *chan
+ 	const struct ieee80211_channel *chan = mphy->sband_5g.sband.channels;
+ 	u32 bitmap, i, offset, width_mhz, size = mphy->sband_5g.sband.n_channels;
+ 	u16 first_control = 0, control_chan = chandef->chan->hw_value;
++	bool not_first;
+ 
+ 	bitmap = mt7996_tm_bw_mapping(chandef->width, BW_MAP_NL_TO_CONTROL_BITMAP_5G);
+ 	if (!bitmap)
+@@ -877,7 +884,9 @@ mt7996_tm_get_center_chan(struct mt7996_phy *phy, struct cfg80211_chan_def *chan
+ 	offset = width_mhz / 10 - 2;
+ 
+ 	for (i = 0; i < size; i++) {
+-		if (!((1 << i) & bitmap))
++		not_first = (chandef->width != NL80211_CHAN_WIDTH_160) ?
++			    (i % bitmap) : (i >= 32) || !((1 << i) & bitmap);
++		if (not_first)
+ 			continue;
+ 
+ 		if (control_chan >= chan[i].hw_value)
+@@ -886,7 +895,7 @@ mt7996_tm_get_center_chan(struct mt7996_phy *phy, struct cfg80211_chan_def *chan
+ 			break;
+ 	}
+ 
+-	if (i == size || first_control == 0)
++	if (first_control == 0)
+ 		return control_chan;
+ 
+ 	return first_control + offset;
+diff --git a/mt7996/testmode.h b/mt7996/testmode.h
+index f97ccb26..ba1767ae 100644
+--- a/mt7996/testmode.h
++++ b/mt7996/testmode.h
+@@ -38,9 +38,9 @@ enum {
+ 	BF_CDBW_8080MHZ,
+ };
+ 
+-#define FIRST_CONTROL_CHAN_BITMAP_BW40		0x5555555
+-#define FIRST_CONTROL_CHAN_BITMAP_BW80		0x111111
+-#define FIRST_CONTROL_CHAN_BITMAP_BW160		0x100101
++#define FIRST_CONTROL_CHAN_BITMAP_BW40		2
++#define FIRST_CONTROL_CHAN_BITMAP_BW80		4
++#define FIRST_CONTROL_CHAN_BITMAP_BW160		0x10010101
+ 
+ enum bw_mapping_method {
+ 	BW_MAP_NL_TO_FW,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1036-mtk-wifi-mt76-mt7996-support-enable-disable-pp-featu.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1036-mtk-wifi-mt76-mt7996-support-enable-disable-pp-featu.patch
new file mode 100644
index 0000000..9bce324
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1036-mtk-wifi-mt76-mt7996-support-enable-disable-pp-featu.patch
@@ -0,0 +1,112 @@
+From 3ee3f424e835e9366924452f5f32d8ce094f2d7b Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Mon, 25 Sep 2023 19:20:49 +0800
+Subject: [PATCH 1036/1041] mtk: wifi: mt76: mt7996: support enable/disable pp
+ feature by nl80211 vendor commands
+
+User can enable/disable preamble puncture feature through hostapd
+configuration and hostapd_cli. Driver can receive the nl80211 vendor
+message and convert it to mcu commands.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt7996/vendor.c | 38 ++++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h | 12 ++++++++++++
+ 2 files changed, 50 insertions(+)
+
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index c7fd3278..9732ed28 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -107,6 +107,11 @@ background_radar_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL] = {
+ 	[MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MODE] = {.type = NLA_U8 },
+ };
+ 
++static struct nla_policy
++pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = {
++	[MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 },
++};
++
+ struct mt7996_amnt_data {
+ 	u8 idx;
+ 	u8 addr[ETH_ALEN];
+@@ -877,6 +882,28 @@ static int mt7996_vendor_background_radar_mode_ctrl(struct wiphy *wiphy,
+ 	return mt7996_mcu_rdd_background_disable_timer(dev, !!background_radar_mode);
+ }
+ 
++static int mt7996_vendor_pp_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev,
++				 const void *data, int data_len)
++{
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_PP_CTRL];
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	int err;
++	u8 val8;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_PP_CTRL_MAX, data, data_len,
++			pp_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	if (tb[MTK_VENDOR_ATTR_PP_MODE]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_MODE]);
++		err = mt7996_mcu_set_pp_en(phy, !!val8, 0, 0);
++	}
++
++	return err;
++}
++
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 	{
+ 		.info = {
+@@ -982,6 +1009,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 		.policy = background_radar_ctrl_policy,
+ 		.maxattr = MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MAX,
+ 	},
++	{
++		.info = {
++			.vendor_id = MTK_NL80211_VENDOR_ID,
++			.subcmd = MTK_NL80211_VENDOR_SUBCMD_PP_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++			WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_pp_ctrl,
++		.policy = pp_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_PP_CTRL_MAX,
++	},
+ };
+ 
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 920b6e6a..98128965 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -15,6 +15,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ 	MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
++	MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
+ };
+ 
+ enum mtk_vendor_attr_edcca_ctrl {
+@@ -214,6 +215,17 @@ enum mtk_vendor_attr_ibf_dump {
+ 		NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
+ };
+ 
++enum mtk_vendor_attr_pp_ctrl {
++	MTK_VENDOR_ATTR_PP_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_PP_MODE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_PP_CTRL,
++	MTK_VENDOR_ATTR_PP_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_PP_CTRL - 1
++};
++
+ #endif
+ 
+ #endif
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1037-mtk-wifi-mt76-testmode-add-kite-testmode-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1037-mtk-wifi-mt76-testmode-add-kite-testmode-support.patch
new file mode 100644
index 0000000..d3e9daf
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1037-mtk-wifi-mt76-testmode-add-kite-testmode-support.patch
@@ -0,0 +1,598 @@
+From 11a74db98d3f18b7d9ce7f2837079172a8b7d159 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 12 Oct 2023 16:17:33 +0800
+Subject: [PATCH 1037/1041] mtk: wifi: mt76: testmode: add kite testmode
+ support
+
+Add Kite testmode support
+1. avoid entering connac 2 testmode flow in kite
+2. refactor prek implementation for handling chip difference
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c   | 63 +++++++++++++-----------------
+ mt7996/eeprom.h   | 81 +++++++++++++++++++++++++++------------
+ mt7996/mcu.c      | 48 ++++++++++++++---------
+ mt7996/mt7996.h   | 18 ++++++++-
+ mt7996/testmode.c | 97 ++++++++++++++++++++++++++++-------------------
+ testmode.c        | 11 ++++--
+ 6 files changed, 198 insertions(+), 120 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index cff1b875..9fef7035 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -29,12 +29,39 @@ const struct ieee80211_channel dpd_5g_skip_ch_list[] = {
+ 	CHAN5G(96, 5480)
+ };
+ 
++const struct ieee80211_channel dpd_5g_ch_list_bw80[] = {
++	CHAN5G(42, 5210),
++	CHAN5G(58, 5290),
++	CHAN5G(106, 5530),
++	CHAN5G(122, 5610),
++	CHAN5G(138, 5690),
++	CHAN5G(155, 5775),
++	CHAN5G(171, 5855)
++};
++
+ const struct ieee80211_channel dpd_5g_ch_list_bw160[] = {
+ 	CHAN5G(50, 5250),
+ 	CHAN5G(114, 5570),
+ 	CHAN5G(163, 5815)
+ };
+ 
++const struct ieee80211_channel dpd_6g_ch_list_bw80[] = {
++	CHAN6G(7, 5985),
++	CHAN6G(23, 6065),
++	CHAN6G(39, 6145),
++	CHAN6G(55, 6225),
++	CHAN6G(71, 6305),
++	CHAN6G(87, 6385),
++	CHAN6G(103, 6465),
++	CHAN6G(119, 6545),
++	CHAN6G(135, 6625),
++	CHAN6G(151, 6705),
++	CHAN6G(167, 6785),
++	CHAN6G(183, 6865),
++	CHAN6G(199, 6945),
++	CHAN6G(215, 7025)
++};
++
+ const struct ieee80211_channel dpd_6g_ch_list_bw160[] = {
+ 	CHAN6G(15, 6025),
+ 	CHAN6G(47, 6185),
+@@ -54,12 +81,6 @@ const struct ieee80211_channel dpd_6g_ch_list_bw320[] = {
+ 	CHAN6G(191, 6905)
+ };
+ 
+-const u32 dpd_2g_bw20_ch_num = ARRAY_SIZE(dpd_2g_ch_list_bw20);
+-const u32 dpd_5g_skip_ch_num = ARRAY_SIZE(dpd_5g_skip_ch_list);
+-const u32 dpd_5g_bw160_ch_num = ARRAY_SIZE(dpd_5g_ch_list_bw160);
+-const u32 dpd_6g_bw160_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw160);
+-const u32 dpd_6g_bw320_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw320);
+-
+ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+ {
+ #define FEM_INT				0
+@@ -126,36 +147,6 @@ const char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ 	}
+ }
+ 
+-int
+-mt7996_get_dpd_per_band_size(struct mt7996_dev *dev, enum nl80211_band band)
+-{
+-	/* handle different sku */
+-	static const u8 band_to_idx[] = {
+-		[NL80211_BAND_2GHZ] = MT_BAND0,
+-		[NL80211_BAND_5GHZ] = MT_BAND1,
+-		[NL80211_BAND_6GHZ] = MT_BAND2,
+-	};
+-	struct mt7996_phy *phy = __mt7996_phy(dev, band_to_idx[band]);
+-	struct mt76_phy *mphy;
+-	int dpd_size;
+-
+-	if (!phy)
+-		return 0;
+-
+-	mphy = phy->mt76;
+-
+-	if (band == NL80211_BAND_2GHZ)
+-		dpd_size = dpd_2g_bw20_ch_num * DPD_PER_CH_BW20_SIZE;
+-	else if (band == NL80211_BAND_5GHZ)
+-		dpd_size = (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
+-			   DPD_PER_CH_BW20_SIZE + dpd_5g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+-	else
+-		dpd_size = mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
+-			   (dpd_6g_bw160_ch_num + dpd_6g_bw320_ch_num) * DPD_PER_CH_GT_BW20_SIZE;
+-
+-	return dpd_size;
+-}
+-
+ static int
+ mt7996_eeprom_load_default(struct mt7996_dev *dev)
+ {
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 3e9992a3..0d05e75e 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -45,36 +45,69 @@ enum mt7996_eeprom_field {
+ #define MT_EE_WIFI_CAL_DPD			GENMASK(5, 3)
+ 
+ #define MT_EE_CAL_UNIT				1024
+-#define MT_EE_CAL_GROUP_SIZE_2G			(4 * MT_EE_CAL_UNIT)
+-#define MT_EE_CAL_GROUP_SIZE_5G			(45 * MT_EE_CAL_UNIT)
+-#define MT_EE_CAL_GROUP_SIZE_6G			(125 * MT_EE_CAL_UNIT)
+-#define MT_EE_CAL_ADCDCOC_SIZE_2G		(4 * 4)
+-#define MT_EE_CAL_ADCDCOC_SIZE_5G		(4 * 4)
+-#define MT_EE_CAL_ADCDCOC_SIZE_6G		(4 * 5)
+-#define MT_EE_CAL_GROUP_SIZE			(MT_EE_CAL_GROUP_SIZE_2G + \
+-						 MT_EE_CAL_GROUP_SIZE_5G + \
+-						 MT_EE_CAL_GROUP_SIZE_6G + \
+-						 MT_EE_CAL_ADCDCOC_SIZE_2G + \
+-						 MT_EE_CAL_ADCDCOC_SIZE_5G + \
+-						 MT_EE_CAL_ADCDCOC_SIZE_6G)
+-
+-#define DPD_PER_CH_LEGACY_SIZE			(4 * MT_EE_CAL_UNIT)
+-#define DPD_PER_CH_MEM_SIZE			(13 * MT_EE_CAL_UNIT)
+-#define DPD_PER_CH_OTFG0_SIZE			(2 * MT_EE_CAL_UNIT)
+-#define DPD_PER_CH_BW20_SIZE			(DPD_PER_CH_LEGACY_SIZE + DPD_PER_CH_OTFG0_SIZE)
+-#define DPD_PER_CH_GT_BW20_SIZE			(DPD_PER_CH_MEM_SIZE + DPD_PER_CH_OTFG0_SIZE)
+-#define MT_EE_CAL_DPD_SIZE			(780 * MT_EE_CAL_UNIT)
++
++enum mt7996_prek_rev {
++	GROUP_SIZE_2G,
++	GROUP_SIZE_5G,
++	GROUP_SIZE_6G,
++	ADCDCOC_SIZE_2G,
++	ADCDCOC_SIZE_5G,
++	ADCDCOC_SIZE_6G,
++	DPD_LEGACY_SIZE,
++	DPD_MEM_SIZE,
++	DPD_OTFG0_SIZE,
++};
++
++static const u32 mt7996_prek_rev[] = {
++	[GROUP_SIZE_2G] =			4 * MT_EE_CAL_UNIT,
++	[GROUP_SIZE_5G] =			45 * MT_EE_CAL_UNIT,
++	[GROUP_SIZE_6G] =			125 * MT_EE_CAL_UNIT,
++	[ADCDCOC_SIZE_2G] =			4 * 4,
++	[ADCDCOC_SIZE_5G] =			4 * 4,
++	[ADCDCOC_SIZE_6G] =			4 * 5,
++	[DPD_LEGACY_SIZE] =			4 * MT_EE_CAL_UNIT,
++	[DPD_MEM_SIZE] =			13 * MT_EE_CAL_UNIT,
++	[DPD_OTFG0_SIZE] =			2 * MT_EE_CAL_UNIT,
++};
++
++/* kite 2/5g config */
++static const u32 mt7992_prek_rev[] = {
++	[GROUP_SIZE_2G] =			4 * MT_EE_CAL_UNIT,
++	[GROUP_SIZE_5G] =			110 * MT_EE_CAL_UNIT,
++	[GROUP_SIZE_6G] =			0,
++	[ADCDCOC_SIZE_2G] =			4 * 4,
++	[ADCDCOC_SIZE_5G] =			4 * 5,
++	[ADCDCOC_SIZE_6G] =			0,
++	[DPD_LEGACY_SIZE] =			5 * MT_EE_CAL_UNIT,
++	[DPD_MEM_SIZE] =			16 * MT_EE_CAL_UNIT,
++	[DPD_OTFG0_SIZE] =			2 * MT_EE_CAL_UNIT,
++};
+ 
+ extern const struct ieee80211_channel dpd_2g_ch_list_bw20[];
+-extern const u32 dpd_2g_bw20_ch_num;
+ extern const struct ieee80211_channel dpd_5g_skip_ch_list[];
+-extern const u32 dpd_5g_skip_ch_num;
++extern const struct ieee80211_channel dpd_5g_ch_list_bw80[];
+ extern const struct ieee80211_channel dpd_5g_ch_list_bw160[];
+-extern const u32 dpd_5g_bw160_ch_num;
++extern const struct ieee80211_channel dpd_6g_ch_list_bw80[];
+ extern const struct ieee80211_channel dpd_6g_ch_list_bw160[];
+-extern const u32 dpd_6g_bw160_ch_num;
+ extern const struct ieee80211_channel dpd_6g_ch_list_bw320[];
+-extern const u32 dpd_6g_bw320_ch_num;
++
++#define PREK(id)				(dev->prek.rev[(id)])
++#define DPD_CH_NUM(_type)			(dev->prek.dpd_ch_num[DPD_CH_NUM_##_type])
++#define MT_EE_CAL_GROUP_SIZE			(PREK(GROUP_SIZE_2G) + PREK(GROUP_SIZE_5G) + \
++						 PREK(GROUP_SIZE_6G) + PREK(ADCDCOC_SIZE_2G) + \
++						 PREK(ADCDCOC_SIZE_5G) + PREK(ADCDCOC_SIZE_6G))
++#define DPD_PER_CH_BW20_SIZE			(PREK(DPD_LEGACY_SIZE) + PREK(DPD_OTFG0_SIZE))
++#define DPD_PER_CH_GT_BW20_SIZE			(PREK(DPD_MEM_SIZE) + PREK(DPD_OTFG0_SIZE))
++#define MT_EE_CAL_DPD_SIZE_2G			(DPD_CH_NUM(BW20_2G) * DPD_PER_CH_BW20_SIZE)
++#define MT_EE_CAL_DPD_SIZE_5G			(DPD_CH_NUM(BW20_5G) * DPD_PER_CH_BW20_SIZE + \
++						 DPD_CH_NUM(BW80_5G) * DPD_PER_CH_GT_BW20_SIZE + \
++						 DPD_CH_NUM(BW160_5G) * DPD_PER_CH_GT_BW20_SIZE)
++#define MT_EE_CAL_DPD_SIZE_6G			(DPD_CH_NUM(BW20_6G) * DPD_PER_CH_BW20_SIZE + \
++						 DPD_CH_NUM(BW80_6G) * DPD_PER_CH_GT_BW20_SIZE + \
++						 DPD_CH_NUM(BW160_6G) * DPD_PER_CH_GT_BW20_SIZE + \
++						 DPD_CH_NUM(BW320_6G) * DPD_PER_CH_GT_BW20_SIZE)
++#define MT_EE_CAL_DPD_SIZE			(MT_EE_CAL_DPD_SIZE_2G + MT_EE_CAL_DPD_SIZE_5G + \
++						 MT_EE_CAL_DPD_SIZE_6G)
+ 
+ #define RF_DPD_FLAT_CAL				BIT(28)
+ #define RF_PRE_CAL				BIT(29)
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 4598d815..a049ab71 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3744,13 +3744,11 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ 	enum nl80211_chan_width bw = chandef->width;
+ 	const struct ieee80211_channel *chan_list;
+ 	u32 cal_id, chan_list_size, base_offset = 0, offs = MT_EE_DO_PRE_CAL;
+-	u32 dpd_size_2g, dpd_size_5g, per_chan_size = DPD_PER_CH_BW20_SIZE;
++	u32 per_chan_size = DPD_PER_CH_BW20_SIZE;
+ 	u16 channel = ieee80211_frequency_to_channel(chandef->center_freq1);
+ 	u8 dpd_mask, *cal = dev->cal, *eeprom = dev->mt76.eeprom.data;
+ 	int idx, i, ret;
+-
+-	dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
+-	dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
++	bool has_skip_ch = (band == NL80211_BAND_5GHZ);
+ 
+ 	switch (band) {
+ 	case NL80211_BAND_2GHZ:
+@@ -3766,27 +3764,35 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ 			return 0;
+ 		cal_id = RF_DPD_FLAT_CAL;
+ 		chan_list = dpd_2g_ch_list_bw20;
+-		chan_list_size = dpd_2g_bw20_ch_num;
++		chan_list_size = DPD_CH_NUM(BW20_2G);
+ 		break;
+ 	case NL80211_BAND_5GHZ:
+ 		dpd_mask = MT_EE_WIFI_CAL_DPD_5G;
+ 		cal_id = RF_DPD_FLAT_5G_CAL;
+ 		chan_list = mphy->sband_5g.sband.channels;
+ 		chan_list_size = mphy->sband_5g.sband.n_channels;
+-		base_offset += dpd_size_2g;
++		base_offset += MT_EE_CAL_DPD_SIZE_2G;
+ 		if (bw == NL80211_CHAN_WIDTH_160) {
+-			base_offset += (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
+-				       DPD_PER_CH_BW20_SIZE;
++			base_offset += DPD_CH_NUM(BW20_5G) * DPD_PER_CH_BW20_SIZE +
++				       DPD_CH_NUM(BW80_5G) * DPD_PER_CH_GT_BW20_SIZE;
+ 			per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
+ 			cal_id = RF_DPD_FLAT_5G_MEM_CAL;
+ 			chan_list = dpd_5g_ch_list_bw160;
+-			chan_list_size = dpd_5g_bw160_ch_num;
++			chan_list_size = DPD_CH_NUM(BW160_5G);
++			has_skip_ch = false;
++		} else if (is_mt7992(&dev->mt76) && bw == NL80211_CHAN_WIDTH_80) {
++			base_offset += DPD_CH_NUM(BW20_5G) * DPD_PER_CH_BW20_SIZE;
++			per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
++			cal_id = RF_DPD_FLAT_5G_MEM_CAL;
++			chan_list = dpd_5g_ch_list_bw80;
++			chan_list_size = DPD_CH_NUM(BW80_5G);
++			has_skip_ch = false;
+ 		} else if (bw > NL80211_CHAN_WIDTH_20) {
+ 			/* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */
+ 			channel -= 2;
+ 		}
+ 		if (channel >= dpd_5g_skip_ch_list[0].hw_value &&
+-		    channel <= dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
++		    channel <= dpd_5g_skip_ch_list[DPD_CH_NUM(BW20_5G_SKIP) - 1].hw_value)
+ 			return 0;
+ 		break;
+ 	case NL80211_BAND_6GHZ:
+@@ -3794,20 +3800,27 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ 		cal_id = RF_DPD_FLAT_6G_CAL;
+ 		chan_list = mphy->sband_6g.sband.channels;
+ 		chan_list_size = mphy->sband_6g.sband.n_channels;
+-		base_offset += dpd_size_2g + dpd_size_5g;
++		base_offset += MT_EE_CAL_DPD_SIZE_2G + MT_EE_CAL_DPD_SIZE_5G;
+ 		if (bw == NL80211_CHAN_WIDTH_160) {
+ 			base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
+ 			per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
+ 			cal_id = RF_DPD_FLAT_6G_MEM_CAL;
+ 			chan_list = dpd_6g_ch_list_bw160;
+-			chan_list_size = dpd_6g_bw160_ch_num;
+-		} else if (bw == NL80211_CHAN_WIDTH_320) {
++			chan_list_size = DPD_CH_NUM(BW160_6G);
++		} else if (is_mt7996(&dev->mt76) && bw == NL80211_CHAN_WIDTH_320) {
+ 			base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
+-				       dpd_6g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
++				       DPD_CH_NUM(BW80_6G) * DPD_PER_CH_GT_BW20_SIZE +
++				       DPD_CH_NUM(BW160_6G) * DPD_PER_CH_GT_BW20_SIZE;
+ 			per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
+ 			cal_id = RF_DPD_FLAT_6G_MEM_CAL;
+ 			chan_list = dpd_6g_ch_list_bw320;
+-			chan_list_size = dpd_6g_bw320_ch_num;
++			chan_list_size = DPD_CH_NUM(BW320_6G);
++		} else if (is_mt7992(&dev->mt76) && bw == NL80211_CHAN_WIDTH_80) {
++			base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
++			per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
++			cal_id = RF_DPD_FLAT_6G_MEM_CAL;
++			chan_list = dpd_6g_ch_list_bw80;
++			chan_list_size = DPD_CH_NUM(BW80_6G);
+ 		} else if (bw > NL80211_CHAN_WIDTH_20) {
+ 			/* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */
+ 			channel -= 2;
+@@ -3827,9 +3840,8 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
+ 	if (idx == chan_list_size)
+ 		return -EINVAL;
+ 
+-	if (band == NL80211_BAND_5GHZ && bw != NL80211_CHAN_WIDTH_160 &&
+-	    channel > dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
+-		idx -= dpd_5g_skip_ch_num;
++	if (has_skip_ch && channel > dpd_5g_skip_ch_list[DPD_CH_NUM(BW20_5G_SKIP) - 1].hw_value)
++		idx -= DPD_CH_NUM(BW20_5G_SKIP);
+ 
+ 	cal += MT_EE_CAL_GROUP_SIZE + base_offset + idx * per_chan_size;
+ 
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 339d9890..17cae7f5 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -195,6 +195,19 @@ struct mt7996_twt_flow {
+ 
+ DECLARE_EWMA(avg_signal, 10, 8)
+ 
++enum mt7996_dpd_ch_num {
++	DPD_CH_NUM_BW20_2G,
++	DPD_CH_NUM_BW20_5G,
++	DPD_CH_NUM_BW20_5G_SKIP,
++	DPD_CH_NUM_BW80_5G,
++	DPD_CH_NUM_BW160_5G,
++	DPD_CH_NUM_BW20_6G,
++	DPD_CH_NUM_BW80_6G,
++	DPD_CH_NUM_BW160_6G,
++	DPD_CH_NUM_BW320_6G,
++	DPD_CH_NUM_TYPE_MAX,
++};
++
+ struct mt7996_sta {
+ 	struct mt76_wcid wcid; /* must be first */
+ 
+@@ -456,6 +469,10 @@ struct mt7996_dev {
+ 
+ 	void *cal;
+ 	u32 cur_prek_offset;
++	struct {
++		const u32 *rev;
++		u8 dpd_ch_num[DPD_CH_NUM_TYPE_MAX];
++	} prek;
+ 
+ 	struct {
+ 		u16 table_mask;
+@@ -592,7 +609,6 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
+ int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
+ 				   struct ieee80211_channel *chan);
+ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band);
+-int mt7996_get_dpd_per_band_size(struct mt7996_dev *dev, enum nl80211_band band);
+ int mt7996_dma_init(struct mt7996_dev *dev);
+ void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
+ void mt7996_dma_prefetch(struct mt7996_dev *dev);
+diff --git a/mt7996/testmode.c b/mt7996/testmode.c
+index 0dc6629d..44ec84cc 100644
+--- a/mt7996/testmode.c
++++ b/mt7996/testmode.c
+@@ -434,7 +434,7 @@ mt7996_tm_set_tx_cont(struct mt7996_phy *phy, bool en)
+ static int
+ mt7996_tm_group_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ {
+-	u8 *eeprom;
++	u8 *eeprom, do_precal;
+ 	u32 i, group_size, dpd_size, size, offs, *pre_cal;
+ 	int ret = 0;
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -462,6 +462,9 @@ mt7996_tm_group_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ 	dpd_size = MT_EE_CAL_DPD_SIZE;
+ 	size = group_size + dpd_size;
+ 	offs = MT_EE_DO_PRE_CAL;
++	do_precal = (MT_EE_WIFI_CAL_GROUP_2G * !!PREK(GROUP_SIZE_2G)) |
++		    (MT_EE_WIFI_CAL_GROUP_5G * !!PREK(GROUP_SIZE_5G)) |
++		    (MT_EE_WIFI_CAL_GROUP_6G * !!PREK(GROUP_SIZE_6G));
+ 
+ 	switch (state) {
+ 	case MT76_TM_STATE_GROUP_PREK:
+@@ -476,13 +479,10 @@ mt7996_tm_group_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ 		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == group_size,
+ 				   30 * HZ);
+ 
+-		if (ret) {
++		if (ret)
+ 			dev_err(dev->mt76.dev, "Group Pre-cal: mcu send msg failed!\n");
+-			return ret;
+-		}
+-
+-		if (!ret)
+-			eeprom[offs] |= MT_EE_WIFI_CAL_GROUP;
++		else
++			eeprom[offs] |= do_precal;
+ 		break;
+ 	case MT76_TM_STATE_GROUP_PREK_DUMP:
+ 		pre_cal = (u32 *)dev->cal;
+@@ -520,10 +520,12 @@ mt7996_tm_dpd_prek_send_req(struct mt7996_phy *phy, struct mt7996_tm_req *req,
+ 	struct mt76_phy *mphy = phy->mt76;
+ 	struct cfg80211_chan_def chandef_backup, *chandef = &mphy->chandef;
+ 	struct ieee80211_channel chan_backup;
+-	int i, ret;
++	int i, ret, skip_ch_num = DPD_CH_NUM(BW20_5G_SKIP);
+ 
+ 	if (!chan_list)
+ 		return -EOPNOTSUPP;
++	if (!channel_size)
++		return 0;
+ 
+ 	req->rf_test.op.rf.param.cal_param.func_data = cpu_to_le32(func_data);
+ 
+@@ -533,7 +535,7 @@ mt7996_tm_dpd_prek_send_req(struct mt7996_phy *phy, struct mt7996_tm_req *req,
+ 	for (i = 0; i < channel_size; i++) {
+ 		if (chan_list[i].band == NL80211_BAND_5GHZ &&
+ 		    chan_list[i].hw_value >= dpd_5g_skip_ch_list[0].hw_value &&
+-		    chan_list[i].hw_value <= dpd_5g_skip_ch_list[dpd_5g_skip_ch_num - 1].hw_value)
++		    chan_list[i].hw_value <= dpd_5g_skip_ch_list[skip_ch_num - 1].hw_value)
+ 			continue;
+ 
+ 		memcpy(chandef->chan, &chan_list[i], sizeof(struct ieee80211_channel));
+@@ -602,11 +604,11 @@ mt7996_tm_dpd_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ 	switch (state) {
+ 	case MT76_TM_STATE_DPD_2G:
+ 		ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_2g_ch_list_bw20,
+-						  dpd_2g_bw20_ch_num,
++						  DPD_CH_NUM(BW20_2G),
+ 						  NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_CAL);
+-		wait_on_prek_offset += dpd_2g_bw20_ch_num * DPD_PER_CH_BW20_SIZE;
+-		wait_event_timeout(mdev->mcu.wait,
+-				   dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++		wait_on_prek_offset += DPD_CH_NUM(BW20_2G) * DPD_PER_CH_BW20_SIZE;
++		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++				   30 * HZ);
+ 
+ 		do_precal = MT_EE_WIFI_CAL_DPD_2G;
+ 		break;
+@@ -617,18 +619,27 @@ mt7996_tm_dpd_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ 						  NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_5G_CAL);
+ 		if (ret)
+ 			return ret;
+-		wait_on_prek_offset += (mphy->sband_5g.sband.n_channels - dpd_5g_skip_ch_num) *
+-				       DPD_PER_CH_BW20_SIZE;
+-		wait_event_timeout(mdev->mcu.wait,
+-				   dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++		wait_on_prek_offset += DPD_CH_NUM(BW20_5G) * DPD_PER_CH_BW20_SIZE;
++		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++				   30 * HZ);
++
++		/* 5g channel bw80 calibration */
++		ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_5g_ch_list_bw80,
++						  DPD_CH_NUM(BW80_5G),
++						  NL80211_CHAN_WIDTH_80, RF_DPD_FLAT_5G_MEM_CAL);
++		if (ret)
++			return ret;
++		wait_on_prek_offset += DPD_CH_NUM(BW80_5G) * DPD_PER_CH_GT_BW20_SIZE;
++		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++				   30 * HZ);
+ 
+ 		/* 5g channel bw160 calibration */
+ 		ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_5g_ch_list_bw160,
+-						  dpd_5g_bw160_ch_num,
++						  DPD_CH_NUM(BW160_5G),
+ 						  NL80211_CHAN_WIDTH_160, RF_DPD_FLAT_5G_MEM_CAL);
+-		wait_on_prek_offset += dpd_5g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+-		wait_event_timeout(mdev->mcu.wait,
+-				   dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++		wait_on_prek_offset += DPD_CH_NUM(BW160_5G) * DPD_PER_CH_GT_BW20_SIZE;
++		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++				   30 * HZ);
+ 
+ 		do_precal = MT_EE_WIFI_CAL_DPD_5G;
+ 		break;
+@@ -639,27 +650,37 @@ mt7996_tm_dpd_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
+ 						  NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_6G_CAL);
+ 		if (ret)
+ 			return ret;
+-		wait_on_prek_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
+-		wait_event_timeout(mdev->mcu.wait,
+-				   dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++		wait_on_prek_offset += DPD_CH_NUM(BW20_6G) * DPD_PER_CH_BW20_SIZE;
++		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++				   30 * HZ);
++
++		/* 6g channel bw80 calibration */
++		ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_6g_ch_list_bw80,
++						  DPD_CH_NUM(BW80_6G),
++						  NL80211_CHAN_WIDTH_80, RF_DPD_FLAT_6G_MEM_CAL);
++		if (ret)
++			return ret;
++		wait_on_prek_offset += DPD_CH_NUM(BW80_6G) * DPD_PER_CH_GT_BW20_SIZE;
++		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++				   30 * HZ);
+ 
+ 		/* 6g channel bw160 calibration */
+ 		ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_6g_ch_list_bw160,
+-						  dpd_6g_bw160_ch_num,
++						  DPD_CH_NUM(BW160_6G),
+ 						  NL80211_CHAN_WIDTH_160, RF_DPD_FLAT_6G_MEM_CAL);
+ 		if (ret)
+ 			return ret;
+-		wait_on_prek_offset += dpd_6g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+-		wait_event_timeout(mdev->mcu.wait,
+-				   dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++		wait_on_prek_offset += DPD_CH_NUM(BW160_6G) * DPD_PER_CH_GT_BW20_SIZE;
++		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++				   30 * HZ);
+ 
+ 		/* 6g channel bw320 calibration */
+ 		ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_6g_ch_list_bw320,
+-						  dpd_6g_bw320_ch_num,
++						  DPD_CH_NUM(BW320_6G),
+ 						  NL80211_CHAN_WIDTH_320, RF_DPD_FLAT_6G_MEM_CAL);
+-		wait_on_prek_offset += dpd_6g_bw320_ch_num * DPD_PER_CH_GT_BW20_SIZE;
+-		wait_event_timeout(mdev->mcu.wait,
+-				   dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++		wait_on_prek_offset += DPD_CH_NUM(BW320_6G) * DPD_PER_CH_GT_BW20_SIZE;
++		wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == wait_on_prek_offset,
++				   30 * HZ);
+ 
+ 		do_precal = MT_EE_WIFI_CAL_DPD_6G;
+ 		break;
+@@ -732,9 +753,9 @@ mt7996_tm_dump_precal(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int
+ 	eeprom = dev->mt76.eeprom.data;
+ 	offs = MT_EE_DO_PRE_CAL;
+ 
+-	dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
+-	dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
+-	dpd_size_6g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_6GHZ);
++	dpd_size_2g = MT_EE_CAL_DPD_SIZE_2G;
++	dpd_size_5g = MT_EE_CAL_DPD_SIZE_5G;
++	dpd_size_6g = MT_EE_CAL_DPD_SIZE_6G;
+ 
+ 	switch (type) {
+ 	case PREK_SYNC_ALL:
+@@ -810,9 +831,9 @@ mt7996_tm_re_cal_event(struct mt7996_dev *dev, struct mt7996_tm_rf_test_result *
+ 	u8 *pre_cal;
+ 
+ 	pre_cal = dev->cal;
+-	dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
+-	dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
+-	dpd_size_6g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_6GHZ);
++	dpd_size_2g = MT_EE_CAL_DPD_SIZE_2G;
++	dpd_size_5g = MT_EE_CAL_DPD_SIZE_5G;
++	dpd_size_6g = MT_EE_CAL_DPD_SIZE_6G;
+ 
+ 	cal_idx = le32_to_cpu(data->cal_idx);
+ 	cal_type = le32_to_cpu(data->cal_type);
+diff --git a/testmode.c b/testmode.c
+index 7b8f9e66..81b492a5 100644
+--- a/testmode.c
++++ b/testmode.c
+@@ -37,6 +37,11 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+ };
+ EXPORT_SYMBOL_GPL(mt76_tm_policy);
+ 
++static inline bool mt76_testmode_offload(struct mt76_dev *dev)
++{
++	return is_mt7996(dev) || is_mt7992(dev);
++}
++
+ void mt76_testmode_tx_pending(struct mt76_phy *phy)
+ {
+ 	struct mt76_testmode_data *td = &phy->test;
+@@ -197,7 +202,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
+ 	u8 max_nss = hweight8(phy->antenna_mask);
+ 	int ret;
+ 
+-	if (is_mt7996(phy->dev))
++	if (mt76_testmode_offload(phy->dev))
+ 		return 0;
+ 
+ 	ret = mt76_testmode_alloc_skb(phy, td->tx_mpdu_len);
+@@ -293,7 +298,7 @@ mt76_testmode_tx_start(struct mt76_phy *phy)
+ 	td->tx_done = 0;
+ 	td->tx_pending = td->tx_count;
+ 
+-	if (!is_mt7996(dev))
++	if (!mt76_testmode_offload(dev))
+ 		mt76_worker_schedule(&dev->tx_worker);
+ }
+ 
+@@ -303,7 +308,7 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
+ 	struct mt76_testmode_data *td = &phy->test;
+ 	struct mt76_dev *dev = phy->dev;
+ 
+-	if (is_mt7996(dev) && dev->test_ops->tx_stop) {
++	if (mt76_testmode_offload(dev) && dev->test_ops->tx_stop) {
+ 		dev->test_ops->tx_stop(phy);
+ 		return;
+ 	}
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1038-mtk-wifi-mt76-mt7996-assign-DEAUTH-to-ALTX-queue-for.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1038-mtk-wifi-mt76-mt7996-assign-DEAUTH-to-ALTX-queue-for.patch
new file mode 100644
index 0000000..00904cc
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1038-mtk-wifi-mt76-mt7996-assign-DEAUTH-to-ALTX-queue-for.patch
@@ -0,0 +1,42 @@
+From a5a57f5c031c978e44a180df423568ff725d7dc2 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Tue, 14 Nov 2023 11:27:06 +0800
+Subject: [PATCH 1038/1041] mtk: wifi: mt76: mt7996: assign DEAUTH to ALTX
+ queue for CERT
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ mt7996/mac.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 27e5fb71..408a59c5 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -753,6 +753,8 @@ static void
+ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
+ 			    struct sk_buff *skb, struct ieee80211_key_conf *key)
+ {
++	struct mt76_phy *mphy =
++		mt76_dev_phy(&dev->mt76, le32_get_bits(txwi[1], MT_TXD1_TGID));
+ 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+ 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+@@ -762,6 +764,14 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
+ 	u8 fc_type, fc_stype;
+ 	u32 val;
+ 
++	if (ieee80211_is_cert_mode(mphy->hw) && ieee80211_is_deauth(fc)) {
++		/* In WPA3 cert TC-4.8.1, the deauth must be transmitted without
++		 * considering PSM bit
++		 */
++		txwi[0] &= ~cpu_to_le32(MT_TXD0_Q_IDX);
++		txwi[0] |= cpu_to_le32(FIELD_PREP(MT_TXD0_Q_IDX, MT_LMAC_ALTX0));
++	}
++
+ 	if (ieee80211_is_action(fc) &&
+ 	    mgmt->u.action.category == WLAN_CATEGORY_BACK &&
+ 	    mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1039-mtk-wifi-mt76-mt7996-add-no_beacon-vendor-command-fo.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1039-mtk-wifi-mt76-mt7996-add-no_beacon-vendor-command-fo.patch
new file mode 100644
index 0000000..0e5a5bb
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1039-mtk-wifi-mt76-mt7996-add-no_beacon-vendor-command-fo.patch
@@ -0,0 +1,153 @@
+From 79d4e84364caca0772254c2a2dbfe82c8f905ab5 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Wed, 22 Nov 2023 22:42:09 +0800
+Subject: [PATCH 1039/1041] mtk: wifi: mt76: mt7996: add no_beacon vendor
+ command for cert
+
+Add the vendor command to disable/enable beacon
+
+[Usage]
+hostapd_cli -i <interface> no_beacon <value>
+<value>
+0: enable beacon
+1: disable beacon
+
+Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
+---
+ mt7996/mcu.c    | 11 +++++++++++
+ mt7996/mt7996.h |  1 +
+ mt7996/vendor.c | 41 +++++++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h | 12 ++++++++++++
+ 4 files changed, 65 insertions(+)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index a049ab71..695a7f54 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -5052,4 +5052,15 @@ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+ 		break;
+ 	}
+ }
++
++void mt7996_set_beacon_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
++{
++	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct ieee80211_hw *hw = mvif->phy->mt76->hw;
++	u8 val = *((u8 *)data);
++
++	vif->bss_conf.enable_beacon = val;
++
++	mt7996_mcu_add_beacon(hw, vif, val);
++}
+ #endif
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 17cae7f5..6233b987 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -828,6 +828,7 @@ void mt7996_set_wireless_amsdu(struct ieee80211_hw *hw, u8 en);
+ void mt7996_mcu_set_mimo(struct mt7996_phy *phy);
+ int mt7996_set_muru_cfg(struct mt7996_phy *phy, u8 action, u8 val);
+ int mt7996_mcu_set_muru_cfg(struct mt7996_phy *phy, void *data);
++void mt7996_set_beacon_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
+ #endif
+ 
+ int mt7996_mcu_edcca_enable(struct mt7996_phy *phy, bool enable);
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 9732ed28..c87cc5c1 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -112,6 +112,11 @@ pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = {
+ 	[MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 },
+ };
+ 
++static const struct nla_policy
++beacon_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BEACON_CTRL] = {
++	[MTK_VENDOR_ATTR_BEACON_CTRL_MODE] = { .type = NLA_U8 },
++};
++
+ struct mt7996_amnt_data {
+ 	u8 idx;
+ 	u8 addr[ETH_ALEN];
+@@ -904,6 +909,31 @@ static int mt7996_vendor_pp_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev,
+ 	return err;
+ }
+ 
++static int mt7996_vendor_beacon_ctrl(struct wiphy *wiphy,
++				     struct wireless_dev *wdev,
++				     const void *data,
++				     int data_len)
++{
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_BEACON_CTRL];
++	int err;
++	u8 val8;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_BEACON_CTRL_MAX, data, data_len,
++			beacon_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	if (tb[MTK_VENDOR_ATTR_BEACON_CTRL_MODE]) {
++		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_BEACON_CTRL_MODE]);
++		ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
++				mt7996_set_beacon_vif, &val8);
++	}
++
++	return 0;
++}
++
++
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 	{
+ 		.info = {
+@@ -1020,6 +1050,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 		.policy = pp_ctrl_policy,
+ 		.maxattr = MTK_VENDOR_ATTR_PP_CTRL_MAX,
+ 	},
++	{
++		.info = {
++			.vendor_id = MTK_NL80211_VENDOR_ID,
++			.subcmd = MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++			 WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_beacon_ctrl,
++		.policy = beacon_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_BEACON_CTRL_MAX,
++	},
+ };
+ 
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 98128965..e7d88828 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -16,6 +16,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ 	MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
+ 	MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
++	MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL = 0xcd,
+ };
+ 
+ enum mtk_vendor_attr_edcca_ctrl {
+@@ -226,6 +227,17 @@ enum mtk_vendor_attr_pp_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_PP_CTRL - 1
+ };
+ 
++enum mtk_vendor_attr_beacon_ctrl {
++	MTK_VENDOR_ATTR_BEACON_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_BEACON_CTRL_MODE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_BEACON_CTRL,
++	MTK_VENDOR_ATTR_BEACON_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_BEACON_CTRL - 1
++};
++
+ #endif
+ 
+ #endif
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1040-mtk-wifi-mt76-mt7996-add-adie-efuse-merge-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1040-mtk-wifi-mt76-mt7996-add-adie-efuse-merge-support.patch
new file mode 100644
index 0000000..0bd9aa0
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1040-mtk-wifi-mt76-mt7996-add-adie-efuse-merge-support.patch
@@ -0,0 +1,209 @@
+From 0e4686ad6417415cf601ffaff2e64858b1b3d56e Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 24 Nov 2023 09:49:08 +0800
+Subject: [PATCH 1040/1041] mtk: wifi: mt76: mt7996: add adie efuse merge
+ support
+
+Merge adie-dependent parameters in efuse into eeprom after FT.
+Note that Eagle BE14000 is not considered yet.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.c    |   6 +-
+ 2 files changed, 149 insertions(+), 2 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 9fef7035..75e31238 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -461,6 +461,147 @@ static int mt7996_eeprom_load_precal(struct mt7996_dev *dev)
+ 	return mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
+ }
+ 
++static int mt7996_apply_cal_free_data(struct mt7996_dev *dev)
++{
++#define MT_EE_CAL_FREE_MAX_SIZE		30
++#define MT_EE_7977BN_OFFSET		(0x1200 - 0x500)
++#define MT_EE_END_OFFSET		0xffff
++	enum adie_type {
++		ADIE_7975,
++		ADIE_7976,
++		ADIE_7977,
++		ADIE_7978,
++		ADIE_7979,
++	};
++	static const u16 adie_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
++		[ADIE_7975] = {0x5cd, 0x5cf, 0x5d1, 0x5d3, 0x6c0, 0x6c1, 0x6c2, 0x6c3,
++			       0x7a1, 0x7a6, 0x7a8, 0x7aa, -1},
++		[ADIE_7976] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59,
++			       0x70, 0x71, 0x790, 0x791, 0x794, 0x795, 0x7a6, 0x7a8, 0x7aa, -1},
++		[ADIE_7977] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59,
++			       0x69, 0x6a, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, -1},
++		[ADIE_7978] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59,
++			       0x90, 0x91, 0x94, 0x95, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
++			       0x100, 0x101, 0x102, 0x103, 0x104, 0x105, -1},
++		[ADIE_7979] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59,
++			       0x69, 0x6a, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, -1},
++	};
++	static const u16 eep_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
++		[ADIE_7975] = {0x451, 0x453, 0x455, 0x457, 0x44c, 0x44d, 0x44e, 0x44f,
++			       0xba1, 0xba6, 0xba8, 0xbaa, -1},
++		[ADIE_7976] = {0x44c, 0x44d, 0x44e, 0x44f, 0x450,
++			       0x451, 0x453, 0x455, 0x457, 0x459,
++			       0x470, 0x471, 0xb90, 0xb91, 0xb94, 0xb95,
++			       0xba6, 0xba8, 0xbaa, -1},
++		[ADIE_7977] = {0x124c, 0x124d, 0x124e, 0x124f, 0x1250,
++			       0x1251, 0x1253, 0x1255, 0x1257, 0x1259,
++			       0x1269, 0x126a, 0x127a, 0x127b, 0x127c, 0x127d, 0x127e, -1},
++		[ADIE_7978] = {0x44c, 0x44d, 0x44e, 0x44f, 0x450,
++			       0x451, 0x453, 0x455, 0x457, 0x459,
++			       0xb90, 0xb91, 0xb94, 0xb95,
++			       0xba6, 0xba7, 0xba8, 0xba9, 0xbaa,
++			       0x480, 0x481, 0x482, 0x483, 0x484, 0x485, -1},
++		[ADIE_7979] = {0x124c, 0x124d, 0x124e, 0x124f, 0x1250,
++			       0x1251, 0x1253, 0x1255, 0x1257, 0x1259,
++			       0x1269, 0x126a, 0x127a, 0x127b, 0x127c, 0x127d, 0x127e, -1},
++	};
++	static const u16 adie_base_7996[] = {
++		0x400, 0x1e00, 0x1200
++	};
++	static const u16 adie_base_7992[] = {
++		0x400, 0x1200, 0x0
++	};
++	static const u16 *adie_offs[__MT_MAX_BAND];
++	static const u16 *eep_offs[__MT_MAX_BAND];
++	static const u16 *adie_base;
++	u8 *eeprom = dev->mt76.eeprom.data;
++	u8 buf[MT7996_EEPROM_BLOCK_SIZE];
++	int adie_id, band, i, ret;
++
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7990:
++		adie_base = adie_base_7996;
++		/* adie 0 */
++		if (dev->fem_type == MT7996_FEM_INT)
++			adie_id = ADIE_7975;
++		else
++			adie_id = ADIE_7976;
++		adie_offs[0] = adie_offs_list[adie_id];
++		eep_offs[0] = eep_offs_list[adie_id];
++
++		/* adie 1 */
++		if (dev->chip_sku != MT7996_SKU_404) {
++			adie_offs[1] = adie_offs_list[ADIE_7977];
++			eep_offs[1] = eep_offs_list[ADIE_7977];
++		}
++
++		/* adie 2 */
++		adie_offs[2] = adie_offs_list[ADIE_7977];
++		eep_offs[2] = eep_offs_list[ADIE_7977];
++		break;
++	case 0x7992:
++		adie_base = adie_base_7992;
++		/* adie 0 */
++		if (dev->chip_sku == MT7992_SKU_44 &&
++		    dev->fem_type != MT7996_FEM_EXT)
++			adie_id = ADIE_7975;
++		else if (dev->chip_sku == MT7992_SKU_24)
++			adie_id = ADIE_7978;
++		else
++			adie_id = ADIE_7976;
++		adie_offs[0] = adie_offs_list[adie_id];
++		eep_offs[0] = eep_offs_list[adie_id];
++
++		/* adie 1 */
++		if (dev->chip_sku == MT7992_SKU_44 &&
++		    dev->fem_type != MT7996_FEM_INT)
++			adie_id = ADIE_7977;
++		else if (dev->chip_sku != MT7992_SKU_23)
++			adie_id = ADIE_7979;
++		else
++			break;
++		adie_offs[1] = adie_offs_list[adie_id];
++		eep_offs[1] = eep_offs_list[adie_id];
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	for (band = 0; band < __MT_MAX_BAND; band++) {
++		u16 adie_offset, eep_offset;
++		u32 block_num, prev_block_num = -1;
++
++		if (!adie_offs[band])
++			continue;
++
++		for (i = 0; i < MT_EE_CAL_FREE_MAX_SIZE; i++) {
++			adie_offset = adie_offs[band][i] + adie_base[band];
++			eep_offset = eep_offs[band][i];
++			block_num = adie_offset / MT7996_EEPROM_BLOCK_SIZE;
++
++			if (adie_offs[band][i] == MT_EE_END_OFFSET)
++				break;
++
++			if (is_mt7996(&dev->mt76) && dev->chip_sku == MT7996_SKU_444 &&
++			    band == MT_BAND1)
++				eep_offset -= MT_EE_7977BN_OFFSET;
++
++			if (prev_block_num != block_num) {
++				ret = mt7996_mcu_get_eeprom(dev, adie_offset, buf);
++				if (ret) {
++					prev_block_num = -1;
++					continue;
++				}
++			}
++
++			eeprom[eep_offset] = buf[adie_offset % MT7996_EEPROM_BLOCK_SIZE];
++			prev_block_num = block_num;
++		}
++	}
++
++	return 0;
++}
++
+ int mt7996_eeprom_init(struct mt7996_dev *dev)
+ {
+ 	int ret;
+@@ -486,6 +627,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	ret = mt7996_apply_cal_free_data(dev);
++	if (ret)
++		return ret;
++
+ 	ret = mt7996_eeprom_parse_hw_cap(dev, &dev->phy);
+ 	if (ret < 0)
+ 		return ret;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 695a7f54..6364be35 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3615,7 +3615,7 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *read_buf)
+ 	};
+ 	struct sk_buff *skb;
+ 	bool valid;
+-	int ret;
++	int ret = 0;
+ 	u8 *buf = read_buf;
+ 
+ 	ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+@@ -3633,11 +3633,13 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *read_buf)
+ 
+ 		skb_pull(skb, 48);
+ 		memcpy(buf, skb->data, MT7996_EEPROM_BLOCK_SIZE);
++	} else {
++		ret = -EINVAL;
+ 	}
+ 
+ 	dev_kfree_skb(skb);
+ 
+-	return 0;
++	return ret;
+ }
+ 
+ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1041-mtk-wifi-mt7996-add-Eagle-2adie-TBTC-BE14000-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1041-mtk-wifi-mt7996-add-Eagle-2adie-TBTC-BE14000-support.patch
new file mode 100644
index 0000000..861c9dc
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1041-mtk-wifi-mt7996-add-Eagle-2adie-TBTC-BE14000-support.patch
@@ -0,0 +1,167 @@
+From 0b73b1e3d8790bfd9d9d362e7876866f631fec14 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 5 Dec 2023 16:48:33 +0800
+Subject: [PATCH 1041/1041] mtk: wifi: mt7996: add Eagle 2adie TBTC (BE14000)
+ support
+
+Add fwdl/default eeprom load support for Eagle 2 adie TBTC
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+Add Eagle 2adie TBTC efuse merge
+Add Eagle 2adie TBTC group prek size
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c |  8 ++++++--
+ mt7996/eeprom.h | 12 ++++++++++++
+ mt7996/init.c   |  6 ++++++
+ mt7996/mcu.c    |  5 +++++
+ mt7996/mt7996.h |  8 ++++++++
+ mt7996/regs.h   |  1 +
+ 6 files changed, 38 insertions(+), 2 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 75e31238..e33acdfb 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -128,6 +128,8 @@ const char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ 	case 0x7990:
+ 		if (dev->chip_sku == MT7996_SKU_404)
+ 			return MT7996_EEPROM_DEFAULT_404;
++		else if (dev->chip_sku == MT7996_SKU_233)
++			return MT7996_EEPROM_DEFAULT_233;
+ 		return MT7996_EEPROM_DEFAULT;
+ 	case 0x7992:
+ 		if (dev->chip_sku == MT7992_SKU_23) {
+@@ -415,6 +417,8 @@ static void mt7996_eeprom_init_precal(struct mt7996_dev *dev)
+ 	switch (mt76_chip(&dev->mt76)) {
+ 	case 0x7990:
+ 		dev->prek.rev = mt7996_prek_rev;
++		if (dev->chip_sku == MT7996_SKU_233)
++			dev->prek.rev = mt7996_prek_rev_233;
+ 		/* 5g & 6g bw 80 dpd channel list is not used */
+ 		dev->prek.dpd_ch_num[DPD_CH_NUM_BW320_6G] = ARRAY_SIZE(dpd_6g_ch_list_bw320);
+ 		break;
+@@ -522,7 +526,7 @@ static int mt7996_apply_cal_free_data(struct mt7996_dev *dev)
+ 	case 0x7990:
+ 		adie_base = adie_base_7996;
+ 		/* adie 0 */
+-		if (dev->fem_type == MT7996_FEM_INT)
++		if (dev->fem_type == MT7996_FEM_INT && dev->chip_sku != MT7996_SKU_233)
+ 			adie_id = ADIE_7975;
+ 		else
+ 			adie_id = ADIE_7976;
+@@ -530,7 +534,7 @@ static int mt7996_apply_cal_free_data(struct mt7996_dev *dev)
+ 		eep_offs[0] = eep_offs_list[adie_id];
+ 
+ 		/* adie 1 */
+-		if (dev->chip_sku != MT7996_SKU_404) {
++		if (dev->chip_sku == MT7996_SKU_444) {
+ 			adie_offs[1] = adie_offs_list[ADIE_7977];
+ 			eep_offs[1] = eep_offs_list[ADIE_7977];
+ 		}
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 0d05e75e..cd866123 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -70,6 +70,18 @@ static const u32 mt7996_prek_rev[] = {
+ 	[DPD_OTFG0_SIZE] =			2 * MT_EE_CAL_UNIT,
+ };
+ 
++static const u32 mt7996_prek_rev_233[] = {
++	[GROUP_SIZE_2G] =			4 * MT_EE_CAL_UNIT,
++	[GROUP_SIZE_5G] =			44 * MT_EE_CAL_UNIT,
++	[GROUP_SIZE_6G] =			100 * MT_EE_CAL_UNIT,
++	[ADCDCOC_SIZE_2G] =			4 * 4,
++	[ADCDCOC_SIZE_5G] =			4 * 4,
++	[ADCDCOC_SIZE_6G] =			4 * 5,
++	[DPD_LEGACY_SIZE] =			4 * MT_EE_CAL_UNIT,
++	[DPD_MEM_SIZE] =			13 * MT_EE_CAL_UNIT,
++	[DPD_OTFG0_SIZE] =			2 * MT_EE_CAL_UNIT,
++};
++
+ /* kite 2/5g config */
+ static const u32 mt7992_prek_rev[] = {
+ 	[GROUP_SIZE_2G] =			4 * MT_EE_CAL_UNIT,
+diff --git a/mt7996/init.c b/mt7996/init.c
+index b3677e03..c7576ffe 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -910,6 +910,12 @@ int mt7996_get_chip_sku(struct mt7996_dev *dev)
+ 
+ 	switch (mt76_chip(&dev->mt76)) {
+ 	case 0x7990:
++		if (FIELD_GET(MT_PAD_GPIO_2ADIE_TBTC, val)) {
++			dev->chip_sku = MT7996_SKU_233;
++			dev->fem_type = MT7996_FEM_INT;
++			return 0;
++		}
++
+ 		adie_comb = FIELD_GET(MT_PAD_GPIO_ADIE_COMB, val);
+ 		if (adie_comb <= 1)
+ 			dev->chip_sku = MT7996_SKU_444;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 6364be35..c980f345 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -23,6 +23,11 @@
+ 			_fw = MT7992_##name;			\
+ 		break;						\
+ 	case 0x7990:						\
++		if ((_dev)->chip_sku == MT7996_SKU_233)		\
++			_fw = MT7996_##name##_233;		\
++		else						\
++			_fw = MT7996_##name;			\
++		break;						\
+ 	default:						\
+ 		_fw = MT7996_##name;				\
+ 		break;						\
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 6233b987..9bcb6ff8 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -35,6 +35,12 @@
+ #define MT7996_FIRMWARE_WM_TM		"mediatek/mt7996/mt7996_wm_tm.bin"
+ #define MT7996_ROM_PATCH		"mediatek/mt7996/mt7996_rom_patch.bin"
+ 
++#define MT7996_FIRMWARE_WA_233		"mediatek/mt7996/mt7996_wa_233.bin"
++#define MT7996_FIRMWARE_WM_233		"mediatek/mt7996/mt7996_wm_233.bin"
++#define MT7996_FIRMWARE_DSP_233		MT7996_FIRMWARE_DSP
++#define MT7996_FIRMWARE_WM_TM_233	"mediatek/mt7996/mt7996_wm_tm_233.bin"
++#define MT7996_ROM_PATCH_233		"mediatek/mt7996/mt7996_rom_patch_233.bin"
++
+ #define MT7992_FIRMWARE_WA		"mediatek/mt7996/mt7992_wa.bin"
+ #define MT7992_FIRMWARE_WM		"mediatek/mt7996/mt7992_wm.bin"
+ #define MT7992_FIRMWARE_DSP		"mediatek/mt7996/mt7992_dsp.bin"
+@@ -54,6 +60,7 @@
+ #define MT7992_ROM_PATCH_23		"mediatek/mt7996/mt7992_rom_patch_23.bin"
+ 
+ #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
++#define MT7996_EEPROM_DEFAULT_233	"mediatek/mt7996/mt7996_eeprom_233.bin"
+ #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
+ #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
+ #define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom_2i5i.bin"
+@@ -123,6 +130,7 @@ enum mt7996_fem_type {
+ enum mt7996_sku_type {
+ 	MT7996_SKU_404,
+ 	MT7996_SKU_444,
++	MT7996_SKU_233,
+ };
+ 
+ enum mt7992_sku_type {
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index aa04d8d2..8d1462a7 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -666,6 +666,7 @@ enum offs_rev {
+ 
+ #define MT_PAD_GPIO				0x700056f0
+ #define MT_PAD_GPIO_ADIE_COMB			GENMASK(16, 15)
++#define MT_PAD_GPIO_2ADIE_TBTC			BIT(19)
+ #define MT_PAD_GPIO_ADIE_COMB_7992		GENMASK(17, 16)
+ #define MT_PAD_GPIO_ADIE_NUM_7992		BIT(15)
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2000-mtk-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
similarity index 84%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2000-mtk-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
index d2800ea..a7a243d 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2000-mtk-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
@@ -1,22 +1,21 @@
-From cc82fae54b1efd7de07034bea7a883b9fb362799 Mon Sep 17 00:00:00 2001
+From d0983563a9735b4b4a59efefaeb7dd0c49425ec8 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 6 Feb 2023 19:49:22 +0800
-Subject: [PATCH 64/98] wifi: mt76: revert page_poll for kernel 5.4
+Subject: [PATCH 2000/2020] mtk: wifi: mt76: revert page_poll for kernel 5.4
 
 This reverts commit e8c10835cf062c577ddf426913788c39d30b4bd7.
 
-Change-Id: I4e5764fc545087f691fb4c2f43e7a9cefd1e1657
 ---
- dma.c         | 75 +++++++++++++++++++++++++++------------------------
- mac80211.c    | 57 ---------------------------------------
- mmio.c        | 56 ++++++++++++++++++++++++--------------
- mt76.h        | 22 +--------------
- mt7915/main.c | 26 +++++++-----------
- usb.c         | 43 ++++++++++++++---------------
- 6 files changed, 109 insertions(+), 170 deletions(-)
+ dma.c         | 86 +++++++++++++++++++++++++--------------------------
+ mac80211.c    | 57 ----------------------------------
+ mmio.c        | 52 ++++++++++++++++++++-----------
+ mt76.h        | 22 +------------
+ mt7915/main.c | 26 ++++++----------
+ usb.c         | 43 +++++++++++++-------------
+ 6 files changed, 110 insertions(+), 176 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index bb995e2..06b76ea 100644
+index be8e2aaa..028c2fd5 100644
 --- a/dma.c
 +++ b/dma.c
 @@ -178,7 +178,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
@@ -28,7 +27,7 @@
  		kfree(t);
  	}
  	local_bh_enable();
-@@ -445,9 +445,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -452,9 +452,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  		if (!t)
  			return NULL;
  
@@ -41,7 +40,7 @@
  
  		buf = t->ptr;
  		t->dma_addr = 0;
-@@ -457,9 +457,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -464,9 +464,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  		if (drop)
  			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
  	} else {
@@ -54,7 +53,7 @@
  	}
  
  done:
-@@ -626,11 +626,11 @@ free_skb:
+@@ -636,11 +636,11 @@ free_skb:
  }
  
  static int
@@ -69,7 +68,7 @@
  
  	if (!q->ndesc)
  		return 0;
-@@ -639,28 +639,29 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -649,28 +649,29 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
  
  	while (q->queued < q->ndesc - 1) {
  		struct mt76_queue_buf qbuf = {};
@@ -109,7 +108,7 @@
  			break;
  		}
  		frames++;
-@@ -704,7 +705,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -714,7 +715,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
  		/* WED txfree queue needs ring to be initialized before setup */
  		q->flags = 0;
  		mt76_dma_queue_reset(dev, q);
@@ -118,7 +117,7 @@
  
  		ret = mtk_wed_device_txfree_ring_setup(q->wed, q->regs);
  		if (!ret)
-@@ -733,7 +734,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -743,7 +744,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
  	case MT76_WED_RRO_Q_IND:
  		q->flags &= ~MT_QFLAG_WED;
  		mt76_dma_queue_reset(dev, q);
@@ -127,7 +126,7 @@
  		mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
  		break;
  	default:
-@@ -789,10 +790,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -799,10 +800,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  	if (!q->entry)
  		return -ENOMEM;
  
@@ -138,7 +137,7 @@
  	ret = mt76_dma_wed_setup(dev, q, false);
  	if (ret)
  		return ret;
-@@ -811,6 +808,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -821,6 +818,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  static void
  mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  {
@@ -146,7 +145,7 @@
  	void *buf;
  	bool more;
  
-@@ -825,7 +823,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -836,7 +834,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  			break;
  
  		if (!mt76_queue_is_wed_rro(q))
@@ -154,8 +153,8 @@
 +			skb_free_frag(buf);
  	} while (1);
  
- 	if (q->rx_head) {
-@@ -834,6 +832,16 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+ 	spin_lock_bh(&q->lock);
+@@ -846,6 +844,16 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  	}
  
  	spin_unlock_bh(&q->lock);
@@ -172,25 +171,36 @@
  }
  
  static void
-@@ -857,7 +865,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+@@ -868,15 +876,10 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+ 	/* reset WED rx queues */
  	mt76_dma_wed_setup(dev, q, true);
- 	if (!mt76_queue_is_wed_tx_free(q)) {
- 		mt76_dma_sync_idx(dev, q);
--		mt76_dma_rx_fill(dev, q, false);
+ 
+-	if (mt76_queue_is_wed_tx_free(q))
+-		return;
+-
+-	if (mtk_wed_device_active(&dev->mmio.wed) &&
+-	    mt76_queue_is_wed_rro(q))
+-		return;
+-
+-	mt76_dma_sync_idx(dev, q);
+-	mt76_dma_rx_fill(dev, q, false);
++	if (!mt76_queue_is_wed_tx_free(q)) {
++		mt76_dma_sync_idx(dev, q);
 +		mt76_dma_rx_fill(dev, q);
- 	}
++	}
  }
  
-@@ -875,7 +883,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
+ static void
+@@ -893,7 +896,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
  
  		skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size);
  	} else {
--		mt76_put_page_pool_buf(data, true);
+-		mt76_put_page_pool_buf(data, allow_direct);
 +		skb_free_frag(data);
  	}
  
  	if (more)
-@@ -948,7 +956,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -968,7 +971,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  			goto free_frag;
  
  		skb_reserve(skb, q->buf_offset);
@@ -198,11 +208,11 @@
  
  		*(u32 *)skb->cb = info;
  
-@@ -964,10 +971,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -984,10 +986,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		continue;
  
  free_frag:
--		mt76_put_page_pool_buf(data, true);
+-		mt76_put_page_pool_buf(data, allow_direct);
 +		skb_free_frag(data);
  	}
  
@@ -211,7 +221,7 @@
  	return done;
  }
  
-@@ -1012,7 +1019,7 @@ mt76_dma_init(struct mt76_dev *dev,
+@@ -1032,7 +1034,7 @@ mt76_dma_init(struct mt76_dev *dev,
  
  	mt76_for_each_q_rx(dev, i) {
  		netif_napi_add(&dev->napi_dev, &dev->napi[i], poll);
@@ -220,7 +230,7 @@
  		napi_enable(&dev->napi[i]);
  	}
  
-@@ -1067,8 +1074,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+@@ -1101,8 +1103,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
  
  		netif_napi_del(&dev->napi[i]);
  		mt76_dma_rx_cleanup(dev, q);
@@ -230,7 +240,7 @@
  
  	if (mtk_wed_device_active(&dev->mmio.wed))
 diff --git a/mac80211.c b/mac80211.c
-index 9c582cb..3715c73 100644
+index f74f6e85..885577fc 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -4,7 +4,6 @@
@@ -241,7 +251,7 @@
  #include "mt76.h"
  
  static const struct ieee80211_channel mt76_channels_2ghz[] = {
-@@ -546,47 +545,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
+@@ -566,47 +565,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
  }
  EXPORT_SYMBOL_GPL(mt76_unregister_phy);
  
@@ -289,7 +299,7 @@
  struct mt76_dev *
  mt76_alloc_device(struct device *pdev, unsigned int size,
  		  const struct ieee80211_ops *ops,
-@@ -1786,21 +1744,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
+@@ -1819,21 +1777,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  }
  EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
  
@@ -312,7 +322,7 @@
  {
  	struct ieee80211_hw *hw = phy->hw;
 diff --git a/mmio.c b/mmio.c
-index c346249..5fb8392 100644
+index c3e0e23e..6c28e27b 100644
 --- a/mmio.c
 +++ b/mmio.c
 @@ -89,8 +89,12 @@ EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
@@ -354,10 +364,9 @@
  
  	for (i = 0; i < size; i++) {
 -		enum dma_data_direction dir;
--		dma_addr_t addr;
--		u32 offset;
 +		struct mt76_txwi_cache *t = mt76_get_rxwi(dev);
-+		dma_addr_t phy_addr;
+ 		dma_addr_t addr;
+-		u32 offset;
 +		struct page *page;
  		int token;
 -		void *buf;
@@ -379,30 +388,29 @@
 -		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
 -		dir = page_pool_get_dma_dir(q->page_pool);
 -		dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
-+		phy_addr = dma_map_single(dev->dma_dev, ptr,
++		addr = dma_map_single(dev->dma_dev, ptr,
 +					  wed->wlan.rx_size,
 +					  DMA_TO_DEVICE);
- 
--		desc->buf0 = cpu_to_le32(addr);
--		token = mt76_rx_token_consume(dev, buf, t, addr);
-+		if (unlikely(dma_mapping_error(dev->dev, phy_addr))) {
++
++		if (unlikely(dma_mapping_error(dev->dev, addr))) {
 +			skb_free_frag(ptr);
 +			mt76_put_rxwi(dev, t);
 +			goto unmap;
 +		}
-+
-+		desc->buf0 = cpu_to_le32(phy_addr);
-+		token = mt76_rx_token_consume(dev, ptr, t, phy_addr);
+ 
+ 		desc->buf0 = cpu_to_le32(addr);
+-		token = mt76_rx_token_consume(dev, buf, t, addr);
++		token = mt76_rx_token_consume(dev, ptr, t, addr);
  		if (token < 0) {
 -			mt76_put_page_pool_buf(buf, false);
-+			dma_unmap_single(dev->dma_dev, phy_addr,
++			dma_unmap_single(dev->dma_dev, addr,
 +					 wed->wlan.rx_size, DMA_TO_DEVICE);
 +			__free_pages(page, get_order(length));
 +			mt76_put_rxwi(dev, t);
  			goto unmap;
  		}
  
-@@ -150,8 +168,6 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -153,8 +171,6 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  	return 0;
  
  unmap:
@@ -412,7 +420,7 @@
  
  	return -ENOMEM;
 diff --git a/mt76.h b/mt76.h
-index d59a1f5..3af97e5 100644
+index 2a7b0ed9..e7b798b2 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -245,7 +245,7 @@ struct mt76_queue {
@@ -424,7 +432,7 @@
  };
  
  struct mt76_mcu_ops {
-@@ -1566,7 +1566,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
+@@ -1592,7 +1592,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
  	return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout);
  }
  
@@ -432,7 +440,7 @@
  void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  			 struct mt76_sta_stats *stats, bool eht);
  int mt76_skb_adjust_pad(struct sk_buff *skb, int pad);
-@@ -1707,25 +1706,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
+@@ -1738,25 +1737,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
  struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
  int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
  			  struct mt76_txwi_cache *r, dma_addr_t phys);
@@ -459,10 +467,10 @@
  static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
  {
 diff --git a/mt7915/main.c b/mt7915/main.c
-index ba34c8e..4c80473 100644
+index df2d4279..a6768512 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1397,22 +1397,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
+@@ -1398,22 +1398,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
  			   struct ieee80211_vif *vif,
  			   u32 sset, u8 *data)
  {
@@ -491,7 +499,7 @@
  }
  
  static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
-@@ -1440,7 +1437,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1441,7 +1438,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
  		.idx = mvif->mt76.idx,
  	};
  	/* See mt7915_ampdu_stat_read_phy, etc */
@@ -500,7 +508,7 @@
  
  	mutex_lock(&dev->mt76.mutex);
  
-@@ -1552,12 +1549,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1553,12 +1550,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
  		return;
  
  	ei += wi.worker_stat_count;
@@ -517,7 +525,7 @@
  
  static void
 diff --git a/usb.c b/usb.c
-index 5e5c7bf..3e28171 100644
+index 5e5c7bf5..3e281715 100644
 --- a/usb.c
 +++ b/usb.c
 @@ -319,27 +319,29 @@ mt76u_set_endpoints(struct usb_interface *intf,
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-rework-wed-rx-flow.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2001-mtk-wifi-mt76-rework-wed-rx-flow.patch
similarity index 84%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-rework-wed-rx-flow.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2001-mtk-wifi-mt76-rework-wed-rx-flow.patch
index a0854af..68382a2 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-rework-wed-rx-flow.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2001-mtk-wifi-mt76-rework-wed-rx-flow.patch
@@ -1,22 +1,21 @@
-From 78b8b86fce85c8ff6fad935bd9bd8b2df0e151ab Mon Sep 17 00:00:00 2001
+From 9601aeb0a394a557c038fdac877ada4620e06f61 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 6 Feb 2023 13:37:23 +0800
-Subject: [PATCH 65/98] wifi: mt76: rework wed rx flow
+Subject: [PATCH 2001/2020] mtk: wifi: mt76: rework wed rx flow
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Change-Id: Icd787345c811cb5ad30d9c7c1c5f9e5298bd3be6
 ---
  dma.c           | 125 +++++++++++++++++++++++++++++++-----------------
  mac80211.c      |   2 +-
- mmio.c          |  58 ++++++++++++++--------
- mt76.h          |  23 +++++----
+ mmio.c          |  57 ++++++++++++++--------
+ mt76.h          |  25 ++++++----
  mt7915/mmio.c   |   3 +-
  mt7915/mt7915.h |   1 +
  tx.c            |  16 +++----
- 7 files changed, 143 insertions(+), 85 deletions(-)
+ 7 files changed, 144 insertions(+), 85 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 06b76ea..f48ec57 100644
+index 028c2fd5..16cb23b4 100644
 --- a/dma.c
 +++ b/dma.c
 @@ -64,17 +64,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
@@ -54,8 +53,8 @@
 -	struct mt76_txwi_cache *t = NULL;
 +	struct mt76_rxwi_cache *r = NULL;
  
--	spin_lock(&dev->wed_lock);
-+	spin_lock(&dev->lock);
+-	spin_lock_bh(&dev->wed_lock);
++	spin_lock_bh(&dev->lock);
  	if (!list_empty(&dev->rxwi_cache)) {
 -		t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache,
 +		r = list_first_entry(&dev->rxwi_cache, struct mt76_rxwi_cache,
@@ -63,8 +62,8 @@
 -		list_del(&t->list);
 +		list_del(&r->list);
  	}
--	spin_unlock(&dev->wed_lock);
-+	spin_unlock(&dev->lock);
+-	spin_unlock_bh(&dev->wed_lock);
++	spin_unlock_bh(&dev->lock);
  
 -	return t;
 +	return r;
@@ -100,12 +99,12 @@
 +	if (!r)
  		return;
  
--	spin_lock(&dev->wed_lock);
+-	spin_lock_bh(&dev->wed_lock);
 -	list_add(&t->list, &dev->rxwi_cache);
--	spin_unlock(&dev->wed_lock);
-+	spin_lock(&dev->lock);
+-	spin_unlock_bh(&dev->wed_lock);
++	spin_lock_bh(&dev->lock);
 +	list_add(&r->list, &dev->rxwi_cache);
-+	spin_unlock(&dev->lock);
++	spin_unlock_bh(&dev->lock);
  }
  EXPORT_SYMBOL_GPL(mt76_put_rxwi);
  
@@ -139,10 +138,10 @@
  	struct mt76_queue_entry *entry = &q->entry[q->head];
 -	struct mt76_txwi_cache *txwi = NULL;
  	struct mt76_desc *desc;
- 	u32 buf1 = 0, ctrl;
  	int idx = q->head;
-@@ -248,13 +248,15 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+ 	u32 buf1 = 0, ctrl;
+@@ -251,13 +251,15 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ #endif
  
  	if (mt76_queue_is_wed_rx(q)) {
 -		txwi = mt76_get_rxwi(dev);
@@ -162,7 +161,7 @@
  			return -ENOMEM;
  		}
  
-@@ -270,7 +272,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -273,7 +275,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
  done:
  	entry->dma_addr[0] = buf->addr;
  	entry->dma_len[0] = buf->len;
@@ -171,7 +170,7 @@
  	entry->buf = data;
  	entry->wcid = 0xffff;
  	entry->skip_buf1 = true;
-@@ -412,7 +414,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
+@@ -422,7 +424,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
  
  static void *
  mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
@@ -180,9 +179,9 @@
  {
  	struct mt76_queue_entry *e = &q->entry[idx];
  	struct mt76_desc *desc = &q->desc[idx];
-@@ -440,20 +442,53 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -447,20 +449,53 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 
  	if (mt76_queue_is_wed_rx(q)) {
- 		u32 buf1 = le32_to_cpu(desc->buf1);
  		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
 -		struct mt76_txwi_cache *t = mt76_rx_token_release(dev, token);
 +		struct mt76_rxwi_cache *r = mt76_rx_token_release(dev, token);
@@ -241,7 +240,7 @@
  		if (drop)
  			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
  	} else {
-@@ -490,7 +525,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
+@@ -497,7 +532,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
  	q->tail = (q->tail + 1) % q->ndesc;
  	q->queued--;
  
@@ -250,7 +249,7 @@
  }
  
  static int
-@@ -658,7 +693,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -668,7 +703,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
  done:
  		qbuf.len = len - offset;
  		qbuf.skip_unmap = false;
@@ -260,10 +259,10 @@
  					 DMA_FROM_DEVICE);
  			skb_free_frag(buf);
 diff --git a/mac80211.c b/mac80211.c
-index 3715c73..4552bc2 100644
+index 885577fc..ff5f4853 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -575,7 +575,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+@@ -595,7 +595,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
  	spin_lock_init(&dev->lock);
  	spin_lock_init(&dev->cc_lock);
  	spin_lock_init(&dev->status_lock);
@@ -271,7 +270,7 @@
  	mutex_init(&dev->mutex);
  	init_waitqueue_head(&dev->tx_wait);
  
-@@ -608,6 +607,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+@@ -628,6 +627,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
  	INIT_LIST_HEAD(&dev->txwi_cache);
  	INIT_LIST_HEAD(&dev->rxwi_cache);
  	dev->token_size = dev->drv->token_size;
@@ -280,7 +279,7 @@
  	for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
  		skb_queue_head_init(&dev->rx_skb[i]);
 diff --git a/mmio.c b/mmio.c
-index 5fb8392..f7495f6 100644
+index 6c28e27b..b792a7bd 100644
 --- a/mmio.c
 +++ b/mmio.c
 @@ -89,28 +89,45 @@ EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
@@ -340,14 +339,14 @@
  }
  EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
  
-@@ -125,18 +142,17 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -125,18 +142,18 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  				sizeof(struct skb_shared_info));
  
  	for (i = 0; i < size; i++) {
 -		struct mt76_txwi_cache *t = mt76_get_rxwi(dev);
 +		struct mt76_rxwi_cache *r = mt76_get_rxwi(dev);
- 		dma_addr_t phy_addr;
--		struct page *page;
+ 		dma_addr_t addr;
+ 		struct page *page;
  		int token;
  		void *ptr;
  
@@ -364,20 +363,20 @@
   			goto unmap;
  		}
  
-@@ -146,17 +162,17 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -146,17 +163,17 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  
- 		if (unlikely(dma_mapping_error(dev->dev, phy_addr))) {
+ 		if (unlikely(dma_mapping_error(dev->dev, addr))) {
  			skb_free_frag(ptr);
 -			mt76_put_rxwi(dev, t);
 +			mt76_put_rxwi(dev, r);
  			goto unmap;
  		}
  
- 		desc->buf0 = cpu_to_le32(phy_addr);
--		token = mt76_rx_token_consume(dev, ptr, t, phy_addr);
-+		token = mt76_rx_token_consume(dev, ptr, r, phy_addr);
+ 		desc->buf0 = cpu_to_le32(addr);
+-		token = mt76_rx_token_consume(dev, ptr, t, addr);
++		token = mt76_rx_token_consume(dev, ptr, r, addr);
  		if (token < 0) {
- 			dma_unmap_single(dev->dma_dev, phy_addr,
+ 			dma_unmap_single(dev->dma_dev, addr,
  					 wed->wlan.rx_size, DMA_TO_DEVICE);
 -			__free_pages(page, get_order(length));
 -			mt76_put_rxwi(dev, t);
@@ -387,7 +386,7 @@
  		}
  
 diff --git a/mt76.h b/mt76.h
-index 3af97e5..b960f3d 100644
+index e7b798b2..17b39179 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -200,6 +200,7 @@ struct mt76_queue_entry {
@@ -398,7 +397,7 @@
  		struct urb *urb;
  		int buf_sz;
  	};
-@@ -410,10 +411,14 @@ struct mt76_txwi_cache {
+@@ -410,12 +411,16 @@ struct mt76_txwi_cache {
  	struct list_head list;
  	dma_addr_t dma_addr;
  
@@ -406,6 +405,9 @@
 -		struct sk_buff *skb;
 -		void *ptr;
 -	};
+-
+ 	unsigned long jiffies;
++
 +	struct sk_buff *skb;
 +};
 +
@@ -417,7 +419,7 @@
  };
  
  struct mt76_rx_tid {
-@@ -499,6 +504,7 @@ struct mt76_driver_ops {
+@@ -503,6 +508,7 @@ struct mt76_driver_ops {
  	u16 txwi_size;
  	u16 token_size;
  	u8 mcs_rates;
@@ -425,7 +427,7 @@
  
  	void (*update_survey)(struct mt76_phy *phy);
  
-@@ -858,7 +864,6 @@ struct mt76_dev {
+@@ -880,7 +886,6 @@ struct mt76_dev {
  
  	struct ieee80211_hw *hw;
  
@@ -433,7 +435,7 @@
  	spinlock_t lock;
  	spinlock_t cc_lock;
  
-@@ -1521,8 +1526,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
+@@ -1547,8 +1552,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
  }
  
  void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
@@ -444,7 +446,7 @@
  void mt76_free_pending_rxwi(struct mt76_dev *dev);
  void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
  		      struct napi_struct *napi);
-@@ -1703,9 +1708,9 @@ struct mt76_txwi_cache *
+@@ -1734,9 +1739,9 @@ struct mt76_txwi_cache *
  mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
  int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi);
  void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
@@ -457,19 +459,19 @@
  static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
  {
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 85cb3fe..690cac5 100644
+index aff4f21e..9657636e 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -687,7 +687,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -680,7 +680,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  	wed->wlan.reset = mt7915_mmio_wed_reset;
- 	wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete;
+ 	wed->wlan.reset_complete = mt76_mmio_wed_reset_complete;
  
 -	dev->mt76.rx_token_size = wed->wlan.rx_npkt;
 +	dev->mt76.rx_token_size += wed->wlan.rx_npkt;
  
  	if (mtk_wed_device_attach(wed))
  		return 0;
-@@ -893,6 +893,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
+@@ -886,6 +886,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
  				SURVEY_INFO_TIME_RX |
  				SURVEY_INFO_TIME_BSS_RX,
  		.token_size = MT7915_TOKEN_SIZE,
@@ -478,7 +480,7 @@
  		.tx_complete_skb = mt76_connac_tx_complete_skb,
  		.rx_skb = mt7915_queue_rx_skb,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index d317c52..91eb5ad 100644
+index 4727d9c7..ec224b46 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -62,6 +62,7 @@
@@ -490,10 +492,10 @@
  #define MT7915_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
  #define MT7915_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
 diff --git a/tx.c b/tx.c
-index 1809b03..74bf0de 100644
+index 4596b367..e0c3e854 100644
 --- a/tx.c
 +++ b/tx.c
-@@ -843,16 +843,16 @@ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
+@@ -851,16 +851,16 @@ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
  EXPORT_SYMBOL_GPL(mt76_token_consume);
  
  int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
@@ -514,7 +516,7 @@
  	}
  	spin_unlock_bh(&dev->rx_token_lock);
  
-@@ -889,15 +889,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
+@@ -897,15 +897,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
  }
  EXPORT_SYMBOL_GPL(mt76_token_release);
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2002-mtk-wifi-mt76-wed-change-wed-token-init-size-to-adap.patch
similarity index 75%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2002-mtk-wifi-mt76-wed-change-wed-token-init-size-to-adap.patch
index 3dc3543..a4cf2c7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2002-mtk-wifi-mt76-wed-change-wed-token-init-size-to-adap.patch
@@ -1,8 +1,8 @@
-From 1c0cb4fc09293006efdf8d1a9e92715a5705c29e Mon Sep 17 00:00:00 2001
+From cdecc4effebebbd6344eaf94516e8336afe70792 Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Wed, 19 Apr 2023 17:13:41 +0800
-Subject: [PATCH 66/98] wifi: mt76: wed: change wed token init size to adapt
- wed3.0
+Subject: [PATCH 2002/2020] mtk: wifi: mt76: wed: change wed token init size to
+ adapt wed3.0
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
 ---
@@ -10,10 +10,10 @@
  1 file changed, 7 insertions(+), 3 deletions(-)
 
 diff --git a/tx.c b/tx.c
-index 74bf0de..3857c2a 100644
+index e0c3e854..1420ff71 100644
 --- a/tx.c
 +++ b/tx.c
-@@ -819,12 +819,16 @@ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
+@@ -827,12 +827,16 @@ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
  
  int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
  {
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2003-mtk-wifi-mt76-add-random-early-drop-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2003-mtk-wifi-mt76-add-random-early-drop-support.patch
new file mode 100644
index 0000000..51ffcfe
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2003-mtk-wifi-mt76-add-random-early-drop-support.patch
@@ -0,0 +1,316 @@
+From e0fcc09873c502b3591934ad11d4382f78210b97 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Wed, 19 Apr 2023 18:32:41 +0800
+Subject: [PATCH 2003/2020] mtk: wifi: mt76: add random early drop support
+
+---
+ mt7996/debugfs.c     |  1 +
+ mt7996/mac.c         |  7 ++++
+ mt7996/mcu.c         | 81 ++++++++++++++++++++++++++++++++++++++++++--
+ mt7996/mcu.h         |  4 ++-
+ mt7996/mt7996.h      |  5 ++-
+ mt7996/mtk_debugfs.c | 23 +++++++++++++
+ mt7996/mtk_mcu.c     | 26 ++++++++++++++
+ mt7996/mtk_mcu.h     | 24 +++++++++++++
+ 8 files changed, 167 insertions(+), 4 deletions(-)
+
+diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
+index 67c6bd09..223b655e 100644
+--- a/mt7996/debugfs.c
++++ b/mt7996/debugfs.c
+@@ -621,6 +621,7 @@ mt7996_tx_stats_show(struct seq_file *file, void *data)
+ 	seq_printf(file, "Tx attempts: %8u (MPDUs)\n", attempts);
+ 	seq_printf(file, "Tx success: %8u (MPDUs)\n", success);
+ 	seq_printf(file, "Tx PER: %u%%\n", per);
++	seq_printf(file, "Tx RED drop: %8u\n", phy->red_drop);
+ 
+ 	mt7996_txbf_stat_read_phy(phy, file);
+ 
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 408a59c5..a9d8f7dd 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1176,6 +1176,13 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+ 
+ 			wcid->stats.tx_retries += tx_retries;
+ 			wcid->stats.tx_failed += tx_failed;
++
++			if (FIELD_GET(MT_TXFREE_INFO_STAT, info) == 2) {
++				struct mt7996_phy *mphy =
++					__mt7996_phy(dev, wcid->phy_idx);
++
++				mphy->red_drop++;
++			}
+ 			continue;
+ 		}
+ 
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index c980f345..e893e79b 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3140,8 +3140,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
+-	return mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
+-				 MCU_WA_PARAM_RED, 0, 0);
++	return mt7996_mcu_red_config(dev,
++			mtk_wed_device_active(&dev->mt76.mmio.wed));
+ }
+ 
+ int mt7996_mcu_init(struct mt7996_dev *dev)
+@@ -3173,6 +3173,83 @@ out:
+ 	skb_queue_purge(&dev->mt76.mcu.res_q);
+ }
+ 
++static int mt7996_mcu_wa_red_config(struct mt7996_dev *dev)
++{
++#define RED_TOKEN_SRC_CNT	4
++#define RED_TOKEN_CONFIG	2
++	struct {
++		__le32 arg0;
++		__le32 arg1;
++		__le32 arg2;
++
++		u8 mode;
++		u8 version;
++		u8 _rsv[4];
++		__le16 len;
++
++		__le16 tcp_offset;
++		__le16 priority_offset;
++		__le16 token_per_src[RED_TOKEN_SRC_CNT];
++		__le16 token_thr_per_src[RED_TOKEN_SRC_CNT];
++
++		u8 _rsv2[604];
++	} __packed req = {
++		.arg0 = cpu_to_le32(MCU_WA_PARAM_RED_CONFIG),
++
++		.mode = RED_TOKEN_CONFIG,
++		.len = cpu_to_le16(sizeof(req) - sizeof(__le32) * 3),
++
++		.tcp_offset = cpu_to_le16(200),
++		.priority_offset = cpu_to_le16(255),
++	};
++	u8 i;
++
++	for (i = 0; i < RED_TOKEN_SRC_CNT; i++) {
++		req.token_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE);
++		req.token_thr_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE);
++	}
++
++	if (!mtk_wed_device_active(&dev->mt76.mmio.wed))
++		req.token_per_src[RED_TOKEN_SRC_CNT - 1] =
++			cpu_to_le16(MT7996_TOKEN_SIZE - MT7996_HW_TOKEN_SIZE);
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET),
++				 &req, sizeof(req), false);
++}
++
++int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable)
++{
++#define RED_DISABLE		0
++#define RED_BY_WA_ENABLE	2
++	struct {
++		u8 __rsv1[4];
++
++		__le16 tag;
++		__le16 len;
++		u8 enable;
++		u8 __rsv2[3];
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_VOW_RED_ENABLE),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.enable = enable ? RED_BY_WA_ENABLE : RED_DISABLE,
++	};
++	int ret;
++
++	ret = mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
++				 sizeof(req), true);
++
++	if (ret)
++		return ret;
++
++	ret = mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
++				MCU_WA_PARAM_RED_EN, enable, 0);
++
++	if (ret || !enable)
++		return ret;
++
++	return mt7996_mcu_wa_red_config(dev);
++}
++
+ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans)
+ {
+ 	struct {
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 398bf3d2..4fa399bc 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -346,8 +346,9 @@ enum {
+ enum {
+ 	MCU_WA_PARAM_PDMA_RX = 0x04,
+ 	MCU_WA_PARAM_CPU_UTIL = 0x0b,
+-	MCU_WA_PARAM_RED = 0x0e,
++	MCU_WA_PARAM_RED_EN = 0x0e,
+ 	MCU_WA_PARAM_HW_PATH_HIF_VER = 0x2f,
++	MCU_WA_PARAM_RED_CONFIG = 0x40,
+ };
+ 
+ enum mcu_mmps_mode {
+@@ -919,6 +920,7 @@ enum {
+ 	UNI_VOW_DRR_CTRL,
+ 	UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
+ 	UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
++	UNI_VOW_RED_ENABLE = 0x18,
+ };
+ 
+ enum {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 9bcb6ff8..e6a0b15a 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -351,6 +351,7 @@ struct mt7996_phy {
+ 	bool has_aux_rx;
+ 
+ 	struct mt7996_scs_ctrl scs_ctrl;
++	u32 red_drop;
+ 
+ 	u8 muru_onoff;
+ 
+@@ -696,6 +697,7 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
+ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
+ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val);
+ int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
++int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
+ int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
+ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
+ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
+@@ -869,11 +871,12 @@ void mt7996_mcu_set_ppdu_tx_type(struct mt7996_phy *phy, u8 ppdu_type);
+ void mt7996_mcu_set_nusers_ofdma(struct mt7996_phy *phy, u8 type, u8 ofdma_user_cnt);
+ void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type);
+ void mt7996_tm_update_channel(struct mt7996_phy *phy);
++
++int mt7996_mcu_set_vow_drr_dbg(struct mt7996_dev *dev, u32 val);
+ #endif
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ int mt7996_dma_rro_init(struct mt7996_dev *dev);
+ #endif /* CONFIG_NET_MEDIATEK_SOC_WED */
+ 
+-
+ #endif
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 0fdb911d..9cf3e6dc 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2919,6 +2919,27 @@ static int mt7996_muru_prot_thr_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_prot_thr, NULL,
+ 			 mt7996_muru_prot_thr_set, "%lld\n");
+ 
++static int
++mt7996_red_config_set(void *data, u64 val)
++{
++	struct mt7996_dev *dev = data;
++
++	return mt7996_mcu_red_config(dev, !!val);
++}
++
++DEFINE_DEBUGFS_ATTRIBUTE(fops_red_config, NULL,
++			 mt7996_red_config_set, "%lld\n");
++
++static int
++mt7996_vow_drr_dbg(void *data, u64 val)
++{
++	struct mt7996_dev *dev = data;
++
++	return mt7996_mcu_set_vow_drr_dbg(dev, (u32)val);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_vow_drr_dbg, NULL,
++			 mt7996_vow_drr_dbg, "%lld\n");
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -2995,6 +3016,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ 				    mt7996_wtbl_read);
+ 
+ 	debugfs_create_devm_seqfile(dev->mt76.dev, "token", dir, mt7996_token_read);
++	debugfs_create_file("red", 0200, dir, dev, &fops_red_config);
++	debugfs_create_file("vow_drr_dbg", 0200, dir, dev, &fops_vow_drr_dbg);
+ 
+ 	debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
+ 	debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index 2d8b08cd..6440efcf 100644
+--- a/mt7996/mtk_mcu.c
++++ b/mt7996/mtk_mcu.c
+@@ -1255,4 +1255,30 @@ void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type)
+ 			  sizeof(req), false);
+ }
+ 
++int mt7996_mcu_set_vow_drr_dbg(struct mt7996_dev *dev, u32 val)
++{
++#define MT7996_VOW_DEBUG_MODE	0xe
++	struct {
++		u8 __rsv1[4];
++
++		__le16 tag;
++		__le16 len;
++		u8 __rsv2[4];
++		__le32 action;
++		__le32 val;
++		u8 __rsv3[8];
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_VOW_DRR_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.action = cpu_to_le32(MT7996_VOW_DEBUG_MODE),
++		.val = cpu_to_le32(val),
++	};
++
++	if (val & ~VOW_DRR_DBG_FLAGS)
++		return -EINVAL;
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
++				 sizeof(req), true);
++}
++
+ #endif
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index 881afef1..7d76bfea 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -1022,6 +1022,30 @@ enum muru_vendor_ctrl {
+ 	MU_CTRL_DL_USER_CNT,
+ 	MU_CTRL_UL_USER_CNT,
+ };
++
++enum {
++	VOW_DRR_DBG_DUMP_BMP = BIT(0),
++	VOW_DRR_DBG_EST_AT_PRINT = BIT(1),
++	VOW_DRR_DBG_ADJ_GLOBAL_THLD = BIT(21),
++	VOW_DRR_DBG_PRN_LOUD = BIT(22),
++	VOW_DRR_DBG_PRN_ADJ_STA = BIT(23),
++	VOW_DRR_DBG_FIX_CR = GENMASK(27, 24),
++	VOW_DRR_DBG_CLR_FIX_CR = BIT(28),
++	VOW_DRR_DBG_DISABLE = BIT(29),
++	VOW_DRR_DBG_DUMP_CR = BIT(30),
++	VOW_DRR_DBG_PRN = BIT(31)
++};
++
++#define VOW_DRR_DBG_FLAGS (VOW_DRR_DBG_DUMP_BMP |	\
++			  VOW_DRR_DBG_EST_AT_PRINT |	\
++			  VOW_DRR_DBG_ADJ_GLOBAL_THLD |	\
++			  VOW_DRR_DBG_PRN_LOUD |	\
++			  VOW_DRR_DBG_PRN_ADJ_STA |	\
++			  VOW_DRR_DBG_FIX_CR |		\
++			  VOW_DRR_DBG_CLR_FIX_CR |	\
++			  VOW_DRR_DBG_DISABLE |		\
++			  VOW_DRR_DBG_DUMP_CR |		\
++			  VOW_DRR_DBG_PRN)
+ #endif
+ 
+ #endif
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-add-random-early-drop-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-add-random-early-drop-support.patch
deleted file mode 100644
index e21fa8b..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-add-random-early-drop-support.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 50d93c608b1cfe0750fa98c1fbafe6ad6ed3212d Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Wed, 19 Apr 2023 18:32:41 +0800
-Subject: [PATCH 67/98] wifi: mt76: add random early drop support
-
----
- mt7996/mcu.c    | 81 +++++++++++++++++++++++++++++++++++++++++++++++--
- mt7996/mcu.h    |  4 ++-
- mt7996/mt7996.h |  1 +
- 3 files changed, 83 insertions(+), 3 deletions(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index b8d26ec..6589610 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -3012,8 +3012,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
--	return mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
--				 MCU_WA_PARAM_RED, 0, 0);
-+	return mt7996_mcu_red_config(dev,
-+			mtk_wed_device_active(&dev->mt76.mmio.wed));
- }
- 
- int mt7996_mcu_init(struct mt7996_dev *dev)
-@@ -3045,6 +3045,83 @@ out:
- 	skb_queue_purge(&dev->mt76.mcu.res_q);
- }
- 
-+static int mt7996_mcu_wa_red_config(struct mt7996_dev *dev)
-+{
-+#define RED_TOKEN_SRC_CNT	4
-+#define RED_TOKEN_CONFIG	2
-+	struct {
-+		__le32 arg0;
-+		__le32 arg1;
-+		__le32 arg2;
-+
-+		u8 mode;
-+		u8 version;
-+		u8 _rsv[4];
-+		__le16 len;
-+
-+		__le16 tcp_offset;
-+		__le16 priority_offset;
-+		__le16 token_per_src[RED_TOKEN_SRC_CNT];
-+		__le16 token_thr_per_src[RED_TOKEN_SRC_CNT];
-+
-+		u8 _rsv2[604];
-+	} __packed req = {
-+		.arg0 = cpu_to_le32(MCU_WA_PARAM_RED_CONFIG),
-+
-+		.mode = RED_TOKEN_CONFIG,
-+		.len = cpu_to_le16(sizeof(req) - sizeof(__le32) * 3),
-+
-+		.tcp_offset = cpu_to_le16(200),
-+		.priority_offset = cpu_to_le16(255),
-+	};
-+	u8 i;
-+
-+	for (i = 0; i < RED_TOKEN_SRC_CNT; i++) {
-+		req.token_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE);
-+		req.token_thr_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE);
-+	}
-+
-+	if (!mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		req.token_per_src[RED_TOKEN_SRC_CNT - 1] =
-+			cpu_to_le16(MT7996_TOKEN_SIZE - MT7996_HW_TOKEN_SIZE);
-+
-+	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET),
-+				 &req, sizeof(req), false);
-+}
-+
-+int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable)
-+{
-+#define RED_DISABLE		0
-+#define RED_BY_WA_ENABLE	2
-+	struct {
-+		u8 __rsv1[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+		u8 enable;
-+		u8 __rsv2[3];
-+	} __packed req = {
-+		.tag = cpu_to_le16(UNI_VOW_RED_ENABLE),
-+		.len = cpu_to_le16(sizeof(req) - 4),
-+		.enable = enable ? RED_BY_WA_ENABLE : RED_DISABLE,
-+	};
-+	int ret;
-+
-+	ret = mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
-+				 sizeof(req), true);
-+
-+	if (ret)
-+		return ret;
-+
-+	ret = mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
-+				MCU_WA_PARAM_RED_EN, enable, 0);
-+
-+	if (ret || !enable)
-+		return ret;
-+
-+	return mt7996_mcu_wa_red_config(dev);
-+}
-+
- int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans)
- {
- 	struct {
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index bb876f3..666216a 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -287,8 +287,9 @@ enum {
- enum {
- 	MCU_WA_PARAM_PDMA_RX = 0x04,
- 	MCU_WA_PARAM_CPU_UTIL = 0x0b,
--	MCU_WA_PARAM_RED = 0x0e,
-+	MCU_WA_PARAM_RED_EN = 0x0e,
- 	MCU_WA_PARAM_HW_PATH_HIF_VER = 0x2f,
-+	MCU_WA_PARAM_RED_CONFIG = 0x40,
- };
- 
- enum mcu_mmps_mode {
-@@ -817,6 +818,7 @@ enum {
- 	UNI_VOW_DRR_CTRL,
- 	UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
- 	UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
-+	UNI_VOW_RED_ENABLE = 0x18,
- };
- 
- enum {
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 6775360..bba1364 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -654,6 +654,7 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
- int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
- int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
- int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
-+int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
- int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
- int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
- int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2004-mtk-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2004-mtk-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
new file mode 100644
index 0000000..8ddf523
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2004-mtk-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
@@ -0,0 +1,93 @@
+From 97a7decba0c4e4d3fb25a869caba6fd8928ffdab Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Thu, 18 May 2023 15:01:47 +0800
+Subject: [PATCH 2004/2020] mtk: wifi: mt76: mt7996: reset addr_elem when
+ delete ba
+
+The old addr element info may be used when the signature is not equel to
+0xff, and sta will find error SDP cause the SDP/SDL=0 issue.
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+
+1. without this patch will delete wrong session id when delete ba.
+Due to fw change the cmd format.
+https://gerrit.mediatek.inc/c/neptune/firmware/bora/wifi/custom/+/7969193
+
+Signed-off-by: mtk27745 <rex.lu@mediatek.com>
+---
+ mt76.h       |  1 +
+ mt7996/mcu.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/mt76.h b/mt76.h
+index 17b39179..2ce1e84e 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -438,6 +438,7 @@ struct mt76_rx_tid {
+ 	u16 nframes;
+ 
+ 	u8 num;
++	u16 session_id;
+ 
+ 	u8 started:1, stopped:1, timer_pending:1;
+ 
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 4fa399bc..a2604192 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -298,6 +298,52 @@ struct mt7996_mcu_thermal_notify {
+ 	u8 __rsv2[4];
+ } __packed;
+ 
++struct mt7996_mcu_rro_event {
++	struct mt7996_mcu_rxd rxd;
++
++	u8 __rsv1[4];
++
++	__le16 tag;
++	__le16 len;
++} __packed;
++
++struct mt7996_mcu_rro_ba {
++	__le16 tag;
++	__le16 len;
++
++	__le16 wlan_id;
++	u8 tid;
++	u8 __rsv1;
++	__le32 status;
++	__le16 session_id;
++	u8 __rsv2[2];
++} __packed;
++
++struct mt7996_mcu_rro_ba_del_chk_done {
++	__le16 tag;
++	__le16 len;
++
++	__le16 session_id;
++	__le16 mld_id;
++	u8 tid;
++	u8 __rsv[3];
++} __packed;
++
++enum  {
++	UNI_RRO_BA_SESSION_STATUS = 0,
++	UNI_RRO_BA_SESSION_TBL	= 1,
++	UNI_RRO_BA_SESSION_DEL_CHK_DONE = 2,
++	UNI_RRO_BA_SESSION_MAX_NUM
++};
++
++struct mt7996_mcu_rro_del_ba {
++	struct mt7996_mcu_rro_event event;
++
++	u8  wlan_idx;
++	u8  tid;
++	u8 __rsv2[2];
++};
++
+ enum mt7996_chan_mib_offs {
+ 	UNI_MIB_OBSS_AIRTIME = 26,
+ 	UNI_MIB_NON_WIFI_TIME = 27,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
deleted file mode 100644
index d9fe625..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
+++ /dev/null
@@ -1,425 +0,0 @@
-From d663fd304a7bd5701b2b3ac42b4743dabb252750 Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Thu, 18 May 2023 15:01:47 +0800
-Subject: [PATCH 68/98] wifi: mt76: mt7996: reset addr_elem when delete ba
-
-The old addr element info may be used when the signature is not equel to
-0xff, and sta will find error SDP cause the SDP/SDL=0 issue.
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- mt76.h            |  1 +
- mt76_connac_mcu.h |  1 +
- mt7996/init.c     |  3 ++
- mt7996/mac.c      | 97 +++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.c      | 77 +++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      | 46 ++++++++++++++++++++++
- mt7996/mt7996.h   | 27 +++++++++++++
- mt7996/regs.h     |  6 +++
- 8 files changed, 258 insertions(+)
-
-diff --git a/mt76.h b/mt76.h
-index b960f3d..bea58ff 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -434,6 +434,7 @@ struct mt76_rx_tid {
- 	u16 nframes;
- 
- 	u8 num;
-+	u16 session_id;
- 
- 	u8 started:1, stopped:1, timer_pending:1;
- 
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index e904ebc..f659d2e 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1038,6 +1038,7 @@ enum {
- 	MCU_UNI_EVENT_THERMAL = 0x35,
- 	MCU_UNI_EVENT_NIC_CAPAB = 0x43,
- 	MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
-+	MCU_UNI_EVENT_RRO = 0x57,
- 	MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
- 	MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
- };
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 4503482..1f01f24 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -779,6 +779,9 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
- 	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
- 		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
- 
-+	INIT_WORK(&dev->wed_rro.rro_del_work, mt7996_rro_delete_sessions);
-+	INIT_LIST_HEAD(&dev->wed_rro.rro_poll_list);
-+
- 	/* rro ind cmd queue init */
- 	return mt7996_dma_rro_init(dev);
- #else
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index b24f237..60ca23b 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1450,6 +1450,96 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 	}
- }
- 
-+static struct mt7996_wed_rro_addr *
-+mt7996_rro_get_addr_elem(struct mt7996_dev *dev, u16 seid, u16 sn)
-+{
-+	u32 idx;
-+	void *addr;
-+
-+	if (seid == MT7996_RRO_MAX_SESSION) {
-+		addr = dev->wed_rro.session.ptr;
-+		idx = sn % MT7996_RRO_WINDOW_MAX_LEN;
-+	} else {
-+		addr = dev->wed_rro.addr_elem[seid / MT7996_RRO_BA_BITMAP_SESSION_SIZE].ptr;
-+		idx = (seid % MT7996_RRO_BA_BITMAP_SESSION_SIZE) * MT7996_RRO_WINDOW_MAX_LEN
-+			+ (sn % MT7996_RRO_WINDOW_MAX_LEN);
-+	}
-+	return addr + idx * sizeof(struct mt7996_wed_rro_addr);
-+}
-+
-+static bool mt7996_rro_reset_sessions(struct mt7996_dev *dev, u16 session_id)
-+{
-+	struct  mt7996_wed_rro_addr *elem;
-+	int i;
-+
-+	for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {
-+		elem = mt7996_rro_get_addr_elem(dev, session_id, i);
-+		elem->signature = 0xff;
-+	}
-+	return true;
-+
-+}
-+
-+void  mt7996_rro_delete_sessions(struct work_struct *work)
-+{
-+	struct mt7996_dev *dev;
-+	struct mt7996_rro_ba_session_elem *e;
-+	int elem_nums;
-+	LIST_HEAD(rro_poll_list);
-+
-+	dev = (struct mt7996_dev *)container_of(work, struct mt7996_dev,
-+					       wed_rro.rro_del_work);
-+	elem_nums = dev->wed_rro.elem_nums;
-+
-+	spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
-+	list_splice_init(&dev->wed_rro.rro_poll_list, &rro_poll_list);
-+	spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
-+
-+	do {
-+		spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
-+		if (list_empty(&rro_poll_list)) {
-+			spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
-+			break;
-+		}
-+
-+		e = list_first_entry(&rro_poll_list,
-+				     struct mt7996_rro_ba_session_elem,
-+				     poll_list);
-+		if (!e) {
-+			spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
-+			break;
-+		}
-+		list_del_init(&e->poll_list);
-+		spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
-+
-+		if (mt7996_rro_reset_sessions(dev, e->session_id)) {
-+			mt7996_mcu_reset_rro_sessions(dev, e->session_id);
-+			kfree(e);
-+			dev->wed_rro.elem_nums--;
-+		}
-+		elem_nums--;
-+	} while (elem_nums);
-+}
-+
-+int mt7996_rro_add_delete_elem(struct mt7996_dev *dev, u16 seid)
-+{
-+	struct mt7996_rro_ba_session_elem *e;
-+
-+	e = kzalloc(sizeof(*e), GFP_ATOMIC);
-+	if (!e)
-+		return -ENOMEM;
-+
-+	e->session_id = seid;
-+
-+	spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
-+	list_add_tail(&e->poll_list, &dev->wed_rro.rro_poll_list);
-+	spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
-+	dev->wed_rro.elem_nums++;
-+
-+	ieee80211_queue_work(mt76_hw(dev), &dev->wed_rro.rro_del_work);
-+	return 0;
-+}
-+
- void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy)
- {
- 	struct mt7996_dev *dev = phy->dev;
-@@ -1774,6 +1864,9 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
- 	if (phy3)
- 		ieee80211_stop_queues(phy3->mt76->hw);
- 
-+	if (dev->has_rro)
-+		cancel_work_sync(&dev->wed_rro.rro_del_work);
-+
- 	cancel_delayed_work_sync(&dev->mphy.mac_work);
- 	if (phy2)
- 		cancel_delayed_work_sync(&phy2->mt76->mac_work);
-@@ -1865,6 +1958,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 	set_bit(MT76_RESET, &dev->mphy.state);
- 	set_bit(MT76_MCU_RESET, &dev->mphy.state);
- 	wake_up(&dev->mt76.mcu.wait);
-+
-+	if (dev->has_rro)
-+		cancel_work_sync(&dev->wed_rro.rro_del_work);
-+
- 	cancel_delayed_work_sync(&dev->mphy.mac_work);
- 	if (phy2) {
- 		set_bit(MT76_RESET, &phy2->mt76->state);
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 6589610..ce38a5e 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -538,6 +538,60 @@ mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rat
- 	return 0;
- }
- 
-+static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
-+{
-+	struct mt7996_mcu_rro_event *event;
-+	struct mt7996_mcu_rro_ba *rro;
-+	struct mt7996_mcu_rro_ba_del_chk_done *delba;
-+	u16 len;
-+
-+	if (!dev->has_rro)
-+		return;
-+
-+	event = (struct mt7996_mcu_rro_event *)skb->data;
-+	skb_pull(skb, sizeof(struct mt7996_mcu_rxd) + 4);
-+
-+	switch (event->tag) {
-+	case UNI_RRO_BA_SESSION_STATUS: {
-+		len = sizeof(struct mt7996_mcu_rro_ba);
-+		while (unlikely(len > skb->len) ? NULL : true) {
-+			rro = (struct mt7996_mcu_rro_ba *)skb->data;
-+			u16 idx = cpu_to_le16(rro->wlan_id);
-+			struct mt76_rx_tid *tid;
-+			struct mt76_wcid *wcid;
-+
-+			wcid = rcu_dereference(dev->mt76.wcid[idx]);
-+			if (!wcid || !wcid->sta)
-+				return;
-+
-+			tid = rcu_dereference(wcid->aggr[rro->tid]);
-+			if (!tid)
-+				return;
-+			tid->session_id = cpu_to_le16(rro->session_id);
-+			skb_pull(skb, len);
-+		}
-+		break;
-+	}
-+	case UNI_RRO_BA_SESSION_DEL_CHK_DONE: {
-+		len = sizeof(struct mt7996_mcu_rro_ba_del_chk_done);
-+		while (unlikely(len > skb->len) ? NULL : true) {
-+			delba = (struct mt7996_mcu_rro_ba_del_chk_done *)skb->data;
-+			u16 session_id = cpu_to_le16(delba->session_id);
-+
-+			mt7996_rro_add_delete_elem(dev, session_id);
-+			skb_pull(skb, len);
-+		}
-+		break;
-+	}
-+
-+	default:
-+		dev_info(dev->mt76.dev, "%s: unknown rro event tag %d\n",
-+			 __func__, event->tag);
-+		break;
-+	}
-+
-+}
-+
- static void
- mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
- {
-@@ -663,6 +717,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
- 		mt7996_tm_rf_test_event(dev, skb);
- 		break;
- #endif
-+	case MCU_UNI_EVENT_RRO:
-+		mt7996_mcu_rx_rro(dev, skb);
-+		break;
- 	default:
- 		break;
- 	}
-@@ -4615,6 +4672,26 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
- 				 sizeof(req), true);
- }
- 
-+int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev, u16 seid)
-+{
-+	struct {
-+		/* fixed field */
-+		u8 __rsv[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+		__le16 session_id;
-+		u8 pad[4];
-+	} __packed req = {
-+		.tag = cpu_to_le16(UNI_RRO_DEL_BA_SESSION),
-+		.len = cpu_to_le16(sizeof(req) - 4),
-+		.session_id = cpu_to_le16(seid),
-+	};
-+
-+	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO),
-+				 &req, sizeof(req), true);
-+}
-+
- int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
- {
- 	struct mt7996_dev *dev = phy->dev;
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 666216a..0aa68f7 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -239,6 +239,50 @@ struct mt7996_mcu_all_sta_info_event {
- 	};
- } __packed;
- 
-+struct mt7996_mcu_rro_event {
-+	struct mt7996_mcu_rxd rxd;
-+
-+	u8 __rsv1[4];
-+
-+	__le16 tag;
-+	__le16 len;
-+} __packed;
-+
-+struct mt7996_mcu_rro_ba {
-+	__le16 tag;
-+	__le16 len;
-+
-+	__le16 wlan_id;
-+	u8 tid;
-+	u8 __rsv1;
-+	__le32 status;
-+	__le16 session_id;
-+	u8 __rsv2[2];
-+} __packed;
-+
-+struct mt7996_mcu_rro_ba_del_chk_done {
-+	__le16 tag;
-+	__le16 len;
-+
-+	__le16 session_id;
-+	u8 __rsv2[2];
-+} __packed;
-+
-+enum  {
-+	UNI_RRO_BA_SESSION_STATUS = 0,
-+	UNI_RRO_BA_SESSION_TBL	= 1,
-+	UNI_RRO_BA_SESSION_DEL_CHK_DONE = 2,
-+	UNI_RRO_BA_SESSION_MAX_NUM
-+};
-+
-+struct mt7996_mcu_rro_del_ba {
-+	struct mt7996_mcu_rro_event event;
-+
-+	u8  wlan_idx;
-+	u8  tid;
-+	u8 __rsv2[2];
-+};
-+
- enum mt7996_chan_mib_offs {
- 	UNI_MIB_OBSS_AIRTIME = 26,
- 	UNI_MIB_NON_WIFI_TIME = 27,
-@@ -840,6 +884,8 @@ enum {
- 	UNI_RRO_GET_BA_SESSION_TABLE,
- 	UNI_RRO_SET_BYPASS_MODE,
- 	UNI_RRO_SET_TXFREE_PATH,
-+	UNI_RRO_DEL_BA_SESSION,
-+	UNI_RRO_SET_FLUSH_TIMEOUT
- };
- 
- enum{
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index bba1364..af67c59 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -282,6 +282,26 @@ struct mt7996_wed_rro_addr {
- 	u32 signature : 8;
- };
- 
-+struct mt7996_rro_ba_session {
-+	u32 ack_sn         :12;
-+	u32 win_sz         :3;
-+	u32 bn             :1;
-+	u32 last_in_sn     :12;
-+	u32 bc             :1;
-+	u32 bd             :1;
-+	u32 sat            :1;
-+	u32 cn             :1;
-+	u32 within_cnt     :12;
-+	u32 to_sel         :3;
-+	u32 rsv            :1;
-+	u32 last_in_rxtime :12;
-+};
-+
-+struct mt7996_rro_ba_session_elem {
-+	struct list_head poll_list;
-+	u16 session_id;
-+};
-+
- struct mt7996_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7996_dev *dev;
-@@ -418,6 +438,10 @@ struct mt7996_dev {
- 			void *ptr;
- 			dma_addr_t phy_addr;
- 		} session;
-+		struct work_struct rro_del_work;
-+		spinlock_t rro_stbl_lock;
-+		struct list_head rro_poll_list;
-+		u16 elem_nums;
- 	} wed_rro;
- 
- 	bool testmode_enable;
-@@ -653,6 +677,7 @@ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
- int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
- int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
- int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
-+int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev, u16 seid);
- int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
- int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
- int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
-@@ -757,6 +782,8 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- 			  struct ieee80211_sta *sta,
- 			  struct mt76_tx_info *tx_info);
- void mt7996_tx_token_put(struct mt7996_dev *dev);
-+void  mt7996_rro_delete_sessions(struct work_struct *work);
-+int mt7996_rro_add_delete_elem(struct mt7996_dev *dev, u16 seid);
- void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 			 struct sk_buff *skb, u32 *info);
- bool mt7996_rx_check(struct mt76_dev *mdev, void *data, int len);
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index d305c25..38467d9 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -101,6 +101,12 @@ enum offs_rev {
- #define MT_RRO_ACK_SN_CTRL_SN_MASK		GENMASK(27, 16)
- #define MT_RRO_ACK_SN_CTRL_SESSION_MASK		GENMASK(11, 0)
- 
-+#define MT_RRO_DBG_RD_CTRL			MT_RRO_TOP(0xe0)
-+#define MT_RRO_DBG_RD_ADDR			GENMASK(15, 0)
-+#define MT_RRO_DBG_RD_EXEC			BIT(31)
-+
-+#define MT_RRO_DBG_RDAT_DW(_n)			MT_RRO_TOP(0xf0 + _n * 0x4)
-+
- #define MT_MCU_INT_EVENT			0x2108
- #define MT_MCU_INT_EVENT_DMA_STOPPED		BIT(0)
- #define MT_MCU_INT_EVENT_DMA_INIT		BIT(1)
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2005-mtk-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2005-mtk-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G.patch
new file mode 100644
index 0000000..f322d86
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2005-mtk-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G.patch
@@ -0,0 +1,68 @@
+From cd5a67a360ea7897a5129ae5b4b4c1fee73837dc Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Fri, 6 Oct 2023 14:01:41 +0800
+Subject: [PATCH 2005/2020] mtk: wifi: mt76 : wed : change pcie0 R5 to pcie1 to
+ get 6G ICS
+
+---
+ mt7996/dma.c  | 4 ++++
+ mt7996/init.c | 6 ++----
+ mt7996/mmio.c | 5 ++++-
+ 3 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 8e29ab06..40ab65f8 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -537,6 +537,10 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 	if (mt7996_band_valid(dev, MT_BAND2)) {
+ 		/* rx data queue for mt7996 band2 */
+ 		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
++		if (mtk_wed_device_active(wed_hif2) && mtk_wed_get_rx_capa(wed_hif2)) {
++			dev->mt76.q_rx[MT_RXQ_BAND2].flags = MT_WED_Q_RX(0);
++			dev->mt76.q_rx[MT_RXQ_BAND2].wed = wed_hif2;
++		}
+ 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
+ 				       MT_RXQ_ID(MT_RXQ_BAND2),
+ 				       MT7996_RX_RING_SIZE,
+diff --git a/mt7996/init.c b/mt7996/init.c
+index c7576ffe..10b17f7d 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -642,10 +642,8 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 		goto error;
+ 
+ 	if (wed == &dev->mt76.mmio.wed_hif2 && mtk_wed_device_active(wed)) {
+-		u32 irq_mask = dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2;
+-
+-		mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask);
+-		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask);
++		mt76_wr(dev, MT_INT_PCIE1_MASK_CSR, MT_INT_TX_RX_DONE_EXT);
++		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, MT_INT_TX_RX_DONE_EXT);
+ 	}
+ 
+ 	return 0;
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index d3d34f04..4814897c 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -532,12 +532,15 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
+ 					       dev->mt76.mmio.irqmask);
+ 		if (intr1 & MT_INT_RX_TXFREE_EXT)
+ 			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
++
++		if (intr1 & MT_INT_RX_DONE_BAND2_EXT)
++			napi_schedule(&dev->mt76.napi[MT_RXQ_BAND2]);
+ 	}
+ 
+ 	if (mtk_wed_device_active(wed)) {
+ 		mtk_wed_device_irq_set_mask(wed, 0);
+ 		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
+-		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
++		intr |= (intr1 & ~MT_INT_TX_RX_DONE_EXT);
+ 	} else {
+ 		mt76_wr(dev, MT_INT_MASK_CSR, 0);
+ 		if (dev->hif2)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G-ICS.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G-ICS.patch
deleted file mode 100644
index 306c6e6..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G-ICS.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 161fde22deceee4e676f62b9d3b0366ffe52dc07 Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Fri, 6 Oct 2023 14:01:41 +0800
-Subject: [PATCH 69/98] wifi: mt76 : wed : change pcie0 R5 to pcie1 to get 6G
- ICS
-
----
- mt7996/dma.c  | 4 ++++
- mt7996/init.c | 6 ++----
- mt7996/mmio.c | 5 ++++-
- mt7996/regs.h | 6 ++++++
- 4 files changed, 16 insertions(+), 5 deletions(-)
-
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 23f6f16..2397fe5 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -519,6 +519,10 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 	if (mt7996_band_valid(dev, MT_BAND2)) {
- 		/* rx data queue for band2 */
- 		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
-+		if (mtk_wed_device_active(wed_hif2) && mtk_wed_get_rx_capa(wed_hif2)) {
-+			dev->mt76.q_rx[MT_RXQ_BAND2].flags = MT_WED_Q_RX(0);
-+			dev->mt76.q_rx[MT_RXQ_BAND2].wed = wed_hif2;
-+		}
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
- 				       MT_RXQ_ID(MT_RXQ_BAND2),
- 				       MT7996_RX_RING_SIZE,
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 1f01f24..5627605 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -619,10 +619,8 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 		goto error;
- 
- 	if (wed == &dev->mt76.mmio.wed_hif2 && mtk_wed_device_active(wed)) {
--		u32 irq_mask = dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2;
--
--		mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask);
--		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask);
-+		mt76_wr(dev, MT_INT_PCIE1_MASK_CSR, MT_INT_TRX_DONE_EXT);
-+		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, MT_INT_TRX_DONE_EXT);
- 	}
- 
- 	return 0;
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 2132b2e..2e395d1 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -504,12 +504,15 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
- 					       dev->mt76.mmio.irqmask);
- 		if (intr1 & MT_INT_RX_TXFREE_EXT)
- 			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
-+
-+		if (intr1 & MT_INT_RX_DONE_BAND2_EXT)
-+			napi_schedule(&dev->mt76.napi[MT_RXQ_BAND2]);
- 	}
- 
- 	if (mtk_wed_device_active(wed)) {
- 		mtk_wed_device_irq_set_mask(wed, 0);
- 		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
--		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
-+		intr |= (intr1 & ~MT_INT_TRX_DONE_EXT);
- 	} else {
- 		mt76_wr(dev, MT_INT_MASK_CSR, 0);
- 		if (dev->hif2)
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 38467d9..a0b5270 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -501,6 +501,8 @@ enum offs_rev {
- #define MT_INT_RX_TXFREE_MAIN			BIT(17)
- #define MT_INT_RX_TXFREE_TRI			BIT(15)
- #define MT_INT_MCU_CMD				BIT(29)
-+
-+#define MT_INT_RX_DONE_BAND2_EXT		BIT(23)
- #define MT_INT_RX_TXFREE_EXT			BIT(26)
- 
- #define MT_INT_RX_DONE_RRO_BAND0		BIT(16)
-@@ -551,6 +553,10 @@ enum offs_rev {
- #define MT_INT_TX_DONE_BAND1			BIT(31)
- #define MT_INT_TX_DONE_BAND2			BIT(15)
- 
-+#define MT_INT_TRX_DONE_EXT			(MT_INT_TX_DONE_BAND2 |	\
-+						 MT_INT_RX_DONE_BAND2_EXT |	\
-+						 MT_INT_RX_TXFREE_EXT)
-+
- #define MT_INT_TX_DONE_MCU			(MT_INT_TX_MCU(MT_MCUQ_WA) |	\
- 						 MT_INT_TX_MCU(MT_MCUQ_WM) |	\
- 						 MT_INT_TX_MCU(MT_MCUQ_FWDL))
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2006-mtk-wifi-mt76-add-SER-support-for-wed3.0.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2006-mtk-wifi-mt76-add-SER-support-for-wed3.0.patch
new file mode 100644
index 0000000..d471b73
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2006-mtk-wifi-mt76-add-SER-support-for-wed3.0.patch
@@ -0,0 +1,41 @@
+From 4d9f1a03be245fcefd8567c5b3623de9f85945ae Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Tue, 23 May 2023 12:06:29 +0800
+Subject: [PATCH 2006/2020] mtk: wifi: mt76: add SER support for wed3.0
+
+---
+ dma.c         | 5 +++--
+ mt7996/mmio.c | 1 +
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 16cb23b4..dfce79fa 100644
+--- a/dma.c
++++ b/dma.c
+@@ -910,8 +910,9 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+ 
+ 	/* reset WED rx queues */
+ 	mt76_dma_wed_setup(dev, q, true);
+-
+-	if (!mt76_queue_is_wed_tx_free(q)) {
++	if (!mt76_queue_is_wed_tx_free(q) &&
++	    !(mt76_queue_is_wed_rro(q) &&
++	    mtk_wed_device_active(&dev->mmio.wed))) {
+ 		mt76_dma_sync_idx(dev, q);
+ 		mt76_dma_rx_fill(dev, q);
+ 	}
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 4814897c..488f5103 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -302,6 +302,7 @@ out:
+ 
+ 	return ret;
+ }
++
+ #endif
+ 
+ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2006-wifi-mt76-mt7996-add-rro-elem-free-when-rmmod-wifi-m.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2006-wifi-mt76-mt7996-add-rro-elem-free-when-rmmod-wifi-m.patch
deleted file mode 100644
index 7511279..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2006-wifi-mt76-mt7996-add-rro-elem-free-when-rmmod-wifi-m.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From a2bd3309c6c1ea4d63d8ac3fc066914186740ab5 Mon Sep 17 00:00:00 2001
-From: mtk27745 <rex.lu@mediatek.com>
-Date: Fri, 6 Oct 2023 15:48:37 +0800
-Subject: [PATCH 70/98] wifi: mt76: mt7996: add rro elem free when rmmod wifi
- module
-
----
- mt7996/init.c | 34 ++++++++++++++++++++++++++++++++++
- 1 file changed, 34 insertions(+)
-
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 5627605..1ece390 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -670,6 +670,38 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
- 	msleep(20);
- }
- 
-+static int mt7996_rro_free(struct mt7996_dev *dev)
-+{
-+	int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.ba_bitmap); i++) {
-+		if (dev->wed_rro.ba_bitmap[i].ptr)
-+			dmam_free_coherent(dev->mt76.dma_dev,
-+					   MT7996_RRO_BA_BITMAP_CR_SIZE,
-+					   dev->wed_rro.ba_bitmap[i].ptr,
-+					   dev->wed_rro.ba_bitmap[i].phy_addr);
-+	}
-+
-+	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
-+		if (dev->wed_rro.addr_elem[i].ptr) {
-+			dmam_free_coherent(dev->mt76.dma_dev,
-+					   MT7996_RRO_WINDOW_MAX_SIZE *
-+					   sizeof(struct mt7996_wed_rro_addr),
-+					   dev->wed_rro.addr_elem[i].ptr,
-+					   dev->wed_rro.addr_elem[i].phy_addr);
-+		}
-+	}
-+
-+	if (dev->wed_rro.session.ptr)
-+		dmam_free_coherent(dev->mt76.dma_dev,
-+				   MT7996_RRO_WINDOW_MAX_LEN *
-+				   sizeof(struct mt7996_wed_rro_addr),
-+				   dev->wed_rro.session.ptr,
-+				   dev->wed_rro.session.phy_addr);
-+
-+	return 0;
-+}
-+
- static int mt7996_wed_rro_init(struct mt7996_dev *dev)
- {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
-@@ -1295,6 +1327,8 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
- 	mt7996_coredump_unregister(dev);
- 	mt76_unregister_device(&dev->mt76);
- 	mt7996_mcu_exit(dev);
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->has_rro)
-+		mt7996_rro_free(dev);
- 	mt7996_tx_token_put(dev);
- 	mt7996_dma_cleanup(dev);
- 	tasklet_disable(&dev->mt76.irq_tasklet);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2007-mtk-wifi-mt76-mt7915-wed-find-rx-token-by-physical-a.patch
similarity index 75%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2007-mtk-wifi-mt76-mt7915-wed-find-rx-token-by-physical-a.patch
index 2688d54..575675d 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2007-mtk-wifi-mt76-mt7915-wed-find-rx-token-by-physical-a.patch
@@ -1,8 +1,8 @@
-From 50c902b8856af271bc5514d623ad09f7c3f2d880 Mon Sep 17 00:00:00 2001
+From 2ce94ab60b821db9a1f3368df1b24b4f7904a00b Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Wed, 19 Jul 2023 10:55:09 +0800
-Subject: [PATCH 72/98] wifi: mt76: mt7915: wed: find rx token by physical
- address
+Subject: [PATCH 2007/2020] mtk: wifi: mt76: mt7915: wed: find rx token by
+ physical address
 
 The token id in RxDMAD may be incorrect when it is not the last frame due to
 WED HW bug. Lookup correct token id by physical address in sdp0.
@@ -14,15 +14,14 @@
  1 file changed, 25 insertions(+), 2 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 141a97b..3983ebb 100644
+index dfce79fa..69333769 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -440,10 +440,33 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 	}
+@@ -448,9 +448,32 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 	mt76_dma_should_drop_buf(drop, ctrl, buf1, desc_info);
  
  	if (mt76_queue_is_wed_rx(q)) {
 +		u32 id, find = 0;
- 		u32 buf1 = le32_to_cpu(desc->buf1);
  		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
 -		struct mt76_rxwi_cache *r = mt76_rx_token_release(dev, token);
 +		struct mt76_rxwi_cache *r;
@@ -52,7 +51,7 @@
  		if (!r)
  			return NULL;
  
-@@ -965,7 +988,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -978,7 +1001,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		if (!data)
  			break;
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-add-SER-support-for-wed3.0.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-add-SER-support-for-wed3.0.patch
deleted file mode 100644
index 2ba1f4e..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-add-SER-support-for-wed3.0.patch
+++ /dev/null
@@ -1,278 +0,0 @@
-From 487a6e92fb6ce81d043b5a7632133379b8bcfbcb Mon Sep 17 00:00:00 2001
-From: mtk27745 <rex.lu@mediatek.com>
-Date: Tue, 23 May 2023 12:06:29 +0800
-Subject: [PATCH 71/98] wifi: mt76: add SER support for wed3.0
-
-Change-Id: I2711b9dc336fca9a1ae32a8fbf27810a7e27b1e3
----
- dma.c         |  4 +++-
- mt7996/dma.c  | 42 +++++++++++++++++++++++++++++++++++++++---
- mt7996/mac.c  | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
- mt7996/mmio.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 136 insertions(+), 5 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index f48ec57..141a97b 100644
---- a/dma.c
-+++ b/dma.c
-@@ -898,7 +898,9 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
- 
- 	/* reset WED rx queues */
- 	mt76_dma_wed_setup(dev, q, true);
--	if (!mt76_queue_is_wed_tx_free(q)) {
-+	if (!mt76_queue_is_wed_tx_free(q) &&
-+	    !(mt76_queue_is_wed_rro(q) &&
-+	    mtk_wed_device_active(&dev->mmio.wed))) {
- 		mt76_dma_sync_idx(dev, q);
- 		mt76_dma_rx_fill(dev, q);
- 	}
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 2397fe5..b2c7ae6 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -615,11 +615,35 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 	return 0;
- }
- 
-+static void mt7996_dma_wed_reset(struct mt7996_dev *dev)
-+{
-+	struct mt76_dev *mdev = &dev->mt76;
-+
-+	if (!test_bit(MT76_STATE_WED_RESET, &dev->mphy.state))
-+		return;
-+
-+	complete(&mdev->mmio.wed_reset);
-+
-+	if (!wait_for_completion_timeout(&dev->mt76.mmio.wed_reset_complete,
-+					 3 * HZ))
-+		dev_err(dev->mt76.dev, "wed reset complete timeout\n");
-+}
-+
-+static void
-+mt7996_dma_reset_tx_queue(struct mt7996_dev *dev, struct mt76_queue *q)
-+{
-+	mt76_queue_reset(dev, q);
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		mt76_dma_wed_setup(&dev->mt76, q, true);
-+}
-+
- void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
- {
- 	struct mt76_phy *phy2 = dev->mt76.phys[MT_BAND1];
- 	struct mt76_phy *phy3 = dev->mt76.phys[MT_BAND2];
- 	u32 hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
- 	int i;
- 
- 	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
-@@ -653,21 +677,33 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
- 	if (force)
- 		mt7996_wfsys_reset(dev);
- 
-+	if (dev->hif2 && mtk_wed_device_active(wed_hif2))
-+		mtk_wed_device_dma_reset(wed_hif2);
-+
-+	if (mtk_wed_device_active(wed))
-+		mtk_wed_device_dma_reset(wed);
-+
- 	mt7996_dma_disable(dev, force);
-+	mt7996_dma_wed_reset(dev);
- 
- 	/* reset hw queues */
- 	for (i = 0; i < __MT_TXQ_MAX; i++) {
--		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
-+		mt7996_dma_reset_tx_queue(dev, dev->mphy.q_tx[i]);
- 		if (phy2)
--			mt76_queue_reset(dev, phy2->q_tx[i]);
-+			mt7996_dma_reset_tx_queue(dev, phy2->q_tx[i]);
- 		if (phy3)
--			mt76_queue_reset(dev, phy3->q_tx[i]);
-+			mt7996_dma_reset_tx_queue(dev, phy3->q_tx[i]);
- 	}
- 
- 	for (i = 0; i < __MT_MCUQ_MAX; i++)
- 		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
- 
- 	mt76_for_each_q_rx(&dev->mt76, i) {
-+		if (mtk_wed_device_active(wed) &&
-+		    (mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]) ||
-+		    mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i])))
-+			continue;
-+
- 		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
- 	}
- 
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 60ca23b..22cff71 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1762,6 +1762,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
- 	/* disable all tx/rx napi */
- 	mt76_worker_disable(&dev->mt76.tx_worker);
- 	mt76_for_each_q_rx(mdev, i) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    mt76_queue_is_wed_rro(&mdev->q_rx[i]))
-+			continue;
-+
- 		if (mdev->q_rx[i].ndesc)
- 			napi_disable(&dev->mt76.napi[i]);
- 	}
-@@ -1775,6 +1779,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
- 
- 	local_bh_disable();
- 	mt76_for_each_q_rx(mdev, i) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    mt76_queue_is_wed_rro(&mdev->q_rx[i]))
-+			continue;
-+
- 		if (mdev->q_rx[i].ndesc) {
- 			napi_enable(&dev->mt76.napi[i]);
- 			napi_schedule(&dev->mt76.napi[i]);
-@@ -1949,6 +1957,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 
- 	dev_info(dev->mt76.dev,"\n%s L1 SER recovery start.",
- 		 wiphy_name(dev->mt76.hw->wiphy));
-+
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
-+		mtk_wed_device_stop(&dev->mt76.mmio.wed_hif2);
-+
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		mtk_wed_device_stop(&dev->mt76.mmio.wed);
-+
- 	ieee80211_stop_queues(mt76_hw(dev));
- 	if (phy2)
- 		ieee80211_stop_queues(phy2->mt76->hw);
-@@ -1972,8 +1987,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 		cancel_delayed_work_sync(&phy3->mt76->mac_work);
- 	}
- 	mt76_worker_disable(&dev->mt76.tx_worker);
--	mt76_for_each_q_rx(&dev->mt76, i)
-+	mt76_for_each_q_rx(&dev->mt76, i) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]))
-+			continue;
-+
- 		napi_disable(&dev->mt76.napi[i]);
-+	}
- 	napi_disable(&dev->mt76.tx_napi);
- 
- 	mutex_lock(&dev->mt76.mutex);
-@@ -1996,6 +2016,27 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 	/* enable DMA Tx/Tx and interrupt */
- 	mt7996_dma_start(dev, false, false);
- 
-+
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
-+		u32 wed_irq_mask = dev->mt76.mmio.irqmask |
-+				   MT_INT_RRO_RX_DONE |
-+				   MT_INT_TX_DONE_BAND2;
-+
-+		if (mtk_wed_get_rx_capa(&dev->mt76.mmio.wed))
-+			wed_irq_mask &= ~MT_INT_RX_DONE_RRO_IND;
-+
-+		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
-+
-+		mtk_wed_device_start_hwrro(&dev->mt76.mmio.wed, wed_irq_mask, true);
-+		mt7996_irq_enable(dev, wed_irq_mask);
-+		mt7996_irq_disable(dev, 0);
-+	}
-+
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) {
-+		mt76_wr(dev, MT_INT_PCIE1_MASK_CSR, MT_INT_TRX_DONE_EXT);
-+		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, MT_INT_TRX_DONE_EXT);
-+	}
-+
- 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
- 	clear_bit(MT76_RESET, &dev->mphy.state);
- 	if (phy2)
-@@ -2005,6 +2046,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 
- 	local_bh_disable();
- 	mt76_for_each_q_rx(&dev->mt76, i) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]))
-+			continue;
-+
- 		napi_enable(&dev->mt76.napi[i]);
- 		napi_schedule(&dev->mt76.napi[i]);
- 	}
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 2e395d1..631d905 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -6,9 +6,11 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
-+#include <linux/rtnetlink.h>
- 
- #include "mt7996.h"
- #include "mac.h"
-+#include "mcu.h"
- #include "../trace.h"
- #include "../dma.h"
- 
-@@ -271,6 +273,45 @@ static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
- 	return val;
- }
- 
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+static int mt7996_mmio_wed_reset(struct mtk_wed_device *wed)
-+{
-+	struct mt76_dev *mdev = container_of(wed, struct mt76_dev, mmio.wed);
-+	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
-+	struct mt76_phy *mphy = &dev->mphy;
-+	int ret;
-+
-+	ASSERT_RTNL();
-+
-+	if (test_and_set_bit(MT76_STATE_WED_RESET, &mphy->state))
-+		return -EBUSY;
-+
-+	ret = mt7996_mcu_set_ser(dev, UNI_CMD_SER_TRIGGER, UNI_CMD_SER_SET_RECOVER_L1,
-+				 mphy->band_idx);
-+	if (ret)
-+		goto out;
-+
-+	rtnl_unlock();
-+	if (!wait_for_completion_timeout(&mdev->mmio.wed_reset, 20 * HZ)) {
-+		dev_err(mdev->dev, "wed reset timeout\n");
-+		ret = -ETIMEDOUT;
-+	}
-+	rtnl_lock();
-+out:
-+	clear_bit(MT76_STATE_WED_RESET, &mphy->state);
-+
-+	return ret;
-+}
-+
-+static void mt7996_mmio_wed_reset_complete(struct mtk_wed_device *wed)
-+{
-+	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
-+
-+	complete(&dev->mmio.wed_reset_complete);
-+}
-+
-+#endif
-+
- int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 			 bool hif2, int *irq)
- {
-@@ -387,6 +428,13 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 	wed->wlan.release_rx_buf = mt76_mmio_wed_release_rx_buf;
- 	wed->wlan.offload_enable = mt76_mmio_wed_offload_enable;
- 	wed->wlan.offload_disable = mt76_mmio_wed_offload_disable;
-+	if (hif2) {
-+		wed->wlan.reset = NULL;
-+		wed->wlan.reset_complete = NULL;
-+	} else {
-+		wed->wlan.reset = mt7996_mmio_wed_reset;
-+		wed->wlan.reset_complete = mt7996_mmio_wed_reset_complete;
-+	}
- 
- 	if (mtk_wed_device_attach(wed))
- 		return 0;
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2008-mtk-wifi-mt76-mt7996-add-dma-mask-limitation.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2008-mtk-wifi-mt76-mt7996-add-dma-mask-limitation.patch
new file mode 100644
index 0000000..dce4540
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2008-mtk-wifi-mt76-mt7996-add-dma-mask-limitation.patch
@@ -0,0 +1,57 @@
+From 20990e5d6a405c24354d78e2632a8c0510613f18 Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Thu, 20 Jul 2023 10:25:50 +0800
+Subject: [PATCH 2008/2020] mtk: wifi: mt76: mt7996: add dma mask limitation
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ dma.c  | 4 ++--
+ mmio.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 69333769..5bff27dd 100644
+--- a/dma.c
++++ b/dma.c
+@@ -490,7 +490,7 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		} else {
+ 			struct mt76_queue_buf qbuf;
+ 
+-			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
+ 			if (!buf)
+ 				return NULL;
+ 
+@@ -712,7 +712,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+ 		if (mt76_queue_is_wed_rro_ind(q))
+ 			goto done;
+ 
+-		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
+ 		if (!buf)
+ 			break;
+ 
+diff --git a/mmio.c b/mmio.c
+index b792a7bd..269fd932 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -144,14 +144,14 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 	for (i = 0; i < size; i++) {
+ 		struct mt76_rxwi_cache *r = mt76_get_rxwi(dev);
+ 		dma_addr_t addr;
+-		struct page *page;
+ 		int token;
+ 		void *ptr;
+ 
+ 		if (!r)
+ 			goto unmap;
+ 
+-		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length, GFP_ATOMIC);
++		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
++				      GFP_ATOMIC | GFP_DMA32);
+ 		if (!ptr) {
+ 			mt76_put_rxwi(dev, r);
+  			goto unmap;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2009-mtk-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
similarity index 86%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2009-mtk-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
index 3295f14..197f001 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2009-mtk-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
@@ -1,7 +1,7 @@
-From d97655d3fe3ddf2bbd508de52e207bc91d0115e2 Mon Sep 17 00:00:00 2001
+From f738720718ccb088c71be5dfa9bd5b9a2b7cb78e Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Fri, 18 Aug 2023 10:17:08 +0800
-Subject: [PATCH 76/98] wifi: mt76: mt7996: add per bss statistic info
+Subject: [PATCH 2009/2020] mtk: wifi: mt76: mt7996: add per bss statistic info
 
 Whenever WED is enabled, unicast traffic might run through HW path.
 As a result, we need to count them using WM event.
@@ -22,10 +22,10 @@
  3 files changed, 37 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 51649dd..20e14e7 100644
+index 10b17f7d..d807c357 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -378,6 +378,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
+@@ -390,6 +390,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
@@ -34,7 +34,7 @@
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION);
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION);
 diff --git a/mt7996/main.c b/mt7996/main.c
-index d27275a..2e0b1f1 100644
+index 5a5b549a..939b0943 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -251,6 +251,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
@@ -46,11 +46,11 @@
  
  	mt7996_mac_wtbl_update(dev, idx,
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index bebd020..b2cb627 100644
+index e893e79b..c5167732 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -592,6 +592,27 @@ static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
- 
+@@ -521,6 +521,27 @@ mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rat
+ 	return 0;
  }
  
 +static inline void __mt7996_stat_to_netdev(struct mt76_phy *mphy,
@@ -77,7 +77,7 @@
  static void
  mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  {
-@@ -607,7 +628,7 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -536,7 +557,7 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  		u16 wlan_idx;
  		struct mt76_wcid *wcid;
  		struct mt76_phy *mphy;
@@ -86,7 +86,7 @@
  
  		switch (le16_to_cpu(res->tag)) {
  		case UNI_ALL_STA_TXRX_RATE:
-@@ -635,6 +656,9 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -564,6 +585,9 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  				wcid->stats.tx_bytes += tx_bytes;
  				wcid->stats.rx_bytes += rx_bytes;
  
@@ -96,7 +96,7 @@
  				ieee80211_tpt_led_trig_tx(mphy->hw, tx_bytes);
  				ieee80211_tpt_led_trig_rx(mphy->hw, rx_bytes);
  			}
-@@ -646,10 +670,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -575,10 +599,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  			if (!wcid)
  				break;
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2009-wifi-mt76-drop-packet-based-on-ind_reason.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2009-wifi-mt76-drop-packet-based-on-ind_reason.patch
deleted file mode 100644
index 675e4eb..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2009-wifi-mt76-drop-packet-based-on-ind_reason.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From f322c87d1e0634ec86acb5b254220918842132c6 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Wed, 26 Jul 2023 16:33:43 +0800
-Subject: [PATCH 73/98] wifi: mt76: drop packet based on ind_reason
-
-Driver should drop packet which ind_reason is REPEAT and OLDPKT.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- dma.c | 15 +++++++++++++--
- dma.h |  9 +++++++++
- 2 files changed, 22 insertions(+), 2 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 3983ebb..69e314a 100644
---- a/dma.c
-+++ b/dma.c
-@@ -435,8 +435,19 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 
- 	if (drop) {
- 		*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A | MT_DMA_CTL_DROP));
--		if (ctrl & MT_DMA_CTL_VER_MASK)
--			*drop = !!(ctrl & MT_DMA_CTL_PN_CHK_FAIL);
-+		if (ctrl & MT_DMA_CTL_VER_MASK) {
-+			switch (le32_get_bits(desc->buf1, MT_DMA_IND_REASON)) {
-+			case IND_REASON_REPEAT:
-+				*drop = true;
-+				break;
-+			case IND_REASON_OLDPKT:
-+				*drop = !le32_get_bits(desc->info, MT_DMA_INFO_DMA_FRAG);
-+				break;
-+			default:
-+				*drop = !!(ctrl & MT_DMA_CTL_PN_CHK_FAIL);
-+				break;
-+			}
-+		}
- 	}
- 
- 	if (mt76_queue_is_wed_rx(q)) {
-diff --git a/dma.h b/dma.h
-index 22b79d5..afcbcdd 100644
---- a/dma.h
-+++ b/dma.h
-@@ -23,6 +23,7 @@
- 
- #define MT_DMA_PPE_CPU_REASON		GENMASK(15, 11)
- #define MT_DMA_PPE_ENTRY		GENMASK(30, 16)
-+#define MT_DMA_INFO_DMA_FRAG		BIT(9)
- #define MT_DMA_INFO_PPE_VLD		BIT(31)
- 
- #define MT_DMA_CTL_PN_CHK_FAIL		BIT(13)
-@@ -31,6 +32,7 @@
- #define MT_DMA_RRO_EN		BIT(13)
- 
- #define MT_DMA_WED_IND_CMD_CNT		8
-+#define MT_DMA_IND_REASON		GENMASK(15, 12)
- 
- #define MT_DMA_HDR_LEN			4
- #define MT_RX_INFO_LEN			4
-@@ -66,6 +68,13 @@ enum mt76_mcu_evt_type {
- 	EVT_EVENT_DFS_DETECT_RSP,
- };
- 
-+enum ind_reason {
-+	IND_REASON_NORMAL,
-+	IND_REASON_REPEAT,
-+	IND_REASON_OLDPKT,
-+	IND_REASON_MAX
-+};
-+
- int mt76_dma_rx_poll(struct napi_struct *napi, int budget);
- void mt76_dma_attach(struct mt76_dev *dev);
- void mt76_dma_cleanup(struct mt76_dev *dev);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2010-mtk-wifi-mt76-mt7996-do-not-report-netdev-stats-on-m.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2010-mtk-wifi-mt76-mt7996-do-not-report-netdev-stats-on-m.patch
new file mode 100644
index 0000000..41093ff
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2010-mtk-wifi-mt76-mt7996-do-not-report-netdev-stats-on-m.patch
@@ -0,0 +1,37 @@
+From fc585381223ac634308f6c396e548a4b03c9c190 Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Thu, 26 Oct 2023 17:27:43 +0800
+Subject: [PATCH 2010/2020] mtk: wifi: mt76: mt7996: do not report netdev stats
+ on monitor vif
+
+This fixes the following NULL pointer crash when enabling monitor mode:
+[  205.593158] Call trace:
+[  205.595597]  mt7996_mcu_rx_event+0x4a0/0x6e8 [mt7996e]
+[  205.600725]  mt7996_queue_rx_skb+0x6e4/0xfa0 [mt7996e]
+[  205.605851]  mt76_dma_rx_poll+0x384/0x420 [mt76]
+[  205.610459]  __napi_poll+0x38/0x1c0
+[  205.613935]  napi_threaded_poll+0x80/0xe8
+[  205.617934]  kthread+0x124/0x128
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/mcu.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index c5167732..3116e664 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -537,6 +537,9 @@ static inline void __mt7996_stat_to_netdev(struct mt76_phy *mphy,
+ 				   drv_priv);
+ 		wdev = ieee80211_vif_to_wdev(vif);
+ 
++		if (vif->type == NL80211_IFTYPE_MONITOR)
++			return;
++
+ 		dev_sw_netstats_tx_add(wdev->netdev, tx_packets, tx_bytes);
+ 		dev_sw_netstats_rx_add(wdev->netdev, rx_packets, rx_bytes);
+ 	}
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2010-wifi-mt76-mt7996-add-rro-timeout-setting.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2010-wifi-mt76-mt7996-add-rro-timeout-setting.patch
deleted file mode 100644
index 6fe2cea..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2010-wifi-mt76-mt7996-add-rro-timeout-setting.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 531d586b936634fad23651d18d2bbc832692c520 Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Fri, 11 Aug 2023 18:26:39 +0800
-Subject: [PATCH 74/98] wifi: mt76: mt7996: add rro timeout setting
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- mt7996/init.c   |  5 +++++
- mt7996/mcu.c    | 11 ++++++++++-
- mt7996/mt7996.h |  2 +-
- mt7996/regs.h   |  2 ++
- 4 files changed, 18 insertions(+), 2 deletions(-)
-
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 1ece390..51649dd 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -506,6 +506,11 @@ void mt7996_mac_init(struct mt7996_dev *dev)
- 	/* rro module init */
- 	mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
- 	if (dev->has_rro) {
-+		u16 timeout;
-+
-+		timeout = mt76_rr(dev, MT_HW_REV) == MT_HW_VER1 ? 512 : 128;
-+
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_FLUSH_TIMEOUT, timeout);
- 		mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 1);
- 		mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 0);
- 	} else {
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index ce38a5e..bebd020 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -4626,7 +4626,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev)
- 				 &req, sizeof(req), false);
- }
- 
--int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
-+int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val)
- {
- 	struct {
- 		u8 __rsv1[4];
-@@ -4648,6 +4648,11 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
- 				u8 path;
- 				u8 __rsv2[3];
- 			} __packed txfree_path;
-+			struct {
-+				u16 flush_one;
-+				u16 flush_all;
-+				u8 __rsv2[4];
-+			}  __packed timeout;
- 		};
- 	} __packed req = {
- 		.tag = cpu_to_le16(tag),
-@@ -4664,6 +4669,10 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
- 	case UNI_RRO_SET_TXFREE_PATH:
- 		req.txfree_path.path = val;
- 		break;
-+	case UNI_RRO_SET_FLUSH_TIMEOUT:
-+		req.timeout.flush_one = val;
-+		req.timeout.flush_all = val * 2;
-+		break;
- 	default:
- 		return -EINVAL;
- 	}
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index af67c59..06e00f4 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -676,7 +676,7 @@ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
- 				    u16 rate_idx, bool beacon);
- int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
- int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
--int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
-+int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val);
- int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev, u16 seid);
- int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
- int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index a0b5270..77a2f9d 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -667,6 +667,8 @@ enum offs_rev {
- #define MT_PAD_GPIO_ADIE_NUM_7992		BIT(15)
- 
- #define MT_HW_REV				0x70010204
-+#define MT_HW_VER1				0x8a00
-+
- #define MT_WF_SUBSYS_RST			0x70028600
- 
- /* PCIE MAC */
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2011-mtk-wifi-mt76-mt7996-add-support-for-HW-ATF.patch
similarity index 68%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2011-mtk-wifi-mt76-mt7996-add-support-for-HW-ATF.patch
index a581775..7e19302 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2011-mtk-wifi-mt76-mt7996-add-support-for-HW-ATF.patch
@@ -1,21 +1,129 @@
-From dda3205c68ab3b38945f0066be5fc95ba067f3af Mon Sep 17 00:00:00 2001
+From 7768e810767e4ac6bb65f42ad459e84fbc22c6c0 Mon Sep 17 00:00:00 2001
 From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
 Date: Mon, 11 Sep 2023 16:35:15 +0800
-Subject: [PATCH 78/98] wifi: mt76: mt7996: add support for HW-ATF
- initialization
+Subject: [PATCH 2011/2020] mtk: wifi: mt76: mt7996: add support for HW-ATF
 
 ---
- mt7996/init.c   |  43 ++++++++
- mt7996/mcu.c    | 263 +++++++++++++++++++++++++++++++++++++++++++-----
- mt7996/mcu.h    |   1 +
- mt7996/mt7996.h |  94 +++++++++++++++++
- 4 files changed, 376 insertions(+), 25 deletions(-)
+ mt7996/debugfs.c |  89 ++++++++++++++++
+ mt7996/init.c    |  43 ++++++++
+ mt7996/mac.c     |   6 ++
+ mt7996/mcu.c     | 265 ++++++++++++++++++++++++++++++++++++++++++-----
+ mt7996/mcu.h     |   1 +
+ mt7996/mt7996.h  |  96 ++++++++++++++++-
+ 6 files changed, 474 insertions(+), 26 deletions(-)
 
+diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
+index 223b655e..3d514c44 100644
+--- a/mt7996/debugfs.c
++++ b/mt7996/debugfs.c
+@@ -863,6 +863,90 @@ mt7996_rf_regval_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7996_rf_regval_get,
+ 			 mt7996_rf_regval_set, "0x%08llx\n");
+ 
++static int
++mt7996_vow_info_read(struct seq_file *s, void *data)
++{
++	struct mt7996_dev *dev = dev_get_drvdata(s->private);
++	struct mt7996_vow_ctrl *vow = &dev->vow;
++	int i;
++
++	seq_printf(s, "VoW ATF Configuration:\n");
++	seq_printf(s, "ATF: %s\n", vow->atf_enable ? "enabled" : "disabled");
++	seq_printf(s, "WATF: %s\n", vow->watf_enable ? "enabled" : "disabled");
++	seq_printf(s, "Airtime Quantums (unit: 256 us)\n");
++	for (i = 0; i < VOW_DRR_QUANTUM_NUM; ++i)
++		seq_printf(s, "\tL%d: %hhu\n", i, vow->drr_quantum[i]);
++	seq_printf(s, "Max Airtime Deficit: %hhu (unit: 256 us)\n", vow->max_deficit);
++
++	return 0;
++}
++
++static int
++mt7996_atf_enable_get(void *data, u64 *val)
++{
++	struct mt7996_phy *phy = data;
++
++	*val = phy->dev->vow.atf_enable;
++
++	return 0;
++}
++
++static int
++mt7996_atf_enable_set(void *data, u64 val)
++{
++	struct mt7996_phy *phy = data;
++	struct mt7996_vow_ctrl *vow = &phy->dev->vow;
++	int ret;
++
++	vow->max_deficit = val ? 64 : 1;
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, NULL, VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND);
++	if (ret)
++		return ret;
++
++	vow->atf_enable = !!val;
++	return mt7996_mcu_set_vow_feature_ctrl(phy);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_atf_enable, mt7996_atf_enable_get,
++	                 mt7996_atf_enable_set, "%llu\n");
++
++static int
++mt7996_airtime_read(struct seq_file *s, void *data)
++{
++	struct mt7996_dev *dev = dev_get_drvdata(s->private);
++	struct mt76_dev *mdev = &dev->mt76;
++	struct mt7996_vow_sta_ctrl *vow;
++	struct ieee80211_sta *sta;
++	struct mt7996_sta *msta;
++	struct mt76_wcid *wcid;
++	struct mt76_vif *vif;
++	u64 airtime;
++	u16 i;
++
++	seq_printf(s, "VoW Airtime Information:\n");
++	rcu_read_lock();
++	for (i = 1; i < MT7996_WTBL_STA; ++i) {
++		wcid = rcu_dereference(mdev->wcid[i]);
++		if (!wcid || !wcid->sta)
++			continue;
++
++		msta = container_of(wcid, struct mt7996_sta, wcid);
++		sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
++		vow = &msta->vow;
++		vif = &msta->vif->mt76;
++
++		spin_lock_bh(&vow->lock);
++		airtime = vow->tx_airtime;
++		vow->tx_airtime = 0;
++		spin_unlock_bh(&vow->lock);
++
++		seq_printf(s, "%pM WCID: %hu BandIdx: %hhu OmacIdx: 0x%hhx\tTxAirtime: %llu\n",
++		           sta->addr, i, vif->band_idx, vif->omac_idx, airtime);
++	}
++	rcu_read_unlock();
++
++	return 0;
++}
++
+ int mt7996_init_debugfs(struct mt7996_phy *phy)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -889,6 +973,11 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
+ 	debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
+ 				    mt7996_twt_stats);
+ 	debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
++	debugfs_create_devm_seqfile(dev->mt76.dev, "vow_info", dir,
++	                            mt7996_vow_info_read);
++	debugfs_create_file("atf_enable", 0600, dir, phy, &fops_atf_enable);
++	debugfs_create_devm_seqfile(dev->mt76.dev, "airtime", dir,
++	                            mt7996_airtime_read);
+ 
+ 	if (phy->mt76->cap.has_5ghz) {
+ 		debugfs_create_u32("dfs_hw_pattern", 0400, dir,
 diff --git a/mt7996/init.c b/mt7996/init.c
-index d539af0..d1db1d7 100644
+index d807c357..50453801 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -553,6 +553,37 @@ int mt7996_txbf_init(struct mt7996_dev *dev)
+@@ -566,6 +566,37 @@ int mt7996_txbf_init(struct mt7996_dev *dev)
  	return mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);
  }
  
@@ -53,7 +161,7 @@
  static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
  			       enum mt76_band_id band)
  {
-@@ -626,6 +657,12 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+@@ -638,6 +669,12 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
  	if (ret)
  		goto error;
  
@@ -66,7 +174,7 @@
  	ret = mt7996_init_debugfs(phy);
  	if (ret)
  		goto error;
-@@ -1315,6 +1352,12 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1443,6 +1480,12 @@ int mt7996_register_device(struct mt7996_dev *dev)
  
  	dev->recovery.hw_init_done = true;
  
@@ -79,11 +187,42 @@
  	ret = mt7996_init_debugfs(&dev->phy);
  	if (ret)
  		goto error;
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index a9d8f7dd..d51f4129 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -103,6 +103,7 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
+ 	};
+ 	struct ieee80211_sta *sta;
+ 	struct mt7996_sta *msta;
++	struct mt7996_vow_sta_ctrl *vow;
+ 	u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
+ 	LIST_HEAD(sta_poll_list);
+ 	int i;
+@@ -161,6 +162,7 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
+ 
+ 		sta = container_of((void *)msta, struct ieee80211_sta,
+ 				   drv_priv);
++		vow = &msta->vow;
+ 		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ 			u8 q = mt76_connac_lmac_mapping(i);
+ 			u32 tx_cur = tx_time[q];
+@@ -171,6 +173,10 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
+ 				continue;
+ 
+ 			ieee80211_sta_register_airtime(sta, tid, tx_cur, rx_cur);
++
++			spin_lock_bh(&vow->lock);
++			vow->tx_airtime += tx_cur;
++			spin_unlock_bh(&vow->lock);
+ 		}
+ 
+ 		/* get signal strength of resp frames (CTS/BA/ACK) */
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index b2cb627..1915a22 100644
+index 3116e664..45a44cd8 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2147,34 +2147,35 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2220,34 +2220,37 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  }
  
  static int
@@ -126,6 +265,8 @@
 +	vow->drr_quantum[IEEE80211_AC_VI] = VOW_DRR_QUANTUM_IDX1;
 +	vow->drr_quantum[IEEE80211_AC_BE] = VOW_DRR_QUANTUM_IDX2;
 +	vow->drr_quantum[IEEE80211_AC_BK] = VOW_DRR_QUANTUM_IDX2;
++	vow->tx_airtime = 0;
++	spin_lock_init(&vow->lock);
 +
 +	ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_BSS_GROUP);
 +	if (ret)
@@ -143,7 +284,7 @@
  }
  
  int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-@@ -2228,7 +2229,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2301,7 +2304,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
  	}
  
@@ -152,8 +293,8 @@
  	if (ret) {
  		dev_kfree_skb(skb);
  		return ret;
-@@ -5027,6 +5028,218 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
- 				     MCU_WM_UNI_CMD(TXPOWER), true);
+@@ -5137,6 +5140,218 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
+ 				 &req, sizeof(req), false);
  }
  
 +int mt7996_mcu_set_vow_drr_ctrl(struct mt7996_phy *phy, struct mt7996_sta *msta,
@@ -372,10 +513,10 @@
  void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
  {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 0aa68f7..fb81645 100644
+index a2604192..7b8540f6 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -860,6 +860,7 @@ enum {
+@@ -964,6 +964,7 @@ enum {
  
  enum {
  	UNI_VOW_DRR_CTRL,
@@ -384,10 +525,10 @@
  	UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
  	UNI_VOW_RED_ENABLE = 0x18,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 4333d51..ba73520 100644
+index e6a0b15a..56538825 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -107,6 +107,12 @@
+@@ -115,6 +115,12 @@
  #define MT7996_RX_MSDU_PAGE_SIZE	(128 + \
  					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
  
@@ -400,9 +541,9 @@
  struct mt7996_vif;
  struct mt7996_sta;
  struct mt7996_dfs_pulse;
-@@ -187,6 +193,79 @@ struct mt7996_twt_flow {
- 
- DECLARE_EWMA(avg_signal, 10, 8)
+@@ -216,6 +222,81 @@ enum mt7996_dpd_ch_num {
+ 	DPD_CH_NUM_TYPE_MAX,
+ };
  
 +enum {
 +	VOW_SEARCH_AC_FIRST,
@@ -475,12 +616,14 @@
 +	bool paused;
 +	u8 bss_grp_idx;
 +	u8 drr_quantum[IEEE80211_NUM_ACS];
++	u64 tx_airtime;
++	spinlock_t lock;
 +};
 +
  struct mt7996_sta {
  	struct mt76_wcid wcid; /* must be first */
  
-@@ -206,6 +285,8 @@ struct mt7996_sta {
+@@ -235,6 +316,8 @@ struct mt7996_sta {
  		u8 flowid_mask;
  		struct mt7996_twt_flow flow[MT7996_MAX_STA_TWT_AGRT];
  	} twt;
@@ -489,7 +632,7 @@
  };
  
  struct mt7996_vif {
-@@ -470,6 +551,7 @@ struct mt7996_dev {
+@@ -492,6 +575,7 @@ struct mt7996_dev {
  
  	u8 wtbl_size_group;
  
@@ -497,18 +640,21 @@
  #ifdef CONFIG_MTK_DEBUG
  	u16 wlan_idx;
  	struct {
-@@ -697,6 +779,10 @@ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+@@ -712,10 +796,12 @@ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
+ #ifdef CONFIG_NL80211_TESTMODE
  void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
  #endif
- 
+-int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
+ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
+ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+ int mt7996_mcu_set_band_confg(struct mt7996_phy *phy, u16 option, bool enable);
 +int mt7996_mcu_set_vow_drr_ctrl(struct mt7996_phy *phy, struct mt7996_sta *msta,
 +	                        enum vow_drr_ctrl_id id);
 +int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy);
-+
- static inline u16 mt7996_eeprom_size(struct mt7996_dev *dev)
+ 
+ static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
  {
- 	return is_mt7996(&dev->mt76) ? MT7996_EEPROM_SIZE : MT7992_EEPROM_SIZE;
-@@ -749,6 +835,14 @@ static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy)
+@@ -765,6 +851,14 @@ static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy)
  	return tx_chainmask | (BIT(fls(tx_chainmask)) * phy->has_aux_rx);
  }
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2011-wifi-mt76-mt7996-add-dma-mask-limitation.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2011-wifi-mt76-mt7996-add-dma-mask-limitation.patch
deleted file mode 100644
index fec02ea..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2011-wifi-mt76-mt7996-add-dma-mask-limitation.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 39a1bb49d83141f79bf329fdd68e82bb77f5d0a2 Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Thu, 20 Jul 2023 10:25:50 +0800
-Subject: [PATCH 75/98] wifi: mt76: mt7996: add dma mask limitation
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- dma.c         | 4 ++--
- mmio.c        | 3 ++-
- mt7996/mmio.c | 8 --------
- mt7996/pci.c  | 2 +-
- 4 files changed, 5 insertions(+), 12 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 69e314a..7616921 100644
---- a/dma.c
-+++ b/dma.c
-@@ -494,7 +494,7 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 		} else {
- 			struct mt76_queue_buf qbuf;
- 
--			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
-+			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
- 			if (!buf)
- 				return NULL;
- 
-@@ -713,7 +713,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 		if (mt76_queue_is_wed_rro_ind(q))
- 			goto done;
- 
--		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
-+		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
- 		if (!buf)
- 			break;
- 
-diff --git a/mmio.c b/mmio.c
-index f7495f6..22629af 100644
---- a/mmio.c
-+++ b/mmio.c
-@@ -150,7 +150,8 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- 		if (!r)
- 			goto unmap;
- 
--		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length, GFP_ATOMIC);
-+		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
-+				      GFP_ATOMIC | GFP_DMA32);
- 		if (!ptr) {
- 			mt76_put_rxwi(dev, r);
-  			goto unmap;
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 631d905..38b8843 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -442,14 +442,6 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 	*irq = wed->irq;
- 	dev->mt76.dma_dev = wed->dev;
- 
--	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
--	if (ret)
--		return ret;
--
--	ret = dma_set_coherent_mask(wed->dev, DMA_BIT_MASK(32));
--	if (ret)
--		return ret;
--
- 	return 1;
- #else
- 	return 0;
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index 2bb707d..0024929 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -111,7 +111,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 
- 	pci_set_master(pdev);
- 
--	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
-+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- 	if (ret)
- 		return ret;
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2012-mtk-wifi-mt76-mt7996-wed-add-SER0.5-support-w-wed3.0.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2012-mtk-wifi-mt76-mt7996-wed-add-SER0.5-support-w-wed3.0.patch
new file mode 100644
index 0000000..d78fcf3
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2012-mtk-wifi-mt76-mt7996-wed-add-SER0.5-support-w-wed3.0.patch
@@ -0,0 +1,386 @@
+From 2e7ac514e17ad740c9a837190f9d43ebeb8a9397 Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Thu, 12 Oct 2023 10:04:54 +0800
+Subject: [PATCH 2012/2020] mtk: wifi: mt76: mt7996: wed: add SER0.5 support w/
+ wed3.0
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ dma.c           |  13 ++---
+ dma.h           |   2 +-
+ mt76.h          |  14 ++++--
+ mt792x_dma.c    |   6 +--
+ mt7996/dma.c    |  20 ++++++--
+ mt7996/init.c   | 127 +++++++++++++++++++++++++++++++-----------------
+ mt7996/mac.c    |  25 ++++++++++
+ mt7996/mt7996.h |   1 +
+ 8 files changed, 145 insertions(+), 63 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 5bff27dd..5ddb6be9 100644
+--- a/dma.c
++++ b/dma.c
+@@ -220,9 +220,9 @@ __mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
+ }
+ 
+ static void
+-mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
++mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ {
+-	__mt76_dma_queue_reset(dev, q, true);
++	__mt76_dma_queue_reset(dev, q, reset);
+ }
+ 
+ static int
+@@ -542,7 +542,8 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
+ 	if (!q->queued)
+ 		return NULL;
+ 
+-	if (mt76_queue_is_wed_rro_data(q))
++	if (mt76_queue_is_wed_rro_data(q) ||
++	    mt76_queue_is_wed_rro_msdu_pg(q))
+ 		return NULL;
+ 
+ 	if (!mt76_queue_is_wed_rro_ind(q)) {
+@@ -772,7 +773,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ 	case MT76_WED_Q_TXFREE:
+ 		/* WED txfree queue needs ring to be initialized before setup */
+ 		q->flags = 0;
+-		mt76_dma_queue_reset(dev, q);
++		mt76_dma_queue_reset(dev, q, true);
+ 		mt76_dma_rx_fill(dev, q);
+ 
+ 		ret = mtk_wed_device_txfree_ring_setup(q->wed, q->regs);
+@@ -801,7 +802,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ 		break;
+ 	case MT76_WED_RRO_Q_IND:
+ 		q->flags &= ~MT_QFLAG_WED;
+-		mt76_dma_queue_reset(dev, q);
++		mt76_dma_queue_reset(dev, q, true);
+ 		mt76_dma_rx_fill(dev, q);
+ 		mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
+ 		break;
+@@ -868,7 +869,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ 			return 0;
+ 	}
+ 
+-	mt76_dma_queue_reset(dev, q);
++	mt76_dma_queue_reset(dev, q, true);
+ 
+ 	return 0;
+ }
+diff --git a/dma.h b/dma.h
+index c479cc63..b7e63bd5 100644
+--- a/dma.h
++++ b/dma.h
+@@ -85,7 +85,7 @@ void mt76_dma_wed_reset(struct mt76_dev *dev);
+ static inline void
+ mt76_dma_reset_tx_queue(struct mt76_dev *dev, struct mt76_queue *q)
+ {
+-	dev->queue_ops->reset_q(dev, q);
++	dev->queue_ops->reset_q(dev, q, true);
+ 	if (mtk_wed_device_active(&dev->mmio.wed))
+ 		mt76_dma_wed_setup(dev, q, true);
+ }
+diff --git a/mt76.h b/mt76.h
+index 2ce1e84e..cf88eafa 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -295,7 +295,7 @@ struct mt76_queue_ops {
+ 
+ 	void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
+ 
+-	void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q);
++	void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q,  bool reset);
+ };
+ 
+ enum mt76_phy_type {
+@@ -1722,8 +1722,13 @@ static inline bool mt76_queue_is_wed_rro_ind(struct mt76_queue *q)
+ static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q)
+ {
+ 	return mt76_queue_is_wed_rro(q) &&
+-	       (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA ||
+-		FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG);
++	       (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA);
++}
++
++static inline bool mt76_queue_is_wed_rro_msdu_pg(struct mt76_queue *q)
++{
++	return mt76_queue_is_wed_rro(q) &&
++	       (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG);
+ }
+ 
+ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+@@ -1732,7 +1737,8 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+ 		return false;
+ 
+ 	return FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX ||
+-	       mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q);
++	       mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q) ||
++	       mt76_queue_is_wed_rro_msdu_pg(q);
+ 
+ }
+ 
+diff --git a/mt792x_dma.c b/mt792x_dma.c
+index 488326ce..8811351c 100644
+--- a/mt792x_dma.c
++++ b/mt792x_dma.c
+@@ -172,13 +172,13 @@ mt792x_dma_reset(struct mt792x_dev *dev, bool force)
+ 
+ 	/* reset hw queues */
+ 	for (i = 0; i < __MT_TXQ_MAX; i++)
+-		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
++		mt76_queue_reset(dev, dev->mphy.q_tx[i], true);
+ 
+ 	for (i = 0; i < __MT_MCUQ_MAX; i++)
+-		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
++		mt76_queue_reset(dev, dev->mt76.q_mcu[i], true);
+ 
+ 	mt76_for_each_q_rx(&dev->mt76, i)
+-		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
++		mt76_queue_reset(dev, &dev->mt76.q_rx[i], true);
+ 
+ 	mt76_tx_status_check(&dev->mt76, true);
+ 
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 40ab65f8..8df119d0 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -710,21 +710,31 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+ 	}
+ 
+ 	for (i = 0; i < __MT_MCUQ_MAX; i++)
+-		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
++		mt76_queue_reset(dev, dev->mt76.q_mcu[i], true);
+ 
+ 	mt76_for_each_q_rx(&dev->mt76, i) {
+-		if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++		if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+ 			if (mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]) ||
+-			    mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i]))
++			    mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i])) {
++				if (force && mt76_queue_is_wed_rro_data(&dev->mt76.q_rx[i]))
++					mt76_queue_reset(dev, &dev->mt76.q_rx[i], false);
+ 				continue;
++			}
++		}
+ 
+-		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
++		mt76_queue_reset(dev, &dev->mt76.q_rx[i], true);
+ 	}
+ 
+ 	mt76_tx_status_check(&dev->mt76, true);
+ 
+-	mt76_for_each_q_rx(&dev->mt76, i)
++	mt76_for_each_q_rx(&dev->mt76, i) {
++		if (mtk_wed_device_active(&dev->mt76.mmio.wed) && force &&
++		    (mt76_queue_is_wed_rro_ind(&dev->mt76.q_rx[i]) ||
++		     mt76_queue_is_wed_rro_msdu_pg(&dev->mt76.q_rx[i])))
++			continue;
++
+ 		mt76_queue_rx_reset(dev, i);
++	}
+ 
+ 	mt7996_dma_enable(dev, !force);
+ }
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 50453801..a1b76e33 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -728,11 +728,91 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
+ 	msleep(20);
+ }
+ 
+-static int mt7996_wed_rro_init(struct mt7996_dev *dev)
++void mt7996_rro_hw_init(struct mt7996_dev *dev)
+ {
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ 	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ 	u32 reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;
++	int i;
++
++	if (!dev->has_rro)
++		return;
++
++	if (is_mt7992(&dev->mt76)) {
++		/* set emul 3.0 function */
++		mt76_wr(dev, MT_RRO_3_0_EMU_CONF,
++			MT_RRO_3_0_EMU_CONF_EN_MASK);
++
++		mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE0,
++			dev->wed_rro.addr_elem[0].phy_addr);
++	} else {
++		/* TODO: remove line after WM has set */
++		mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
++
++		/* setup BA bitmap cache address */
++		mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
++			dev->wed_rro.ba_bitmap[0].phy_addr);
++		mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
++		mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
++			dev->wed_rro.ba_bitmap[1].phy_addr);
++		mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
++
++		/* setup Address element address */
++		for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
++			mt76_wr(dev, reg, dev->wed_rro.addr_elem[i].phy_addr >> 4);
++			reg += 4;
++		}
++
++		/* setup Address element address - separate address segment mode */
++		mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
++			MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
++	}
++	wed->wlan.ind_cmd.win_size = ffs(MT7996_RRO_WINDOW_MAX_LEN) - 6;
++	if (is_mt7996(&dev->mt76))
++		wed->wlan.ind_cmd.particular_sid = MT7996_RRO_MAX_SESSION;
++	else
++		wed->wlan.ind_cmd.particular_sid = 1;
++	wed->wlan.ind_cmd.particular_se_phys = dev->wed_rro.session.phy_addr;
++	wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_LEN;
++	wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
++
++	mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
++	mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
++		 MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
++
++	/* particular session configure */
++	/* use max session idx + 1 as particular session id */
++	mt76_wr(dev, MT_RRO_PARTICULAR_CFG0, dev->wed_rro.session.phy_addr);
++
++	if (is_mt7992(&dev->mt76)) {
++		reg = MT_RRO_MSDU_PG_SEG_ADDR0;
++
++		mt76_set(dev, MT_RRO_3_1_GLOBAL_CONFIG,
++			 MT_RRO_3_1_GLOBAL_CONFIG_INTERLEAVE_EN);
++
++		/* setup Msdu page address */
++		for (i = 0; i < MT7996_RRO_MSDU_PG_CR_CNT; i++) {
++			mt76_wr(dev, reg, dev->wed_rro.msdu_pg[i].phy_addr >> 4);
++			reg += 4;
++		}
++		mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
++			MT_RRO_PARTICULAR_CONFG_EN |
++			FIELD_PREP(MT_RRO_PARTICULAR_SID, 1));
++	} else {
++		mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
++			MT_RRO_PARTICULAR_CONFG_EN |
++			FIELD_PREP(MT_RRO_PARTICULAR_SID, MT7996_RRO_MAX_SESSION));
++	}
++	/* interrupt enable */
++	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
++		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
++#endif
++}
++
++static int mt7996_wed_rro_init(struct mt7996_dev *dev)
++{
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ 	struct mt7996_wed_rro_addr *addr;
+ 	void *ptr;
+ 	int i;
+@@ -792,50 +872,9 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
+ 		addr++;
+ 	}
+ 
+-	/* rro hw init */
+-	/* TODO: remove line after WM has set */
+-	mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
+-
+-	/* setup BA bitmap cache address */
+-	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
+-		dev->wed_rro.ba_bitmap[0].phy_addr);
+-	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
+-	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
+-		dev->wed_rro.ba_bitmap[1].phy_addr);
+-	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
+-
+-	/* setup Address element address */
+-	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
+-		mt76_wr(dev, reg, dev->wed_rro.addr_elem[i].phy_addr >> 4);
+-		reg += 4;
+-	}
+-
+-	/* setup Address element address - separate address segment mode */
+-	mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
+-		MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
+-
+-	wed->wlan.ind_cmd.win_size = ffs(MT7996_RRO_WINDOW_MAX_LEN) - 6;
+-	wed->wlan.ind_cmd.particular_sid = MT7996_RRO_MAX_SESSION;
+-	wed->wlan.ind_cmd.particular_se_phys = dev->wed_rro.session.phy_addr;
+-	wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_LEN;
+-	wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
+-
+-	mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
+-	mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
+-		 MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
+-
+-	/* particular session configure */
+-	/* use max session idx + 1 as particular session id */
+-	mt76_wr(dev, MT_RRO_PARTICULAR_CFG0, dev->wed_rro.session.phy_addr);
+-	mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
+-		MT_RRO_PARTICULAR_CONFG_EN |
+-		FIELD_PREP(MT_RRO_PARTICULAR_SID, MT7996_RRO_MAX_SESSION));
+-
+-	/* interrupt enable */
+-	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
+-		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
+-
+ 	/* rro ind cmd queue init */
++	mt7996_rro_hw_init(dev);
++
+ 	return mt7996_dma_rro_init(dev);
+ #else
+ 	return 0;
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index d51f4129..19e66256 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1755,6 +1755,31 @@ mt7996_mac_restart(struct mt7996_dev *dev)
+ 	if (ret)
+ 		goto out;
+ 
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->has_rro) {
++		u32 wed_irq_mask = dev->mt76.mmio.irqmask |
++				   MT_INT_RRO_RX_DONE |
++				   MT_INT_TX_DONE_BAND2;
++
++		mt7996_rro_hw_init(dev);
++		mt76_for_each_q_rx(&dev->mt76, i) {
++			if (mt76_queue_is_wed_rro_ind(&dev->mt76.q_rx[i]) ||
++			    mt76_queue_is_wed_rro_msdu_pg(&dev->mt76.q_rx[i]))
++				mt76_queue_rx_reset(dev, i);
++		}
++
++		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
++		mtk_wed_device_start_hwrro(&dev->mt76.mmio.wed, wed_irq_mask, false);
++		mt7996_irq_enable(dev, wed_irq_mask);
++		mt7996_irq_disable(dev, 0);
++	}
++
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) {
++		mt76_wr(dev, MT_INT_PCIE1_MASK_CSR,
++			MT_INT_TX_RX_DONE_EXT);
++		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2,
++				     MT_INT_TX_RX_DONE_EXT);
++	}
++
+ 	/* set the necessary init items */
+ 	ret = mt7996_mcu_set_eeprom(dev);
+ 	if (ret)
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 56538825..7a1cae71 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -691,6 +691,7 @@ extern const struct mt76_testmode_ops mt7996_testmode_ops;
+ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
+ 				     void __iomem *mem_base, u32 device_id);
+ void mt7996_wfsys_reset(struct mt7996_dev *dev);
++void mt7996_rro_hw_init(struct mt7996_dev *dev);
+ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
+ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
+ int mt7996_register_device(struct mt7996_dev *dev);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2013-mtk-wifi-mt76-mt7996-support-backaward-compatiable.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2013-mtk-wifi-mt76-mt7996-support-backaward-compatiable.patch
new file mode 100644
index 0000000..671d734
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2013-mtk-wifi-mt76-mt7996-support-backaward-compatiable.patch
@@ -0,0 +1,223 @@
+From 68d3bbf7120da35068e5983d89cae5ee470e55f4 Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Fri, 6 Oct 2023 20:59:42 +0800
+Subject: [PATCH 2013/2020] mtk: wifi: mt76: mt7996: support backaward
+ compatiable
+
+revert upstream wed trigger mode to polling mode
+
+Signed-off-by: mtk27745 <rex.lu@mediatek.com>
+
+[Description]
+Change the SW token size from 1024 to 15360 according to HW capability.
+
+[Release-log]
+N/A
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mmio.c          |  2 +-
+ mt7996/dma.c    |  2 +-
+ mt7996/mac.c    |  2 +-
+ mt7996/main.c   |  6 +++---
+ mt7996/mcu.c    |  2 +-
+ mt7996/mmio.c   | 20 +++++++++++---------
+ mt7996/mt7996.h |  1 +
+ mt7996/pci.c    | 17 +++++++++--------
+ 8 files changed, 28 insertions(+), 24 deletions(-)
+
+diff --git a/mmio.c b/mmio.c
+index 269fd932..117da4d1 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -134,7 +134,7 @@ EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
+ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ {
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+-	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
++	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
+ 	u32 length;
+ 	int i;
+ 
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 8df119d0..773bab71 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -431,7 +431,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
+ 	irq_mask = mdev->mmio.irqmask | MT_INT_RRO_RX_DONE |
+ 		   MT_INT_TX_DONE_BAND2;
+ 	mt76_wr(dev, MT_INT_MASK_CSR, irq_mask);
+-	mtk_wed_device_start_hw_rro(&mdev->mmio.wed, irq_mask, false);
++	mtk_wed_device_start_hwrro(&mdev->mmio.wed, irq_mask, false);
+ 	mt7996_irq_enable(dev, irq_mask);
+ 
+ 	return 0;
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 19e66256..8171a43d 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1998,7 +1998,7 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 
+ 		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
+ 
+-		mtk_wed_device_start_hw_rro(&dev->mt76.mmio.wed, wed_irq_mask,
++		mtk_wed_device_start_hwrro(&dev->mt76.mmio.wed, wed_irq_mask,
+ 					    true);
+ 		mt7996_irq_enable(dev, wed_irq_mask);
+ 		mt7996_irq_disable(dev, 0);
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 939b0943..45461949 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1593,10 +1593,10 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
+ 	path->mtk_wdma.wcid = msta->wcid.idx;
+ 
+ 	if (ieee80211_hw_check(hw, SUPPORTS_AMSDU_IN_AMPDU) &&
+-	    mtk_wed_is_amsdu_supported(wed))
+-		path->mtk_wdma.amsdu = msta->wcid.amsdu;
++	    mtk_wed_device_support_pao(wed))
++		path->mtk_wdma.amsdu_en = msta->wcid.amsdu;
+ 	else
+-		path->mtk_wdma.amsdu = 0;
++		path->mtk_wdma.amsdu_en = 0;
+ 
+ 	ctx->dev = NULL;
+ 
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 45a44cd8..57af55ec 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3247,7 +3247,7 @@ static int mt7996_mcu_wa_red_config(struct mt7996_dev *dev)
+ 
+ 	if (!mtk_wed_device_active(&dev->mt76.mmio.wed))
+ 		req.token_per_src[RED_TOKEN_SRC_CNT - 1] =
+-			cpu_to_le16(MT7996_TOKEN_SIZE - MT7996_HW_TOKEN_SIZE);
++			cpu_to_le16(MT7996_SW_TOKEN_SIZE);
+ 
+ 	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET),
+ 				 &req, sizeof(req), false);
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 488f5103..69d16dad 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -14,7 +14,7 @@
+ #include "../trace.h"
+ #include "../dma.h"
+ 
+-static bool wed_enable;
++static bool wed_enable = true;
+ module_param(wed_enable, bool, 0644);
+ 
+ static const struct __base mt7996_reg_base[] = {
+@@ -352,14 +352,14 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 		}
+ 
+ 		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
+-		wed->wlan.wpdma_rx = wed->wlan.phy_base + hif1_ofs +
++		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base + hif1_ofs +
+ 				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
+ 				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
+ 
+-		wed->wlan.id = 0x7991;
++		wed->wlan.chip_id = 0x7991;
+ 		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
+ 	} else {
+-		wed->wlan.hw_rro = dev->has_rro; /* default on */
++		wed->wlan.hwrro = dev->has_rro; /* default on */
+ 		wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
+ 		wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
+ 		wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
+@@ -367,7 +367,7 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 
+ 		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
+ 
+-		wed->wlan.wpdma_rx = wed->wlan.phy_base +
++		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base +
+ 				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
+ 				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
+ 
+@@ -409,11 +409,11 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 		dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
+ 	}
+ 
+-	wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE;
+-	wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf;
++	wed->wlan.nbuf = MT7996_TOKEN_SIZE;
++	wed->wlan.token_start = 0;
+ 
+-	wed->wlan.amsdu_max_subframes = 8;
+-	wed->wlan.amsdu_max_len = 1536;
++	wed->wlan.max_amsdu_nums = 8;
++	wed->wlan.max_amsdu_len = 1536;
+ 
+ 	wed->wlan.init_buf = mt7996_wed_init_buf;
+ 	wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
+@@ -431,6 +431,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 	*irq = wed->irq;
+ 	dev->mt76.dma_dev = wed->dev;
+ 
++	dev->mt76.token_size = MT7996_SW_TOKEN_SIZE;
++
+ 	return 1;
+ #else
+ 	return 0;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 7a1cae71..056d07fe 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -74,6 +74,7 @@
+ #define MT7996_EEPROM_BLOCK_SIZE	16
+ #define MT7996_TOKEN_SIZE		16384
+ #define MT7996_HW_TOKEN_SIZE		8192
++#define MT7996_SW_TOKEN_SIZE		15360
+ 
+ #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
+ #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index 05830c01..4e957771 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -171,7 +171,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 
+ 		ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &hif2_irq);
+ 		if (ret < 0)
+-			goto free_hif2_wed_irq_vector;
++			goto free_wed_or_irq_vector;
+ 
+ 		if (!ret) {
+ 			ret = pci_alloc_irq_vectors(hif2_dev, 1, 1,
+@@ -180,14 +180,15 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 				goto free_hif2;
+ 
+ 			dev->hif2->irq = hif2_dev->irq;
+-			hif2_irq = dev->hif2->irq;
++		} else {
++			dev->hif2->irq = irq;
+ 		}
+ 
+-		ret = devm_request_irq(mdev->dev, hif2_irq, mt7996_irq_handler,
+-				       IRQF_SHARED, KBUILD_MODNAME "-hif",
+-				       dev);
++		ret = devm_request_irq(mdev->dev, dev->hif2->irq,
++				       mt7996_irq_handler, IRQF_SHARED,
++				       KBUILD_MODNAME "-hif", dev);
+ 		if (ret)
+-			goto free_hif2_wed_irq_vector;
++			goto free_hif2_irq_vector;
+ 
+ 		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+ 		/* master switch of PCIe tnterrupt enable */
+@@ -202,8 +203,8 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 
+ free_hif2_irq:
+ 	if (dev->hif2)
+-		devm_free_irq(mdev->dev, hif2_irq, dev);
+-free_hif2_wed_irq_vector:
++		devm_free_irq(mdev->dev, dev->hif2->irq, dev);
++free_hif2_irq_vector:
+ 	if (dev->hif2) {
+ 		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
+ 			mtk_wed_device_detach(&dev->mt76.mmio.wed_hif2);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2013-wifi-mt76-mt7996-support-TX-RX-for-Kite-without-WED-.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2013-wifi-mt76-mt7996-support-TX-RX-for-Kite-without-WED-.patch
deleted file mode 100644
index 8dd2d61..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2013-wifi-mt76-mt7996-support-TX-RX-for-Kite-without-WED-.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From bd93ad7026e316307453438f4b7bce59e30bf03e Mon Sep 17 00:00:00 2001
-From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
-Date: Wed, 7 Jun 2023 14:11:28 +0800
-Subject: [PATCH 77/98] wifi: mt76: mt7996: support TX/RX for Kite without WED
- and RRO
-
-Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt76_connac3_mac.h |  3 ++-
- mt7996/dma.c       | 61 +++++++++++++++++++++++++++++++++++++---------
- mt7996/init.c      | 10 ++++++--
- mt7996/mac.c       |  7 ++++--
- mt7996/mt7996.h    |  4 +--
- mt7996/regs.h      |  4 +--
- 6 files changed, 68 insertions(+), 21 deletions(-)
-
-diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
-index 7402de2..3fd46ae 100644
---- a/mt76_connac3_mac.h
-+++ b/mt76_connac3_mac.h
-@@ -244,7 +244,8 @@ enum tx_mgnt_type {
- #define MT_TXD6_TX_RATE			GENMASK(21, 16)
- #define MT_TXD6_TIMESTAMP_OFS_EN	BIT(15)
- #define MT_TXD6_TIMESTAMP_OFS_IDX	GENMASK(14, 10)
--#define MT_TXD6_MSDU_CNT		GENMASK(9, 4)
-+#define MT_TXD6_MSDU_CNT_MT7996		GENMASK(9, 4)
-+#define MT_TXD6_MSDU_CNT_MT7992		GENMASK(15, 10)
- #define MT_TXD6_DIS_MAT			BIT(3)
- #define MT_TXD6_DAS			BIT(2)
- #define MT_TXD6_AMSDU_CAP		BIT(1)
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index b2c7ae6..1163550 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -57,13 +57,21 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
- 	RXQ_CONFIG(MT_RXQ_MCU, WFDMA0, MT_INT_RX_DONE_WM, MT7996_RXQ_MCU_WM);
- 	RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_RX_DONE_WA, MT7996_RXQ_MCU_WA);
- 
--	/* band0/band1 */
-+	/* MT7996 band0/band1
-+	 * MT7992 band0
-+	 */
- 	RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0, MT7996_RXQ_BAND0);
- 	RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_RX_DONE_WA_MAIN, MT7996_RXQ_MCU_WA_MAIN);
- 
--	/* band2 */
--	RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
--	RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
-+	if (is_mt7996(&dev->mt76)) {
-+		/* MT7996 band2 */
-+		RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
-+		RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
-+	} else {
-+		/* MT7992 band1 */
-+		RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1, MT7996_RXQ_BAND1);
-+		RXQ_CONFIG(MT_RXQ_BAND1_WA, WFDMA0, MT_INT_RX_DONE_WA_EXT, MT7996_RXQ_MCU_WA_EXT);
-+	}
- 
- 	if (dev->has_rro) {
- 		/* band0 */
-@@ -90,8 +98,12 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
- 
- 	/* data tx queue */
- 	TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7996_TXQ_BAND0);
--	TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
--	TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
-+	if (is_mt7996(&dev->mt76)) {
-+		TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
-+		TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
-+	} else {
-+		TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
-+	}
- 
- 	/* mcu tx queue */
- 	MCUQ_CONFIG(MT_MCUQ_WM, WFDMA0, MT_INT_TX_DONE_MCU_WM, MT7996_TXQ_MCU_WM);
-@@ -123,10 +135,15 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, PREFETCH(0x2));
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, PREFETCH(0x2));
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, PREFETCH(0x2));
--	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x2));
-+	if (is_mt7996(&dev->mt76))
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x2));
-+	else
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND1_WA) + ofs, PREFETCH(0x2));
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x10));
--	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x10));
--
-+	if (is_mt7996(&dev->mt76))
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x10));
-+	else
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND1) + ofs, PREFETCH(0x10));
- 	if (dev->has_rro) {
- 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
- 			PREFETCH(0x10));
-@@ -488,7 +505,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
--	/* rx data queue for band0 and band1 */
-+	/* rx data queue for band0 and MT7996 band1 */
- 	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed)) {
- 		dev->mt76.q_rx[MT_RXQ_MAIN].flags = MT_WED_Q_RX(0);
- 		dev->mt76.q_rx[MT_RXQ_MAIN].wed = wed;
-@@ -517,7 +534,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 		return ret;
- 
- 	if (mt7996_band_valid(dev, MT_BAND2)) {
--		/* rx data queue for band2 */
-+		/* rx data queue for MT7996 band2 */
- 		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
- 		if (mtk_wed_device_active(wed_hif2) && mtk_wed_get_rx_capa(wed_hif2)) {
- 			dev->mt76.q_rx[MT_RXQ_BAND2].flags = MT_WED_Q_RX(0);
-@@ -531,7 +548,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 		if (ret)
- 			return ret;
- 
--		/* tx free notify event from WA for band2
-+		/* tx free notify event from WA for MT7996 band2
- 		 * use pcie0's rx ring3, but, redirect pcie0 rx ring3 interrupt to pcie1
- 		 */
- 		if (mtk_wed_device_active(wed_hif2) && !dev->has_rro) {
-@@ -546,6 +563,26 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 				       MT_RXQ_RING_BASE(MT_RXQ_BAND2_WA));
- 		if (ret)
- 			return ret;
-+	} else if (mt7996_band_valid(dev, MT_BAND1)) {
-+		/* rx data queue for MT7992 band1 */
-+		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1) + hif1_ofs;
-+		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1],
-+				       MT_RXQ_ID(MT_RXQ_BAND1),
-+				       MT7996_RX_RING_SIZE,
-+				       MT_RX_BUF_SIZE,
-+				       rx_base);
-+		if (ret)
-+			return ret;
-+
-+		/* tx free notify event from WA for MT7992 band1 */
-+		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1_WA) + hif1_ofs;
-+		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1_WA],
-+				       MT_RXQ_ID(MT_RXQ_BAND1_WA),
-+				       MT7996_RX_MCU_RING_SIZE,
-+				       MT_RX_BUF_SIZE,
-+				       rx_base);
-+		if (ret)
-+			return ret;
- 	}
- 
- 	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed) &&
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 20e14e7..d539af0 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -505,7 +505,12 @@ void mt7996_mac_init(struct mt7996_dev *dev)
- 	mt76_rmw_field(dev, MT_DMA_TCRF1(2), MT_DMA_TCRF1_QIDX, 0);
- 
- 	/* rro module init */
--	mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
-+	if (is_mt7996(&dev->mt76))
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
-+	else
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE,
-+				   dev->hif2 ? 7 : 0);
-+
- 	if (dev->has_rro) {
- 		u16 timeout;
- 
-@@ -562,7 +567,8 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	if (phy)
- 		return 0;
- 
--	if (band == MT_BAND2 && dev->hif2) {
-+	if ((is_mt7996(&dev->mt76) && band == MT_BAND2 && dev->hif2) ||
-+	    (is_mt7992(&dev->mt76) && band == MT_BAND1 && dev->hif2)) {
- 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
- 		wed = &dev->mt76.mmio.wed_hif2;
- 	}
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 22cff71..a92298d 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -878,8 +878,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
- 		val |= MT_TXD5_TX_STATUS_HOST;
- 	txwi[5] = cpu_to_le32(val);
- 
--	val = MT_TXD6_DIS_MAT | MT_TXD6_DAS |
--	      FIELD_PREP(MT_TXD6_MSDU_CNT, 1);
-+	val = MT_TXD6_DIS_MAT | MT_TXD6_DAS;
-+	if (is_mt7996(&dev->mt76))
-+		val |= FIELD_PREP(MT_TXD6_MSDU_CNT_MT7996, 1);
-+	else
-+		val |= FIELD_PREP(MT_TXD6_MSDU_CNT_MT7992, 1);
- 	txwi[6] = cpu_to_le32(val);
- 	txwi[7] = 0;
- 
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 06e00f4..4333d51 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -152,10 +152,10 @@ enum mt7996_rxq_id {
- 	MT7996_RXQ_MCU_WM = 0,
- 	MT7996_RXQ_MCU_WA,
- 	MT7996_RXQ_MCU_WA_MAIN = 2,
--	MT7996_RXQ_MCU_WA_EXT = 2,/* unused */
-+	MT7996_RXQ_MCU_WA_EXT = 3, /* Only used by MT7992. */
- 	MT7996_RXQ_MCU_WA_TRI = 3,
- 	MT7996_RXQ_BAND0 = 4,
--	MT7996_RXQ_BAND1 = 4,/* unused */
-+	MT7996_RXQ_BAND1 = 5, /* Only used by MT7992. */
- 	MT7996_RXQ_BAND2 = 5,
- 	MT7996_RXQ_RRO_BAND0 = 8,
- 	MT7996_RXQ_RRO_BAND1 = 8,/* unused */
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 77a2f9d..c9e90e3 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -491,12 +491,12 @@ enum offs_rev {
- #define MT_INT1_MASK_CSR			MT_WFDMA0_PCIE1(0x204)
- 
- #define MT_INT_RX_DONE_BAND0			BIT(12)
--#define MT_INT_RX_DONE_BAND1			BIT(12)
-+#define MT_INT_RX_DONE_BAND1			BIT(13) /* Only used by MT7992. */
- #define MT_INT_RX_DONE_BAND2			BIT(13)
- #define MT_INT_RX_DONE_WM			BIT(0)
- #define MT_INT_RX_DONE_WA			BIT(1)
- #define MT_INT_RX_DONE_WA_MAIN			BIT(2)
--#define MT_INT_RX_DONE_WA_EXT			BIT(2)
-+#define MT_INT_RX_DONE_WA_EXT			BIT(3) /* Only used by MT7992. */
- #define MT_INT_RX_DONE_WA_TRI			BIT(3)
- #define MT_INT_RX_TXFREE_MAIN			BIT(17)
- #define MT_INT_RX_TXFREE_TRI			BIT(15)
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2014-mtk-wifi-mt76-mt7996-wed-add-wed-support-for-mt7992.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2014-mtk-wifi-mt76-mt7996-wed-add-wed-support-for-mt7992.patch
new file mode 100644
index 0000000..1b52408
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2014-mtk-wifi-mt76-mt7996-wed-add-wed-support-for-mt7992.patch
@@ -0,0 +1,432 @@
+From fe2c7b5514551f1b61404e9bc11cea12c6ae77de Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Fri, 8 Sep 2023 11:57:39 +0800
+Subject: [PATCH 2014/2020] mtk: wifi: mt76: mt7996: wed: add wed support for
+ mt7992
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+
+Fix incomplete WED initialization for Kite band-1 RX ring.
+
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+---
+ mt7996/dma.c    | 91 +++++++++++++++++++++++++++++++++----------------
+ mt7996/init.c   | 12 +++++++
+ mt7996/mac.c    |  4 +++
+ mt7996/mmio.c   | 49 ++++++++++++++++++--------
+ mt7996/mt7996.h | 10 +++++-
+ mt7996/pci.c    | 10 ++++--
+ mt7996/regs.h   | 14 +++++++-
+ 7 files changed, 142 insertions(+), 48 deletions(-)
+
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 773bab71..4c92f13b 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -77,18 +77,23 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
+ 			   MT7996_RXQ_RRO_BAND0);
+ 		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND0, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND0,
+ 			   MT7996_RXQ_MSDU_PG_BAND0);
+-		RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0, MT_INT_RX_TXFREE_MAIN,
+-			   MT7996_RXQ_TXFREE0);
+-		/* band1 */
+-		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND1,
+-			   MT7996_RXQ_MSDU_PG_BAND1);
+-		/* band2 */
+-		RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0, MT_INT_RX_DONE_RRO_BAND2,
+-			   MT7996_RXQ_RRO_BAND2);
+-		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND2,
+-			   MT7996_RXQ_MSDU_PG_BAND2);
+-		RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0, MT_INT_RX_TXFREE_TRI,
+-			   MT7996_RXQ_TXFREE2);
++		if (is_mt7996(&dev->mt76)) {
++			RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0, MT_INT_RX_TXFREE_MAIN,
++				   MT7996_RXQ_TXFREE0);
++			/* band1 */
++			RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND1,
++				   MT7996_RXQ_MSDU_PG_BAND1);
++			/* band2 */
++			RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0, MT_INT_RX_DONE_RRO_BAND2,
++				   MT7996_RXQ_RRO_BAND2);
++			RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND2,
++				   MT7996_RXQ_MSDU_PG_BAND2);
++			RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0, MT_INT_RX_TXFREE_TRI,
++				   MT7996_RXQ_TXFREE2);
++		} else {
++			RXQ_CONFIG(MT_RXQ_RRO_BAND1, WFDMA0, MT_INT_RX_DONE_RRO_BAND1,
++				   MT7996_RXQ_RRO_BAND1);
++		}
+ 
+ 		RXQ_CONFIG(MT_RXQ_RRO_IND, WFDMA0, MT_INT_RX_DONE_RRO_IND,
+ 			   MT7996_RXQ_RRO_IND);
+@@ -146,8 +151,13 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
+ 	if (dev->has_rro) {
+ 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
+ 			PREFETCH(0x10));
+-		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
+-			PREFETCH(0x10));
++		if (is_mt7996(&dev->mt76))
++			mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
++				PREFETCH(0x10));
++		else
++			mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND1) + ofs,
++				PREFETCH(0x10));
++
+ 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND0) + ofs,
+ 			PREFETCH(0x4));
+ 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND1) + ofs,
+@@ -360,12 +370,16 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ 		 * so, redirect pcie0 rx ring3 interrupt to pcie1
+ 		 */
+ 		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+-		    dev->has_rro)
++		    dev->has_rro) {
++			u32 intr = is_mt7996(&dev->mt76) ?
++				   MT_WFDMA0_RX_INT_SEL_RING6 :
++				   MT_WFDMA0_RX_INT_SEL_RING9;
+ 			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
+-				 MT_WFDMA0_RX_INT_SEL_RING6);
+-		else
++				 intr);
++		} else {
+ 			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
+ 				 MT_WFDMA0_RX_INT_SEL_RING3);
++		}
+ 	}
+ 
+ 	mt7996_dma_start(dev, reset, true);
+@@ -400,7 +414,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
+-	if (mt7996_band_valid(dev, MT_BAND1)) {
++	if (mt7996_band_valid(dev, MT_BAND1) && is_mt7996(&dev->mt76)) {
+ 		/* rx msdu page queue for band1 */
+ 		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags =
+ 			MT_WED_RRO_Q_MSDU_PG(1) | MT_QFLAG_WED_RRO_EN;
+@@ -521,7 +535,9 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 		return ret;
+ 
+ 	/* tx free notify event from WA for band0 */
+-	if (mtk_wed_device_active(wed) && !dev->has_rro) {
++	if (mtk_wed_device_active(wed) &&
++	    ((is_mt7996(&dev->mt76) && !dev->has_rro) ||
++	     (is_mt7992(&dev->mt76)))) {
+ 		dev->mt76.q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
+ 		dev->mt76.q_rx[MT_RXQ_MAIN_WA].wed = wed;
+ 	}
+@@ -567,6 +583,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 	} else if (mt7996_band_valid(dev, MT_BAND1)) {
+ 		/* rx data queue for mt7992 band1 */
+ 		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1) + hif1_ofs;
++		if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed)) {
++			dev->mt76.q_rx[MT_RXQ_BAND1].flags = MT_WED_Q_RX(1);
++			dev->mt76.q_rx[MT_RXQ_BAND1].wed = wed;
++		}
++
+ 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1],
+ 				       MT_RXQ_ID(MT_RXQ_BAND1),
+ 				       MT7996_RX_RING_SIZE,
+@@ -600,17 +621,29 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 		if (ret)
+ 			return ret;
+ 
+-		/* tx free notify event from WA for band0 */
+-		dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
+-		dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].wed = wed;
++		if (is_mt7992(&dev->mt76)) {
++			dev->mt76.q_rx[MT_RXQ_RRO_BAND1].flags =
++				MT_WED_RRO_Q_DATA(1) | MT_QFLAG_WED_RRO_EN;
++			dev->mt76.q_rx[MT_RXQ_RRO_BAND1].wed = wed;
++			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND1],
++					       MT_RXQ_ID(MT_RXQ_RRO_BAND1),
++					       MT7996_RX_RING_SIZE,
++					       MT7996_RX_BUF_SIZE,
++					       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND1));
++			if (ret)
++				return ret;
++		} else {
++			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
++			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].wed = wed;
+ 
+-		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
+-				       MT_RXQ_ID(MT_RXQ_TXFREE_BAND0),
+-				       MT7996_RX_MCU_RING_SIZE,
+-				       MT7996_RX_BUF_SIZE,
+-				       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND0));
+-		if (ret)
+-			return ret;
++			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
++					       MT_RXQ_ID(MT_RXQ_TXFREE_BAND0),
++					       MT7996_RX_MCU_RING_SIZE,
++					       MT7996_RX_BUF_SIZE,
++					       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND0));
++			if (ret)
++				return ret;
++		}
+ 
+ 		if (mt7996_band_valid(dev, MT_BAND2)) {
+ 			/* rx rro data queue for band2 */
+diff --git a/mt7996/init.c b/mt7996/init.c
+index a1b76e33..cc7d570a 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -806,6 +806,7 @@ void mt7996_rro_hw_init(struct mt7996_dev *dev)
+ 	/* interrupt enable */
+ 	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
+ 		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
++
+ #endif
+ }
+ 
+@@ -858,6 +859,17 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
+ 			dev->wed_rro.addr_elem[i].phy_addr;
+ 	}
+ 
++	for (i = 0; i < MT7996_RRO_MSDU_PG_CR_CNT; i++) {
++		ptr = dmam_alloc_coherent(dev->mt76.dma_dev, MT7996_RRO_MSDU_PG_SIZE_PER_CR,
++					  &dev->wed_rro.msdu_pg[i].phy_addr,
++					  GFP_KERNEL);
++		if (!ptr)
++			return -ENOMEM;
++		dev->wed_rro.msdu_pg[i].ptr = ptr;
++
++		memset(dev->wed_rro.msdu_pg[i].ptr, 0, MT7996_RRO_MSDU_PG_SIZE_PER_CR);
++	}
++
+ 	ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
+ 				  MT7996_RRO_WINDOW_MAX_LEN * sizeof(*addr),
+ 				  &dev->wed_rro.session.phy_addr,
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 8171a43d..751a960a 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1998,6 +1998,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 
+ 		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
+ 
++		if (is_mt7992(&dev->mt76) && dev->has_rro)
++			mt76_wr(dev, MT_RRO_3_0_EMU_CONF,
++				MT_RRO_3_0_EMU_CONF_EN_MASK);
++
+ 		mtk_wed_device_start_hwrro(&dev->mt76.mmio.wed, wed_irq_mask,
+ 					    true);
+ 		mt7996_irq_enable(dev, wed_irq_mask);
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 69d16dad..b5b97dcb 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -318,7 +318,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 
+ 	dev->has_rro = true;
+ 
+-	hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++	if (dev->hif2)
++		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
+ 
+ 	if (hif2)
+ 		wed = &dev->mt76.mmio.wed_hif2;
+@@ -353,8 +354,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 
+ 		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
+ 		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base + hif1_ofs +
+-				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
+-				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
++				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND2) +
++				     MT7996_RXQ_BAND2 * MT_RING_SIZE;
+ 
+ 		wed->wlan.chip_id = 0x7991;
+ 		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
+@@ -374,9 +375,19 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 		wed->wlan.wpdma_rx_rro[0] = wed->wlan.phy_base +
+ 					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND0) +
+ 					    MT7996_RXQ_RRO_BAND0 * MT_RING_SIZE;
+-		wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
+-					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
+-					    MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
++		if (is_mt7996(&dev->mt76)) {
++			wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
++						    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
++						    MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
++		} else {
++			wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base +
++						    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND1) +
++						    MT7996_RXQ_RRO_BAND1 * MT_RING_SIZE;
++			wed->wlan.wpdma_rx[1] = wed->wlan.phy_base +
++						MT_RXQ_RING_BASE(MT7996_RXQ_BAND1) +
++						MT7996_RXQ_BAND1 * MT_RING_SIZE;
++		}
++
+ 		wed->wlan.wpdma_rx_pg = wed->wlan.phy_base +
+ 					MT_RXQ_RING_BASE(MT7996_RXQ_MSDU_PG_BAND0) +
+ 					MT7996_RXQ_MSDU_PG_BAND0 * MT_RING_SIZE;
+@@ -386,10 +397,14 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 		wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
+ 
+ 		wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
+-		wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
+-
+ 		wed->wlan.rro_rx_tbit[0] = ffs(MT_INT_RX_DONE_RRO_BAND0) - 1;
+-		wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND2) - 1;
++		if (is_mt7996(&dev->mt76)) {
++			wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
++			wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND2) - 1;
++		} else {
++			wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND1) - 1;
++			wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND1) - 1;
++		}
+ 
+ 		wed->wlan.rx_pg_tbit[0] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND0) - 1;
+ 		wed->wlan.rx_pg_tbit[1] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND1) - 1;
+@@ -397,14 +412,20 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 
+ 		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
+ 		wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
+-		if (dev->has_rro) {
+-			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
+-						 MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
+-			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
++		if (is_mt7996(&dev->mt76)) {
++			if (dev->has_rro) {
++				wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
++							 MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
++				wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
++			} else {
++				wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
++				wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
++							 MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
++			}
+ 		} else {
+ 			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
+ 			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
+-						  MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
++						 MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
+ 		}
+ 		dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
+ 	}
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 056d07fe..677f00b0 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -122,6 +122,10 @@
+ #define MT7996_DRR_STA_AC2_QNTM_MASK	GENMASK(18, 16)
+ #define MT7996_DRR_STA_AC3_QNTM_MASK	GENMASK(22, 20)
+ 
++/* RRO 3.1 */
++#define MT7996_RRO_MSDU_PG_CR_CNT 8
++#define MT7996_RRO_MSDU_PG_SIZE_PER_CR 0x10000
++
+ struct mt7996_vif;
+ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+@@ -181,7 +185,7 @@ enum mt7996_rxq_id {
+ 	MT7996_RXQ_BAND1 = 5, /* for mt7992 */
+ 	MT7996_RXQ_BAND2 = 5,
+ 	MT7996_RXQ_RRO_BAND0 = 8,
+-	MT7996_RXQ_RRO_BAND1 = 8,/* unused */
++	MT7996_RXQ_RRO_BAND1 = 9,
+ 	MT7996_RXQ_RRO_BAND2 = 6,
+ 	MT7996_RXQ_MSDU_PG_BAND0 = 10,
+ 	MT7996_RXQ_MSDU_PG_BAND1 = 11,
+@@ -540,6 +544,10 @@ struct mt7996_dev {
+ 			void *ptr;
+ 			dma_addr_t phy_addr;
+ 		} session;
++		struct {
++			void *ptr;
++			dma_addr_t phy_addr;
++		} msdu_pg[MT7996_RRO_MSDU_PG_CR_CNT];
+ 
+ 		struct work_struct work;
+ 		struct list_head poll_list;
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index 4e957771..f0d3f199 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -107,7 +107,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 	struct pci_dev *hif2_dev;
+ 	struct mt7996_hif *hif2;
+ 	struct mt7996_dev *dev;
+-	int irq, hif2_irq, ret;
++	int irq, ret;
+ 	struct mt76_dev *mdev;
+ 
+ 	hif2_enable |= (id->device == 0x7990 || id->device == 0x7991);
+@@ -143,6 +143,8 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 	mdev = &dev->mt76;
+ 	mt7996_wfsys_reset(dev);
+ 	hif2 = mt7996_pci_init_hif2(pdev);
++	if (hif2)
++		dev->hif2 = hif2;
+ 
+ 	ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
+ 	if (ret < 0)
+@@ -167,9 +169,11 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 
+ 	if (hif2) {
+ 		hif2_dev = container_of(hif2->dev, struct pci_dev, dev);
+-		dev->hif2 = hif2;
++		ret = 0;
++
++		if (is_mt7996(&dev->mt76))
++			ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &irq);
+ 
+-		ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &hif2_irq);
+ 		if (ret < 0)
+ 			goto free_wed_or_irq_vector;
+ 
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 8d1462a7..352d1b29 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -77,6 +77,8 @@ enum offs_rev {
+ #define MT_RRO_BA_BITMAP_BASE1			MT_RRO_TOP(0xC)
+ #define WF_RRO_AXI_MST_CFG			MT_RRO_TOP(0xB8)
+ #define WF_RRO_AXI_MST_CFG_DIDX_OK		BIT(12)
++
++#define MT_RRO_ADDR_ARRAY_BASE0			MT_RRO_TOP(0x30)
+ #define MT_RRO_ADDR_ARRAY_BASE1			MT_RRO_TOP(0x34)
+ #define MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE	BIT(31)
+ 
+@@ -97,6 +99,14 @@ enum offs_rev {
+ 
+ #define MT_RRO_ADDR_ELEM_SEG_ADDR0		MT_RRO_TOP(0x400)
+ 
++#define MT_RRO_3_0_EMU_CONF			MT_RRO_TOP(0x600)
++#define MT_RRO_3_0_EMU_CONF_EN_MASK		BIT(11)
++
++#define MT_RRO_3_1_GLOBAL_CONFIG		MT_RRO_TOP(0x604)
++#define MT_RRO_3_1_GLOBAL_CONFIG_INTERLEAVE_EN	BIT(0)
++
++#define MT_RRO_MSDU_PG_SEG_ADDR0		MT_RRO_TOP(0x620)
++
+ #define MT_RRO_ACK_SN_CTRL			MT_RRO_TOP(0x50)
+ #define MT_RRO_ACK_SN_CTRL_SN_MASK		GENMASK(27, 16)
+ #define MT_RRO_ACK_SN_CTRL_SESSION_MASK		GENMASK(11, 0)
+@@ -402,6 +412,7 @@ enum offs_rev {
+ #define MT_WFDMA0_RX_INT_PCIE_SEL		MT_WFDMA0(0x154)
+ #define MT_WFDMA0_RX_INT_SEL_RING3		BIT(3)
+ #define MT_WFDMA0_RX_INT_SEL_RING6		BIT(6)
++#define MT_WFDMA0_RX_INT_SEL_RING9		BIT(9)
+ 
+ #define MT_WFDMA0_MCU_HOST_INT_ENA		MT_WFDMA0(0x1f4)
+ 
+@@ -503,13 +514,14 @@ enum offs_rev {
+ #define MT_INT_RX_DONE_WA_EXT			BIT(3) /* for mt7992 */
+ #define MT_INT_RX_DONE_WA_TRI			BIT(3)
+ #define MT_INT_RX_TXFREE_MAIN			BIT(17)
++#define MT_INT_RX_TXFREE_BAND1			BIT(15)
+ #define MT_INT_RX_TXFREE_TRI			BIT(15)
+ #define MT_INT_RX_DONE_BAND2_EXT		BIT(23)
+ #define MT_INT_RX_TXFREE_EXT			BIT(26)
+ #define MT_INT_MCU_CMD				BIT(29)
+ 
+ #define MT_INT_RX_DONE_RRO_BAND0		BIT(16)
+-#define MT_INT_RX_DONE_RRO_BAND1		BIT(16)
++#define MT_INT_RX_DONE_RRO_BAND1		BIT(17)
+ #define MT_INT_RX_DONE_RRO_BAND2		BIT(14)
+ #define MT_INT_RX_DONE_RRO_IND			BIT(11)
+ #define MT_INT_RX_DONE_MSDU_PG_BAND0		BIT(18)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2015-mtk-wifi-mt76-mt7992-wed-add-2pcie-one-wed-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2015-mtk-wifi-mt76-mt7992-wed-add-2pcie-one-wed-support.patch
new file mode 100644
index 0000000..21d53cc
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2015-mtk-wifi-mt76-mt7992-wed-add-2pcie-one-wed-support.patch
@@ -0,0 +1,177 @@
+From fe7511e18f6fd543b5b3d2fac9dd61c9ed02d938 Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Wed, 13 Sep 2023 17:35:43 +0800
+Subject: [PATCH 2015/2020] mtk: wifi: mt76: mt7992: wed: add 2pcie one wed
+ support
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ mt7996/dma.c         | 13 +++++++++++--
+ mt7996/mmio.c        |  7 +++----
+ mt7996/mtk_debug.h   |  5 +++++
+ mt7996/mtk_debugfs.c | 25 ++++++++++++++++++-------
+ mt7996/regs.h        |  2 ++
+ 5 files changed, 39 insertions(+), 13 deletions(-)
+
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 4c92f13b..80458b31 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -354,6 +354,13 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ 			 MT_WFDMA_HOST_CONFIG_PDMA_BAND |
+ 			 MT_WFDMA_HOST_CONFIG_BAND2_PCIE1);
+ 
++		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++		    is_mt7992(&dev->mt76)) {
++			mt76_set(dev, MT_WFDMA_HOST_CONFIG,
++				 MT_WFDMA_HOST_CONFIG_PDMA_BAND |
++				 MT_WFDMA_HOST_CONFIG_BAND1_PCIE1);
++		}
++
+ 		/* AXI read outstanding number */
+ 		mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL,
+ 			 MT_WFDMA_AXI_R2A_CTRL_OUTSTAND_MASK, 0x14);
+@@ -373,7 +380,8 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ 		    dev->has_rro) {
+ 			u32 intr = is_mt7996(&dev->mt76) ?
+ 				   MT_WFDMA0_RX_INT_SEL_RING6 :
+-				   MT_WFDMA0_RX_INT_SEL_RING9;
++				   MT_WFDMA0_RX_INT_SEL_RING9 |
++				   MT_WFDMA0_RX_INT_SEL_RING5;
+ 			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
+ 				 intr);
+ 		} else {
+@@ -629,10 +637,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 					       MT_RXQ_ID(MT_RXQ_RRO_BAND1),
+ 					       MT7996_RX_RING_SIZE,
+ 					       MT7996_RX_BUF_SIZE,
+-					       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND1));
++					       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND1) + hif1_ofs);
+ 			if (ret)
+ 				return ret;
+ 		} else {
++			/* tx free notify event from WA for band0 */
+ 			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
+ 			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].wed = wed;
+ 
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index b5b97dcb..8faceb3b 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -380,10 +380,10 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 						    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
+ 						    MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
+ 		} else {
+-			wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base +
++			wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
+ 						    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND1) +
+ 						    MT7996_RXQ_RRO_BAND1 * MT_RING_SIZE;
+-			wed->wlan.wpdma_rx[1] = wed->wlan.phy_base +
++			wed->wlan.wpdma_rx[1] = wed->wlan.phy_base + hif1_ofs +
+ 						MT_RXQ_RING_BASE(MT7996_RXQ_BAND1) +
+ 						MT7996_RXQ_BAND1 * MT_RING_SIZE;
+ 		}
+@@ -521,10 +521,9 @@ void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
+ 		if (mtk_wed_device_active(&mdev->mmio.wed)) {
+ 			mtk_wed_device_irq_set_mask(&mdev->mmio.wed,
+ 						    mdev->mmio.irqmask);
+-			if (mtk_wed_device_active(&mdev->mmio.wed_hif2)) {
++			if (mtk_wed_device_active(&mdev->mmio.wed_hif2))
+ 				mtk_wed_device_irq_set_mask(&mdev->mmio.wed_hif2,
+ 							    mdev->mmio.irqmask);
+-			}
+ 		} else {
+ 			mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
+ 			mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
+diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
+index 27d8f1cb..da2a6072 100644
+--- a/mt7996/mtk_debug.h
++++ b/mt7996/mtk_debug.h
+@@ -561,6 +561,11 @@ struct queue_desc {
+ #define WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING7_CTRL1_ADDR     (WF_WFDMA_HOST_DMA0_PCIE1_BASE + 0x574) // 8574
+ #define WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING7_CTRL2_ADDR     (WF_WFDMA_HOST_DMA0_PCIE1_BASE + 0x578) // 8578
+ #define WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING7_CTRL3_ADDR     (WF_WFDMA_HOST_DMA0_PCIE1_BASE + 0x57c) // 857C
++#define WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING9_CTRL0_ADDR     (WF_WFDMA_HOST_DMA0_PCIE1_BASE + 0x590) // 8590
++#define WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING9_CTRL1_ADDR     (WF_WFDMA_HOST_DMA0_PCIE1_BASE + 0x594) // 8594
++#define WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING9_CTRL2_ADDR     (WF_WFDMA_HOST_DMA0_PCIE1_BASE + 0x598) // 8598
++#define WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING9_CTRL3_ADDR     (WF_WFDMA_HOST_DMA0_PCIE1_BASE + 0x59c) // 859C
++
+ //MCU DMA
+ //#define WF_WFDMA_MCU_DMA0_BASE                                 0x02000
+ #define WF_WFDMA_MCU_DMA0_BASE                                 0x54000000
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 9cf3e6dc..c1764824 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -536,14 +536,22 @@ mt7996_show_dma_info(struct seq_file *s, struct mt7996_dev *dev)
+ 		WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR);
+ 	dump_dma_rx_ring_info(s, dev, "R5:Data1(MAC2H)", "Both",
+ 		WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR);
+-	dump_dma_rx_ring_info(s, dev, "R6:BUF1(MAC2H)", "Both",
+-		WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR);
++	if (is_mt7996(&dev->mt76))
++		dump_dma_rx_ring_info(s, dev, "R6:BUF1(MAC2H)", "Both",
++			WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR);
++	else
++		dump_dma_rx_ring_info(s, dev, "R6:TxDone0(MAC2H)", "Both",
++			WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR);
+ 	dump_dma_rx_ring_info(s, dev, "R7:TxDone1(MAC2H)", "Both",
+ 		WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_ADDR);
+ 	dump_dma_rx_ring_info(s, dev, "R8:BUF0(MAC2H)", "Both",
+ 		WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_CTRL0_ADDR);
+-	dump_dma_rx_ring_info(s, dev, "R9:TxDone0(MAC2H)", "Both",
+-		WF_WFDMA_HOST_DMA0_WPDMA_RX_RING9_CTRL0_ADDR);
++	if (is_mt7996(&dev->mt76))
++		dump_dma_rx_ring_info(s, dev, "R9:TxDone0(MAC2H)", "Both",
++			WF_WFDMA_HOST_DMA0_WPDMA_RX_RING9_CTRL0_ADDR);
++	else
++		dump_dma_rx_ring_info(s, dev, "R9:BUF0(MAC2H)", "Both",
++			WF_WFDMA_HOST_DMA0_WPDMA_RX_RING9_CTRL0_ADDR);
+ 	dump_dma_rx_ring_info(s, dev, "R10:MSDU_PG0(MAC2H)", "Both",
+ 		WF_WFDMA_HOST_DMA0_WPDMA_RX_RING10_CTRL0_ADDR);
+ 	dump_dma_rx_ring_info(s, dev, "R11:MSDU_PG1(MAC2H)", "Both",
+@@ -561,15 +569,18 @@ mt7996_show_dma_info(struct seq_file *s, struct mt7996_dev *dev)
+ 			WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_TX_RING21_CTRL0_ADDR);
+ 		dump_dma_tx_ring_info(s, dev, "T22:TXD?(H2WA)", "AP",
+ 			WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_TX_RING22_CTRL0_ADDR);
+-
+ 		dump_dma_rx_ring_info(s, dev, "R3:TxDone1(WA2H)", "AP",
+ 			WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING3_CTRL0_ADDR);
+ 		dump_dma_rx_ring_info(s, dev, "R5:Data1(MAC2H)", "Both",
+ 			WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING5_CTRL0_ADDR);
+-		dump_dma_rx_ring_info(s, dev, "R6:BUF1(MAC2H)", "Both",
+-			WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING6_CTRL0_ADDR);
++		if (is_mt7996(&dev->mt76))
++			dump_dma_rx_ring_info(s, dev, "R6:BUF1(MAC2H)", "Both",
++				WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING6_CTRL0_ADDR);
+ 		dump_dma_rx_ring_info(s, dev, "R7:TxDone1(MAC2H)", "Both",
+ 			WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING7_CTRL0_ADDR);
++		if (is_mt7992(&dev->mt76))
++			dump_dma_rx_ring_info(s, dev, "R9:BUF1(MAC2H)", "Both",
++				WF_WFDMA_HOST_DMA0_PCIE1_WPDMA_RX_RING9_CTRL0_ADDR);
+ 	}
+ 
+ 	/* MCU DMA information */
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 352d1b29..a3b62339 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -411,6 +411,7 @@ enum offs_rev {
+ 
+ #define MT_WFDMA0_RX_INT_PCIE_SEL		MT_WFDMA0(0x154)
+ #define MT_WFDMA0_RX_INT_SEL_RING3		BIT(3)
++#define MT_WFDMA0_RX_INT_SEL_RING5		BIT(5)
+ #define MT_WFDMA0_RX_INT_SEL_RING6		BIT(6)
+ #define MT_WFDMA0_RX_INT_SEL_RING9		BIT(9)
+ 
+@@ -451,6 +452,7 @@ enum offs_rev {
+ 
+ #define MT_WFDMA_HOST_CONFIG			MT_WFDMA_EXT_CSR(0x30)
+ #define MT_WFDMA_HOST_CONFIG_PDMA_BAND		BIT(0)
++#define MT_WFDMA_HOST_CONFIG_BAND1_PCIE1	BIT(21)
+ #define MT_WFDMA_HOST_CONFIG_BAND2_PCIE1	BIT(22)
+ 
+ #define MT_WFDMA_EXT_CSR_HIF_MISC		MT_WFDMA_EXT_CSR(0x44)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2016-mtk-wifi-mt76-mt7996-add-SER-state-log-for-debug.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2016-mtk-wifi-mt76-mt7996-add-SER-state-log-for-debug.patch
new file mode 100644
index 0000000..093244e
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2016-mtk-wifi-mt76-mt7996-add-SER-state-log-for-debug.patch
@@ -0,0 +1,28 @@
+From f6a8fd2686dbc85ca8a4881258e8bde6b1e06481 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Mon, 6 Nov 2023 16:37:23 +0800
+Subject: [PATCH 2016/2020] mtk: wifi: mt76: mt7996: add SER state log for
+ debug.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+---
+ mt7996/mac.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 751a960a..5ffc6018 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -2158,6 +2158,9 @@ void mt7996_coredump(struct mt7996_dev *dev, u8 state)
+ 
+ void mt7996_reset(struct mt7996_dev *dev)
+ {
++	dev_info(dev->mt76.dev, "%s SER recovery state: 0x%08x\n",
++		 wiphy_name(dev->mt76.hw->wiphy), READ_ONCE(dev->recovery.state));
++
+ 	if (!dev->recovery.hw_init_done)
+ 		return;
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2017-mtk-wifi-mt76-mt7996-Remove-wed-rro-ring-add-napi-at.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2017-mtk-wifi-mt76-mt7996-Remove-wed-rro-ring-add-napi-at.patch
new file mode 100644
index 0000000..49cb21a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2017-mtk-wifi-mt76-mt7996-Remove-wed-rro-ring-add-napi-at.patch
@@ -0,0 +1,31 @@
+From b81245ff66c12f52508f3a2fd22ef2c7cf56cde4 Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Mon, 6 Nov 2023 10:16:34 +0800
+Subject: [PATCH 2017/2020] mtk: wifi: mt76: mt7996: Remove wed rro ring add
+ napi at init state
+
+without this patch. rro ring will add napi at initial state. once rro ring add napi, it will have chance to be used by host driver. if host driver accessed the ring data, it will cause some issue.
+
+Signed-off-by: mtk27745 <rex.lu@mediatek.com>
+---
+ dma.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/dma.c b/dma.c
+index 5ddb6be9..698f39c0 100644
+--- a/dma.c
++++ b/dma.c
+@@ -1093,6 +1093,10 @@ mt76_dma_init(struct mt76_dev *dev,
+ 	init_completion(&dev->mmio.wed_reset_complete);
+ 
+ 	mt76_for_each_q_rx(dev, i) {
++		if (mtk_wed_device_active(&dev->mmio.wed) &&
++		    mt76_queue_is_wed_rro(&dev->q_rx[i]))
++			continue;
++
+ 		netif_napi_add(&dev->napi_dev, &dev->napi[i], poll);
+ 		mt76_dma_rx_fill(dev, &dev->q_rx[i]);
+ 		napi_enable(&dev->napi[i]);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2018-mtk-wifi-mt76-mt7996-Remove-wed_stop-during-L1-SER.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2018-mtk-wifi-mt76-mt7996-Remove-wed_stop-during-L1-SER.patch
new file mode 100644
index 0000000..5ac595c
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2018-mtk-wifi-mt76-mt7996-Remove-wed_stop-during-L1-SER.patch
@@ -0,0 +1,33 @@
+From 3c31acb1c6a90e33ca0aa60f6f605ccc75d0ac93 Mon Sep 17 00:00:00 2001
+From: Rex Lu <rex.lu@mediatek.com>
+Date: Wed, 29 Nov 2023 13:56:52 +0800
+Subject: [PATCH 2018/2020] mtk: wifi: mt76: mt7996: Remove wed_stop during L1
+ SER
+
+Align logan L1 SER flow. During L1 SER, didn't need to close wed interrupt.
+
+Signed-off-by: Rex Lu <rex.lu@mediatek.com>
+---
+ mt7996/mac.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 5ffc6018..0ebad4ac 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1941,12 +1941,6 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 	dev_info(dev->mt76.dev,"\n%s L1 SER recovery start.",
+ 		 wiphy_name(dev->mt76.hw->wiphy));
+ 
+-	if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
+-		mtk_wed_device_stop(&dev->mt76.mmio.wed_hif2);
+-
+-	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
+-		mtk_wed_device_stop(&dev->mt76.mmio.wed);
+-
+ 	ieee80211_stop_queues(mt76_hw(dev));
+ 	if (phy2)
+ 		ieee80211_stop_queues(phy2->mt76->hw);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2019-mtk-wifi-mt76-mt7996-Refactor-rro-del-ba-command-for.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2019-mtk-wifi-mt76-mt7996-Refactor-rro-del-ba-command-for.patch
new file mode 100644
index 0000000..66b06a8
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2019-mtk-wifi-mt76-mt7996-Refactor-rro-del-ba-command-for.patch
@@ -0,0 +1,85 @@
+From 025d64a4244f872c0e767cbefa8dbeb1af84de39 Mon Sep 17 00:00:00 2001
+From: Rex Lu <rex.lu@mediatek.com>
+Date: Wed, 29 Nov 2023 15:51:04 +0800
+Subject: [PATCH 2019/2020] mtk: wifi: mt76: mt7996: Refactor rro del ba
+ command format
+
+1. remove unused struct
+2. refactor upstream del ba command format
+
+Signed-off-by: Rex Lu <rex.lu@mediatek.com>
+---
+ mt7996/mcu.h | 50 +++-----------------------------------------------
+ 1 file changed, 3 insertions(+), 47 deletions(-)
+
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 7b8540f6..a05dd6a5 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -273,7 +273,9 @@ struct mt7996_mcu_wed_rro_ba_delete_event {
+ 	__le16 len;
+ 
+ 	__le16 session_id;
+-	u8 __rsv2[2];
++	__le16 mld_id;
++	u8 tid;
++	u8 __rsv[3];
+ } __packed;
+ 
+ enum  {
+@@ -298,52 +300,6 @@ struct mt7996_mcu_thermal_notify {
+ 	u8 __rsv2[4];
+ } __packed;
+ 
+-struct mt7996_mcu_rro_event {
+-	struct mt7996_mcu_rxd rxd;
+-
+-	u8 __rsv1[4];
+-
+-	__le16 tag;
+-	__le16 len;
+-} __packed;
+-
+-struct mt7996_mcu_rro_ba {
+-	__le16 tag;
+-	__le16 len;
+-
+-	__le16 wlan_id;
+-	u8 tid;
+-	u8 __rsv1;
+-	__le32 status;
+-	__le16 session_id;
+-	u8 __rsv2[2];
+-} __packed;
+-
+-struct mt7996_mcu_rro_ba_del_chk_done {
+-	__le16 tag;
+-	__le16 len;
+-
+-	__le16 session_id;
+-	__le16 mld_id;
+-	u8 tid;
+-	u8 __rsv[3];
+-} __packed;
+-
+-enum  {
+-	UNI_RRO_BA_SESSION_STATUS = 0,
+-	UNI_RRO_BA_SESSION_TBL	= 1,
+-	UNI_RRO_BA_SESSION_DEL_CHK_DONE = 2,
+-	UNI_RRO_BA_SESSION_MAX_NUM
+-};
+-
+-struct mt7996_mcu_rro_del_ba {
+-	struct mt7996_mcu_rro_event event;
+-
+-	u8  wlan_idx;
+-	u8  tid;
+-	u8 __rsv2[2];
+-};
+-
+ enum mt7996_chan_mib_offs {
+ 	UNI_MIB_OBSS_AIRTIME = 26,
+ 	UNI_MIB_NON_WIFI_TIME = 27,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2020-mtk-wifi-mt76-mt7996-get-airtime-and-RSSI-via-MCU-co.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2020-mtk-wifi-mt76-mt7996-get-airtime-and-RSSI-via-MCU-co.patch
new file mode 100644
index 0000000..c34671f
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2020-mtk-wifi-mt76-mt7996-get-airtime-and-RSSI-via-MCU-co.patch
@@ -0,0 +1,784 @@
+From 555895ccd2379f4b9d94148f7d67afb4a4d97be4 Mon Sep 17 00:00:00 2001
+From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Date: Fri, 17 Nov 2023 18:08:06 +0800
+Subject: [PATCH 2020/2020] mtk: wifi: mt76: mt7996: get airtime and RSSI via
+ MCU commands
+
+Direct access to WTBL for airtime and RSSI may cause synchronization issue with FW.
+Moreover, frequent access to WTBL, whenever TX-Free-Done event is received, leads to heavy CPU overheads.
+Therefore, indirect access to WTBL, through FW, with lower frequence is performed.
+
+Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+---
+ mt76.h               |  20 +++++
+ mt76_connac_mcu.h    |  14 +++-
+ mt7996/debugfs.c     |  17 ++---
+ mt7996/mac.c         | 145 ++++++-----------------------------
+ mt7996/mcu.c         | 177 +++++++++++++++++++++++++++++++++++++++++--
+ mt7996/mcu.h         |  32 +++++++-
+ mt7996/mt7996.h      |  26 ++++++-
+ mt7996/mtk_debugfs.c |  71 +++++++++++++++++
+ mt7996/regs.h        |   2 +
+ 9 files changed, 361 insertions(+), 143 deletions(-)
+
+diff --git a/mt76.h b/mt76.h
+index cf88eafa..942d9c11 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -324,11 +324,15 @@ struct mt76_sta_stats {
+ 	u32 tx_packets;		/* unit: MSDU */
+ 	u32 tx_retries;
+ 	u32 tx_failed;
++	u32 tx_total_mpdu_cnt;
++	u32 tx_failed_mpdu_cnt;
++	u64 tx_airtime;
+ 	/* WED RX */
+ 	u64 rx_bytes;
+ 	u32 rx_packets;
+ 	u32 rx_errors;
+ 	u32 rx_drops;
++	u64 rx_airtime;
+ };
+ 
+ enum mt76_wcid_flags {
+@@ -1312,6 +1316,22 @@ static inline int mt76_decr(int val, int size)
+ 
+ u8 mt76_ac_to_hwq(u8 ac);
+ 
++static inline u8
++mt76_ac_to_tid(u8 ac)
++{
++	static const u8 ac_to_tid[] = {
++		[IEEE80211_AC_BE] = 0,
++		[IEEE80211_AC_BK] = 1,
++		[IEEE80211_AC_VI] = 4,
++		[IEEE80211_AC_VO] = 6
++	};
++
++	if (WARN_ON(ac >= IEEE80211_NUM_ACS))
++		return 0;
++
++	return ac_to_tid[ac];
++}
++
+ static inline struct ieee80211_txq *
+ mtxq_to_txq(struct mt76_txq *mtxq)
+ {
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 306e7bee..8056911f 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1357,11 +1357,23 @@ enum {
+ 	UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
+ };
+ 
++enum UNI_PER_STA_INFO_TAG {
++	UNI_PER_STA_RSSI,
++	UNI_PER_STA_CONTENTION_RX_RATE,
++	UNI_PER_STA_PER,
++	UNI_PER_STA_SNR,
++	UNI_PER_STA_TX_RATE,
++	UNI_PER_STA_TX_CNT,
++	UNI_PER_STA_TID_SN_GET,
++	UNI_PER_STA_TID_SN_SET,
++	UNI_PER_STA_MAX_NUM
++};
++
+ enum UNI_ALL_STA_INFO_TAG {
+ 	UNI_ALL_STA_TXRX_RATE,
+ 	UNI_ALL_STA_TX_STAT,
+ 	UNI_ALL_STA_TXRX_ADM_STAT,
+-	UNI_ALL_STA_TXRX_AIR_TIME,
++	UNI_ALL_STA_TXRX_AIRTIME,
+ 	UNI_ALL_STA_DATA_TX_RETRY_COUNT,
+ 	UNI_ALL_STA_GI_MODE,
+ 	UNI_ALL_STA_TXRX_MSDU_COUNT,
+diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
+index 3d514c44..c16099f9 100644
+--- a/mt7996/debugfs.c
++++ b/mt7996/debugfs.c
+@@ -914,12 +914,11 @@ mt7996_airtime_read(struct seq_file *s, void *data)
+ {
+ 	struct mt7996_dev *dev = dev_get_drvdata(s->private);
+ 	struct mt76_dev *mdev = &dev->mt76;
+-	struct mt7996_vow_sta_ctrl *vow;
++	struct mt76_sta_stats *stats;
+ 	struct ieee80211_sta *sta;
+ 	struct mt7996_sta *msta;
+ 	struct mt76_wcid *wcid;
+ 	struct mt76_vif *vif;
+-	u64 airtime;
+ 	u16 i;
+ 
+ 	seq_printf(s, "VoW Airtime Information:\n");
+@@ -931,16 +930,16 @@ mt7996_airtime_read(struct seq_file *s, void *data)
+ 
+ 		msta = container_of(wcid, struct mt7996_sta, wcid);
+ 		sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
+-		vow = &msta->vow;
+ 		vif = &msta->vif->mt76;
++		stats = &wcid->stats;
+ 
+-		spin_lock_bh(&vow->lock);
+-		airtime = vow->tx_airtime;
+-		vow->tx_airtime = 0;
+-		spin_unlock_bh(&vow->lock);
++		seq_printf(s, "%pM WCID: %hu BandIdx: %hhu OmacIdx: 0x%hhx\t"
++		              "TxAirtime: %llu\tRxAirtime: %llu\n",
++		              sta->addr, i, vif->band_idx, vif->omac_idx,
++		              stats->tx_airtime, stats->rx_airtime);
+ 
+-		seq_printf(s, "%pM WCID: %hu BandIdx: %hhu OmacIdx: 0x%hhx\tTxAirtime: %llu\n",
+-		           sta->addr, i, vif->band_idx, vif->omac_idx, airtime);
++		stats->tx_airtime = 0;
++		stats->rx_airtime = 0;
+ 	}
+ 	rcu_read_unlock();
+ 
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 0ebad4ac..bdf808fc 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -12,8 +12,6 @@
+ #include "mcu.h"
+ #include "vendor.h"
+ 
+-#define to_rssi(field, rcpi)	((FIELD_GET(field, rcpi) - 220) / 2)
+-
+ static const struct mt7996_dfs_radar_spec etsi_radar_specs = {
+ 	.pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 },
+ 	.radar_pattern = {
+@@ -93,110 +91,6 @@ u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw)
+ 	return MT_WTBL_LMAC_OFFS(wcid, dw);
+ }
+ 
+-static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
+-{
+-	static const u8 ac_to_tid[] = {
+-		[IEEE80211_AC_BE] = 0,
+-		[IEEE80211_AC_BK] = 1,
+-		[IEEE80211_AC_VI] = 4,
+-		[IEEE80211_AC_VO] = 6
+-	};
+-	struct ieee80211_sta *sta;
+-	struct mt7996_sta *msta;
+-	struct mt7996_vow_sta_ctrl *vow;
+-	u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
+-	LIST_HEAD(sta_poll_list);
+-	int i;
+-
+-	spin_lock_bh(&dev->mt76.sta_poll_lock);
+-	list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
+-	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+-
+-	rcu_read_lock();
+-
+-	while (true) {
+-		bool clear = false;
+-		u32 addr, val;
+-		u16 idx;
+-		s8 rssi[4];
+-
+-		spin_lock_bh(&dev->mt76.sta_poll_lock);
+-		if (list_empty(&sta_poll_list)) {
+-			spin_unlock_bh(&dev->mt76.sta_poll_lock);
+-			break;
+-		}
+-		msta = list_first_entry(&sta_poll_list,
+-					struct mt7996_sta, wcid.poll_list);
+-		list_del_init(&msta->wcid.poll_list);
+-		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+-
+-		idx = msta->wcid.idx;
+-
+-		/* refresh peer's airtime reporting */
+-		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 20);
+-
+-		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+-			u32 tx_last = msta->airtime_ac[i];
+-			u32 rx_last = msta->airtime_ac[i + 4];
+-
+-			msta->airtime_ac[i] = mt76_rr(dev, addr);
+-			msta->airtime_ac[i + 4] = mt76_rr(dev, addr + 4);
+-
+-			tx_time[i] = msta->airtime_ac[i] - tx_last;
+-			rx_time[i] = msta->airtime_ac[i + 4] - rx_last;
+-
+-			if ((tx_last | rx_last) & BIT(30))
+-				clear = true;
+-
+-			addr += 8;
+-		}
+-
+-		if (clear) {
+-			mt7996_mac_wtbl_update(dev, idx,
+-					       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
+-			memset(msta->airtime_ac, 0, sizeof(msta->airtime_ac));
+-		}
+-
+-		if (!msta->wcid.sta)
+-			continue;
+-
+-		sta = container_of((void *)msta, struct ieee80211_sta,
+-				   drv_priv);
+-		vow = &msta->vow;
+-		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+-			u8 q = mt76_connac_lmac_mapping(i);
+-			u32 tx_cur = tx_time[q];
+-			u32 rx_cur = rx_time[q];
+-			u8 tid = ac_to_tid[i];
+-
+-			if (!tx_cur && !rx_cur)
+-				continue;
+-
+-			ieee80211_sta_register_airtime(sta, tid, tx_cur, rx_cur);
+-
+-			spin_lock_bh(&vow->lock);
+-			vow->tx_airtime += tx_cur;
+-			spin_unlock_bh(&vow->lock);
+-		}
+-
+-		/* get signal strength of resp frames (CTS/BA/ACK) */
+-		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
+-		val = mt76_rr(dev, addr);
+-
+-		rssi[0] = to_rssi(GENMASK(7, 0), val);
+-		rssi[1] = to_rssi(GENMASK(15, 8), val);
+-		rssi[2] = to_rssi(GENMASK(23, 16), val);
+-		rssi[3] = to_rssi(GENMASK(31, 14), val);
+-
+-		msta->ack_signal =
+-			mt76_rx_signal(msta->vif->phy->mt76->antenna_mask, rssi);
+-
+-		ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal);
+-	}
+-
+-	rcu_read_unlock();
+-}
+-
+ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
+ 			      struct ieee80211_vif *vif, bool enable)
+ {
+@@ -1206,8 +1100,6 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+ 		}
+ 	}
+ 
+-	mt7996_mac_sta_poll(dev);
+-
+ 	if (wake)
+ 		mt76_set_tx_blocked(&dev->mt76, false);
+ 
+@@ -2369,31 +2261,42 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
+ 
+ void mt7996_mac_work(struct work_struct *work)
+ {
+-	struct mt7996_phy *phy;
+-	struct mt76_phy *mphy;
+-
+-	mphy = (struct mt76_phy *)container_of(work, struct mt76_phy,
+-					       mac_work.work);
+-	phy = mphy->priv;
++	struct mt76_phy *mphy = (struct mt76_phy *)container_of(work, struct mt76_phy,
++	                                                        mac_work.work);
++	struct mt7996_phy *phy = mphy->priv;
++	struct mt76_dev *mdev = mphy->dev;
+ 
+-	mutex_lock(&mphy->dev->mutex);
++	mutex_lock(&mdev->mutex);
+ 
+ 	mt76_update_survey(mphy);
+ 	if (++mphy->mac_work_count == 5) {
++		int i;
++
+ 		mphy->mac_work_count = 0;
+ 
+ 		mt7996_mac_update_stats(phy);
+ 
+-		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_RATE);
+-		if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
+-			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
+-			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
++		/* Update DEV-wise information only in
++		 * the MAC work of the first band running.
++		 */
++		for (i = MT_BAND0; i <= mphy->band_idx; ++i) {
++			if (i == mphy->band_idx) {
++				mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_RATE);
++				mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_AIRTIME);
++				mt7996_mcu_get_rssi(mdev);
++				if (mtk_wed_device_active(&mdev->mmio.wed)) {
++					mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_ADM_STAT);
++					mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_MSDU_COUNT);
++				}
++			} else if (mt7996_band_valid(phy->dev, i) &&
++			           test_bit(MT76_STATE_RUNNING, &mdev->phys[i]->state))
++				break;
+ 		}
+ 	}
+ 
+-	mutex_unlock(&mphy->dev->mutex);
++	mutex_unlock(&mdev->mutex);
+ 
+-	mt76_tx_status_check(mphy->dev, false);
++	mt76_tx_status_check(mdev, false);
+ 
+ 	ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
+ 				     MT7996_WATCHDOG_TIME);
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 57af55ec..b849ebe1 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -560,7 +560,8 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 		u16 wlan_idx;
+ 		struct mt76_wcid *wcid;
+ 		struct mt76_phy *mphy;
+-		u32 tx_bytes, rx_bytes, tx_packets, rx_packets;
++		struct ieee80211_sta *sta;
++		u32 tx_bytes, rx_bytes, tx_airtime, rx_airtime, tx_packets, rx_packets;
+ 
+ 		switch (le16_to_cpu(res->tag)) {
+ 		case UNI_ALL_STA_TXRX_RATE:
+@@ -581,7 +582,7 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 				break;
+ 
+ 			mphy = mt76_dev_phy(&dev->mt76, wcid->phy_idx);
+-			for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
++			for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) {
+ 				tx_bytes = le32_to_cpu(res->adm_stat[i].tx_bytes[ac]);
+ 				rx_bytes = le32_to_cpu(res->adm_stat[i].rx_bytes[ac]);
+ 
+@@ -613,6 +614,24 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 			__mt7996_stat_to_netdev(mphy, wcid, 0, 0,
+ 						tx_packets, rx_packets);
+ 			break;
++		case UNI_ALL_STA_TXRX_AIRTIME:
++			wlan_idx = le16_to_cpu(res->airtime[i].wlan_idx);
++			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
++			sta = wcid_to_sta(wcid);
++			if (!sta)
++				continue;
++
++			for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ++ac) {
++				u8 lmac_ac = mt76_connac_lmac_mapping(ac);
++				tx_airtime = le32_to_cpu(res->airtime[i].tx[lmac_ac]);
++				rx_airtime = le32_to_cpu(res->airtime[i].rx[lmac_ac]);
++
++				wcid->stats.tx_airtime += tx_airtime;
++				wcid->stats.rx_airtime += rx_airtime;
++				ieee80211_sta_register_airtime(sta, mt76_ac_to_tid(ac),
++				                               tx_airtime, rx_airtime);
++			}
++			break;
+ 		default:
+ 			break;
+ 		}
+@@ -2239,8 +2258,6 @@ mt7996_mcu_sta_init_vow(struct mt7996_phy *phy, struct mt7996_sta *msta)
+ 	vow->drr_quantum[IEEE80211_AC_VI] = VOW_DRR_QUANTUM_IDX1;
+ 	vow->drr_quantum[IEEE80211_AC_BE] = VOW_DRR_QUANTUM_IDX2;
+ 	vow->drr_quantum[IEEE80211_AC_BK] = VOW_DRR_QUANTUM_IDX2;
+-	vow->tx_airtime = 0;
+-	spin_lock_init(&vow->lock);
+ 
+ 	ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_BSS_GROUP);
+ 	if (ret)
+@@ -4844,9 +4861,155 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val)
+ 				 sizeof(req), true);
+ }
+ 
+-int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
++int mt7996_mcu_get_per_sta_info(struct mt76_dev *dev, u16 tag,
++	                        u16 sta_num, u16 *sta_list)
++{
++#define PER_STA_INFO_MAX_NUM	90
++	struct mt7996_mcu_per_sta_info_event *res;
++	struct mt76_wcid *wcid;
++	struct sk_buff *skb;
++	u16 wlan_idx;
++	int i, ret;
++	struct {
++		u8 __rsv1;
++		u8 unsolicit;
++		u8 __rsv2[2];
++
++		__le16 tag;
++		__le16 len;
++		__le16 sta_num;
++		u8 __rsv3[2];
++		__le16 sta_list[PER_STA_INFO_MAX_NUM];
++	} __packed req = {
++		.unsolicit = 0,
++		.tag = cpu_to_le16(tag),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.sta_num = cpu_to_le16(sta_num)
++	};
++
++	if (sta_num > PER_STA_INFO_MAX_NUM)
++		return -EINVAL;
++
++	for (i = 0; i < sta_num; ++i)
++		req.sta_list[i] = cpu_to_le16(sta_list[i]);
++
++	ret = mt76_mcu_send_and_get_msg(dev, MCU_WM_UNI_CMD(PER_STA_INFO),
++	                                &req, sizeof(req), true, &skb);
++	if (ret)
++		return ret;
++
++	res = (struct mt7996_mcu_per_sta_info_event *)skb->data;
++	if (le16_to_cpu(res->tag) != tag) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	rcu_read_lock();
++	switch (tag) {
++	case UNI_PER_STA_RSSI:
++		for (i = 0; i < sta_num; ++i) {
++			struct mt7996_sta *msta;
++			struct mt76_phy *phy;
++			s8 rssi[4];
++			u8 *rcpi;
++
++			wlan_idx = le16_to_cpu(res->rssi[i].wlan_idx);
++			wcid = rcu_dereference(dev->wcid[wlan_idx]);
++			if (wcid) {
++				rcpi = res->rssi[i].rcpi;
++				rssi[0] = to_rssi(MT_PRXV_RCPI0, rcpi[0]);
++				rssi[1] = to_rssi(MT_PRXV_RCPI0, rcpi[1]);
++				rssi[2] = to_rssi(MT_PRXV_RCPI0, rcpi[2]);
++				rssi[3] = to_rssi(MT_PRXV_RCPI0, rcpi[3]);
++
++				msta = container_of(wcid, struct mt7996_sta, wcid);
++				phy = msta->vif->phy->mt76;
++				msta->ack_signal = mt76_rx_signal(phy->antenna_mask, rssi);
++				ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal);
++			} else {
++				ret = -EINVAL;
++				dev_err(dev->dev, "Failed to update RSSI for "
++				                  "invalid WCID: %hu\n", wlan_idx);
++			}
++		}
++		break;
++	case UNI_PER_STA_TX_CNT:
++		for (i = 0; i < sta_num; ++i) {
++			wlan_idx = le16_to_cpu(res->tx_cnt[i].wlan_idx);
++			wcid = rcu_dereference(dev->wcid[wlan_idx]);
++			if (wcid) {
++				wcid->stats.tx_total_mpdu_cnt +=
++				            le32_to_cpu(res->tx_cnt[i].total);
++				wcid->stats.tx_failed_mpdu_cnt +=
++				            le32_to_cpu(res->tx_cnt[i].failed);
++			} else {
++				ret = -EINVAL;
++				dev_err(dev->dev, "Failed to update TX MPDU counts "
++				                  "for invalid WCID: %hu\n", wlan_idx);
++			}
++		}
++		break;
++	default:
++		ret = -EINVAL;
++		dev_err(dev->dev, "Unknown UNI_PER_STA_INFO_TAG: %d\n", tag);
++	}
++	rcu_read_unlock();
++out:
++	dev_kfree_skb(skb);
++	return ret;
++}
++
++int mt7996_mcu_get_rssi(struct mt76_dev *dev)
++{
++	u16 sta_list[PER_STA_INFO_MAX_NUM];
++	LIST_HEAD(sta_poll_list);
++	struct mt7996_sta *msta;
++	int i, ret;
++	bool empty = false;
++
++	spin_lock_bh(&dev->sta_poll_lock);
++	list_splice_init(&dev->sta_poll_list, &sta_poll_list);
++	spin_unlock_bh(&dev->sta_poll_lock);
++
++	while (!empty) {
++		for (i = 0; i < PER_STA_INFO_MAX_NUM; ++i) {
++			spin_lock_bh(&dev->sta_poll_lock);
++			if (list_empty(&sta_poll_list)) {
++				spin_unlock_bh(&dev->sta_poll_lock);
++
++				if (i == 0)
++					return 0;
++
++				empty = true;
++				break;
++			}
++			msta = list_first_entry(&sta_poll_list,
++			                        struct mt7996_sta,
++			                        wcid.poll_list);
++			list_del_init(&msta->wcid.poll_list);
++			spin_unlock_bh(&dev->sta_poll_lock);
++
++			sta_list[i] = msta->wcid.idx;
++		}
++
++		ret = mt7996_mcu_get_per_sta_info(dev, UNI_PER_STA_RSSI,
++		                                  i, sta_list);
++		if (ret) {
++			/* Add STAs, whose RSSI has not been updated,
++			 * back to polling list.
++			 */
++			spin_lock_bh(&dev->sta_poll_lock);
++			list_splice(&sta_poll_list, &dev->sta_poll_list);
++			spin_unlock_bh(&dev->sta_poll_lock);
++			break;
++		}
++	}
++
++	return ret;
++}
++
++int mt7996_mcu_get_all_sta_info(struct mt76_dev *dev, u16 tag)
+ {
+-	struct mt7996_dev *dev = phy->dev;
+ 	struct {
+ 		u8 _rsv[4];
+ 
+@@ -4857,7 +5020,7 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
+ 		.len = cpu_to_le16(sizeof(req) - 4),
+ 	};
+ 
+-	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO),
++	return mt76_mcu_send_msg(dev, MCU_WM_UNI_CMD(ALL_STA_INFO),
+ 				 &req, sizeof(req), false);
+ }
+ 
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index a05dd6a5..cd327451 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -199,6 +199,31 @@ struct mt7996_mcu_mib {
+ 	__le64 data;
+ } __packed;
+ 
++struct per_sta_rssi {
++	__le16 wlan_idx;
++	u8 __rsv[2];
++	u8 rcpi[4];
++} __packed;
++
++struct per_sta_tx_cnt {
++	__le16 wlan_idx;
++	u8 __rsv[2];
++	__le32 total;
++	__le32 failed;
++} __packed;
++
++struct mt7996_mcu_per_sta_info_event {
++	u8 __rsv[4];
++
++	__le16 tag;
++	__le16 len;
++
++	union {
++		struct per_sta_rssi rssi[0];
++		struct per_sta_tx_cnt tx_cnt[0];
++	};
++} __packed;
++
+ struct all_sta_trx_rate {
+ 	__le16 wlan_idx;
+ 	u8 __rsv1[2];
+@@ -237,13 +262,18 @@ struct mt7996_mcu_all_sta_info_event {
+ 			__le32 tx_bytes[IEEE80211_NUM_ACS];
+ 			__le32 rx_bytes[IEEE80211_NUM_ACS];
+ 		} adm_stat[0] __packed;
+-
+ 		struct {
+ 			__le16 wlan_idx;
+ 			u8 rsv[2];
+ 			__le32 tx_msdu_cnt;
+ 			__le32 rx_msdu_cnt;
+ 		} msdu_cnt[0] __packed;
++		struct {
++			__le16 wlan_idx;
++			u8 __rsv[2];
++			__le32 tx[IEEE80211_NUM_ACS];
++			__le32 rx[IEEE80211_NUM_ACS];
++		} airtime[0] __packed;
+ 	} __packed;
+ } __packed;
+ 
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 677f00b0..c128fb8e 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -126,6 +126,8 @@
+ #define MT7996_RRO_MSDU_PG_CR_CNT 8
+ #define MT7996_RRO_MSDU_PG_SIZE_PER_CR 0x10000
+ 
++#define to_rssi(field, rcpi)	((FIELD_GET(field, rcpi) - 220) / 2)
++
+ struct mt7996_vif;
+ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+@@ -298,8 +300,6 @@ struct mt7996_vow_sta_ctrl {
+ 	bool paused;
+ 	u8 bss_grp_idx;
+ 	u8 drr_quantum[IEEE80211_NUM_ACS];
+-	u64 tx_airtime;
+-	spinlock_t lock;
+ };
+ 
+ struct mt7996_sta {
+@@ -308,7 +308,6 @@ struct mt7996_sta {
+ 	struct mt7996_vif *vif;
+ 
+ 	struct list_head rc_list;
+-	u32 airtime_ac[8];
+ 
+ 	int ack_signal;
+ 	struct ewma_avg_signal avg_ack_signal;
+@@ -404,6 +403,21 @@ struct mt7996_air_monitor_ctrl {
+ };
+ #endif
+ 
++struct mt7996_rro_ba_session {
++	u32 ack_sn         :12;
++	u32 win_sz         :3;
++	u32 bn             :1;
++	u32 last_in_sn     :12;
++	u32 bc             :1;
++	u32 bd             :1;
++	u32 sat            :1;
++	u32 cn             :1;
++	u32 within_cnt     :12;
++	u32 to_sel         :3;
++	u32 rsv            :1;
++	u32 last_in_rxtime :12;
++};
++
+ struct mt7996_phy {
+ 	struct mt76_phy *mt76;
+ 	struct mt7996_dev *dev;
+@@ -592,6 +606,7 @@ struct mt7996_dev {
+ 		u32 fw_dbg_module;
+ 		u8 fw_dbg_lv;
+ 		u32 bcn_total_cnt[__MT_MAX_BAND];
++		u32 sid;
+ 	} dbg;
+ 	const struct mt7996_dbg_reg_desc *dbg_reg;
+ #endif
+@@ -797,7 +812,10 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
+ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
+ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ void mt7996_mcu_exit(struct mt7996_dev *dev);
+-int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
++int mt7996_mcu_get_per_sta_info(struct mt76_dev *dev, u16 tag,
++	                        u16 sta_num, u16 *sta_list);
++int mt7996_mcu_get_rssi(struct mt76_dev *dev);
++int mt7996_mcu_get_all_sta_info(struct mt76_dev *dev, u16 tag);
+ int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id);
+ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
+ int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index c1764824..3b5ae7ac 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2951,6 +2951,69 @@ mt7996_vow_drr_dbg(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_vow_drr_dbg, NULL,
+ 			 mt7996_vow_drr_dbg, "%lld\n");
+ 
++static int
++mt7996_rro_session_read(struct seq_file *s, void *data)
++{
++	struct mt7996_dev *dev = dev_get_drvdata(s->private);
++	struct mt7996_rro_ba_session *tbl;
++	u32 value[2];
++
++	mt76_wr(dev, MT_RRO_DBG_RD_CTRL, MT_RRO_DBG_RD_EXEC +
++		(dev->dbg.sid >> 1) + 0x200);
++
++	if (dev->dbg.sid & 0x1) {
++		value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(2));
++		value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(3));
++	} else {
++		value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(0));
++		value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(1));
++	}
++
++	tbl = (struct mt7996_rro_ba_session *)&value[0];
++
++	seq_printf(s, " seid %d:\nba session table DW0:%08x DW2:%08x\n",
++		   dev->dbg.sid, value[0], value[1]);
++
++	seq_printf(s, "ack_sn = 0x%x, last_in_sn = 0x%x, sat/bn/bc/bd/cn = %d/%d/%d/%d/%d\n",
++		   tbl->ack_sn, tbl->last_in_sn, tbl->sat, tbl->bn, tbl->bc, tbl->bd, tbl->cn);
++
++	seq_printf(s, "within_cnt = %d, to_sel = %d, last_in_rxtime = %d\n",
++		   tbl->within_cnt, tbl->to_sel, tbl->last_in_rxtime);
++
++	return 0;
++}
++
++static int
++mt7996_show_rro_mib(struct seq_file *s, void *data)
++{
++	struct mt7996_dev *dev = dev_get_drvdata(s->private);
++	u32 reg[12];
++
++	seq_printf(s, "RRO mib Info:\n");
++
++	reg[0] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(0));
++	reg[1] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(1));
++	reg[2] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(2));
++	reg[3] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(3));
++	reg[4] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(4));
++	reg[5] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(5));
++	reg[6] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(6));
++	reg[7] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(7));
++	reg[8] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(8));
++	reg[9] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(9));
++	reg[10] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(10));
++	reg[11] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(11));
++
++	seq_printf(s, "STEP_ONE/WITHIN/SURPASS = %x/%x/%x\n", reg[0], reg[3], reg[4]);
++	seq_printf(s, "REPEAT/OLDPKT/BAR = %x/%x/%x\n", reg[1], reg[2], reg[5]);
++	seq_printf(s, "SURPASS with big gap = %x\n", reg[6]);
++	seq_printf(s, "DISCONNECT/INVALID = %x/%x\n", reg[7], reg[8]);
++	seq_printf(s, "TO(Step one)/TO(flush all) = %x/%x\n", reg[9], reg[10]);
++	seq_printf(s, "buf ran out = %x\n", reg[11]);
++
++	return 0;
++}
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -3049,6 +3112,14 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ 
+ 	debugfs_create_file("muru_prot_thr", 0200, dir, phy, &fops_muru_prot_thr);
+ 
++	if (dev->has_rro) {
++		debugfs_create_u32("rro_sid", 0600, dir, &dev->dbg.sid);
++		debugfs_create_devm_seqfile(dev->mt76.dev, "rro_sid_info", dir,
++					    mt7996_rro_session_read);
++		debugfs_create_devm_seqfile(dev->mt76.dev, "rro_mib", dir,
++					    mt7996_show_rro_mib);
++	}
++
+ 	return 0;
+ }
+ 
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index a3b62339..476b23c3 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -122,6 +122,8 @@ enum offs_rev {
+ #define MT_MCU_INT_EVENT_DMA_INIT		BIT(1)
+ #define MT_MCU_INT_EVENT_RESET_DONE		BIT(3)
+ 
++#define WF_RRO_TOP_STATISTIC(_n)		MT_RRO_TOP(0x180 + _n * 0x4)
++
+ /* PLE */
+ #define MT_PLE_BASE				0x820c0000
+ #define MT_PLE(ofs)				(MT_PLE_BASE + (ofs))
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2999-wifi-mt76-mt7996-support-backaward-compatiable.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2999-wifi-mt76-mt7996-support-backaward-compatiable.patch
deleted file mode 100644
index a6ffa60..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2999-wifi-mt76-mt7996-support-backaward-compatiable.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 52c4cb0df8974126a52d907070fcd3205eb21c28 Mon Sep 17 00:00:00 2001
-From: mtk27745 <rex.lu@mediatek.com>
-Date: Fri, 6 Oct 2023 20:59:42 +0800
-Subject: [PATCH 79/98] wifi: mt76: mt7996: support backaward compatiable
-
----
- mmio.c          |  2 +-
- mt7996/dma.c    |  2 +-
- mt7996/main.c   |  2 +-
- mt7996/mcu.c    |  2 +-
- mt7996/mmio.c   | 20 +++++++++++---------
- mt7996/mt7996.h |  1 +
- 6 files changed, 16 insertions(+), 13 deletions(-)
-
-diff --git a/mmio.c b/mmio.c
-index 22629af..aa6fe45 100644
---- a/mmio.c
-+++ b/mmio.c
-@@ -134,7 +134,7 @@ EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
- u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- {
- 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
--	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
-+	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
- 	u32 length;
- 	int i;
- 
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 1163550..326fd4b 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -430,7 +430,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
- 	irq_mask = mdev->mmio.irqmask | MT_INT_RRO_RX_DONE |
- 		   MT_INT_TX_DONE_BAND2;
- 	mt76_wr(dev, MT_INT_MASK_CSR, irq_mask);
--	mtk_wed_device_start_hw_rro(&mdev->mmio.wed, irq_mask, false);
-+	mtk_wed_device_start_hwrro(&mdev->mmio.wed, irq_mask, false);
- 	mt7996_irq_enable(dev, irq_mask);
- 
- 	return 0;
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 2e0b1f1..44612e9 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -1545,7 +1545,7 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
- 	path->mtk_wdma.queue = 0;
- 	path->mtk_wdma.wcid = msta->wcid.idx;
- 
--	path->mtk_wdma.amsdu = mtk_wed_is_amsdu_supported(wed);
-+	path->mtk_wdma.amsdu_en = mtk_wed_device_support_pao(wed);
- 	ctx->dev = NULL;
- 
- 	return 0;
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 1915a22..ea52e09 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -3171,7 +3171,7 @@ static int mt7996_mcu_wa_red_config(struct mt7996_dev *dev)
- 
- 	if (!mtk_wed_device_active(&dev->mt76.mmio.wed))
- 		req.token_per_src[RED_TOKEN_SRC_CNT - 1] =
--			cpu_to_le16(MT7996_TOKEN_SIZE - MT7996_HW_TOKEN_SIZE);
-+			cpu_to_le16(MT7996_SW_TOKEN_SIZE);
- 
- 	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET),
- 				 &req, sizeof(req), false);
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 38b8843..ab7e58e 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -14,7 +14,7 @@
- #include "../trace.h"
- #include "../dma.h"
- 
--static bool wed_enable;
-+static bool wed_enable = true;
- module_param(wed_enable, bool, 0644);
- 
- static const struct __base mt7996_reg_base[] = {
-@@ -360,14 +360,14 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 		}
- 
- 		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
--		wed->wlan.wpdma_rx = wed->wlan.phy_base + hif1_ofs +
-+		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base + hif1_ofs +
- 				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
- 				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
- 
--		wed->wlan.id = 0x7991;
-+		wed->wlan.chip_id = 0x7991;
- 		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
- 	} else {
--		wed->wlan.hw_rro = dev->has_rro; /* default on */
-+		wed->wlan.hwrro = dev->has_rro; /* default on */
- 		wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
- 		wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
- 		wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
-@@ -375,7 +375,7 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 
- 		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
- 
--		wed->wlan.wpdma_rx = wed->wlan.phy_base +
-+		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base +
- 				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
- 				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
- 
-@@ -417,11 +417,11 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 		dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
- 	}
- 
--	wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE;
--	wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf;
-+	wed->wlan.nbuf = MT7996_TOKEN_SIZE;
-+	wed->wlan.token_start = 0;
- 
--	wed->wlan.amsdu_max_subframes = 8;
--	wed->wlan.amsdu_max_len = 1536;
-+	wed->wlan.max_amsdu_nums = 8;
-+	wed->wlan.max_amsdu_len = 1536;
- 
- 	wed->wlan.init_buf = mt7996_wed_init_buf;
- 	wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
-@@ -442,6 +442,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 	*irq = wed->irq;
- 	dev->mt76.dma_dev = wed->dev;
- 
-+	dev->mt76.token_size = MT7996_SW_TOKEN_SIZE;
-+
- 	return 1;
- #else
- 	return 0;
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index ba73520..55a4087 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -67,6 +67,7 @@
- #define MT7996_EEPROM_BLOCK_SIZE	16
- #define MT7996_TOKEN_SIZE		16384
- #define MT7996_HW_TOKEN_SIZE		8192
-+#define MT7996_SW_TOKEN_SIZE		1024
- 
- #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
- #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc b/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
index f1b8285..6fc22a1 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
@@ -1,82 +1,90 @@
 #patch patches (come from openwrt/lede/target/linux/mediatek)
 SRC_URI_append = " \
-    file://0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch \
-    file://0002-wifi-mt76-wed-sync-to-wed-upstream.patch \
-    file://0003-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch \
-    file://0004-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch \
-    file://0005-wifi-mt76-mt7996-add-thermal-protection-support.patch \
-    file://0006-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch \
-    file://0007-wifi-mt76-mt7996-make-band-capability-init-flexible.patch \
-    file://0008-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch \
-    file://0009-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch \
-    file://0010-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch \
-    file://0011-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch \
-    file://0012-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch \
-    file://0013-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch \
-    file://0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch \
-    file://0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch \
-    file://0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch \
-    file://0017-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch \
-    file://0018-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch \
-    file://0019-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch \
-    file://0020-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch \
-    file://0021-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch \
-    file://0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch \
-    file://0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch \
-    file://0024-wifi-mt76-mt7996-add-kite-pci-support.patch \
-    file://0025-wifi-mt76-mt7996-add-kite-wtbl-size-support.patch \
-    file://0026-wifi-mt76-mt7996-accommodate-MT7992-with-different-c.patch \
-    file://0027-wifi-mt76-mt7996-add-AFE-pll-enable-before-driver-ow.patch \
-    file://0028-wifi-mt76-mt7996-add-kite-eagle-CR-offset-revision.patch \
-    file://0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch \
-    file://0030-wifi-mt76-mt7996-fix-all-sta-info-struct-alignment.patch \
-    file://0031-wifi-mt76-mt7996-refine-ampdu-factor.patch \
-    file://0999-wifi-mt76-mt7996-for-build-pass.patch \
-    file://1000-wifi-mt76-mt7996-add-debug-tool.patch \
-    file://1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch \
-    file://1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch \
-    file://1003-wifi-mt76-testmode-add-basic-testmode-support.patch \
-    file://1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch \
-    file://1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch \
-    file://1006-wifi-mt76-mt7996-add-txpower-support.patch \
-    file://1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch \
-    file://1008-wifi-mt76-mt7996-Add-air-monitor-support.patch \
-    file://1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch \
-    file://1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch \
-    file://1011-wifi-mt76-mt7996-add-binfile-mode-support.patch \
-    file://1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch \
-    file://1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch \
-    file://1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch \
-    file://1015-wifi-mt76-mt7996-add-single-sku.patch \
-    file://1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch \
-    file://1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch \
-    file://1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch \
-    file://1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch \
-    file://1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch \
-    file://1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch \
-    file://1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch \
-    file://1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch \
-    file://1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch \
-    file://1025-wifi-mt76-mt7996-support-dup-wtbl.patch \
-    file://1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch \
-    file://1027-wifi-mt76-mt7996-add-kite-fwdl-support.patch \
-    file://1028-wifi-mt76-mt7996-add-kite-eeprom-load-support.patch \
-    file://1029-wifi-mt76-mt7996-add-kite-fw-default-bin-for-differe.patch \
-    file://1030-wifi-mt76-mt7996-add-wtbl_info-support-for-kite.patch \
-    file://2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch \
-    file://2001-wifi-mt76-rework-wed-rx-flow.patch \
-    file://2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch \
-    file://2003-wifi-mt76-add-random-early-drop-support.patch \
-    file://2004-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch \
-    file://2005-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G-ICS.patch \
-    file://2006-wifi-mt76-mt7996-add-rro-elem-free-when-rmmod-wifi-m.patch \
-    file://2007-wifi-mt76-add-SER-support-for-wed3.0.patch \
-    file://2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch \
-    file://2009-wifi-mt76-drop-packet-based-on-ind_reason.patch \
-    file://2010-wifi-mt76-mt7996-add-rro-timeout-setting.patch \
-    file://2011-wifi-mt76-mt7996-add-dma-mask-limitation.patch \
-    file://2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch \
-    file://2013-wifi-mt76-mt7996-support-TX-RX-for-Kite-without-WED-.patch \
-    file://2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch \
-    file://2999-wifi-mt76-mt7996-support-backaward-compatiable.patch \
+    file://0001-mtk-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch \
+    file://0002-mtk-wifi-mt76-connac-use-peer-address-for-station-BM.patch \
+    file://0003-mtk-wifi-mt76-mt7996-disable-rx-header-translation-f.patch \
+    file://0004-mtk-wifi-mt76-check-txs-format-before-getting-skb-by.patch \
+    file://0005-mtk-wifi-mt76-mt7996-fix-some-twt-issues.patch \
+    file://0006-mtk-wifi-mt76-mt7996-disable-AMSDU-for-non-data-fram.patch \
+    file://0007-mtk-wifi-mt76-mt7996-fix-incorrect-interpretation-of.patch \
+    file://0008-mtk-wifi-mt76-mt7992-add-TLV-sanity-check.patch \
+    file://0009-mtk-wifi-mt76-mt7996-fix-HE-beamformer-phy-cap-for-s.patch \
+    file://0010-mtk-wifi-mt76-mt7996-Let-MAC80211-handles-GCMP-IGTK.patch \
+    file://0011-mtk-wifi-mt76-mt7996-fix-efuse-read-issue.patch \
+    file://0012-mtk-wifi-mt76-mt7996-enable-ser-query.patch \
+    file://0013-mtk-wifi-mt76-mt7996-init-rcpi-to-use-better-init-mc.patch \
+    file://0014-mtk-wifi-mt76-mt7996-Fix-TGax-HE-4.51.1_24G-fail.patch \
+    file://0015-mtk-wifi-mt76-mt7996-add-eagle-default-bin-of-differ.patch \
+    file://0016-mtk-wifi-mt76-mt7996-add-kite-fw-default-bin-for-dif.patch \
+    file://0017-mtk-wifi-mt76-mt7996-add-lock-for-indirect-register-.patch \
+    file://0018-mtk-wifi-mt76-connac-set-correct-muar_idx-for-connac.patch \
+    file://0019-mtk-wifi-mt76-mt7996-ACS-channel-time-too-long-on-du.patch \
+    file://0020-mtk-wifi-mt76-mt7996-Fixed-null-pointer-dereference-.patch \
+    file://0021-mtk-wifi-mt76-add-sanity-check-to-prevent-kernel-cra.patch \
+    file://0022-mtk-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch \
+    file://0023-mtk-wifi-mt76-mt7996-add-preamble-puncture-support-f.patch \
+    file://0999-mtk-wifi-mt76-mt7996-for-build-pass.patch \
+    file://1000-mtk-wifi-mt76-mt7996-add-debug-tool.patch \
+    file://1001-mtk-wifi-mt76-mt7996-support-record-muru-algo-log-wh.patch \
+    file://1002-mtk-wifi-mt76-mt7996-add-check-for-hostapd-config-he.patch \
+    file://1003-mtk-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch \
+    file://1004-mtk-wifi-mt76-testmode-add-basic-testmode-support.patch \
+    file://1005-mtk-wifi-mt76-testmode-add-testmode-pre-calibration-.patch \
+    file://1006-mtk-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-d.patch \
+    file://1007-mtk-wifi-mt76-mt7996-add-txpower-support.patch \
+    file://1008-mtk-wifi-mt76-mt7996-add-single-sku.patch \
+    file://1009-mtk-wifi-mt76-mt7996-add-binfile-mode-support.patch \
+    file://1010-mtk-wifi-mt76-mt7996-add-normal-mode-pre-calibration.patch \
+    file://1011-mtk-wifi-mt76-testmode-add-testmode-ZWDFS-verificati.patch \
+    file://1012-mtk-wifi-mt76-mt7996-add-mu-vendor-command-support.patch \
+    file://1013-mtk-wifi-mt76-mt7996-Add-air-monitor-support.patch \
+    file://1014-mtk-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv.patch \
+    file://1015-mtk-wifi-mt76-mt7996-add-vendor-cmd-to-get-available.patch \
+    file://1016-mtk-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch \
+    file://1017-mtk-wifi-mt76-mt7996-add-support-for-runtime-set-in-.patch \
+    file://1018-mtk-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-en.patch \
+    file://1019-mtk-wifi-mt76-mt7996-add-support-spatial-reuse-debug.patch \
+    file://1020-mtk-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch \
+    file://1021-mtk-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-w.patch \
+    file://1022-mtk-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_le.patch \
+    file://1023-mtk-wifi-mt76-mt7996-support-dup-wtbl.patch \
+    file://1024-mtk-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch \
+    file://1025-mtk-wifi-mt76-try-more-times-when-send-message-timeo.patch \
+    file://1026-mtk-wifi-mt76-mt7996-add-SER-overlap-handle.patch \
+    file://1027-mtk-wifi-mt76-mt7996-kite-default-1-pcie-setting.patch \
+    file://1028-mtk-wifi-mt76-mt7996-add-debugfs-knob-for-rx_counter.patch \
+    file://1029-mtk-wifi-mt76-mt7996-add-three-wire-pta-support.patch \
+    file://1030-mtk-wifi-mt76-mt7996-support-BF-MIMO-debug-commands.patch \
+    file://1031-mtk-wifi-mt76-mt7996-add-build-the-following-MURU-mc.patch \
+    file://1032-mtk-wifi-mt76-mt7996-add-cert-patch.patch \
+    file://1033-mtk-wifi-mt76-testmode-add-testmode-bf-support.patch \
+    file://1034-mtk-wifi-mt76-mt7996-add-zwdfs-cert-mode.patch \
+    file://1035-mtk-wifi-mt76-testmode-add-channel-68-96.patch \
+    file://1036-mtk-wifi-mt76-mt7996-support-enable-disable-pp-featu.patch \
+    file://1037-mtk-wifi-mt76-testmode-add-kite-testmode-support.patch \
+    file://1038-mtk-wifi-mt76-mt7996-assign-DEAUTH-to-ALTX-queue-for.patch \
+    file://1039-mtk-wifi-mt76-mt7996-add-no_beacon-vendor-command-fo.patch \
+    file://1040-mtk-wifi-mt76-mt7996-add-adie-efuse-merge-support.patch \
+    file://1041-mtk-wifi-mt7996-add-Eagle-2adie-TBTC-BE14000-support.patch \
+    file://2000-mtk-wifi-mt76-revert-page_poll-for-kernel-5.4.patch \
+    file://2001-mtk-wifi-mt76-rework-wed-rx-flow.patch \
+    file://2002-mtk-wifi-mt76-wed-change-wed-token-init-size-to-adap.patch \
+    file://2003-mtk-wifi-mt76-add-random-early-drop-support.patch \
+    file://2004-mtk-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch \
+    file://2005-mtk-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G.patch \
+    file://2006-mtk-wifi-mt76-add-SER-support-for-wed3.0.patch \
+    file://2007-mtk-wifi-mt76-mt7915-wed-find-rx-token-by-physical-a.patch \
+    file://2008-mtk-wifi-mt76-mt7996-add-dma-mask-limitation.patch \
+    file://2009-mtk-wifi-mt76-mt7996-add-per-bss-statistic-info.patch \
+    file://2010-mtk-wifi-mt76-mt7996-do-not-report-netdev-stats-on-m.patch \
+    file://2011-mtk-wifi-mt76-mt7996-add-support-for-HW-ATF.patch \
+    file://2012-mtk-wifi-mt76-mt7996-wed-add-SER0.5-support-w-wed3.0.patch \
+    file://2013-mtk-wifi-mt76-mt7996-support-backaward-compatiable.patch \
+    file://2014-mtk-wifi-mt76-mt7996-wed-add-wed-support-for-mt7992.patch \
+    file://2015-mtk-wifi-mt76-mt7992-wed-add-2pcie-one-wed-support.patch \
+    file://2016-mtk-wifi-mt76-mt7996-add-SER-state-log-for-debug.patch \
+    file://2017-mtk-wifi-mt76-mt7996-Remove-wed-rro-ring-add-napi-at.patch \
+    file://2018-mtk-wifi-mt76-mt7996-Remove-wed_stop-during-L1-SER.patch \
+    file://2019-mtk-wifi-mt76-mt7996-Refactor-rro-del-ba-command-for.patch \
+    file://2020-mtk-wifi-mt76-mt7996-get-airtime-and-RSSI-via-MCU-co.patch \
     "
diff --git a/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch b/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
index 39ad5d0..8f533b9 100644
--- a/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
@@ -1,7 +1,7 @@
-From 5b47f914de6c0fb2d4a8494bb4c05a6f7d729135 Mon Sep 17 00:00:00 2001
+From 0833b8306d6614f28f9be5df2174667e486cdab7 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Thu, 18 May 2023 18:11:37 +0800
-Subject: [PATCH 1/7] wifi: mt76: fix incorrect HE TX GI report
+Subject: [PATCH 01/76] wifi: mt76: fix incorrect HE TX GI report
 
 Change GI reporting source from static capability to rate-tuning module.
 
@@ -17,10 +17,10 @@
  7 files changed, 282 insertions(+), 22 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index a238216..0609b4a 100644
+index d2ead58..8f1f0a7 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -254,12 +254,16 @@ struct mt76_queue_ops {
+@@ -276,12 +276,16 @@ struct mt76_queue_ops {
  	void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q);
  };
  
@@ -38,10 +38,10 @@
  	MT_PHY_TYPE_HE_EXT_SU,
  	MT_PHY_TYPE_HE_TB,
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 9312c35..c1f234e 100644
+index 11c4621..ea96d8d 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -660,6 +660,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
+@@ -673,6 +673,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
  	struct mt76_phy *mphy = phy->mt76;
  	int ret;
  
@@ -50,7 +50,7 @@
  	INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work);
  
  	mt7915_eeprom_parse_hw_cap(dev, phy);
-@@ -1192,6 +1194,8 @@ int mt7915_register_device(struct mt7915_dev *dev)
+@@ -1202,6 +1204,8 @@ int mt7915_register_device(struct mt7915_dev *dev)
  	dev->phy.dev = dev;
  	dev->phy.mt76 = &dev->mt76.phy;
  	dev->mt76.phy.priv = &dev->phy;
@@ -60,7 +60,7 @@
  	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
  	INIT_LIST_HEAD(&dev->sta_rc_list);
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 2222fb9..99a770e 100644
+index b01edbe..c083f87 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -173,15 +173,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
@@ -188,7 +188,7 @@
  
  	mt76_tx_status_check(mphy->dev, false);
 diff --git a/mt7915/main.c b/mt7915/main.c
-index a3fd54c..449c2ee 100644
+index df2d427..1949f9a 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -751,6 +751,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -220,7 +220,7 @@
  
  static void mt7915_tx(struct ieee80211_hw *hw,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index b6fba1a..9996c08 100644
+index 09badb1..fce152c 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -3723,6 +3723,167 @@ out:
@@ -392,7 +392,7 @@
  				struct cfg80211_he_bss_color *he_bss_color)
  {
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 1592b5d..aebacc7 100644
+index b41ac4a..8f36546 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -152,6 +152,61 @@ struct mt7915_mcu_eeprom_info {
@@ -466,7 +466,7 @@
 +};
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index d317c52..900ba09 100644
+index 4727d9c..5d14017 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -137,6 +137,7 @@ struct mt7915_sta {
@@ -488,7 +488,7 @@
  #ifdef CONFIG_NL80211_TESTMODE
  	struct {
  		u32 *reg_backup;
-@@ -495,6 +500,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
+@@ -494,6 +499,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
  int mt7915_mcu_get_temperature(struct mt7915_phy *phy);
  int mt7915_mcu_set_thermal_throttling(struct mt7915_phy *phy, u8 state);
  int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy);
diff --git a/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch b/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
index f269b5c..8a7b843 100644
--- a/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
@@ -1,7 +1,8 @@
-From 395824a77010ab860cb20141105dc61a4feacbc9 Mon Sep 17 00:00:00 2001
+From ffa3c4eded779ed99487c86e52db94f04a4c15e0 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 22 May 2023 13:49:37 +0800
-Subject: [PATCH 2/7] wifi: mt76: mt7915: add pc stack dump for WM's coredump.
+Subject: [PATCH 02/76] wifi: mt76: mt7915: add pc stack dump for WM's
+ coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -15,7 +16,7 @@
  7 files changed, 207 insertions(+), 71 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 0609b4a..0d864fe 100644
+index 8f1f0a7..580891f 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -27,6 +27,8 @@
@@ -25,9 +26,9 @@
 +#define MT76_BUILD_TIME_LEN	24
 +
  #define MT_QFLAG_WED_RING	GENMASK(1, 0)
- #define MT_QFLAG_WED_TYPE	GENMASK(3, 2)
- #define MT_QFLAG_WED		BIT(4)
-@@ -54,6 +56,12 @@ enum mt76_bus_type {
+ #define MT_QFLAG_WED_TYPE	GENMASK(4, 2)
+ #define MT_QFLAG_WED		BIT(5)
+@@ -61,6 +63,12 @@ enum mt76_bus_type {
  	MT76_BUS_SDIO,
  };
  
@@ -40,7 +41,7 @@
  enum mt76_wed_type {
  	MT76_WED_Q_TX,
  	MT76_WED_Q_TXFREE,
-@@ -798,6 +806,9 @@ struct mt76_dev {
+@@ -832,6 +840,9 @@ struct mt76_dev {
  	struct device *dma_dev;
  
  	struct mt76_mcu mcu;
@@ -51,30 +52,30 @@
  	struct net_device napi_dev;
  	struct net_device tx_napi_dev;
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index bcd6c20..3aef23a 100644
+index 96494ba..91000b8 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -3049,6 +3049,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
+@@ -2930,6 +2930,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
  		goto out;
  	}
  
-+	dev->wm_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
-+	memcpy(dev->wm_hdr, hdr, sizeof(*hdr));
++	dev->wa_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
++	memcpy(dev->wa_hdr, hdr, sizeof(*hdr));
 +
  	snprintf(dev->hw->wiphy->fw_version,
  		 sizeof(dev->hw->wiphy->fw_version),
  		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
-@@ -3078,6 +3081,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
+@@ -2959,6 +2962,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
  		goto out;
  	}
  
-+	dev->wa_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
-+	memcpy(dev->wa_hdr, hdr, sizeof(*hdr));
++	dev->wm_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
++	memcpy(dev->wm_hdr, hdr, sizeof(*hdr));
 +
  	snprintf(dev->hw->wiphy->fw_version,
  		 sizeof(dev->hw->wiphy->fw_version),
  		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
-@@ -3148,6 +3154,9 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
+@@ -3029,6 +3035,9 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
  	dev_info(dev->dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
  		 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
  
@@ -513,7 +514,7 @@
  	return NULL;
  }
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 99a770e..d81fae9 100644
+index c083f87..5c7e0e6 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -1595,28 +1595,31 @@ void mt7915_mac_reset_work(struct work_struct *work)
@@ -594,7 +595,7 @@
  }
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 900ba09..2c5d929 100644
+index 5d14017..4293385 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -286,7 +286,7 @@ struct mt7915_dev {
diff --git a/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch b/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch
index 9e2ce35..7f167c5 100644
--- a/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch
@@ -1,7 +1,7 @@
-From b5829fc76a9451651a8710a6c8b8f74b93d0a1cf Mon Sep 17 00:00:00 2001
+From bc0336844099fc23c44b0249a41562d4da675d00 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Thu, 13 Jul 2023 15:50:00 +0800
-Subject: [PATCH 3/7] wifi: mt76: mt7915: move temperature margin check to
+Subject: [PATCH 03/76] wifi: mt76: mt7915: move temperature margin check to
  mt7915_thermal_temp_store()
 
 Originally, we would reduce the 10-degree margin to the restore
@@ -17,7 +17,7 @@
  2 files changed, 5 insertions(+), 5 deletions(-)
 
 diff --git a/mt7915/init.c b/mt7915/init.c
-index c1f234e..294876a 100644
+index ea96d8d..d5d9cbf 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
 @@ -83,12 +83,13 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev,
@@ -38,7 +38,7 @@
  		return -EINVAL;
  	}
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 9996c08..9a79119 100644
+index fce152c..6cd6ad1 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -3156,8 +3156,7 @@ int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy)
diff --git a/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch b/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch
index 31fcb9e..e115e77 100644
--- a/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch
@@ -1,22 +1,19 @@
-From 6cb2b319acc161e61dd875536bb2c8ee86efcad8 Mon Sep 17 00:00:00 2001
+From dc05c83d0f280b199b2bfdebb33acce008b57609 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Sat, 29 Jul 2023 04:53:47 +0800
-Subject: [PATCH 4/7] wifi: mt76: mt7915: fix txpower issues
+Subject: [PATCH 04/76] wifi: mt76: mt7915: fix txpower issues
 
 ---
- eeprom.c         |  4 ++--
- mac80211.c       |  2 +-
+ eeprom.c         |  2 +-
  mt7915/debugfs.c | 48 ++++++++++++++++++++++++++----------------------
- mt7915/init.c    |  2 +-
  mt7915/main.c    |  1 +
- mt7915/mcu.h     |  2 +-
- 6 files changed, 32 insertions(+), 27 deletions(-)
+ 3 files changed, 28 insertions(+), 23 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index 2558788..750e031 100644
+index 0bc66cc..ecd09c0 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -338,7 +338,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+@@ -343,7 +343,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
  	u32 ru_rates = ARRAY_SIZE(dest->ru[0]);
  	char band;
  	size_t len;
@@ -25,28 +22,6 @@
  	s8 txs_delta;
  
  	if (!mcs_rates)
-@@ -376,7 +376,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
- 	if (!np)
- 		return target_power;
- 
--	txs_delta = mt76_get_txs_delta(np, hweight8(phy->antenna_mask));
-+	txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask));
- 
- 	val = mt76_get_of_array(np, "rates-cck", &len, ARRAY_SIZE(dest->cck));
- 	mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val,
-diff --git a/mac80211.c b/mac80211.c
-index 12fcb2b..aaaf6a9 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -1538,7 +1538,7 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 		     int *dbm)
- {
- 	struct mt76_phy *phy = hw->priv;
--	int n_chains = hweight8(phy->antenna_mask);
-+	int n_chains = hweight16(phy->chainmask);
- 	int delta = mt76_tx_power_nss_delta(n_chains);
- 
- 	*dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
 index 6c3696c..93e549c 100644
 --- a/mt7915/debugfs.c
@@ -131,24 +106,11 @@
  
  	reg = is_mt7915(&dev->mt76) ? MT_WF_PHY_TPC_CTRL_STAT(band) :
  	      MT_WF_PHY_TPC_CTRL_STAT_MT7916(band);
-diff --git a/mt7915/init.c b/mt7915/init.c
-index 294876a..d8fd8d6 100644
---- a/mt7915/init.c
-+++ b/mt7915/init.c
-@@ -278,7 +278,7 @@ static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
- void mt7915_init_txpower(struct mt7915_dev *dev,
- 			 struct ieee80211_supported_band *sband)
- {
--	int i, n_chains = hweight8(dev->mphy.antenna_mask);
-+	int i, n_chains = hweight16(dev->mphy.chainmask);
- 	int nss_delta = mt76_tx_power_nss_delta(n_chains);
- 	int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);
- 	struct mt76_power_limits limits;
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 449c2ee..96336b6 100644
+index 1949f9a..4e0216e 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1075,6 +1075,7 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+@@ -1076,6 +1076,7 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
  	mt76_set_stream_caps(phy->mt76, true);
  	mt7915_set_stream_vht_txbf_caps(phy);
  	mt7915_set_stream_he_caps(phy);
@@ -156,19 +118,6 @@
  
  	mutex_unlock(&dev->mt76.mutex);
  
-diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index aebacc7..8f36546 100644
---- a/mt7915/mcu.h
-+++ b/mt7915/mcu.h
-@@ -574,7 +574,7 @@ static inline s8
- mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
- {
- 	struct mt76_phy *mphy = phy->mt76;
--	int n_chains = hweight8(mphy->antenna_mask);
-+	int n_chains = hweight16(mphy->chainmask);
- 
- 	txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * 2);
- 	txpower -= mt76_tx_power_nss_delta(n_chains);
 -- 
 2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-init-txpower.patch b/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-init-txpower.patch
deleted file mode 100644
index e6ddc58..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-init-txpower.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From 5fe1dd7724e7af4cb508af3147ddc9e1f12d2dc7 Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Mon, 31 Jul 2023 11:07:35 +0800
-Subject: [PATCH 5/7] wifi: mt76: mt7915: rework init txpower
-
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/init.c   | 30 ++++++++++++++++++++----------
- mt7915/mac.c    |  4 ++--
- mt7915/mt7915.h |  3 +--
- 3 files changed, 23 insertions(+), 14 deletions(-)
-
-diff --git a/mt7915/init.c b/mt7915/init.c
-index d8fd8d6..0d2587c 100644
---- a/mt7915/init.c
-+++ b/mt7915/init.c
-@@ -275,10 +275,11 @@ static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
- 		mt7915_led_set_config(led_cdev, 0xff, 0);
- }
- 
--void mt7915_init_txpower(struct mt7915_dev *dev,
--			 struct ieee80211_supported_band *sband)
-+void __mt7915_init_txpower(struct mt7915_phy *phy,
-+			   struct ieee80211_supported_band *sband)
- {
--	int i, n_chains = hweight16(dev->mphy.chainmask);
-+	struct mt7915_dev *dev = phy->dev;
-+	int i, n_chains = hweight16(phy->mt76->chainmask);
- 	int nss_delta = mt76_tx_power_nss_delta(n_chains);
- 	int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);
- 	struct mt76_power_limits limits;
-@@ -296,7 +297,7 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
- 		}
- 
- 		target_power += pwr_delta;
--		target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
-+		target_power = mt76_get_rate_power_limits(phy->mt76, chan,
- 							  &limits,
- 							  target_power);
- 		target_power += nss_delta;
-@@ -307,6 +308,19 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
- 	}
- }
- 
-+void mt7915_init_txpower(struct mt7915_phy *phy)
-+{
-+	if (!phy)
-+		return;
-+
-+	if (phy->mt76->cap.has_2ghz)
-+		__mt7915_init_txpower(phy, &phy->mt76->sband_2g.sband);
-+	if (phy->mt76->cap.has_5ghz)
-+		__mt7915_init_txpower(phy, &phy->mt76->sband_5g.sband);
-+	if (phy->mt76->cap.has_6ghz)
-+		__mt7915_init_txpower(phy, &phy->mt76->sband_6g.sband);
-+}
-+
- static void
- mt7915_regd_notifier(struct wiphy *wiphy,
- 		     struct regulatory_request *request)
-@@ -322,9 +336,7 @@ mt7915_regd_notifier(struct wiphy *wiphy,
- 	if (dev->mt76.region == NL80211_DFS_UNSET)
- 		mt7915_mcu_rdd_background_enable(phy, NULL);
- 
--	mt7915_init_txpower(dev, &mphy->sband_2g.sband);
--	mt7915_init_txpower(dev, &mphy->sband_5g.sband);
--	mt7915_init_txpower(dev, &mphy->sband_6g.sband);
-+	mt7915_init_txpower(phy);
- 
- 	mphy->dfs_state = MT_DFS_STATE_UNKNOWN;
- 	mt7915_dfs_init_radar_detector(phy);
-@@ -445,6 +457,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
- 	mt76_set_stream_caps(phy->mt76, true);
- 	mt7915_set_stream_vht_txbf_caps(phy);
- 	mt7915_set_stream_he_caps(phy);
-+	mt7915_init_txpower(phy);
- 
- 	wiphy->available_antennas_rx = phy->mt76->antenna_mask;
- 	wiphy->available_antennas_tx = phy->mt76->antenna_mask;
-@@ -708,9 +721,6 @@ static void mt7915_init_work(struct work_struct *work)
- 
- 	mt7915_mcu_set_eeprom(dev);
- 	mt7915_mac_init(dev);
--	mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
--	mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
--	mt7915_init_txpower(dev, &dev->mphy.sband_6g.sband);
- 	mt7915_txbf_init(dev);
- }
- 
-diff --git a/mt7915/mac.c b/mt7915/mac.c
-index d81fae9..a9bdb65 100644
---- a/mt7915/mac.c
-+++ b/mt7915/mac.c
-@@ -1395,8 +1395,8 @@ mt7915_mac_restart(struct mt7915_dev *dev)
- 		goto out;
- 
- 	mt7915_mac_init(dev);
--	mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
--	mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
-+	mt7915_init_txpower(&dev->phy);
-+	mt7915_init_txpower(phy2);
- 	ret = mt7915_txbf_init(dev);
- 
- 	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 2c5d929..4293385 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -430,8 +430,7 @@ void mt7915_dma_cleanup(struct mt7915_dev *dev);
- int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
- int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset);
- int mt7915_txbf_init(struct mt7915_dev *dev);
--void mt7915_init_txpower(struct mt7915_dev *dev,
--			 struct ieee80211_supported_band *sband);
-+void mt7915_init_txpower(struct mt7915_phy *phy);
- void mt7915_reset(struct mt7915_dev *dev);
- int mt7915_run(struct ieee80211_hw *hw);
- int mt7915_mcu_init(struct mt7915_dev *dev);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-rework-mmio-access-flow.patch b/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-mmio-access-flow.patch
similarity index 93%
rename from recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-rework-mmio-access-flow.patch
rename to recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-mmio-access-flow.patch
index 0521fec..eb2191d 100644
--- a/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-rework-mmio-access-flow.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-mmio-access-flow.patch
@@ -1,7 +1,7 @@
-From 441383b3fc8140bdff89d50861fd753b56154cba Mon Sep 17 00:00:00 2001
+From 7b50ef5c4c3768652f1c4bcdb14e8ee0639c8b7f Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 15 Aug 2023 17:28:30 +0800
-Subject: [PATCH 6/7] wifi: mt76: mt7915: rework mmio access flow
+Subject: [PATCH 05/76] wifi: mt76: mt7915: rework mmio access flow
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
@@ -11,7 +11,7 @@
  2 files changed, 45 insertions(+), 5 deletions(-)
 
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index fc7ace6..5509661 100644
+index aff4f21..bd9e01d 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -490,6 +490,11 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)
@@ -97,7 +97,7 @@
  }
  
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
-@@ -813,6 +851,7 @@ static int mt7915_mmio_init(struct mt76_dev *mdev,
+@@ -707,6 +745,7 @@ static int mt7915_mmio_init(struct mt76_dev *mdev,
  
  	dev = container_of(mdev, struct mt7915_dev, mt76);
  	mt76_mmio_init(&dev->mt76, mem_base);
diff --git a/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch b/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
similarity index 76%
rename from recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
rename to recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
index 93f2945..e2b475c 100644
--- a/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
@@ -1,7 +1,7 @@
-From 42bd7d9fbb234b9765983a0fc30926a0df2d1c51 Mon Sep 17 00:00:00 2001
+From f03b72e7cfdeb48938b76550f911533fa6241837 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Wed, 6 Sep 2023 16:27:25 +0800
-Subject: [PATCH 7/7] wifi: mt76: disable HW AMSDU when using fixed rate
+Subject: [PATCH 06/76] wifi: mt76: disable HW AMSDU when using fixed rate
 
 When using fixed rate, HW uses txd DW9 to store tx arrivial time if VTA
 is ture. It would overwrite the msdu_id in txd and lead to token pending
@@ -13,10 +13,10 @@
  1 file changed, 3 insertions(+), 1 deletion(-)
 
 diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index 93402d2..e26fcf8 100644
+index c791464..630c640 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -543,7 +543,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+@@ -544,7 +544,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
  	val = FIELD_PREP(MT_TXD5_PID, pid);
  	if (pid >= MT_PACKET_ID_FIRST) {
  		val |= MT_TXD5_TX_STATUS_HOST;
@@ -25,7 +25,7 @@
  	}
  
  	txwi[5] = cpu_to_le32(val);
-@@ -578,6 +578,8 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+@@ -579,6 +579,8 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
  				spe_idx = 24 + phy_idx;
  			txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, spe_idx));
  		}
diff --git a/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-add-new-chip-version-in-power-on-se.patch b/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-add-new-chip-version-in-power-on-se.patch
similarity index 78%
rename from recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-add-new-chip-version-in-power-on-se.patch
rename to recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-add-new-chip-version-in-power-on-se.patch
index 1a02626..f245ca5 100644
--- a/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-add-new-chip-version-in-power-on-se.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-add-new-chip-version-in-power-on-se.patch
@@ -1,7 +1,8 @@
-From 46622d363ac9ad1a45ab3447eccf76f1fda9dc7e Mon Sep 17 00:00:00 2001
+From 9811a44ffa3f54a904ee706c0a15638733781efa Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Tue, 17 Oct 2023 16:32:51 +0800
-Subject: [PATCH] wifi: mt76: mt7915: add new chip version in power on sequence
+Subject: [PATCH 07/76] wifi: mt76: mt7915: add new chip version in power on
+ sequence
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
 ---
@@ -9,7 +10,7 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/mt7915/soc.c b/mt7915/soc.c
-index d8c80de6..b2916b02 100644
+index d8c80de..b2916b0 100644
 --- a/mt7915/soc.c
 +++ b/mt7915/soc.c
 @@ -517,7 +517,8 @@ static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie)
diff --git a/recipes-wifi/linux-mt76/files/patches/0009-wifi-mt76-mt7915-Fixed-null-pointer-dereference-.patch b/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-Fixed-null-pointer-dereference-issu.patch
similarity index 82%
rename from recipes-wifi/linux-mt76/files/patches/0009-wifi-mt76-mt7915-Fixed-null-pointer-dereference-.patch
rename to recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-Fixed-null-pointer-dereference-issu.patch
index db43154..ee83d2a 100644
--- a/recipes-wifi/linux-mt76/files/patches/0009-wifi-mt76-mt7915-Fixed-null-pointer-dereference-.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-Fixed-null-pointer-dereference-issu.patch
@@ -1,7 +1,7 @@
-From ab20e5711ee36a8c0bace4b39d081626c616b94b Mon Sep 17 00:00:00 2001
+From 5e5c03f7f7fe349d4d835bd6809bc40b32a9ec8a Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Thu, 26 Oct 2023 21:11:05 +0800
-Subject: [PATCH] wifi: mt76: mt7915: Fixed null pointer dereference
+Subject: [PATCH 08/76] wifi: mt76: mt7915: Fixed null pointer dereference
  issue
 
 Without this patch, when the station is still in Authentication stage and
@@ -17,10 +17,10 @@
  1 file changed, 7 insertions(+)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 96336b6..f2fe250 100644
+index 4e0216e..3cf459d 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1165,9 +1165,16 @@ static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
+@@ -1166,9 +1166,16 @@ static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
  				 struct ieee80211_sta *sta,
  				 u32 changed)
  {
@@ -38,5 +38,5 @@
  	ieee80211_queue_work(hw, &dev->rc_work);
  }
 -- 
-2.39.0
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/0009-wifi-mt76-ACS-channel-time-too-long-on-duty-channel.patch b/recipes-wifi/linux-mt76/files/patches/0009-wifi-mt76-ACS-channel-time-too-long-on-duty-channel.patch
new file mode 100644
index 0000000..785d3ff
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/0009-wifi-mt76-ACS-channel-time-too-long-on-duty-channel.patch
@@ -0,0 +1,51 @@
+From 3300d7dc7d506804664567b0039acebd4b351931 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Sat, 18 Nov 2023 07:36:45 +0800
+Subject: [PATCH 09/76] wifi: mt76: ACS channel time too long on duty channel
+
+Issue:
+There's a chance that the channel time for duty channel is zero in ACS
+scan.
+
+Root cause:
+The chan_stat may be reset when restore to duty channel.
+Mac80211 will notify to hostapd when scan done and then restore to duty
+channel.
+And mt76 will clear scan flag after restore done.
+If hostapd get the chan_stat before channel_restore, will get the
+correct channel time;
+If hostapd get the chan_stat after channel_restore, will get zero
+channel time;
+
+Solution:
+When channel switch, will check the mac80211 scan state but not the mt76 scan flag.
+Mac80211 scan state will be set in scanning, and will be reset after
+scan done and before restore to duty channel.
+---
+ mac80211.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/mac80211.c b/mac80211.c
+index cc9e9ff..6c5b4f5 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -928,6 +928,7 @@ void mt76_set_channel(struct mt76_phy *phy)
+ 	struct cfg80211_chan_def *chandef = &hw->conf.chandef;
+ 	bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
+ 	int timeout = HZ / 5;
++	unsigned long was_scanning = ieee80211_get_scanning(hw);
+ 
+ 	wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout);
+ 	mt76_update_survey(phy);
+@@ -942,7 +943,7 @@ void mt76_set_channel(struct mt76_phy *phy)
+ 	if (!offchannel)
+ 		phy->main_chan = chandef->chan;
+ 
+-	if (chandef->chan != phy->main_chan)
++	if (chandef->chan != phy->main_chan || was_scanning)
+ 		memset(phy->chan_state, 0, sizeof(*phy->chan_state));
+ }
+ EXPORT_SYMBOL_GPL(mt76_set_channel);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/0010-wifi-mt76-check-txs-format-before-getting-skb-by-pid.patch b/recipes-wifi/linux-mt76/files/patches/0010-wifi-mt76-check-txs-format-before-getting-skb-by-pid.patch
new file mode 100644
index 0000000..bf761ba
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/0010-wifi-mt76-check-txs-format-before-getting-skb-by-pid.patch
@@ -0,0 +1,53 @@
+From 1313d834950f271d6b84dd71b89535e6e9af1095 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Fri, 8 Dec 2023 07:35:39 +0800
+Subject: [PATCH 10/76] wifi: mt76: check txs format before getting skb by pid
+
+The PPDU TxS does not include the error bit so it cannot use to report
+status to mac80211.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt76_connac2_mac.h | 5 +++++
+ mt76_connac_mac.c  | 7 +++++--
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h
+index bd2a924..5f13211 100644
+--- a/mt76_connac2_mac.h
++++ b/mt76_connac2_mac.h
+@@ -32,6 +32,11 @@ enum {
+ 	MT_LMAC_PSMP0,
+ };
+ 
++enum {
++	MT_TXS_MPDU_FMT = 0,
++	MT_TXS_PPDU_FMT = 2,
++};
++
+ #define MT_TX_FREE_MSDU_CNT		GENMASK(9, 0)
+ #define MT_TX_FREE_WLAN_ID		GENMASK(23, 14)
+ #define MT_TX_FREE_COUNT		GENMASK(12, 0)
+diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
+index 630c640..31d2474 100644
+--- a/mt76_connac_mac.c
++++ b/mt76_connac_mac.c
+@@ -714,10 +714,13 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ 				  int pid, __le32 *txs_data)
+ {
+ 	struct sk_buff_head list;
+-	struct sk_buff *skb;
++	struct sk_buff *skb = NULL;
+ 
+ 	mt76_tx_status_lock(dev, &list);
+-	skb = mt76_tx_status_skb_get(dev, wcid, pid, &list);
++
++	if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) == MT_TXS_MPDU_FMT)
++		skb = mt76_tx_status_skb_get(dev, wcid, pid, &list);
++
+ 	if (skb) {
+ 		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/0010-wifi-mt76-mt7915-add-post-channel-switch-for-DFS-cha.patch b/recipes-wifi/linux-mt76/files/patches/0010-wifi-mt76-mt7915-add-post-channel-switch-for-DFS-cha.patch
new file mode 100644
index 0000000..0fc717d
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/0010-wifi-mt76-mt7915-add-post-channel-switch-for-DFS-cha.patch
@@ -0,0 +1,54 @@
+From 6a213f89194b5449a071b805ea32fba05e2a0673 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 16 Nov 2023 14:41:54 +0800
+Subject: [PATCH] wifi: mt76: mt7915: add post channel switch for DFS channel
+ switching
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7915/main.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/mt7915/main.c b/mt7915/main.c
+index ec4e33f..e01d832 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -736,6 +736,27 @@ mt7915_channel_switch_beacon(struct ieee80211_hw *hw,
+ 	mutex_unlock(&dev->mt76.mutex);
+ }
+ 
++static int
++mt7915_post_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
++{
++	struct mt7915_phy *phy = mt7915_hw_phy(hw);
++	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
++	int ret;
++
++	ret = cfg80211_chandef_dfs_required(hw->wiphy, chandef, NL80211_IFTYPE_AP);
++	if (ret <= 0)
++		goto out;
++
++	ieee80211_stop_queues(hw);
++	ret = mt7915_set_channel(phy);
++	if (ret)
++		goto out;
++	ieee80211_wake_queues(hw);
++
++out:
++	return ret;
++}
++
+ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 		       struct ieee80211_sta *sta)
+ {
+@@ -1710,6 +1731,7 @@ const struct ieee80211_ops mt7915_ops = {
+ 	.get_txpower = mt76_get_txpower,
+ 	.set_sar_specs = mt7915_set_sar_specs,
+ 	.channel_switch_beacon = mt7915_channel_switch_beacon,
++	.post_channel_switch = mt7915_post_channel_switch,
+ 	.get_stats = mt7915_get_stats,
+ 	.get_et_sset_count = mt7915_get_et_sset_count,
+ 	.get_et_stats = mt7915_get_et_stats,
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch b/recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch
index 8ccddd2..8ce34ae 100644
--- a/recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch
@@ -1,25 +1,25 @@
-From ed118d36cb5185ef0bc31725c973998edfc6969f Mon Sep 17 00:00:00 2001
+From f44a5ec67a8f6d1117284c4d6db718da4f0f2617 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Sat, 1 Apr 2023 08:18:17 +0800
-Subject: [PATCH 0999/1040] wifi: mt76: mt7915: build pass for Linux Kernel 5.4
+Subject: [PATCH 11/76] wifi: mt76: mt7915: build pass for Linux Kernel 5.4
  fixes
 
 ---
  debugfs.c         |  2 ++
- dma.c             | 74 ++++++++++++++++++++++++-----------------------
+ dma.c             | 77 ++++++++++++++++++++++++-----------------------
  eeprom.c          |  8 ++++-
- mac80211.c        | 57 ------------------------------------
+ mac80211.c        | 57 -----------------------------------
  mcu.c             |  1 +
+ mmio.c            | 56 ++++++++++++++++++++++------------
  mt76.h            | 22 +-------------
  mt7615/mcu.c      |  1 +
  mt76_connac.h     |  2 --
- mt76_connac_mcu.c | 47 +-----------------------------
+ mt76_connac_mcu.c | 47 +----------------------------
  mt76_connac_mcu.h |  4 ---
- mt7915/main.c     | 25 +++++++---------
+ mt7915/main.c     | 25 ++++++---------
  mt7915/mcu.c      |  1 +
- mt7915/mmio.c     | 55 +++++++++++++++++++++--------------
- usb.c             | 43 +++++++++++++--------------
- 14 files changed, 118 insertions(+), 224 deletions(-)
+ usb.c             | 43 +++++++++++++-------------
+ 14 files changed, 121 insertions(+), 225 deletions(-)
 
 diff --git a/debugfs.c b/debugfs.c
 index c4649ba..1c8328d 100644
@@ -37,7 +37,7 @@
  	return 0;
  }
 diff --git a/dma.c b/dma.c
-index 643e18e..24b44e7 100644
+index 00230f1..9eb2b8f 100644
 --- a/dma.c
 +++ b/dma.c
 @@ -178,7 +178,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
@@ -49,7 +49,7 @@
  		kfree(t);
  	}
  	local_bh_enable();
-@@ -411,9 +411,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -452,9 +452,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  		if (!t)
  			return NULL;
  
@@ -62,10 +62,10 @@
  
  		buf = t->ptr;
  		t->dma_addr = 0;
-@@ -432,9 +432,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -464,9 +464,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		if (drop)
+ 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
  	} else {
- 		buf = e->buf;
- 		e->buf = NULL;
 -		dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0],
 -				SKB_WITH_OVERHEAD(q->buf_size),
 -				page_pool_get_dma_dir(q->page_pool));
@@ -74,8 +74,8 @@
 +				 DMA_FROM_DEVICE);
  	}
  
- 	return buf;
-@@ -594,11 +594,11 @@ free_skb:
+ done:
+@@ -633,11 +633,11 @@ free_skb:
  }
  
  static int
@@ -90,16 +90,19 @@
  
  	if (!q->ndesc)
  		return 0;
-@@ -606,25 +606,26 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -645,30 +645,30 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
  	spin_lock_bh(&q->lock);
  
  	while (q->queued < q->ndesc - 1) {
+-		struct mt76_queue_buf qbuf = {};
 -		enum dma_data_direction dir;
- 		struct mt76_queue_buf qbuf;
 -		dma_addr_t addr;
 -		int offset;
--		void *buf;
-+		void *buf = NULL;
++		struct mt76_queue_buf qbuf;
+ 		void *buf = NULL;
+ 
+ 		if (mt76_queue_is_wed_rro_ind(q))
+ 			goto done;
  
 -		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
 +		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
@@ -116,28 +119,39 @@
 +		}
  
 -		qbuf.addr = addr + q->buf_offset;
--		qbuf.len = len - q->buf_offset;
 +		qbuf.addr = addr + offset;
+ done:
+-		qbuf.len = len - q->buf_offset;
 +		qbuf.len = len - offset;
  		qbuf.skip_unmap = false;
  		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
 -			mt76_put_page_pool_buf(buf, allow_direct);
+-			break;
 +			dma_unmap_single(dev->dma_dev, addr, len,
 +					 DMA_FROM_DEVICE);
 +			skb_free_frag(buf);
- 			break;
  		}
  		frames++;
-@@ -668,7 +669,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ 	}
+@@ -711,7 +711,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
  		/* WED txfree queue needs ring to be initialized before setup */
  		q->flags = 0;
  		mt76_dma_queue_reset(dev, q);
 -		mt76_dma_rx_fill(dev, q, false);
 +		mt76_dma_rx_fill(dev, q);
- 		q->flags = flags;
  
- 		ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
-@@ -716,10 +717,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ 		ret = mtk_wed_device_txfree_ring_setup(q->wed, q->regs);
+ 		if (!ret)
+@@ -740,7 +740,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ 	case MT76_WED_RRO_Q_IND:
+ 		q->flags &= ~MT_QFLAG_WED;
+ 		mt76_dma_queue_reset(dev, q);
+-		mt76_dma_rx_fill(dev, q, false);
++		mt76_dma_rx_fill(dev, q);
+ 		mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
+ 		break;
+ 	default:
+@@ -796,10 +796,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  	if (!q->entry)
  		return -ENOMEM;
  
@@ -148,7 +162,7 @@
  	ret = mt76_dma_wed_setup(dev, q, false);
  	if (ret)
  		return ret;
-@@ -733,6 +730,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -818,6 +814,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  static void
  mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  {
@@ -156,16 +170,16 @@
  	void *buf;
  	bool more;
  
-@@ -746,7 +744,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
- 		if (!buf)
+@@ -833,7 +830,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  			break;
  
--		mt76_put_page_pool_buf(buf, false);
-+		skb_free_frag(buf);
+ 		if (!mt76_queue_is_wed_rro(q))
+-			mt76_put_page_pool_buf(buf, false);
++			skb_free_frag(buf);
  	} while (1);
  
- 	if (q->rx_head) {
-@@ -755,6 +753,13 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+ 	spin_lock_bh(&q->lock);
+@@ -843,6 +840,13 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  	}
  
  	spin_unlock_bh(&q->lock);
@@ -179,25 +193,25 @@
  }
  
  static void
-@@ -775,7 +780,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
- 	mt76_dma_wed_setup(dev, q, true);
- 	if (q->flags != MT_WED_Q_TXFREE) {
- 		mt76_dma_sync_idx(dev, q);
--		mt76_dma_rx_fill(dev, q, false);
-+		mt76_dma_rx_fill(dev, q);
- 	}
+@@ -873,7 +877,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+ 		return;
+ 
+ 	mt76_dma_sync_idx(dev, q);
+-	mt76_dma_rx_fill(dev, q, false);
++	mt76_dma_rx_fill(dev, q);
  }
  
-@@ -793,7 +798,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
+ static void
+@@ -890,7 +894,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
  
  		skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size);
  	} else {
--		mt76_put_page_pool_buf(data, true);
+-		mt76_put_page_pool_buf(data, allow_direct);
 +		skb_free_frag(data);
  	}
  
  	if (more)
-@@ -861,12 +866,11 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -960,12 +964,11 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		    !(dev->drv->rx_check(dev, data, len)))
  			goto free_frag;
  
@@ -211,11 +225,11 @@
  
  		*(u32 *)skb->cb = info;
  
-@@ -882,10 +886,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -981,10 +984,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		continue;
  
  free_frag:
--		mt76_put_page_pool_buf(data, true);
+-		mt76_put_page_pool_buf(data, allow_direct);
 +		skb_free_frag(data);
  	}
  
@@ -224,7 +238,7 @@
  	return done;
  }
  
-@@ -930,7 +934,7 @@ mt76_dma_init(struct mt76_dev *dev,
+@@ -1029,7 +1032,7 @@ mt76_dma_init(struct mt76_dev *dev,
  
  	mt76_for_each_q_rx(dev, i) {
  		netif_napi_add(&dev->napi_dev, &dev->napi[i], poll);
@@ -233,7 +247,7 @@
  		napi_enable(&dev->napi[i]);
  	}
  
-@@ -981,8 +985,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+@@ -1098,8 +1101,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
  
  		netif_napi_del(&dev->napi[i]);
  		mt76_dma_rx_cleanup(dev, q);
@@ -241,12 +255,12 @@
 -		page_pool_destroy(q->page_pool);
  	}
  
- 	mt76_free_pending_txwi(dev);
+ 	if (mtk_wed_device_active(&dev->mmio.wed))
 diff --git a/eeprom.c b/eeprom.c
-index 750e031..ff8dc93 100644
+index ecd09c0..a267397 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -161,9 +161,15 @@ void
+@@ -163,9 +163,15 @@ void
  mt76_eeprom_override(struct mt76_phy *phy)
  {
  	struct mt76_dev *dev = phy->dev;
@@ -264,7 +278,7 @@
  	if (!is_valid_ether_addr(phy->macaddr)) {
  		eth_random_addr(phy->macaddr);
 diff --git a/mac80211.c b/mac80211.c
-index aaaf6a9..647f74c 100644
+index 6c5b4f5..259b448 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -4,7 +4,6 @@
@@ -275,7 +289,7 @@
  #include "mt76.h"
  
  #define CHAN2G(_idx, _freq) {			\
-@@ -567,47 +566,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
+@@ -578,47 +577,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
  }
  EXPORT_SYMBOL_GPL(mt76_unregister_phy);
  
@@ -323,7 +337,7 @@
  struct mt76_dev *
  mt76_alloc_device(struct device *pdev, unsigned int size,
  		  const struct ieee80211_ops *ops,
-@@ -1805,21 +1763,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
+@@ -1818,21 +1776,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  }
  EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
  
@@ -357,11 +371,117 @@
  
  struct sk_buff *
  __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data,
+diff --git a/mmio.c b/mmio.c
+index c3e0e23..6e25a14 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -89,8 +89,12 @@ EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
+ void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+ {
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
++	u32 length;
+ 	int i;
+ 
++	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
++				sizeof(struct skb_shared_info));
++
+ 	for (i = 0; i < dev->rx_token_size; i++) {
+ 		struct mt76_txwi_cache *t;
+ 
+@@ -98,7 +102,9 @@ void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+ 		if (!t || !t->ptr)
+ 			continue;
+ 
+-		mt76_put_page_pool_buf(t->ptr, false);
++		dma_unmap_single(dev->dma_dev, t->dma_addr,
++				 wed->wlan.rx_size, DMA_FROM_DEVICE);
++		__free_pages(virt_to_page(t->ptr), get_order(length));
+ 		t->ptr = NULL;
+ 
+ 		mt76_put_rxwi(dev, t);
+@@ -112,39 +118,51 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ {
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+ 	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
+-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+-	int i, len = SKB_WITH_OVERHEAD(q->buf_size);
+-	struct mt76_txwi_cache *t = NULL;
++	u32 length;
++	int i;
++
++	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
++				sizeof(struct skb_shared_info));
+ 
+ 	for (i = 0; i < size; i++) {
+-		enum dma_data_direction dir;
+-		dma_addr_t addr;
+-		u32 offset;
++		struct mt76_txwi_cache *t = mt76_get_rxwi(dev);
++		dma_addr_t phy_addr;
++		struct page *page;
+ 		int token;
+-		void *buf;
++		void *ptr;
+ 
+-		t = mt76_get_rxwi(dev);
+ 		if (!t)
+ 			goto unmap;
+ 
+-		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
+-		if (!buf)
++		page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
++		if (!page) {
++			mt76_put_rxwi(dev, t);
+ 			goto unmap;
++		}
+ 
+-		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
+-		dir = page_pool_get_dma_dir(q->page_pool);
+-		dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
++		ptr = page_address(page);
++		phy_addr = dma_map_single(dev->dma_dev, ptr,
++					  wed->wlan.rx_size,
++					  DMA_TO_DEVICE);
++		if (unlikely(dma_mapping_error(dev->dev, phy_addr))) {
++			__free_pages(page, get_order(length));
++			mt76_put_rxwi(dev, t);
++			goto unmap;
++		}
+ 
+-		desc->buf0 = cpu_to_le32(addr);
+-		token = mt76_rx_token_consume(dev, buf, t, addr);
++		desc->buf0 = cpu_to_le32(phy_addr);
++		token = mt76_rx_token_consume(dev, ptr, t, phy_addr);
+ 		if (token < 0) {
+-			mt76_put_page_pool_buf(buf, false);
++			dma_unmap_single(dev->dma_dev, phy_addr,
++					 wed->wlan.rx_size, DMA_TO_DEVICE);
++			__free_pages(page, get_order(length));
++			mt76_put_rxwi(dev, t);
+ 			goto unmap;
+ 		}
+ 
+ 		token = FIELD_PREP(MT_DMA_CTL_TOKEN, token);
+ #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+-		token |= FIELD_PREP(MT_DMA_CTL_SDP0_H, addr >> 32);
++		token |= FIELD_PREP(MT_DMA_CTL_SDP0_H, phy_addr >> 32);
+ #endif
+ 		desc->token |= cpu_to_le32(token);
+ 		desc++;
+@@ -153,8 +171,6 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 	return 0;
+ 
+ unmap:
+-	if (t)
+-		mt76_put_rxwi(dev, t);
+ 	mt76_mmio_wed_release_rx_buf(wed);
+ 
+ 	return -ENOMEM;
 diff --git a/mt76.h b/mt76.h
-index 0d864fe..97ced84 100644
+index 580891f..c644647 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -210,7 +210,7 @@ struct mt76_queue {
+@@ -232,7 +232,7 @@ struct mt76_queue {
  
  	dma_addr_t desc_dma;
  	struct sk_buff *rx_head;
@@ -370,7 +490,7 @@
  };
  
  struct mt76_mcu_ops {
-@@ -1457,7 +1457,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
+@@ -1508,7 +1508,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
  	return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout);
  }
  
@@ -378,7 +498,7 @@
  void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  			 struct mt76_sta_stats *stats, bool eht);
  int mt76_skb_adjust_pad(struct sk_buff *skb, int pad);
-@@ -1569,25 +1568,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
+@@ -1653,25 +1652,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
  struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
  int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
  			  struct mt76_txwi_cache *r, dma_addr_t phys);
@@ -405,7 +525,7 @@
  static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
  {
 diff --git a/mt7615/mcu.c b/mt7615/mcu.c
-index 955974a..db337aa 100644
+index ae34d01..c9444c6 100644
 --- a/mt7615/mcu.c
 +++ b/mt7615/mcu.c
 @@ -10,6 +10,7 @@
@@ -417,7 +537,7 @@
  static bool prefer_offload_fw = true;
  module_param(prefer_offload_fw, bool, 0644);
 diff --git a/mt76_connac.h b/mt76_connac.h
-index 1f29d8c..6f5cf18 100644
+index fdde3d7..6c8a453 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
 @@ -56,7 +56,6 @@ enum {
@@ -428,7 +548,7 @@
  
  	CMD_HE_MCS_BW80 = 0,
  	CMD_HE_MCS_BW160,
-@@ -270,7 +269,6 @@ static inline u8 mt76_connac_chan_bw(struct cfg80211_chan_def *chandef)
+@@ -275,7 +274,6 @@ static inline u8 mt76_connac_chan_bw(struct cfg80211_chan_def *chandef)
  		[NL80211_CHAN_WIDTH_10] = CMD_CBW_10MHZ,
  		[NL80211_CHAN_WIDTH_20] = CMD_CBW_20MHZ,
  		[NL80211_CHAN_WIDTH_20_NOHT] = CMD_CBW_20MHZ,
@@ -437,7 +557,7 @@
  
  	if (chandef->width >= ARRAY_SIZE(width_to_bw))
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 3aef23a..f06a81d 100644
+index 91000b8..eea6831 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -4,6 +4,7 @@
@@ -448,7 +568,7 @@
  
  int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
  {
-@@ -1346,40 +1347,6 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1347,40 +1348,6 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
  }
  EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode);
  
@@ -465,7 +585,7 @@
 -	sband = phy->hw->wiphy->bands[band];
 -	eht_cap = ieee80211_get_eht_iftype_cap(sband, vif->type);
 -
--	if (!eht_cap || !eht_cap->has_eht)
+-	if (!eht_cap || !eht_cap->has_eht || !vif->bss_conf.eht_support)
 -		return mode;
 -
 -	switch (band) {
@@ -489,7 +609,7 @@
  const struct ieee80211_sta_he_cap *
  mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
  {
-@@ -1395,18 +1362,6 @@ mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
+@@ -1396,18 +1363,6 @@ mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
  }
  EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap);
  
@@ -509,10 +629,10 @@
  #define DEFAULT_HE_DURATION_RTS_THRES	1023
  static void
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 6064973..ddf901a 100644
+index 84e77fa..5308ddc 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1928,12 +1928,8 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val);
+@@ -1970,12 +1970,8 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val);
  
  const struct ieee80211_sta_he_cap *
  mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif);
@@ -526,10 +646,10 @@
  int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
  			    struct mt76_connac_sta_key_conf *sta_key_conf,
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 96336b6..95ad05d 100644
+index 3cf459d..fea1fea 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1405,22 +1405,20 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
+@@ -1413,22 +1413,20 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
  			   struct ieee80211_vif *vif,
  			   u32 sset, u8 *data)
  {
@@ -558,7 +678,7 @@
  }
  
  static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
-@@ -1448,7 +1446,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1456,7 +1454,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
  		.idx = mvif->mt76.idx,
  	};
  	/* See mt7915_ampdu_stat_read_phy, etc */
@@ -567,7 +687,7 @@
  
  	mutex_lock(&dev->mt76.mutex);
  
-@@ -1560,12 +1558,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1568,12 +1566,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
  		return;
  
  	ei += wi.worker_stat_count;
@@ -584,7 +704,7 @@
  
  static void
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 9a79119..e9d7f20 100644
+index 6cd6ad1..ccd08ed 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -6,6 +6,7 @@
@@ -595,110 +715,6 @@
  
  #define fw_name(_dev, name, ...)	({			\
  	char *_fw;						\
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 5509661..10f4e66 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -608,9 +608,13 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
- static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- {
- 	struct mt7915_dev *dev;
-+	u32 length;
- 	int i;
- 
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-+	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
-+				sizeof(struct skb_shared_info));
-+
- 	for (i = 0; i < dev->mt76.rx_token_size; i++) {
- 		struct mt76_txwi_cache *t;
- 
-@@ -618,7 +622,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- 		if (!t || !t->ptr)
- 			continue;
- 
--		mt76_put_page_pool_buf(t->ptr, false);
-+		dma_unmap_single(dev->mt76.dma_dev, t->dma_addr,
-+				 wed->wlan.rx_size, DMA_FROM_DEVICE);
-+		__free_pages(virt_to_page(t->ptr), get_order(length));
- 		t->ptr = NULL;
- 
- 		mt76_put_rxwi(&dev->mt76, t);
-@@ -630,38 +636,47 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- {
- 	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
--	struct mt76_txwi_cache *t = NULL;
- 	struct mt7915_dev *dev;
--	struct mt76_queue *q;
--	int i, len;
-+	u32 length;
-+	int i;
- 
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
--	q = &dev->mt76.q_rx[MT_RXQ_MAIN];
--	len = SKB_WITH_OVERHEAD(q->buf_size);
-+	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
-+				sizeof(struct skb_shared_info));
- 
- 	for (i = 0; i < size; i++) {
--		enum dma_data_direction dir;
--		dma_addr_t addr;
--		u32 offset;
-+		struct mt76_txwi_cache *t = mt76_get_rxwi(&dev->mt76);
-+		dma_addr_t phy_addr;
-+		struct page *page;
- 		int token;
--		void *buf;
-+		void *ptr;
- 
--		t = mt76_get_rxwi(&dev->mt76);
- 		if (!t)
- 			goto unmap;
- 
--		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
--		if (!buf)
-+		page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
-+		if (!page) {
-+			mt76_put_rxwi(&dev->mt76, t);
- 			goto unmap;
-+		}
- 
--		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
--		dir = page_pool_get_dma_dir(q->page_pool);
--		dma_sync_single_for_device(dev->mt76.dma_dev, addr, len, dir);
-+		ptr = page_address(page);
-+		phy_addr = dma_map_single(dev->mt76.dma_dev, ptr,
-+					  wed->wlan.rx_size,
-+					  DMA_TO_DEVICE);
-+		if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
-+			__free_pages(page, get_order(length));
-+			mt76_put_rxwi(&dev->mt76, t);
-+			goto unmap;
-+		}
- 
--		desc->buf0 = cpu_to_le32(addr);
--		token = mt76_rx_token_consume(&dev->mt76, buf, t, addr);
-+		desc->buf0 = cpu_to_le32(phy_addr);
-+		token = mt76_rx_token_consume(&dev->mt76, ptr, t, phy_addr);
- 		if (token < 0) {
--			mt76_put_page_pool_buf(buf, false);
-+			dma_unmap_single(dev->mt76.dma_dev, phy_addr,
-+					 wed->wlan.rx_size, DMA_TO_DEVICE);
-+			__free_pages(page, get_order(length));
-+			mt76_put_rxwi(&dev->mt76, t);
- 			goto unmap;
- 		}
- 
-@@ -673,8 +688,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- 	return 0;
- 
- unmap:
--	if (t)
--		mt76_put_rxwi(&dev->mt76, t);
- 	mt7915_mmio_wed_release_rx_buf(wed);
- 	return -ENOMEM;
- }
 diff --git a/usb.c b/usb.c
 index 5e5c7bf..3e28171 100644
 --- a/usb.c
diff --git a/recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch b/recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch
index ee5851c..12aa0a4 100644
--- a/recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch
@@ -1,4 +1,4 @@
-From 09961de38c33d2cf5ba12679862726e6937e5c58 Mon Sep 17 00:00:00 2001
+From fc62783246a5f95bbb82928b8395ec695e0ca69c Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Wed, 22 Jun 2022 10:39:47 +0800
 Subject: [PATCH] wifi: mt76: mt7915: add mtk internal debug tools for mt76
@@ -12,20 +12,20 @@
  mt7915/mcu.c          |   48 +-
  mt7915/mcu.h          |    4 +
  mt7915/mt7915.h       |   43 +
- mt7915/mt7915_debug.h | 1418 ++++++++++++++++
- mt7915/mtk_debugfs.c  | 3622 +++++++++++++++++++++++++++++++++++++++++
+ mt7915/mt7915_debug.h | 1442 ++++++++++++++++
+ mt7915/mtk_debugfs.c  | 3743 +++++++++++++++++++++++++++++++++++++++++
  mt7915/mtk_mcu.c      |   51 +
  tools/fwlog.c         |   44 +-
- 12 files changed, 5327 insertions(+), 19 deletions(-)
+ 12 files changed, 5472 insertions(+), 19 deletions(-)
  create mode 100644 mt7915/mt7915_debug.h
  create mode 100644 mt7915/mtk_debugfs.c
  create mode 100644 mt7915/mtk_mcu.c
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index ddf901ae..8b3b7c0b 100644
+index 5308ddc..d28ee91 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1162,6 +1162,7 @@ enum {
+@@ -1183,6 +1183,7 @@ enum {
  	MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11,
  	MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
  	MCU_EXT_CMD_TXBF_ACTION = 0x1e,
@@ -33,7 +33,7 @@
  	MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
  	MCU_EXT_CMD_THERMAL_PROT = 0x23,
  	MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
-@@ -1185,6 +1186,11 @@ enum {
+@@ -1206,6 +1207,11 @@ enum {
  	MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
  	MCU_EXT_CMD_RXDCOC_CAL = 0x59,
  	MCU_EXT_CMD_GET_MIB_INFO = 0x5a,
@@ -46,7 +46,7 @@
  	MCU_EXT_CMD_CAL_CACHE = 0x67,
  	MCU_EXT_CMD_RED_ENABLE = 0x68,
 diff --git a/mt7915/Makefile b/mt7915/Makefile
-index c4dca9c1..fd711416 100644
+index c4dca9c..fd71141 100644
 --- a/mt7915/Makefile
 +++ b/mt7915/Makefile
 @@ -4,7 +4,7 @@ EXTRA_CFLAGS += -DCONFIG_MT76_LEDS
@@ -59,7 +59,7 @@
  mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
  mt7915e-$(CONFIG_MT798X_WMAC) += soc.o
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index 93e549c3..f1813776 100644
+index 93e549c..f181377 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -8,6 +8,9 @@
@@ -231,7 +231,7 @@
  
  	if (dev->relay_fwlog)
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index a9bdb653..2650b875 100644
+index 5c7e0e6..d7b7e78 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -275,6 +275,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
@@ -270,7 +270,7 @@
  }
  
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 95ad05dd..b19aa635 100644
+index fea1fea..38ffd90 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -73,7 +73,11 @@ int mt7915_run(struct ieee80211_hw *hw)
@@ -294,7 +294,7 @@
  	mt7915_mac_wtbl_update(dev, idx,
  			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index e9d7f20b..47e178fd 100644
+index ccd08ed..1cb462f 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -205,6 +205,11 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
@@ -378,7 +378,7 @@
 +}
 +#endif
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 8f365461..dd3b5062 100644
+index 8f36546..dd3b506 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -333,6 +333,10 @@ enum {
@@ -393,7 +393,7 @@
  };
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 35458ec9..887c4a56 100644
+index 35458ec..887c4a5 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -9,6 +9,7 @@
@@ -460,10 +460,10 @@
  #endif
 diff --git a/mt7915/mt7915_debug.h b/mt7915/mt7915_debug.h
 new file mode 100644
-index 0000000..4ab113e
+index 0000000..1ec8de9
 --- /dev/null
 +++ b/mt7915/mt7915_debug.h
-@@ -0,0 +1,1432 @@
+@@ -0,0 +1,1442 @@
 +#ifndef __MT7915_DEBUG_H
 +#define __MT7915_DEBUG_H
 +
@@ -941,14 +941,24 @@
 +};
 +
 +struct cos_program_trace_t{
-+	u32    dest_id;
-+	u32    msg_id;
-+	u32    msg_sn;
-+	u32    ts_gpt2;
-+	u32    LP;
-+	char   name[12];
++	u32    _dest_id;
++	u32    _msg_id;
++	u32    _msg_sn;
++	u32    _ts_gpt2;
++	u32    _LP;
++	char   _name[12];
 +} ;
 +
++struct mt7915_cos_program_trace_t{
++	u32    _dest_id;
++	u32    _msg_id;
++	u32    _msg_sn;
++	u32    _ts_gpt2;
++	u32    _ts_gpt4;
++	u32    _LP;
++	char   _name[12];
++} ;
++
 +struct cos_msg_type {
 +	u32	finish_cnt;
 +	u32	exe_time;
@@ -1898,10 +1908,10 @@
 +#endif
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
 new file mode 100644
-index 00000000..d7bbc598
+index 0000000..f3983da
 --- /dev/null
 +++ b/mt7915/mtk_debugfs.c
-@@ -0,0 +1,3622 @@
+@@ -0,0 +1,3743 @@
 +#include<linux/inet.h>
 +#include "mt7915.h"
 +#include "mt7915_debug.h"
@@ -3270,8 +3280,6 @@
 +	{NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0},
 +};
 +
-+
-+
 +static char* sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"};
 +static u32 chip_show_sta_acq_info(struct seq_file *s, struct mt7915_dev *dev, u32 *ple_stat,
 +				  u32 *sta_pause, u32 *dis_sta_map,
@@ -4828,7 +4836,7 @@
 +{
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
 +	struct mt76_dev *mdev = NULL;
-+	seq_printf(s, "Version: 2.2.14.0\n");
++	seq_printf(s, "Version: 2.2.15.0\n");
 +
 +	if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
 +		return 0;
@@ -4840,16 +4848,11 @@
 +	return 0;
 +}
 +
-+static inline int mt7915_snprintf_error(size_t size, int res)
-+{
-+	return res < 0 || (unsigned int) res >= size;
-+}
-+
 +static void mt7915_show_lp_history(struct seq_file *s, bool fgIsExp)
 +{
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
-+	u32 macVal = 0, gpr_log_idx = 0, oldest_idx = 0;
-+	u32 idx = 0, i = 0;
++	u32 macVal, gpr_log_idx, oldest_idx;
++	u32 idx, i;
 +
 +	if (!fgIsExp) {
 +		/* disable LP recored */
@@ -4859,7 +4862,6 @@
 +		udelay(100);
 +	}
 +
-+	macVal = 0;
 +	macVal = mt76_rr(dev, 0x89050200);
 +	gpr_log_idx = ((macVal >> 16) & 0x1f);
 +	oldest_idx = gpr_log_idx + 2;
@@ -4883,26 +4885,44 @@
 +{
 +#define SYSIRQ_INTERRUPT_HISTORY_NUM	10
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
-+	u32 macVal = 0;
-+	u32 i = 0;
-+	u32 start = 0;
-+	u32 idx = 0;
-+	u8 ucIrqDisIdx = 0;
-+	u8 ucIrqResIdx = 0;
-+	u32 irq_dis_time[10];
-+	u32 irq_dis_lp[10];
-+	u32 irq_res_time[10];
-+	u32 irq_res_lp[10];
++	u32 macVal, i, start, idx;
++	u8 ucIrqDisIdx, ucIrqResIdx;
++	u32 irq_dis_time[SYSIRQ_INTERRUPT_HISTORY_NUM], irq_dis_lp[SYSIRQ_INTERRUPT_HISTORY_NUM];
++	u32 irq_res_time[SYSIRQ_INTERRUPT_HISTORY_NUM], irq_res_lp[SYSIRQ_INTERRUPT_HISTORY_NUM];
++	u32 irq_idx_addr, irq_dis_addr, irq_res_addr;
 +
-+	macVal = 0;
-+	macVal = mt76_rr(dev, 0x022051C0);
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7915:
++		irq_idx_addr = 0x2170BC;
++		irq_dis_addr = 0x2170B8;
++		irq_res_addr = 0x2170B4;
++		break;
++	case 0x7981:
++		irq_idx_addr = 0x02205138;
++		irq_dis_addr = 0x02205140;
++		irq_res_addr = 0x0220513C;
++		break;
++	case 0x7906:
++		irq_idx_addr = 0x02205288;
++		irq_dis_addr = 0x02205290;
++		irq_res_addr = 0x0220528C;
++		break;
++	case 0x7986:
++	default:
++		irq_idx_addr = 0x022051C0;
++		irq_dis_addr = 0x022051C8;
++		irq_res_addr = 0x022051C4;
++		break;
++	}
++
++	macVal = mt76_rr(dev, irq_idx_addr);
 +	ucIrqResIdx = (macVal & 0xff);
 +	ucIrqDisIdx = ((macVal >> 8) & 0xff);
 +
 +	seq_printf(s, "\n\n\n       Irq Idx (Dis=%d Res=%d):\n",
 +		   ucIrqDisIdx, ucIrqResIdx);
 +
-+	start = mt76_rr(dev, 0x022051C8);
++	start = mt76_rr(dev, irq_dis_addr);
 +	for (i = 0; i < SYSIRQ_INTERRUPT_HISTORY_NUM; i++) {
 +		macVal = mt76_rr(dev, (start + (i * 8)));
 +		irq_dis_time[i] = macVal;
@@ -4910,8 +4930,7 @@
 +		irq_dis_lp[i] = macVal;
 +	}
 +
-+	start = mt76_rr(dev, 0x022051C4);
-+
++	start = mt76_rr(dev, irq_res_addr);
 +	for (i = 0; i < SYSIRQ_INTERRUPT_HISTORY_NUM; i++) {
 +		macVal = mt76_rr(dev, (start + (i * 8)));
 +		irq_res_time[i] = macVal;
@@ -4946,30 +4965,57 @@
 +	}
 +}
 +
++static int MemReadOneByte(struct mt7915_dev *dev, u32 addr)
++{
++	u32 val, tmpval;
++
++	val = mt76_rr(dev, (addr & ~(0x3)));
++	tmpval = (val >> (8 * (addr & (0x3)))) & 0xff;
++	return tmpval;
++}
++
 +static void mt7915_show_msg_trace(struct seq_file *s)
 +{
-+#define MSG_HISTORY_NUM	64
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
 +	struct cos_msg_trace_t *msg_trace = NULL;
-+	u32 ptr_addr = 0;
-+	u32 length = 0;
-+	u32 idx = 0;
-+	u32 cnt = 0;
-+	u32 msg_history_num = 0;
++	u32 ptr_addr, length;
++	u32 idx = 0, cnt = 0;
++	u32 msg_history_num, num_addr;
++	u32 trace_ptr_addr, trace_num_addr;
 +
-+	msg_trace = kmalloc(MSG_HISTORY_NUM * sizeof(struct cos_msg_trace_t), GFP_KERNEL);
-+	if (!msg_trace) {
-+		seq_printf(s, "can not allocate cmd msg_trace\n");
-+		return;
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7915:
++		trace_ptr_addr = 0x41F054;
++		trace_num_addr = 0x41F058;
++		num_addr = mt76_rr(dev, 0x41F05C);
++		break;
++	case 0x7981:
++		trace_ptr_addr = 0x02205100;
++		trace_num_addr = 0x02205104;
++		break;
++	case 0x7906:
++		trace_ptr_addr = 0x02205250;
++		trace_num_addr = 0x02205254;
++		break;
++	case 0x7986:
++	default:
++		trace_ptr_addr = 0x02205188;
++		trace_num_addr = 0x0220518C;
++		break;
 +	}
 +
-+	memset(msg_trace, 0,  MSG_HISTORY_NUM * sizeof(struct cos_msg_trace_t));
 +
-+	ptr_addr = mt76_rr(dev, 0x02205188);
-+	msg_history_num = mt76_rr(dev, 0x0220518C);
 +
-+	idx = (msg_history_num >> 8) & 0xff;
++	ptr_addr = mt76_rr(dev, trace_ptr_addr);
++	msg_history_num = mt76_rr(dev, trace_num_addr);
++	idx = (is_mt7915(&dev->mt76) ? MemReadOneByte(dev, num_addr) : (msg_history_num >> 8)) & 0xff;
 +	msg_history_num = msg_history_num & 0xff;
++	msg_trace = kzalloc(msg_history_num * sizeof(struct cos_msg_trace_t), GFP_KERNEL);
++
++	if (!msg_trace) {
++		seq_printf(s, "can not allocate cmd msg_trace\n");
++		return;
++	}
 +
 +	if (idx >= msg_history_num) {
 +		kfree(msg_trace);
@@ -4978,7 +5024,7 @@
 +
 +	length = msg_history_num * sizeof(struct cos_msg_trace_t);
 +	MemSectionRead(dev, (char *)&(msg_trace[0]), length, ptr_addr);
-+	seq_printf(s,"\n");
++	seq_printf(s, "\n");
 +	seq_printf(s, "       msg trace:\n");
 +	seq_printf(s, "       format: t_id=task_id/task_prempt_cnt/msg_read_idx\n");
 +
@@ -5030,9 +5076,9 @@
 +	}
 +
 +	*ptr = 0;
-+	seq_printf(s,"\n\n");
-+	seq_printf(s,"       Assert line\n");
-+	seq_printf(s,"       %s\n", msg);
++	seq_printf(s, "\n\n");
++	seq_printf(s, "       Assert line\n");
++	seq_printf(s, "       %s\n", msg);
 +	if (msg)
 +		kfree(msg);
 +
@@ -5044,33 +5090,47 @@
 +{
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
 +	struct cos_task_info_struct  task_info_g[2];
-+	u32 length = 0, i = 0;
-+	u32 idx = 0;
-+	u32 km_total_time = 0;
-+	u32 addr = 0;
++	u32 length, idx;
++	u32 addr, km_total_time;
++	u32 task_info_addr, km_total_time_addr;
 +	struct cos_task_type tcb;
 +	struct cos_task_type *tcb_ptr;
 +	char   name[2][15] = {
 +		"WIFI	", "WIFI2   "
 +	};
 +
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7915:
++		task_info_addr = 0x215400;
++		km_total_time_addr = 0x219838;
++		break;
++	case 0x7981:
++		task_info_addr = 0x02202978;
++		km_total_time_addr = 0x0220512C;
++		break;
++	case 0x7906:
++		task_info_addr = 0x02202ACC;
++		km_total_time_addr = 0x0220527C;
++		break;
++	case 0x7986:
++	default:
++		task_info_addr = 0x02202A18;
++		km_total_time_addr = 0x022051B4;
++		break;
++	}
++
 +	length = 2 * sizeof(struct cos_task_info_struct);
-+	MemSectionRead(dev, (char *)&(task_info_g[0]), length, 0x02202A18);
++	MemSectionRead(dev, (char *)&(task_info_g[0]), length, task_info_addr);
 +
-+	/*while(i < length) {
-+		task_info_g[i] = mt76_rr(dev, 0x02202A18 + i * 0x4);
-+		i++;
-+	}*/
-+	km_total_time = mt76_rr(dev, 0x022051B4);
++	km_total_time = mt76_rr(dev, km_total_time_addr);
 +	if (km_total_time == 0) {
 +		seq_printf(s, "km_total_time zero!\n");
 +		return;
 +	}
 +
-+	seq_printf(s,"\n\n\n	  TASK	 XTIME	  RATIO    PREMPT CNT\n");
++	seq_printf(s, "\n\n\n	  TASK	 XTIME	  RATIO    PREMPT CNT\n");
 +	for (idx = 0 ;	idx < 2 ; idx++) {
 +		addr = task_info_g[idx].task_id;
-+		i = 0;
 +		MemSectionRead(dev, (char *)&(tcb), sizeof(struct cos_task_type), addr);
 +
 +		length = sizeof(struct cos_task_type);
@@ -5090,67 +5150,96 @@
 +
 +static void mt7915_show_prog_trace(struct seq_file *s)
 +{
-+#define PROGRAM_TRACE_HISTORY_NUM 32
++#define mt7915_cos_access_ptr(_idx, _member)	(is_mt7915(&dev->mt76) ? \
++						mt7915_cos_program_trace_ptr[_idx]._##_member : \
++						cos_program_trace_ptr[_idx]._##_member)
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
 +	struct cos_program_trace_t *cos_program_trace_ptr = NULL;
-+	u32 trace_ptr = 0;
-+	u32 idx = 0;
-+	u32 old_idx = 0;
-+	u32 old_idx_addr = 0;
-+	u32 prev_idx = 0;
-+	u32 prev_time = 0;
-+	u32 curr_time = 0;
-+	u32 diff = 0;
-+	//u32 length = 0, i = 0;
++	struct mt7915_cos_program_trace_t *mt7915_cos_program_trace_ptr = NULL;
++	char *buf;
++	u32 trace_ptr;
++	u32 idx;
++	u32 old_idx;
++	u32 old_idx_addr;
++	u32 prev_idx, diff;
++	u32 prev_time, prev_dest_id, prev_msg_sn;
++	u32 old_time, old_dest_id, old_msg_sn;
++	u32 trace_ptr_addr, trace_idx_addr, trace_num_addr, trace_num;
++	int size;
++
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7915:
++		trace_ptr_addr = 0x41F0E0;
++		trace_idx_addr = 0x41F0E8;
++		trace_num_addr = mt76_rr(dev, 0x41F0E4);
++		break;
++	case 0x7981:
++		trace_ptr_addr = 0x022050C4;
++		trace_idx_addr = 0x022050C0;
++		break;
++	case 0x7906:
++		trace_ptr_addr = 0x02205214;
++		trace_idx_addr = 0x02205210;
++		break;
++	case 0x7986:
++	default:
++		trace_ptr_addr = 0x0220514C;
++		trace_idx_addr = 0x02205148;
++		break;
++	}
 +
-+	cos_program_trace_ptr = kmalloc(PROGRAM_TRACE_HISTORY_NUM * sizeof(struct cos_program_trace_t), GFP_KERNEL);
-+	if (!cos_program_trace_ptr) {
++	size = is_mt7915(&dev->mt76) ? sizeof(struct mt7915_cos_program_trace_t) : sizeof(struct cos_program_trace_t);
++	trace_num = is_mt7915(&dev->mt76) ? MemReadOneByte(dev, trace_num_addr) & 0xff : 32;
++	buf = kzalloc(trace_num * size, GFP_KERNEL);
++	if (!buf) {
 +		seq_printf(s, "can not allocate cos_program_trace_ptr memory\n");
 +		return;
 +	}
-+	memset(cos_program_trace_ptr, 0, PROGRAM_TRACE_HISTORY_NUM * sizeof(struct cos_program_trace_t));
 +
-+	trace_ptr = mt76_rr(dev, 0x0220514C);
-+	old_idx_addr = mt76_rr(dev, 0x02205148);
++	trace_ptr = mt76_rr(dev, trace_ptr_addr);
++	old_idx_addr = mt76_rr(dev, trace_idx_addr);
++	old_idx = (is_mt7915(&dev->mt76) ? MemReadOneByte(dev, old_idx_addr) : (old_idx_addr >> 8)) & 0xff;
 +
-+	old_idx = (old_idx_addr >> 8) & 0xff;
++	MemSectionRead(dev, &buf[0], trace_num * size, trace_ptr);
 +
-+	MemSectionRead(dev, (char *)&cos_program_trace_ptr[0], PROGRAM_TRACE_HISTORY_NUM * sizeof(struct cos_program_trace_t), trace_ptr);
++	if (is_mt7915(&dev->mt76))
++		mt7915_cos_program_trace_ptr = (struct mt7915_cos_program_trace_t *)buf;
++	else
++		cos_program_trace_ptr = (struct cos_program_trace_t *)buf;
 +
-+	/*length = PROGRAM_TRACE_HISTORY_NUM * sizeof(struct cos_program_trace_t);
-+	while(i < length) {
-+		cos_program_trace_ptr[i] = mt76_rr(dev, trace_ptr + i * 0x4);
-+		i++;
-+	}*/
 +	seq_printf(s, "\n");
 +	seq_printf(s, "       program trace:\n");
-+	for (idx = 0 ; idx < PROGRAM_TRACE_HISTORY_NUM ; idx++) {
-+		prev_idx = ((old_idx + 32 - 1) % 32);
++	for (idx = 0 ; idx < trace_num ; idx++) {
++		prev_idx = ((old_idx + trace_num - 1) % trace_num);
++
++		prev_time = mt7915_cos_access_ptr(prev_idx, ts_gpt2);
++		old_time = mt7915_cos_access_ptr(old_idx, ts_gpt2);
++		prev_dest_id = mt7915_cos_access_ptr(prev_idx, dest_id);
++		old_dest_id = mt7915_cos_access_ptr(old_idx, dest_id);
++		prev_msg_sn = mt7915_cos_access_ptr(prev_idx, msg_sn);
++		old_msg_sn = mt7915_cos_access_ptr(old_idx, msg_sn);
 +
 +		seq_printf(s, "       (p_%d)t_id=%x/%d, m_id=%d, LP=0x%x, name=%s, ts2=%d, ",
 +			old_idx,
-+			cos_program_trace_ptr[old_idx].dest_id,
-+			cos_program_trace_ptr[old_idx].msg_sn,
-+			cos_program_trace_ptr[old_idx].msg_id,
-+			cos_program_trace_ptr[old_idx].LP,
-+			cos_program_trace_ptr[old_idx].name,
-+			cos_program_trace_ptr[old_idx].ts_gpt2);
++			old_dest_id,
++			old_msg_sn,
++			mt7915_cos_access_ptr(old_idx, msg_id),
++			mt7915_cos_access_ptr(old_idx, LP),
++			mt7915_cos_access_ptr(old_idx, name),
++			old_time);
 +
 +		/* diff for gpt2 */
-+		prev_time = cos_program_trace_ptr[prev_idx].ts_gpt2;
-+		curr_time = cos_program_trace_ptr[old_idx].ts_gpt2;
++
++		diff = 0xFFFFFFFF;
 +
 +		if (prev_time) {
-+			if ((cos_program_trace_ptr[prev_idx].dest_id == cos_program_trace_ptr[old_idx].dest_id) &&
-+				(cos_program_trace_ptr[prev_idx].msg_sn == cos_program_trace_ptr[old_idx].msg_sn)) {
-+				if (curr_time > prev_time)
-+					diff = curr_time - prev_time;
++			if ((prev_dest_id == old_dest_id) && (prev_msg_sn == old_msg_sn)) {
++				if (old_time > prev_time)
++					diff = old_time - prev_time;
 +				else
-+					diff = 0xFFFFFFFF - prev_time + curr_time + 1;
-+			} else
-+				diff = 0xFFFFFFFF;
-+		} else
-+			diff = 0xFFFFFFFF;
++					diff = 0xFFFFFFFF - prev_time + old_time + 1;
++			}
++		}
 +
 +		if (diff == 0xFFFFFFFF)
 +			seq_printf(s, "diff2=NA, \n");
@@ -5158,117 +5247,205 @@
 +			seq_printf(s, "diff2=%8d\n", diff);
 +
 +		old_idx++;
-+		if (old_idx >= 32)
++		if (old_idx >= trace_num)
 +			old_idx = 0;
 +	}
-+	if (cos_program_trace_ptr)
-+		kfree(cos_program_trace_ptr);
++	if (buf)
++		kfree(buf);
 +}
 +
 +static int mt7915_fw_wm_info_read(struct seq_file *s, void *data)
 +{
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
-+	u32 macVal = 0, g_exp_type = 0, COS_Interrupt_Count = 0;
-+	u8 exp_assert_proc_entry_cnt = 0, exp_assert_state = 0, g_irq_history_num = 0;
-+	u16 processing_irqx = 0;
-+	u32 processing_lisr = 0, Current_Task_Id = 0, Current_Task_Indx = 0;
-+	u8 km_irq_info_idx = 0, km_eint_info_idx = 0, km_sched_info_idx = 0, g_sched_history_num = 0;
-+	u32 km_sched_trace_ptr = 0,km_irq_trace_ptr = 0, km_total_time  = 0, TaskStart[3] = {0};
++	u32 macVal, g_exp_type, COS_Interrupt_Count;
++	u8 exp_assert_proc_entry_cnt, exp_assert_state, g_irq_history_num;
++	u16 processing_irqx;
++	u32 processing_lisr, Current_Task_Id, Current_Task_Indx;
++	u8 km_irq_info_idx, km_eint_info_idx, km_sched_info_idx, g_sched_history_num;
++	u32 km_sched_trace_ptr, km_irq_trace_ptr, km_total_time;
 +	bool fgIsExp = false, fgIsAssert = false;
-+	u32 TaskEnd[3] = {0}, exp_assert_state_addr = 0, g1_exp_counter_addr = 0;
-+	u32 g_exp_type_addr = 0, cos_interrupt_count_addr = 0;
-+	u32 processing_irqx_addr = 0, processing_lisr_addr = 0;
-+	u32 Current_Task_Id_addr = 0, Current_Task_Indx_addr = 0, last_dequeued_msg_id_addr = 0;
-+	u32 km_irq_info_idx_addr = 0, km_eint_info_idx_addr = 0, km_sched_info_idx_addr = 0;
-+	u32 g_sched_history_num_addr = 0, km_sched_trace_ptr_addr = 0;
-+	u32 km_irq_trace_ptr_addr = 0, km_total_time_addr  = 0, last_dequeued_msg_id = 0;
-+	u32 i = 0 ,t1 = 0, t2 = 0, t3 = 0;
-+	u8 idx = 0, str[32], exp_type[64];
-+	int ret;
++	u32 TaskStart[2], TaskEnd[2];
++	u32 exp_assert_state_addr, g1_exp_counter_addr;
++	u32 g_exp_type_addr, cos_interrupt_count_addr;
++	u32 processing_irqx_addr, processing_lisr_addr;
++	u32 Current_Task_Id_addr, Current_Task_Indx_addr, last_dequeued_msg_id_addr;
++	u32 km_irq_info_idx_addr, km_eint_info_idx_addr, km_sched_info_idx_addr;
++	u32 g_sched_history_num_addr, km_sched_trace_ptr_addr;
++	u32 km_irq_trace_ptr_addr, km_total_time_addr, last_dequeued_msg_id;
++	u32 TaskStart_0, TaskEnd_0, TaskStart_1, TaskEnd_1;
++	u32 t1_base_addr, t2_base_addr, t3_base_addr, t_addr_ofs;
++	u32 cpu_itype_addr, cpu_eva_addr, cpu_ipc_addr, pc_addr;
++	u32 busy_addr, peak_addr;
++	u32 i, t1, t2, t3;
++	u8 idx, exp_type[64];
 +
-+	g_exp_type_addr = 0x022050DC;
-+	exp_assert_state_addr = 0x02204B54;
-+	g1_exp_counter_addr = 0x02204FFC;
-+	cos_interrupt_count_addr = 0x022001AC;
-+	processing_irqx_addr = 0x02204EC4;
-+	processing_lisr_addr = 0x02205010;
-+	Current_Task_Id_addr = 0x02204FAC;
-+	Current_Task_Indx_addr = 0x02204F4C;
-+	last_dequeued_msg_id_addr = 0x02204F28;
-+	km_irq_info_idx_addr = 0x0220519C;
-+	km_eint_info_idx_addr = 0x02205194;
-+	km_sched_info_idx_addr = 0x022051A4;
-+	g_sched_history_num_addr = 0x022051A4;
-+	km_sched_trace_ptr_addr = 0x022051A0;
-+	km_irq_trace_ptr_addr = 0x02205198;
-+	km_total_time_addr = 0x022051B4;
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7915:
++		g_exp_type_addr = 0x21987C;
++		exp_assert_state_addr = 0x219848;
++		g1_exp_counter_addr = 0x219848;
++		cos_interrupt_count_addr = 0x216F94;
++		processing_irqx_addr = 0x216EF8;
++		processing_lisr_addr = 0x2170AC;
++		Current_Task_Id_addr = 0x216F90;
++		Current_Task_Indx_addr = 0x216F9C;
++		last_dequeued_msg_id_addr = 0x216F70;
++		km_irq_info_idx_addr = 0x219820;
++		km_eint_info_idx_addr = 0x219818;
++		km_sched_info_idx_addr = 0x219828;
++		g_sched_history_num_addr = 0x219828;
++		km_sched_trace_ptr_addr = 0x219824;
++		km_irq_trace_ptr_addr = 0x21981C;
++		km_total_time_addr = 0x219838;
++		TaskStart_0 = 0x2195A0;
++		TaskEnd_0 = 0x21959C;
++		TaskStart_1 = 0x219680;
++		TaskEnd_1 = 0x21967C;
++		t1_base_addr = 0x219558;
++		t2_base_addr = 0x219554;
++		t3_base_addr = 0x219560;
++		cpu_itype_addr = 0x41F088;
++		cpu_eva_addr = 0x41F08C;
++		cpu_ipc_addr = 0x41F094;
++		pc_addr = 0x7C060204;
++		busy_addr = 0x41F030;
++		peak_addr = 0x41F034;
++		break;
++	case 0x7981:
++		g_exp_type_addr = 0x02205054;
++		exp_assert_state_addr = 0x02204AC0;
++		g1_exp_counter_addr = 0x02204F68;
++		cos_interrupt_count_addr = 0x02204FFC;
++		processing_irqx_addr = 0x02204E30;
++		processing_lisr_addr = 0x02204F7C;
++		Current_Task_Id_addr = 0x02204F18;
++		Current_Task_Indx_addr = 0x02204F18;
++		last_dequeued_msg_id_addr = 0x02204E94;
++		km_irq_info_idx_addr = 0x02205114;
++		km_eint_info_idx_addr = 0x0220510C;
++		km_sched_info_idx_addr = 0x0220511C;
++		g_sched_history_num_addr = 0x0220511C;
++		km_sched_trace_ptr_addr = 0x02205118;
++		km_irq_trace_ptr_addr = 0x02205110;
++		km_total_time_addr = 0x0220512C;
++		TaskStart_0 = 0x022028B4;
++		TaskEnd_0 = 0x022028C0;
++		TaskStart_1 = 0x02202A38;
++		TaskEnd_1 = 0x02202934;
++		t1_base_addr = 0x02202718;
++		t2_base_addr = 0x0220287C;
++		t3_base_addr = 0x02202884;
++		cpu_itype_addr = 0x02205058;
++		cpu_eva_addr = 0x02205060;
++		cpu_ipc_addr = 0x0220505C;
++		pc_addr = 0x7C060204;
++		busy_addr = 0x7C053B20;
++		peak_addr = 0x7C053B24;
++		break;
++	case 0x7906:
++		g_exp_type_addr = 0x022051A4;
++		exp_assert_state_addr = 0x02204C14;
++		g1_exp_counter_addr = 0x022050BC;
++		cos_interrupt_count_addr = 0x022001AC;
++		processing_irqx_addr = 0x02204F84;
++		processing_lisr_addr = 0x022050D0;
++		Current_Task_Id_addr = 0x0220406C;
++		Current_Task_Indx_addr = 0x0220500C;
++		last_dequeued_msg_id_addr = 0x02204FE8;
++		km_irq_info_idx_addr = 0x02205264;
++		km_eint_info_idx_addr = 0x0220525C;
++		km_sched_info_idx_addr = 0x0220526C;
++		g_sched_history_num_addr = 0x0220516C;
++		km_sched_trace_ptr_addr = 0x02205268;
++		km_irq_trace_ptr_addr = 0x02205260;
++		km_total_time_addr = 0x0220517C;
++		TaskStart_0 = 0x022028C8;
++		TaskEnd_0 = 0x022028C4;
++		TaskStart_1 = 0x02202A38;
++		TaskEnd_1 = 0x02202934;
++		t1_base_addr = 0x0220286C;
++		t2_base_addr = 0x02202870;
++		t3_base_addr = 0x02202878;
++		cpu_itype_addr = 0x022051A8;
++		cpu_eva_addr = 0x022051B0;
++		cpu_ipc_addr = 0x022051AC;
++		pc_addr = 0x7C060204;
++		busy_addr = 0x7C053B20;
++		peak_addr = 0x7C053B24;
++		break;
++	case 0x7986:
++	default:
++		g_exp_type_addr = 0x022050DC;
++		exp_assert_state_addr = 0x02204B54;
++		g1_exp_counter_addr = 0x02204FFC;
++		cos_interrupt_count_addr = 0x022001AC;
++		processing_irqx_addr = 0x02204EC4;
++		processing_lisr_addr = 0x02205010;
++		Current_Task_Id_addr = 0x02204FAC;
++		Current_Task_Indx_addr = 0x02204F4C;
++		last_dequeued_msg_id_addr = 0x02204F28;
++		km_irq_info_idx_addr = 0x0220519C;
++		km_eint_info_idx_addr = 0x02205194;
++		km_sched_info_idx_addr = 0x022051A4;
++		g_sched_history_num_addr = 0x022051A4;
++		km_sched_trace_ptr_addr = 0x022051A0;
++		km_irq_trace_ptr_addr = 0x02205198;
++		km_total_time_addr = 0x022051B4;
++		TaskStart_0 = 0x02202814;
++		TaskEnd_0 = 0x02202810;
++		TaskStart_1 = 0x02202984;
++		TaskEnd_1 = 0x02202980;
++		t1_base_addr = 0x022027B8;
++		t2_base_addr = 0x022027BC;
++		t3_base_addr = 0x022027C4;
++		cpu_itype_addr = 0x022050E0;
++		cpu_eva_addr = 0x022050E8;
++		cpu_ipc_addr = 0x022050E4;
++		pc_addr = 0x7C060204;
++		busy_addr = 0x7C053B20;
++		peak_addr = 0x7C053B24;
++		break;
++	}
 +
-+	macVal = 0;
 +	macVal = mt76_rr(dev, exp_assert_state_addr);
 +	exp_assert_state = (macVal & 0xff);
 +
-+	macVal = 0;
 +	macVal = mt76_rr(dev, g1_exp_counter_addr);
-+	exp_assert_proc_entry_cnt = (macVal & 0xff);
++	exp_assert_proc_entry_cnt = (is_mt7915(&dev->mt76) ? (macVal >> 8) : macVal) & 0xff;
 +
-+	macVal = 0;
 +	macVal = mt76_rr(dev, g_exp_type_addr);
-+	g_exp_type = macVal;
++	g_exp_type = is_mt7915(&dev->mt76) ? ((macVal >> 8) & 0xff) : macVal;
 +
-+	macVal = 0;
-+	macVal = mt76_rr(dev, cos_interrupt_count_addr);
-+	COS_Interrupt_Count = macVal;
++	COS_Interrupt_Count = mt76_rr(dev, cos_interrupt_count_addr);
 +
-+	macVal = 0;
 +	macVal = mt76_rr(dev, processing_irqx_addr);
-+	processing_irqx = (macVal & 0xffff);
-+
-+	macVal = 0;
-+	macVal = mt76_rr(dev, processing_lisr_addr);
-+	processing_lisr = macVal;
-+
-+	macVal = 0;
-+	macVal = mt76_rr(dev, Current_Task_Id_addr);
-+	Current_Task_Id = macVal;
-+
-+	macVal = 0;
-+	macVal = mt76_rr(dev, Current_Task_Indx_addr);
-+	Current_Task_Indx = macVal;
++	processing_irqx = (is_mt7915(&dev->mt76) ? (macVal >> 16) : macVal) & 0xffff;
 +
-+	macVal = 0;
-+	macVal = mt76_rr(dev, last_dequeued_msg_id_addr);
-+	last_dequeued_msg_id = macVal;
++	processing_lisr = mt76_rr(dev, processing_lisr_addr);
++	Current_Task_Id = mt76_rr(dev, Current_Task_Id_addr);
++	Current_Task_Indx = mt76_rr(dev, Current_Task_Indx_addr);
++	last_dequeued_msg_id = mt76_rr(dev, last_dequeued_msg_id_addr);
 +
-+	macVal = 0;
 +	macVal = mt76_rr(dev, km_eint_info_idx_addr);
-+	km_eint_info_idx = ((macVal >> 8) & 0xff);
++	km_eint_info_idx = (is_mt7915(&dev->mt76) ? macVal : (macVal >> 8)) & 0xff;
 +
-+	macVal = 0;
 +	macVal = mt76_rr(dev, g_sched_history_num_addr);
-+	g_sched_history_num = (macVal & 0xff);
-+	km_sched_info_idx = ((macVal >> 8) & 0xff);
++	g_sched_history_num = (is_mt7915(&dev->mt76) ? (macVal >> 8) : macVal) & 0xff;
++	km_sched_info_idx = (is_mt7915(&dev->mt76) ? macVal : (macVal >> 8)) & 0xff;
 +
-+	macVal = 0;
-+	macVal = mt76_rr(dev, km_sched_trace_ptr_addr);
-+	km_sched_trace_ptr = macVal;
++	km_sched_trace_ptr = mt76_rr(dev, km_sched_trace_ptr_addr);
 +
-+	macVal = 0;
 +	macVal = mt76_rr(dev, km_irq_info_idx_addr);
-+	g_irq_history_num = (macVal & 0xff);
-+	km_irq_info_idx = ((macVal >> 16) & 0xff);
++	g_irq_history_num = (is_mt7915(&dev->mt76) ? (macVal >> 8) : macVal) & 0xff;
++	km_irq_info_idx = (is_mt7915(&dev->mt76) ? macVal : (macVal >> 16)) & 0xff;
 +
-+	macVal = 0;
-+	macVal = mt76_rr(dev, km_irq_trace_ptr_addr);
-+	km_irq_trace_ptr = macVal;
++	km_irq_trace_ptr = mt76_rr(dev, km_irq_trace_ptr_addr);
++	km_total_time = mt76_rr(dev, km_total_time_addr);
 +
-+	macVal = 0;
-+	macVal = mt76_rr(dev, km_total_time_addr);
-+	km_total_time = macVal;
-+
-+	TaskStart[0] = mt76_rr(dev, 0x02202814);
-+	TaskEnd[0] = mt76_rr(dev, 0x02202810);
-+	TaskStart[1] = mt76_rr(dev, 0x02202984);
-+	TaskEnd[1] = mt76_rr(dev, 0x02202980);
++	TaskStart[0] = mt76_rr(dev, TaskStart_0);
++	TaskEnd[0] = mt76_rr(dev, TaskEnd_0);
++	TaskStart[1] = mt76_rr(dev, TaskStart_1);
++	TaskEnd[1] = mt76_rr(dev, TaskEnd_1);
 +
 +	seq_printf(s, "================FW DBG INFO===================\n");
 +	seq_printf(s, "       exp_assert_proc_entry_cnt = 0x%x\n",
@@ -5277,40 +5454,19 @@
 +		  exp_assert_state);
 +
 +	if (exp_assert_proc_entry_cnt == 0) {
-+		ret = snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Normal");
-+		if (mt7915_snprintf_error(sizeof(exp_type), ret)) {
-+			seq_printf(s, " exp_type Snprintf failed!\n");
-+			return 0;
-+		}
-+	} else if (exp_assert_proc_entry_cnt == 1 &&
-+		exp_assert_state > 1 && g_exp_type == 5) {
-+		ret = snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Assert");
-+		if (mt7915_snprintf_error(sizeof(exp_type), ret)) {
-+			seq_printf(s, " exp_type Snprintf failed!\n");
-+			return 0;
-+		}
++		snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Normal");
++	} else if (exp_assert_proc_entry_cnt == 1 && exp_assert_state > 1 && g_exp_type == 5) {
++		snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Assert");
 +		fgIsExp = true;
 +		fgIsAssert = true;
 +	} else if (exp_assert_proc_entry_cnt == 1 && exp_assert_state > 1) {
-+		ret = snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Exception");
-+		if (mt7915_snprintf_error(sizeof(exp_type), ret)) {
-+			seq_printf(s, " exp_type Snprintf failed!\n");
-+			return 0;
-+		}
++		snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Exception");
 +		fgIsExp = true;
 +	} else if (exp_assert_proc_entry_cnt > 1) {
-+		ret = snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Exception re-entry");
-+		if (mt7915_snprintf_error(sizeof(exp_type), ret)) {
-+			seq_printf(s, " exp_type Snprintf failed!\n");
-+			return 0;
-+		}
++		snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Exception re-entry");
 +		fgIsExp = true;
 +	} else {
-+		ret = snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Unknown'?");
-+		if (mt7915_snprintf_error(sizeof(exp_type), ret)) {
-+			seq_printf(s, " exp_type Snprintf failed!\n");
-+			return 0;
-+		}
++		snprintf(exp_type, sizeof(exp_type), "%s", "exp_type : Unknown?");
 +	}
 +
 +	seq_printf(s, "       COS_Interrupt_Count = 0x%x\n", COS_Interrupt_Count);
@@ -5365,27 +5521,14 @@
 +	seq_printf(s, "\n       <4>TASK STACK INFO (size in byte)\n");
 +	seq_printf(s, "       TASK  START       END       SIZE  PEAK  INTEGRITY\n");
 +
++	t_addr_ofs = is_mt7915(&dev->mt76) ? 224 : 368;
 +	for (i = 0 ; i < 2 ; i++) {
-+		t1 = mt76_rr(dev,  0x022027B8+(i*368));
-+		t2 = mt76_rr(dev,  0x022027BC+(i*368));
-+		t3 = mt76_rr(dev,  0x022027C4+(i*368));
-+
-+		if (i == 0) {
-+			ret = snprintf(str, sizeof(str), "%s", "WIFI");
-+			if (mt7915_snprintf_error(sizeof(str), ret)) {
-+				seq_printf(s, " str Snprintf failed!\n");
-+				return 0;
-+			}
-+		} else if (i == 1) {
-+			ret = snprintf(str, sizeof(str), "%s", "WIFI2");
-+			if (mt7915_snprintf_error(sizeof(str), ret)) {
-+				seq_printf(s, " str Snprintf failed!\n");
-+				return 0;
-+			}
-+		}
++		t1 = mt76_rr(dev,  t1_base_addr + (i*t_addr_ofs));
++		t2 = mt76_rr(dev,  t2_base_addr + (i*t_addr_ofs));
++		t3 = mt76_rr(dev,  t3_base_addr + (i*t_addr_ofs));
 +
 +		seq_printf(s, "       %s  0x%x  0x%x  %d\n",
-+			str, t1, t2, t3);
++			i == 0 ? "WIFI" : "WIFI2", t1, t2, t3);
 +	}
 +
 +	seq_printf(s, "\n       <5>fw state\n");
@@ -5402,38 +5545,26 @@
 +				Current_Task_Id, Current_Task_Indx);
 +	}
 +
-+	macVal = 0;
-+	macVal= mt76_rr(dev, g1_exp_counter_addr);
++	macVal = mt76_rr(dev, is_mt7915(&dev->mt76) ? 0x41F080 : g1_exp_counter_addr);
 +	seq_printf(s, "       EXCP_CNT = 0x%x\n", macVal);
 +
 +	seq_printf(s, "       EXCP_TYPE = 0x%x\n", g_exp_type);
-+
-+	macVal = 0;
-+	macVal = mt76_rr(dev, 0x022050E0);
-+	seq_printf(s, "       CPU_ITYPE = 0x%x\n", macVal);
-+
-+	macVal = 0;
-+	macVal = mt76_rr(dev,  0x022050E8);
-+	seq_printf(s, "       CPU_EVA = 0x%x\n", macVal);
-+
-+	macVal = 0;
-+	macVal = mt76_rr(dev, 0x022050E4);
-+	seq_printf(s, "       CPU_IPC = 0x%x\n", macVal);
-+
-+	macVal = 0;
-+	macVal = mt76_rr(dev, 0x7C060204);
-+	seq_printf(s, "       PC = 0x%x\n\n\n", macVal);
++	seq_printf(s, "       CPU_ITYPE = 0x%x\n", mt76_rr(dev, cpu_itype_addr));
++	seq_printf(s, "       CPU_EVA = 0x%x\n", mt76_rr(dev, cpu_eva_addr));
++	seq_printf(s, "       CPU_IPC = 0x%x\n", mt76_rr(dev, cpu_ipc_addr));
++	seq_printf(s, "       PC = 0x%x\n\n\n", mt76_rr(dev, pc_addr));
 +
 +	mt7915_show_lp_history(s, fgIsExp);
 +	mt7915_show_irq_history(s);
 +
-+	seq_printf(s, "\n\n       cpu ultility\n");
++	seq_printf(s, "\n\n       cpu utility\n");
 +	seq_printf(s, "       Busy:%d%% Peak:%d%%\n\n",
-+		   mt76_rr(dev, 0x7C053B20), mt76_rr(dev, 0x7C053B24));
++		   mt76_rr(dev, busy_addr), mt76_rr(dev, peak_addr));
 +
 +	mt7915_show_msg_trace(s);
 +	mt7915_show_sech_trace(s);
 +	mt7915_show_prog_trace(s);
++
 +	if (fgIsAssert)
 +		mt7915_show_assert_line(s);
 +
@@ -5526,7 +5657,7 @@
 +#endif
 diff --git a/mt7915/mtk_mcu.c b/mt7915/mtk_mcu.c
 new file mode 100644
-index 00000000..143dae26
+index 0000000..143dae2
 --- /dev/null
 +++ b/mt7915/mtk_mcu.c
 @@ -0,0 +1,51 @@
@@ -5582,7 +5713,7 @@
 +				 sizeof(req), true);
 +}
 diff --git a/tools/fwlog.c b/tools/fwlog.c
-index e5d4a105..3d51d9ec 100644
+index e5d4a10..3d51d9e 100644
 --- a/tools/fwlog.c
 +++ b/tools/fwlog.c
 @@ -26,7 +26,7 @@ static const char *debugfs_path(const char *phyname, const char *file)
diff --git a/recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch b/recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch
index 900672a..654e632 100644
--- a/recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch
@@ -1,26 +1,27 @@
-From e6ccf89484d41dbd38992cf60150ef0db4bbafb2 Mon Sep 17 00:00:00 2001
+From 799948d6f5dc16251034621b69a48bdf6f30a197 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 6 Jun 2022 20:13:02 +0800
-Subject: [PATCH 1001/1040] wifi: mt76: mt7915: csi: implement csi support
+Subject: [PATCH 13/76] wifi: mt76: mt7915: csi: implement csi support
 
 ---
  mt76_connac_mcu.h |   2 +
  mt7915/Makefile   |   4 +-
- mt7915/init.c     |  39 ++++
- mt7915/mcu.c      | 111 ++++++++++++
- mt7915/mcu.h      |  77 ++++++++
- mt7915/mt7915.h   |  20 ++
- mt7915/vendor.c   | 452 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7915/vendor.h   |  60 ++++++
- 8 files changed, 763 insertions(+), 2 deletions(-)
+ mt7915/init.c     |  38 ++++
+ mt7915/main.c     |   4 +
+ mt7915/mcu.c      | 203 ++++++++++++++++++++
+ mt7915/mcu.h      |  74 ++++++++
+ mt7915/mt7915.h   |  60 ++++++
+ mt7915/vendor.c   | 470 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7915/vendor.h   |  63 +++++++
+ 9 files changed, 916 insertions(+), 2 deletions(-)
  create mode 100644 mt7915/vendor.c
  create mode 100644 mt7915/vendor.h
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 8b3b7c0..8a377dd 100644
+index d28ee91..b31f19a 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1007,6 +1007,7 @@ enum {
+@@ -1017,6 +1017,7 @@ enum {
  	MCU_EXT_EVENT_WA_TX_STAT = 0x74,
  	MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
  	MCU_EXT_EVENT_MURU_CTRL = 0x9f,
@@ -28,7 +29,7 @@
  };
  
  /* unified event table */
-@@ -1207,6 +1208,7 @@ enum {
+@@ -1228,6 +1229,7 @@ enum {
  	MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
  	MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
@@ -54,7 +55,7 @@
  mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
  mt7915e-$(CONFIG_MT798X_WMAC) += soc.o
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 0d2587c..607d881 100644
+index d5d9cbf..d4bf09c 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
 @@ -696,6 +696,12 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
@@ -70,7 +71,7 @@
  	ret = mt76_register_phy(mphy, true, mt76_rates,
  				ARRAY_SIZE(mt76_rates));
  	if (ret)
-@@ -1173,6 +1179,25 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+@@ -1173,6 +1179,24 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
  	}
  }
  
@@ -88,7 +89,6 @@
 +	}
 +	spin_unlock_bh(&phy->csi.csi_lock);
 +
-+
 +	return 0;
 +}
 +#endif
@@ -96,7 +96,7 @@
  static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
  {
  	struct mt7915_phy *phy = mt7915_ext_phy(dev);
-@@ -1181,6 +1206,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
+@@ -1181,6 +1205,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
  	if (!phy)
  		return;
  
@@ -107,7 +107,7 @@
  	mt7915_unregister_thermal(phy);
  	mt76_unregister_phy(mphy);
  	ieee80211_free_hw(mphy->hw);
-@@ -1193,6 +1222,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
+@@ -1193,6 +1221,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
  	mt7915_dma_cleanup(dev);
  	tasklet_disable(&dev->mt76.irq_tasklet);
  
@@ -118,7 +118,7 @@
  	if (is_mt798x(&dev->mt76))
  		mt7986_wmac_disable(dev);
  }
-@@ -1233,6 +1266,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
+@@ -1233,6 +1265,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
  	dev->mt76.test_ops = &mt7915_testmode_ops;
  #endif
  
@@ -131,8 +131,23 @@
  	ret = mt76_register_device(&dev->mt76, true, mt76_rates,
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 38ffd90..a4baa3d 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -784,6 +784,10 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	struct mt7915_phy *phy = msta->vif->phy;
+ 	int i;
+ 
++#ifdef CONFIG_MTK_VENDOR
++	mt7915_mcu_set_csi(&dev->phy, 2, 8, 1, 0, sta->addr, 0);
++#endif
++
+ 	mt7915_mcu_add_sta(dev, vif, sta, false);
+ 
+ 	mt7915_mac_wtbl_update(dev, msta->wcid.idx,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 47e178f..729a41d 100644
+index 1cb462f..3202c4e 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -40,6 +40,10 @@ static bool sr_scene_detect = true;
@@ -158,13 +173,13 @@
  	case MCU_EXT_EVENT_BCC_NOTIFY:
  		mt7915_mcu_rx_bcc_notify(dev, skb);
  		break;
-@@ -4024,6 +4033,108 @@ out:
+@@ -4024,6 +4033,200 @@ out:
  	return ret;
  }
  
 +#ifdef CONFIG_MTK_VENDOR
 +int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
-+			u8 cfg, u8 v1, u32 v2, u8 *mac_addr)
++		       u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval)
 +{
 +	struct mt7915_dev *dev = phy->dev;
 +	struct mt7915_mcu_csi req = {
@@ -175,27 +190,71 @@
 +		.v2 = cpu_to_le32(v2),
 +	};
 +
-+	if (is_valid_ether_addr(mac_addr))
++	if (is_valid_ether_addr(mac_addr)) {
 +		ether_addr_copy(req.mac_addr, mac_addr);
 +
++		if (req.v2 == 1 && sta_interval)
++			req.sta_interval = sta_interval;
++	}
++
 +	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(CSI_CTRL), &req,
-+				 sizeof(req), false);
++				 sizeof(req), true);
 +}
 +
++static int csi_integret_segment_data(struct mt7915_phy *phy, struct csi_data *csi)
++{
++	struct csi_data *csi_temp = NULL;
++
++	if (csi->segment_num == 0 &&
++	    csi->remain_last == 0)
++		return CSI_CHAIN_COMPLETE;
++	else if (csi->segment_num == 0 &&
++		 csi->remain_last == 1) {
++		memcpy(&phy->csi.buffered_csi,
++		       csi, sizeof(struct csi_data));
++
++		return CSI_CHAIN_SEGMENT_FIRST;
++	} else if (csi->segment_num != 0) {
++		csi_temp = &phy->csi.buffered_csi;
++		if (csi->chain_info !=
++			csi_temp->chain_info ||
++			csi->segment_num !=
++			(csi_temp->segment_num + 1))
++			return CSI_CHAIN_SEGMENT_ERR;
++
++		memcpy(&csi_temp->data_i[csi_temp->data_num],
++		       csi->data_i, csi->data_num * sizeof(s16));
++
++		memcpy(&csi_temp->data_q[csi_temp->data_num],
++		       csi->data_q, csi->data_num * sizeof(s16));
++
++		csi_temp->data_num += csi->data_num;
++		csi_temp->segment_num = csi->segment_num;
++		csi_temp->remain_last = csi->remain_last;
++
++		if (csi->remain_last == 0)
++			return CSI_CHAIN_SEGMENT_LAST;
++		else if (csi->remain_last == 1)
++			return CSI_CHAIN_SEGMENT_MIDDLE;
++	}
++
++	return CSI_CHAIN_ERR;
++}
++
 +static int
 +mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
 +{
 +	struct mt76_connac2_mcu_rxd *rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
 +	struct mt7915_phy *phy = &dev->phy;
-+	struct mt7915_mcu_csi_report *cr;
-+	struct csi_data *csi;
 +	int len, i;
++	struct mt7915_mcu_csi_report *cr;
++	int ret;
++	struct csi_data *current_csi = NULL;
++	struct csi_data *target_csi = NULL;
 +
 +	skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
 +
 +	len = le16_to_cpu(rxd->len) - sizeof(struct mt76_connac2_mcu_rxd) + 24;
-+	if (len < sizeof(*cr))
-+		return -EINVAL;
 +
 +	cr = (struct mt7915_mcu_csi_report *)skb->data;
 +
@@ -203,46 +262,94 @@
 +	    le32_to_cpu(cr->ts) < phy->csi.last_record + phy->csi.interval)
 +		return 0;
 +
++	current_csi = kzalloc(sizeof(*current_csi), GFP_KERNEL);
++
-+	csi = kzalloc(sizeof(*csi), GFP_KERNEL);
-+	if (!csi)
++	if (!current_csi)
 +		return -ENOMEM;
 +
-+#define SET_CSI_DATA(_field)	csi->_field = le32_to_cpu(cr->_field)
++	memset(current_csi, 0, sizeof(struct csi_data));
++
++#define SET_CSI_DATA(_field)	(current_csi->_field = le32_to_cpu((cr->_field)))
 +	SET_CSI_DATA(ch_bw);
 +	SET_CSI_DATA(rssi);
 +	SET_CSI_DATA(snr);
 +	SET_CSI_DATA(data_num);
 +	SET_CSI_DATA(data_bw);
 +	SET_CSI_DATA(pri_ch_idx);
-+	SET_CSI_DATA(info);
++	SET_CSI_DATA(ext_info);
 +	SET_CSI_DATA(rx_mode);
-+	SET_CSI_DATA(h_idx);
++	SET_CSI_DATA(chain_info);
 +	SET_CSI_DATA(ts);
 +
++	if (is_mt798x(&dev->mt76) || is_mt7916(&dev->mt76)) {
++		SET_CSI_DATA(segment_num);
++		SET_CSI_DATA(remain_last);
++		SET_CSI_DATA(pkt_sn);
++		SET_CSI_DATA(tr_stream);
++	}
++
 +	SET_CSI_DATA(band);
-+	if (csi->band && !phy->mt76->band_idx)
++	if (current_csi->band && !phy->mt76->band_idx)
 +		phy = mt7915_ext_phy(dev);
 +#undef SET_CSI_DATA
 +
-+	for (i = 0; i < csi->data_num; i++) {
-+		csi->data_i[i] = le16_to_cpu(cr->data_i[i]);
-+		csi->data_q[i] = le16_to_cpu(cr->data_q[i]);
++	switch (current_csi->ch_bw) {
++	case CSI_BW20:
++		if (is_mt798x(&dev->mt76) || is_mt7916(&dev->mt76))
++			current_csi->data_num = CSI_BW20_DATA_COUNT;
++		break;
++	case CSI_BW40:
++		if (is_mt798x(&dev->mt76) || is_mt7916(&dev->mt76))
++			current_csi->data_num = CSI_BW40_DATA_COUNT;
++		break;
++	default:
++		break;
 +	}
 +
++	for (i = 0; i < current_csi->data_num; i++) {
++		current_csi->data_i[i] = le16_to_cpu(cr->data_i[i]);
++		current_csi->data_q[i] = le16_to_cpu(cr->data_q[i]);
++	}
++
++	memcpy(current_csi->ta, cr->ta, ETH_ALEN);
++	current_csi->tx_idx = le32_get_bits(cr->trx_idx, GENMASK(31, 16));
++	current_csi->rx_idx = le32_get_bits(cr->trx_idx, GENMASK(15, 0));
++
-+	memcpy(csi->ta, cr->ta, ETH_ALEN);
-+	csi->tx_idx = le32_get_bits(cr->trx_idx, GENMASK(31, 16));
-+	csi->rx_idx = le32_get_bits(cr->trx_idx, GENMASK(15, 0));
++	/* integret the bw80 segment */
++	if ((is_mt798x(&dev->mt76) || is_mt7916(&dev->mt76)) && current_csi->ch_bw >= CSI_BW80) {
++		ret = csi_integret_segment_data(phy, current_csi);
 +
-+	INIT_LIST_HEAD(&csi->node);
++		/* event data error or event drop */
++		if (ret == CSI_CHAIN_ERR || ret == CSI_CHAIN_SEGMENT_ERR) {
++			kfree(current_csi);
++			return -EINVAL;
++		}
++
++		if (ret == CSI_CHAIN_SEGMENT_FIRST || ret == CSI_CHAIN_SEGMENT_MIDDLE) {
++			kfree(current_csi);
++			return 0;
++		} else if (ret == CSI_CHAIN_COMPLETE) {
++			target_csi = current_csi;
++		} else if (ret == CSI_CHAIN_SEGMENT_LAST) {
++			target_csi = current_csi;
++			memcpy(target_csi, &phy->csi.buffered_csi, sizeof(struct csi_data));
++			memset(&phy->csi.buffered_csi, 0, sizeof(struct csi_data));
++		}
++	} else {
++		target_csi = current_csi;
++	}
++
++	/* put the csi data into list */
++	INIT_LIST_HEAD(&target_csi->node);
 +	spin_lock_bh(&phy->csi.csi_lock);
 +
 +	if (!phy->csi.enable) {
-+		kfree(csi);
++		kfree(target_csi);
 +		spin_unlock_bh(&phy->csi.csi_lock);
 +		return 0;
 +	}
 +
-+	list_add_tail(&csi->node, &phy->csi.csi_list);
++	list_add_tail(&target_csi->node, &phy->csi.csi_list);
 +	phy->csi.count++;
 +
 +	if (phy->csi.count > CSI_MAX_BUF_NUM) {
@@ -256,8 +363,8 @@
 +		phy->csi.count--;
 +	}
 +
-+	if (csi->h_idx & BIT(15)) /* last chain */
-+		phy->csi.last_record = csi->ts;
++	if (target_csi->chain_info & BIT(15)) /* last chain */
++		phy->csi.last_record = target_csi->ts;
 +	spin_unlock_bh(&phy->csi.csi_lock);
 +
 +	return 0;
@@ -268,10 +375,10 @@
  int mt7915_dbg_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3, bool wait_resp)
  {
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index dd3b506..67eac5c 100644
+index dd3b506..09aa7ec 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
-@@ -589,4 +589,81 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
+@@ -589,4 +589,78 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
  enum {
  	MCU_GET_TX_RATE = 4
  };
@@ -284,7 +391,9 @@
 +	u8 v1;
 +	__le32 v2;
 +	u8 mac_addr[ETH_ALEN];
-+	u8 _rsv[34];
++	u8 _rsv1[2];
++	u32 sta_interval;
++	u8 _rsv2[28];
 +} __packed;
 +
 +struct csi_tlv {
@@ -292,7 +401,6 @@
 +	__le32 len;
 +} __packed;
 +
-+#define CSI_MAX_COUNT	256
 +#define CSI_MAX_BUF_NUM	3000
 +
 +struct mt7915_mcu_csi_report {
@@ -309,9 +417,9 @@
 +	struct csi_tlv _t5;
 +	__le32 data_num;
 +	struct csi_tlv _t6;
-+	__le16 data_i[CSI_MAX_COUNT];
++	__le16 data_i[CSI_BW80_DATA_COUNT];
 +	struct csi_tlv _t7;
-+	__le16 data_q[CSI_MAX_COUNT];
++	__le16 data_q[CSI_BW80_DATA_COUNT];
 +	struct csi_tlv _t8;
 +	__le32 data_bw;
 +	struct csi_tlv _t9;
@@ -319,22 +427,62 @@
 +	struct csi_tlv _t10;
 +	u8 ta[8];
 +	struct csi_tlv _t11;
-+	__le32 info;
++	__le32 ext_info;
 +	struct csi_tlv _t12;
 +	__le32 rx_mode;
 +	struct csi_tlv _t17;
-+	__le32 h_idx;
++	__le32 chain_info;
 +	struct csi_tlv _t18;
 +	__le32 trx_idx;
 +	struct csi_tlv _t19;
 +	__le32 ts;
++	struct csi_tlv _t20;
++	__le32 pkt_sn;
++	struct csi_tlv _t21;
++	__le32 segment_num;
++	struct csi_tlv _t22;
++	__le32 remain_last;
++	struct csi_tlv _t23;
++	__le32 tr_stream;
 +} __packed;
 +
++enum CSI_CHAIN_TYPE {
++	CSI_CHAIN_ERR,
++	CSI_CHAIN_COMPLETE,
++	CSI_CHAIN_SEGMENT_FIRST,
++	CSI_CHAIN_SEGMENT_MIDDLE,
++	CSI_CHAIN_SEGMENT_LAST,
++	CSI_CHAIN_SEGMENT_ERR,
++};
++#endif
++
+ #endif
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 887c4a5..475fcf7 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -195,6 +195,45 @@ struct mt7915_hif {
+ 	int irq;
+ };
+ 
++#ifdef CONFIG_MTK_VENDOR
++enum csi_bw {
++	CSI_BW20,
++	CSI_BW40,
++	CSI_BW80,
++	CSI_BW160
++};
++
++#define CSI_BW20_DATA_COUNT	64
++#define CSI_BW40_DATA_COUNT	128
++#define CSI_BW80_DATA_COUNT	256
++#define CSI_BW160_DATA_COUNT	512
++
 +struct csi_data {
 +	u8 ch_bw;
 +	u16 data_num;
-+	s16 data_i[CSI_MAX_COUNT];
-+	s16 data_q[CSI_MAX_COUNT];
++	s16 data_i[CSI_BW160_DATA_COUNT];
++	s16 data_q[CSI_BW160_DATA_COUNT];
 +	u8 band;
 +	s8 rssi;
 +	u8 snr;
@@ -342,22 +490,24 @@
 +	u8 data_bw;
 +	u8 pri_ch_idx;
 +	u8 ta[ETH_ALEN];
-+	u32 info;
++	u32 ext_info;
 +	u8 rx_mode;
-+	u32 h_idx;
++	u32 chain_info;
 +	u16 tx_idx;
 +	u16 rx_idx;
++	u32 segment_num;
++	u8 remain_last;
++	u16 pkt_sn;
++	u8 tr_stream;
 +
 +	struct list_head node;
 +};
 +#endif
 +
- #endif
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 887c4a5..6a96996 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -243,6 +243,20 @@ struct mt7915_phy {
+ struct mt7915_phy {
+ 	struct mt76_phy *mt76;
+ 	struct mt7915_dev *dev;
+@@ -243,6 +282,21 @@ struct mt7915_phy {
  		u8 spe_idx;
  	} test;
  #endif
@@ -365,12 +515,13 @@
 +#ifdef CONFIG_MTK_VENDOR
 +	struct {
 +		struct list_head csi_list;
-+		spinlock_t csi_lock;
++		spinlock_t csi_lock; /* used for csi data push/pop */
 +		u32 count;
 +		bool mask;
 +		bool reorder;
 +		bool enable;
 +
++		struct csi_data buffered_csi;
 +		u32 interval;
 +		u32 last_record;
 +	} csi;
@@ -378,14 +529,14 @@
  };
  
  struct mt7915_dev {
-@@ -624,6 +638,12 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -624,6 +678,12 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  			 bool pci, int *irq);
  
 +#ifdef CONFIG_MTK_VENDOR
 +void mt7915_vendor_register(struct mt7915_phy *phy);
 +int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
-+			u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
++		       u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval);
 +#endif
 +
  #ifdef MTK_DEBUG
@@ -393,10 +544,10 @@
  int mt7915_dbg_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3, bool wait_resp);
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
 new file mode 100644
-index 0000000..98fd9c2
+index 0000000..55da60a
 --- /dev/null
 +++ b/mt7915/vendor.c
-@@ -0,0 +1,452 @@
+@@ -0,0 +1,470 @@
 +// SPDX-License-Identifier: ISC
 +/*
 + * Copyright (C) 2020, MediaTek Inc. All rights reserved.
@@ -417,6 +568,7 @@
 +	[MTK_VENDOR_ATTR_CSI_CTRL_CFG_VAL2] = { .type = NLA_U8 },
 +	[MTK_VENDOR_ATTR_CSI_CTRL_MAC_ADDR] = { .type = NLA_NESTED },
 +	[MTK_VENDOR_ATTR_CSI_CTRL_INTERVAL] = { .type = NLA_U32 },
++	[MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL] = { .type = NLA_U32 },
 +	[MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM] = { .type = NLA_U16 },
 +	[MTK_VENDOR_ATTR_CSI_CTRL_DATA] = { .type = NLA_NESTED },
 +};
@@ -426,7 +578,7 @@
 +	u8 end;
 +};
 +
-+struct csi_reorder{
++struct csi_reorder {
 +	u8 dest;
 +	u8 start;
 +	u8 end;
@@ -591,14 +743,20 @@
 +	if (err)
 +		return err;
 +
++	if (is_mt7915(phy->mt76->dev) && phy->mt76->chandef.width > NL80211_CHAN_WIDTH_80) {
++		err = -EINVAL;
++		return err;
++	}
++
 +	if (tb[MTK_VENDOR_ATTR_CSI_CTRL_CFG]) {
 +		u8 mode = 0, type = 0, v1 = 0, v2 = 0;
 +		u8 mac_addr[ETH_ALEN] = {};
 +		struct nlattr *cur;
 +		int rem;
++		u32 sta_interval = 0;
 +
 +		nla_for_each_nested(cur, tb[MTK_VENDOR_ATTR_CSI_CTRL_CFG], rem) {
-+			switch(nla_type(cur)) {
++			switch (nla_type(cur)) {
 +			case MTK_VENDOR_ATTR_CSI_CTRL_CFG_MODE:
 +				mode = nla_get_u8(cur);
 +				break;
@@ -622,9 +780,17 @@
 +			nla_for_each_nested(cur, tb[MTK_VENDOR_ATTR_CSI_CTRL_MAC_ADDR], rem) {
 +				mac_addr[idx++] = nla_get_u8(cur);
 +			}
++
++			/* when configure mac filter, add interval for report interval per sta */
++			if (tb[MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL])
++				sta_interval =
++					nla_get_u32(tb[MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL]);
 +		}
 +
-+		mt7915_mcu_set_csi(phy, mode, type, v1, v2, mac_addr);
++		err = mt7915_mcu_set_csi(phy, mode, type, v1, v2, mac_addr, sta_interval);
++
++		if (err < 0)
++			return err;
 +
 +		spin_lock_bh(&phy->csi.csi_lock);
 +
@@ -792,27 +958,30 @@
 +		    nla_put_u16(skb, MTK_VENDOR_ATTR_CSI_DATA_RX_ANT, csi->rx_idx))
 +			goto out;
 +
-+		if (nla_put_u32(skb, MTK_VENDOR_ATTR_CSI_DATA_INFO, csi->info) ||
-+		    nla_put_u32(skb, MTK_VENDOR_ATTR_CSI_DATA_H_IDX, csi->h_idx) ||
++		if (nla_put_u32(skb, MTK_VENDOR_ATTR_CSI_DATA_INFO, csi->ext_info) ||
++		    nla_put_u32(skb, MTK_VENDOR_ATTR_CSI_DATA_CHAIN_INFO, csi->chain_info) ||
 +		    nla_put_u32(skb, MTK_VENDOR_ATTR_CSI_DATA_TS, csi->ts))
 +			goto out;
 +
 +		b = nla_nest_start(skb, MTK_VENDOR_ATTR_CSI_DATA_TA);
-+			for (i = 0; i < ARRAY_SIZE(csi->ta); i++)
-+				if (nla_put_u8(skb, i, csi->ta[i]))
-+					goto out;
++		for (i = 0; i < ARRAY_SIZE(csi->ta); i++)
++			if (nla_put_u8(skb, i, csi->ta[i]))
++				goto out;
 +		nla_nest_end(skb, b);
 +
++		if (nla_put_u32(skb, MTK_VENDOR_ATTR_CSI_DATA_NUM, csi->data_num))
++			goto out;
++
 +		b = nla_nest_start(skb, MTK_VENDOR_ATTR_CSI_DATA_I);
-+			for (i = 0; i < ARRAY_SIZE(csi->data_i); i++)
-+				if (nla_put_u16(skb, i, csi->data_i[i]))
-+					goto out;
++		for (i = 0; i < csi->data_num; i++)
++			if (nla_put_u16(skb, i, csi->data_i[i]))
++				goto out;
 +		nla_nest_end(skb, b);
 +
 +		b = nla_nest_start(skb, MTK_VENDOR_ATTR_CSI_DATA_Q);
-+			for (i = 0; i < ARRAY_SIZE(csi->data_q); i++)
-+				if (nla_put_u16(skb, i, csi->data_q[i]))
-+					goto out;
++		for (i = 0; i < csi->data_num; i++)
++			if (nla_put_u16(skb, i, csi->data_q[i]))
++				goto out;
 +		nla_nest_end(skb, b);
 +
 +		nla_nest_end(skb, a);
@@ -851,10 +1020,11 @@
 +}
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
 new file mode 100644
-index 0000000..9d3db2a
+index 0000000..e1f5fd3
 --- /dev/null
 +++ b/mt7915/vendor.h
-@@ -0,0 +1,60 @@
+@@ -0,0 +1,63 @@
++/* SPDX-License-Identifier: ISC */
 +#ifndef __MT7915_VENDOR_H
 +#define __MT7915_VENDOR_H
 +
@@ -874,6 +1044,7 @@
 +	MTK_VENDOR_ATTR_CSI_CTRL_CFG_VAL2,
 +	MTK_VENDOR_ATTR_CSI_CTRL_MAC_ADDR,
 +	MTK_VENDOR_ATTR_CSI_CTRL_INTERVAL,
++	MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL,
 +
 +	MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM,
 +
@@ -896,6 +1067,7 @@
 +	MTK_VENDOR_ATTR_CSI_DATA_BW,
 +	MTK_VENDOR_ATTR_CSI_DATA_CH_IDX,
 +	MTK_VENDOR_ATTR_CSI_DATA_TA,
++	MTK_VENDOR_ATTR_CSI_DATA_NUM,
 +	MTK_VENDOR_ATTR_CSI_DATA_I,
 +	MTK_VENDOR_ATTR_CSI_DATA_Q,
 +	MTK_VENDOR_ATTR_CSI_DATA_INFO,
@@ -906,7 +1078,7 @@
 +	MTK_VENDOR_ATTR_CSI_DATA_TX_ANT,
 +	MTK_VENDOR_ATTR_CSI_DATA_RX_ANT,
 +	MTK_VENDOR_ATTR_CSI_DATA_MODE,
-+	MTK_VENDOR_ATTR_CSI_DATA_H_IDX,
++	MTK_VENDOR_ATTR_CSI_DATA_CHAIN_INFO,
 +
 +	/* keep last */
 +	NUM_MTK_VENDOR_ATTRS_CSI_DATA,
diff --git a/recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch b/recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch
index cd80105..03e2bbf 100644
--- a/recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch
@@ -1,22 +1,22 @@
-From 9887703630f6949fffbbca476a121a38afc2d558 Mon Sep 17 00:00:00 2001
+From 868bd53b53d3885f8ad99198528d7f6abd8ac109 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Tue, 11 Jan 2022 12:03:23 +0800
-Subject: [PATCH 1002/1040] wifi: mt76: mt7915: air monitor support
+Subject: [PATCH 14/76] wifi: mt76: mt7915: air monitor support
 
 ---
  mt76_connac_mcu.h |   2 +
  mt7915/mac.c      |   4 +
  mt7915/main.c     |   3 +
- mt7915/mt7915.h   |  34 +++++
+ mt7915/mt7915.h   |  32 ++++
  mt7915/vendor.c   | 361 ++++++++++++++++++++++++++++++++++++++++++++++
  mt7915/vendor.h   |  38 +++++
- 6 files changed, 442 insertions(+)
+ 6 files changed, 440 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 8a377dd..c1d9191 100644
+index b31f19a..b758679 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1208,6 +1208,8 @@ enum {
+@@ -1229,6 +1229,8 @@ enum {
  	MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
  	MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
@@ -26,7 +26,7 @@
  };
  
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 2650b87..f171e97 100644
+index d7b7e78..c0a390d 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -524,6 +524,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
@@ -41,10 +41,10 @@
  		status->flag |= RX_FLAG_8023;
  		mt7915_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
 diff --git a/mt7915/main.c b/mt7915/main.c
-index b4dfe4b..d667b44 100644
+index a4baa3d..7d15a40 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -772,6 +772,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -773,6 +773,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (ret)
  		return ret;
  
@@ -55,14 +55,14 @@
  }
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 6a96996..6192e81 100644
+index 475fcf7..8c83b9f 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -195,6 +195,35 @@ struct mt7915_hif {
- 	int irq;
- };
+@@ -232,6 +232,33 @@ struct csi_data {
  
-+#ifdef CONFIG_MTK_VENDOR
+ 	struct list_head node;
+ };
++
 +#define MT7915_AIR_MONITOR_MAX_ENTRY	16
 +#define MT7915_AIR_MONITOR_MAX_GROUP	MT7915_AIR_MONITOR_MAX_ENTRY >> 1
 +
@@ -89,12 +89,10 @@
 +	struct mt7915_air_monitor_group group[MT7915_AIR_MONITOR_MAX_GROUP];
 +	struct mt7915_air_monitor_entry entry[MT7915_AIR_MONITOR_MAX_ENTRY];
 +};
-+#endif
-+
+ #endif
+ 
  struct mt7915_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7915_dev *dev;
-@@ -256,6 +285,8 @@ struct mt7915_phy {
+@@ -296,6 +323,8 @@ struct mt7915_phy {
  		u32 interval;
  		u32 last_record;
  	} csi;
@@ -103,10 +101,10 @@
  #endif
  };
  
-@@ -642,6 +673,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -682,6 +711,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  void mt7915_vendor_register(struct mt7915_phy *phy);
  int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
- 			u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
+ 		       u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval);
 +void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
 +int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
 +				  struct ieee80211_sta *sta);
@@ -114,10 +112,10 @@
  
  #ifdef MTK_DEBUG
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 98fd9c2..43f9690 100644
+index 55da60a..c964b14 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
-@@ -430,6 +430,355 @@ out:
+@@ -448,6 +448,355 @@ out:
  	return err;
  }
  
@@ -473,7 +471,7 @@
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
  		.info = {
-@@ -442,6 +791,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -460,6 +809,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.dumpit = mt7915_vendor_csi_ctrl_dump,
  		.policy = csi_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_CSI_CTRL_MAX,
@@ -493,10 +491,10 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 9d3db2a..976817f 100644
+index e1f5fd3..1863eee 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
-@@ -4,6 +4,7 @@
+@@ -5,6 +5,7 @@
  #define MTK_NL80211_VENDOR_ID	0x0ce7
  
  enum mtk_nl80211_vendor_subcmds {
@@ -504,7 +502,7 @@
  	MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
  };
  
-@@ -57,4 +58,41 @@ enum mtk_vendor_attr_csi_data {
+@@ -60,4 +61,41 @@ enum mtk_vendor_attr_csi_data {
  		NUM_MTK_VENDOR_ATTRS_CSI_DATA - 1
  };
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch b/recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch
index 831ac6c..b3646c3 100644
--- a/recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch
@@ -1,17 +1,30 @@
-From 74fffd688572bd2f2f9633f0acb0da2dba249aa7 Mon Sep 17 00:00:00 2001
+From f0393af40ecc847516a78740eee53956ae8a4f13 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Tue, 4 Apr 2023 02:23:57 +0800
-Subject: [PATCH 1003/1040] wifi: mt76: mt7915: add support for muru_onoff via
+Subject: [PATCH] wifi: mt76: mt7915: add support for muru_onoff via
 
 ---
+ mt7915/init.c        |  1 +
  mt7915/mcu.c         | 10 ++++++++--
  mt7915/mcu.h         |  6 ++++++
  mt7915/mt7915.h      |  2 ++
  mt7915/mtk_debugfs.c | 33 +++++++++++++++++++++++++++++++++
- 4 files changed, 49 insertions(+), 2 deletions(-)
+ 5 files changed, 50 insertions(+), 2 deletions(-)
 
+diff --git a/mt7915/init.c b/mt7915/init.c
+index 46d9499..974dd34 100644
+--- a/mt7915/init.c
++++ b/mt7915/init.c
+@@ -363,6 +363,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+ 		IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
+ 
+ 	phy->slottime = 9;
++	phy->muru_onoff = OFDMA_DL | OFDMA_UL | MUMIMO_DL | MUMIMO_UL;
+ 
+ 	hw->sta_data_size = sizeof(struct mt7915_sta);
+ 	hw->vif_data_size = sizeof(struct mt7915_vif);
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 729a41d..66ec469 100644
+index d43b597..8c84b24 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -875,6 +875,7 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
@@ -72,7 +85,7 @@
  	struct mt76_channel_state state_ts;
  
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 275acc6..b7c54cc 100644
+index d7bbc59..803cabc 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -2556,6 +2556,38 @@ static int mt7915_token_txd_read(struct seq_file *s, void *data)
diff --git a/recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-certification-patches.patch b/recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-certification-patches.patch
index 34cfb64..a0f9cf2 100644
--- a/recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-certification-patches.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-certification-patches.patch
@@ -1,7 +1,7 @@
-From 2dcee575f60d16902ef7fc10fda827a9f389f61a Mon Sep 17 00:00:00 2001
+From 5b5f463212f00b4489d1c23f8e1a88f59c7cc7df Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Mon, 6 Jun 2022 20:15:51 +0800
-Subject: [PATCH] wifi: mt76: mt7915: certification patches
+Subject: [PATCH 16/76] wifi: mt76: mt7915: certification patches
 
 ---
  mt76_connac_mcu.h    |   1 +
@@ -16,10 +16,10 @@
  9 files changed, 955 insertions(+), 5 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index c1d9191..9b065f3 100644
+index b758679..c4f5a64 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1210,6 +1210,7 @@ enum {
+@@ -1231,6 +1231,7 @@ enum {
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
  	/* for vendor csi and air monitor */
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
@@ -28,7 +28,7 @@
  };
  
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index f171e97..8d1eeef 100644
+index c0a390d..2168387 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -8,6 +8,7 @@
@@ -76,7 +76,7 @@
  			       IEEE80211_RC_NSS_CHANGED |
  			       IEEE80211_RC_BW_CHANGED))
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 7c27897..0b6622e 100644
+index 3b33659..76d1cd7 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -748,6 +748,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -107,7 +107,7 @@
  
  void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 66ec469..92fa560 100644
+index 8c84b24..63a1292 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -4139,6 +4139,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
diff --git a/recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch b/recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch
index 92ce23e..aefe8bc 100644
--- a/recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch
@@ -1,8 +1,8 @@
-From e1fb54da7217b4c2c88666cf1b782669632a795c Mon Sep 17 00:00:00 2001
+From a49b1acefb6d57b8147a931edbbe77536f870d12 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Thu, 23 Mar 2023 09:55:50 +0800
-Subject: [PATCH 1005/1040] wifi: mt76: mt7915: add support for runtime set
- in-band discovery
+Subject: [PATCH 17/76] wifi: mt76: mt7915: add support for runtime set in-band
+ discovery
 
 Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
 ---
@@ -10,7 +10,7 @@
  1 file changed, 2 insertions(+), 3 deletions(-)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 92fa560..f2ab2e3 100644
+index 63a1292..95a5593 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -1940,8 +1940,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
diff --git a/recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch b/recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
index 5b0bacc..3e34d28 100644
--- a/recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
@@ -1,8 +1,7 @@
-From 1a9f08c9d8dfb8c2f1c06f8bd52d6e08c0df7e8d Mon Sep 17 00:00:00 2001
+From 7a1f1d03b9546d1b025637fcd8f36cd78ac2e429 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Tue, 4 Apr 2023 02:27:44 +0800
-Subject: [PATCH 1006/1040] wifi: mt76: mt7915: add mt76 vendor muru onoff
- command
+Subject: [PATCH 18/76] wifi: mt76: mt7915: add mt76 vendor muru onoff command
 
 ---
  mt7915/mcu.c    |  7 +++++++
@@ -12,7 +11,7 @@
  4 files changed, 63 insertions(+)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index f2ab2e3..7b3c70e 100644
+index 95a5593..9bd9253 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -4158,6 +4158,13 @@ void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
@@ -42,7 +41,7 @@
  };
  
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 5a1cce1..df1cac3 100644
+index 19c9e71..6fc88f9 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -34,6 +34,11 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -57,7 +56,7 @@
  static const struct nla_policy
  rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
  	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
-@@ -944,6 +949,33 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
+@@ -945,6 +950,33 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
  	return 0;
  }
  
@@ -91,7 +90,7 @@
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
  		.info = {
-@@ -990,6 +1022,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -991,6 +1023,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.doit = mt7915_vendor_wireless_ctrl,
  		.policy = wireless_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX,
diff --git a/recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-mt7915-drop-undefined-action-frame.patch b/recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-mt7915-drop-undefined-action-frame.patch
index a08e7de..4248bc6 100644
--- a/recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-mt7915-drop-undefined-action-frame.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-mt7915-drop-undefined-action-frame.patch
@@ -1,14 +1,14 @@
-From 86b11ceef3db1601919f54f5cc73b3e301094223 Mon Sep 17 00:00:00 2001
+From cec905b3ba5574b56cddde6ec5fca32990290336 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Thu, 14 Apr 2022 15:18:02 +0800
-Subject: [PATCH 1007/1040] wifi: mt76: mt7915: drop undefined action frame
+Subject: [PATCH 19/76] wifi: mt76: mt7915: drop undefined action frame
 
 ---
  mt7915/mac.c | 6 ++++++
  1 file changed, 6 insertions(+)
 
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 8d1eeef..f1c78ec 100644
+index 2168387..6047121 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -737,6 +737,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
diff --git a/recipes-wifi/linux-mt76/files/patches/1008-wifi-mt76-testmode-rework-testmode-init-registers.patch b/recipes-wifi/linux-mt76/files/patches/1008-wifi-mt76-testmode-rework-testmode-init-registers.patch
index 1ad2d4a..37f9bd0 100644
--- a/recipes-wifi/linux-mt76/files/patches/1008-wifi-mt76-testmode-rework-testmode-init-registers.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1008-wifi-mt76-testmode-rework-testmode-init-registers.patch
@@ -1,8 +1,7 @@
-From db7a7f8f00bf19913b153a377a7808900bafeb20 Mon Sep 17 00:00:00 2001
+From 88ebb3ad1cef268dd72f9e1892ef58bdb6b94a93 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Mon, 6 Jun 2022 19:46:26 +0800
-Subject: [PATCH 1008/1040] wifi: mt76: testmode: rework testmode init
- registers
+Subject: [PATCH 20/76] wifi: mt76: testmode: rework testmode init registers
 
 ---
  mac80211.c        |   3 +-
@@ -18,10 +17,10 @@
  10 files changed, 164 insertions(+), 35 deletions(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index 647f74c..430ed1c 100644
+index 259b448..432bc40 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -793,7 +793,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
+@@ -804,7 +804,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
  	}
  
  #ifdef CONFIG_NL80211_TESTMODE
@@ -32,10 +31,10 @@
  		if (status->flag & RX_FLAG_FAILED_FCS_CRC)
  			phy->test.rx_stats.fcs_error[q]++;
 diff --git a/mt76.h b/mt76.h
-index 97ced84..d66f4d0 100644
+index c644647..2244ab5 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -672,6 +672,8 @@ struct mt76_testmode_ops {
+@@ -706,6 +706,8 @@ struct mt76_testmode_ops {
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
  };
  
@@ -44,7 +43,7 @@
  struct mt76_testmode_data {
  	enum mt76_testmode_state state;
  
-@@ -703,6 +705,8 @@ struct mt76_testmode_data {
+@@ -737,6 +739,8 @@ struct mt76_testmode_data {
  
  	u8 addr[3][ETH_ALEN];
  
@@ -53,7 +52,7 @@
  	u32 tx_pending;
  	u32 tx_queued;
  	u16 tx_queued_limit;
-@@ -710,6 +714,7 @@ struct mt76_testmode_data {
+@@ -744,6 +748,7 @@ struct mt76_testmode_data {
  	struct {
  		u64 packets[__MT_RXQ_MAX];
  		u64 fcs_error[__MT_RXQ_MAX];
@@ -62,10 +61,10 @@
  };
  
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 9b065f3..cb68141 100644
+index c4f5a64..d4254be 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1204,6 +1204,7 @@ enum {
+@@ -1225,6 +1225,7 @@ enum {
  	MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
  	MCU_EXT_CMD_SET_RDD_TH = 0x9d,
  	MCU_EXT_CMD_MURU_CTRL = 0x9f,
@@ -86,7 +85,7 @@
  	MCU_ATE_CLEAN_TXQUEUE = 0x1c,
  };
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 10f4e66..10c2c7d 100644
+index bd9e01d..0fd1a34 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -120,6 +120,7 @@ static const u32 mt7986_reg[] = {
diff --git a/recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-additional-supports.patch b/recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-additional-supports.patch
index 9f92153..fc2c244 100644
--- a/recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-additional-supports.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-additional-supports.patch
@@ -1,7 +1,7 @@
-From e7c6d49d0b5582ba7cb37d9d844a341b18c5a393 Mon Sep 17 00:00:00 2001
+From c568828715236c265d20d3791948041cb23de480 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 21 Apr 2022 15:43:19 +0800
-Subject: [PATCH 1009/1042] wifi: mt76: testmode: additional supports
+Subject: [PATCH 21/76] wifi: mt76: testmode: additional supports
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -22,17 +22,17 @@
  mt7915/regs.h     |    3 +
  mt7915/testmode.c | 1244 ++++++++++++++++++++++++++++++++++++++++++---
  mt7915/testmode.h |  278 ++++++++++
- testmode.c        |  287 +++++++++--
+ testmode.c        |  289 +++++++++--
  testmode.h        |   79 +++
  tools/fields.c    |   90 +++-
  tx.c              |    3 +-
- 20 files changed, 2063 insertions(+), 168 deletions(-)
+ 20 files changed, 2064 insertions(+), 169 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 24b44e7..8049830 100644
+index 9eb2b8f..d338424 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -576,8 +576,7 @@ free:
+@@ -615,8 +615,7 @@ free:
  	if (mt76_is_testmode_skb(dev, skb, &hw)) {
  		struct mt76_phy *phy = hw->priv;
  
@@ -43,7 +43,7 @@
  #endif
  
 diff --git a/mac80211.c b/mac80211.c
-index 430ed1c..fccf26d 100644
+index 432bc40..241621c 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -55,6 +55,13 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
@@ -73,10 +73,10 @@
  
  static const struct ieee80211_channel mt76_channels_6ghz[] = {
 diff --git a/mt76.h b/mt76.h
-index d66f4d0..597488d 100644
+index 2244ab5..7924cca 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -670,6 +670,21 @@ struct mt76_testmode_ops {
+@@ -704,6 +704,21 @@ struct mt76_testmode_ops {
  	int (*set_params)(struct mt76_phy *phy, struct nlattr **tb,
  			  enum mt76_testmode_state new_state);
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
@@ -98,7 +98,7 @@
  };
  
  #define MT_TM_FW_RX_COUNT	BIT(0)
-@@ -678,16 +693,13 @@ struct mt76_testmode_data {
+@@ -712,16 +727,13 @@ struct mt76_testmode_data {
  	enum mt76_testmode_state state;
  
  	u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)];
@@ -117,7 +117,7 @@
  	u8 tx_rate_stbc;
  	u8 tx_ltf;
  
-@@ -703,10 +715,37 @@ struct mt76_testmode_data {
+@@ -737,10 +749,37 @@ struct mt76_testmode_data {
  	u8 tx_power[4];
  	u8 tx_power_control;
  
@@ -156,7 +156,7 @@
  	u32 tx_pending;
  	u32 tx_queued;
  	u16 tx_queued_limit;
-@@ -1276,6 +1315,59 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
+@@ -1327,6 +1366,59 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
  #endif
  }
  
@@ -216,7 +216,7 @@
  static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
  					struct sk_buff *skb,
  					struct ieee80211_hw **hw)
-@@ -1286,7 +1378,8 @@ static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
+@@ -1337,7 +1429,8 @@ static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
  	for (i = 0; i < ARRAY_SIZE(dev->phys); i++) {
  		struct mt76_phy *phy = dev->phys[i];
  
@@ -226,7 +226,7 @@
  			*hw = dev->phys[i]->hw;
  			return true;
  		}
-@@ -1388,7 +1481,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1439,7 +1532,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
  		       struct netlink_callback *cb, void *data, int len);
  int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state);
@@ -237,10 +237,10 @@
  static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable)
  {
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index f06a81d..60e159c 100644
+index eea6831..69babba 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -396,6 +396,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -397,6 +397,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  	switch (vif->type) {
  	case NL80211_IFTYPE_MESH_POINT:
  	case NL80211_IFTYPE_AP:
@@ -248,7 +248,7 @@
  		if (vif->p2p && !is_mt7921(dev))
  			conn_type = CONNECTION_P2P_GC;
  		else
-@@ -577,6 +578,9 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
+@@ -578,6 +579,9 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
  	rx->rca2 = 1;
  	rx->rv = 1;
  
@@ -259,10 +259,10 @@
  		return;
  
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index cb68141..7a7dbf4 100644
+index d4254be..b61c195 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1002,6 +1002,7 @@ enum {
+@@ -1012,6 +1012,7 @@ enum {
  	MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
  	MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
  	MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
@@ -270,7 +270,7 @@
  	MCU_EXT_EVENT_RDD_REPORT = 0x3a,
  	MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
  	MCU_EXT_EVENT_WA_TX_STAT = 0x74,
-@@ -1211,6 +1212,7 @@ enum {
+@@ -1232,6 +1233,7 @@ enum {
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
  	/* for vendor csi and air monitor */
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
@@ -279,10 +279,10 @@
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
  };
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index 76be730..f5ab331 100644
+index 3bb2643..0441d91 100644
 --- a/mt7915/eeprom.c
 +++ b/mt7915/eeprom.c
-@@ -131,7 +131,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
+@@ -136,7 +136,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
  		/* read eeprom data from efuse */
  		block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size);
  		for (i = 0; i < block_num; i++) {
@@ -292,7 +292,7 @@
  				return ret;
  		}
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 607d881..d908a58 100644
+index 46d9499..db61953 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
 @@ -725,7 +725,7 @@ static void mt7915_init_work(struct work_struct *work)
@@ -305,7 +305,7 @@
  	mt7915_txbf_init(dev);
  }
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index f1c78ec..06a5fb1 100644
+index 6047121..d3b4a60 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -579,6 +579,7 @@ mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
@@ -395,7 +395,7 @@
  		goto out;
  
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 0b6622e..44a1b21 100644
+index 76d1cd7..7124e18 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -238,7 +238,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
@@ -408,7 +408,7 @@
  		mvif->mt76.wmm_idx += 2;
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 7b3c70e..0d1e09c 100644
+index 9bd9253..8288589 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -391,6 +391,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
@@ -547,7 +547,7 @@
  
  enum {
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 10c2c7d..87a5c5c 100644
+index 0fd1a34..c0cf8fb 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -134,6 +134,7 @@ static const u32 mt7915_offs[] = {
@@ -2417,7 +2417,7 @@
 +
  #endif
 diff --git a/testmode.c b/testmode.c
-index 1b37392..b39fef4 100644
+index 1b37392..bc7f0b5 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -8,6 +8,7 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
@@ -2601,7 +2601,7 @@
  			dev_kfree_skb(head);
  			return -ENOMEM;
  		}
-@@ -167,15 +228,14 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+@@ -167,23 +228,22 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
  		frag_tail = &(*frag_tail)->next;
  	}
  
@@ -2621,8 +2621,9 @@
  {
  	struct mt76_testmode_data *td = &phy->test;
  	struct ieee80211_tx_info *info;
-@@ -183,7 +243,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
- 	u8 max_nss = hweight8(phy->antenna_mask);
+ 	struct ieee80211_tx_rate *rate;
+-	u8 max_nss = hweight8(phy->antenna_mask);
++	u8 max_nss = hweight8(phy->chainmask);
  	int ret;
  
 -	ret = mt76_testmode_alloc_skb(phy, td->tx_mpdu_len);
diff --git a/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-add-pre-cal-support.patch b/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-add-pre-cal-support.patch
index f789822..670097d 100644
--- a/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-add-pre-cal-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-add-pre-cal-support.patch
@@ -1,7 +1,7 @@
-From c1b540f4e8ec1de754a3325f1f7abe8099108309 Mon Sep 17 00:00:00 2001
+From 824fba94e1bc5a00182da6e1bad32795c4b85882 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 31 Aug 2022 20:06:52 +0800
-Subject: [PATCH] wifi: mt76: testmode: add pre-cal support
+Subject: [PATCH 22/76] wifi: mt76: testmode: add pre-cal support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -19,10 +19,10 @@
  11 files changed, 562 insertions(+), 13 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index ff8dc939..9b637992 100644
+index a267397..3625b16 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -94,8 +94,10 @@ static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offs
+@@ -94,8 +94,10 @@ int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int l
  	}
  
  #ifdef CONFIG_NL80211_TESTMODE
@@ -36,10 +36,10 @@
  
  out_put_node:
 diff --git a/mt76.h b/mt76.h
-index 597488db..66495b17 100644
+index 7924cca..f43cb53 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -671,6 +671,7 @@ struct mt76_testmode_ops {
+@@ -705,6 +705,7 @@ struct mt76_testmode_ops {
  			  enum mt76_testmode_state new_state);
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
  	int (*set_eeprom)(struct mt76_phy *phy, u32 offset, u8 *val, u8 action);
@@ -48,10 +48,10 @@
  
  struct mt76_testmode_entry_data {
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 7a7dbf48..a6449d1c 100644
+index b61c195..964ee53 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -998,6 +998,7 @@ enum {
+@@ -1008,6 +1008,7 @@ enum {
  
  /* ext event table */
  enum {
@@ -60,7 +60,7 @@
  	MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
  	MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
 diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h
-index f3e56817..88aaa16a 100644
+index adc26a2..25f0b32 100644
 --- a/mt7915/eeprom.h
 +++ b/mt7915/eeprom.h
 @@ -39,10 +39,18 @@ enum mt7915_eeprom_field {
@@ -85,7 +85,7 @@
  
  #define MT_EE_WIFI_CONF0_TX_PATH		GENMASK(2, 0)
  #define MT_EE_WIFI_CONF0_BAND_SEL		GENMASK(7, 6)
-@@ -155,6 +163,26 @@ mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
+@@ -156,6 +164,26 @@ mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
  		return val & MT_EE_WIFI_CONF7_TSSI0_5G;
  }
  
@@ -113,7 +113,7 @@
  
  #endif
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 0d1e09c3..474bed1b 100644
+index 8288589..19e88b0 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -395,6 +395,9 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
@@ -168,7 +168,7 @@
  
  	idx = mt7915_dpd_freq_idx(center_freq, chandef->width);
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index b91af946..ce128ab5 100644
+index b91af94..ce128ab 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -359,6 +359,10 @@ struct mt7915_dev {
@@ -191,7 +191,7 @@
  static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
  {
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 83672046..3a4516ef 100644
+index 32dc85c..4b34430 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -5,6 +5,7 @@
@@ -202,7 +202,7 @@
  
  enum {
  	TM_CHANGED_TXPOWER,
-@@ -1602,18 +1603,16 @@ mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper)
+@@ -1604,18 +1605,16 @@ mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper)
  static int
  mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
  {
@@ -223,7 +223,7 @@
  		.icap_len = 120,
  		.op.rf.func_idx = cpu_to_le32(func_idx),
  	};
-@@ -1698,6 +1697,316 @@ out:
+@@ -1700,6 +1699,316 @@ out:
  				 sizeof(req), true);
  }
  
@@ -540,7 +540,7 @@
  static void
  mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
  {
-@@ -1746,6 +2055,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -1750,6 +2059,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
  	else if (prev_state == MT76_TM_STATE_OFF ||
  		 state == MT76_TM_STATE_OFF)
  		mt7915_tm_init(phy, !(state == MT76_TM_STATE_OFF));
@@ -551,7 +551,7 @@
  
  	if ((state == MT76_TM_STATE_IDLE &&
  	     prev_state == MT76_TM_STATE_OFF) ||
-@@ -1926,9 +2239,113 @@ mt7915_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
+@@ -1930,9 +2243,113 @@ mt7915_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
  	return ret;
  }
  
@@ -666,7 +666,7 @@
 +	.dump_precal = mt7915_tm_dump_precal,
  };
 diff --git a/mt7915/testmode.h b/mt7915/testmode.h
-index eb0e0432..75698261 100644
+index eb0e043..7569826 100644
 --- a/mt7915/testmode.h
 +++ b/mt7915/testmode.h
 @@ -81,6 +81,11 @@ struct tm_tx_cont {
@@ -734,7 +734,7 @@
  	TAM_ARB_OP_MODE_NORMAL = 1,
  	TAM_ARB_OP_MODE_TEST,
 diff --git a/testmode.c b/testmode.c
-index b39fef4f..26e2de24 100644
+index bc7f0b5..3f108e4 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -771,6 +771,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
@@ -767,7 +767,7 @@
  
  	if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
 diff --git a/testmode.h b/testmode.h
-index 7a686250..e4c1b521 100644
+index 7a68625..e4c1b52 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -19,6 +19,7 @@
@@ -823,7 +823,7 @@
  
  	/* keep last */
 diff --git a/tools/fields.c b/tools/fields.c
-index 406ba77c..27801dbe 100644
+index 406ba77..27801db 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -11,6 +11,14 @@ static const char * const testmode_state[] = {
diff --git a/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-iBF-command-mode-support.patch b/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-iBF-command-mode-support.patch
index b476e79..e9fd3aa 100644
--- a/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-iBF-command-mode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-iBF-command-mode-support.patch
@@ -1,7 +1,7 @@
-From bc3169129e2978e3ec2e1a630023a30e78d18237 Mon Sep 17 00:00:00 2001
+From b9f52cadd2e44becb966867882ba9533b7500698 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 12 Sep 2022 18:16:54 +0800
-Subject: [PATCH 1011/1040] wifi: mt76: testmode: add iBF command mode support
+Subject: [PATCH 23/76] wifi: mt76: testmode: add iBF command mode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,10 +12,10 @@
  4 files changed, 85 insertions(+), 7 deletions(-)
 
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 5ff183a..86deae6 100644
+index 4b34430..453319e 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
-@@ -720,6 +720,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
+@@ -722,6 +722,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
  	struct ieee80211_vif *vif = phy->monitor_vif;
  	struct mt7915_tm_pfmu_tag *tag = phy->dev->test.txbf_pfmu_tag;
  	u8 pfmu_idx = val[0], nc = val[2], nr;
@@ -23,7 +23,7 @@
  	int ret;
  
  	if (td->tx_antenna_mask == 3)
-@@ -767,7 +768,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
+@@ -769,7 +770,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
  	if (ret)
  		return ret;
  
@@ -32,7 +32,7 @@
  		return mt7915_tm_txbf_apply_tx(phy, 1, false, true, true);
  
  	return 0;
-@@ -794,7 +795,7 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
+@@ -796,7 +797,7 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
  		.group_l_m_n = val[1],
  		.sx2 = val[2],
  		.cal_type = val[3],
@@ -41,7 +41,7 @@
  	};
  	struct mt7915_tm_txbf_phase *phase =
  		(struct mt7915_tm_txbf_phase *)dev->test.txbf_phase_cal;
-@@ -833,6 +834,8 @@ int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -835,6 +836,8 @@ int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb)
  			phase = &phase[cal->group];
  			memcpy(&phase->phase, cal->buf + 16, sizeof(phase->phase));
  			phase->status = cal->status;
@@ -50,7 +50,7 @@
  			break;
  		case IBF_PHASE_CAL_VERIFY:
  		case IBF_PHASE_CAL_VERIFY_INSTRUMENT:
-@@ -885,7 +888,6 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
+@@ -887,7 +890,6 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
  	pfmu_data->phi11 = cpu_to_le16(phi11);
  	pfmu_data->phi21 = cpu_to_le16(phi21);
  	pfmu_data->phi31 = cpu_to_le16(phi31);
@@ -58,7 +58,7 @@
  	if (subc_id == 63) {
  		struct mt7915_dev *dev = phy->dev;
  		struct {
-@@ -943,8 +945,8 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -945,8 +947,8 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
  	struct mt76_testmode_data *td = &phy->mt76->test;
  	u16 *val = td->txbf_param;
  
@@ -69,7 +69,7 @@
  
  	switch (td->txbf_act) {
  	case MT76_TM_TXBF_ACT_INIT:
-@@ -962,10 +964,17 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -964,10 +966,17 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
  		return mt7915_tm_txbf_profile_update(phy, val, true);
  	case MT76_TM_TXBF_ACT_PHASE_CAL:
  		return mt7915_tm_txbf_phase_cal(phy, val);
@@ -87,7 +87,7 @@
  	default:
  		break;
  	};
-@@ -1092,7 +1101,6 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
+@@ -1094,7 +1103,6 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
  		rate.legacy = sband->bitrates[rate.mcs].bitrate;
  		break;
  	case MT76_TM_TX_MODE_HT:
@@ -95,7 +95,7 @@
  		flags |= RATE_INFO_FLAGS_MCS;
  
  		if (td->tx_rate_sgi)
-@@ -1457,7 +1465,6 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1461,7 +1469,6 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
  			if (duty_cycle < 100)
  				tx_time = duty_cycle * ipg / (100 - duty_cycle);
  		}
@@ -104,10 +104,10 @@
  		mt7915_tm_set_tx_len(phy, tx_time);
  
 diff --git a/testmode.c b/testmode.c
-index b1b643c..f415bec 100644
+index 3f108e4..898ef3a 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -534,6 +534,42 @@ out:
+@@ -535,6 +535,42 @@ out:
  	return err;
  }
  
@@ -150,7 +150,7 @@
  int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		      void *data, int len)
  {
-@@ -672,6 +708,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -676,6 +712,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  				   0, MT76_TM_TXBF_ACT_MAX))
  			goto out;
  
@@ -163,10 +163,10 @@
  		nla_for_each_nested(cur, tb[MT76_TM_ATTR_TXBF_PARAM], rem) {
  			if (nla_len(cur) != 2 ||
 diff --git a/testmode.h b/testmode.h
-index 109a556..d2675dd 100644
+index e4c1b52..1d7aef8 100644
 --- a/testmode.h
 +++ b/testmode.h
-@@ -281,8 +281,10 @@ enum mt76_testmode_txbf_act {
+@@ -285,8 +285,10 @@ enum mt76_testmode_txbf_act {
  	MT76_TM_TXBF_ACT_TX_PREP,
  	MT76_TM_TXBF_ACT_IBF_PROF_UPDATE,
  	MT76_TM_TXBF_ACT_EBF_PROF_UPDATE,
@@ -178,7 +178,7 @@
  
  	/* keep last */
 diff --git a/tools/fields.c b/tools/fields.c
-index 3ca5cd1..6bf4c04 100644
+index 27801db..b0ee84d 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -32,6 +32,20 @@ static const char * const testmode_tx_mode[] = {
@@ -220,7 +220,7 @@
  static bool parse_u32(const struct tm_field *field, int idx,
  		      struct nl_msg *msg, const char *val)
  {
-@@ -384,6 +409,8 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+@@ -387,6 +412,8 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
  	FIELD(u8, AID, "aid"),
  	FIELD(u8, RU_ALLOC, "ru_alloc"),
  	FIELD(u8, RU_IDX, "ru_idx"),
@@ -229,7 +229,7 @@
  	FIELD_MAC(MAC_ADDRS, "mac_addrs"),
  	FIELD_NESTED_RO(STATS, stats, "",
  			.print_extra = print_extra_stats),
-@@ -414,6 +441,7 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
+@@ -418,6 +445,7 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
  	[MT76_TM_ATTR_RU_ALLOC] = { .type = NLA_U8 },
  	[MT76_TM_ATTR_RU_IDX] = { .type = NLA_U8 },
  	[MT76_TM_ATTR_STATS] = { .type = NLA_NESTED },
diff --git a/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch b/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
index abeb149..89129dc 100644
--- a/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
@@ -1,7 +1,7 @@
-From 1334f63638dc3cfc7bbcd8f14ee72d2b9847dd6d Mon Sep 17 00:00:00 2001
+From 2dd660a1655c17d701507ab739f8fe74f8561de3 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 27 Oct 2022 17:42:07 +0800
-Subject: [PATCH 1012/1040] wifi: mt76: testmode: add ZWDFS test mode support
+Subject: [PATCH 24/76] wifi: mt76: testmode: add ZWDFS test mode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -18,10 +18,10 @@
  10 files changed, 508 insertions(+), 1 deletion(-)
 
 diff --git a/mt76.h b/mt76.h
-index ed1c864..ed69106 100644
+index f43cb53..98e8e71 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -754,6 +754,15 @@ struct mt76_testmode_data {
+@@ -790,6 +790,15 @@ struct mt76_testmode_data {
  		u64 fcs_error[__MT_RXQ_MAX];
  		u64 len_mismatch;
  	} rx_stats;
@@ -38,10 +38,10 @@
  
  struct mt76_vif {
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index a6449d1..2848179 100644
+index 964ee53..efb87d3 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1206,6 +1206,7 @@ enum {
+@@ -1227,6 +1227,7 @@ enum {
  	MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
  	MCU_EXT_CMD_SET_RDD_TH = 0x9d,
  	MCU_EXT_CMD_MURU_CTRL = 0x9f,
@@ -49,7 +49,7 @@
  	MCU_EXT_CMD_RX_STAT = 0xa4,
  	MCU_EXT_CMD_SET_SPR = 0xa8,
  	MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
-@@ -1216,6 +1217,7 @@ enum {
+@@ -1237,6 +1238,7 @@ enum {
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_CERT_CFG = 0xb7,
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
@@ -58,7 +58,7 @@
  
  enum {
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 474bed1..2cd772b 100644
+index 19e88b0..ddf130b 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -2670,6 +2670,7 @@ mt7915_mcu_background_chain_ctrl(struct mt7915_phy *phy,
@@ -196,7 +196,7 @@
  #define OFDMA_DL                       BIT(0)
  #define OFDMA_UL                       BIT(1)
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 18881c0..33ac2d2 100644
+index ce128ab..78ddbaf 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -256,6 +256,7 @@ struct mt7915_phy {
@@ -207,7 +207,7 @@
  
  	u8 stats_work_count;
  	struct list_head stats_list;
-@@ -710,6 +711,9 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
+@@ -711,6 +712,9 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
  				  struct ieee80211_sta *sta);
  #endif
  
@@ -231,10 +231,10 @@
  #define MT_WF_PHY_BASE			0x83080000
  #define MT_WF_PHY(ofs)			(MT_WF_PHY_BASE + (ofs))
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 86deae6..e321848 100644
+index 453319e..caa3590 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
-@@ -13,6 +13,12 @@ enum {
+@@ -14,6 +14,12 @@ enum {
  	TM_CHANGED_AID,
  	TM_CHANGED_CFG,
  	TM_CHANGED_TXBF_ACT,
@@ -247,7 +247,7 @@
  
  	/* must be last */
  	NUM_TM_CHANGED
-@@ -24,6 +30,12 @@ static const u8 tm_change_map[] = {
+@@ -26,6 +32,12 @@ static const u8 tm_change_map[] = {
  	[TM_CHANGED_AID] = MT76_TM_ATTR_AID,
  	[TM_CHANGED_CFG] = MT76_TM_ATTR_CFG,
  	[TM_CHANGED_TXBF_ACT] = MT76_TM_ATTR_TXBF_ACT,
@@ -260,7 +260,7 @@
  };
  
  struct reg_band {
-@@ -982,6 +994,272 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -984,6 +996,272 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
  	return 0;
  }
  
@@ -533,7 +533,7 @@
  static int
  mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
  		      u16 cw_max, u16 txop, u8 tx_cmd)
-@@ -1269,6 +1547,8 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
+@@ -1273,6 +1551,8 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
  		phy->mt76->test.tx_mpdu_len = 0;
  		phy->test.bf_en = 0;
  		mt7915_tm_set_entry(phy);
@@ -542,7 +542,7 @@
  	}
  }
  
-@@ -2028,6 +2308,14 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
+@@ -2038,6 +2318,14 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
  		mt7915_tm_set_cfg(phy);
  	if (changed & BIT(TM_CHANGED_TXBF_ACT))
  		mt7915_tm_set_txbf(phy);
@@ -558,10 +558,10 @@
  
  static int
 diff --git a/testmode.c b/testmode.c
-index f415bec..babae8d 100644
+index 898ef3a..dc972e3 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -25,6 +25,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+@@ -26,6 +26,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
  	[MT76_TM_ATTR_TX_TIME] = { .type = NLA_U32 },
  	[MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
  	[MT76_TM_ATTR_DRV_DATA] = { .type = NLA_NESTED },
@@ -575,7 +575,7 @@
  };
  EXPORT_SYMBOL_GPL(mt76_tm_policy);
  
-@@ -406,6 +413,7 @@ mt76_testmode_init_defaults(struct mt76_phy *phy)
+@@ -407,6 +414,7 @@ mt76_testmode_init_defaults(struct mt76_phy *phy)
  	td->tx_count = 1;
  	td->tx_rate_mode = MT76_TM_TX_MODE_OFDM;
  	td->tx_rate_nss = 1;
@@ -583,7 +583,7 @@
  
  	memcpy(td->addr[0], phy->macaddr, ETH_ALEN);
  	memcpy(td->addr[1], phy->macaddr, ETH_ALEN);
-@@ -611,6 +619,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -615,6 +623,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	if (tb[MT76_TM_ATTR_TX_RATE_IDX])
  		td->tx_rate_idx = nla_get_u8(tb[MT76_TM_ATTR_TX_RATE_IDX]);
  
@@ -593,7 +593,7 @@
  	if (mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_MODE], &td->tx_rate_mode,
  			   0, MT76_TM_TX_MODE_MAX) ||
  	    mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_NSS], &td->tx_rate_nss,
-@@ -627,7 +638,16 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -631,7 +642,16 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  			   &td->tx_power_control, 0, 1) ||
  	    mt76_tm_get_u8(tb[MT76_TM_ATTR_AID], &td->aid, 0, 16) ||
  	    mt76_tm_get_u8(tb[MT76_TM_ATTR_RU_ALLOC], &td->ru_alloc, 0, 0xff) ||
@@ -611,7 +611,7 @@
  		goto out;
  
  	if (tb[MT76_TM_ATTR_TX_LENGTH]) {
-@@ -861,6 +881,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -866,6 +886,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_MODE, td->tx_rate_mode) ||
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_SGI, td->tx_rate_sgi) ||
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) ||
@@ -622,10 +622,10 @@
  	     nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
  	    (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
 diff --git a/testmode.h b/testmode.h
-index d2675dd..97e7596 100644
+index 1d7aef8..b39cf51 100644
 --- a/testmode.h
 +++ b/testmode.h
-@@ -63,6 +63,20 @@
+@@ -64,6 +64,20 @@
   *	(nested, u8 attrs)
   *
   * @MT76_TM_ATTR_CFG: config testmode rf feature (nested, see &mt76_testmode_cfg)
@@ -646,7 +646,7 @@
   *
   */
  enum mt76_testmode_attr {
-@@ -116,6 +130,16 @@ enum mt76_testmode_attr {
+@@ -118,6 +132,16 @@ enum mt76_testmode_attr {
  	MT76_TM_ATTR_TXBF_ACT,
  	MT76_TM_ATTR_TXBF_PARAM,
  
@@ -663,7 +663,7 @@
  	/* keep last */
  	NUM_MT76_TM_ATTRS,
  	MT76_TM_ATTR_MAX = NUM_MT76_TM_ATTRS - 1,
-@@ -292,4 +316,25 @@ enum mt76_testmode_txbf_act {
+@@ -296,4 +320,25 @@ enum mt76_testmode_txbf_act {
  	MT76_TM_TXBF_ACT_MAX = NUM_MT76_TM_TXBF_ACT - 1,
  };
  
@@ -690,7 +690,7 @@
 +
  #endif
 diff --git a/tools/fields.c b/tools/fields.c
-index 6bf4c04..fc01043 100644
+index b0ee84d..e2cf4b9 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -46,6 +46,14 @@ static const char * const testmode_txbf_act[] = {
@@ -708,7 +708,7 @@
  static void print_enum(const struct tm_field *field, struct nlattr *attr)
  {
  	unsigned int i = nla_get_u8(attr);
-@@ -411,6 +419,13 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+@@ -414,6 +422,13 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
  	FIELD(u8, RU_IDX, "ru_idx"),
  	FIELD_ENUM(TXBF_ACT, "txbf_act", testmode_txbf_act),
  	FIELD_ARRAY(u16_hex, TXBF_PARAM, "txbf_param"),
@@ -722,7 +722,7 @@
  	FIELD_MAC(MAC_ADDRS, "mac_addrs"),
  	FIELD_NESTED_RO(STATS, stats, "",
  			.print_extra = print_extra_stats),
-@@ -442,6 +457,13 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
+@@ -446,6 +461,13 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
  	[MT76_TM_ATTR_RU_IDX] = { .type = NLA_U8 },
  	[MT76_TM_ATTR_STATS] = { .type = NLA_NESTED },
  	[MT76_TM_ATTR_TXBF_ACT] = { .type = NLA_U8 },
diff --git a/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch b/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
index eedc6de..4fccf5a 100644
--- a/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
@@ -1,8 +1,8 @@
-From abf253c784db9cb42cf14ca7b825227ef982c3cd Mon Sep 17 00:00:00 2001
+From 1e99f66f9d2c81340bd1f4fb2b9adbaf69263299 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 15 Dec 2022 19:45:18 +0800
-Subject: [PATCH] wifi: mt76: testmode: add iBF/eBF cal and cert commands with
- golden
+Subject: [PATCH 25/76] wifi: mt76: testmode: add iBF/eBF cal and cert commands
+ with golden
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -25,10 +25,10 @@
  16 files changed, 858 insertions(+), 324 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 7ae061d..d16accd 100644
+index 98e8e71..87bb745 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -718,6 +718,7 @@ struct mt76_testmode_data {
+@@ -752,6 +752,7 @@ struct mt76_testmode_data {
  
  	struct list_head tm_entry_list;
  	struct mt76_wcid *cur_entry;
@@ -36,7 +36,7 @@
  	u8 entry_num;
  	union {
  		struct mt76_testmode_entry_data ed;
-@@ -746,6 +747,9 @@ struct mt76_testmode_data {
+@@ -780,6 +781,9 @@ struct mt76_testmode_data {
  
  	u8 txbf_act;
  	u16 txbf_param[8];
@@ -47,10 +47,10 @@
  	u32 tx_pending;
  	u32 tx_queued;
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 60e159c..07bd57b 100644
+index 69babba..4a7b694 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -2796,6 +2796,7 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
+@@ -2677,6 +2677,7 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
  	u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA;
  	struct bss_info_basic *bss;
  	struct tlv *tlv;
@@ -58,7 +58,7 @@
  
  	tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss));
  	bss = (struct bss_info_basic *)tlv;
-@@ -2855,6 +2856,8 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
+@@ -2736,6 +2737,8 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
  		bss->dtim_period = vif->bss_conf.dtim_period;
  		bss->phy_mode = mt76_connac_get_phy_mode(phy, vif,
  							 chandef->chan->band, NULL);
@@ -68,7 +68,7 @@
  		memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
  	}
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 06a5fb1..948f07b 100644
+index d3b4a60..9fd764f 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -730,8 +730,10 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
@@ -84,7 +84,7 @@
  	txwi[6] |= cpu_to_le32(val);
  #endif
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 44a1b21..8c9b0b2 100644
+index 7124e18..c85a919 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -205,46 +205,37 @@ static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif)
@@ -175,7 +175,7 @@
  
  	return ret;
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 2cd772b..83d974c 100644
+index ddf130b..3645540 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -199,6 +199,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
@@ -448,7 +448,7 @@
  	MURU_SET_ARB_OP_MODE = 14,
  	MURU_SET_PLATFORM_TYPE = 25,
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 87a5c5c..6dd6eca 100644
+index c0cf8fb..aa51df3 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -133,6 +133,7 @@ static const u32 mt7915_offs[] = {
@@ -859,7 +859,7 @@
  #define MT_WF_RMAC_BASE(_band)		((_band) ? 0x820f5000 : 0x820e5000)
  #define MT_WF_RMAC(_band, ofs)		(MT_WF_RMAC_BASE(_band) + (ofs))
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 1e6791e..5e20cb9 100644
+index caa3590..faf6014 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -55,6 +55,8 @@ struct reg_band {
@@ -1610,7 +1610,7 @@
  }
  
  static int
-@@ -1547,7 +1711,7 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
+@@ -1549,7 +1713,7 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
  
  		phy->mt76->test.aid = 0;
  		phy->mt76->test.tx_mpdu_len = 0;
@@ -1619,7 +1619,7 @@
  		mt7915_tm_set_entry(phy);
  	} else {
  		INIT_DELAYED_WORK(&phy->ipi_work, mt7915_tm_ipi_work);
-@@ -1732,7 +1896,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1734,7 +1898,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
  		u32 tx_time = td->tx_time, ipg = td->tx_ipg;
  		u8 duty_cycle = td->tx_duty_cycle;
  
@@ -1628,7 +1628,7 @@
  			mt7915_tm_update_channel(phy);
  
  		if (td->tx_spe_idx)
-@@ -1747,7 +1911,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1749,7 +1913,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
  			if (duty_cycle < 100)
  				tx_time = duty_cycle * ipg / (100 - duty_cycle);
  		}
@@ -1637,7 +1637,7 @@
  		mt7915_tm_set_tx_len(phy, tx_time);
  
  		if (ipg)
-@@ -1766,6 +1930,9 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1768,6 +1932,9 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
  		mt7915_tm_tx_frames_mu(phy, en);
  
  	mt7915_tm_set_trx(phy, TM_MAC_TX, en);
@@ -1647,7 +1647,7 @@
  }
  
  static int
-@@ -1857,7 +2024,7 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
+@@ -1859,7 +2026,7 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
  	mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
  
  	if (en) {
@@ -1656,7 +1656,7 @@
  			mt7915_tm_update_channel(phy);
  		if (td->aid)
  			mt7915_tm_set_rx_user_idx(phy, td->aid);
-@@ -1874,6 +2041,9 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
+@@ -1876,6 +2043,9 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
  		mt7915_tm_set_muru_aid(phy, en ? td->aid : 0xf800);
  
  	mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
@@ -1666,7 +1666,7 @@
  }
  
  static int
-@@ -1933,34 +2103,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
+@@ -1935,34 +2105,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
  		rate_idx = sband->bitrates[idx].hw_value & 0xff;
  	}
  
@@ -1847,7 +1847,7 @@
  
  #endif
 diff --git a/testmode.c b/testmode.c
-index 4c22dfc..410c7ab 100644
+index dc972e3..0dfed1e 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -196,6 +196,7 @@ mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len,
diff --git a/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch b/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch
index ce08209..c6bf7a4 100644
--- a/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch
@@ -1,18 +1,17 @@
-From 6f767bac12cec3502c3760984abffcf2d806b70f Mon Sep 17 00:00:00 2001
+From 60d4943ff781d30aaedb00338f8daa5653e9f887 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Sun, 24 Apr 2022 10:07:00 +0800
-Subject: [PATCH 1014/1040] wifi: mt76: mt7915: init rssi in WTBL when add
- station
+Subject: [PATCH 26/76] wifi: mt76: mt7915: init rssi in WTBL when add station
 
 ---
  mt7915/main.c | 4 ++++
  1 file changed, 4 insertions(+)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 169d597..e11ae9f 100644
+index c85a919..d73cf9f 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -761,6 +761,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -762,6 +762,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy;
  #endif
  	int ret, idx;
@@ -20,7 +19,7 @@
  
  	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
  	if (idx < 0)
-@@ -785,6 +786,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -786,6 +787,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (ret)
  		return ret;
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch b/recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch
index f7936c9..a93efee 100644
--- a/recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch
@@ -1,7 +1,7 @@
-From c1864400a5aa6b60aebe412f8625109b61db04c0 Mon Sep 17 00:00:00 2001
+From aff3cbd4b173bd58066c0ca30a18f2ccf6607d3d Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 6 May 2022 15:58:42 +0800
-Subject: [PATCH 1015/1040] wifi: mt76: connac: airtime fairness feature off in
+Subject: [PATCH 27/76] wifi: mt76: connac: airtime fairness feature off in
  mac80211
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 1 deletion(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index fccf26d..ad3a5e2 100644
+index 241621c..1a7d690 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -440,7 +440,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
+@@ -451,7 +451,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
  			WIPHY_FLAG_AP_UAPSD;
  
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
diff --git a/recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch b/recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch
index c018337..4a9bca9 100644
--- a/recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch
@@ -1,25 +1,25 @@
-From c30637769e5ab91210b3ef958fb5e27212ed89e4 Mon Sep 17 00:00:00 2001
+From 3139498918652ecf180fa6ccfa465cbcdf5185fc Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Fri, 20 May 2022 19:19:25 +0800
-Subject: [PATCH 1016/1040] wifi: mt76: mt7915: add mt7986 and mt7916
- pre-calibration
+Date: Wed, 13 Dec 2023 09:55:27 +0800
+Subject: [PATCH] wifi: mt76: mt7915: add mt7986 and mt7916 pre-calibration
 
 Add pre-calibration for mt7986 and mt7916. It has different data size
 with mt7915. Group cal needs 54k and 94k for 2G + 5G and 2G + 6G,
 respectively. DPD cal needs 300k.
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
- mt7915/eeprom.c | 15 +++++------
+ mt7915/eeprom.c | 17 ++++++------
  mt7915/eeprom.h |  1 +
  mt7915/mcu.c    | 72 ++++++++++++++++++++++++++++++++++++-------------
- 3 files changed, 62 insertions(+), 26 deletions(-)
+ 3 files changed, 63 insertions(+), 27 deletions(-)
 
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index f5ab331..a5c99a5 100644
+index 0441d91..5e74b5f 100644
 --- a/mt7915/eeprom.c
 +++ b/mt7915/eeprom.c
-@@ -9,23 +9,22 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
+@@ -9,28 +9,27 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
  {
  	struct mt76_dev *mdev = &dev->mt76;
  	u8 *eeprom = mdev->eeprom.data;
@@ -27,6 +27,7 @@
 -	u32 offs;
 +	u32 offs = is_mt7915(&dev->mt76) ? MT_EE_DO_PRE_CAL : MT_EE_DO_PRE_CAL_V2;
 +	u32 size, val = eeprom[offs];
+ 	int ret;
  
 -	if (!dev->flash_mode)
 +	if (!dev->flash_mode || !val)
@@ -45,13 +46,18 @@
  
  	offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
  
--	return mt76_get_of_eeprom(mdev, dev->cal, offs, val);
-+	return mt76_get_of_eeprom(mdev, dev->cal, offs, size);
+-	ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, val);
++	ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);
+ 	if (!ret)
+ 		return ret;
+ 
+-	return mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", val);
++	return mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
  }
  
  static int mt7915_check_eeprom(struct mt7915_dev *dev)
 diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h
-index 88aaa16..fdae347 100644
+index 25f0b32..4a31375 100644
 --- a/mt7915/eeprom.h
 +++ b/mt7915/eeprom.h
 @@ -19,6 +19,7 @@ enum mt7915_eeprom_field {
@@ -63,7 +69,7 @@
  	MT_EE_RATE_DELTA_5G =	0x29d,
  	MT_EE_TX0_POWER_2G =	0x2fc,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 83d974c..8202a4e 100644
+index 3645540..174e1b0 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -2955,7 +2955,8 @@ static int mt7915_mcu_set_pre_cal(struct mt7915_dev *dev, u8 idx,
diff --git a/recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch b/recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
index 3562374..0c22fa9 100644
--- a/recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
@@ -1,8 +1,7 @@
-From 4bca02444e44f948a9d8d26fb155c7c1f1304f31 Mon Sep 17 00:00:00 2001
+From 7144ac4907d9ca8d2364ad29e380f3d27fadc493 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <Yi-Chia.Hsieh@mediatek.com>
 Date: Tue, 12 Jul 2022 10:04:35 -0700
-Subject: [PATCH 1017/1040] wifi: mt76: mt7915: add phy capability vendor
- command
+Subject: [PATCH 29/76] wifi: mt76: mt7915: add phy capability vendor command
 
 ---
  mt7915/mt7915.h |  1 +
@@ -11,7 +10,7 @@
  3 files changed, 78 insertions(+)
 
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 135b39b..b41c96b 100644
+index 2ef63a3..053c6a8 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -11,6 +11,7 @@
@@ -23,7 +22,7 @@
  #define MT7916_WTBL_SIZE		544
  #define MT7915_WTBL_RESERVED		(mt7915_wtbl_size(dev) - 1)
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index df1cac3..3dbbd32 100644
+index 6fc88f9..a801315 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -50,6 +50,18 @@ rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
@@ -45,7 +44,7 @@
  struct csi_null_tone {
  	u8 start;
  	u8 end;
-@@ -976,6 +988,35 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
+@@ -977,6 +989,35 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  	return 0;
  }
  
@@ -81,7 +80,7 @@
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
  		.info = {
-@@ -1033,6 +1074,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1034,6 +1075,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.doit = mt7915_vendor_mu_ctrl,
  		.policy = mu_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX,
diff --git a/recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch b/recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch
index b7ed3aa..69565c4 100644
--- a/recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch
@@ -1,7 +1,7 @@
-From fb237147a73b10808a651273198583b938003338 Mon Sep 17 00:00:00 2001
+From 8fa041e702bd756560a1f409f4ad783f90b412d9 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Fri, 24 Jun 2022 11:15:45 +0800
-Subject: [PATCH 1018/1040] wifi: mt76: mt7915: add vendor subcmd EDCCA ctrl
+Subject: [PATCH 30/76] wifi: mt76: mt7915: add vendor subcmd EDCCA ctrl
  enable/threshold/compensation
 
 Change-Id: I06a3f94d5e444be894200e2b6588d76ed38d09d0
@@ -16,10 +16,10 @@
  7 files changed, 265 insertions(+), 1 deletion(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 2848179..4905411 100644
+index efb87d3..9e40749 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1216,6 +1216,7 @@ enum {
+@@ -1237,6 +1237,7 @@ enum {
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_CERT_CFG = 0xb7,
@@ -28,10 +28,10 @@
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
  };
 diff --git a/mt7915/main.c b/mt7915/main.c
-index e11ae9f..287ca99 100644
+index d73cf9f..f7fee40 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -478,6 +478,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
+@@ -479,6 +479,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
  			mutex_unlock(&dev->mt76.mutex);
  		}
  #endif
@@ -42,7 +42,7 @@
  		ret = mt7915_set_channel(phy);
  		if (ret)
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 8202a4e..83ceb2e 100644
+index 174e1b0..884b394 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -4827,3 +4827,76 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w
@@ -155,10 +155,10 @@
  
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index b41c96b..c5f4e94 100644
+index 053c6a8..795af63 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -713,7 +713,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
+@@ -714,7 +714,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
  int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
  				  struct ieee80211_sta *sta);
  #endif
@@ -169,7 +169,7 @@
  int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp);
  
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 3dbbd32..afba18e 100644
+index a801315..635c218 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -62,6 +62,24 @@ phy_capa_dump_policy[NUM_MTK_VENDOR_ATTRS_PHY_CAPA_DUMP] = {
@@ -197,7 +197,7 @@
  struct csi_null_tone {
  	u8 start;
  	u8 end;
-@@ -1017,6 +1035,108 @@ mt7915_vendor_phy_capa_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -1018,6 +1036,108 @@ mt7915_vendor_phy_capa_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
  	return len;
  }
  
@@ -306,7 +306,7 @@
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
  		.info = {
-@@ -1085,6 +1205,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1086,6 +1206,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.dumpit = mt7915_vendor_phy_capa_ctrl_dump,
  		.policy = phy_capa_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_PHY_CAPA_CTRL_MAX,
diff --git a/recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-implement-bin-file-mode.patch b/recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-implement-bin-file-mode.patch
index 230ef81..e78398b 100644
--- a/recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-implement-bin-file-mode.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-implement-bin-file-mode.patch
@@ -1,4 +1,4 @@
-From b33cf2d53b4719f00d96ba1b5280b7df593870cf Mon Sep 17 00:00:00 2001
+From 2b5f249307be0134f4ee8ee3ddf7a5374294ffce Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 7 Jul 2022 11:09:59 +0800
 Subject: [PATCH] wifi: mt76: mt7915: implement bin file mode
@@ -6,22 +6,22 @@
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 ---
- eeprom.c             | 25 +++++++++++++++++
+ eeprom.c             | 25 ++++++++++++++++++
  mt76.h               |  4 +++
- mt7915/eeprom.c      | 65 +++++++++++++++++++++++++++++++++++++++++---
+ mt7915/eeprom.c      | 63 +++++++++++++++++++++++++++++++++++++++++---
  mt7915/eeprom.h      |  7 +++++
- mt7915/mt7915.h      |  3 ++
- mt7915/mtk_debugfs.c | 44 ++++++++++++++++++++++++++++++
+ mt7915/mt7915.h      |  3 +++
+ mt7915/mtk_debugfs.c | 44 +++++++++++++++++++++++++++++++
  testmode.h           |  2 +-
- 7 files changed, 145 insertions(+), 5 deletions(-)
+ 7 files changed, 144 insertions(+), 4 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index 9b63799..d5b8c56 100644
+index 3625b16..9d029c0 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -159,6 +159,31 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
+@@ -161,6 +161,31 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
+ 	return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
  }
- EXPORT_SYMBOL_GPL(mt76_get_of_eeprom);
  
 +bool mt76_check_bin_file_mode(struct mt76_dev *dev)
 +{
@@ -52,10 +52,10 @@
  mt76_eeprom_override(struct mt76_phy *phy)
  {
 diff --git a/mt76.h b/mt76.h
-index d16accd..9673926 100644
+index 87bb745..3f55022 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -943,6 +943,9 @@ struct mt76_dev {
+@@ -977,6 +977,9 @@ struct mt76_dev {
  		struct mt76_usb usb;
  		struct mt76_sdio sdio;
  	};
@@ -65,16 +65,16 @@
  };
  
  /* per-phy stats.  */
-@@ -1175,6 +1178,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
- int mt76_eeprom_init(struct mt76_dev *dev, int len);
- void mt76_eeprom_override(struct mt76_phy *phy);
- int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len);
+@@ -1225,6 +1228,7 @@ void mt76_eeprom_override(struct mt76_phy *phy);
+ int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
+ int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
+ 				const char *cell_name, int len);
 +bool mt76_check_bin_file_mode(struct mt76_dev *dev);
  
  struct mt76_queue *
  mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index a5c99a5..5eb9f88 100644
+index 5e74b5f..3c99b4d 100644
 --- a/mt7915/eeprom.c
 +++ b/mt7915/eeprom.c
 @@ -5,6 +5,30 @@
@@ -108,19 +108,17 @@
  static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
  {
  	struct mt76_dev *mdev = &dev->mt76;
-@@ -24,7 +48,10 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
+@@ -25,6 +49,9 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
  
  	offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
  
--	return mt76_get_of_eeprom(mdev, dev->cal, offs, size);
-+	if (!dev->bin_file_mode)
-+		return mt76_get_of_eeprom(mdev, dev->cal, offs, size);
-+	else
++	if (dev->bin_file_mode)
 +		return mt7915_eeprom_load_precal_binfile(dev, offs, size);
- }
- 
- static int mt7915_check_eeprom(struct mt7915_dev *dev)
-@@ -47,8 +74,11 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev)
++
+ 	ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);
+ 	if (!ret)
+ 		return ret;
+@@ -52,8 +79,11 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev)
  	}
  }
  
@@ -133,7 +131,7 @@
  	switch (mt76_chip(&dev->mt76)) {
  	case 0x7915:
  		return dev->dbdc_support ?
-@@ -89,7 +119,10 @@ mt7915_eeprom_load_default(struct mt7915_dev *dev)
+@@ -94,7 +124,10 @@ mt7915_eeprom_load_default(struct mt7915_dev *dev)
  		return ret;
  
  	if (!fw || !fw->data) {
@@ -145,7 +143,7 @@
  		ret = -EINVAL;
  		goto out;
  	}
-@@ -114,6 +147,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
+@@ -119,6 +152,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
  
  	if (ret) {
  		dev->flash_mode = true;
@@ -153,7 +151,7 @@
  	} else {
  		u8 free_block_num;
  		u32 block_num, i;
-@@ -134,6 +168,8 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
+@@ -139,6 +173,8 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
  			if (ret < 0)
  				return ret;
  		}
@@ -162,7 +160,7 @@
  	}
  
  	return mt7915_check_eeprom(dev);
-@@ -239,12 +275,33 @@ int mt7915_eeprom_init(struct mt7915_dev *dev)
+@@ -244,12 +280,33 @@ int mt7915_eeprom_init(struct mt7915_dev *dev)
  {
  	int ret;
  
@@ -198,7 +196,7 @@
  		if (ret)
  			return ret;
 diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h
-index fdae347..9056d78 100644
+index 4a31375..a1ab05a 100644
 --- a/mt7915/eeprom.h
 +++ b/mt7915/eeprom.h
 @@ -108,6 +108,13 @@ enum mt7915_sku_rate_group {
@@ -237,7 +235,7 @@
  #define PKT_BIN_DEBUG_MAGIC	0xc8763123
  enum {
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 7105cf0..5c676d8 100644
+index 2ce1837..8c5184d 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -3,6 +3,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-Add-mu-dump-support.patch b/recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-Add-mu-dump-support.patch
index 013b88f..0a5e0ce 100644
--- a/recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-Add-mu-dump-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-Add-mu-dump-support.patch
@@ -1,7 +1,7 @@
-From ffa6ac27f043615593e71b38734e47521cb066c0 Mon Sep 17 00:00:00 2001
+From 840d6089ac85c927bfb6f352c826ec3bd3846104 Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Thu, 11 Aug 2022 18:09:45 -0700
-Subject: [PATCH 1020/1040] wifi: mt76: mt7915: Add mu dump support
+Subject: [PATCH 32/76] wifi: mt76: mt7915: Add mu dump support
 
 Change-Id: I521214f3feb6f0d528a9f550255050ffd1ec96d2
 ---
@@ -10,7 +10,7 @@
  2 files changed, 25 insertions(+)
 
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index afba18e..0c0b47e 100644
+index 635c218..25509d6 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -37,6 +37,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -21,7 +21,7 @@
  };
  
  static const struct nla_policy
-@@ -1006,6 +1007,28 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
+@@ -1007,6 +1008,28 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  	return 0;
  }
  
@@ -50,7 +50,7 @@
  static int
  mt7915_vendor_phy_capa_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
  			     struct sk_buff *skb, const void *data, int data_len,
-@@ -1192,6 +1215,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1193,6 +1216,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
  			WIPHY_VENDOR_CMD_NEED_RUNNING,
  		.doit = mt7915_vendor_mu_ctrl,
diff --git a/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch b/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch
index 7f0aff5..8fd0e42 100644
--- a/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch
@@ -1,8 +1,8 @@
-From fc0376cf18d75e6691d1c1dee207a0a7536a8d4f Mon Sep 17 00:00:00 2001
+From 05f2c9d7b83e9528809d5ee9773a8f3653fe3334 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 28 Oct 2022 10:15:56 +0800
-Subject: [PATCH 1021/1040] wifi: mt76: mt7915: add vendor subcmd three wire
- (PTA) ctrl
+Subject: [PATCH 33/76] wifi: mt76: mt7915: add vendor subcmd three wire (PTA)
+ ctrl
 
 Change-Id: Ic1044698f294455594a0c6254f55326fdab90580
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,10 +16,10 @@
  6 files changed, 111 insertions(+), 29 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 4905411..3b5c58b 100644
+index 9e40749..b4392bc 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1215,7 +1215,7 @@ enum {
+@@ -1236,7 +1236,7 @@ enum {
  	/* for vendor csi and air monitor */
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
@@ -29,7 +29,7 @@
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 83ceb2e..7e33386 100644
+index 884b394..42f699f 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -4526,37 +4526,33 @@ void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable)
@@ -134,10 +134,10 @@
  #define OFDMA_DL                       BIT(0)
  #define OFDMA_UL                       BIT(1)
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index b6a564e..febe070 100644
+index 992323d..8730655 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -707,6 +707,7 @@ void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
+@@ -708,6 +708,7 @@ void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
  void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable);
  int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val);
  void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type);
@@ -146,7 +146,7 @@
  void mt7915_vendor_register(struct mt7915_phy *phy);
  int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 0c0b47e..b651cea 100644
+index 25509d6..0db493d 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -40,6 +40,11 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
@@ -161,7 +161,7 @@
  static const struct nla_policy
  rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
  	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
-@@ -973,7 +978,7 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
+@@ -974,7 +979,7 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
  			mt7915_set_wireless_vif, &val32);
  	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]) {
  		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]);
@@ -170,7 +170,7 @@
  		mt7915_mcu_set_bypass_smthint(phy, val8); /* Cert bypass smooth interpolation */
  	}
  
-@@ -1117,6 +1122,7 @@ static int mt7915_vendor_edcca_ctrl(struct wiphy *wiphy,
+@@ -1118,6 +1123,7 @@ static int mt7915_vendor_edcca_ctrl(struct wiphy *wiphy,
  	return 0;
  }
  
@@ -178,7 +178,7 @@
  static int
  mt7915_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
  			     struct sk_buff *skb, const void *data, int data_len,
-@@ -1160,6 +1166,31 @@ mt7915_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -1161,6 +1167,31 @@ mt7915_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
  	return len;
  }
  
@@ -210,7 +210,7 @@
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
  		.info = {
-@@ -1241,6 +1272,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1242,6 +1273,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.dumpit = mt7915_vendor_edcca_ctrl_dump,
  		.policy = edcca_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_EDCCA_CTRL_MAX,
diff --git a/recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch b/recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch
index 479b39f..e4829b0 100644
--- a/recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch
@@ -1,7 +1,7 @@
-From a16d1b2e363994a284d5542c4f980a693fdbe326 Mon Sep 17 00:00:00 2001
+From 6bc96533e92948ed6fa7fa1c497d4ff844f72af1 Mon Sep 17 00:00:00 2001
 From: mtk27835 <shurong.wen@mediatek.com>
 Date: Wed, 7 Sep 2022 14:01:29 -0700
-Subject: [PATCH 1022/1040] wifi: mt76: mt7915: add ibf control vendor cmd
+Subject: [PATCH 34/76] wifi: mt76: mt7915: add ibf control vendor cmd
 
 Signed-off-by: mtk27835 <shurong.wen@mediatek.com>
 ---
@@ -10,7 +10,7 @@
  2 files changed, 89 insertions(+), 1 deletion(-)
 
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index b651cea..b661ea4 100644
+index 0db493d..f190bd0 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -86,6 +86,11 @@ edcca_dump_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP] = {
@@ -25,7 +25,7 @@
  struct csi_null_tone {
  	u8 start;
  	u8 end;
-@@ -1190,6 +1195,54 @@ static int mt7915_vendor_3wire_ctrl(struct wiphy *wiphy,
+@@ -1191,6 +1196,54 @@ static int mt7915_vendor_3wire_ctrl(struct wiphy *wiphy,
  	return mt7915_mcu_set_cfg(phy, CFGINFO_3WIRE_EN_CFG, three_wire_mode);
  }
  
@@ -80,7 +80,7 @@
  
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
-@@ -1283,6 +1336,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1284,6 +1337,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.doit = mt7915_vendor_3wire_ctrl,
  		.policy = three_wire_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_3WIRE_CTRL_MAX,
diff --git a/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch b/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
deleted file mode 100644
index 408e5b6..0000000
--- a/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 81ddde34a61e2a320cf1af73cc91e0465e92cad8 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Thu, 30 Mar 2023 15:12:37 +0800
-Subject: [PATCH 1023/1040] wifi: mt76: mt7915: add E3 re-bonding for low yield
- rate issue
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7915/eeprom.c | 28 ++++++++++++++++++++++++++++
- mt7915/mt7915.h |  1 +
- 2 files changed, 29 insertions(+)
-
-diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index fd08d42..3b44a9d 100644
---- a/mt7915/eeprom.c
-+++ b/mt7915/eeprom.c
-@@ -244,6 +244,32 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
- 	dev->chainshift = hweight8(dev->mphy.chainmask);
- }
- 
-+void mt7915_eeprom_rebonding(struct mt7915_dev *dev)
-+{
-+#define MT7976_ADIE_MASK			BIT(1)
-+#define MT7986_ADIE1_EFFUSE_OFFSET		0x1000
-+#define MT7986_ADIE1_MT7976C_OFFSET		0x270
-+#define MT7986_ADIE1_E3_OFFSET			0x271
-+	u32 adie_offset, offset, sku = mt7915_check_adie(dev, true);
-+	u8 read_buf[MT7915_EEPROM_BLOCK_SIZE], *eeprom = dev->mt76.eeprom.data;
-+
-+
-+	if (!(sku & MT7976_ADIE_MASK))
-+		return;
-+
-+	adie_offset = (sku == MT7976_DUAL_ADIE) ? MT7986_ADIE1_EFFUSE_OFFSET : 0;
-+
-+	/* 7976 A-Die, To identify MT7976C */
-+	offset = MT7986_ADIE1_MT7976C_OFFSET + adie_offset;
-+	mt7915_mcu_get_eeprom(dev, offset, read_buf);
-+	eeprom[MT7986_ADIE1_MT7976C_OFFSET] = read_buf[offset % MT7915_EEPROM_BLOCK_SIZE];
-+
-+	/* E3 re-binding */
-+	offset = MT7986_ADIE1_E3_OFFSET + adie_offset;
-+	mt7915_mcu_get_eeprom(dev, offset, read_buf);
-+	eeprom[MT7986_ADIE1_E3_OFFSET] = read_buf[offset % MT7915_EEPROM_BLOCK_SIZE];
-+}
-+
- int mt7915_eeprom_init(struct mt7915_dev *dev)
- {
- 	int ret;
-@@ -280,6 +306,8 @@ int mt7915_eeprom_init(struct mt7915_dev *dev)
- 			return ret;
- 	}
- 
-+	mt7915_eeprom_rebonding(dev);
-+
- 	ret = mt7915_eeprom_load_precal(dev);
- 	if (ret)
- 		return ret;
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index febe070..a3d7b4b 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -506,6 +506,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
- 
- int mt7915_register_device(struct mt7915_dev *dev);
- void mt7915_unregister_device(struct mt7915_dev *dev);
-+void mt7915_eeprom_rebonding(struct mt7915_dev *dev);
- int mt7915_eeprom_init(struct mt7915_dev *dev);
- void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
- 				struct mt7915_phy *phy);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch b/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch
new file mode 100644
index 0000000..69b21f7
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch
@@ -0,0 +1,268 @@
+From 2b1ca7b7f8e5c65abd254b51a7a79418457684ea Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 30 Mar 2023 15:12:37 +0800
+Subject: [PATCH 35/76] wifi: mt76: mt7915: add cal free data merge support
+
+1. add basic cal free data support
+2. add E3 low yield rate workaround for panther E3 with 7976 adie
+3. add Harrier freq offset workaround
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7915/eeprom.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7915/mcu.c    |  13 ++--
+ mt7915/mt7915.h |   1 +
+ 3 files changed, 198 insertions(+), 4 deletions(-)
+
+diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
+index 5eb9f88..b96776d 100644
+--- a/mt7915/eeprom.c
++++ b/mt7915/eeprom.c
+@@ -271,6 +271,190 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
+ 	dev->chainshift = hweight8(dev->mphy.chainmask);
+ }
+ 
++static int mt7915_apply_cal_free_data(struct mt7915_dev *dev)
++{
++#define MT_EE_CAL_FREE_MAX_SIZE		70
++#define MT_EE_FREQ_OFFSET		0x77
++#define MT_EE_ADIE1_MT7976C_OFFSET	0x270
++#define MT_EE_ADIE1_E3_OFFSET		0x271
++#define MT_EE_END_OFFSET		0xffff
++#define MT_EE_ADIE1_BASE_7896		0x1000
++	enum adie_type {
++		ADIE_7975,
++		ADIE_7976,
++	};
++	enum ddie_type {
++		DDIE_7915,
++		DDIE_7916,
++	};
++	static const u16 ddie_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
++		[DDIE_7915] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
++			       0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23, 0x24,
++			       0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
++			       0x52, 0x70, 0x71, 0x72, 0x76, 0xa8, 0xa9, 0xaa, 0xab, 0xac,
++			       0xad, 0xae, 0xaf, -1},
++		[DDIE_7916] = {0x30, 0x31, 0x34, 0x35, 0x36, 0x38, 0x3c, 0x3a, 0x3d, 0x44,
++			       0x46, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xe0, -1},
++	};
++	static const u16 adie_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
++		[ADIE_7975] = {0x7cd, 0x7cf, 0x7d1, 0x7d3, 0x802, 0x803, 0x804, 0x805, 0x806,
++			       0x808, 0x80a, 0x80b, 0x80c, 0x80d, 0x80e, 0x810, 0x812, 0x813,
++			       0x814, 0x815, 0x816, 0x818, 0x81a, 0x81b, 0x81c, 0x81d, 0x81e,
++			       0x820, 0x822, 0x823, 0x824, 0x825, 0x826, 0x827, 0x828, 0x829,
++			       0x82f, 0x8c0, 0x8c1, 0x8c2, 0x8c3, 0x9a0, 0x8d0, 0x8d1, 0x8d7,
++			       0x8d8, 0x8fa, 0x9a1, 0x9a5, 0x9a6, 0x9a8, 0x9aa, 0x9b0, 0x9b1,
++			       0x9b2, 0x9b3, 0x9b4, 0x9b5, 0x9b6, 0x9b7, -1},
++		[ADIE_7976] = {0x24c, 0x24d, 0x24e, 0x24f, 0x250, 0x251, 0x253, 0x255, 0x257,
++			       0x259, 0x990, 0x991, 0x994, 0x995, 0x9a6, 0x9a8, 0x9aa, -1},
++	};
++	static const u16 eep_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
++		[ADIE_7975] = {0xe00, 0xe01, 0xe02, 0xe03, 0xe04, 0xe05, 0xe06, 0xe07, 0xe08,
++			       0xe09, 0xe0a, 0xe0b, 0xe0c, 0xe0d, 0x80e, 0xe0f, 0xe10, 0xe11,
++			       0xe12, 0xe13, 0xe14, 0xe15, 0xe16, 0xe17, 0xe18, 0xe19, 0xe1a,
++			       0xe1b, 0xe1c, 0xe1d, 0xe1e, 0xe1f, 0xe20, 0xe21, 0xe22, 0xe23,
++			       0xe24, 0xe25, 0xe26, 0xe27, 0xe28, 0xe29, 0xe2a, 0xe2b, 0xe2c,
++			       0xe2d, 0xe2e, 0xe2f, 0xe33, 0xe34, 0xe36, 0xe38, 0xe39, 0xe3a,
++			       0xe3b, 0xe3c, 0xe3d, 0xe3e, 0xe3f, 0xe40, -1},
++		[ADIE_7976] = {0x33c, 0x33d, 0x33e, 0x33f, 0x340, 0x341, 0x343, 0x345, 0x347,
++			       0x349, 0x359, 0x35a, 0x35d, 0x35e, 0x36a, 0x36c, 0x36e, -1},
++	};
++	static const u16 *ddie_offs;
++	static const u16 *adie_offs[__MT_MAX_BAND];
++	static const u16 *eep_offs[__MT_MAX_BAND];
++	static u16 adie_base[__MT_MAX_BAND] = {0};
++	u8 *eeprom = dev->mt76.eeprom.data;
++	u8 buf[MT7915_EEPROM_BLOCK_SIZE];
++	int adie_id, band, i, ret;
++
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7915:
++		ddie_offs = ddie_offs_list[DDIE_7915];
++		ret = mt7915_mcu_get_eeprom(dev, MT_EE_ADIE_FT_VERSION, buf);
++		if (ret)
++			return ret;
++		adie_id = buf[MT_EE_ADIE_FT_VERSION % MT7915_EEPROM_BLOCK_SIZE] - 1;
++		adie_offs[0] = adie_offs_list[ADIE_7975];
++		/* same as adie offset */
++		eep_offs[0] = NULL;
++		break;
++	case 0x7906:
++	case 0x7981:
++		if (is_mt7916(&dev->mt76))
++			ddie_offs = ddie_offs_list[DDIE_7916];
++		adie_offs[0] = adie_offs_list[ADIE_7976];
++		eep_offs[0] = NULL;
++		break;
++	case 0x7986:
++		adie_id = mt7915_check_adie(dev, true);
++		switch (adie_id) {
++		case MT7975_ONE_ADIE:
++		case MT7975_DUAL_ADIE:
++			adie_offs[0] = adie_offs_list[ADIE_7975];
++			eep_offs[0] = NULL;
++			if (adie_id == MT7975_DUAL_ADIE) {
++				adie_offs[1] = adie_offs_list[ADIE_7975];
++				eep_offs[1] = eep_offs_list[ADIE_7975];
++			}
++			break;
++		case MT7976_ONE_ADIE_DBDC:
++		case MT7976_ONE_ADIE:
++		case MT7976_DUAL_ADIE: {
++			u16 base = 0, offset = MT_EE_ADIE1_MT7976C_OFFSET;
++
++			adie_offs[0] = adie_offs_list[ADIE_7976];
++			eep_offs[0] = NULL;
++			if (adie_id == MT7976_DUAL_ADIE) {
++				adie_offs[1] = adie_offs_list[ADIE_7976];
++				eep_offs[1] = eep_offs_list[ADIE_7976];
++				base = MT_EE_ADIE1_BASE_7896;
++			}
++
++			/* E3 re-bonding workaround */
++			ret = mt7915_mcu_get_eeprom(dev, offset + base, buf);
++			if (ret)
++				break;
++			offset = (offset + base) % MT7915_EEPROM_BLOCK_SIZE;
++			eeprom[MT_EE_ADIE1_MT7976C_OFFSET] = buf[offset];
++			offset = (MT_EE_ADIE1_E3_OFFSET + base) % MT7915_EEPROM_BLOCK_SIZE;
++			eeprom[MT_EE_ADIE1_E3_OFFSET] = buf[offset];
++			break;
++		}
++		default:
++			return -EINVAL;
++		}
++		adie_base[1] = MT_EE_ADIE1_BASE_7896;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* ddie */
++	if (ddie_offs) {
++		u16 ddie_offset;
++		u32 block_num, prev_block_num = -1;
++
++		for (i = 0; i < MT_EE_CAL_FREE_MAX_SIZE; i++) {
++			ddie_offset = ddie_offs[i];
++			block_num = ddie_offset / MT7915_EEPROM_BLOCK_SIZE;
++
++			if (ddie_offset == MT_EE_END_OFFSET)
++				break;
++
++			if (prev_block_num != block_num) {
++				ret = mt7915_mcu_get_eeprom(dev, ddie_offset, buf);
++				if (ret) {
++					prev_block_num = -1;
++					continue;
++				}
++			}
++
++			eeprom[ddie_offset] = buf[ddie_offset % MT7915_EEPROM_BLOCK_SIZE];
++			prev_block_num = block_num;
++		}
++	}
++
++	/* adie */
++	for (band = 0; band < __MT_MAX_BAND; band++) {
++		u16 adie_offset, eep_offset;
++		u32 block_num, prev_block_num = -1;
++
++		if (!adie_offs[band])
++			continue;
++
++		for (i = 0; i < MT_EE_CAL_FREE_MAX_SIZE; i++) {
++			adie_offset = adie_offs[band][i] + adie_base[band];
++			eep_offset = adie_offset;
++			if (eep_offs[band])
++				eep_offset = eep_offs[band][i];
++			block_num = adie_offset / MT7915_EEPROM_BLOCK_SIZE;
++
++			if (adie_offs[band][i] == MT_EE_END_OFFSET)
++				break;
++
++			if (is_mt7915(&dev->mt76) && !adie_id &&
++			    adie_offset >= 0x8c0 && adie_offset <= 0x8c3)
++				continue;
++
++			if (prev_block_num != block_num) {
++				ret = mt7915_mcu_get_eeprom(dev, adie_offset, buf);
++				if (ret) {
++					prev_block_num = -1;
++					continue;
++				}
++			}
++
++			eeprom[eep_offset] = buf[adie_offset % MT7915_EEPROM_BLOCK_SIZE];
++			prev_block_num = block_num;
++
++			/* workaround for Harrier */
++			if (is_mt7915(&dev->mt76) && adie_offset == 0x9a1)
++				eeprom[MT_EE_FREQ_OFFSET] = eeprom[adie_offset];
++		}
++	}
++
++	return 0;
++}
++
+ int mt7915_eeprom_init(struct mt7915_dev *dev)
+ {
+ 	int ret;
+@@ -311,6 +495,10 @@ int mt7915_eeprom_init(struct mt7915_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	ret = mt7915_apply_cal_free_data(dev);
++	if (ret)
++		return ret;
++
+ 	mt7915_eeprom_parse_hw_cap(dev, &dev->phy);
+ 	memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
+ 	       ETH_ALEN);
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 42f699f..d3ed33a 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -2879,6 +2879,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset, u8 *read_buf)
+ 	};
+ 	struct mt7915_mcu_eeprom_info *res;
+ 	struct sk_buff *skb;
++	bool valid;
+ 	int ret;
+ 	u8 *buf = read_buf;
+ 
+@@ -2889,10 +2890,14 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset, u8 *read_buf)
+ 		return ret;
+ 
+ 	res = (struct mt7915_mcu_eeprom_info *)skb->data;
+-
+-	if (!buf)
+-		buf = dev->mt76.eeprom.data + le32_to_cpu(res->addr);
+-	memcpy(buf, res->data, MT7915_EEPROM_BLOCK_SIZE);
++	valid = !!le32_to_cpu(res->valid);
++	if (valid) {
++		if (!buf)
++			buf = dev->mt76.eeprom.data + le32_to_cpu(res->addr);
++		memcpy(buf, res->data, MT7915_EEPROM_BLOCK_SIZE);
++	} else {
++		ret = -EINVAL;
++	}
+ 
+ 	dev_kfree_skb(skb);
+ 
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 8730655..25a6815 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -507,6 +507,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+ 
+ int mt7915_register_device(struct mt7915_dev *dev);
+ void mt7915_unregister_device(struct mt7915_dev *dev);
++void mt7915_eeprom_rebonding(struct mt7915_dev *dev);
+ int mt7915_eeprom_init(struct mt7915_dev *dev);
+ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
+ 				struct mt7915_phy *phy);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch b/recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch
index 0ac0f94..0bd8edc 100644
--- a/recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch
@@ -1,7 +1,7 @@
-From bf55d4819b6c12dd7c6e13a51f8ee28636265345 Mon Sep 17 00:00:00 2001
+From aa15abf250978f6a2b7452fe45390138544859b5 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 14 Oct 2022 11:15:13 +0800
-Subject: [PATCH 1024/1040] wifi: mt76: mt7915: support on off SW ACI through
+Subject: [PATCH 36/76] wifi: mt76: mt7915: support on off SW ACI through
  debugfs
 
 Signed-off-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
@@ -12,10 +12,10 @@
  2 files changed, 22 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 3b5c58b..4925890 100644
+index b4392bc..bf5ab81 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1217,6 +1217,7 @@ enum {
+@@ -1238,6 +1238,7 @@ enum {
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_SET_CFG = 0xb7,
  	MCU_EXT_CMD_EDCCA = 0xba,
@@ -24,7 +24,7 @@
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
  };
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index b949ad7..ef5d581 100644
+index 8c5184d..b8a8516 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -3642,6 +3642,25 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
diff --git a/recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch b/recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch
index 032e44d..c7c5d3f 100644
--- a/recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch
@@ -1,8 +1,7 @@
-From 51e7036b3f6295eb7a8e5925dea43cb71998f0dd Mon Sep 17 00:00:00 2001
+From 2a604d8b017da2ff941a7e10535af8d4d49c5ce8 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Mon, 5 Dec 2022 18:21:51 +0800
-Subject: [PATCH 1025/1042] wifi: mt76: mt7915: add bf backoff limit table
- support
+Subject: [PATCH 37/76] wifi: mt76: mt7915: add bf backoff limit table support
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 ---
@@ -31,10 +30,10 @@
  		seq_printf(file, " %2d", val[i]);
  	seq_puts(file, "\n");
 diff --git a/eeprom.c b/eeprom.c
-index eb532c7..c0536f1 100644
+index 8f8e375..cf142c5 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -326,9 +326,10 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data,
+@@ -337,9 +337,10 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data,
  static void
  mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
  			     const __be32 *data, size_t len, s8 target_power,
@@ -46,7 +45,7 @@
  
  	if (!data)
  		return;
-@@ -340,7 +341,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
+@@ -351,7 +352,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
  			break;
  
  		mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1,
@@ -55,7 +54,7 @@
  		if (--cur > 0)
  			continue;
  
-@@ -367,12 +368,16 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+@@ -378,12 +379,16 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
  	char band;
  	size_t len;
  	s8 max_power = -127;
@@ -73,7 +72,7 @@
  
  	if (!IS_ENABLED(CONFIG_OF))
  		return target_power;
-@@ -418,14 +423,40 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+@@ -429,14 +434,40 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
  	val = mt76_get_of_array(np, "rates-mcs", &len, mcs_rates + 1);
  	mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]),
  				     ARRAY_SIZE(dest->mcs), val, len,
@@ -118,10 +117,10 @@
  EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
  
 diff --git a/mt76.h b/mt76.h
-index 9673926..6ed3e1e 100644
+index 99f21e2..c322135 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -1049,6 +1049,14 @@ struct mt76_power_limits {
+@@ -1083,6 +1083,14 @@ struct mt76_power_limits {
  	s8 mcs[4][10];
  	s8 ru[7][12];
  	s8 eht[16][16];
@@ -249,10 +248,10 @@
  				    mt7915_twt_stats);
  	debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
 diff --git a/mt7915/init.c b/mt7915/init.c
-index d908a58..b2fdd43 100644
+index db61953..82fbec4 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -284,6 +284,8 @@ void __mt7915_init_txpower(struct mt7915_phy *phy,
+@@ -284,6 +284,8 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy,
  	int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);
  	struct mt76_power_limits limits;
  
@@ -261,7 +260,7 @@
  	for (i = 0; i < sband->n_channels; i++) {
  		struct ieee80211_channel *chan = &sband->channels[i];
  		u32 target_power = 0;
-@@ -300,6 +302,11 @@ void __mt7915_init_txpower(struct mt7915_phy *phy,
+@@ -300,6 +302,11 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy,
  		target_power = mt76_get_rate_power_limits(phy->mt76, chan,
  							  &limits,
  							  target_power);
@@ -274,7 +273,7 @@
  		target_power = DIV_ROUND_UP(target_power, 2);
  		chan->max_power = min_t(int, chan->max_reg_power,
 diff --git a/mt7915/main.c b/mt7915/main.c
-index da9cfc6..df7aab5 100644
+index f7fee40..0ac81ad 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -74,10 +74,12 @@ int mt7915_run(struct ieee80211_hw *hw)
@@ -294,10 +293,10 @@
  		goto out;
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 7e33386..224ce21 100644
+index d3ed33a..62aad77 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3311,7 +3311,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3316,7 +3316,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  	int ret;
  	s8 txpower_sku[MT7915_SKU_RATE_NUM];
  
@@ -307,7 +306,7 @@
  	if (ret)
  		return ret;
  
-@@ -3351,53 +3352,139 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3356,53 +3357,139 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  				 sizeof(req), true);
  }
  
@@ -474,7 +473,7 @@
  	struct mt7915_dev *dev = phy->dev;
  	struct {
  		u8 format_id;
-@@ -3406,10 +3493,9 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
+@@ -3411,10 +3498,9 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
  		u8 _rsv;
  	} __packed req = {
  		.format_id = TX_POWER_LIMIT_INFO,
@@ -486,7 +485,7 @@
  	struct sk_buff *skb;
  	int ret, i;
  
-@@ -3419,9 +3505,15 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
+@@ -3424,9 +3510,15 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
  	if (ret)
  		return ret;
  
@@ -505,7 +504,7 @@
  
  	dev_kfree_skb(skb);
  
-@@ -3450,7 +3542,7 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
+@@ -3455,7 +3547,7 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
  				 sizeof(req), false);
  }
  
@@ -514,7 +513,7 @@
  {
  	struct mt7915_dev *dev = phy->dev;
  	struct mt7915_sku {
-@@ -3461,10 +3553,21 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
+@@ -3466,10 +3558,21 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
  	} __packed req = {
  		.format_id = TX_POWER_LIMIT_ENABLE,
  		.band_idx = phy->mt76->band_idx,
diff --git a/recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-amsdu-set-and-get-control.patch b/recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-amsdu-set-and-get-control.patch
index 4dd0383..091d42f 100644
--- a/recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-amsdu-set-and-get-control.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-amsdu-set-and-get-control.patch
@@ -1,7 +1,7 @@
-From ff2283c46ffd78340efabfe1e614dfd69405bd6d Mon Sep 17 00:00:00 2001
+From ffc38f4303f435b7b885a6fa078adcf45a118e66 Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Wed, 14 Dec 2022 00:44:07 -0800
-Subject: [PATCH 1026/1040] wifi: mt76: mt7915: amsdu set and get control
+Subject: [PATCH 38/76] wifi: mt76: mt7915: amsdu set and get control
 
 ---
  mt7915/mac.c    |  7 +++++++
@@ -11,10 +11,10 @@
  4 files changed, 50 insertions(+)
 
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 4244177..51073ab 100644
+index 9fd764f..cdffdf3 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -2032,6 +2032,13 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
+@@ -2033,6 +2033,13 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
  	spin_unlock_bh(&phy->stats_lock);
  }
  
@@ -29,10 +29,10 @@
  void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta)
  {
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 4dc3825..75967f9 100644
+index c2fb12d..6d28e3f 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -698,6 +698,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -702,6 +702,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  			 bool pci, int *irq);
  
  #ifdef CONFIG_MTK_VENDOR
@@ -41,7 +41,7 @@
  void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
  void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index b661ea4..0105d2f 100644
+index f190bd0..844b22e 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -30,10 +30,16 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -61,7 +61,7 @@
  static const struct nla_policy
  mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
  	[MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 },
-@@ -985,11 +991,34 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
+@@ -986,11 +992,34 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
  		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]);
  		mt7915_mcu_set_cfg(phy, CFGINFO_CERT_CFG, val8); /* Cert Enable for OMI */
  		mt7915_mcu_set_bypass_smthint(phy, val8); /* Cert bypass smooth interpolation */
@@ -96,7 +96,7 @@
  static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  				  struct wireless_dev *wdev,
  				  const void *data,
-@@ -1288,6 +1317,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1289,6 +1318,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
  			WIPHY_VENDOR_CMD_NEED_RUNNING,
  		.doit = mt7915_vendor_wireless_ctrl,
diff --git a/recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch b/recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch
index cf5d9b7..79fa538 100644
--- a/recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch
@@ -1,8 +1,8 @@
-From 7bf557aff6961e6d224f599b1be6068393c68bfc Mon Sep 17 00:00:00 2001
+From 87a3861eb9e06519ee27a0b949cd5387d6fa9c7a Mon Sep 17 00:00:00 2001
 From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
 Date: Tue, 24 Jan 2023 14:32:08 +0800
-Subject: [PATCH 1027/1040] wifi: mt76: mt7915: Add vendor command attribute
- for RTS BW signaling.
+Subject: [PATCH 39/76] wifi: mt76: mt7915: Add vendor command attribute for
+ RTS BW signaling.
 
 Signed-off-by: himanshu.goyal <himanshu.goyal@mediatek.com>
 ---
@@ -13,10 +13,10 @@
  4 files changed, 20 insertions(+)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index f65f0ec..12ee063 100644
+index 62aad77..64fd91a 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4612,6 +4612,12 @@ int mt7915_mcu_set_cfg(struct mt7915_phy *phy, u8 cfg_info, u8 type)
+@@ -4650,6 +4650,12 @@ int mt7915_mcu_set_cfg(struct mt7915_phy *phy, u8 cfg_info, u8 type)
  		req.cert.length = cpu_to_le16(tlv_len);
  		req.cert.cert_program = type;
  		break;
@@ -62,7 +62,7 @@
  };
  
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 0105d2f..fb2fe82 100644
+index 844b22e..05d95f3 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -33,6 +33,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -73,7 +73,7 @@
  };
  
  static const struct nla_policy
-@@ -994,6 +995,9 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
+@@ -995,6 +996,9 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
  	} else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU]) {
  		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU]);
  		mt7915_set_wireless_amsdu(hw, val8);
diff --git a/recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch b/recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch
index 2dd5226..6eac734 100644
--- a/recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch
@@ -1,7 +1,7 @@
-From cbfad5aeabda8196ffa1e21f23ebdeb3864b9860 Mon Sep 17 00:00:00 2001
+From ef94525684dc7777ac6a3e80b1e6fb9a08d04b25 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Thu, 26 Jan 2023 08:50:47 +0800
-Subject: [PATCH 1028/1040] wifi: mt76: mt7915: add vendor cmd to get available
+Subject: [PATCH 40/76] wifi: mt76: mt7915: add vendor cmd to get available
  color bitmap
 
 Add a vendor cmd to notify user space available color bitmap.
@@ -14,7 +14,7 @@
  2 files changed, 48 insertions(+)
 
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index fb2fe82..94c4aad 100644
+index 05d95f3..b325b89 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -98,6 +98,11 @@ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
@@ -29,7 +29,7 @@
  struct csi_null_tone {
  	u8 start;
  	u8 end;
-@@ -1276,6 +1281,27 @@ mt7915_vendor_ibf_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -1277,6 +1282,27 @@ mt7915_vendor_ibf_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
  	return 1;
  }
  
@@ -57,7 +57,7 @@
  
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
-@@ -1382,6 +1408,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1383,6 +1409,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.dumpit = mt7915_vendor_ibf_ctrl_dump,
  		.policy = ibf_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_IBF_CTRL_MAX,
diff --git a/recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch b/recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch
index 1e0c6d6..9fca716 100644
--- a/recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch
@@ -1,7 +1,7 @@
-From 9720802e9abc886c7676d3994e3735aa440ed78e Mon Sep 17 00:00:00 2001
+From ec30b7800a1b06f58e4b0e08ee51c7073e305b26 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Fri, 24 Feb 2023 16:29:42 +0800
-Subject: [PATCH 1029/1040] wifi: mt76: mt7915: disable SW-ACI by default
+Subject: [PATCH 41/76] wifi: mt76: mt7915: disable SW-ACI by default
 
 Support to enable/disable SW-ACI by module parameter "sw_aci_enable".
 SW-ACI feature is disable by default.
@@ -13,7 +13,7 @@
  4 files changed, 29 insertions(+), 9 deletions(-)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 287ca99..5b4581c 100644
+index 0ac81ad..0318254 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -8,6 +8,10 @@
@@ -39,10 +39,10 @@
  
  	if (phy != &dev->phy) {
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 12ee063..fe00519 100644
+index 64fd91a..6ff1c47 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4972,3 +4972,18 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value)
+@@ -5010,3 +5010,18 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value)
  
  	return 0;
  }
@@ -62,10 +62,10 @@
 +				 sizeof(req), NULL);
 +}
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 75967f9..722f3bc 100644
+index 6d28e3f..3f6cf7b 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -722,6 +722,7 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
+@@ -726,6 +726,7 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
  #endif
  int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value, s8 compensation);
  int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value);
@@ -74,7 +74,7 @@
  int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp);
  
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index ef5d581..80b7bc1 100644
+index b8a8516..671791e 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -3645,16 +3645,12 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
diff --git a/recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch b/recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch
index 3503c08..1795f07 100644
--- a/recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch
@@ -1,8 +1,7 @@
-From babeb3948faef2769f838dd35050eb71c7194175 Mon Sep 17 00:00:00 2001
+From c762ac55ec18f656d508a5805f953427e2657e9a Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Thu, 27 Apr 2023 15:37:33 +0800
-Subject: [PATCH 1030/1040] wifi: mt76: mt7915: add muru user number debug
- command
+Subject: [PATCH 42/76] wifi: mt76: mt7915: add muru user number debug command
 
 ---
  mt7915/mt7915.h |  1 +
@@ -11,10 +10,10 @@
  3 files changed, 17 insertions(+), 1 deletion(-)
 
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 722f3bc..9f62e5e 100644
+index 3f6cf7b..72fe2fc 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -586,6 +586,7 @@ int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev,
+@@ -590,6 +590,7 @@ int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev,
  int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
  			    const struct mt7915_dfs_pattern *pattern);
  int mt7915_mcu_set_muru_ctrl(struct mt7915_dev *dev, u32 cmd, u32 val);
@@ -23,7 +22,7 @@
  int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy);
  int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 94c4aad..b450808 100644
+index b325b89..d7cb088 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -45,6 +45,8 @@ static const struct nla_policy
@@ -35,7 +34,7 @@
  };
  
  static const struct nla_policy
-@@ -1034,9 +1036,10 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
+@@ -1035,9 +1037,10 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  				  int data_len)
  {
  	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
@@ -47,7 +46,7 @@
  	u32 val32 = 0;
  
  	err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len,
-@@ -1050,6 +1053,16 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
+@@ -1051,6 +1054,16 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  			 FIELD_PREP(RATE_CFG_VAL, val8);
  		ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
  			mt7915_set_wireless_vif, &val32);
diff --git a/recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch b/recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch
index a194c24..11f2d1a 100644
--- a/recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch
@@ -1,7 +1,7 @@
-From 0b6b1f1ab13a801b23459161251b54ee94e41562 Mon Sep 17 00:00:00 2001
+From ace56f2c1ee008bcab3191494d7ed92538e50339 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 22 May 2023 15:30:21 +0800
-Subject: [PATCH 1031/1040] wifi: mt76: mt7915: add debugfs for fw coredump.
+Subject: [PATCH 43/76] wifi: mt76: mt7915: add debugfs for fw coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -67,10 +67,10 @@
  	/* SER statistics */
  	desc += scnprintf(buff + desc, bufsz - desc,
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 51073ab..e4f46e0 100644
+index cdffdf3..07f0e30 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -1725,10 +1725,34 @@ void mt7915_mac_dump_work(struct work_struct *work)
+@@ -1726,10 +1726,34 @@ void mt7915_mac_dump_work(struct work_struct *work)
  
  	dev = container_of(work, struct mt7915_dev, dump_work);
  
@@ -107,7 +107,7 @@
  }
  
  void mt7915_reset(struct mt7915_dev *dev)
-@@ -1747,7 +1771,7 @@ void mt7915_reset(struct mt7915_dev *dev)
+@@ -1748,7 +1772,7 @@ void mt7915_reset(struct mt7915_dev *dev)
  			 wiphy_name(dev->mt76.hw->wiphy));
  
  		mt7915_irq_disable(dev, MT_INT_MCU_CMD);
@@ -135,7 +135,7 @@
  	SER_ENABLE = 2,
  	SER_RECOVER
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 9f62e5e..16f2661 100644
+index 72fe2fc..34005a3 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -91,6 +91,13 @@ struct mt7915_sta;
@@ -152,7 +152,7 @@
  enum mt7915_txq_id {
  	MT7915_TXQ_FWDL = 16,
  	MT7915_TXQ_MCU_WM,
-@@ -337,6 +344,7 @@ struct mt7915_dev {
+@@ -341,6 +348,7 @@ struct mt7915_dev {
  
  	/* protects coredump data */
  	struct mutex dump_mutex;
@@ -160,7 +160,7 @@
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
  		struct mt7915_crash_data *crash_data[__MT76_RAM_TYPE_MAX];
-@@ -524,6 +532,7 @@ int mt7915_txbf_init(struct mt7915_dev *dev);
+@@ -528,6 +536,7 @@ int mt7915_txbf_init(struct mt7915_dev *dev);
  void mt7915_init_txpower(struct mt7915_phy *phy);
  int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_en);
  void mt7915_reset(struct mt7915_dev *dev);
diff --git a/recipes-wifi/linux-mt76/files/patches/1032-wifi-mt76-mt7915-remove-BW160-support.patch b/recipes-wifi/linux-mt76/files/patches/1032-wifi-mt76-mt7915-remove-BW160-support.patch
index cad5964..5e9922c 100644
--- a/recipes-wifi/linux-mt76/files/patches/1032-wifi-mt76-mt7915-remove-BW160-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1032-wifi-mt76-mt7915-remove-BW160-support.patch
@@ -1,7 +1,7 @@
-From 45e1cac480f32d75ec7f13389594768eb471ca66 Mon Sep 17 00:00:00 2001
+From 4d81cdd22da999d7101ed1e72ff3e3cbe04eeb34 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Wed, 24 May 2023 22:35:54 +0800
-Subject: [PATCH 1032/1040] wifi: mt76: mt7915: remove BW160 support
+Subject: [PATCH 44/76] wifi: mt76: mt7915: remove BW160 support
 
 Remove BW160 capability in mt7915.
 ---
@@ -9,10 +9,10 @@
  1 file changed, 6 insertions(+), 20 deletions(-)
 
 diff --git a/mt7915/init.c b/mt7915/init.c
-index d908a58..a942bc2 100644
+index 82fbec4..a44d3fa 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -431,11 +431,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+@@ -438,11 +438,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
  			vht_cap->cap |=
  				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
  				IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
@@ -24,7 +24,7 @@
  		} else {
  			phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
  				IEEE80211_HT_MPDU_DENSITY_2;
-@@ -891,13 +886,9 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,
+@@ -898,13 +893,9 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,
  	int sts = hweight8(phy->mt76->chainmask);
  	u8 c, sts_160 = sts;
  
@@ -41,7 +41,7 @@
  
  #ifdef CONFIG_MAC80211_MESH
  	if (vif == NL80211_IFTYPE_MESH_POINT)
-@@ -977,15 +968,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
+@@ -984,15 +975,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
  	int i, idx = 0, nss = hweight8(phy->mt76->antenna_mask);
  	u16 mcs_map = 0;
  	u16 mcs_map_160 = 0;
diff --git a/recipes-wifi/linux-mt76/files/patches/1033-wifi-mt76-mt7915-add-txpower-info-dump-support.patch b/recipes-wifi/linux-mt76/files/patches/1033-wifi-mt76-mt7915-add-txpower-info-dump-support.patch
index 78dba54..1c7278d 100644
--- a/recipes-wifi/linux-mt76/files/patches/1033-wifi-mt76-mt7915-add-txpower-info-dump-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1033-wifi-mt76-mt7915-add-txpower-info-dump-support.patch
@@ -1,7 +1,7 @@
-From a8a300579541b1e29f498d887e4711c481af1809 Mon Sep 17 00:00:00 2001
+From 35f6ac0e81382f76932b195a75fe0fa4ebc690e7 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Tue, 11 Jul 2023 17:06:04 +0800
-Subject: [PATCH 1033/1040] wifi: mt76: mt7915: add txpower info dump support
+Subject: [PATCH 45/76] wifi: mt76: mt7915: add txpower info dump support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -116,10 +116,10 @@
  				    mt7915_twt_stats);
  	debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index fe00519..344ba85 100644
+index 6ff1c47..80a678c 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3482,6 +3482,8 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
+@@ -3518,6 +3518,8 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
  			txpower[i] = res[i][req.band_idx];
  	} else if (category == TX_POWER_INFO_PATH) {
  		memcpy(txpower, skb->data + 4, len);
diff --git a/recipes-wifi/linux-mt76/files/patches/1034-wifi-mt76-mt7915-report-tx-and-rx-byte-to-tpt_led-wh.patch b/recipes-wifi/linux-mt76/files/patches/1034-wifi-mt76-mt7915-report-tx-and-rx-byte-to-tpt_led-wh.patch
index d987346..3e3cc5d 100644
--- a/recipes-wifi/linux-mt76/files/patches/1034-wifi-mt76-mt7915-report-tx-and-rx-byte-to-tpt_led-wh.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1034-wifi-mt76-mt7915-report-tx-and-rx-byte-to-tpt_led-wh.patch
@@ -1,8 +1,8 @@
-From 1118417f6ad1e37fe5031701522f1287dfd38491 Mon Sep 17 00:00:00 2001
+From 407b1b989e82300f8fd1124364e503bd1b446a88 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Fri, 23 Jun 2023 06:06:21 +0800
-Subject: [PATCH 1034/1040] wifi: mt76: mt7915: report tx and rx byte to
- tpt_led when wed is enabled
+Subject: [PATCH 46/76] wifi: mt76: mt7915: report tx and rx byte to tpt_led
+ when wed is enabled
 
 Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 ---
@@ -11,10 +11,10 @@
  2 files changed, 11 insertions(+), 4 deletions(-)
 
 diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index e26fcf8..c2f31bf 100644
+index 31d2474..707892b 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -596,9 +596,15 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
+@@ -597,9 +597,15 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
  
  	txs = le32_to_cpu(txs_data[0]);
  
@@ -30,7 +30,7 @@
  		stats->tx_bytes +=
  			le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) -
  			le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE);
-@@ -639,10 +645,6 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
+@@ -640,10 +646,6 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
  		cck = true;
  		fallthrough;
  	case MT_PHY_TYPE_OFDM:
@@ -42,10 +42,10 @@
  			sband = &mphy->sband_5g.sband;
  		else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 6dd6eca..b47bfff 100644
+index aa51df3..06f5a19 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -704,6 +704,7 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
+@@ -592,6 +592,7 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
  	int idx = le16_to_cpu(stats->wlan_idx);
  	struct mt7915_dev *dev;
  	struct mt76_wcid *wcid;
@@ -53,7 +53,7 @@
  
  	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
  
-@@ -714,6 +715,10 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
+@@ -602,6 +603,10 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
  
  	wcid = rcu_dereference(dev->mt76.wcid[idx]);
  	if (wcid) {
diff --git a/recipes-wifi/linux-mt76/files/patches/1035-wifi-mt76-mt7915-Establish-BA-in-VO-queue.patch b/recipes-wifi/linux-mt76/files/patches/1035-wifi-mt76-mt7915-Establish-BA-in-VO-queue.patch
index 8de22b4..33bd524 100644
--- a/recipes-wifi/linux-mt76/files/patches/1035-wifi-mt76-mt7915-Establish-BA-in-VO-queue.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1035-wifi-mt76-mt7915-Establish-BA-in-VO-queue.patch
@@ -1,17 +1,17 @@
-From 170d9117dbf1f31f9a5ccc1f5824c547b6209533 Mon Sep 17 00:00:00 2001
+From dc3bc9dadab098db977049a805ec458d19b2011d Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 8 Aug 2023 11:20:58 +0800
-Subject: [PATCH 1035/1040] wifi: mt76: mt7915: Establish BA in VO queue
+Subject: [PATCH 47/76] wifi: mt76: mt7915: Establish BA in VO queue
 
 ---
  mt76_connac_mac.c | 2 --
  1 file changed, 2 deletions(-)
 
 diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index c2f31bf..02d5232 100644
+index 707892b..362d937 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -1114,8 +1114,6 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+@@ -1118,8 +1118,6 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
  		return;
  
  	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
diff --git a/recipes-wifi/linux-mt76/files/patches/1036-wifi-mt76-mt7915-Disable-RegDB-when-enable-single-sk.patch b/recipes-wifi/linux-mt76/files/patches/1036-wifi-mt76-mt7915-Disable-RegDB-when-enable-single-sk.patch
index 96441b6..c83e758 100644
--- a/recipes-wifi/linux-mt76/files/patches/1036-wifi-mt76-mt7915-Disable-RegDB-when-enable-single-sk.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1036-wifi-mt76-mt7915-Disable-RegDB-when-enable-single-sk.patch
@@ -1,52 +1,15 @@
-From 378077f87cb5c696dbb2b313d9d4ef08383b1a6e Mon Sep 17 00:00:00 2001
+From a873e1dc3b0de28f1ef61e96b46a55ee7c4294bf Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Fri, 11 Aug 2023 16:46:53 +0800
-Subject: [PATCH 1036/1042] wifi: mt76: mt7915: Disable RegDB when enable
- single sku
+Subject: [PATCH 48/76] wifi: mt76: mt7915: Disable RegDB when enable single
+ sku
 
 ---
- eeprom.c         |  3 ++-
- mt76.h           |  3 +++
  mt7915/debugfs.c | 49 +++++++++++++++++++++++++++++++++++++++++++-----
  mt7915/init.c    | 11 +++++++++--
  mt7915/regs.h    |  8 ++++----
- 5 files changed, 62 insertions(+), 12 deletions(-)
+ 3 files changed, 57 insertions(+), 11 deletions(-)
 
-diff --git a/eeprom.c b/eeprom.c
-index c0536f1..cf5e933 100644
---- a/eeprom.c
-+++ b/eeprom.c
-@@ -216,7 +216,7 @@ static bool mt76_string_prop_find(struct property *prop, const char *str)
- 	return false;
- }
- 
--static struct device_node *
-+struct device_node *
- mt76_find_power_limits_node(struct mt76_dev *dev)
- {
- 	struct device_node *np = dev->dev->of_node;
-@@ -255,6 +255,7 @@ mt76_find_power_limits_node(struct mt76_dev *dev)
- 	of_node_put(np);
- 	return fallback;
- }
-+EXPORT_SYMBOL_GPL(mt76_find_power_limits_node);
- 
- static const __be32 *
- mt76_get_of_array(struct device_node *np, char *name, size_t *len, int min)
-diff --git a/mt76.h b/mt76.h
-index 6ed3e1e..e3f0dff 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -1675,6 +1675,9 @@ mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd,
- 
- void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
- 
-+struct device_node *
-+mt76_find_power_limits_node(struct mt76_dev *dev);
-+
- s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
- 			      struct ieee80211_channel *chan,
- 			      struct mt76_power_limits *dest,
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
 index 2bf907c..6dcee10 100644
 --- a/mt7915/debugfs.c
@@ -140,10 +103,10 @@
  	return ret;
  }
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 39bc2f6..fdfd284 100644
+index a44d3fa..2b002df 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -283,9 +283,11 @@ void __mt7915_init_txpower(struct mt7915_phy *phy,
+@@ -283,9 +283,11 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy,
  	int nss_delta = mt76_tx_power_nss_delta(n_chains);
  	int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);
  	struct mt76_power_limits limits;
@@ -155,7 +118,7 @@
  	for (i = 0; i < sband->n_channels; i++) {
  		struct ieee80211_channel *chan = &sband->channels[i];
  		u32 target_power = 0;
-@@ -309,8 +311,13 @@ void __mt7915_init_txpower(struct mt7915_phy *phy,
+@@ -309,8 +311,13 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy,
  
  		target_power += nss_delta;
  		target_power = DIV_ROUND_UP(target_power, 2);
diff --git a/recipes-wifi/linux-mt76/files/patches/1037-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch b/recipes-wifi/linux-mt76/files/patches/1037-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch
index 0258ff1..23c9cdf 100644
--- a/recipes-wifi/linux-mt76/files/patches/1037-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1037-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch
@@ -1,7 +1,7 @@
-From d7300215f0c2ca425ee97339618051a5e810608d Mon Sep 17 00:00:00 2001
+From c36e0cb6a541fa4b91b4665119ddb280b74e87d6 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Thu, 24 Aug 2023 03:01:27 +0800
-Subject: [PATCH 1037/1040] wifi: mt76: mt7915: enable the mac80211 hw bmc ps
+Subject: [PATCH 49/76] wifi: mt76: mt7915: enable the mac80211 hw bmc ps
  buffer function.
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 1 insertion(+)
 
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 82fe443..36621ad 100644
+index 2b002df..ff7bd11 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -405,6 +405,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+@@ -412,6 +412,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
  	ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
  	ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
  	ieee80211_hw_set(hw, WANT_MONITOR_VIF);
diff --git a/recipes-wifi/linux-mt76/files/patches/1038-wifi-mt76-update-debugfs-knob-to-dump-token-pending-.patch b/recipes-wifi/linux-mt76/files/patches/1038-wifi-mt76-update-debugfs-knob-to-dump-token-pending-.patch
index ebaf572..1df84b4 100644
--- a/recipes-wifi/linux-mt76/files/patches/1038-wifi-mt76-update-debugfs-knob-to-dump-token-pending-.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1038-wifi-mt76-update-debugfs-knob-to-dump-token-pending-.patch
@@ -1,8 +1,8 @@
-From e4019ba63d7bb60ac0b56618e3fd9421c97ce474 Mon Sep 17 00:00:00 2001
+From ad7d61fd7de176ea7bec5b675ddfc355070833f7 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Tue, 29 Aug 2023 09:22:18 +0800
-Subject: [PATCH 1038/1040] wifi: mt76: update debugfs knob to dump token
- pending time
+Subject: [PATCH 50/76] wifi: mt76: update debugfs knob to dump token pending
+ time
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
 ---
@@ -12,10 +12,10 @@
  3 files changed, 10 insertions(+), 4 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 91da8c5..ad1402a 100644
+index c322135..4704c50 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -368,6 +368,8 @@ struct mt76_txwi_cache {
+@@ -401,6 +401,8 @@ struct mt76_txwi_cache {
  	struct list_head list;
  	dma_addr_t dma_addr;
  
@@ -25,10 +25,10 @@
  		struct sk_buff *skb;
  		void *ptr;
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index e4f46e0..817763a 100644
+index 07f0e30..170a51b 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -802,6 +802,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -803,6 +803,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
  	if (id < 0)
  		return id;
  
@@ -37,7 +37,7 @@
  	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
  	mt7915_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, pid, key,
  			      qid, 0);
-@@ -1000,6 +1002,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -1001,6 +1003,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
  			if (!txwi)
  				continue;
  
@@ -46,7 +46,7 @@
  			mt76_connac2_txwi_free(mdev, txwi, sta, &free_list);
  		}
  	}
-@@ -1032,6 +1036,8 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
+@@ -1033,6 +1037,8 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
  		if (!txwi)
  			continue;
  
@@ -56,7 +56,7 @@
  	}
  
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 80b7bc1..46f1b0b 100644
+index 671791e..f4bc89c 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -2211,10 +2211,8 @@ static int mt7915_token_read(struct seq_file *s, void *data)
diff --git a/recipes-wifi/linux-mt76/files/patches/1039-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch b/recipes-wifi/linux-mt76/files/patches/1039-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch
index 5b0a6bc..fad77c9 100644
--- a/recipes-wifi/linux-mt76/files/patches/1039-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1039-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch
@@ -1,7 +1,7 @@
-From ac7a0356360173149824d63e9f5803adb7c94ae4 Mon Sep 17 00:00:00 2001
+From b2c4e27677bb08e773d33b90c3d417121d5454c8 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Tue, 5 Sep 2023 20:17:19 +0800
-Subject: [PATCH 1039/1040] wifi: mt76: mt7915: support enable/disable spatial
+Subject: [PATCH 51/76] wifi: mt76: mt7915: support enable/disable spatial
  reuse through debugfs
 
 Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
@@ -12,10 +12,10 @@
  3 files changed, 14 insertions(+), 2 deletions(-)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 344ba85..cd4f472 100644
+index 80a678c..ac015ab 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3609,8 +3609,7 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
+@@ -3647,8 +3647,7 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
  				 sizeof(req), true);
  }
  
@@ -26,10 +26,10 @@
  	struct mt7915_dev *dev = phy->dev;
  	struct mt7915_mcu_sr_ctrl req = {
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 16f2661..72d6cc0 100644
+index 34005a3..346333e 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -735,6 +735,7 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value);
+@@ -739,6 +739,7 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value);
  int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val);
  int mt7915_mcu_ipi_hist_ctrl(struct mt7915_phy *phy, void *data, u8 cmd, bool wait_resp);
  int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp);
@@ -38,7 +38,7 @@
  #ifdef MTK_DEBUG
  int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir);
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 46f1b0b..c58a2d1 100644
+index f4bc89c..4a0bb4c 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -3655,6 +3655,17 @@ mt7915_sw_aci_set(void *data, u64 val)
diff --git a/recipes-wifi/linux-mt76/files/patches/1040-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch b/recipes-wifi/linux-mt76/files/patches/1040-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch
index 378596d..c3ef908 100644
--- a/recipes-wifi/linux-mt76/files/patches/1040-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1040-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch
@@ -1,7 +1,7 @@
-From b010edba440f66a02eb9b72fb55831befb60107f Mon Sep 17 00:00:00 2001
+From 493e528b81ef05cb34d63440b8f0f731aaf60c08 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 11 Sep 2023 17:11:24 +0800
-Subject: [PATCH 1040/1040] wifi: mt76: mt7915: add debug log for SER flow.
+Subject: [PATCH 52/76] wifi: mt76: mt7915: add debug log for SER flow.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -9,10 +9,10 @@
  1 file changed, 9 insertions(+)
 
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 817763a..e51440d 100644
+index 170a51b..5e92e28 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -1570,6 +1570,9 @@ void mt7915_mac_reset_work(struct work_struct *work)
+@@ -1571,6 +1571,9 @@ void mt7915_mac_reset_work(struct work_struct *work)
  	if (!(READ_ONCE(dev->recovery.state) & MT_MCU_CMD_STOP_DMA))
  		return;
  
@@ -22,7 +22,7 @@
  	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
  		mtk_wed_device_stop(&dev->mt76.mmio.wed);
  		if (!is_mt798x(&dev->mt76))
-@@ -1648,6 +1651,9 @@ void mt7915_mac_reset_work(struct work_struct *work)
+@@ -1649,6 +1652,9 @@ void mt7915_mac_reset_work(struct work_struct *work)
  		ieee80211_queue_delayed_work(ext_phy->hw,
  					     &phy2->mt76->mac_work,
  					     MT7915_WATCHDOG_TIME);
@@ -32,7 +32,7 @@
  }
  
  /* firmware coredump */
-@@ -1763,6 +1769,9 @@ void mt7915_coredump(struct mt7915_dev *dev, u8 state)
+@@ -1764,6 +1770,9 @@ void mt7915_coredump(struct mt7915_dev *dev, u8 state)
  
  void mt7915_reset(struct mt7915_dev *dev)
  {
diff --git a/recipes-wifi/linux-mt76/files/patches/1041-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch b/recipes-wifi/linux-mt76/files/patches/1041-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch
index 705bd74..906a097 100644
--- a/recipes-wifi/linux-mt76/files/patches/1041-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1041-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch
@@ -1,7 +1,7 @@
-From 134bea3d6ba955e2dcccad2b2af144e163d4b2c1 Mon Sep 17 00:00:00 2001
+From f4ae3b90eb43f820b65e55085936ce8a7fb508fd Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 20 Sep 2023 11:10:57 +0800
-Subject: [PATCH] wifi: mt76: mt7915: add additional chain signal info to
+Subject: [PATCH 53/76] wifi: mt76: mt7915: add additional chain signal info to
  station dump
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index ec0de9b..b696f02 100644
+index 5e92e28..e5480ee 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -435,7 +435,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
diff --git a/recipes-wifi/linux-mt76/files/patches/1042-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch b/recipes-wifi/linux-mt76/files/patches/1042-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch
index 42c1246..f90df87 100644
--- a/recipes-wifi/linux-mt76/files/patches/1042-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1042-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch
@@ -1,7 +1,8 @@
-From ddd20028e31060d5bbbc72bd6e465c45819adb56 Mon Sep 17 00:00:00 2001
+From 93bf76280034ba4ecb511bad9843daa29234818a Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Mon, 2 Oct 2023 14:00:13 +0800
-Subject: [PATCH] wifi: mt76: mt7915: add debuffs knob for protect threshold
+Subject: [PATCH 54/76] wifi: mt76: mt7915: add debuffs knob for protect
+ threshold
 
 ---
  mt7915/mt7915.h      |  1 +
@@ -9,10 +10,10 @@
  2 files changed, 12 insertions(+)
 
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index e8a6ee68..2a01bd62 100644
+index 346333e..ad08582 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -716,6 +716,7 @@ void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
+@@ -719,6 +719,7 @@ void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
  		       struct ieee80211_vif *vif, struct ieee80211_sta *sta);
  int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig_type);
  int mt7915_mcu_set_mu_dl_ack_policy(struct mt7915_phy *phy, u8 policy_num);
@@ -21,7 +22,7 @@
  void mt7915_mcu_set_nusers_ofdma(struct mt7915_phy *phy, u8 type, u8 ofdma_user_cnt);
  void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index ed90d346..a9570ced 100644
+index 4a0bb4c..49fd6c5 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -2838,6 +2838,16 @@ static int mt7915_sta_tx_amsdu_set(void *data, u64 tx_amsdu)
diff --git a/recipes-wifi/linux-mt76/files/patches/1043-wifi-mt76-mt7915-add-cheetah-eeprom-related-fix.patch b/recipes-wifi/linux-mt76/files/patches/1043-wifi-mt76-mt7915-add-cheetah-eeprom-related-fix.patch
deleted file mode 100644
index 9ff6874..0000000
--- a/recipes-wifi/linux-mt76/files/patches/1043-wifi-mt76-mt7915-add-cheetah-eeprom-related-fix.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 02120d0ab9b6d2f864706c2a0d6583c7b8fc60e8 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Tue, 31 Oct 2023 16:28:52 +0800
-Subject: [PATCH] wifi: mt76: mt7915: add cheetah eeprom related fix
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7915/eeprom.h | 3 ++-
- mt7915/main.c   | 5 +++--
- 2 files changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h
-index 9056d78..a1ab05a 100644
---- a/mt7915/eeprom.h
-+++ b/mt7915/eeprom.h
-@@ -160,7 +160,8 @@ static inline bool
- mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
- {
- 	u8 *eep = dev->mt76.eeprom.data;
--	u8 val = eep[MT_EE_WIFI_CONF + 7];
-+	u8 offs = is_mt7981(&dev->mt76) ? 8 : 7;
-+	u8 val = eep[MT_EE_WIFI_CONF + offs];
- 
- 	if (band == NL80211_BAND_2GHZ)
- 		return val & MT_EE_WIFI_CONF7_TSSI0_2G;
-diff --git a/mt7915/main.c b/mt7915/main.c
-index 797a3b4..9ab93f4 100644
---- a/mt7915/main.c
-+++ b/mt7915/main.c
-@@ -1110,8 +1110,9 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
- 
- 	phy->mt76->antenna_mask = tx_ant;
- 
--	/* handle a variant of mt7916 which has 3T3R but nss2 on 5 GHz band */
--	if (is_mt7916(&dev->mt76) && band && hweight8(tx_ant) == max_nss)
-+	/* handle a variant of mt7916/mt7981 which has 3T3R but nss2 on 5 GHz band */
-+	if ((is_mt7916(&dev->mt76) || is_mt7981(&dev->mt76)) &&
-+	    band && hweight8(tx_ant) == max_nss)
- 		phy->mt76->chainmask = (dev->chainmask >> chainshift) << chainshift;
- 	else
- 		phy->mt76->chainmask = tx_ant << (chainshift * band);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/1044-wifi-mt76-testmode-add-cheetah-support.patch b/recipes-wifi/linux-mt76/files/patches/1043-wifi-mt76-testmode-add-cheetah-support.patch
similarity index 88%
rename from recipes-wifi/linux-mt76/files/patches/1044-wifi-mt76-testmode-add-cheetah-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1043-wifi-mt76-testmode-add-cheetah-support.patch
index 0f53710..6aef19c 100644
--- a/recipes-wifi/linux-mt76/files/patches/1044-wifi-mt76-testmode-add-cheetah-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1043-wifi-mt76-testmode-add-cheetah-support.patch
@@ -1,7 +1,7 @@
-From 14b505d62c856f210ce46e831886ae0fab253252 Mon Sep 17 00:00:00 2001
+From 5186827e8a40a71363aa2c7cc3aef1fafae3665f Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Tue, 31 Oct 2023 16:29:13 +0800
-Subject: [PATCH] wifi: mt76: testmode: add cheetah support
+Subject: [PATCH 55/76] wifi: mt76: testmode: add cheetah support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  4 files changed, 37 insertions(+), 8 deletions(-)
 
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index f8166dd..50ed7ba 100644
+index b96776d..c8ea1d9 100644
 --- a/mt7915/eeprom.c
 +++ b/mt7915/eeprom.c
 @@ -39,8 +39,7 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
@@ -56,10 +56,10 @@
  
  #endif
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index cd4f472..492cfcd 100644
+index ac015ab..2b41feb 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3035,13 +3035,30 @@ static int mt7915_dpd_freq_idx(struct mt7915_dev *dev, u16 freq, u8 bw)
+@@ -3040,13 +3040,30 @@ static int mt7915_dpd_freq_idx(struct mt7915_dev *dev, u16 freq, u8 bw)
  		/* 5G BW160 */
  		5250, 5570, 5815
  	};
@@ -93,10 +93,10 @@
  
  	if (freq < 4000) {
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 5e20cb9..4aa7eb6 100644
+index faf6014..ecd6271 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
-@@ -2149,7 +2149,7 @@ mt7915_tm_group_prek(struct mt7915_phy *phy, enum mt76_testmode_state state)
+@@ -2151,7 +2151,7 @@ mt7915_tm_group_prek(struct mt7915_phy *phy, enum mt76_testmode_state state)
  	eeprom = mdev->eeprom.data;
  	dev->cur_prek_offset = 0;
  	group_size = mt7915_get_cal_group_size(dev);
@@ -105,7 +105,7 @@
  	size = group_size + dpd_size;
  	offs = is_mt7915(&dev->mt76) ? MT_EE_DO_PRE_CAL : MT_EE_DO_PRE_CAL_V2;
  
-@@ -2231,11 +2231,11 @@ mt7915_tm_dpd_prek(struct mt7915_phy *phy, enum mt76_testmode_state state)
+@@ -2233,11 +2233,11 @@ mt7915_tm_dpd_prek(struct mt7915_phy *phy, enum mt76_testmode_state state)
  	eeprom = mdev->eeprom.data;
  	dev->cur_prek_offset = 0;
  	group_size = mt7915_get_cal_group_size(dev);
@@ -118,7 +118,7 @@
  		offs = MT_EE_DO_PRE_CAL;
  	} else {
  		dev->dpd_chan_num_5g = hweight32(DPD_5G_CH_BW20_BITMAP_0) +
-@@ -2244,7 +2244,8 @@ mt7915_tm_dpd_prek(struct mt7915_phy *phy, enum mt76_testmode_state state)
+@@ -2246,7 +2246,8 @@ mt7915_tm_dpd_prek(struct mt7915_phy *phy, enum mt76_testmode_state state)
  		dev->dpd_chan_num_6g = hweight32(DPD_6G_CH_BW20_BITMAP_0) +
  				       hweight32(DPD_6G_CH_BW20_BITMAP_1) +
  				       ARRAY_SIZE(bw160_6g_freq);
@@ -128,7 +128,7 @@
  		offs = MT_EE_DO_PRE_CAL_V2;
  	}
  	size = group_size + dpd_size;
-@@ -2707,7 +2708,7 @@ mt7915_tm_dump_precal(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int
+@@ -2711,7 +2712,7 @@ mt7915_tm_dump_precal(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int
  	}
  
  	group_size = mt7915_get_cal_group_size(dev);
diff --git a/recipes-wifi/linux-mt76/files/patches/1044-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch b/recipes-wifi/linux-mt76/files/patches/1044-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch
new file mode 100644
index 0000000..9d52762
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/1044-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch
@@ -0,0 +1,78 @@
+From c3880a47f6c4b0b8c2f2d2eb7824cb3545db8a60 Mon Sep 17 00:00:00 2001
+From: "Henry.Yen" <henry.yen@mediatek.com>
+Date: Mon, 11 Dec 2023 16:01:55 +0800
+Subject: [PATCH 56/76] wifi: mt76: mt7915 add mt7981 efuse variants support
+
+---
+ mt7915/eeprom.c | 22 ++++++++++++++++++++++
+ mt7915/mt7915.h |  7 ++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
+index c8ea1d9..b21763a 100644
+--- a/mt7915/eeprom.c
++++ b/mt7915/eeprom.c
+@@ -174,6 +174,21 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
+ 	return mt7915_check_eeprom(dev);
+ }
+ 
++static int mt7915_eeprom_parse_efuse_hw_cap(struct mt7915_dev *dev)
++{
++#define WTBL_SIZE_GROUP		GENMASK(1, 0)
++	u32 buf;
++	int ret;
++
++	ret = mt76_get_of_data_from_nvmem(&dev->mt76, &buf, "variant", 4);
++	if (ret)
++		return ret;
++
++	dev->limited_wtbl_size = buf & WTBL_SIZE_GROUP;
++
++	return 0;
++}
++
+ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
+ {
+ 	struct mt7915_dev *dev = phy->dev;
+@@ -224,6 +239,13 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
+ 	u8 path, nss, nss_max = 4, *eeprom = dev->mt76.eeprom.data;
+ 	struct mt76_phy *mphy = phy->mt76;
+ 	u8 band = phy->mt76->band_idx;
++	int ret;
++
++	if (is_mt7981(&dev->mt76)) {
++		ret = mt7915_eeprom_parse_efuse_hw_cap(dev);
++		if (ret)
++			dev->limited_wtbl_size = true;
++	}
+ 
+ 	mt7915_eeprom_parse_band_config(phy);
+ 
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index ad08582..47349b9 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -361,6 +361,7 @@ struct mt7915_dev {
+ 
+ 	u32 hw_pattern;
+ 
++	bool limited_wtbl_size;
+ 	bool dbdc_support;
+ 	bool flash_mode;
+ 	bool bin_file_mode;
+@@ -625,7 +626,11 @@ void mt7915_tm_rf_test_event(struct mt7915_dev *dev, struct sk_buff *skb);
+ 
+ static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
+ {
+-	return is_mt7915(&dev->mt76) ? MT7915_WTBL_SIZE : MT7916_WTBL_SIZE;
++	if (is_mt7915(&dev->mt76) ||
++	    (is_mt7981(&dev->mt76) && dev->limited_wtbl_size))
++		return MT7915_WTBL_SIZE;
++
++	return MT7916_WTBL_SIZE;
+ }
+ 
+ static inline u16 mt7915_eeprom_size(struct mt7915_dev *dev)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/1045-wifi-mt76-mt7915-support-scs-feature.patch b/recipes-wifi/linux-mt76/files/patches/1045-wifi-mt76-mt7915-support-scs-feature.patch
new file mode 100644
index 0000000..4cb13d3
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/1045-wifi-mt76-mt7915-support-scs-feature.patch
@@ -0,0 +1,383 @@
+From 775a9c8aa928a43fd4eaf8d252c5691dcce8fd08 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Wed, 6 Dec 2023 08:53:03 +0800
+Subject: [PATCH] wifi: mt76: mt7915: support scs feature
+
+Add support scs feature for connac2 codebase. This commit includes three
+parts.
+1. enable scs feature when interface is up.
+2. support configure scs feature on/off by debugfs scs_enable.
+3. Firmware needs driver to provide the tx_bytes, rx_bytes,
+active_station_number, total throughtput and min rssi of all connected
+stations. In mt76 driver, we run a delayed work to send all must-need
+statistics through mcu command every second.
+
+Please noted that the scs feature is only enable for apsoc is 7986 or
+7981 (WED Rx 2.0).
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt76.h               |   2 +
+ mt76_connac_mcu.h    |   1 +
+ mt7915/init.c        |   1 +
+ mt7915/mac.c         |  11 ++++
+ mt7915/main.c        |  13 +++++
+ mt7915/mcu.c         | 118 +++++++++++++++++++++++++++++++++++++++++++
+ mt7915/mcu.h         |   4 ++
+ mt7915/mt7915.h      |  13 +++++
+ mt7915/mtk_debugfs.c |  24 +++++++++
+ 9 files changed, 187 insertions(+)
+
+diff --git a/mt76.h b/mt76.h
+index 4704c50..c0fdbd6 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -310,6 +310,7 @@ struct mt76_sta_stats {
+ 	u64 tx_nss[4];		/* 1, 2, 3, 4 */
+ 	u64 tx_mcs[16];		/* mcs idx */
+ 	u64 tx_bytes;
++	u64 last_tx_bytes;
+ 	/* WED TX */
+ 	u32 tx_packets;		/* unit: MSDU */
+ 	u32 tx_retries;
+@@ -319,6 +320,7 @@ struct mt76_sta_stats {
+ 	u32 rx_packets;
+ 	u32 rx_errors;
+ 	u32 rx_drops;
++	u64 last_rx_bytes;
+ };
+ 
+ enum mt76_wcid_flags {
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index bf5ab81..48874d1 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1222,6 +1222,7 @@ enum {
+ 	MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
+ 	MCU_EXT_CMD_MWDS_SUPPORT = 0x80,
+ 	MCU_EXT_CMD_SET_SER_TRIGGER = 0x81,
++	MCU_EXT_CMD_SCS_FEATURE_CTRL = 0x82,
+ 	MCU_EXT_CMD_TWT_AGRT_UPDATE = 0x94,
+ 	MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
+ 	MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
+diff --git a/mt7915/init.c b/mt7915/init.c
+index 53dea70..cab711c 100644
+--- a/mt7915/init.c
++++ b/mt7915/init.c
+@@ -1244,6 +1244,7 @@ int mt7915_register_device(struct mt7915_dev *dev)
+ 	spin_lock_init(&dev->phy.stats_lock);
+ 	INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work);
+ 	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
++	INIT_DELAYED_WORK(&dev->scs_work, mt7915_mcu_scs_sta_poll);
+ 	INIT_LIST_HEAD(&dev->sta_rc_list);
+ 	INIT_LIST_HEAD(&dev->twt_list);
+ 
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index e5480ee..0e8c64e 100644
+--- a/mt7915/mac.c
++++ b/mt7915/mac.c
+@@ -1503,6 +1503,8 @@ mt7915_mac_full_reset(struct mt7915_dev *dev)
+ 	if (ext_phy)
+ 		cancel_delayed_work_sync(&ext_phy->mac_work);
+ 
++	cancel_delayed_work_sync(&dev->scs_work);
++
+ 	mutex_lock(&dev->mt76.mutex);
+ 	for (i = 0; i < 10; i++) {
+ 		if (!mt7915_mac_restart(dev))
+@@ -1528,6 +1530,10 @@ mt7915_mac_full_reset(struct mt7915_dev *dev)
+ 		ieee80211_queue_delayed_work(ext_phy->hw,
+ 					     &ext_phy->mac_work,
+ 					     MT7915_WATCHDOG_TIME);
++
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++	    mtk_wed_get_rx_capa(&dev->mt76.mmio.wed))
++		ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
+ }
+ 
+ /* system error recovery */
+@@ -1592,6 +1598,7 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 		set_bit(MT76_RESET, &phy2->mt76->state);
+ 		cancel_delayed_work_sync(&phy2->mt76->mac_work);
+ 	}
++	cancel_delayed_work_sync(&dev->scs_work);
+ 	mt76_worker_disable(&dev->mt76.tx_worker);
+ 	mt76_for_each_q_rx(&dev->mt76, i)
+ 		napi_disable(&dev->mt76.napi[i]);
+@@ -1653,6 +1660,10 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 					     &phy2->mt76->mac_work,
+ 					     MT7915_WATCHDOG_TIME);
+ 
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++	    mtk_wed_get_rx_capa(&dev->mt76.mmio.wed))
++		ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
++
+ 	dev_info(dev->mt76.dev,"\n%s L1 SER recovery completed.",
+ 		 wiphy_name(dev->mt76.hw->wiphy));
+ }
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 0318254..5be931b 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -95,12 +95,24 @@ int mt7915_run(struct ieee80211_hw *hw)
+ 	if (ret)
+ 		goto out;
+ 
++	/* Enable SCS if and only if WED Rx (2.0 and after) is supported. */
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++	    mtk_wed_get_rx_capa(&dev->mt76.mmio.wed) &&
++	    !mt76_testmode_enabled(phy->mt76)) {
++		ret = mt7915_mcu_set_scs_en(phy, true);
++		if (ret)
++			goto out;
++	}
++
+ 	set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
+ 
+ 	if (!mt76_testmode_enabled(phy->mt76))
+ 		ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
+ 					     MT7915_WATCHDOG_TIME);
+ 
++	if (!running && phy->scs_ctrl.scs_enable)
++		ieee80211_queue_delayed_work(hw, &dev->scs_work, HZ);
++
+ 	if (!running)
+ 		mt7915_mac_reset_counters(phy);
+ 
+@@ -141,6 +153,7 @@ static void mt7915_stop(struct ieee80211_hw *hw)
+ 	}
+ 
+ 	if (!mt7915_dev_running(dev)) {
++		cancel_delayed_work_sync(&dev->scs_work);
+ 		mt76_connac_mcu_set_pm(&dev->mt76, dev->phy.mt76->band_idx, 1);
+ 		mt7915_mcu_set_mac(dev, dev->phy.mt76->band_idx, false, false);
+ 	}
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 2b41feb..38679d2 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -5043,3 +5043,121 @@ int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val)
+ 	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SWLNA_ACI_CTRL), &req,
+ 				 sizeof(req), NULL);
+ }
++
++int mt7915_mcu_set_scs_en(struct mt7915_phy *phy, u8 enable)
++{
++	struct mt7915_dev *dev = phy->dev;
++	struct {
++		__le32 subcmd;
++		u8 band_idx;
++		u8 enable;
++	} __packed req = {
++		.subcmd = cpu_to_le32(SCS_ENABLE),
++		.band_idx = phy->mt76->band_idx,
++		.enable = enable + 1,
++	};
++
++	phy->scs_ctrl.scs_enable = !!enable;
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SCS_FEATURE_CTRL),
++				 &req, sizeof(req), NULL);
++}
++
++void mt7915_sta_scs_para(void *data, struct ieee80211_sta *sta)
++{
++#define SCS_ACTIVE_STA_CRITERIA_2M 250000
++	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
++	struct mt7915_phy *poll_phy = (struct mt7915_phy *)data;
++	u8 band_idx = msta->wcid.phy_idx;
++	s64 tx_bytes_last_sec, rx_bytes_last_sec;
++	u64 total_bytes_last_sec;
++
++	if (band_idx > MT_BAND1)
++		return;
++
++	tx_bytes_last_sec = (s64)msta->wcid.stats.tx_bytes -
++			    (s64)msta->wcid.stats.last_tx_bytes;
++	rx_bytes_last_sec = (s64)msta->wcid.stats.rx_bytes -
++			    (s64)msta->wcid.stats.last_rx_bytes;
++
++	/**
++	 * Since wo reports rx stats every 900ms, it needs to be converted as
++	 * statistics every one second.
++	 */
++	rx_bytes_last_sec = rx_bytes_last_sec / 9 * 10;
++
++	poll_phy->scs_ctrl.tx_bytes_last_sec += tx_bytes_last_sec;
++	poll_phy->scs_ctrl.rx_bytes_last_sec += rx_bytes_last_sec;
++
++	total_bytes_last_sec = tx_bytes_last_sec + rx_bytes_last_sec;
++	if (total_bytes_last_sec > SCS_ACTIVE_STA_CRITERIA_2M) {
++		poll_phy->scs_ctrl.tput += total_bytes_last_sec >> 17;
++		poll_phy->scs_ctrl.active_sta++;
++	}
++
++	msta->wcid.stats.last_tx_bytes = msta->wcid.stats.tx_bytes;
++	msta->wcid.stats.last_rx_bytes = msta->wcid.stats.rx_bytes;
++
++	if (poll_phy->scs_ctrl.sta_min_rssi > msta->ack_signal)
++		poll_phy->scs_ctrl.sta_min_rssi = msta->ack_signal;
++}
++
++int mt7915_mcu_set_scs_stats(struct mt7915_phy *phy)
++{
++	struct mt7915_dev *dev = phy->dev;
++	struct {
++		__le32 subcmd;
++		u8 band_idx;
++		u8 active_sta;
++		__le16 tput;
++		bool rx_only_mode;
++		u8 __rsv;
++		s8 min_rssi;
++	} __packed req = {
++		.subcmd = cpu_to_le32(SCS_SEND_DATA),
++		.band_idx = phy->mt76->band_idx,
++		.active_sta = phy->scs_ctrl.active_sta,
++		.tput = cpu_to_le16(phy->scs_ctrl.tput),
++		.rx_only_mode = false,
++		.min_rssi = phy->scs_ctrl.sta_min_rssi,
++	};
++
++	/* Rx only mode is that Rx percentage is larger than 90% */
++	if (phy->scs_ctrl.tx_bytes_last_sec < phy->scs_ctrl.rx_bytes_last_sec / 9)
++		req.rx_only_mode = true;
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SCS_FEATURE_CTRL),
++				 &req, sizeof(req), NULL);
++}
++
++void mt7915_mcu_scs_sta_poll(struct work_struct *work)
++{
++	struct mt7915_dev *dev = container_of(work, struct mt7915_dev,
++					      scs_work.work);
++	struct mt7915_phy *phy;
++	bool scs_enable_flag = false;
++	u8 i;
++
++	for (i = MT_BAND0; i < MT_BAND2; i++) {
++		if (!dev->mt76.phys[i])
++			continue;
++
++		phy = dev->mt76.phys[i]->priv;
++		if (!phy->scs_ctrl.scs_enable ||
++		    !test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
++			continue;
++
++		ieee80211_iterate_stations_atomic(dev->mt76.phys[i]->hw,
++						  mt7915_sta_scs_para, phy);
++
++		mt7915_mcu_set_scs_stats(phy);
++
++		memset(&phy->scs_ctrl, 0, sizeof(phy->scs_ctrl));
++		phy->scs_ctrl.scs_enable = true;
++
++		scs_enable_flag = true;
++	}
++
++	if (scs_enable_flag)
++		ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
++}
+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
+index 6e6f320..723f23e 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -1188,4 +1188,8 @@ struct mt7915_mcu_edcca_info {
+ };
+ #endif
+ 
++enum {
++	SCS_SEND_DATA = 0,
++	SCS_ENABLE = 3,
++};
+ #endif
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 47349b9..464eb3f 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -233,6 +233,15 @@ struct mt7915_air_monitor_ctrl {
+ };
+ #endif
+ 
++struct mt7915_scs_ctrl {
++	u64 tx_bytes_last_sec;
++	u64 rx_bytes_last_sec;
++	bool scs_enable;
++	s8 sta_min_rssi;
++	u16 tput;
++	u8 active_sta;
++};
++
+ struct mt7915_phy {
+ 	struct mt76_phy *mt76;
+ 	struct mt7915_dev *dev;
+@@ -306,6 +315,7 @@ struct mt7915_phy {
+ 
+ 	struct mt7915_air_monitor_ctrl amnt_ctrl;
+ #endif
++	struct mt7915_scs_ctrl scs_ctrl;
+ };
+ 
+ struct mt7915_dev {
+@@ -424,6 +434,7 @@ struct mt7915_dev {
+ 	} dbg;
+ 	const struct mt7915_dbg_reg_desc *dbg_reg;
+ #endif
++	struct delayed_work scs_work;
+ };
+ 
+ enum {
+@@ -746,6 +757,8 @@ int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val);
+ int mt7915_mcu_ipi_hist_ctrl(struct mt7915_phy *phy, void *data, u8 cmd, bool wait_resp);
+ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp);
+ int mt7915_mcu_enable_obss_spr(struct mt7915_phy *phy, u8 action, u8 val);
++int mt7915_mcu_set_scs_en(struct mt7915_phy *phy, u8 enable);
++void mt7915_mcu_scs_sta_poll(struct work_struct *work);
+ 
+ #ifdef MTK_DEBUG
+ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir);
+diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
+index 49fd6c5..d8e7589 100644
+--- a/mt7915/mtk_debugfs.c
++++ b/mt7915/mtk_debugfs.c
+@@ -3676,6 +3676,29 @@ mt7915_sr_enable_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enable, NULL,
+ 			 mt7915_sr_enable_set, "%llx\n");
+ 
++static int
++mt7915_scs_enable_set(void *data, u64 val)
++{
++	struct mt7915_phy *phy = data;
++	int ret;
++
++	/* Enable scs if and only if WED Rx (2.0 and after) is supported */
++	if (!mtk_wed_device_active(&phy->dev->mt76.mmio.wed) ||
++	    !mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed))
++		return 0;
++
++	ret = mt7915_mcu_set_scs_en(phy, (u8) val);
++	if (ret)
++		return ret;
++
++	if (phy->scs_ctrl.scs_enable)
++		ieee80211_queue_delayed_work(phy->mt76->hw, &phy->dev->scs_work, HZ);
++
++	return 0;
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_scs_enable, NULL,
++			 mt7915_scs_enable_set, "%lld\n");
++
+ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7915_dev *dev = phy->dev;
+@@ -3768,6 +3791,7 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+ 	debugfs_create_file("sw_aci", 0600, dir, dev,
+ 			    &fops_sw_aci);
+ 	debugfs_create_file("sr_enable", 0200, dir, phy, &fops_sr_enable);
++	debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
+ 	return 0;
+ }
+ #endif
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch b/recipes-wifi/linux-mt76/files/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch
index 4a0e51b..773f894 100644
--- a/recipes-wifi/linux-mt76/files/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch
@@ -1,19 +1,33 @@
-From 9ea9f8159f6d14dd41c65bf437cde772efcbb8ea Mon Sep 17 00:00:00 2001
+From 9182ca1fd7e9df4dc89a80105137edd62c00d924 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Fri, 25 Nov 2022 10:38:53 +0800
-Subject: [PATCH 2000/2011] wifi: mt76: mt7915: wed: add wed tx support
+Subject: [PATCH 58/76] wifi: mt76: mt7915: wed: add wed tx support
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
+ mmio.c          |  2 +-
  mt76_connac.h   |  1 +
  mt7915/mac.c    | 10 +++++++---
  mt7915/main.c   |  4 ++--
- mt7915/mmio.c   |  5 +++--
+ mt7915/mmio.c   |  3 ++-
  mt7915/mt7915.h |  2 +-
- 5 files changed, 14 insertions(+), 8 deletions(-)
+ 6 files changed, 14 insertions(+), 8 deletions(-)
 
+diff --git a/mmio.c b/mmio.c
+index 6e25a14..d9d5047 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -194,7 +194,7 @@ void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+ 
+ 	spin_lock_bh(&dev->token_lock);
+-	dev->token_size = dev->drv->token_size;
++	dev->token_size = wed->wlan.token_start;
+ 	spin_unlock_bh(&dev->token_lock);
+ }
+ EXPORT_SYMBOL_GPL(mt76_mmio_wed_offload_disable);
 diff --git a/mt76_connac.h b/mt76_connac.h
-index 6f5cf18..76f9555 100644
+index 6c8a453..e482a7e 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
 @@ -130,6 +130,7 @@ struct mt76_connac_sta_key_conf {
@@ -25,10 +39,10 @@
  struct mt76_connac_fw_txp {
  	__le16 flags;
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index e51440d..3c6b308 100644
+index 0e8c64e..8aeee3c 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -869,9 +869,9 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
+@@ -870,9 +870,9 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
  
  	txp->token = cpu_to_le16(token_id);
  	txp->nbuf = 1;
@@ -40,7 +54,7 @@
  }
  
  static void
-@@ -920,6 +920,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -921,6 +921,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
  	LIST_HEAD(free_list);
  	void *end = data + len;
  	bool v3, wake = false;
@@ -48,7 +62,7 @@
  	u16 total, count = 0;
  	u32 txd = le32_to_cpu(free->txd);
  	__le32 *cur_info;
-@@ -1001,6 +1002,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -1002,6 +1003,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
  			txwi = mt76_token_release(mdev, msdu, &wake);
  			if (!txwi)
  				continue;
@@ -57,7 +71,7 @@
  
  			txwi->jiffies = 0;
  
-@@ -1008,7 +1011,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -1009,7 +1012,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
  		}
  	}
  
@@ -68,10 +82,10 @@
  
  static void
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 5b4581c..7274b5d 100644
+index 2e1f4b9..659ae48 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1685,14 +1685,14 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1708,14 +1708,14 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
  	if (!mtk_wed_device_active(wed))
  		return -ENODEV;
  
@@ -89,7 +103,7 @@
  
  	ctx->dev = NULL;
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index b47bfff..cae8b81 100644
+index 06f5a19..cdfd35f 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -13,7 +13,7 @@
@@ -101,16 +115,7 @@
  module_param(wed_enable, bool, 0644);
  MODULE_PARM_DESC(wed_enable, "Enable Wireless Ethernet Dispatch support");
  
-@@ -607,7 +607,7 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- 
- 	spin_lock_bh(&dev->mt76.token_lock);
--	dev->mt76.token_size = MT7915_TOKEN_SIZE;
-+	dev->mt76.token_size = wed->wlan.token_start;//MT7915_TOKEN_SIZE
- 	spin_unlock_bh(&dev->mt76.token_lock);
- }
- 
-@@ -855,6 +855,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -736,6 +736,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  
  	*irq = wed->irq;
  	dev->mt76.dma_dev = wed->dev;
@@ -119,7 +124,7 @@
  	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
  	if (ret)
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 72d6cc0..af9e3ae 100644
+index 464eb3f..bb0a806 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -62,7 +62,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch b/recipes-wifi/linux-mt76/files/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch
index da1686e..467d98e 100644
--- a/recipes-wifi/linux-mt76/files/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch
@@ -1,8 +1,8 @@
-From 3256ae03ed8d4b0c9aca091c7c183b91ca595db7 Mon Sep 17 00:00:00 2001
+From 1c87f95ce8be271a28470bf1d2809aed425c6870 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Tue, 13 Dec 2022 17:51:26 +0800
-Subject: [PATCH 2001/2011] wifi: mt76: mt7915: wed: add wds support when wed
- is enabled
+Subject: [PATCH 59/76] wifi: mt76: mt7915: wed: add wds support when wed is
+ enabled
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
@@ -15,11 +15,11 @@
  6 files changed, 82 insertions(+), 10 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index ad1402a..d00ef21 100644
+index c0fdbd6..a54da76 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -68,6 +68,12 @@ enum mt76_wed_type {
- 	MT76_WED_Q_RX,
+@@ -78,6 +78,12 @@ enum mt76_wed_type {
+ 	MT76_WED_RRO_Q_IND,
  };
  
 +enum mt76_wed_state {
@@ -32,10 +32,10 @@
  	u32 (*rr)(struct mt76_dev *dev, u32 offset);
  	void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 7274b5d..e274f02 100644
+index 659ae48..bbfb643 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -773,8 +773,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -788,8 +788,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  #endif
  	int ret, idx;
  	u32 addr;
@@ -52,7 +52,7 @@
  	if (idx < 0)
  		return -ENOSPC;
  
-@@ -1253,6 +1260,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
+@@ -1276,6 +1283,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
  	else
  		clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
  
@@ -66,7 +66,7 @@
  	mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
  }
  
-@@ -1692,8 +1706,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1715,8 +1729,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
  	path->dev = ctx->dev;
  	path->mtk_wdma.wdma_idx = wed->wdma_idx;
  	path->mtk_wdma.bss = mvif->mt76.idx;
@@ -81,7 +81,7 @@
  	ctx->dev = NULL;
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index cd4f472..d8b9318 100644
+index 38679d2..405bdfc 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -2397,10 +2397,18 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev)
@@ -108,7 +108,7 @@
  	ret = mt7915_mcu_set_mwds(dev, 1);
  	if (ret)
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 6e6f320..825bb7d 100644
+index 723f23e..3b169d6 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -339,6 +339,7 @@ enum {
diff --git a/recipes-wifi/linux-mt76/files/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch b/recipes-wifi/linux-mt76/files/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch
index a3eadce..1a25989 100644
--- a/recipes-wifi/linux-mt76/files/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch
@@ -1,7 +1,7 @@
-From db9a693311a05bb9df09d59b940b0006953ea93f Mon Sep 17 00:00:00 2001
+From d14b8c573cb2b131505eab63751fc8cb10afea77 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 19 May 2023 07:05:22 +0800
-Subject: [PATCH 2002/2011] wifi: mt76: mt7915: wed: add fill receive path to
+Subject: [PATCH 60/76] wifi: mt76: mt7915: wed: add fill receive path to
  report wed idx
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
@@ -10,13 +10,14 @@
  1 file changed, 18 insertions(+)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index e274f02..f08fb2d 100644
+index bbfb643..72ad108 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1718,6 +1718,23 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1740,6 +1740,23 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+ 
  	return 0;
  }
- 
++
 +static int
 +mt7915_net_fill_receive_path(struct ieee80211_hw *hw,
 +			     struct net_device_path_ctx *ctx,
@@ -33,16 +34,15 @@
 +
 +	return 0;
 +}
-+
- static int
- mt7915_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 		    struct net_device *netdev, enum tc_setup_type type,
-@@ -1785,6 +1802,7 @@ const struct ieee80211_ops mt7915_ops = {
+ #endif
+ 
+ const struct ieee80211_ops mt7915_ops = {
+@@ -1794,6 +1811,7 @@ const struct ieee80211_ops mt7915_ops = {
  	.set_radar_background = mt7915_set_radar_background,
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
  	.net_fill_forward_path = mt7915_net_fill_forward_path,
 +	.net_fill_receive_path = mt7915_net_fill_receive_path,
- 	.net_setup_tc = mt7915_net_setup_tc,
+ 	.net_setup_tc = mt76_net_setup_tc,
  #endif
  };
 -- 
diff --git a/recipes-wifi/linux-mt76/files/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch b/recipes-wifi/linux-mt76/files/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
index 16b9a1a..e2feee5 100644
--- a/recipes-wifi/linux-mt76/files/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
@@ -1,7 +1,7 @@
-From 51125c922550f392c705ef3aa1151eb92105e88a Mon Sep 17 00:00:00 2001
+From 20b4bf7d7c23e79dc6dd8d067ddeb2c5e7358f92 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Fri, 25 Nov 2022 14:32:35 +0800
-Subject: [PATCH 2003/2011] wifi: mt76: mt7915: wed: find rx token by physical
+Subject: [PATCH 61/76] wifi: mt76: mt7915: wed: find rx token by physical
  address
 
 The token id in RxDMAD may be incorrect when it is not the last frame due to
@@ -13,13 +13,13 @@
  1 file changed, 24 insertions(+), 1 deletion(-)
 
 diff --git a/dma.c b/dma.c
-index 8049830..e877d26 100644
+index d338424..b2b30d6 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -405,9 +405,32 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -446,9 +446,32 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 	mt76_dma_should_drop_buf(drop, ctrl, buf1, desc_info);
  
  	if (mt76_queue_is_wed_rx(q)) {
- 		u32 buf1 = le32_to_cpu(desc->buf1);
 +		u32 id, find = 0;
  		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
 -		struct mt76_txwi_cache *t = mt76_rx_token_release(dev, token);
diff --git a/recipes-wifi/linux-mt76/files/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch b/recipes-wifi/linux-mt76/files/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
index c30f05a..8c280bf 100644
--- a/recipes-wifi/linux-mt76/files/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
@@ -1,7 +1,7 @@
-From c6f5b4acf35c16b737f9dd72c4fc7245ed7224dc Mon Sep 17 00:00:00 2001
+From eff1a6ef317006da115f694dab8e5ba721771929 Mon Sep 17 00:00:00 2001
 From: Lian Chen <lian.chen@mediatek.com>
 Date: Mon, 7 Nov 2022 14:47:44 +0800
-Subject: [PATCH 2004/2012] wifi: mt76: mt7915: wed: HW ATF support for mt7986
+Subject: [PATCH] wifi: mt76: mt7915: wed: HW ATF support for mt7986
 
 Signed-off-by: Lian Chen <lian.chen@mediatek.com>
 Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
@@ -12,14 +12,14 @@
  mt7915/main.c        |  14 ++
  mt7915/mcu.c         | 169 +++++++++++++++++-
  mt7915/mt7915.h      |  69 ++++++++
- mt7915/mtk_debugfs.c | 131 +++++++++++++-
- 7 files changed, 844 insertions(+), 4 deletions(-)
+ mt7915/mtk_debugfs.c | 130 ++++++++++++++
+ 7 files changed, 844 insertions(+), 3 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 4925890..9ad1883 100644
+index 48874d1..22a6779 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1175,6 +1175,7 @@ enum {
+@@ -1196,6 +1196,7 @@ enum {
  	MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
  	MCU_EXT_CMD_WTBL_UPDATE = 0x32,
  	MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
@@ -27,7 +27,7 @@
  	MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
  	MCU_EXT_CMD_ATE_CTRL = 0x3d,
  	MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
-@@ -1184,6 +1185,7 @@ enum {
+@@ -1205,6 +1206,7 @@ enum {
  	MCU_EXT_CMD_MUAR_UPDATE = 0x48,
  	MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
  	MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a,
@@ -466,10 +466,10 @@
  	if (!dev->dbdc_support || phy->mt76->band_idx) {
  		debugfs_create_u32("dfs_hw_pattern", 0400, dir,
 diff --git a/mt7915/init.c b/mt7915/init.c
-index e31a5a6..c643c33 100644
+index cab711c..e00c667 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -607,10 +607,65 @@ mt7915_init_led_mux(struct mt7915_dev *dev)
+@@ -608,10 +608,65 @@ mt7915_init_led_mux(struct mt7915_dev *dev)
  	}
  }
  
@@ -535,7 +535,7 @@
  
  	/* config pse qid6 wfdma port selection */
  	if (!is_mt7915(&dev->mt76) && dev->hif2)
-@@ -634,6 +689,9 @@ void mt7915_mac_init(struct mt7915_dev *dev)
+@@ -635,6 +690,9 @@ void mt7915_mac_init(struct mt7915_dev *dev)
  		mt7915_mac_init_band(dev, i);
  
  	mt7915_init_led_mux(dev);
@@ -546,10 +546,10 @@
  
  int mt7915_txbf_init(struct mt7915_dev *dev)
 diff --git a/mt7915/main.c b/mt7915/main.c
-index ee58f1c..040bc75 100644
+index 26ea989..9a3c1db 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -219,6 +219,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
+@@ -232,6 +232,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
  {
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
  	struct mt7915_dev *dev = phy->dev;
@@ -557,7 +557,7 @@
  	struct mt76_txq *mtxq;
  	bool ext_phy = phy != &dev->phy;
  	int idx, ret = 0;
-@@ -281,6 +282,9 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
+@@ -294,6 +295,9 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
  	mt7915_mcu_add_sta(dev, vif, NULL, true);
  	rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
  
@@ -567,7 +567,7 @@
  	return ret;
  }
  
-@@ -771,6 +775,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -784,6 +788,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
  	bool ext_phy = mvif->phy != &dev->phy;
@@ -575,7 +575,7 @@
  #ifdef CONFIG_MTK_VENDOR
  	struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy;
  #endif
-@@ -821,6 +826,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -834,6 +839,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (phy->muru_onoff & MUMIMO_DL_CERT)
  		mt7915_mcu_set_mimo(phy, 0);
  #endif
@@ -592,7 +592,7 @@
  }
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 45344ac..636a2ab 100644
+index 405bdfc..d66b42a 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -1674,7 +1674,7 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
@@ -624,7 +624,7 @@
  	ret = mt7915_mcu_add_group(dev, vif, sta);
  	if (ret) {
  		dev_kfree_skb(skb);
-@@ -3601,6 +3601,169 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
+@@ -3623,6 +3623,169 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
  				 &req, sizeof(req), false);
  }
  
@@ -795,7 +795,7 @@
  {
  #define MT_BF_PROCESSING	4
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 0c0bd82..90bfc47 100644
+index bb0a806..cc4c402 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -141,6 +141,58 @@ struct mt7915_twt_flow {
@@ -865,16 +865,16 @@
  };
  
  struct mt7915_vif_cap {
-@@ -423,6 +476,8 @@ struct mt7915_dev {
- 	} dbg;
+@@ -435,6 +488,8 @@ struct mt7915_dev {
  	const struct mt7915_dbg_reg_desc *dbg_reg;
  #endif
+ 	struct delayed_work scs_work;
 +	struct delayed_work vow_work;
 +	struct mt7915_vow_cfg vow_cfg;
  };
  
  enum {
-@@ -455,6 +510,15 @@ enum mt7915_rdd_cmd {
+@@ -467,6 +522,15 @@ enum mt7915_rdd_cmd {
  	RDD_IRQ_OFF,
  };
  
@@ -890,7 +890,7 @@
  static inline struct mt7915_phy *
  mt7915_hw_phy(struct ieee80211_hw *hw)
  {
-@@ -584,6 +648,11 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
+@@ -596,6 +660,11 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
  int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
  			      u8 en);
  int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
@@ -903,18 +903,10 @@
  int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
  int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 9fe7dcb..9ff4c5c 100644
+index eaff887..387d51b 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
-@@ -1368,7 +1368,6 @@ static EMPTY_QUEUE_INFO_T ple_txcmd_queue_empty_info[] = {
- };
- 
- 
--
- static char* sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"};
- static u32 chip_show_sta_acq_info(struct seq_file *s, struct mt7915_dev *dev, u32 *ple_stat,
- 				  u32 *sta_pause, u32 *dis_sta_map,
-@@ -1520,6 +1519,136 @@ static void chip_get_sta_pause(struct mt7915_dev *dev, u32 *sta_pause)
+@@ -1518,6 +1518,136 @@ static void chip_get_sta_pause(struct mt7915_dev *dev, u32 *sta_pause)
  	}
  }
  
diff --git a/recipes-wifi/linux-mt76/files/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch b/recipes-wifi/linux-mt76/files/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch
index ecffb76..61121c8 100644
--- a/recipes-wifi/linux-mt76/files/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch
@@ -1,22 +1,23 @@
-From a71cacc640b5c4ddacdb4e3ce7c3571a08a2daa4 Mon Sep 17 00:00:00 2001
+From 2948ff57ae985d1698739c1a696d93c57aa462b5 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Fri, 6 Jan 2023 18:18:50 +0800
-Subject: [PATCH 2005/2011] wifi: mt76: mt7915: wed: add rxwi for further in
- chip rro
+Subject: [PATCH 63/76] wifi: mt76: mt7915: wed: add rxwi for further in chip
+ rro
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
  dma.c           | 93 +++++++++++++++++++++++++------------------------
  mac80211.c      |  2 +-
+ mmio.c          | 26 +++++++-------
  mt76.h          | 24 ++++++++-----
  mt7915/dma.c    |  2 --
- mt7915/mmio.c   | 29 +++++++--------
+ mt7915/mmio.c   |  3 +-
  mt7915/mt7915.h |  1 +
  tx.c            | 16 ++++-----
- 7 files changed, 87 insertions(+), 80 deletions(-)
+ 8 files changed, 87 insertions(+), 80 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index e877d26..e3e2f38 100644
+index b2b30d6..cf6ca04 100644
 --- a/dma.c
 +++ b/dma.c
 @@ -64,17 +64,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
@@ -54,8 +55,8 @@
 -	struct mt76_txwi_cache *t = NULL;
 +	struct mt76_rxwi_cache *r = NULL;
  
--	spin_lock(&dev->wed_lock);
-+	spin_lock(&dev->lock);
+-	spin_lock_bh(&dev->wed_lock);
++	spin_lock_bh(&dev->lock);
  	if (!list_empty(&dev->rxwi_cache)) {
 -		t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache,
 +		r = list_first_entry(&dev->rxwi_cache, struct mt76_rxwi_cache,
@@ -63,8 +64,8 @@
 -		list_del(&t->list);
 +		list_del(&r->list);
  	}
--	spin_unlock(&dev->wed_lock);
-+	spin_unlock(&dev->lock);
+-	spin_unlock_bh(&dev->wed_lock);
++	spin_unlock_bh(&dev->lock);
  
 -	return t;
 +	return r;
@@ -100,12 +101,12 @@
 +	if (!r)
  		return;
  
--	spin_lock(&dev->wed_lock);
+-	spin_lock_bh(&dev->wed_lock);
 -	list_add(&t->list, &dev->rxwi_cache);
--	spin_unlock(&dev->wed_lock);
-+	spin_lock(&dev->lock);
+-	spin_unlock_bh(&dev->wed_lock);
++	spin_lock_bh(&dev->lock);
 +	list_add(&r->list, &dev->rxwi_cache);
-+	spin_unlock(&dev->lock);
++	spin_unlock_bh(&dev->lock);
  }
  EXPORT_SYMBOL_GPL(mt76_put_rxwi);
  
@@ -128,17 +129,17 @@
  	}
  	local_bh_enable();
  }
-@@ -217,7 +217,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -230,7 +230,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ 		    struct mt76_queue_buf *buf, void *data)
  {
- 	struct mt76_desc *desc = &q->desc[q->head];
  	struct mt76_queue_entry *entry = &q->entry[q->head];
 -	struct mt76_txwi_cache *txwi = NULL;
 +	struct mt76_rxwi_cache *rxwi = NULL;
- 	u32 buf1 = 0, ctrl;
+ 	struct mt76_desc *desc;
  	int idx = q->head;
- 	int rx_token;
-@@ -225,13 +225,13 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+ 	u32 buf1 = 0, ctrl;
+@@ -251,13 +251,13 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ #endif
  
  	if (mt76_queue_is_wed_rx(q)) {
 -		txwi = mt76_get_rxwi(dev);
@@ -155,8 +156,8 @@
  			return -ENOMEM;
  		}
  
-@@ -246,7 +246,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 
+@@ -273,7 +273,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ done:
  	entry->dma_addr[0] = buf->addr;
  	entry->dma_len[0] = buf->len;
 -	entry->txwi = txwi;
@@ -164,7 +165,7 @@
  	entry->buf = data;
  	entry->wcid = 0xffff;
  	entry->skip_buf1 = true;
-@@ -259,7 +259,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -286,7 +286,7 @@ done:
  static int
  mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
  		 struct mt76_queue_buf *buf, int nbufs, u32 info,
@@ -173,7 +174,7 @@
  {
  	struct mt76_queue_entry *entry;
  	struct mt76_desc *desc;
-@@ -312,6 +312,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -346,6 +346,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
  	}
  
  	q->entry[idx].txwi = txwi;
@@ -181,8 +182,8 @@
  	q->entry[idx].skb = skb;
  	q->entry[idx].wcid = 0xffff;
  
-@@ -407,13 +408,13 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 		u32 buf1 = le32_to_cpu(desc->buf1);
+@@ -448,13 +449,13 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 	if (mt76_queue_is_wed_rx(q)) {
  		u32 id, find = 0;
  		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
 -		struct mt76_txwi_cache *t;
@@ -198,7 +199,7 @@
  					find = 1;
  					token = id;
  
-@@ -430,19 +431,19 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -471,19 +472,19 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  				return NULL;
  		}
  
@@ -222,10 +223,10 @@
  
 -		mt76_put_rxwi(dev, t);
 +		mt76_put_rxwi(dev, r);
- 
- 		if (drop) {
- 			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
-@@ -506,7 +507,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+ 		if (drop)
+ 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
+ 	} else {
+@@ -545,7 +546,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
  	buf.len = skb->len;
  
  	spin_lock_bh(&q->lock);
@@ -234,7 +235,7 @@
  	mt76_dma_kick_queue(dev, q);
  	spin_unlock_bh(&q->lock);
  
-@@ -586,7 +587,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -625,7 +626,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
  		goto unmap;
  
  	return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
@@ -244,10 +245,10 @@
  unmap:
  	for (n--; n > 0; n--)
 diff --git a/mac80211.c b/mac80211.c
-index ad3a5e2..6232534 100644
+index 1a7d690..013298e 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -607,7 +607,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+@@ -618,7 +618,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
  	spin_lock_init(&dev->lock);
  	spin_lock_init(&dev->cc_lock);
  	spin_lock_init(&dev->status_lock);
@@ -255,7 +256,7 @@
  	mutex_init(&dev->mutex);
  	init_waitqueue_head(&dev->tx_wait);
  
-@@ -640,6 +639,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+@@ -651,6 +650,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
  	INIT_LIST_HEAD(&dev->txwi_cache);
  	INIT_LIST_HEAD(&dev->rxwi_cache);
  	dev->token_size = dev->drv->token_size;
@@ -263,11 +264,84 @@
  
  	for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
  		skb_queue_head_init(&dev->rx_skb[i]);
+diff --git a/mmio.c b/mmio.c
+index d9d5047..edc3cac 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -96,18 +96,18 @@ void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+ 				sizeof(struct skb_shared_info));
+ 
+ 	for (i = 0; i < dev->rx_token_size; i++) {
+-		struct mt76_txwi_cache *t;
++		struct mt76_rxwi_cache *r;
+ 
+-		t = mt76_rx_token_release(dev, i);
+-		if (!t || !t->ptr)
++		r = mt76_rx_token_release(dev, i);
++		if (!r || !r->ptr)
+ 			continue;
+ 
+-		dma_unmap_single(dev->dma_dev, t->dma_addr,
++		dma_unmap_single(dev->dma_dev, r->dma_addr,
+ 				 wed->wlan.rx_size, DMA_FROM_DEVICE);
+-		__free_pages(virt_to_page(t->ptr), get_order(length));
+-		t->ptr = NULL;
++		__free_pages(virt_to_page(r->ptr), get_order(length));
++		r->ptr = NULL;
+ 
+-		mt76_put_rxwi(dev, t);
++		mt76_put_rxwi(dev, r);
+ 	}
+ 
+ 	mt76_free_pending_rxwi(dev);
+@@ -125,18 +125,18 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 				sizeof(struct skb_shared_info));
+ 
+ 	for (i = 0; i < size; i++) {
+-		struct mt76_txwi_cache *t = mt76_get_rxwi(dev);
++		struct mt76_rxwi_cache *r = mt76_get_rxwi(dev);
+ 		dma_addr_t phy_addr;
+ 		struct page *page;
+ 		int token;
+ 		void *ptr;
+ 
+-		if (!t)
++		if (!r)
+ 			goto unmap;
+ 
+ 		page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
+ 		if (!page) {
+-			mt76_put_rxwi(dev, t);
++			mt76_put_rxwi(dev, r);
+ 			goto unmap;
+ 		}
+ 
+@@ -146,17 +146,17 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 					  DMA_TO_DEVICE);
+ 		if (unlikely(dma_mapping_error(dev->dev, phy_addr))) {
+ 			__free_pages(page, get_order(length));
+-			mt76_put_rxwi(dev, t);
++			mt76_put_rxwi(dev, r);
+ 			goto unmap;
+ 		}
+ 
+ 		desc->buf0 = cpu_to_le32(phy_addr);
+-		token = mt76_rx_token_consume(dev, ptr, t, phy_addr);
++		token = mt76_rx_token_consume(dev, ptr, r, phy_addr);
+ 		if (token < 0) {
+ 			dma_unmap_single(dev->dma_dev, phy_addr,
+ 					 wed->wlan.rx_size, DMA_TO_DEVICE);
+ 			__free_pages(page, get_order(length));
+-			mt76_put_rxwi(dev, t);
++			mt76_put_rxwi(dev, r);
+ 			goto unmap;
+ 		}
+ 
 diff --git a/mt76.h b/mt76.h
-index d00ef21..968bf08 100644
+index a54da76..981445a 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -173,6 +173,7 @@ struct mt76_queue_entry {
+@@ -193,6 +193,7 @@ struct mt76_queue_entry {
  	};
  	union {
  		struct mt76_txwi_cache *txwi;
@@ -275,7 +349,7 @@
  		struct urb *urb;
  		int buf_sz;
  	};
-@@ -376,10 +377,15 @@ struct mt76_txwi_cache {
+@@ -411,10 +412,15 @@ struct mt76_txwi_cache {
  
  	unsigned long jiffies;
  
@@ -295,7 +369,7 @@
  };
  
  struct mt76_rx_tid {
-@@ -465,6 +471,7 @@ struct mt76_driver_ops {
+@@ -501,6 +507,7 @@ struct mt76_driver_ops {
  	u16 txwi_size;
  	u16 token_size;
  	u8 mcs_rates;
@@ -303,7 +377,7 @@
  
  	void (*update_survey)(struct mt76_phy *phy);
  
-@@ -851,7 +858,6 @@ struct mt76_dev {
+@@ -889,7 +896,6 @@ struct mt76_dev {
  
  	struct ieee80211_hw *hw;
  
@@ -311,7 +385,7 @@
  	spinlock_t lock;
  	spinlock_t cc_lock;
  
-@@ -1543,8 +1549,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
+@@ -1599,8 +1605,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
  }
  
  void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
@@ -322,7 +396,7 @@
  void mt76_free_pending_rxwi(struct mt76_dev *dev);
  void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
  		      struct napi_struct *napi);
-@@ -1699,9 +1705,9 @@ struct mt76_txwi_cache *
+@@ -1785,9 +1791,9 @@ struct mt76_txwi_cache *
  mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
  int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi);
  void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
@@ -335,108 +409,39 @@
  static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
  {
 diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 59a44d7..326c8c8 100644
+index c91a1c5..17a3fa0 100644
 --- a/mt7915/dma.c
 +++ b/mt7915/dma.c
-@@ -509,7 +509,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+@@ -512,7 +512,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
  		    mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
- 			dev->mt76.q_rx[MT_RXQ_MAIN].flags =
+ 			mdev->q_rx[MT_RXQ_MAIN].flags =
  				MT_WED_Q_RX(MT7915_RXQ_BAND0);
 -			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
+ 			mdev->q_rx[MT_RXQ_MAIN].wed = &mdev->mmio.wed;
  		}
  
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
-@@ -546,7 +545,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+@@ -551,7 +550,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
  		    mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
- 			dev->mt76.q_rx[MT_RXQ_BAND1].flags =
+ 			mdev->q_rx[MT_RXQ_BAND1].flags =
  				MT_WED_Q_RX(MT7915_RXQ_BAND1);
 -			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
+ 			mdev->q_rx[MT_RXQ_BAND1].wed = &mdev->mmio.wed;
  		}
  
- 		/* rx data queue for band1 */
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index cae8b81..d739390 100644
+index cdfd35f..c8258f1 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -622,18 +622,18 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- 				sizeof(struct skb_shared_info));
- 
- 	for (i = 0; i < dev->mt76.rx_token_size; i++) {
--		struct mt76_txwi_cache *t;
-+		struct mt76_rxwi_cache *r;
- 
--		t = mt76_rx_token_release(&dev->mt76, i);
--		if (!t || !t->ptr)
-+		r = mt76_rx_token_release(&dev->mt76, i);
-+		if (!r || !r->ptr)
- 			continue;
- 
--		dma_unmap_single(dev->mt76.dma_dev, t->dma_addr,
-+		dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
- 				 wed->wlan.rx_size, DMA_FROM_DEVICE);
--		__free_pages(virt_to_page(t->ptr), get_order(length));
--		t->ptr = NULL;
-+		__free_pages(virt_to_page(r->ptr), get_order(length));
-+		r->ptr = NULL;
- 
--		mt76_put_rxwi(&dev->mt76, t);
-+		mt76_put_rxwi(&dev->mt76, r);
- 	}
- 
- 	mt76_free_pending_rxwi(&dev->mt76);
-@@ -651,18 +651,18 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- 				sizeof(struct skb_shared_info));
- 
- 	for (i = 0; i < size; i++) {
--		struct mt76_txwi_cache *t = mt76_get_rxwi(&dev->mt76);
-+		struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
- 		dma_addr_t phy_addr;
- 		struct page *page;
- 		int token;
- 		void *ptr;
- 
--		if (!t)
-+		if (!r)
- 			goto unmap;
- 
- 		page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
- 		if (!page) {
--			mt76_put_rxwi(&dev->mt76, t);
-+			mt76_put_rxwi(&dev->mt76, r);
- 			goto unmap;
- 		}
- 
-@@ -672,17 +672,17 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- 					  DMA_TO_DEVICE);
- 		if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
- 			__free_pages(page, get_order(length));
--			mt76_put_rxwi(&dev->mt76, t);
-+			mt76_put_rxwi(&dev->mt76, r);
- 			goto unmap;
- 		}
- 
- 		desc->buf0 = cpu_to_le32(phy_addr);
--		token = mt76_rx_token_consume(&dev->mt76, ptr, t, phy_addr);
-+		token = mt76_rx_token_consume(&dev->mt76, ptr, r, phy_addr);
- 		if (token < 0) {
- 			dma_unmap_single(dev->mt76.dma_dev, phy_addr,
- 					 wed->wlan.rx_size, DMA_TO_DEVICE);
- 			__free_pages(page, get_order(length));
--			mt76_put_rxwi(&dev->mt76, t);
-+			mt76_put_rxwi(&dev->mt76, r);
- 			goto unmap;
- 		}
- 
-@@ -848,7 +848,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -729,7 +729,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  	wed->wlan.reset = mt7915_mmio_wed_reset;
- 	wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete;
+ 	wed->wlan.reset_complete = mt76_mmio_wed_reset_complete;
  
 -	dev->mt76.rx_token_size = wed->wlan.rx_npkt;
 +	dev->mt76.rx_token_size += wed->wlan.rx_npkt;
  
  	if (mtk_wed_device_attach(wed))
  		return 0;
-@@ -1056,6 +1056,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
+@@ -937,6 +937,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
  				SURVEY_INFO_TIME_RX |
  				SURVEY_INFO_TIME_BSS_RX,
  		.token_size = MT7915_TOKEN_SIZE,
@@ -445,7 +450,7 @@
  		.tx_complete_skb = mt76_connac_tx_complete_skb,
  		.rx_skb = mt7915_queue_rx_skb,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 764edc5..c1f3a0a 100644
+index cc4c402..8dd9386 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -64,6 +64,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch b/recipes-wifi/linux-mt76/files/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch
index ac5bfb1..05f6021 100644
--- a/recipes-wifi/linux-mt76/files/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch
@@ -1,8 +1,7 @@
-From 999021989ad387b46c8ff4ffed43cc0017322c5e Mon Sep 17 00:00:00 2001
+From 3f8204402961042f92bcc4d7b3aa9e9bbb89c923 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Wed, 11 Jan 2023 10:56:27 +0800
-Subject: [PATCH 2006/2011] wifi: mt76: add debugfs knob to show packet error
- rate
+Subject: [PATCH 64/76] wifi: mt76: add debugfs knob to show packet error rate
 
 Get tx count and tx failed from mcu command
 ---
@@ -15,11 +14,11 @@
  6 files changed, 194 insertions(+), 1 deletion(-)
 
 diff --git a/mt76.h b/mt76.h
-index 968bf08..3032cdd 100644
+index 981445a..f5776ab 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -297,8 +297,10 @@ struct mt76_sta_stats {
- 	u64 tx_bytes;
+@@ -320,8 +320,10 @@ struct mt76_sta_stats {
+ 	u64 last_tx_bytes;
  	/* WED TX */
  	u32 tx_packets;		/* unit: MSDU */
 +	u32 tx_mpdu_cnt;
@@ -30,10 +29,10 @@
  	u64 rx_bytes;
  	u32 rx_packets;
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 9ad1883..2d6e610 100644
+index 22a6779..66aca6d 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1173,6 +1173,7 @@ enum {
+@@ -1194,6 +1194,7 @@ enum {
  	MCU_EXT_CMD_EDCA_UPDATE = 0x27,
  	MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
  	MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
@@ -42,10 +41,10 @@
  	MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
  	MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index b2b5c76..d4b0617 100644
+index d66b42a..19d5aa5 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4233,6 +4233,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
+@@ -4287,6 +4287,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
  		return mt7915_mcu_get_tx_rate_v2(phy, wcidx);
  }
  
@@ -161,7 +160,7 @@
  				struct cfg80211_he_bss_color *he_bss_color)
  {
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 825bb7d..12c98c5 100644
+index 3b169d6..7a2732c 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -791,7 +791,8 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
@@ -200,10 +199,10 @@
     CAPI_SU,
     CAPI_MU,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index c1f3a0a..d47abcf 100644
+index 8dd9386..79e0fae 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -677,6 +677,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+@@ -694,6 +694,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
  				     struct cfg80211_chan_def *chandef);
  int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
@@ -212,12 +211,12 @@
  int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
  int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 928bb50..4defc17 100644
+index 40a6dfb..367f41d 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
-@@ -3795,6 +3795,66 @@ mt7915_sr_enable_set(void *data, u64 val)
- DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enable, NULL,
- 			 mt7915_sr_enable_set, "%llx\n");
+@@ -3828,6 +3828,66 @@ mt7915_scs_enable_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_scs_enable, NULL,
+ 			 mt7915_scs_enable_set, "%lld\n");
  
 +static int mt7915_reset_counter(void *data, u64 val)
 +{
@@ -282,10 +281,10 @@
  int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  {
  	struct mt7915_dev *dev = phy->dev;
-@@ -3886,6 +3946,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
- 	debugfs_create_file("sw_aci", 0600, dir, dev,
+@@ -3921,6 +3981,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  			    &fops_sw_aci);
  	debugfs_create_file("sr_enable", 0200, dir, phy, &fops_sr_enable);
+ 	debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
 +	debugfs_create_file("reset_counter", 0200, dir, dev, &fops_reset_counter);
 +	debugfs_create_devm_seqfile(dev->mt76.dev, "per", dir, mt7915_per_read);
  	return 0;
diff --git a/recipes-wifi/linux-mt76/files/patches/2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch b/recipes-wifi/linux-mt76/files/patches/2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch
index 83cda65..1513414 100644
--- a/recipes-wifi/linux-mt76/files/patches/2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch
@@ -1,7 +1,7 @@
-From 1d021dcf4503c9003919b805f5ead1d78b50ad7a Mon Sep 17 00:00:00 2001
+From 5142b743b0fa3d2eca084469e2826778924808f4 Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Thu, 6 Apr 2023 17:50:52 +0800
-Subject: [PATCH 2007/2011] wifi: mt76: mt7915: add ctxd support for mt7916
+Subject: [PATCH 65/76] wifi: mt76: mt7915: add ctxd support for mt7916
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
 ---
@@ -10,10 +10,10 @@
  2 files changed, 35 insertions(+)
 
 diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 326c8c8..f71ec55 100644
+index 17a3fa0..a0f393a 100644
 --- a/mt7915/dma.c
 +++ b/mt7915/dma.c
-@@ -433,6 +433,26 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+@@ -435,6 +435,26 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
  			if (is_mt7915(mdev))
  				mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP,
  					 MT_WFDMA0_EXT0_RXWB_KEEP);
diff --git a/recipes-wifi/linux-mt76/files/patches/2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch b/recipes-wifi/linux-mt76/files/patches/2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch
index a50ea6c..852d5f9 100644
--- a/recipes-wifi/linux-mt76/files/patches/2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch
@@ -1,19 +1,19 @@
-From 7a963d92dd37bb16d00cc9ba7684f131d3331a78 Mon Sep 17 00:00:00 2001
+From 9e48b3a3d1ddfd625bedf7fdd7aac2121ba03e71 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Thu, 5 Jan 2023 16:43:57 +0800
-Subject: [PATCH 2008/2011] wifi: mt76: connac: wed: add wed rx copy skb
+Subject: [PATCH 66/76] wifi: mt76: connac: wed: add wed rx copy skb
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
- dma.c         | 76 +++++++++++++++++++++++++++++++++++++++------------
- mt7915/mmio.c | 35 ++++++++++++++++++------
- 2 files changed, 85 insertions(+), 26 deletions(-)
+ dma.c  | 71 ++++++++++++++++++++++++++++++++++++++++++++--------------
+ mmio.c | 37 +++++++++++++++++++++---------
+ 2 files changed, 80 insertions(+), 28 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index e3e2f38..7c5e623 100644
+index cf6ca04..dfedbcd 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -213,11 +213,11 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -227,10 +227,10 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
  
  static int
  mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
@@ -21,14 +21,13 @@
 +		    struct mt76_queue_buf *buf, void *data,
 +		    struct mt76_rxwi_cache *rxwi)
  {
- 	struct mt76_desc *desc = &q->desc[q->head];
  	struct mt76_queue_entry *entry = &q->entry[q->head];
 -	struct mt76_rxwi_cache *rxwi = NULL;
- 	u32 buf1 = 0, ctrl;
+ 	struct mt76_desc *desc;
  	int idx = q->head;
- 	int rx_token;
-@@ -225,9 +225,11 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+ 	u32 buf1 = 0, ctrl;
+@@ -251,9 +251,11 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ #endif
  
  	if (mt76_queue_is_wed_rx(q)) {
 -		rxwi = mt76_get_rxwi(dev);
@@ -42,7 +41,7 @@
  
  		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
  		if (rx_token < 0) {
-@@ -389,7 +391,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
+@@ -423,7 +425,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
  
  static void *
  mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
@@ -51,7 +50,7 @@
  {
  	struct mt76_queue_entry *e = &q->entry[idx];
  	struct mt76_desc *desc = &q->desc[idx];
-@@ -439,11 +441,43 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -480,11 +482,44 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  				 SKB_WITH_OVERHEAD(q->buf_size),
  				 DMA_FROM_DEVICE);
  
@@ -62,13 +61,12 @@
 +			buf = r->ptr;
 +			r->dma_addr = 0;
 +			r->ptr = NULL;
- 
--		mt76_put_rxwi(dev, r);
++
 +			mt76_put_rxwi(dev, r);
 +		} else {
 +			struct mt76_queue_buf qbuf;
 +
-+			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
 +			if (!buf)
 +				return NULL;
 +
@@ -97,9 +95,11 @@
 +			}
 +		}
  
- 		if (drop) {
- 			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
-@@ -482,7 +516,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
+-		mt76_put_rxwi(dev, r);
+ 		if (drop)
+ 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
+ 	} else {
+@@ -521,7 +556,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
  	q->tail = (q->tail + 1) % q->ndesc;
  	q->queued--;
  
@@ -108,16 +108,8 @@
  }
  
  static int
-@@ -622,6 +656,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 	int len = SKB_WITH_OVERHEAD(q->buf_size);
- 	int frames = 0, offset = q->buf_offset;
- 	dma_addr_t addr;
-+	bool flags = false;
- 
- 	if (!q->ndesc)
- 		return 0;
-@@ -645,7 +680,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 		qbuf.addr = addr + offset;
+@@ -688,7 +723,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+ done:
  		qbuf.len = len - offset;
  		qbuf.skip_unmap = false;
 -		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
@@ -125,19 +117,7 @@
  			dma_unmap_single(dev->dma_dev, addr, len,
  					 DMA_FROM_DEVICE);
  			skb_free_frag(buf);
-@@ -654,7 +689,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 		frames++;
- 	}
- 
--	if (frames)
-+	flags = (q->flags & MT_QFLAG_WED) &&
-+		FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
-+
-+	if (frames || flags)
- 		mt76_dma_kick_queue(dev, q);
- 
- 	spin_unlock_bh(&q->lock);
-@@ -777,12 +815,14 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -864,12 +899,14 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  
  	spin_unlock_bh(&q->lock);
  
@@ -157,33 +137,39 @@
  }
  
  static void
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index d739390..aa5c5dd 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -614,6 +614,7 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
- static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+diff --git a/mmio.c b/mmio.c
+index edc3cac..cdd5595 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -89,12 +89,9 @@ EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
+ void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  {
- 	struct mt7915_dev *dev;
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+-	u32 length;
 +	struct page *page;
- 	u32 length;
  	int i;
  
-@@ -630,13 +631,33 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+-	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
+-				sizeof(struct skb_shared_info));
+-
+ 	for (i = 0; i < dev->rx_token_size; i++) {
+ 		struct mt76_rxwi_cache *r;
+ 
+@@ -104,13 +101,33 @@ void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  
- 		dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
+ 		dma_unmap_single(dev->dma_dev, r->dma_addr,
  				 wed->wlan.rx_size, DMA_FROM_DEVICE);
 -		__free_pages(virt_to_page(r->ptr), get_order(length));
 +		skb_free_frag(r->ptr);
  		r->ptr = NULL;
  
- 		mt76_put_rxwi(&dev->mt76, r);
+ 		mt76_put_rxwi(dev, r);
  	}
  
- 	mt76_free_pending_rxwi(&dev->mt76);
+ 	mt76_free_pending_rxwi(dev);
 +
-+	mt76_for_each_q_rx(&dev->mt76, i) {
-+		struct mt76_queue *q = &dev->mt76.q_rx[i];
++	mt76_for_each_q_rx(dev, i) {
++		struct mt76_queue *q = &dev->q_rx[i];
 +
 +		if (mt76_queue_is_wed_rx(q)) {
 +			if (!q->rx_page.va)
@@ -202,11 +188,11 @@
 +	__page_frag_cache_drain(page, wed->rx_buf_ring.rx_page.pagecnt_bias);
 +	memset(&wed->rx_buf_ring.rx_page, 0, sizeof(wed->rx_buf_ring.rx_page));
  }
+ EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
  
- static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
-@@ -653,35 +674,33 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -127,25 +144,23 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  	for (i = 0; i < size; i++) {
- 		struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
+ 		struct mt76_rxwi_cache *r = mt76_get_rxwi(dev);
  		dma_addr_t phy_addr;
 -		struct page *page;
  		int token;
@@ -219,30 +205,27 @@
 -		if (!page) {
 +		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length, GFP_ATOMIC);
 +		if (!ptr) {
- 			mt76_put_rxwi(&dev->mt76, r);
+ 			mt76_put_rxwi(dev, r);
  			goto unmap;
  		}
  
 -		ptr = page_address(page);
- 		phy_addr = dma_map_single(dev->mt76.dma_dev, ptr,
+ 		phy_addr = dma_map_single(dev->dma_dev, ptr,
  					  wed->wlan.rx_size,
  					  DMA_TO_DEVICE);
-+		
- 		if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
+ 		if (unlikely(dma_mapping_error(dev->dev, phy_addr))) {
 -			__free_pages(page, get_order(length));
 +			skb_free_frag(ptr);
- 			mt76_put_rxwi(&dev->mt76, r);
+ 			mt76_put_rxwi(dev, r);
  			goto unmap;
  		}
--
- 		desc->buf0 = cpu_to_le32(phy_addr);
- 		token = mt76_rx_token_consume(&dev->mt76, ptr, r, phy_addr);
+@@ -155,7 +170,7 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  		if (token < 0) {
- 			dma_unmap_single(dev->mt76.dma_dev, phy_addr,
+ 			dma_unmap_single(dev->dma_dev, phy_addr,
  					 wed->wlan.rx_size, DMA_TO_DEVICE);
 -			__free_pages(page, get_order(length));
 +			skb_free_frag(ptr);
- 			mt76_put_rxwi(&dev->mt76, r);
+ 			mt76_put_rxwi(dev, r);
  			goto unmap;
  		}
 -- 
diff --git a/recipes-wifi/linux-mt76/files/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch b/recipes-wifi/linux-mt76/files/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch
index 97e343a..367f32d 100644
--- a/recipes-wifi/linux-mt76/files/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch
@@ -1,7 +1,7 @@
-From 8b5f1f9d44e11290d97dbae675457d1cf5030374 Mon Sep 17 00:00:00 2001
+From 114a4a301cdb7f1d6d02d8f9b04de1ec5b597c6b Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Fri, 8 Sep 2023 18:26:21 +0800
-Subject: [PATCH 2009/2011] wifi: mt76: mt7915: enable wa log to uart
+Subject: [PATCH 67/76] wifi: mt76: mt7915: enable wa log to uart
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
 ---
diff --git a/recipes-wifi/linux-mt76/files/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch b/recipes-wifi/linux-mt76/files/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch
index d004b61..31077d2 100644
--- a/recipes-wifi/linux-mt76/files/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch
@@ -1,7 +1,7 @@
-From 7dabeeff8a38468359c857c5df6da076faa95444 Mon Sep 17 00:00:00 2001
+From ef41f8efe719d69b5c7e5e6bb1bca9544762d647 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Fri, 8 Sep 2023 18:29:32 +0800
-Subject: [PATCH 2010/2011] wifi: mt76: mt7915: add error message when driver
+Subject: [PATCH 68/76] wifi: mt76: mt7915: add error message when driver
  receive invalid token id
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 6 insertions(+)
 
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 3c6b308..a5369ea 100644
+index 8aeee3c..a5a5ebd 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -998,6 +998,12 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -999,6 +999,12 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
  			} else {
  				msdu = FIELD_GET(MT_TX_FREE_MSDU_ID, info);
  			}
diff --git a/recipes-wifi/linux-mt76/files/patches/2011-wifi-mt76-mt7915-wed-change-wed-token-init-size-to-a.patch b/recipes-wifi/linux-mt76/files/patches/2011-wifi-mt76-mt7915-wed-change-wed-token-init-size-to-a.patch
index 49870b2..a81b578 100644
--- a/recipes-wifi/linux-mt76/files/patches/2011-wifi-mt76-mt7915-wed-change-wed-token-init-size-to-a.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2011-wifi-mt76-mt7915-wed-change-wed-token-init-size-to-a.patch
@@ -1,20 +1,57 @@
-From 98e230f53b3e81ec9fc216054ebcf567c5e73406 Mon Sep 17 00:00:00 2001
+From 7c1d1577b0df8af83a6d3db7aa006cb00fef321c Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Mon, 11 Sep 2023 17:57:32 +0800
-Subject: [PATCH 20/25] wifi: mt76: mt7915: wed: change wed token init size to
+Subject: [PATCH 69/76] wifi: mt76: mt7915: wed: change wed token init size to
  adapt wed version
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
 ---
+ mmio.c          |  4 ++--
+ mt76.h          |  2 ++
  mt7915/mac.c    | 10 ++++++++--
  mt7915/mcu.c    |  7 +++++--
- mt7915/mmio.c   | 13 ++++++++-----
+ mt7915/mmio.c   |  9 ++++++---
  mt7915/mt7915.h |  4 +++-
  tx.c            | 26 ++++++++------------------
- 5 files changed, 32 insertions(+), 28 deletions(-)
+ 7 files changed, 34 insertions(+), 28 deletions(-)
 
+diff --git a/mmio.c b/mmio.c
+index cdd5595..b6617f7 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -197,7 +197,7 @@ int mt76_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+ 
+ 	spin_lock_bh(&dev->token_lock);
+-	dev->token_size = wed->wlan.token_start;
++	dev->token_size = MT76_WED_SW_TOKEN_SIZE;
+ 	spin_unlock_bh(&dev->token_lock);
+ 
+ 	return !wait_event_timeout(dev->tx_wait, !dev->wed_token_count, HZ);
+@@ -209,7 +209,7 @@ void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+ 
+ 	spin_lock_bh(&dev->token_lock);
+-	dev->token_size = wed->wlan.token_start;
++	dev->token_size = MT76_WED_SW_TOKEN_SIZE;
+ 	spin_unlock_bh(&dev->token_lock);
+ }
+ EXPORT_SYMBOL_GPL(mt76_mmio_wed_offload_disable);
+diff --git a/mt76.h b/mt76.h
+index f5776ab..5fea9a5 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -29,6 +29,8 @@
+ 
+ #define MT76_BUILD_TIME_LEN	24
+ 
++#define MT76_WED_SW_TOKEN_SIZE	1024
++
+ #define MT_QFLAG_WED_RING	GENMASK(1, 0)
+ #define MT_QFLAG_WED_TYPE	GENMASK(4, 2)
+ #define MT_QFLAG_WED		BIT(5)
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 59cc1fd7..a473fc61 100644
+index a5a5ebd..fdafaf3 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -932,7 +932,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
@@ -49,7 +86,7 @@
  					msdu);
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index ebacfd27..b42f7be9 100644
+index 19d5aa5..d0f4bf6 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -2318,6 +2318,9 @@ mt7915_mcu_init_rx_airtime(struct mt7915_dev *dev)
@@ -74,28 +111,10 @@
  
  	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET), &req,
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index aa5c5dd6..2ad7ba4a 100644
+index c8258f1..74cf4ad 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -593,7 +593,7 @@ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- 
- 	spin_lock_bh(&dev->mt76.token_lock);
--	dev->mt76.token_size = wed->wlan.token_start;
-+	dev->mt76.token_size = MT7915_WED_SW_TOKEN_SIZE;
- 	spin_unlock_bh(&dev->mt76.token_lock);
- 
- 	return !wait_event_timeout(dev->mt76.tx_wait,
-@@ -607,7 +607,7 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- 
- 	spin_lock_bh(&dev->mt76.token_lock);
--	dev->mt76.token_size = wed->wlan.token_start;//MT7915_TOKEN_SIZE
-+	dev->mt76.token_size = MT7915_WED_SW_TOKEN_SIZE;
- 	spin_unlock_bh(&dev->mt76.token_lock);
- }
- 
-@@ -837,11 +837,14 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -699,11 +699,14 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  		wed->wlan.wpdma_rx_glo = res->start + MT_WPDMA_GLO_CFG;
  		wed->wlan.wpdma_rx = res->start + MT_RXQ_WED_DATA_RING_BASE;
  	}
@@ -112,7 +131,7 @@
  	wed->wlan.wcid_512 = !is_mt7915(&dev->mt76);
  
  	wed->wlan.rx_nbuf = 65536;
-@@ -874,7 +877,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -736,7 +739,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  
  	*irq = wed->irq;
  	dev->mt76.dma_dev = wed->dev;
@@ -122,7 +141,7 @@
  	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
  	if (ret)
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 6156850b..6a175374 100644
+index 79e0fae..057b0f1 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -62,7 +62,9 @@
@@ -137,7 +156,7 @@
  #define MT7915_RX_TOKEN_SIZE		4096
  
 diff --git a/tx.c b/tx.c
-index e290aef3..96f9009b 100644
+index e290aef..96f9009 100644
 --- a/tx.c
 +++ b/tx.c
 @@ -818,20 +818,18 @@ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
diff --git a/recipes-wifi/linux-mt76/files/patches/2012-wifi-mt76-mt7915-wed-add-per-bss-statistic-info.patch b/recipes-wifi/linux-mt76/files/patches/2012-wifi-mt76-mt7915-wed-add-per-bss-statistic-info.patch
index e9267b5..3d4d7f6 100644
--- a/recipes-wifi/linux-mt76/files/patches/2012-wifi-mt76-mt7915-wed-add-per-bss-statistic-info.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2012-wifi-mt76-mt7915-wed-add-per-bss-statistic-info.patch
@@ -1,20 +1,20 @@
-From 72f6ac700c7a66508aeb8a8341789b138360c416 Mon Sep 17 00:00:00 2001
+From 8fe16f6826223482cd87c672b6015463cfdc4ba8 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 1 Nov 2023 07:50:08 +0800
-Subject: [PATCH 1/6] wifi: mt76: mt7915: wed: add per bss statistic info
+Subject: [PATCH 70/76] wifi: mt76: mt7915: wed: add per bss statistic info
 
 ---
  mt7915/init.c        |  1 +
  mt7915/mac.c         | 21 +++++++++++++++++++++
  mt7915/main.c        |  2 +-
  mt7915/mcu.c         | 30 +++++++++++++++++++++++++++---
- mt7915/mmio.c        | 24 ++++++++++++++++++++++++
+ mt7915/mmio.c        | 26 +++++++++++++++++++++++++-
  mt7915/mt7915.h      |  3 ++-
  mt7915/mtk_debugfs.c |  2 +-
- 7 files changed, 77 insertions(+), 6 deletions(-)
+ 7 files changed, 78 insertions(+), 7 deletions(-)
 
 diff --git a/mt7915/init.c b/mt7915/init.c
-index c643c33..9978edb 100644
+index 14bf6ef..978e585 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
 @@ -397,6 +397,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
@@ -26,7 +26,7 @@
  	if (!is_mt7915(&dev->mt76))
  		wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index a473fc6..e403f0f 100644
+index fdafaf3..e452337 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -1067,6 +1067,7 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
@@ -70,7 +70,7 @@
  	spin_lock_bh(&dev->mt76.sta_poll_lock);
  	if (list_empty(&msta->wcid.poll_list))
  		list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
-@@ -2081,6 +2101,7 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
+@@ -2092,6 +2112,7 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
  		spin_unlock_bh(&phy->stats_lock);
  
  		mt7915_mcu_get_tx_rate(phy, sta->wcid.idx);
@@ -79,10 +79,10 @@
  		spin_lock_bh(&phy->stats_lock);
  	}
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 72bcaab..9595b55 100644
+index 92750df..02682ce 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1188,7 +1188,7 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
+@@ -1200,7 +1200,7 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
  		sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
  		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
  
@@ -92,10 +92,10 @@
  			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
  		}
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index fe3f151..72f74e1 100644
+index d0f4bf6..3ff53db 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4467,7 +4467,8 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
+@@ -4472,7 +4472,8 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
  				 &req, sizeof(req), true);
  }
  
@@ -105,7 +105,7 @@
  {
  	struct {
  		__le32 cmd;
-@@ -4511,11 +4512,34 @@ int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx)
+@@ -4516,11 +4517,34 @@ int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx)
  	rcu_read_lock();
  
  	wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
@@ -143,10 +143,19 @@
  out:
  	dev_kfree_skb(skb);
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 2ad7ba4..ce976b4 100644
+index 74cf4ad..f4ba115 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -742,8 +742,32 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
+@@ -596,7 +596,7 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
+ 
+ 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+ 
+-	if (idx >= mt7915_wtbl_size(dev))
++	if (idx <= 0 || idx >= mt7915_wtbl_size(dev))
+ 		return;
+ 
+ 	rcu_read_lock();
+@@ -611,8 +611,32 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
  		wcid->stats.rx_packets += le32_to_cpu(stats->rx_pkt_cnt);
  		wcid->stats.rx_errors += le32_to_cpu(stats->rx_err_cnt);
  		wcid->stats.rx_drops += le32_to_cpu(stats->rx_drop_cnt);
@@ -180,10 +189,10 @@
  }
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 091af43..1510f10 100644
+index 057b0f1..a61651a 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -683,7 +683,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+@@ -695,7 +695,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  			   struct ieee80211_sta *sta, struct rate_info *rate);
  int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
  				     struct cfg80211_chan_def *chandef);
@@ -194,10 +203,10 @@
  int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
  int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index e73db5d..f481231 100644
+index 367f41d..a5c6d35 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
-@@ -3812,7 +3812,7 @@ static int mt7915_reset_counter(void *data, u64 val)
+@@ -3835,7 +3835,7 @@ static int mt7915_reset_counter(void *data, u64 val)
  	struct mt76_wcid *wcid;
  
  	/* Clear the firmware counters */
diff --git a/recipes-wifi/linux-mt76/files/patches/2013-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-selected-.patch b/recipes-wifi/linux-mt76/files/patches/2013-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-selected-.patch
index 6d7a03f..cfa8066 100644
--- a/recipes-wifi/linux-mt76/files/patches/2013-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-selected-.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2013-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-selected-.patch
@@ -1,7 +1,7 @@
-From 5fb134dd94aaa8986704094e0b0a62c9f2bfd391 Mon Sep 17 00:00:00 2001
+From 877b1fb4df6f2302b0eecbaf4311a1c432ee3c3a Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Mon, 23 Oct 2023 10:25:13 +0800
-Subject: [PATCH 2/6] Revert "wifi: mt76: mt7921: fix the wrong rate selected
+Subject: [PATCH 71/76] Revert "wifi: mt76: mt7921: fix the wrong rate selected
  in fw for the chanctx driver"
 
 This reverts commit 9fc37b0ac5467cfe5e3d2ad8a29e9a7646ece2be.
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+), 7 deletions(-)
 
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 07bd57b..1d22ab9 100644
+index 4a7b694..e359388 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -846,9 +846,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -847,9 +847,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  			     struct ieee80211_vif *vif,
  			     u8 rcpi, u8 sta_state)
  {
@@ -24,7 +24,7 @@
  	enum nl80211_band band = chandef->chan->band;
  	struct mt76_dev *dev = mphy->dev;
  	struct sta_rec_ra_info *ra_info;
-@@ -1354,10 +1352,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode);
+@@ -1355,10 +1353,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode);
  const struct ieee80211_sta_he_cap *
  mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
  {
diff --git a/recipes-wifi/linux-mt76/files/patches/2014-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-pickup-fo.patch b/recipes-wifi/linux-mt76/files/patches/2014-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-pickup-fo.patch
index 92b04dc..aae4f6c 100644
--- a/recipes-wifi/linux-mt76/files/patches/2014-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-pickup-fo.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2014-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-pickup-fo.patch
@@ -1,8 +1,8 @@
-From 8beef73782b0b068ed1d86dcfec92f16e8297d4e Mon Sep 17 00:00:00 2001
+From 371a05c81b4ae064bcf3b5409839048ffc45f447 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Mon, 23 Oct 2023 10:25:18 +0800
-Subject: [PATCH 3/6] Revert "wifi: mt76: mt7921: fix the wrong rate pickup for
- the chanctx driver"
+Subject: [PATCH 72/76] Revert "wifi: mt76: mt7921: fix the wrong rate pickup
+ for the chanctx driver"
 
 This reverts commit 66d5694e1898c5584a83c60876bec16909ebe2b0.
 ---
@@ -12,10 +12,10 @@
  3 files changed, 5 insertions(+), 14 deletions(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index 6232534..e7c4dc4 100644
+index 013298e..09c9eb2 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -1715,16 +1715,11 @@ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
+@@ -1728,16 +1728,11 @@ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
  }
  EXPORT_SYMBOL_GPL(mt76_init_queue);
  
@@ -35,24 +35,24 @@
  
  	/* pick the lowest rate for hidden nodes */
 diff --git a/mt76.h b/mt76.h
-index 0a7f4f1..05144b2 100644
+index 5fea9a5..d082b24 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -1207,8 +1207,7 @@ bool mt76_check_bin_file_mode(struct mt76_dev *dev);
+@@ -1262,8 +1262,7 @@ bool mt76_check_bin_file_mode(struct mt76_dev *dev);
  struct mt76_queue *
  mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
- 		int ring_base, u32 flags);
+ 		int ring_base, void *wed, u32 flags);
 -u16 mt76_calculate_default_rate(struct mt76_phy *phy,
 -				struct ieee80211_vif *vif, int rateidx);
 +u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx);
  static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx,
- 				     int n_desc, int ring_base, u32 flags)
- {
+ 				     int n_desc, int ring_base, void *wed,
+ 				     u32 flags)
 diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index 02d5232..f2b4ec9 100644
+index 362d937..83d0dd2 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -293,10 +293,7 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy,
+@@ -294,10 +294,7 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy,
  				 struct ieee80211_vif *vif,
  				 bool beacon, bool mcast)
  {
@@ -64,7 +64,7 @@
  	int rateidx = 0, mcast_rate;
  
  	if (!vif)
-@@ -329,7 +326,7 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy,
+@@ -330,7 +327,7 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy,
  		rateidx = ffs(vif->bss_conf.basic_rates) - 1;
  
  legacy:
diff --git a/recipes-wifi/linux-mt76/files/patches/2015-Revert-wifi-mt76-move-struct-ieee80211_chanctx_conf-.patch b/recipes-wifi/linux-mt76/files/patches/2015-Revert-wifi-mt76-move-struct-ieee80211_chanctx_conf-.patch
index db3e36c..474ef7b 100644
--- a/recipes-wifi/linux-mt76/files/patches/2015-Revert-wifi-mt76-move-struct-ieee80211_chanctx_conf-.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2015-Revert-wifi-mt76-move-struct-ieee80211_chanctx_conf-.patch
@@ -1,8 +1,8 @@
-From 7ff6353fd667964cc3e814dce1d79859e07fbdf4 Mon Sep 17 00:00:00 2001
+From c5df80abbbbcfe8b3845a03ca48fc7745ba0d972 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Mon, 23 Oct 2023 10:25:25 +0800
-Subject: [PATCH 4/6] Revert "wifi: mt76: move struct ieee80211_chanctx_conf up
- to struct mt76_vif"
+Subject: [PATCH 73/76] Revert "wifi: mt76: move struct ieee80211_chanctx_conf
+ up to struct mt76_vif"
 
 This reverts commit d1881b1b2bf6018d1cb1b91e4301a60021cacaa3.
 ---
@@ -13,10 +13,10 @@
  4 files changed, 9 insertions(+), 9 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 05144b2..3ff348f 100644
+index d082b24..699d84e 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -798,7 +798,6 @@ struct mt76_vif {
+@@ -836,7 +836,6 @@ struct mt76_vif {
  	u8 basic_rates_idx;
  	u8 mcast_rates_idx;
  	u8 beacon_rates_idx;
@@ -25,10 +25,10 @@
  
  struct mt76_phy {
 diff --git a/mt7921/main.c b/mt7921/main.c
-index 6a5c2ca..28c7e04 100644
+index aa0cd78..ffcad1e 100644
 --- a/mt7921/main.c
 +++ b/mt7921/main.c
-@@ -756,7 +756,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -801,7 +801,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  
  	if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
  		mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, &mvif->sta.wcid,
@@ -37,7 +37,7 @@
  
  	ewma_avg_signal_init(&msta->avg_ack_signal);
  
-@@ -791,7 +791,7 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -836,7 +836,7 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  		if (!sta->tdls)
  			mt76_connac_mcu_uni_add_bss(&dev->mphy, vif,
  						    &mvif->sta.wcid, false,
@@ -46,7 +46,7 @@
  	}
  
  	spin_lock_bh(&dev->mt76.sta_poll_lock);
-@@ -1208,7 +1208,7 @@ mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1255,7 +1255,7 @@ mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	mt792x_mutex_acquire(dev);
  
  	err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,
@@ -55,7 +55,7 @@
  	if (err)
  		goto out;
  
-@@ -1240,7 +1240,7 @@ mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1287,7 +1287,7 @@ mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		goto out;
  
  	mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, false,
@@ -64,7 +64,7 @@
  
  out:
  	mt792x_mutex_release(dev);
-@@ -1265,7 +1265,7 @@ static void mt7921_ctx_iter(void *priv, u8 *mac,
+@@ -1312,7 +1312,7 @@ static void mt7921_ctx_iter(void *priv, u8 *mac,
  	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
  	struct ieee80211_chanctx_conf *ctx = priv;
  
@@ -73,7 +73,7 @@
  		return;
  
  	if (vif->type == NL80211_IFTYPE_MONITOR)
-@@ -1298,7 +1298,7 @@ static void mt7921_mgd_prepare_tx(struct ieee80211_hw *hw,
+@@ -1345,7 +1345,7 @@ static void mt7921_mgd_prepare_tx(struct ieee80211_hw *hw,
  		       jiffies_to_msecs(HZ);
  
  	mt792x_mutex_acquire(dev);
@@ -83,10 +83,10 @@
  	mt792x_mutex_release(dev);
  }
 diff --git a/mt792x.h b/mt792x.h
-index 548e89f..39cbd13 100644
+index 3c897b3..558753f 100644
 --- a/mt792x.h
 +++ b/mt792x.h
-@@ -93,6 +93,7 @@ struct mt792x_vif {
+@@ -106,6 +106,7 @@ struct mt792x_vif {
  	struct ewma_rssi rssi;
  
  	struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
@@ -95,10 +95,10 @@
  
  struct mt792x_phy {
 diff --git a/mt792x_core.c b/mt792x_core.c
-index 7c4a74f..8c97ac0 100644
+index 502be22..1228a8a 100644
 --- a/mt792x_core.c
 +++ b/mt792x_core.c
-@@ -243,7 +243,7 @@ int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
+@@ -265,7 +265,7 @@ int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
  	struct mt792x_dev *dev = mt792x_hw_dev(hw);
  
  	mutex_lock(&dev->mt76.mutex);
@@ -107,7 +107,7 @@
  	mutex_unlock(&dev->mt76.mutex);
  
  	return 0;
-@@ -259,7 +259,7 @@ void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw,
+@@ -281,7 +281,7 @@ void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw,
  	struct mt792x_dev *dev = mt792x_hw_dev(hw);
  
  	mutex_lock(&dev->mt76.mutex);
diff --git a/recipes-wifi/linux-mt76/files/patches/2016-Revert-wifi-mt76-fix-race-condition-related-to-check.patch b/recipes-wifi/linux-mt76/files/patches/2016-Revert-wifi-mt76-fix-race-condition-related-to-check.patch
index d23662b..10eeb5e 100644
--- a/recipes-wifi/linux-mt76/files/patches/2016-Revert-wifi-mt76-fix-race-condition-related-to-check.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2016-Revert-wifi-mt76-fix-race-condition-related-to-check.patch
@@ -1,7 +1,7 @@
-From 04de28f9fec0bce1f37dd6bb3c2081d91bdc218e Mon Sep 17 00:00:00 2001
+From 32681b271d223bd7646372cae382c11d8784797b Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Mon, 23 Oct 2023 10:26:01 +0800
-Subject: [PATCH 5/6] Revert "wifi: mt76: fix race condition related to
+Subject: [PATCH 74/76] Revert "wifi: mt76: fix race condition related to
  checking tx queue fill status"
 
 This reverts commit f1e1e67d97d1e9a8bb01b59ab20c45ebc985a958.
@@ -12,10 +12,10 @@
  3 files changed, 20 insertions(+), 120 deletions(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index e7c4dc4..4caa714 100644
+index 09c9eb2..5e01353 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -427,9 +427,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
+@@ -438,9 +438,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
  	struct mt76_dev *dev = phy->dev;
  	struct wiphy *wiphy = hw->wiphy;
  
@@ -25,7 +25,7 @@
  	SET_IEEE80211_DEV(hw, dev->dev);
  	SET_IEEE80211_PERM_ADDR(hw, phy->macaddr);
  
-@@ -662,7 +659,6 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
+@@ -673,7 +670,6 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
  	int ret;
  
  	dev_set_drvdata(dev->dev, dev);
@@ -33,7 +33,7 @@
  	ret = mt76_phy_init(phy, hw);
  	if (ret)
  		return ret;
-@@ -718,7 +714,6 @@ void mt76_unregister_device(struct mt76_dev *dev)
+@@ -729,7 +725,6 @@ void mt76_unregister_device(struct mt76_dev *dev)
  	if (IS_ENABLED(CONFIG_MT76_LEDS))
  		mt76_led_cleanup(&dev->phy);
  	mt76_tx_status_check(dev, true);
@@ -41,7 +41,7 @@
  	ieee80211_unregister_hw(hw);
  }
  EXPORT_SYMBOL_GPL(mt76_unregister_device);
-@@ -1465,9 +1460,6 @@ EXPORT_SYMBOL_GPL(mt76_sta_pre_rcu_remove);
+@@ -1477,9 +1472,6 @@ EXPORT_SYMBOL_GPL(mt76_sta_pre_rcu_remove);
  
  void mt76_wcid_init(struct mt76_wcid *wcid)
  {
@@ -51,7 +51,7 @@
  	INIT_LIST_HEAD(&wcid->list);
  	idr_init(&wcid->pktid);
  }
-@@ -1475,32 +1467,13 @@ EXPORT_SYMBOL_GPL(mt76_wcid_init);
+@@ -1487,32 +1479,13 @@ EXPORT_SYMBOL_GPL(mt76_wcid_init);
  
  void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid)
  {
@@ -85,10 +85,10 @@
  EXPORT_SYMBOL_GPL(mt76_wcid_cleanup);
  
 diff --git a/mt76.h b/mt76.h
-index 3ff348f..5eb571e 100644
+index 699d84e..70801f7 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -354,9 +354,6 @@ struct mt76_wcid {
+@@ -380,9 +380,6 @@ struct mt76_wcid {
  	u32 tx_info;
  	bool sw_iv;
  
@@ -98,7 +98,7 @@
  	struct list_head list;
  	struct idr pktid;
  
-@@ -808,8 +805,6 @@ struct mt76_phy {
+@@ -846,8 +843,6 @@ struct mt76_phy {
  	unsigned long state;
  	u8 band_idx;
  
diff --git a/recipes-wifi/linux-mt76/files/patches/2999-wifi-mt76-mt7915-support-backaward-compatiable.patch b/recipes-wifi/linux-mt76/files/patches/2999-wifi-mt76-mt7915-support-backaward-compatiable.patch
new file mode 100644
index 0000000..933e475
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/2999-wifi-mt76-mt7915-support-backaward-compatiable.patch
@@ -0,0 +1,57 @@
+From d862aa94954361f72187565f0835a6bd025d3b7a Mon Sep 17 00:00:00 2001
+From: Rex Lu <rex.lu@mediatek.com>
+Date: Mon, 11 Dec 2023 19:21:16 +0800
+Subject: [PATCH 75/76] wifi: mt76: mt7915: support backaward compatiable
+
+---
+ dma.c  | 20 --------------------
+ mmio.c |  2 +-
+ 2 files changed, 1 insertion(+), 21 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index dfedbcd..174ac89 100644
+--- a/dma.c
++++ b/dma.c
+@@ -781,26 +781,6 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ 		if (!ret)
+ 			q->wed_regs = q->wed->rx_ring[ring].reg_base;
+ 		break;
+-	case MT76_WED_RRO_Q_DATA:
+-		q->flags &= ~MT_QFLAG_WED;
+-		__mt76_dma_queue_reset(dev, q, false);
+-		mtk_wed_device_rro_rx_ring_setup(q->wed, ring, q->regs);
+-		q->head = q->ndesc - 1;
+-		q->queued = q->head;
+-		break;
+-	case MT76_WED_RRO_Q_MSDU_PG:
+-		q->flags &= ~MT_QFLAG_WED;
+-		__mt76_dma_queue_reset(dev, q, false);
+-		mtk_wed_device_msdu_pg_rx_ring_setup(q->wed, ring, q->regs);
+-		q->head = q->ndesc - 1;
+-		q->queued = q->head;
+-		break;
+-	case MT76_WED_RRO_Q_IND:
+-		q->flags &= ~MT_QFLAG_WED;
+-		mt76_dma_queue_reset(dev, q);
+-		mt76_dma_rx_fill(dev, q);
+-		mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
+-		break;
+ 	default:
+ 		ret = -EINVAL;
+ 		break;
+diff --git a/mmio.c b/mmio.c
+index b6617f7..f4d0142 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -134,7 +134,7 @@ EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
+ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ {
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+-	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
++	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
+ 	u32 length;
+ 	int i;
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch b/recipes-wifi/linux-mt76/files/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch
index 3132a24..3946fb9 100644
--- a/recipes-wifi/linux-mt76/files/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch
+++ b/recipes-wifi/linux-mt76/files/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch
@@ -1,12 +1,13 @@
-From 8a9009b2bed6a9ae4c7a3a4d12fe8d7e15293103 Mon Sep 17 00:00:00 2001
+From f399cbeaea461c522df665bea9f46b927eb2b691 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 5 Apr 2023 08:29:19 +0800
-Subject: [PATCH 6/6] mt76: revert for backports-5.15 wireless stack
+Subject: [PATCH 76/76] mt76: revert for backports-5.15 wireless stack
 
 wifi: mt76: mt7915: add support for he ldpc control from hostapd
 ---
  dma.c             |   2 +-
  mac80211.c        |  15 +--
+ mmio.c            |   1 +
  mt7615/dma.c      |   4 +-
  mt7615/main.c     |   6 +-
  mt7615/mcu.c      |   8 +-
@@ -18,16 +19,15 @@
  mt7915/init.c     |   3 +-
  mt7915/main.c     |  36 ++-----
  mt7915/mcu.c      | 246 ++++++++++++++++++++++++++++++----------------
- mt7915/mmio.c     |   2 +-
  mt7915/testmode.c |   8 +-
  tx.c              |  22 ++---
- 16 files changed, 259 insertions(+), 226 deletions(-)
+ 16 files changed, 259 insertions(+), 225 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 7c5e623..908852c 100644
+index 174ac89..34b8a5c 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -996,7 +996,7 @@ mt76_dma_init(struct mt76_dev *dev,
+@@ -1071,7 +1071,7 @@ mt76_dma_init(struct mt76_dev *dev,
  	init_completion(&dev->mmio.wed_reset_complete);
  
  	mt76_for_each_q_rx(dev, i) {
@@ -37,10 +37,10 @@
  		napi_enable(&dev->napi[i]);
  	}
 diff --git a/mac80211.c b/mac80211.c
-index 4caa714..923c6a3 100644
+index 5e01353..5bf918b 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -1041,14 +1041,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -1053,14 +1053,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
  	status->enc_flags = mstat.enc_flags;
  	status->encoding = mstat.encoding;
  	status->bw = mstat.bw;
@@ -58,7 +58,7 @@
  	status->rate_idx = mstat.rate_idx;
  	status->nss = mstat.nss;
  	status->band = mstat.band;
-@@ -1546,7 +1541,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power);
+@@ -1558,7 +1553,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power);
  static void
  __mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
  {
@@ -67,7 +67,7 @@
  		ieee80211_csa_finish(vif);
  }
  
-@@ -1568,7 +1563,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
+@@ -1580,7 +1575,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
  {
  	struct mt76_dev *dev = priv;
  
@@ -76,8 +76,20 @@
  		return;
  
  	dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif);
+diff --git a/mmio.c b/mmio.c
+index f4d0142..04c4988 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -159,6 +159,7 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 		phy_addr = dma_map_single(dev->dma_dev, ptr,
+ 					  wed->wlan.rx_size,
+ 					  DMA_TO_DEVICE);
++
+ 		if (unlikely(dma_mapping_error(dev->dev, phy_addr))) {
+ 			skb_free_frag(ptr);
+ 			mt76_put_rxwi(dev, r);
 diff --git a/mt7615/dma.c b/mt7615/dma.c
-index 0ce01cc..ad32485 100644
+index e7135b2..6767c39 100644
 --- a/mt7615/dma.c
 +++ b/mt7615/dma.c
 @@ -282,8 +282,8 @@ int mt7615_dma_init(struct mt7615_dev *dev)
@@ -123,7 +135,7 @@
  	if (changed & BSS_CHANGED_MU_GROUPS)
  		 mt7615_update_mu_group(hw, vif, info);
 diff --git a/mt7615/mcu.c b/mt7615/mcu.c
-index db337aa..c4d9743 100644
+index c9444c6..466f38e 100644
 --- a/mt7615/mcu.c
 +++ b/mt7615/mcu.c
 @@ -353,7 +353,7 @@ out:
@@ -163,10 +175,10 @@
  		.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
  	};
 diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index f2b4ec9..431d60d 100644
+index 83d0dd2..74a65df 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -1107,7 +1107,7 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+@@ -1111,7 +1111,7 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
  	u32 val;
  
  	if (!sta ||
@@ -176,10 +188,10 @@
  
  	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 1d22ab9..3a6404a 100644
+index e359388..5bf5fa1 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -198,7 +198,7 @@ int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
+@@ -199,7 +199,7 @@ int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
  			      */
  	} req = {
  		.bss_idx = mvif->idx,
@@ -188,7 +200,7 @@
  	};
  
  	if (vif->type != NL80211_IFTYPE_STATION)
-@@ -410,7 +410,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -411,7 +411,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  		else
  			conn_type = CONNECTION_INFRA_AP;
  		basic->conn_type = cpu_to_le32(conn_type);
@@ -197,7 +209,7 @@
  		break;
  	case NL80211_IFTYPE_ADHOC:
  		basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
-@@ -554,7 +554,7 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
+@@ -555,7 +555,7 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
  
  	if (sta) {
  		if (vif->type == NL80211_IFTYPE_STATION)
@@ -206,7 +218,7 @@
  		else
  			generic->partial_aid = cpu_to_le16(sta->aid);
  		memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
-@@ -603,14 +603,14 @@ mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+@@ -604,14 +604,14 @@ mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  	    vif->type != NL80211_IFTYPE_STATION)
  		return;
  
@@ -223,7 +235,7 @@
  			       IEEE80211_MAX_MPDU_LEN_VHT_7991;
  
  	wcid->amsdu = true;
-@@ -621,7 +621,7 @@ mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+@@ -622,7 +622,7 @@ mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  static void
  mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  {
@@ -232,7 +244,7 @@
  	struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
  	struct sta_rec_he *he;
  	struct tlv *tlv;
-@@ -709,7 +709,7 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -710,7 +710,7 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  
  	he->he_cap = cpu_to_le32(cap);
  
@@ -241,7 +253,7 @@
  	case IEEE80211_STA_RX_BW_160:
  		if (elem->phy_cap_info[0] &
  		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
-@@ -754,7 +754,7 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -755,7 +755,7 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  void
  mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
  {
@@ -250,7 +262,7 @@
  	struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
  	struct sta_rec_he_v2 *he;
  	struct tlv *tlv;
-@@ -765,7 +765,7 @@ mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -766,7 +766,7 @@ mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
  	memcpy(he->he_phy_cap, elem->phy_cap_info, sizeof(he->he_phy_cap));
  	memcpy(he->he_mac_cap, elem->mac_cap_info, sizeof(he->he_mac_cap));
  
@@ -259,7 +271,7 @@
  	case IEEE80211_STA_RX_BW_160:
  		if (elem->phy_cap_info[0] &
  		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
-@@ -781,7 +781,7 @@ mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -782,7 +782,7 @@ mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
  		break;
  	}
  
@@ -268,7 +280,7 @@
  }
  EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_he_tlv_v2);
  
-@@ -792,14 +792,12 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+@@ -793,14 +793,12 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
  	struct ieee80211_sta_ht_cap *ht_cap;
  	struct ieee80211_sta_vht_cap *vht_cap;
  	const struct ieee80211_sta_he_cap *he_cap;
@@ -286,7 +298,7 @@
  	} else {
  		struct ieee80211_supported_band *sband;
  
-@@ -807,7 +805,6 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+@@ -808,7 +806,6 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
  		ht_cap = &sband->ht_cap;
  		vht_cap = &sband->vht_cap;
  		he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
@@ -294,7 +306,7 @@
  	}
  
  	if (band == NL80211_BAND_2GHZ) {
-@@ -818,9 +815,6 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+@@ -819,9 +816,6 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
  
  		if (he_cap && he_cap->has_he)
  			mode |= PHY_TYPE_BIT_HE;
@@ -304,7 +316,7 @@
  	} else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
  		mode |= PHY_TYPE_BIT_OFDM;
  
-@@ -832,9 +826,6 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+@@ -833,9 +827,6 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
  
  		if (he_cap && he_cap->has_he)
  			mode |= PHY_TYPE_BIT_HE;
@@ -314,7 +326,7 @@
  	}
  
  	return mode;
-@@ -856,25 +847,25 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -857,25 +848,25 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  	u16 supp_rates;
  
  	/* starec ht */
@@ -346,7 +358,7 @@
  	}
  
  	/* starec uapsd */
-@@ -883,11 +874,11 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -884,11 +875,11 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  	if (!is_mt7921(dev))
  		return;
  
@@ -360,7 +372,7 @@
  		mt76_connac_mcu_sta_he_tlv(skb, sta);
  		mt76_connac_mcu_sta_he_tlv_v2(skb, sta);
  		if (band == NL80211_BAND_6GHZ &&
-@@ -897,7 +888,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -898,7 +889,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  			tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G,
  						      sizeof(*he_6g_capa));
  			he_6g_capa = (struct sta_rec_he_6g_capa *)tlv;
@@ -369,7 +381,7 @@
  		}
  	}
  
-@@ -907,14 +898,14 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -908,14 +899,14 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  	phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
  	phy->rcpi = rcpi;
  	phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR,
@@ -387,7 +399,7 @@
  	if (band == NL80211_BAND_2GHZ)
  		supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) |
  			     FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf);
-@@ -923,18 +914,18 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -924,18 +915,18 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  
  	ra_info->legacy = cpu_to_le16(supp_rates);
  
@@ -411,7 +423,7 @@
  			IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
  	}
  }
-@@ -950,7 +941,7 @@ void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb,
+@@ -951,7 +942,7 @@ void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb,
  	tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
  					     wtbl_tlv, sta_wtbl);
  	smps = (struct wtbl_smps *)tlv;
@@ -420,7 +432,7 @@
  }
  EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_smps_tlv);
  
-@@ -962,27 +953,27 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -963,27 +954,27 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  	struct tlv *tlv;
  	u32 flags = 0;
  
@@ -456,7 +468,7 @@
  		struct wtbl_vht *vht;
  		u8 af;
  
-@@ -991,18 +982,18 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -992,18 +983,18 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  						     sta_wtbl);
  		vht = (struct wtbl_vht *)tlv;
  		vht->ldpc = vht_ldpc &&
@@ -478,7 +490,7 @@
  		/* sgi */
  		u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 |
  			  MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160;
-@@ -1012,15 +1003,15 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -1013,15 +1004,15 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  						     sizeof(*raw), wtbl_tlv,
  						     sta_wtbl);
  
@@ -499,7 +511,7 @@
  				flags |= MT_WTBL_W5_SHORT_GI_160;
  		}
  		raw = (struct wtbl_raw *)tlv;
-@@ -1309,9 +1300,9 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1310,9 +1301,9 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
  		return 0x38;
  
  	if (sta) {
@@ -512,7 +524,7 @@
  	} else {
  		struct ieee80211_supported_band *sband;
  
-@@ -1631,7 +1622,6 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1632,7 +1623,6 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
  	for (i = 0; i < sreq->n_ssids; i++) {
  		if (!sreq->ssids[i].ssid_len)
  			continue;
@@ -520,7 +532,7 @@
  		req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
  		memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
  		       sreq->ssids[i].ssid_len);
-@@ -1771,7 +1761,6 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
+@@ -1772,7 +1762,6 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
  		memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
  		req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
  	}
@@ -528,7 +540,7 @@
  	req->match_num = sreq->n_match_sets;
  	for (i = 0; i < req->match_num; i++) {
  		match = &sreq->match_sets[i];
-@@ -2267,10 +2256,8 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
+@@ -2148,10 +2137,8 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
  				      struct mt76_vif *vif,
  				      struct ieee80211_bss_conf *info)
  {
@@ -540,7 +552,7 @@
  			   IEEE80211_BSS_ARP_ADDR_LIST_LEN);
  	struct {
  		struct {
-@@ -2298,7 +2285,7 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
+@@ -2179,7 +2166,7 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
  
  	skb_put_data(skb, &req_hdr, sizeof(req_hdr));
  	for (i = 0; i < len; i++)
@@ -590,10 +602,10 @@
  	field = RATE_PARAM_FIXED;
  
 diff --git a/mt7915/dma.c b/mt7915/dma.c
-index f71ec55..b4e231b 100644
+index a0f393a..4cb94d3 100644
 --- a/mt7915/dma.c
 +++ b/mt7915/dma.c
-@@ -590,8 +590,8 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+@@ -596,8 +596,8 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
  	if (ret < 0)
  		return ret;
  
@@ -605,7 +617,7 @@
  
  	mt7915_dma_enable(dev, false);
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 9978edb..d50e694 100644
+index 978e585..c845bfe 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
 @@ -1181,8 +1181,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
@@ -619,10 +631,10 @@
  
  		if (band == NL80211_BAND_6GHZ) {
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 9595b55..29bfec8 100644
+index 02682ce..1b47016 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -540,7 +540,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
+@@ -552,7 +552,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
  
  static int
  mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -631,7 +643,7 @@
  	       const struct ieee80211_tx_queue_params *params)
  {
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-@@ -641,7 +641,7 @@ mt7915_update_bss_color(struct ieee80211_hw *hw,
+@@ -653,7 +653,7 @@ mt7915_update_bss_color(struct ieee80211_hw *hw,
  static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
  				    struct ieee80211_vif *vif,
  				    struct ieee80211_bss_conf *info,
@@ -640,7 +652,7 @@
  {
  	struct mt7915_phy *phy = mt7915_hw_phy(hw);
  	struct mt7915_dev *dev = mt7915_hw_dev(hw);
-@@ -657,7 +657,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+@@ -669,7 +669,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
  	    vif->type == NL80211_IFTYPE_STATION)
  		set_bss_info = set_sta = !is_zero_ether_addr(info->bssid);
  	if (changed & BSS_CHANGED_ASSOC)
@@ -649,7 +661,7 @@
  	if (changed & BSS_CHANGED_BEACON_ENABLED &&
  	    vif->type != NL80211_IFTYPE_AP)
  		set_bss_info = set_sta = info->enable_beacon;
-@@ -705,27 +705,8 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+@@ -717,27 +717,8 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
  	mutex_unlock(&dev->mt76.mutex);
  }
  
@@ -678,7 +690,7 @@
  {
  	struct mt7915_phy *phy = mt7915_hw_phy(hw);
  	struct mt7915_dev *dev = mt7915_hw_dev(hw);
-@@ -733,8 +714,6 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -745,8 +726,6 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  
  	mutex_lock(&dev->mt76.mutex);
  
@@ -687,7 +699,7 @@
  	err = mt7915_mcu_add_bss_info(phy, vif, true);
  	if (err)
  		goto out;
-@@ -746,8 +725,7 @@ out:
+@@ -758,8 +737,7 @@ out:
  }
  
  static void
@@ -697,7 +709,7 @@
  {
  	struct mt7915_dev *dev = mt7915_hw_dev(hw);
  
-@@ -1317,10 +1295,10 @@ static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw,
+@@ -1329,10 +1307,10 @@ static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw,
  {
  	struct mt7915_phy *phy = mt7915_hw_phy(hw);
  	struct mt7915_dev *dev = mt7915_hw_dev(hw);
@@ -711,7 +723,7 @@
  
  	mutex_lock(&dev->mt76.mutex);
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 72f74e1..cb534af 100644
+index 3ff53db..2af358c 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -67,7 +67,7 @@ mt7915_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs,
@@ -1303,7 +1315,7 @@
  	mt7915_mcu_beacon_cntdwn(vif, rskb, skb, bcn, &offs);
  	mt7915_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs);
  	mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
-@@ -3351,17 +3431,17 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3356,17 +3436,17 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  	if (txpower) {
  		u32 offs, len, i;
  
@@ -1324,19 +1336,6 @@
  					offs += len + sku_len[SKU_HE_RU26] * 3;
  					len = sku_len[SKU_HE_RU242] * 4;
  				}
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index ce976b4..3755690 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -689,7 +689,7 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- 		phy_addr = dma_map_single(dev->mt76.dma_dev, ptr,
- 					  wed->wlan.rx_size,
- 					  DMA_TO_DEVICE);
--		
-+
- 		if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
- 			skb_free_frag(ptr);
- 			mt76_put_rxwi(&dev->mt76, r);
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
 index ecd6271..b2c442b 100644
 --- a/mt7915/testmode.c
diff --git a/recipes-wifi/linux-mt76/files/patches/patches.inc b/recipes-wifi/linux-mt76/files/patches/patches.inc
index 8eeae08..e0f5c10 100644
--- a/recipes-wifi/linux-mt76/files/patches/patches.inc
+++ b/recipes-wifi/linux-mt76/files/patches/patches.inc
@@ -4,11 +4,13 @@
     file://0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch \
     file://0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch \
     file://0004-wifi-mt76-mt7915-fix-txpower-issues.patch \
-    file://0005-wifi-mt76-mt7915-rework-init-txpower.patch \
-    file://0006-wifi-mt76-mt7915-rework-mmio-access-flow.patch \
-    file://0007-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch \
-    file://0008-wifi-mt76-mt7915-add-new-chip-version-in-power-on-se.patch \
-    file://0009-wifi-mt76-mt7915-Fixed-null-pointer-dereference-.patch \
+    file://0005-wifi-mt76-mt7915-rework-mmio-access-flow.patch \
+    file://0006-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch \
+    file://0007-wifi-mt76-mt7915-add-new-chip-version-in-power-on-se.patch \
+    file://0008-wifi-mt76-mt7915-Fixed-null-pointer-dereference-issu.patch \
+    file://0009-wifi-mt76-ACS-channel-time-too-long-on-duty-channel.patch \
+    file://0010-wifi-mt76-check-txs-format-before-getting-skb-by-pid.patch \
+    file://0010-wifi-mt76-mt7915-add-post-channel-switch-for-DFS-cha.patch \
     file://0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch \
     file://1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch \
     file://1001-wifi-mt76-mt7915-csi-implement-csi-support.patch \
@@ -33,7 +35,7 @@
     file://1020-wifi-mt76-mt7915-Add-mu-dump-support.patch \
     file://1021-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch \
     file://1022-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch \
-    file://1023-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch \
+    file://1023-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch \
     file://1024-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch \
     file://1025-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch \
     file://1026-wifi-mt76-mt7915-amsdu-set-and-get-control.patch \
@@ -53,8 +55,9 @@
     file://1040-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch \
     file://1041-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch \
     file://1042-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch \
-    file://1043-wifi-mt76-mt7915-add-cheetah-eeprom-related-fix.patch \
-    file://1044-wifi-mt76-testmode-add-cheetah-support.patch \
+    file://1043-wifi-mt76-testmode-add-cheetah-support.patch \
+    file://1044-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch \
+    file://1045-wifi-mt76-mt7915-support-scs-feature.patch \
     file://2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch \
     file://2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch \
     file://2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch \
@@ -72,5 +75,6 @@
     file://2014-Revert-wifi-mt76-mt7921-fix-the-wrong-rate-pickup-fo.patch \
     file://2015-Revert-wifi-mt76-move-struct-ieee80211_chanctx_conf-.patch \
     file://2016-Revert-wifi-mt76-fix-race-condition-related-to-check.patch \
+    file://2999-wifi-mt76-mt7915-support-backaward-compatiable.patch \
     file://9999-mt76-revert-for-backports-5.15-wireless-stack.patch \
     "
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7988/i2p5ge-phy-pmb.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7988/i2p5ge-phy-pmb.bin
new file mode 100644
index 0000000..125dbcf
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7988/i2p5ge-phy-pmb.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_dsp.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_dsp.bin
new file mode 100644
index 0000000..59e7198
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_dsp.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_rom_patch.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_rom_patch.bin
new file mode 100644
index 0000000..362e1e0
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_rom_patch.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wa.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wa.bin
new file mode 100644
index 0000000..5779202
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wa.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wm.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wm.bin
new file mode 100644
index 0000000..369d2c2
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wm.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wm_tm.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wm_tm.bin
new file mode 100644
index 0000000..b965306
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_wm_tm.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_dsp.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_dsp.bin
index ada308b..d30bb8b 100755
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_dsp.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_dsp.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom.bin
index 3ef03df..6fb81b6 100755
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom_233.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom_233.bin
new file mode 100644
index 0000000..11eaa85
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom_233.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom_dual_404.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom_dual_404.bin
index 1a9f6c3..b490256 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom_dual_404.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_eeprom_dual_404.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin
index c391788..bb59108 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wa.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wa.bin
index 20d91ee..f848a78 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wa.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wa.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm.bin
index b6ca1a9..4d17742 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm_tm.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm_tm.bin
index 98d6517..cd98e1a 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm_tm.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm_tm.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/mt76.inc b/recipes-wifi/linux-mt76/mt76.inc
index b025358..b14cd49 100644
--- a/recipes-wifi/linux-mt76/mt76.inc
+++ b/recipes-wifi/linux-mt76/mt76.inc
@@ -1 +1 @@
-SRCREV ?= "2afc7285f75dca5a0583fd917285bf33f1429cc6"
+SRCREV ?= "bebd9cffc2aeb2cecb40aadbb8c6eab3bdf7971b"
diff --git a/recipes-wifi/mt76-vendor/files/src/csi.c b/recipes-wifi/mt76-vendor/files/src/csi.c
index d99eb58..ca7732e 100644
--- a/recipes-wifi/mt76-vendor/files/src/csi.c
+++ b/recipes-wifi/mt76-vendor/files/src/csi.c
@@ -14,6 +14,7 @@
 	[MTK_VENDOR_ATTR_CSI_CTRL_CFG_VAL2] = { .type = NLA_U8 },
 	[MTK_VENDOR_ATTR_CSI_CTRL_MAC_ADDR] = { .type = NLA_NESTED },
 	[MTK_VENDOR_ATTR_CSI_CTRL_INTERVAL] = { .type = NLA_U32 },
+	[MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL] = { .type = NLA_U32 },
 	[MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM] = { .type = NLA_U16 },
 	[MTK_VENDOR_ATTR_CSI_CTRL_DATA] = { .type = NLA_NESTED },
 };
@@ -26,13 +27,14 @@
 	[MTK_VENDOR_ATTR_CSI_DATA_BW] = { .type = NLA_U8 },
 	[MTK_VENDOR_ATTR_CSI_DATA_CH_IDX] = { .type = NLA_U8 },
 	[MTK_VENDOR_ATTR_CSI_DATA_TA] = { .type = NLA_NESTED },
+	[MTK_VENDOR_ATTR_CSI_DATA_NUM] = { .type = NLA_U32 },
 	[MTK_VENDOR_ATTR_CSI_DATA_I] = { .type = NLA_NESTED },
 	[MTK_VENDOR_ATTR_CSI_DATA_Q] = { .type = NLA_NESTED },
 	[MTK_VENDOR_ATTR_CSI_DATA_INFO] = { .type = NLA_U32 },
 	[MTK_VENDOR_ATTR_CSI_DATA_TX_ANT] = { .type = NLA_U8 },
 	[MTK_VENDOR_ATTR_CSI_DATA_RX_ANT] = { .type = NLA_U8 },
 	[MTK_VENDOR_ATTR_CSI_DATA_MODE] = { .type = NLA_U8 },
-	[MTK_VENDOR_ATTR_CSI_DATA_H_IDX] = { .type = NLA_U32 },
+	[MTK_VENDOR_ATTR_CSI_DATA_CHAIN_INFO] = { .type = NLA_U32 },
 };
 
 static int mt76_csi_dump_cb(struct nl_msg *msg, void *arg)
@@ -71,7 +73,7 @@
 	      tb_data[MTK_VENDOR_ATTR_CSI_DATA_Q] &&
 	      tb_data[MTK_VENDOR_ATTR_CSI_DATA_INFO] &&
 	      tb_data[MTK_VENDOR_ATTR_CSI_DATA_MODE] &&
-	      tb_data[MTK_VENDOR_ATTR_CSI_DATA_H_IDX])) {
+	      tb_data[MTK_VENDOR_ATTR_CSI_DATA_CHAIN_INFO])) {
 		fprintf(stderr, "Attributes error for CSI data\n");
 		return NL_SKIP;
 	}
@@ -85,11 +87,13 @@
 	c->tx_idx = nla_get_u16(tb_data[MTK_VENDOR_ATTR_CSI_DATA_TX_ANT]);
 	c->rx_idx = nla_get_u16(tb_data[MTK_VENDOR_ATTR_CSI_DATA_RX_ANT]);
 
-	c->info = nla_get_u32(tb_data[MTK_VENDOR_ATTR_CSI_DATA_INFO]);
-	c->h_idx = nla_get_u32(tb_data[MTK_VENDOR_ATTR_CSI_DATA_H_IDX]);
+	c->ext_info = nla_get_u32(tb_data[MTK_VENDOR_ATTR_CSI_DATA_INFO]);
+	c->chain_info = nla_get_u32(tb_data[MTK_VENDOR_ATTR_CSI_DATA_CHAIN_INFO]);
 
 	c->ts = nla_get_u32(tb_data[MTK_VENDOR_ATTR_CSI_DATA_TS]);
 
+	c->data_num = nla_get_u32(tb_data[MTK_VENDOR_ATTR_CSI_DATA_NUM]);
+
 	idx = 0;
 	nla_for_each_nested(cur, tb_data[MTK_VENDOR_ATTR_CSI_DATA_TA], rem) {
 		if (idx < ETH_ALEN)
@@ -98,13 +102,13 @@
 
 	idx = 0;
 	nla_for_each_nested(cur, tb_data[MTK_VENDOR_ATTR_CSI_DATA_I], rem) {
-		if (idx < CSI_MAX_COUNT)
+		if (idx < c->data_num)
 			c->data_i[idx++] = nla_get_u16(cur);
 	}
 
 	idx = 0;
 	nla_for_each_nested(cur, tb_data[MTK_VENDOR_ATTR_CSI_DATA_Q], rem) {
-		if (idx < CSI_MAX_COUNT)
+		if (idx < c->data_num)
 			c->data_q[idx++] = nla_get_u16(cur);
 	}
 
@@ -152,21 +156,21 @@
 		pos += snprintf(pos, MAX_BUF_SIZE, "%u,", c->rx_mode);
 		pos += snprintf(pos, MAX_BUF_SIZE, "%d,", c->tx_idx);
 		pos += snprintf(pos, MAX_BUF_SIZE, "%d,", c->rx_idx);
-		pos += snprintf(pos, MAX_BUF_SIZE, "%d,", c->h_idx);
-		pos += snprintf(pos, MAX_BUF_SIZE, "%d,", c->info);
+		pos += snprintf(pos, MAX_BUF_SIZE, "%d,", c->chain_info);
+		pos += snprintf(pos, MAX_BUF_SIZE, "%d,", c->ext_info);
 
 		pos += snprintf(pos, MAX_BUF_SIZE, "%c", '[');
-		for (j = 0; j < 256; j++) {
+		for (j = 0; j < c->data_num; j++) {
 			pos += snprintf(pos, MAX_BUF_SIZE, "%d", c->data_i[j]);
-			if (j != 255)
+			if (j != (c->data_num - 1))
 				pos += snprintf(pos, MAX_BUF_SIZE, ",");
 		}
 		pos += snprintf(pos, MAX_BUF_SIZE, "%c,", ']');
 
 		pos += snprintf(pos, MAX_BUF_SIZE, "%c", '[');
-		for (j = 0; j < 256; j++) {
+		for (j = 0; j < c->data_num; j++) {
 			pos += snprintf(pos, MAX_BUF_SIZE, "%d", c->data_q[j]);
-			if (j != 255)
+			if (j != (c->data_num - 1))
 				pos += snprintf(pos, MAX_BUF_SIZE, ",");
 		}
 		pos += snprintf(pos, MAX_BUF_SIZE, "%c", ']');
@@ -241,6 +245,7 @@
 			fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
 
 		unl_free(&unl);
+
 	}
 
 	mt76_csi_to_json(argv[1]);
@@ -278,7 +283,7 @@
 
 		free(s2);
 
-		if (argc == 2 &&
+		if ((argc == 2 || argc == 3) &&
 		!strncmp(argv[1], "mac_addr", strlen("mac_addr"))) {
 			u8 a[ETH_ALEN];
 			int matches, i;
@@ -303,6 +308,24 @@
 
 			nla_nest_end(msg, data);
 		}
+
+		if (argc == 3 &&
+		!strncmp(argv[2], "sta_interval", strlen("sta_interval"))) {
+			u32 sta_interval = 0;
+
+			val = strchr(argv[2], '=');
+
+			*(val++) = 0;
+
+			if (!val)
+				return -EINVAL;
+
+			sta_interval = strtoul(val, NULL, 0);
+
+			nla_put_u32(msg, MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL, sta_interval);
+
+		}
+
 	} else if (!strncmp(argv[0], "interval", 8)) {
 		u32 interval = strtoul(val, NULL, 0);
 
diff --git a/recipes-wifi/mt76-vendor/files/src/mt76-vendor.h b/recipes-wifi/mt76-vendor/files/src/mt76-vendor.h
index 61b0426..b591575 100644
--- a/recipes-wifi/mt76-vendor/files/src/mt76-vendor.h
+++ b/recipes-wifi/mt76-vendor/files/src/mt76-vendor.h
@@ -52,6 +52,7 @@
 	MTK_VENDOR_ATTR_CSI_CTRL_CFG_VAL2,
 	MTK_VENDOR_ATTR_CSI_CTRL_MAC_ADDR,
 	MTK_VENDOR_ATTR_CSI_CTRL_INTERVAL,
+	MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL,
 
 	MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM,
 
@@ -74,6 +75,7 @@
 	MTK_VENDOR_ATTR_CSI_DATA_BW,
 	MTK_VENDOR_ATTR_CSI_DATA_CH_IDX,
 	MTK_VENDOR_ATTR_CSI_DATA_TA,
+	MTK_VENDOR_ATTR_CSI_DATA_NUM,
 	MTK_VENDOR_ATTR_CSI_DATA_I,
 	MTK_VENDOR_ATTR_CSI_DATA_Q,
 	MTK_VENDOR_ATTR_CSI_DATA_INFO,
@@ -84,7 +86,7 @@
 	MTK_VENDOR_ATTR_CSI_DATA_TX_ANT,
 	MTK_VENDOR_ATTR_CSI_DATA_RX_ANT,
 	MTK_VENDOR_ATTR_CSI_DATA_MODE,
-	MTK_VENDOR_ATTR_CSI_DATA_H_IDX,
+	MTK_VENDOR_ATTR_CSI_DATA_CHAIN_INFO,
 
 	/* keep last */
 	NUM_MTK_VENDOR_ATTRS_CSI_DATA,
@@ -199,23 +201,33 @@
 		NUM_MTK_VENDOR_ATTRS_PHY_CAPA_DUMP - 1
 };
 
-#define CSI_MAX_COUNT 256
+#define CSI_BW20_DATA_COUNT	64
+#define CSI_BW40_DATA_COUNT	128
+#define CSI_BW80_DATA_COUNT	256
+#define CSI_BW160_DATA_COUNT	512
 #define ETH_ALEN 6
 
 struct csi_data {
-	s16 data_i[CSI_MAX_COUNT];
-	s16 data_q[CSI_MAX_COUNT];
+	u8 ch_bw;
+	u16 data_num;
+	s16 data_i[CSI_BW160_DATA_COUNT];
+	s16 data_q[CSI_BW160_DATA_COUNT];
+	u8 band;
 	s8 rssi;
 	u8 snr;
 	u32 ts;
 	u8 data_bw;
 	u8 pri_ch_idx;
 	u8 ta[ETH_ALEN];
-	u32 info;
+	u32 ext_info;
 	u8 rx_mode;
-	u32 h_idx;
+	u32 chain_info;
 	u16 tx_idx;
 	u16 rx_idx;
+	u32 segment_num;
+	u8 remain_last;
+	u16 pkt_sn;
+	u8 tr_stream;
 };
 
 struct amnt_data {
diff --git a/recipes-wifi/ubus/ubus_git.bb b/recipes-wifi/ubus/ubus_git.bb
index 3b4ce84..d163b4e 100644
--- a/recipes-wifi/ubus/ubus_git.bb
+++ b/recipes-wifi/ubus/ubus_git.bb
@@ -10,7 +10,10 @@
           file://0001-lua5.3-support.patch \
           "
 
-SRCREV = "f787c97b34894a38b15599886cacbca01271684f"
+wifi6_ver = "4fc532c8a55ba8217ad67d7fd47c5eb9a8aba044"
+wifi7_ver = "f84eb5998c6ea2d34989ca2d3254e56c66139313"
+
+SRCREV = "${@bb.utils.contains('DISTRO_FEATURES', 'wifi_eht', '${wifi7_ver}', '${wifi6_ver}', d)}"
 
 PV = "git${SRCPV}"
 
diff --git a/recipes-wifi/udebug/Makefile b/recipes-wifi/udebug/Makefile
new file mode 100644
index 0000000..0a54515
--- /dev/null
+++ b/recipes-wifi/udebug/Makefile
@@ -0,0 +1,82 @@
+#
+# Copyright (C) 2023 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=udebug
+CMAKE_INSTALL:=1
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=$(PROJECT_GIT)/project/udebug.git
+PKG_MIRROR_HASH:=553a58a14b59dc7b22755557acbc74f0655a431442a4faca56d28cdb1ef14fb4
+PKG_SOURCE_DATE:=2023-12-06
+PKG_SOURCE_VERSION:=6d3f51f9fda706f0cf4732c762e4dbe8c21e12cf
+PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
+
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libudebug
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=udebug client library
+  DEPENDS:=+libubox +libubus
+endef
+
+define Package/udebugd
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=OpenWrt debug service
+  DEPENDS:=+libudebug
+endef
+
+define Package/udebugd/conffiles
+/etc/config/udebug
+endef
+
+define Package/ucode-mod-udebug
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=ucode udebug module
+  DEPENDS:=+libucode +libudebug
+endef
+
+define Package/udebug-cli
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=OpenWrt debug service CLI
+  DEPENDS:=+udebugd +ucode-mod-udebug
+endef
+
+define Package/libudebug/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib
+endef
+
+define Package/ucode-mod-udebug/install
+	$(INSTALL_DIR) $(1)/usr/lib/ucode
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/ucode/*.so $(1)/usr/lib/ucode
+endef
+
+define Package/udebugd/install
+	$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config
+	$(INSTALL_BIN) ./files/udebug.config $(1)/etc/config/udebug
+	$(INSTALL_BIN) ./files/udebug.init $(1)/etc/init.d/udebug
+	$(CP) $(PKG_INSTALL_DIR)/usr/sbin/udebugd $(1)/usr/sbin
+endef
+
+define Package/udebug-cli/install
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/udebug-cli $(1)/usr/sbin/udebug
+endef
+
+$(eval $(call BuildPackage,libudebug))
+$(eval $(call BuildPackage,udebugd))
+$(eval $(call BuildPackage,ucode-mod-udebug))
+$(eval $(call BuildPackage,udebug-cli))
diff --git a/recipes-wifi/udebug/files/COPYING b/recipes-wifi/udebug/files/COPYING
new file mode 100644
index 0000000..d511905
--- /dev/null
+++ b/recipes-wifi/udebug/files/COPYING
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/recipes-wifi/udebug/files/udebug.config b/recipes-wifi/udebug/files/udebug.config
new file mode 100644
index 0000000..68ddefe
--- /dev/null
+++ b/recipes-wifi/udebug/files/udebug.config
@@ -0,0 +1,30 @@
+config service procd
+	option enabled 0
+
+config service log
+	option enabled 0
+	option debug 0
+	option kernel 1
+	option syslog 1
+
+config service hostapd
+	option enabled 0
+	option wpa_log 1
+	option wpa_nl_rx 0
+	option wpa_nl_tx 0
+	option wpa_nl_ctrl 0
+
+config service wpa_supplicant
+	option enabled 0
+	option wpa_log 1
+	option wpa_nl_rx 0
+	option wpa_nl_tx 0
+	option wpa_nl_ctrl 0
+
+config service netifd
+	option enabled 0
+	option netifd_log 1
+	option netifd_nl 0
+
+config service umdns
+	option enabled 0
diff --git a/recipes-wifi/udebug/files/udebug.init b/recipes-wifi/udebug/files/udebug.init
new file mode 100644
index 0000000..b57e962
--- /dev/null
+++ b/recipes-wifi/udebug/files/udebug.init
@@ -0,0 +1,55 @@
+#!/bin/sh /etc/rc.common
+# Copyright (c) 2021 OpenWrt.org
+
+START=11
+
+USE_PROCD=1
+PROG=/usr/sbin/udebugd
+
+start_service() {
+	procd_open_instance
+	procd_set_param command "$PROG"
+	procd_set_param respawn
+	procd_close_instance
+}
+
+get_vars() {
+	local cfg="$1"
+	uci show "udebug.$cfg" | while read LINE; do
+		cur="${LINE##udebug.$1.}"
+		[[ "$cur" = "$LINE" ]] && continue
+		var="${cur%%=*}"
+		[[ "$cur" = "$var" ]] && continue
+		echo "$var"
+	done
+}
+
+add_debug_service() {
+	local cfg="$1"
+
+	json_add_object "$cfg"
+	for var in $(get_vars "$cfg"); do
+		config_get val "$cfg" "$var"
+		json_add_string "$var" "$val"
+	done
+	json_close_object "$cfg"
+}
+
+reload_service() {
+	config_load udebug
+
+	json_init
+	json_add_object service
+	config_foreach add_debug_service service
+	json_close_object
+	ubus call udebug set_config "$(json_dump)"
+}
+
+service_triggers() {
+	procd_add_reload_trigger udebug
+}
+
+service_started() {
+	ubus -t 10 wait_for udebug
+	[ $? = 0 ] && reload_service
+}
diff --git a/recipes-wifi/udebug/udebug_git.bb b/recipes-wifi/udebug/udebug_git.bb
new file mode 100644
index 0000000..71228f2
--- /dev/null
+++ b/recipes-wifi/udebug/udebug_git.bb
@@ -0,0 +1,29 @@
+DESCRIPTION = "OpenWrt debug service"
+SECTION = "utils"
+LICENSE = "GPL-2.0-only"
+LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
+
+SRC_URI = " \
+    git://git.openwrt.org/project/udebug.git;protocol=https \
+    file://udebug.config \
+    file://udebug.init \
+    file://COPYING;subdir=git \
+"
+
+SRCREV = "6d3f51f9fda706f0cf4732c762e4dbe8c21e12cf"
+PV = "git${SRCPV}"
+
+S = "${WORKDIR}/git"
+
+
+DEPENDS += "libnl-tiny libubox ubus ucode"
+
+INSANE_SKIP_${PN} += "file-rdeps dev-deps dev-so"
+FILES_SOLIBSDEV = ""
+
+FILES_${PN}-dev = "${includedir}/*"
+FILES_${PN} = "${bindir}/* ${libdir}/*.so* ${libdir}/ucode/*"
+
+inherit cmake pkgconfig python3native  
+
+
diff --git a/recipes-wifi/wpa-supplicant/files/002-rdkb-add-ucode-support.patch b/recipes-wifi/wpa-supplicant/files/002-rdkb-add-ucode-support.patch
index 16e099a..d31a75f 100644
--- a/recipes-wifi/wpa-supplicant/files/002-rdkb-add-ucode-support.patch
+++ b/recipes-wifi/wpa-supplicant/files/002-rdkb-add-ucode-support.patch
@@ -4,7 +4,7 @@
  OBJS += ../src/utils/ucode.o
  OBJS += ../src/ap/ucode.o
  NEED_ULOOP:=y
-+LIBS += -lblobmsg_json -lucode
++LIBS += -lblobmsg_json -lucode -ludebug
  endif
  
  ifdef NEED_ULOOP
@@ -15,7 +15,7 @@
  OBJS += ../src/utils/ucode.o
  OBJS += ucode.o
  NEED_ULOOP:=y
-+LIBS += -lblobmsg_json -lucode
++LIBS += -lblobmsg_json -lucode -ludebug
  endif
  
  ifdef NEED_ULOOP
\ No newline at end of file
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/601-ucode_support.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/601-ucode_support.patch
index 23f535b..cfdb51f 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/601-ucode_support.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/601-ucode_support.patch
@@ -196,7 +196,7 @@
  
  #ifdef CONFIG_BGSCAN
  	if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid)
-@@ -7596,6 +7597,7 @@ struct wpa_supplicant * wpa_supplicant_a
+@@ -7594,6 +7595,7 @@ struct wpa_supplicant * wpa_supplicant_a
  #endif /* CONFIG_P2P */
  
  	wpas_ubus_add_bss(wpa_s);
@@ -204,7 +204,7 @@
  
  	return wpa_s;
  }
-@@ -7623,6 +7625,7 @@ int wpa_supplicant_remove_iface(struct w
+@@ -7621,6 +7623,7 @@ int wpa_supplicant_remove_iface(struct w
  	struct wpa_supplicant *parent = wpa_s->parent;
  #endif /* CONFIG_MESH */
  
@@ -212,7 +212,7 @@
  	wpas_ubus_free_bss(wpa_s);
  
  	/* Remove interface from the global list of interfaces */
-@@ -7933,6 +7936,7 @@ struct wpa_global * wpa_supplicant_init(
+@@ -7931,6 +7934,7 @@ struct wpa_global * wpa_supplicant_init(
  
  	eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
  			       wpas_periodic, global, NULL);
@@ -220,7 +220,7 @@
  
  	return global;
  }
-@@ -7971,12 +7975,8 @@ int wpa_supplicant_run(struct wpa_global
+@@ -7969,12 +7973,8 @@ int wpa_supplicant_run(struct wpa_global
  	eloop_register_signal_terminate(wpa_supplicant_terminate, global);
  	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
  
@@ -233,7 +233,7 @@
  	return 0;
  }
  
-@@ -8009,6 +8009,8 @@ void wpa_supplicant_deinit(struct wpa_gl
+@@ -8007,6 +8007,8 @@ void wpa_supplicant_deinit(struct wpa_gl
  
  	wpas_notify_supplicant_deinitialized(global);
  
@@ -395,7 +395,60 @@
  {
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -1333,7 +1333,7 @@ static void wpa_driver_nl80211_event_rtm
+@@ -73,6 +73,16 @@ enum nlmsgerr_attrs {
+ 
+ #endif /* ANDROID */
+ 
++static void handle_nl_debug_hook(struct nl_msg *msg, int tx)
++{
++	const struct nlmsghdr *nlh;
++
++	if (!wpa_netlink_hook)
++		return;
++
++	nlh = nlmsg_hdr(msg);
++	wpa_netlink_hook(tx, nlh, nlh->nlmsg_len);
++}
+ 
+ static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
+ {
+@@ -379,6 +389,11 @@ static int no_seq_check(struct nl_msg *m
+ 	return NL_OK;
+ }
+ 
++static int debug_handler(struct nl_msg *msg, void *arg)
++{
++	handle_nl_debug_hook(msg, 0);
++	return NL_OK;
++}
+ 
+ static void nl80211_nlmsg_clear(struct nl_msg *msg)
+ {
+@@ -415,6 +430,7 @@ static int send_and_recv(struct nl80211_
+ 	if (!msg)
+ 		return -ENOMEM;
+ 
++	handle_nl_debug_hook(msg, 1);
+ 	cb = nl_cb_clone(global->nl_cb);
+ 	if (!cb)
+ 		goto out;
+@@ -443,6 +459,7 @@ static int send_and_recv(struct nl80211_
+ 
+ 	err = 1;
+ 
++	nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
+ 	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
+ 	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
+ 	if (ack_handler_custom) {
+@@ -919,6 +936,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs
+ 			os_free(w);
+ 			return NULL;
+ 		}
++		nl_cb_set(w->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
+ 		nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
+ 			  no_seq_check, NULL);
+ 		nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
+@@ -1333,7 +1351,7 @@ static void wpa_driver_nl80211_event_rtm
  		}
  		wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
  			   namebuf, ifname);
@@ -404,7 +457,7 @@
  			wpa_printf(MSG_DEBUG,
  				   "nl80211: Not the main interface (%s) - do not indicate interface down",
  				   drv->first_bss->ifname);
-@@ -1369,7 +1369,7 @@ static void wpa_driver_nl80211_event_rtm
+@@ -1369,7 +1387,7 @@ static void wpa_driver_nl80211_event_rtm
  		}
  		wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
  			   namebuf, ifname);
@@ -413,7 +466,23 @@
  			wpa_printf(MSG_DEBUG,
  				   "nl80211: Not the main interface (%s) - do not indicate interface up",
  				   drv->first_bss->ifname);
-@@ -8432,6 +8432,7 @@ static void *i802_init(struct hostapd_da
+@@ -1992,6 +2010,7 @@ static int wpa_driver_nl80211_init_nl_gl
+ 		/* Continue without vendor events */
+ 	}
+ 
++	nl_cb_set(global->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
+ 	nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
+ 		  no_seq_check, NULL);
+ 	nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
+@@ -2160,6 +2179,7 @@ static int nl80211_init_bss(struct i802_
+ 	if (!bss->nl_cb)
+ 		return -1;
+ 
++	nl_cb_set(bss->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
+ 	nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
+ 		  no_seq_check, NULL);
+ 	nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
+@@ -8432,6 +8452,7 @@ static void *i802_init(struct hostapd_da
  	char master_ifname[IFNAMSIZ];
  	int ifindex, br_ifindex = 0;
  	int br_added = 0;
@@ -421,7 +490,7 @@
  
  	bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
  					  params->global_priv, 1,
-@@ -8491,21 +8492,17 @@ static void *i802_init(struct hostapd_da
+@@ -8491,21 +8512,17 @@ static void *i802_init(struct hostapd_da
  	    (params->num_bridge == 0 || !params->bridge[0]))
  		add_ifidx(drv, br_ifindex, drv->ifindex);
  
@@ -453,7 +522,7 @@
  	}
  
  	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
-@@ -8875,6 +8872,50 @@ static int wpa_driver_nl80211_if_remove(
+@@ -8875,6 +8892,50 @@ static int wpa_driver_nl80211_if_remove(
  	return 0;
  }
  
@@ -504,7 +573,7 @@
  
  static int cookie_handler(struct nl_msg *msg, void *arg)
  {
-@@ -10513,6 +10554,37 @@ static int driver_nl80211_if_remove(void
+@@ -10513,6 +10574,37 @@ static int driver_nl80211_if_remove(void
  }
  
  
@@ -542,7 +611,7 @@
  static int driver_nl80211_send_mlme(void *priv, const u8 *data,
  				    size_t data_len, int noack,
  				    unsigned int freq,
-@@ -13697,6 +13769,8 @@ const struct wpa_driver_ops wpa_driver_n
+@@ -13697,6 +13789,8 @@ const struct wpa_driver_ops wpa_driver_n
  	.set_acl = wpa_driver_nl80211_set_acl,
  	.if_add = wpa_driver_nl80211_if_add,
  	.if_remove = driver_nl80211_if_remove,
@@ -551,3 +620,52 @@
  	.send_mlme = driver_nl80211_send_mlme,
  	.get_hw_feature_data = nl80211_get_hw_feature_data,
  	.sta_add = wpa_driver_nl80211_sta_add,
+--- a/src/utils/wpa_debug.c
++++ b/src/utils/wpa_debug.c
+@@ -26,6 +26,10 @@ static FILE *wpa_debug_tracing_file = NU
+ #define WPAS_TRACE_PFX "wpas <%d>: "
+ #endif /* CONFIG_DEBUG_LINUX_TRACING */
+ 
++void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
++void (*wpa_hexdump_hook)(int level, const char *title, const void *buf,
++			 size_t len);
++void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
+ 
+ int wpa_debug_level = MSG_INFO;
+ int wpa_debug_show_keys = 0;
+@@ -210,6 +214,12 @@ void _wpa_printf(int level, const char *
+ {
+ 	va_list ap;
+ 
++	if (wpa_printf_hook) {
++		va_start(ap, fmt);
++		wpa_printf_hook(level, fmt, ap);
++		va_end(ap);
++	}
++
+ 	if (level >= wpa_debug_level) {
+ #ifdef CONFIG_ANDROID_LOG
+ 		va_start(ap, fmt);
+@@ -260,6 +270,9 @@ void _wpa_hexdump(int level, const char
+ {
+ 	size_t i;
+ 
++	if (wpa_hexdump_hook)
++		wpa_hexdump_hook(level, title, buf, len);
++
+ #ifdef CONFIG_DEBUG_LINUX_TRACING
+ 	if (wpa_debug_tracing_file != NULL) {
+ 		fprintf(wpa_debug_tracing_file,
+--- a/src/utils/wpa_debug.h
++++ b/src/utils/wpa_debug.h
+@@ -11,6 +11,10 @@
+ 
+ #include "wpabuf.h"
+ 
++extern void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
++extern void (*wpa_hexdump_hook)(int level, const char *title,
++				const void *buf, size_t len);
++extern void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
+ extern int wpa_debug_level;
+ extern int wpa_debug_show_keys;
+ extern int wpa_debug_timestamp;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch
deleted file mode 100644
index 7c00526..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch
+++ /dev/null
@@ -1,437 +0,0 @@
-From 9ae2d23b69518792f81ec574c3d6e9000deb1b5d Mon Sep 17 00:00:00 2001
-From: "howard.hsu" <howard-yh.hsu@mediatek.com>
-Date: Wed, 19 Jan 2022 19:18:07 +0800
-Subject: [PATCH 01/38] hostapd: mtk: Add neighbor report and BSS Termination
- for MBO certification
-
-1. Add hostapd_neighbor_count() and hostapd_neighbor_insert_buffer ()
-The first function can count the number of neighbor report in neighbore report
-database. The second can iterate neighbor report database to build up neighbor
-report data.
-
-2. Support including neighbor report elements in ANQP response
-3. Support including neignbor report elements in BTM response
-4. Support configuring BSS Termination TSF by using hostapd_cli command
-5. Disable interface if BSS Termination TSF is set
-6. Support including neighbor report elements in BTM request
-7. Add hostapd_neighbor_set_own_report_pref()
-8. Add hostapd_neighbor_set_pref_by_non_pref_chan()
-
-Revert set_send_disassoc_frame_timer
----
- hostapd/ctrl_iface.c   |   5 ++
- src/ap/ap_config.c     |   1 +
- src/ap/ap_config.h     |   1 +
- src/ap/ctrl_iface_ap.c |  19 ++++++-
- src/ap/gas_serv.c      |  29 ++++++++++
- src/ap/gas_serv.h      |   2 +
- src/ap/neighbor_db.c   | 119 +++++++++++++++++++++++++++++++++++++++++
- src/ap/neighbor_db.h   |   9 ++++
- src/ap/wnm_ap.c        |  42 ++++++++++++++-
- 9 files changed, 223 insertions(+), 4 deletions(-)
-
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 0a892c9..98d598e 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -1290,6 +1290,11 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
- #endif /* CONFIG_DPP */
- 	} else if (os_strcasecmp(cmd, "setband") == 0) {
- 		ret = hostapd_ctrl_iface_set_band(hapd, value);
-+	} else if (os_strcasecmp(cmd, "bss_termination_tsf") == 0) {
-+		int termination_sec = atoi(value);
-+		hapd->conf->bss_termination_tsf = termination_sec;
-+		wpa_printf(MSG_DEBUG, "BSS Termination TSF: value = %d",
-+                termination_sec);
- 	} else {
- 		ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
- 		if (ret)
-diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 298216a..73b33b4 100644
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -171,6 +171,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
- 	bss->pasn_comeback_after = 10;
- 	bss->pasn_noauth = 1;
- #endif /* CONFIG_PASN */
-+	bss->bss_termination_tsf = 0;
- }
- 
- 
-diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 0790478..82338e2 100644
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -558,6 +558,7 @@ struct hostapd_bss_config {
- 	int wnm_sleep_mode;
- 	int wnm_sleep_mode_no_keys;
- 	int bss_transition;
-+	unsigned int bss_termination_tsf;
- 
- 	/* IEEE 802.11u - Interworking */
- 	int interworking;
-diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
-index 42c9593..0e173f1 100644
---- a/src/ap/ctrl_iface_ap.c
-+++ b/src/ap/ctrl_iface_ap.c
-@@ -1274,6 +1274,10 @@ int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
- 			wpa_printf(MSG_DEBUG, "Invalid bss_term data");
- 			return -1;
- 		}
-+		if (hapd->conf->bss_termination_tsf) {
-+			WPA_PUT_LE64(&bss_term_dur[2], hapd->conf->bss_termination_tsf);
-+		}
-+
- 		end++;
- 		WPA_PUT_LE16(&bss_term_dur[10], atoi(end));
- 	}
-@@ -1300,14 +1304,25 @@ int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
- 		req_mode |= WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT;
- 	}
- 
--	if (os_strstr(cmd, " pref=1"))
-+	if (os_strstr(cmd, " pref=1")) {
- 		req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED;
-+		if (nei_len == 0) {
-+			// Add neigibor report from neighbor report db to nei_rep buffer
-+			nei_len = hostapd_neighbor_insert_buffer (hapd, nei_rep, 1000);
-+		}
-+	}
- 	if (os_strstr(cmd, " abridged=1"))
- 		req_mode |= WNM_BSS_TM_REQ_ABRIDGED;
--	if (os_strstr(cmd, " disassoc_imminent=1"))
-+	if (os_strstr(cmd, " disassoc_imminent=1")) {
- 		req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
-+		/* Set own BSS neighbor report preference value as 0 */
-+		hostapd_neighbor_set_own_report_pref(hapd, nei_rep, nei_len, 0);
-+	}
-+
- 
- #ifdef CONFIG_MBO
-+	hostapd_neighbor_set_pref_by_non_pref_chan(hapd, sta, nei_rep, nei_len);
-+
- 	pos = os_strstr(cmd, "mbo=");
- 	if (pos) {
- 		unsigned int mbo_reason, cell_pref, reassoc_delay;
-diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
-index 4642e49..cce6df4 100644
---- a/src/ap/gas_serv.c
-+++ b/src/ap/gas_serv.c
-@@ -19,6 +19,7 @@
- #include "dpp_hostapd.h"
- #include "sta_info.h"
- #include "gas_serv.h"
-+#include "neighbor_db.h"
- 
- 
- #ifdef CONFIG_DPP
-@@ -369,6 +370,24 @@ static void anqp_add_network_auth_type(struct hostapd_data *hapd,
- 	}
- }
- 
-+static void anqp_add_neighbor_report(struct hostapd_data *hapd,
-+				       struct wpabuf *buf)
-+{
-+	struct hostapd_neighbor_entry *nr;
-+	u8 *len_pos = gas_anqp_add_element(buf, ANQP_NEIGHBOR_REPORT);
-+	if (dl_list_empty(&hapd->nr_db)) {
-+		wpabuf_put_le16(buf, 0);
-+	}
-+	else {
-+		dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list ) {
-+			wpabuf_put_u8(buf, WLAN_EID_NEIGHBOR_REPORT);
-+			wpabuf_put_u8(buf, wpabuf_len(nr->nr));
-+			wpabuf_put_buf(buf, nr->nr);
-+		}
-+	}
-+	gas_anqp_set_element_len(buf, len_pos);
-+}
-+
- 
- static void anqp_add_roaming_consortium(struct hostapd_data *hapd,
- 					struct wpabuf *buf)
-@@ -986,6 +1005,9 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
- 		len += 1000;
- 	if (request & ANQP_REQ_ICON_REQUEST)
- 		len += 65536;
-+    if (request & ANQP_REQ_NEIGHBOR_REPORT) {
-+        len += (40 * hostapd_neighbor_count(hapd));
-+    }
- #ifdef CONFIG_FILS
- 	if (request & ANQP_FILS_REALM_INFO)
- 		len += 2 * dl_list_len(&hapd->conf->fils_realms);
-@@ -1028,6 +1050,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
- 		anqp_add_elem(hapd, buf, ANQP_TDLS_CAPABILITY);
- 	if (request & ANQP_REQ_EMERGENCY_NAI)
- 		anqp_add_elem(hapd, buf, ANQP_EMERGENCY_NAI);
-+	if (request & ANQP_REQ_NEIGHBOR_REPORT)
-+		anqp_add_neighbor_report(hapd, buf);
- 
- 	for (i = 0; i < num_extra_req; i++) {
- #ifdef CONFIG_FILS
-@@ -1172,6 +1196,11 @@ static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id,
- 			     "Emergency NAI",
- 			     get_anqp_elem(hapd, info_id) != NULL, qi);
- 		break;
-+	case ANQP_NEIGHBOR_REPORT:
-+		set_anqp_req(ANQP_REQ_NEIGHBOR_REPORT,
-+			     "Neighbor Report",
-+			     get_anqp_elem(hapd, info_id) != NULL, qi);
-+		break;
- 	default:
- #ifdef CONFIG_FILS
- 		if (info_id == ANQP_FILS_REALM_INFO &&
-diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h
-index 7646a98..ce492b5 100644
---- a/src/ap/gas_serv.h
-+++ b/src/ap/gas_serv.h
-@@ -40,6 +40,8 @@
- 	(1 << (ANQP_TDLS_CAPABILITY - ANQP_QUERY_LIST))
- #define ANQP_REQ_EMERGENCY_NAI \
- 	(1 << (ANQP_EMERGENCY_NAI - ANQP_QUERY_LIST))
-+#define ANQP_REQ_NEIGHBOR_REPORT \
-+	(1 << (ANQP_NEIGHBOR_REPORT - ANQP_QUERY_LIST))
- /*
-  * First 15 Hotspot 2.0 vendor specific ANQP-elements can be included in the
-  * optimized bitmap.
-diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
-index 5b276e8..1c14b32 100644
---- a/src/ap/neighbor_db.c
-+++ b/src/ap/neighbor_db.c
-@@ -89,6 +89,38 @@ int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen)
- }
- 
- 
-+int hostapd_neighbor_count(struct hostapd_data *hapd)
-+{
-+	struct hostapd_neighbor_entry *nr;
-+	int count = 0;
-+
-+	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
-+			 list) {
-+		count++;
-+	}
-+	return count;
-+}
-+
-+
-+int hostapd_neighbor_insert_buffer(struct hostapd_data *hapd, char *buf,
-+        size_t buflen)
-+{
-+	struct hostapd_neighbor_entry *nr;
-+	char *pos = buf;
-+
-+	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
-+			 list) {
-+		/* For neighbor report IE, we only need bssid and nr*/
-+		*pos++ = WLAN_EID_NEIGHBOR_REPORT;
-+		*pos++ = wpabuf_len(nr->nr);
-+		os_memcpy(pos, wpabuf_head(nr->nr), wpabuf_len(nr->nr));
-+		pos += wpabuf_len(nr->nr);
-+	}
-+
-+	return pos - buf;
-+}
-+
-+
- static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
- {
- 	wpabuf_free(nr->nr);
-@@ -325,3 +357,90 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
- 	wpabuf_free(nr);
- #endif /* NEED_AP_MLME */
- }
-+
-+
-+void hostapd_neighbor_set_own_report_pref(struct hostapd_data *hapd, char *nei_buf,
-+			 size_t buflen, const int pref)
-+{
-+	struct hostapd_neighbor_entry *nr;
-+	char *pos, *next_nr;
-+
-+	pos = nei_buf;
-+	next_nr = nei_buf;
-+
-+	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
-+			 list) {
-+		pos = next_nr;
-+		next_nr = pos + 2 + wpabuf_len(nr->nr);
-+		/* Shift 2 bytes for Element ID and Neighbor report length */
-+		pos = pos + 2;
-+		if(os_memcmp(pos, hapd->own_addr, ETH_ALEN) == 0) {
-+			/* Shift for BSSID + BSSID info + Op_class + channel num + PHY type */
-+			pos = pos + 6 + 4 + 1 + 1 + 1;
-+
-+			/* Iterate Subelement */
-+			while (next_nr - pos > 0) {
-+				if (*pos == 3) {
-+					pos = pos + 2;
-+					*pos = pref;
-+					return;
-+				} else {
-+					pos++;
-+					int shift_len = *pos++;
-+					pos = pos + shift_len;
-+				}
-+			}
-+		}
-+	}
-+}
-+
-+#ifdef CONFIG_MBO
-+void hostapd_neighbor_set_pref_by_non_pref_chan(struct hostapd_data *hapd,
-+			 struct sta_info* sta, char *nei_buf, size_t buflen)
-+{
-+	struct hostapd_neighbor_entry *nr;
-+	struct mbo_non_pref_chan_info *info;
-+	u8 i;
-+
-+	for(info = sta->non_pref_chan; info; info = info->next) {
-+		/* Check OP_Class and Channel num */
-+		for(i = 0; i < info->num_channels; i++) {
-+			char *pos, *next_nr;
-+
-+			pos = nei_buf;
-+			next_nr = nei_buf;
-+
-+			/* Iterate Neighbor report database */
-+			dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
-+					 list) {
-+				pos = next_nr;
-+				next_nr = pos + 2 + wpabuf_len(nr->nr);
-+				/**
-+				 * Shift 12 bytes for Element ID, Neighbor report length,
-+				 * BSSID and BSSID info.
-+				 */
-+				pos = pos + 12;
-+				int nr_op_class = *pos++;
-+				int nr_channel = *pos;
-+				if(info->op_class == nr_op_class && info->channels[i] == nr_channel) {
-+					/* Shift for Channel Num + PHY type */
-+					pos = pos + 1 + 1;
-+
-+					// Iterate Subelement
-+					while(next_nr - pos > 0) {
-+						if(*pos == 3) {
-+							pos = pos + 2;
-+							*pos = info->pref;
-+							break;
-+						}else {
-+							pos++;
-+							int shift_len = *pos++;
-+							pos = pos + shift_len;
-+						}
-+					}
-+				}
-+			}
-+		}
-+	}
-+}
-+#endif
-diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
-index 992671b..a1ddc07 100644
---- a/src/ap/neighbor_db.h
-+++ b/src/ap/neighbor_db.h
-@@ -24,4 +24,13 @@ int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
- 			    const struct wpa_ssid_value *ssid);
- void hostapd_free_neighbor_db(struct hostapd_data *hapd);
- 
-+int hostapd_neighbor_count(struct hostapd_data *hapd);
-+int hostapd_neighbor_insert_buffer(struct hostapd_data *hapd, char *buf,
-+        size_t buflen);
-+void hostapd_neighbor_set_own_report_pref(struct hostapd_data *hapd, char *nei_buf,
-+			 size_t buflen, const int pref);
-+#ifdef CONFIG_MBO
-+void hostapd_neighbor_set_pref_by_non_pref_chan(struct hostapd_data *hapd,
-+			 struct sta_info* sta, char *nei_buf, size_t buflen);
-+#endif
- #endif /* NEIGHBOR_DB_H */
-diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
-index ba1dd2e..939d447 100644
---- a/src/ap/wnm_ap.c
-+++ b/src/ap/wnm_ap.c
-@@ -20,6 +20,7 @@
- #include "ap/wpa_auth.h"
- #include "mbo_ap.h"
- #include "wnm_ap.h"
-+#include "ap/neighbor_db.h"
- 
- #define MAX_TFS_IE_LEN  1024
- 
-@@ -370,9 +371,21 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
- 	u8 *pos;
- 	int res;
- 
--	mgmt = os_zalloc(sizeof(*mgmt));
--	if (mgmt == NULL)
-+	int nr_num = hostapd_neighbor_count(hapd);
-+	int nr_size = ETH_ALEN + 4 + 1 + 1 + 1 + 5;
-+	int total_nr_size = nr_num * nr_size;
-+	u8 *nr_data = os_malloc(total_nr_size);
-+	int nr_data_len = 0;
-+	if(nr_data == NULL) {
-+		wpa_printf (MSG_ERROR, "Failed to allocate memory");
-+	} else {
-+	    nr_data_len = hostapd_neighbor_insert_buffer(hapd, nr_data, total_nr_size);
-+	}
-+	mgmt = os_zalloc(sizeof(*mgmt) + nr_data_len);
-+	if (mgmt == NULL) {
-+		wpa_printf (MSG_ERROR, "Failed to allocate memory for mgmt frame");
- 		return -1;
-+	}
- 	os_memcpy(mgmt->da, addr, ETH_ALEN);
- 	os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
- 	os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
-@@ -382,10 +395,18 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
- 	mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
- 	mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
- 	mgmt->u.action.u.bss_tm_req.req_mode = 0;
-+	if(nr_num) {
-+		mgmt->u.action.u.bss_tm_req.req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED;
-+	}
- 	mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
- 	mgmt->u.action.u.bss_tm_req.validity_interval = 1;
- 	pos = mgmt->u.action.u.bss_tm_req.variable;
- 
-+	if(nr_num) {
-+		os_memcpy(pos, nr_data, nr_data_len);
-+		pos += nr_data_len;
-+	}
-+
- 	hapd->openwrt_stats.wnm.bss_transition_request_tx++;
- 	wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
- 		   MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
-@@ -890,6 +911,22 @@ static void set_disassoc_timer(struct hostapd_data *hapd, struct sta_info *sta,
- }
- 
- 
-+void bss_termination_disable_iface(void *eloop_ctx, void *timeout_ctx)
-+{
-+	struct hostapd_data *hapd = eloop_ctx;
-+	hostapd_disable_iface(hapd->iface);
-+}
-+
-+
-+static void set_disable_iface_timer(struct hostapd_data *hapd, struct sta_info *sta,
-+			       int disable_iface_timer)
-+{
-+	wpa_printf(MSG_DEBUG, "Disable interface timer set to %d secs", disable_iface_timer);
-+	eloop_register_timeout(disable_iface_timer, 0,
-+			       bss_termination_disable_iface, hapd, NULL);
-+}
-+
-+
- int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
- 				   struct sta_info *sta, const char *url,
- 				   int disassoc_timer)
-@@ -979,6 +1016,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
- 	    bss_term_dur) {
- 		os_memcpy(pos, bss_term_dur, 12);
- 		pos += 12;
-+		set_disable_iface_timer(hapd, sta, hapd->conf->bss_termination_tsf);
- 	}
- 
- 	if (url) {
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0001-mtk-hostapd-Add-neighbor-report-and-BSS-Termination-.patch
similarity index 96%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0001-mtk-hostapd-Add-neighbor-report-and-BSS-Termination-.patch
index 7c00526..25892c8 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0001-mtk-hostapd-Add-neighbor-report-and-BSS-Termination-.patch
@@ -1,7 +1,7 @@
-From 9ae2d23b69518792f81ec574c3d6e9000deb1b5d Mon Sep 17 00:00:00 2001
+From 154b32c66ff22838dc619d85332eadae16cb0353 Mon Sep 17 00:00:00 2001
 From: "howard.hsu" <howard-yh.hsu@mediatek.com>
 Date: Wed, 19 Jan 2022 19:18:07 +0800
-Subject: [PATCH 01/38] hostapd: mtk: Add neighbor report and BSS Termination
+Subject: [PATCH 01/54] mtk: hostapd: Add neighbor report and BSS Termination
  for MBO certification
 
 1. Add hostapd_neighbor_count() and hostapd_neighbor_insert_buffer ()
@@ -31,7 +31,7 @@
  9 files changed, 223 insertions(+), 4 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 0a892c9..98d598e 100644
+index 0a892c915..98d598ea9 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -1290,6 +1290,11 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
@@ -47,7 +47,7 @@
  		ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
  		if (ret)
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 298216a..73b33b4 100644
+index 298216a47..73b33b42a 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -171,6 +171,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
@@ -59,7 +59,7 @@
  
  
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 0790478..82338e2 100644
+index 0790478ee..82338e213 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -558,6 +558,7 @@ struct hostapd_bss_config {
@@ -71,7 +71,7 @@
  	/* IEEE 802.11u - Interworking */
  	int interworking;
 diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
-index 42c9593..0e173f1 100644
+index 42c959387..0e173f174 100644
 --- a/src/ap/ctrl_iface_ap.c
 +++ b/src/ap/ctrl_iface_ap.c
 @@ -1274,6 +1274,10 @@ int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
@@ -114,7 +114,7 @@
  	if (pos) {
  		unsigned int mbo_reason, cell_pref, reassoc_delay;
 diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
-index 4642e49..cce6df4 100644
+index 4642e4927..cce6df41c 100644
 --- a/src/ap/gas_serv.c
 +++ b/src/ap/gas_serv.c
 @@ -19,6 +19,7 @@
@@ -182,7 +182,7 @@
  #ifdef CONFIG_FILS
  		if (info_id == ANQP_FILS_REALM_INFO &&
 diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h
-index 7646a98..ce492b5 100644
+index 7646a98a4..ce492b53f 100644
 --- a/src/ap/gas_serv.h
 +++ b/src/ap/gas_serv.h
 @@ -40,6 +40,8 @@
@@ -195,7 +195,7 @@
   * First 15 Hotspot 2.0 vendor specific ANQP-elements can be included in the
   * optimized bitmap.
 diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
-index 5b276e8..1c14b32 100644
+index 5b276e8da..1c14b3201 100644
 --- a/src/ap/neighbor_db.c
 +++ b/src/ap/neighbor_db.c
 @@ -89,6 +89,38 @@ int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen)
@@ -329,7 +329,7 @@
 +}
 +#endif
 diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
-index 992671b..a1ddc07 100644
+index 992671b62..a1ddc075b 100644
 --- a/src/ap/neighbor_db.h
 +++ b/src/ap/neighbor_db.h
 @@ -24,4 +24,13 @@ int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
@@ -347,7 +347,7 @@
 +#endif
  #endif /* NEIGHBOR_DB_H */
 diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
-index ba1dd2e..939d447 100644
+index ba1dd2ed1..939d4471b 100644
 --- a/src/ap/wnm_ap.c
 +++ b/src/ap/wnm_ap.c
 @@ -20,6 +20,7 @@
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch
deleted file mode 100644
index d9b0cba..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From b76669952a1971105f1de99b69e9711ab71e9c63 Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 20 Sep 2022 19:33:45 +0800
-Subject: [PATCH 02/38] hostapd: mtk: print sae groups by hostapd ctrl
-
----
- hostapd/ctrl_iface.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 98d598e..c03e6f6 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -1364,6 +1364,19 @@ static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd,
- 		if (os_snprintf_error(buflen, res))
- 			return -1;
- 		return res;
-+	} else if (os_strcmp(cmd, "sae_group_capability") == 0) {
-+#ifdef CONFIG_SAE
-+		/* see sae_set_group() */
-+		res = os_snprintf(buf, buflen, "%s%s%s%s19 20 21",
-+				  dh_groups_get(15) ? "15 ": "",
-+				  dh_groups_get(16) ? "16 ": "",
-+				  dh_groups_get(17) ? "17 ": "",
-+				  dh_groups_get(18) ? "18 ": "");
-+
-+		if (os_snprintf_error(buflen, res))
-+			return -1;
-+		return res;
-+#endif /* CONFIG_SAE */
- 	}
- 
- 	return -1;
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0002-mtk-hostapd-print-sae-groups-by-hostapd-ctrl.patch
similarity index 84%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0002-mtk-hostapd-print-sae-groups-by-hostapd-ctrl.patch
index d9b0cba..976c625 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0002-mtk-hostapd-print-sae-groups-by-hostapd-ctrl.patch
@@ -1,14 +1,14 @@
-From b76669952a1971105f1de99b69e9711ab71e9c63 Mon Sep 17 00:00:00 2001
+From 135e2f4368bba88d8823da63a134fdcc587fe698 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 20 Sep 2022 19:33:45 +0800
-Subject: [PATCH 02/38] hostapd: mtk: print sae groups by hostapd ctrl
+Subject: [PATCH 02/54] mtk: hostapd: print sae groups by hostapd ctrl
 
 ---
  hostapd/ctrl_iface.c | 13 +++++++++++++
  1 file changed, 13 insertions(+)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 98d598e..c03e6f6 100644
+index 98d598ea9..c03e6f608 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -1364,6 +1364,19 @@ static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch
deleted file mode 100644
index 85ffb3b..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From 9aaf05a3b4ec0cf420a20cbb5b2dc65b66eacb49 Mon Sep 17 00:00:00 2001
-From: MeiChia Chiu <meichia.chiu@mediatek.com>
-Date: Tue, 31 May 2022 21:15:54 +0800
-Subject: [PATCH 03/38] hostapd: mtk: add support for runtime set in-band
- discovery
-
-Usage:
-hostapd_cli unsolic_probe_resp [tx_type] [interval]
-
-0: disable all in-band discovery
-1: enable unsolicited probe response
-2: enable FILS discovery
-
-Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
----
- hostapd/ctrl_iface.c         | 66 ++++++++++++++++++++++++++++++++++++
- hostapd/hostapd_cli.c        | 20 +++++++++++
- src/ap/beacon.c              |  5 ++-
- src/drivers/driver_nl80211.c | 10 ++++--
- src/drivers/nl80211_copy.h   |  1 +
- 5 files changed, 98 insertions(+), 4 deletions(-)
-
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c03e6f6..ee6d492 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -770,6 +770,69 @@ static int hostapd_ctrl_iface_send_qos_map_conf(struct hostapd_data *hapd,
- 
- #endif /* CONFIG_INTERWORKING */
- 
-+static int hostapd_ctrl_iface_inband_discovery(struct hostapd_data *hapd,
-+					       const char *cmd)
-+{
-+	struct hostapd_bss_config *conf = hapd->conf;
-+	const char *pos = cmd;
-+	int tx_type, interval, ret;
-+
-+	tx_type = atoi(pos);
-+	if (tx_type < 0 || tx_type > 2) {
-+		wpa_printf(MSG_ERROR, "Invalid tx type\n");
-+		return -1;
-+	}
-+
-+	pos = os_strchr(pos, ' ');
-+	if(!pos)
-+		return -1;
-+	pos++;
-+	interval = atoi(pos);
-+	if (interval < 0 || interval > 20) {
-+		wpa_printf(MSG_ERROR, "Invalid interval value\n");
-+		return -1;
-+	}
-+
-+	wpa_printf(MSG_ERROR, "Set inband discovery type:%d, interval:%d\n",
-+			      tx_type, interval);
-+
-+#define DISABLE_INBAND_DISC 0
-+#define UNSOL_PROBE_RESP 1
-+#define FILS_DISCOVERY 2
-+
-+#ifdef CONFIG_FILS
-+	conf->fils_discovery_max_int = 0;
-+	conf->fils_discovery_min_int = 0;
-+#endif /* CONFIG_FILS */
-+	conf->unsol_bcast_probe_resp_interval = 0;
-+
-+	switch (tx_type) {
-+	case DISABLE_INBAND_DISC:
-+	default:
-+		/* Disable both Unsolicited probe response and FILS discovery*/
-+		break;
-+	case UNSOL_PROBE_RESP:
-+		/* Enable Unsolicited probe response */
-+		conf->unsol_bcast_probe_resp_interval = interval;
-+		break;
-+#ifdef CONFIG_FILS
-+	case FILS_DISCOVERY:
-+		/* Enable FILS discovery */
-+		conf->fils_discovery_min_int = interval;
-+		conf->fils_discovery_max_int = interval;
-+		break;
-+#endif /* CONFIG_FILS */
-+	}
-+
-+	ret = ieee802_11_update_beacons(hapd->iface);
-+	if(ret) {
-+		wpa_printf(MSG_DEBUG,
-+			"Failed to update with inband discovery parameters\n");
-+		return -1;
-+	}
-+
-+	return 0;
-+}
- 
- #ifdef CONFIG_WNM_AP
- 
-@@ -3483,6 +3546,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 		if (hostapd_ctrl_iface_coloc_intf_req(hapd, buf + 15))
- 			reply_len = -1;
- #endif /* CONFIG_WNM_AP */
-+	} else if (os_strncmp(buf, "INBAND_DISCOVERY ", 17) == 0) {
-+		if (hostapd_ctrl_iface_inband_discovery(hapd, buf + 17))
-+			reply_len = -1;
- 	} else if (os_strcmp(buf, "GET_CONFIG") == 0) {
- 		reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
- 							  reply_size);
-diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 61f8cba..dfc996d 100644
---- a/hostapd/hostapd_cli.c
-+++ b/hostapd/hostapd_cli.c
-@@ -655,6 +655,24 @@ static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
- 	return wpa_ctrl_command(ctrl, buf);
- }
- 
-+static int hostapd_cli_cmd_inband_discovery(struct wpa_ctrl *ctrl, int argc,
-+					    char *argv[])
-+{
-+	char buf[300];
-+	int res;
-+
-+	if (argc < 2) {
-+		printf("Invalid 'inband_discovery' command - two arguments"
-+		       "tx_type interval\n");
-+		return -1;
-+	}
-+
-+	res = os_snprintf(buf, sizeof(buf), "INBAND_DISCOVERY %s %s",
-+			  argv[0], argv[1]);
-+	if (os_snprintf_error(sizeof(buf), res))
-+		return -1;
-+	return wpa_ctrl_command(ctrl, buf);
-+}
- 
- static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc,
- 					     char *argv[])
-@@ -1773,6 +1791,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
- 	{ "driver", hostapd_cli_cmd_driver, NULL,
- 	  "<driver sub command> [<hex formatted data>] = send driver command data" },
- #endif /* ANDROID */
-+	{ "inband_discovery", hostapd_cli_cmd_inband_discovery, NULL,
-+          "<tx type(0/1/2)> <interval> = runtime set inband discovery" },
- 	{ NULL, NULL, NULL, NULL }
- };
- 
-diff --git a/src/ap/beacon.c b/src/ap/beacon.c
-index 6366d77..d160675 100644
---- a/src/ap/beacon.c
-+++ b/src/ap/beacon.c
-@@ -1648,6 +1648,8 @@ static u8 * hostapd_fils_discovery(struct hostapd_data *hapd,
- 				   struct wpa_driver_ap_params *params)
- {
- 	params->fd_max_int = hapd->conf->fils_discovery_max_int;
-+	params->unsol_bcast_probe_resp_interval =
-+		hapd->conf->unsol_bcast_probe_resp_interval;
- 	if (is_6ghz_op_class(hapd->iconf->op_class) &&
- 	    params->fd_max_int > FD_MAX_INTERVAL_6GHZ)
- 		params->fd_max_int = FD_MAX_INTERVAL_6GHZ;
-@@ -1656,7 +1658,8 @@ static u8 * hostapd_fils_discovery(struct hostapd_data *hapd,
- 	if (params->fd_min_int > params->fd_max_int)
- 		params->fd_min_int = params->fd_max_int;
- 
--	if (params->fd_max_int)
-+	if (params->fd_max_int || (is_6ghz_op_class(hapd->iconf->op_class) &&
-+	    !params->unsol_bcast_probe_resp_interval))
- 		return hostapd_gen_fils_discovery(hapd,
- 						  &params->fd_frame_tmpl_len);
- 
-diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index f6c5df9..c7745b6 100644
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -4686,9 +4686,10 @@ static int nl80211_fils_discovery(struct i802_bss *bss, struct nl_msg *msg,
- 			params->fd_max_int) ||
- 	    (params->fd_frame_tmpl &&
- 	     nla_put(msg, NL80211_FILS_DISCOVERY_ATTR_TMPL,
--		     params->fd_frame_tmpl_len, params->fd_frame_tmpl)))
-+		     params->fd_frame_tmpl_len, params->fd_frame_tmpl)) ||
-+	    nla_put_u32(msg, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INTE,
-+			params->unsol_bcast_probe_resp_interval))
- 		return -1;
--
- 	nla_nest_end(msg, attr);
- 	return 0;
- }
-@@ -5300,7 +5301,10 @@ static int wpa_driver_nl80211_set_ap(void *priv,
- #endif /* CONFIG_SAE */
- 
- #ifdef CONFIG_FILS
--	if (params->fd_max_int && nl80211_fils_discovery(bss, msg, params) < 0)
-+	if ((params->fd_max_int ||
-+	    ((params->freq->freq > 5950 && params->freq->freq <= 7115) &&
-+	      !(params->unsol_bcast_probe_resp_interval))) &&
-+	     nl80211_fils_discovery(bss, msg, params) < 0)
- 		goto fail;
- #endif /* CONFIG_FILS */
- 
-diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index c59fec4..82860ae 100644
---- a/src/drivers/nl80211_copy.h
-+++ b/src/drivers/nl80211_copy.h
-@@ -7591,6 +7591,7 @@ enum nl80211_fils_discovery_attributes {
- 	NL80211_FILS_DISCOVERY_ATTR_INT_MIN,
- 	NL80211_FILS_DISCOVERY_ATTR_INT_MAX,
- 	NL80211_FILS_DISCOVERY_ATTR_TMPL,
-+	NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INTE,
- 
- 	/* keep last */
- 	__NL80211_FILS_DISCOVERY_ATTR_LAST,
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0003-mtk-hostapd-add-support-for-runtime-set-in-band-disc.patch
similarity index 93%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0003-mtk-hostapd-add-support-for-runtime-set-in-band-disc.patch
index 85ffb3b..29b4c03 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0003-mtk-hostapd-add-support-for-runtime-set-in-band-disc.patch
@@ -1,7 +1,7 @@
-From 9aaf05a3b4ec0cf420a20cbb5b2dc65b66eacb49 Mon Sep 17 00:00:00 2001
+From 55220dcc0fcd43270edf583720e0b36e453dc2d7 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 31 May 2022 21:15:54 +0800
-Subject: [PATCH 03/38] hostapd: mtk: add support for runtime set in-band
+Subject: [PATCH 03/54] mtk: hostapd: add support for runtime set in-band
  discovery
 
 Usage:
@@ -21,7 +21,7 @@
  5 files changed, 98 insertions(+), 4 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c03e6f6..ee6d492 100644
+index c03e6f608..ee6d492f8 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -770,6 +770,69 @@ static int hostapd_ctrl_iface_send_qos_map_conf(struct hostapd_data *hapd,
@@ -105,7 +105,7 @@
  		reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
  							  reply_size);
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 61f8cba..dfc996d 100644
+index 61f8cba12..dfc996d49 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -655,6 +655,24 @@ static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
@@ -143,7 +143,7 @@
  };
  
 diff --git a/src/ap/beacon.c b/src/ap/beacon.c
-index 6366d77..d160675 100644
+index 6366d77f0..d160675cb 100644
 --- a/src/ap/beacon.c
 +++ b/src/ap/beacon.c
 @@ -1648,6 +1648,8 @@ static u8 * hostapd_fils_discovery(struct hostapd_data *hapd,
@@ -166,10 +166,10 @@
  						  &params->fd_frame_tmpl_len);
  
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index f6c5df9..c7745b6 100644
+index 98510f1cf..a3e436e95 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -4686,9 +4686,10 @@ static int nl80211_fils_discovery(struct i802_bss *bss, struct nl_msg *msg,
+@@ -4706,9 +4706,10 @@ static int nl80211_fils_discovery(struct i802_bss *bss, struct nl_msg *msg,
  			params->fd_max_int) ||
  	    (params->fd_frame_tmpl &&
  	     nla_put(msg, NL80211_FILS_DISCOVERY_ATTR_TMPL,
@@ -182,7 +182,7 @@
  	nla_nest_end(msg, attr);
  	return 0;
  }
-@@ -5300,7 +5301,10 @@ static int wpa_driver_nl80211_set_ap(void *priv,
+@@ -5320,7 +5321,10 @@ static int wpa_driver_nl80211_set_ap(void *priv,
  #endif /* CONFIG_SAE */
  
  #ifdef CONFIG_FILS
@@ -195,7 +195,7 @@
  #endif /* CONFIG_FILS */
  
 diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index c59fec4..82860ae 100644
+index c59fec406..82860ae32 100644
 --- a/src/drivers/nl80211_copy.h
 +++ b/src/drivers/nl80211_copy.h
 @@ -7591,6 +7591,7 @@ enum nl80211_fils_discovery_attributes {
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0004-hostapd-mtk-Add-mtk_vendor.h.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0004-mtk-hostapd-Add-mtk_vendor.h.patch
similarity index 97%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0004-hostapd-mtk-Add-mtk_vendor.h.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0004-mtk-hostapd-Add-mtk_vendor.h.patch
index 13a7d1d..16949b7 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0004-hostapd-mtk-Add-mtk_vendor.h.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0004-mtk-hostapd-Add-mtk_vendor.h.patch
@@ -1,7 +1,7 @@
-From 86553b9434ad98e4ec3dd19fbc5589ca24501f4d Mon Sep 17 00:00:00 2001
+From 2bba6f165367d21c44cb4da8b74904ecee956d55 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Mon, 30 May 2022 15:04:57 +0800
-Subject: [PATCH 04/38] hostapd: mtk: Add mtk_vendor.h
+Subject: [PATCH 04/54] mtk: hostapd: Add mtk_vendor.h
 
 ---
  src/common/mtk_vendor.h | 197 ++++++++++++++++++++++++++++++++++++++++
@@ -10,7 +10,7 @@
 
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
 new file mode 100644
-index 0000000..4a19d2f
+index 000000000..4a19d2fc9
 --- /dev/null
 +++ b/src/common/mtk_vendor.h
 @@ -0,0 +1,197 @@
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0005-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0005-mtk-hostapd-Support-EDCCA-hostapd-configuration.patch
similarity index 96%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0005-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0005-mtk-hostapd-Support-EDCCA-hostapd-configuration.patch
index 868adca..37f5172 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0005-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0005-mtk-hostapd-Support-EDCCA-hostapd-configuration.patch
@@ -1,7 +1,7 @@
-From 906a70c7df5918c40c9552e078690ab7305ed40e Mon Sep 17 00:00:00 2001
+From 7e1b6b0dc2167af5b9d58466ce693b67e6b5dbf2 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Mon, 30 May 2022 16:31:34 +0800
-Subject: [PATCH 05/38] hostapd: mtk: Support EDCCA hostapd configuration
+Subject: [PATCH 05/54] mtk: hostapd: Support EDCCA hostapd configuration
 
 edcca_enable and edcca_compensation and implement edcca related handlers.
 ---
@@ -20,7 +20,7 @@
  12 files changed, 428 insertions(+), 6 deletions(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 4b0f99f..d281026 100644
+index 4b0f99fd2..d281026e8 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4809,6 +4809,40 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -65,7 +65,7 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index ee6d492..cad3f86 100644
+index ee6d492f8..cad3f863c 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -542,6 +542,19 @@ static const char * pbc_status_str(enum pbc_status status)
@@ -215,7 +215,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 73b33b4..8e56d10 100644
+index 73b33b42a..8e56d1082 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -295,6 +295,9 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -237,7 +237,7 @@
  	wpabuf_free(conf->civic);
  
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 82338e2..24d540d 100644
+index 82338e213..24d540dbf 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1193,8 +1193,38 @@ struct hostapd_config {
@@ -280,7 +280,7 @@
  static inline enum oper_chan_width
  hostapd_get_oper_chwidth(struct hostapd_config *conf)
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 75ddfa1..99ba973 100644
+index 75ddfa15c..99ba973aa 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1137,3 +1137,27 @@ int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
@@ -312,7 +312,7 @@
 +	return hapd->driver->get_edcca(hapd->drv_priv, mode, value);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 96c8c4e..6ca693b 100644
+index 96c8c4e2c..6ca693b0b 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -144,6 +144,10 @@ int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
@@ -327,7 +327,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 6746de2..1b9ce6f 100644
+index a203546b6..f7c80c73b 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2511,6 +2511,13 @@ dfs_offload:
@@ -345,7 +345,7 @@
  		   iface->bss[0]->conf->iface);
  	if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 4a19d2f..6121857 100644
+index 4a19d2fc9..6121857dd 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -30,14 +30,22 @@ enum mtk_vendor_attr_edcca_ctrl {
@@ -378,10 +378,10 @@
  	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
  	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index cc49011..fca2035 100644
+index c5cc26737..7d71aa783 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5102,6 +5102,10 @@ struct wpa_driver_ops {
+@@ -5105,6 +5105,10 @@ struct wpa_driver_ops {
  			      const u8 *match, size_t match_len,
  			      bool multicast);
  #endif /* CONFIG_TESTING_OPTIONS */
@@ -393,7 +393,7 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index c7745b6..0a159d5 100644
+index a3e436e95..1a2f52b77 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
 @@ -37,6 +37,8 @@
@@ -405,7 +405,7 @@
  
  
  #ifndef NETLINK_CAP_ACK
-@@ -13748,6 +13750,174 @@ static int testing_nl80211_radio_disable(void *priv, int disabled)
+@@ -13768,6 +13770,174 @@ static int testing_nl80211_radio_disable(void *priv, int disabled)
  
  #endif /* CONFIG_TESTING_OPTIONS */
  
@@ -580,7 +580,7 @@
  
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
-@@ -13904,4 +14074,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -13924,4 +14094,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.register_frame = testing_nl80211_register_frame,
  	.radio_disable = testing_nl80211_radio_disable,
  #endif /* CONFIG_TESTING_OPTIONS */
@@ -590,7 +590,7 @@
 +	.get_edcca = nl80211_get_edcca,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index aee8c45..51b3fbe 100644
+index aee8c4512..51b3fbec8 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -202,6 +202,7 @@ struct wpa_driver_nl80211_data {
@@ -602,7 +602,7 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 5e64068..5dadf24 100644
+index f01a526a0..47654f65b 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
 @@ -18,6 +18,7 @@
@@ -613,7 +613,7 @@
  
  
  static int protocol_feature_handler(struct nl_msg *msg, void *arg)
-@@ -1107,6 +1108,12 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1111,6 +1112,12 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  					break;
  				}
  #endif /* CONFIG_DRIVER_NL80211_BRCM */
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
deleted file mode 100644
index 43f214c..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
+++ /dev/null
@@ -1,450 +0,0 @@
-From f868636d86170f6ebe9dba785f22195b06177af1 Mon Sep 17 00:00:00 2001
-From: TomLiu <tomml.liu@mediatek.com>
-Date: Tue, 9 Aug 2022 10:23:44 -0700
-Subject: [PATCH 06/38] hostapd: mtk: Add hostapd MU SET/GET control
-
----
- hostapd/config_file.c             |   9 +++
- hostapd/ctrl_iface.c              |  62 +++++++++++++++++
- hostapd/hostapd_cli.c             |  18 +++++
- src/ap/ap_config.c                |   1 +
- src/ap/ap_config.h                |   1 +
- src/ap/ap_drv_ops.c               |  14 ++++
- src/ap/ap_drv_ops.h               |   2 +
- src/ap/hostapd.c                  |   2 +
- src/common/mtk_vendor.h           |  15 ++++
- src/drivers/driver.h              |  13 ++++
- src/drivers/driver_nl80211.c      | 110 ++++++++++++++++++++++++++++++
- src/drivers/driver_nl80211.h      |   1 +
- src/drivers/driver_nl80211_capa.c |   3 +
- 13 files changed, 251 insertions(+)
-
-diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index d281026..ec3b41a 100644
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -3677,6 +3677,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 			return 1;
- 		}
- 		conf->mbssid = mbssid;
-+	} else if (os_strcmp(buf, "mu_onoff") == 0) {
-+		int val = atoi(pos);
-+		if (val < 0 || val > 15) {
-+			wpa_printf(MSG_ERROR,
-+				   "Line %d: invalid mu_onoff value",
-+				   line);
-+			return 1;
-+		}
-+		conf->mu_onoff = val;
- #endif /* CONFIG_IEEE80211AX */
- 	} else if (os_strcmp(buf, "max_listen_interval") == 0) {
- 		bss->max_listen_interval = atoi(pos);
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index cad3f86..c5d92b0 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -3488,6 +3488,63 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
- }
- 
- 
-+static int
-+hostapd_ctrl_iface_set_mu(struct hostapd_data *hapd, char *cmd,
-+					 char *buf, size_t buflen)
-+{
-+	char *pos, *config, *value;
-+	config = cmd;
-+	pos = os_strchr(config, ' ');
-+	if (pos == NULL)
-+		return -1;
-+	*pos++ = '\0';
-+
-+	if(pos == NULL)
-+		return -1;
-+	value = pos;
-+
-+	if (os_strcmp(config, "onoff") == 0) {
-+		int mu = atoi(value);
-+		if (mu < 0 || mu > 15) {
-+			wpa_printf(MSG_ERROR, "Invalid value for mu");
-+			return -1;
-+		}
-+		hapd->iconf->mu_onoff = (u8) mu;
-+	} else {
-+		wpa_printf(MSG_ERROR,
-+			"Unsupported parameter %s for SET_MU", config);
-+		return -1;
-+	}
-+
-+	if(hostapd_drv_mu_ctrl(hapd) == 0) {
-+		return os_snprintf(buf, buflen, "OK\n");
-+	} else {
-+		return -1;
-+	}
-+}
-+
-+
-+static int
-+hostapd_ctrl_iface_get_mu(struct hostapd_data *hapd, char *buf,
-+					 size_t buflen)
-+{
-+	u8 mu_onoff;
-+	char *pos, *end;
-+
-+	pos = buf;
-+	end = buf + buflen;
-+
-+	if (hostapd_drv_mu_dump(hapd, &mu_onoff) == 0) {
-+		hapd->iconf->mu_onoff = mu_onoff;
-+		return os_snprintf(pos, end - pos, "[hostapd_cli] = UL MU-MIMO: %d, DL MU-MIMO: %d, UL OFDMA: %d, DL OFDMA: %d\n",
-+			!!(mu_onoff&BIT(3)), !!(mu_onoff&BIT(2)), !!(mu_onoff&BIT(1)), !!(mu_onoff&BIT(0)));
-+	} else {
-+		wpa_printf(MSG_INFO, "ctrl iface failed to call");
-+		return -1;
-+	}
-+}
-+
-+
- static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 					      char *buf, char *reply,
- 					      int reply_size,
-@@ -4047,6 +4104,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 	} else if (os_strncmp(buf, "GET_EDCCA ", 10) == 0) {
- 		reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
- 							  reply_size);
-+	} else if (os_strncmp(buf, "SET_MU ", 7) == 0) {
-+		reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 7, reply,
-+							  reply_size);
-+	} else if (os_strncmp(buf, "GET_MU", 6) == 0) {
-+		reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
- 	} else {
- 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
- 		reply_len = 16;
-diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index dfc996d..98892ee 100644
---- a/hostapd/hostapd_cli.c
-+++ b/hostapd/hostapd_cli.c
-@@ -1400,6 +1400,20 @@ static int hostapd_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
- }
- 
- 
-+static int hostapd_cli_cmd_set_mu(struct wpa_ctrl *ctrl, int argc,
-+					   char *argv[])
-+{
-+	return hostapd_cli_cmd(ctrl, "SET_MU", 1, argc, argv);
-+}
-+
-+
-+static int hostapd_cli_cmd_get_mu(struct wpa_ctrl *ctrl, int argc,
-+					   char *argv[])
-+{
-+	return hostapd_cli_cmd(ctrl, "GET_MU", 0, NULL, NULL);
-+}
-+
-+
- #ifdef CONFIG_DPP
- 
- static int hostapd_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc,
-@@ -1729,6 +1743,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
- 	  " = send FTM range request"},
- 	{ "driver_flags", hostapd_cli_cmd_driver_flags, NULL,
- 	  " = show supported driver flags"},
-+	{ "set_mu", hostapd_cli_cmd_set_mu, NULL,
-+		"<value> [0-15] bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0)"},
-+	{ "get_mu", hostapd_cli_cmd_get_mu, NULL,
-+		" = show mu onoff value in 0-15 bitmap"},
- #ifdef CONFIG_DPP
- 	{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
- 	  "report a scanned DPP URI from a QR Code" },
-diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 8e56d10..cf7f563 100644
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -281,6 +281,7 @@ struct hostapd_config * hostapd_config_defaults(void)
- 	conf->he_6ghz_max_ampdu_len_exp = 7;
- 	conf->he_6ghz_rx_ant_pat = 1;
- 	conf->he_6ghz_tx_ant_pat = 1;
-+	conf->mu_onoff = 15;
- #endif /* CONFIG_IEEE80211AX */
- 
- 	/* The third octet of the country string uses an ASCII space character
-diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 24d540d..421e6a6 100644
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -1146,6 +1146,7 @@ struct hostapd_config {
- 	u8 he_6ghz_tx_ant_pat;
- 	u8 he_6ghz_reg_pwr_type;
- 	bool require_he;
-+	u8 mu_onoff;
- #endif /* CONFIG_IEEE80211AX */
- 
- 	/* VHT enable/disable config from CHAN_SWITCH */
-diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 99ba973..44f494e 100644
---- a/src/ap/ap_drv_ops.c
-+++ b/src/ap/ap_drv_ops.c
-@@ -1161,3 +1161,17 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
- 		return 0;
- 	return hapd->driver->get_edcca(hapd->drv_priv, mode, value);
- }
-+
-+int hostapd_drv_mu_ctrl(struct hostapd_data *hapd)
-+{
-+	if (!hapd->driver || !hapd->driver->mu_ctrl)
-+		return 0;
-+	return hapd->driver->mu_ctrl(hapd->drv_priv, hapd->iconf->mu_onoff);
-+}
-+
-+int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
-+{
-+	if (!hapd->driver || !hapd->driver->mu_dump)
-+		return 0;
-+	return hapd->driver->mu_dump(hapd->drv_priv, mu_onoff);
-+}
-diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 6ca693b..8a7d981 100644
---- a/src/ap/ap_drv_ops.h
-+++ b/src/ap/ap_drv_ops.h
-@@ -148,6 +148,8 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
- int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd,
- 					  const int *threshold);
- int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value);
-+int hostapd_drv_mu_ctrl(struct hostapd_data *hapd);
-+int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
- 
- #include "drivers/driver.h"
- 
-diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 1b9ce6f..865991e 100644
---- a/src/ap/hostapd.c
-+++ b/src/ap/hostapd.c
-@@ -2517,6 +2517,8 @@ dfs_offload:
- 	if (hostapd_drv_configure_edcca_threshold(hapd,
- 						  hapd->iconf->edcca_threshold) < 0)
- 		goto fail;
-+	if (hostapd_drv_mu_ctrl(hapd) < 0)
-+		goto fail;
- 
- 	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
- 		   iface->bss[0]->conf->iface);
-diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 6121857..60bc4cd 100644
---- a/src/common/mtk_vendor.h
-+++ b/src/common/mtk_vendor.h
-@@ -10,6 +10,8 @@ enum mtk_nl80211_vendor_subcmds {
- 	MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
- 	MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL = 0xc3,
- 	MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
-+	MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
-+	MTK_NL80211_VENDOR_SUBCMD_PHY_CAPA_CTRL= 0xc6,
- 	MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
- };
- 
-@@ -177,6 +179,19 @@ enum mtk_vendor_attr_rfeature_ctrl {
- 		NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL - 1
- };
- 
-+enum mtk_vendor_attr_mu_ctrl {
-+	MTK_VENDOR_ATTR_MU_CTRL_UNSPEC,
-+
-+	MTK_VENDOR_ATTR_MU_CTRL_ONOFF,
-+	MTK_VENDOR_ATTR_MU_CTRL_DUMP,
-+
-+	/* keep last */
-+	NUM_MTK_VENDOR_ATTRS_MU_CTRL,
-+	MTK_VENDOR_ATTR_MU_CTRL_MAX =
-+		NUM_MTK_VENDOR_ATTRS_MU_CTRL - 1
-+};
-+
-+
- #define CSI_MAX_COUNT 256
- #define ETH_ALEN 6
- 
-diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index fca2035..542dd45 100644
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -176,6 +176,11 @@ struct hostapd_channel_data {
- 	 * punct_bitmap - RU puncturing bitmap
- 	 */
- 	u16 punct_bitmap;
-+
-+	/**
-+	 * mu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
-+	 */
-+	u8 mu_onoff;
- };
- 
- #define HE_MAC_CAPAB_0		0
-@@ -5106,6 +5111,14 @@ struct wpa_driver_ops {
- 				  const s8 edcca_compensation);
- 	int (*configure_edcca_threshold)(void *priv, const int *threshold);
- 	int (*get_edcca)(void *priv, const u8 mode, u8 *value);
-+
-+	/**
-+	 * mu_ctrl - ctrl on off for UL/DL MURU
-+	 * @priv: Private driver interface data
-+	 *
-+	 */
-+	 int (*mu_ctrl)(void *priv, u8 mu_onoff);
-+	 int (*mu_dump)(void *priv, u8 *mu_onoff);
- };
- 
- /**
-diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 0a159d5..07c72f5 100644
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -13613,6 +13613,114 @@ fail:
- }
- 
- 
-+#ifdef CONFIG_IEEE80211AX
-+static int nl80211_mu_onoff(void *priv, u8 mu_onoff)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	struct nl_msg *msg;
-+	struct nlattr *data;
-+	int ret;
-+
-+	if (!drv->mtk_mu_vendor_cmd_avail) {
-+		wpa_printf(MSG_INFO,
-+			   "nl80211: Driver does not support setting mu control");
-+		return 0;
-+	}
-+
-+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
-+		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
-+		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_MU_CTRL) ||
-+		!(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
-+		nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_ONOFF, mu_onoff)) {
-+		nlmsg_free(msg);
-+		return -ENOBUFS;
-+	}
-+	nla_nest_end(msg, data);
-+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
-+	if(ret){
-+		wpa_printf(MSG_ERROR, "Failed to set mu_onoff. ret=%d (%s)", ret, strerror(-ret));
-+	}
-+	return ret;
-+}
-+
-+
-+static int mu_dump_handler(struct nl_msg *msg, void *arg)
-+{
-+	u8 *mu_onoff = (u8 *) arg;
-+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-+	struct nlattr *tb_vendor[MTK_VENDOR_ATTR_MU_CTRL_MAX + 1];
-+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-+	struct nlattr *nl_vend, *attr;
-+
-+	static const struct nla_policy
-+	mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL + 1] = {
-+		[MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 },
-+		[MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 },
-+	};
-+
-+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-+			genlmsg_attrlen(gnlh, 0), NULL);
-+
-+	nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
-+	if (!nl_vend)
-+		return NL_SKIP;
-+
-+	nla_parse(tb_vendor, MTK_VENDOR_ATTR_MU_CTRL_MAX,
-+		  nla_data(nl_vend), nla_len(nl_vend), NULL);
-+
-+	attr = tb_vendor[MTK_VENDOR_ATTR_MU_CTRL_DUMP];
-+	if (!attr) {
-+		wpa_printf(MSG_ERROR, "nl80211: cannot find MTK_VENDOR_ATTR_MU_CTRL_DUMP");
-+		return NL_SKIP;
-+	}
-+
-+	*mu_onoff = nla_get_u8(attr);
-+	wpa_printf(MSG_DEBUG, "nla_get mu_onoff: %d\n", *mu_onoff);
-+
-+	return 0;
-+}
-+
-+static int nl80211_mu_dump(void *priv, u8 *mu_onoff)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	struct nl_msg *msg;
-+	struct nlattr *attr;
-+	int ret;
-+
-+	if (!drv->mtk_mu_vendor_cmd_avail) {
-+		wpa_printf(MSG_INFO,
-+			   "nl80211: Driver does not support setting mu control");
-+		return 0;
-+	}
-+
-+	if (!(msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_VENDOR)) ||
-+		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
-+		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_MU_CTRL)) {
-+		nlmsg_free(msg);
-+		return -ENOBUFS;
-+	}
-+
-+  attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
-+	if (!attr) {
-+		nlmsg_free(msg);
-+		return -1;
-+	}
-+
-+	nla_nest_end(msg, attr);
-+
-+	ret = send_and_recv_msgs(drv, msg, mu_dump_handler, mu_onoff, NULL, NULL);
-+
-+	if(ret){
-+		wpa_printf(MSG_ERROR, "Failed to get mu_onoff. ret=%d (%s)", ret, strerror(-ret));
-+	}
-+
-+	return ret;
-+}
-+#endif /* CONFIG_IEEE80211AX */
-+
-+
- #ifdef CONFIG_DPP
- static int nl80211_dpp_listen(void *priv, bool enable)
- {
-@@ -14065,6 +14173,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.update_connect_params = nl80211_update_connection_params,
- 	.send_external_auth_status = nl80211_send_external_auth_status,
- 	.set_4addr_mode = nl80211_set_4addr_mode,
-+	.mu_ctrl = nl80211_mu_onoff,
-+	.mu_dump = nl80211_mu_dump,
- #ifdef CONFIG_DPP
- 	.dpp_listen = nl80211_dpp_listen,
- #endif /* CONFIG_DPP */
-diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 51b3fbe..bd5d284 100644
---- a/src/drivers/driver_nl80211.h
-+++ b/src/drivers/driver_nl80211.h
-@@ -203,6 +203,7 @@ struct wpa_driver_nl80211_data {
- 	unsigned int puncturing:1;
- 	unsigned int qca_ap_allowed_freqs:1;
- 	unsigned int mtk_edcca_vendor_cmd_avail:1;
-+	unsigned int mtk_mu_vendor_cmd_avail:1;
- 
- 	u64 vendor_scan_cookie;
- 	u64 remain_on_chan_cookie;
-diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 5dadf24..ac66a91 100644
---- a/src/drivers/driver_nl80211_capa.c
-+++ b/src/drivers/driver_nl80211_capa.c
-@@ -1113,6 +1113,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
- 				case MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL:
- 					drv->mtk_edcca_vendor_cmd_avail = 1;
- 					break;
-+				case MTK_NL80211_VENDOR_SUBCMD_MU_CTRL :
-+					drv->mtk_mu_vendor_cmd_avail = 1;
-+					break;
- 				}
- 			}
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-mtk-hostapd-Add-hostapd-MU-SET-GET-control.patch
similarity index 91%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-mtk-hostapd-Add-hostapd-MU-SET-GET-control.patch
index 43f214c..e0bdc50 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-mtk-hostapd-Add-hostapd-MU-SET-GET-control.patch
@@ -1,11 +1,11 @@
-From f868636d86170f6ebe9dba785f22195b06177af1 Mon Sep 17 00:00:00 2001
+From 8ed06968aea1170b6fbb7d88fbf546764c404eae Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Tue, 9 Aug 2022 10:23:44 -0700
-Subject: [PATCH 06/38] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH 06/54] mtk: hostapd: Add hostapd MU SET/GET control
 
 ---
  hostapd/config_file.c             |   9 +++
- hostapd/ctrl_iface.c              |  62 +++++++++++++++++
+ hostapd/ctrl_iface.c              |  66 ++++++++++++++++++
  hostapd/hostapd_cli.c             |  18 +++++
  src/ap/ap_config.c                |   1 +
  src/ap/ap_config.h                |   1 +
@@ -17,10 +17,10 @@
  src/drivers/driver_nl80211.c      | 110 ++++++++++++++++++++++++++++++
  src/drivers/driver_nl80211.h      |   1 +
  src/drivers/driver_nl80211_capa.c |   3 +
- 13 files changed, 251 insertions(+)
+ 13 files changed, 255 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index d281026..ec3b41a 100644
+index d281026e8..ec3b41abe 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -3677,6 +3677,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -40,10 +40,10 @@
  	} else if (os_strcmp(buf, "max_listen_interval") == 0) {
  		bss->max_listen_interval = atoi(pos);
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index cad3f86..c5d92b0 100644
+index cad3f863c..b10483652 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3488,6 +3488,63 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
+@@ -3488,6 +3488,67 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
  }
  
  
@@ -93,6 +93,10 @@
 +	pos = buf;
 +	end = buf + buflen;
 +
++	if (hapd->iface->state != HAPD_IFACE_ENABLED)
++		return os_snprintf(pos, end - pos, "Not allowed to get_mu when current state is %s\n",
++				   hostapd_state_text(hapd->iface->state));
++
 +	if (hostapd_drv_mu_dump(hapd, &mu_onoff) == 0) {
 +		hapd->iconf->mu_onoff = mu_onoff;
 +		return os_snprintf(pos, end - pos, "[hostapd_cli] = UL MU-MIMO: %d, DL MU-MIMO: %d, UL OFDMA: %d, DL OFDMA: %d\n",
@@ -107,7 +111,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4047,6 +4104,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4047,6 +4108,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "GET_EDCCA ", 10) == 0) {
  		reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
  							  reply_size);
@@ -120,7 +124,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index dfc996d..98892ee 100644
+index dfc996d49..98892ee9d 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1400,6 +1400,20 @@ static int hostapd_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
@@ -156,7 +160,7 @@
  	{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
  	  "report a scanned DPP URI from a QR Code" },
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 8e56d10..cf7f563 100644
+index 8e56d1082..cf7f56392 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -281,6 +281,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -168,7 +172,7 @@
  
  	/* The third octet of the country string uses an ASCII space character
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 24d540d..421e6a6 100644
+index 24d540dbf..421e6a647 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1146,6 +1146,7 @@ struct hostapd_config {
@@ -180,7 +184,7 @@
  
  	/* VHT enable/disable config from CHAN_SWITCH */
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 99ba973..44f494e 100644
+index 99ba973aa..44f494ed9 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1161,3 +1161,17 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
@@ -202,7 +206,7 @@
 +	return hapd->driver->mu_dump(hapd->drv_priv, mu_onoff);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 6ca693b..8a7d981 100644
+index 6ca693b0b..8a7d98128 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -148,6 +148,8 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
@@ -215,7 +219,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 1b9ce6f..865991e 100644
+index f7c80c73b..65fdc47da 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2517,6 +2517,8 @@ dfs_offload:
@@ -228,7 +232,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 6121857..60bc4cd 100644
+index 6121857dd..60bc4cd4c 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -10,6 +10,8 @@ enum mtk_nl80211_vendor_subcmds {
@@ -261,7 +265,7 @@
  #define ETH_ALEN 6
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index fca2035..542dd45 100644
+index 7d71aa783..a23de244f 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
 @@ -176,6 +176,11 @@ struct hostapd_channel_data {
@@ -276,7 +280,7 @@
  };
  
  #define HE_MAC_CAPAB_0		0
-@@ -5106,6 +5111,14 @@ struct wpa_driver_ops {
+@@ -5109,6 +5114,14 @@ struct wpa_driver_ops {
  				  const s8 edcca_compensation);
  	int (*configure_edcca_threshold)(void *priv, const int *threshold);
  	int (*get_edcca)(void *priv, const u8 mode, u8 *value);
@@ -292,10 +296,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 0a159d5..07c72f5 100644
+index 1a2f52b77..f7f157bf0 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13613,6 +13613,114 @@ fail:
+@@ -13633,6 +13633,114 @@ fail:
  }
  
  
@@ -410,7 +414,7 @@
  #ifdef CONFIG_DPP
  static int nl80211_dpp_listen(void *priv, bool enable)
  {
-@@ -14065,6 +14173,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14085,6 +14193,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.update_connect_params = nl80211_update_connection_params,
  	.send_external_auth_status = nl80211_send_external_auth_status,
  	.set_4addr_mode = nl80211_set_4addr_mode,
@@ -420,7 +424,7 @@
  	.dpp_listen = nl80211_dpp_listen,
  #endif /* CONFIG_DPP */
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 51b3fbe..bd5d284 100644
+index 51b3fbec8..bd5d28404 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -203,6 +203,7 @@ struct wpa_driver_nl80211_data {
@@ -432,10 +436,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 5dadf24..ac66a91 100644
+index 47654f65b..07f6cb133 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1113,6 +1113,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1117,6 +1117,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL:
  					drv->mtk_edcca_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
deleted file mode 100644
index 5967879..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
+++ /dev/null
@@ -1,247 +0,0 @@
-From f02858d395fd60a2b5b772ceaccf883455605af4 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 2 Sep 2022 01:03:23 +0800
-Subject: [PATCH 07/38] hostapd: mtk: Add three wire PTA ctrl hostapd vendor
- command
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- hostapd/config_file.c             |  4 ++++
- src/ap/ap_config.c                |  1 +
- src/ap/ap_config.h                | 13 ++++++++++++
- src/ap/ap_drv_ops.c               | 11 +++++++++++
- src/ap/ap_drv_ops.h               |  1 +
- src/ap/hostapd.c                  |  2 ++
- src/common/mtk_vendor.h           | 16 +++++++++++++++
- src/drivers/driver.h              |  8 ++++++++
- src/drivers/driver_nl80211.c      | 33 +++++++++++++++++++++++++++++++
- src/drivers/driver_nl80211.h      |  1 +
- src/drivers/driver_nl80211_capa.c |  3 +++
- 11 files changed, 93 insertions(+)
-
-diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index ec3b41a..d515b6e 100644
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -4852,6 +4852,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 			return 1;
- 		}
- 		conf->edcca_compensation = (s8) val;
-+	} else if (os_strcmp(buf, "three_wire_enable") == 0) {
-+		u8 en = atoi(pos);
-+
-+		conf->three_wire_enable = en;
- 	} else {
- 		wpa_printf(MSG_ERROR,
- 			   "Line %d: unknown configuration item '%s'",
-diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index cf7f563..8b11545 100644
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -298,6 +298,7 @@ struct hostapd_config * hostapd_config_defaults(void)
- 
- 	conf->edcca_enable = EDCCA_MODE_AUTO;
- 	conf->edcca_compensation = EDCCA_DEFAULT_COMPENSATION;
-+	conf->three_wire_enable = THREE_WIRE_MODE_DISABLE;
- 
- 	return conf;
- }
-diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 421e6a6..52df2e0 100644
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -1198,6 +1198,19 @@ struct hostapd_config {
- 	u8 edcca_enable;
- 	s8 edcca_compensation;
- 	int *edcca_threshold;
-+	u8 three_wire_enable;
-+};
-+
-+enum three_wire_mode {
-+	THREE_WIRE_MODE_DISABLE,
-+	THREE_WIRE_MODE_EXT0_ENABLE,
-+	THREE_WIRE_MODE_EXT1_ENABLE,
-+	THREE_WIRE_MODE_ALL_ENABLE,
-+
-+	/* keep last */
-+	NUM_THREE_WIRE_MODE,
-+	THREE_WIRE_MODE_MAX =
-+		NUM_THREE_WIRE_MODE - 1
- };
- 
- enum edcca_mode {
-diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 44f494e..2f15f99 100644
---- a/src/ap/ap_drv_ops.c
-+++ b/src/ap/ap_drv_ops.c
-@@ -1175,3 +1175,14 @@ int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
- 		return 0;
- 	return hapd->driver->mu_dump(hapd->drv_priv, mu_onoff);
- }
-+
-+int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd)
-+{
-+	if (!hapd->driver || !hapd->driver->three_wire_ctrl)
-+		return 0;
-+	if (hapd->iconf->three_wire_enable > THREE_WIRE_MODE_MAX) {
-+		wpa_printf(MSG_INFO, "Invalid value for three wire enable\n");
-+		return 0;
-+	}
-+	return hapd->driver->three_wire_ctrl(hapd->drv_priv, hapd->iconf->three_wire_enable);
-+}
-diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 8a7d981..ed3b4cf 100644
---- a/src/ap/ap_drv_ops.h
-+++ b/src/ap/ap_drv_ops.h
-@@ -150,6 +150,7 @@ int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd,
- int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value);
- int hostapd_drv_mu_ctrl(struct hostapd_data *hapd);
- int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
-+int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
- 
- #include "drivers/driver.h"
- 
-diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 865991e..cad5d67 100644
---- a/src/ap/hostapd.c
-+++ b/src/ap/hostapd.c
-@@ -2519,6 +2519,8 @@ dfs_offload:
- 		goto fail;
- 	if (hostapd_drv_mu_ctrl(hapd) < 0)
- 		goto fail;
-+	if (hostapd_drv_three_wire_ctrl(hapd) < 0)
-+		goto fail;
- 
- 	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
- 		   iface->bss[0]->conf->iface);
-diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 60bc4cd..99ecbaf 100644
---- a/src/common/mtk_vendor.h
-+++ b/src/common/mtk_vendor.h
-@@ -13,6 +13,7 @@ enum mtk_nl80211_vendor_subcmds {
- 	MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
- 	MTK_NL80211_VENDOR_SUBCMD_PHY_CAPA_CTRL= 0xc6,
- 	MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
-+	MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8
- };
- 
- enum mtk_vendor_attr_edcca_ctrl {
-@@ -58,6 +59,21 @@ static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
- 	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC160_VAL] = { .type = NLA_U8 },
- };
- 
-+enum mtk_vendor_attr_3wire_ctrl {
-+	MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC,
-+
-+	MTK_VENDOR_ATTR_3WIRE_CTRL_MODE,
-+
-+	/* keep last */
-+	NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL,
-+	MTK_VENDOR_ATTR_3WIRE_CTRL_MAX =
-+		NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1
-+};
-+
-+static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
-+	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
-+};
-+
- enum mtk_vendor_attr_csi_ctrl {
- 	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
- 
-diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 542dd45..07af191 100644
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -5119,6 +5119,14 @@ struct wpa_driver_ops {
- 	 */
- 	 int (*mu_ctrl)(void *priv, u8 mu_onoff);
- 	 int (*mu_dump)(void *priv, u8 *mu_onoff);
-+
-+	/**
-+	 * three_wire_ctrl - set three_wire_ctrl mode
-+	 * @priv: Private driver interface data
-+	 * @three_wire_enable: three_wire_ctrl mode
-+	 *
-+	 */
-+	 int (*three_wire_ctrl)(void *priv, u8 three_wire_enable);
- };
- 
- /**
-diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 07c72f5..cf1f2d0 100644
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -14026,6 +14026,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
- 	return ret;
- }
- 
-+static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	/* Prepare nl80211 cmd */
-+	struct nl_msg *msg;
-+	struct nlattr *data;
-+	int ret;
-+
-+	if (!drv->mtk_3wire_vendor_cmd_avail) {
-+		wpa_printf(MSG_INFO,
-+			   "nl80211: Driver does not support setting three wire control");
-+		return 0;
-+	}
-+
-+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
-+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
-+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
-+			MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL) ||
-+	    !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
-+	    nla_put_u8(msg, MTK_VENDOR_ATTR_3WIRE_CTRL_MODE, three_wire_enable)) {
-+		nlmsg_free(msg);
-+		return -ENOBUFS;
-+	}
-+	nla_nest_end(msg, data);
-+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
-+	if (ret) {
-+		wpa_printf(MSG_ERROR, "Failed to enable three wire. ret=%d (%s) ",
-+			   ret, strerror(-ret));
-+	}
-+	return ret;
-+}
- 
- const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.name = "nl80211",
-@@ -14188,4 +14220,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.configure_edcca_enable = nl80211_configure_edcca_enable,
- 	.configure_edcca_threshold = nl80211_configure_edcca_threshold,
- 	.get_edcca = nl80211_get_edcca,
-+	.three_wire_ctrl = nl80211_enable_three_wire,
- };
-diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index bd5d284..99af8b0 100644
---- a/src/drivers/driver_nl80211.h
-+++ b/src/drivers/driver_nl80211.h
-@@ -204,6 +204,7 @@ struct wpa_driver_nl80211_data {
- 	unsigned int qca_ap_allowed_freqs:1;
- 	unsigned int mtk_edcca_vendor_cmd_avail:1;
- 	unsigned int mtk_mu_vendor_cmd_avail:1;
-+	unsigned int mtk_3wire_vendor_cmd_avail:1;
- 
- 	u64 vendor_scan_cookie;
- 	u64 remain_on_chan_cookie;
-diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index ac66a91..3ff47f3 100644
---- a/src/drivers/driver_nl80211_capa.c
-+++ b/src/drivers/driver_nl80211_capa.c
-@@ -1116,6 +1116,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
- 				case MTK_NL80211_VENDOR_SUBCMD_MU_CTRL :
- 					drv->mtk_mu_vendor_cmd_avail = 1;
- 					break;
-+				case MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL :
-+					drv->mtk_3wire_vendor_cmd_avail = 1;
-+					break;
- 				}
- 			}
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0007-mtk-hostapd-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
similarity index 90%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0007-mtk-hostapd-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
index 5967879..c24b78a 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0007-mtk-hostapd-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
@@ -1,7 +1,7 @@
-From f02858d395fd60a2b5b772ceaccf883455605af4 Mon Sep 17 00:00:00 2001
+From 022b58d6277d12517ada28d8b5581a75e501d779 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 2 Sep 2022 01:03:23 +0800
-Subject: [PATCH 07/38] hostapd: mtk: Add three wire PTA ctrl hostapd vendor
+Subject: [PATCH 07/54] mtk: hostapd: Add three wire PTA ctrl hostapd vendor
  command
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -20,7 +20,7 @@
  11 files changed, 93 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index ec3b41a..d515b6e 100644
+index ec3b41abe..d515b6ea9 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4852,6 +4852,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -35,7 +35,7 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index cf7f563..8b11545 100644
+index cf7f56392..8b1154553 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -298,6 +298,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -47,7 +47,7 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 421e6a6..52df2e0 100644
+index 421e6a647..52df2e0c0 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1198,6 +1198,19 @@ struct hostapd_config {
@@ -71,7 +71,7 @@
  
  enum edcca_mode {
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 44f494e..2f15f99 100644
+index 44f494ed9..2f15f99f4 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1175,3 +1175,14 @@ int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
@@ -90,7 +90,7 @@
 +	return hapd->driver->three_wire_ctrl(hapd->drv_priv, hapd->iconf->three_wire_enable);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 8a7d981..ed3b4cf 100644
+index 8a7d98128..ed3b4cf11 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -150,6 +150,7 @@ int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd,
@@ -102,7 +102,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 865991e..cad5d67 100644
+index 65fdc47da..5487c9489 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2519,6 +2519,8 @@ dfs_offload:
@@ -115,7 +115,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 60bc4cd..99ecbaf 100644
+index 60bc4cd4c..99ecbaf71 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -13,6 +13,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -149,10 +149,10 @@
  	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 542dd45..07af191 100644
+index a23de244f..03d268b2e 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5119,6 +5119,14 @@ struct wpa_driver_ops {
+@@ -5122,6 +5122,14 @@ struct wpa_driver_ops {
  	 */
  	 int (*mu_ctrl)(void *priv, u8 mu_onoff);
  	 int (*mu_dump)(void *priv, u8 *mu_onoff);
@@ -168,10 +168,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 07c72f5..cf1f2d0 100644
+index f7f157bf0..d5c0ea81a 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14026,6 +14026,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
+@@ -14046,6 +14046,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
  	return ret;
  }
  
@@ -210,14 +210,14 @@
  
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
-@@ -14188,4 +14220,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14208,4 +14240,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.configure_edcca_enable = nl80211_configure_edcca_enable,
  	.configure_edcca_threshold = nl80211_configure_edcca_threshold,
  	.get_edcca = nl80211_get_edcca,
 +	.three_wire_ctrl = nl80211_enable_three_wire,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index bd5d284..99af8b0 100644
+index bd5d28404..99af8b075 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -204,6 +204,7 @@ struct wpa_driver_nl80211_data {
@@ -229,10 +229,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index ac66a91..3ff47f3 100644
+index 07f6cb133..47ba17933 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1116,6 +1116,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1120,6 +1120,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_MU_CTRL :
  					drv->mtk_mu_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch
deleted file mode 100644
index de3e848..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch
+++ /dev/null
@@ -1,431 +0,0 @@
-From 59a1d486171bd4976b39bcf076d7a5b50237de58 Mon Sep 17 00:00:00 2001
-From: mtk27835 <shurong.wen@mediatek.com>
-Date: Wed, 7 Sep 2022 14:41:51 -0700
-Subject: [PATCH 08/38] hostapd: mtk: Add hostapd iBF control
-
-Signed-off-by: mtk27835 <shurong.wen@mediatek.com>
----
- hostapd/config_file.c             |   3 +
- hostapd/ctrl_iface.c              |  26 +++++++
- hostapd/hostapd_cli.c             |   9 +++
- src/ap/ap_config.c                |   1 +
- src/ap/ap_config.h                |   2 +
- src/ap/ap_drv_ops.c               |  14 ++++
- src/ap/ap_drv_ops.h               |   2 +
- src/ap/hostapd.c                  |   2 +
- src/common/mtk_vendor.h           |  35 +++++++++-
- src/drivers/driver.h              |  19 ++++++
- src/drivers/driver_nl80211.c      | 108 ++++++++++++++++++++++++++++++
- src/drivers/driver_nl80211.h      |   1 +
- src/drivers/driver_nl80211_capa.c |   3 +
- 13 files changed, 224 insertions(+), 1 deletion(-)
-
-diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index d515b6e..f8560a7 100644
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -4856,6 +4856,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 		u8 en = atoi(pos);
- 
- 		conf->three_wire_enable = en;
-+	} else if (os_strcmp(buf, "ibf_enable") == 0) { /*ibf setting is per device*/
-+		int val = atoi(pos);
-+		conf->ibf_enable = !!val;
- 	} else {
- 		wpa_printf(MSG_ERROR,
- 			   "Line %d: unknown configuration item '%s'",
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c5d92b0..7d7ebe3 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -3545,6 +3545,30 @@ hostapd_ctrl_iface_get_mu(struct hostapd_data *hapd, char *buf,
- }
- 
- 
-+static int
-+hostapd_ctrl_iface_get_ibf(struct hostapd_data *hapd, char *buf,
-+					 size_t buflen)
-+{
-+	u8 ibf_enable;
-+	int ret;
-+	char *pos, *end;
-+
-+	pos = buf;
-+	end = buf + buflen;
-+
-+	if (hostapd_drv_ibf_dump(hapd, &ibf_enable) == 0) {
-+		hapd->iconf->ibf_enable = ibf_enable;
-+		ret = os_snprintf(pos, end - pos, "ibf_enable: %u\n",
-+			  ibf_enable);
-+	}
-+
-+	if (os_snprintf_error(end - pos, ret))
-+		return 0;
-+
-+	return ret;
-+}
-+
-+
- static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 					      char *buf, char *reply,
- 					      int reply_size,
-@@ -4109,6 +4133,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 							  reply_size);
- 	} else if (os_strncmp(buf, "GET_MU", 6) == 0) {
- 		reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
-+	} else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
-+		reply_len = hostapd_ctrl_iface_get_ibf(hapd, reply, reply_size);
- 	} else {
- 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
- 		reply_len = 16;
-diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 98892ee..4fa2d32 100644
---- a/hostapd/hostapd_cli.c
-+++ b/hostapd/hostapd_cli.c
-@@ -1606,6 +1606,13 @@ static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
- #endif /* ANDROID */
- 
- 
-+static int hostapd_cli_cmd_get_ibf(struct wpa_ctrl *ctrl, int argc,
-+					   char *argv[])
-+{
-+	return hostapd_cli_cmd(ctrl, "GET_IBF", 0, NULL, NULL);
-+}
-+
-+
- struct hostapd_cli_cmd {
- 	const char *cmd;
- 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
-@@ -1811,6 +1818,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
- #endif /* ANDROID */
- 	{ "inband_discovery", hostapd_cli_cmd_inband_discovery, NULL,
-           "<tx type(0/1/2)> <interval> = runtime set inband discovery" },
-+	{ "get_ibf", hostapd_cli_cmd_get_ibf, NULL,
-+	  " = show iBF state (enabled/disabled)"},
- 	{ NULL, NULL, NULL, NULL }
- };
- 
-diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 8b11545..c9b9683 100644
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -299,6 +299,7 @@ struct hostapd_config * hostapd_config_defaults(void)
- 	conf->edcca_enable = EDCCA_MODE_AUTO;
- 	conf->edcca_compensation = EDCCA_DEFAULT_COMPENSATION;
- 	conf->three_wire_enable = THREE_WIRE_MODE_DISABLE;
-+	conf->ibf_enable = IBF_DEFAULT_ENABLE;
- 
- 	return conf;
- }
-diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 52df2e0..ffbc4fb 100644
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -1199,6 +1199,7 @@ struct hostapd_config {
- 	s8 edcca_compensation;
- 	int *edcca_threshold;
- 	u8 three_wire_enable;
-+	u8 ibf_enable;
- };
- 
- enum three_wire_mode {
-@@ -1324,6 +1325,7 @@ hostapd_set_oper_centr_freq_seg1_idx(struct hostapd_config *conf,
- 	conf->vht_oper_centr_freq_seg1_idx = oper_centr_freq_seg1_idx;
- }
- 
-+#define IBF_DEFAULT_ENABLE 0
- 
- int hostapd_mac_comp(const void *a, const void *b);
- struct hostapd_config * hostapd_config_defaults(void);
-diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 2f15f99..41e76aa 100644
---- a/src/ap/ap_drv_ops.c
-+++ b/src/ap/ap_drv_ops.c
-@@ -1186,3 +1186,17 @@ int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd)
- 	}
- 	return hapd->driver->three_wire_ctrl(hapd->drv_priv, hapd->iconf->three_wire_enable);
- }
-+
-+int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd)
-+{
-+	if (!hapd->driver || !hapd->driver->ibf_ctrl)
-+		return 0;
-+	return hapd->driver->ibf_ctrl(hapd->drv_priv, hapd->iconf->ibf_enable);
-+}
-+
-+int hostapd_drv_ibf_dump(struct hostapd_data *hapd, u8 *ibf_enable)
-+{
-+	if (!hapd->driver || !hapd->driver->ibf_dump)
-+		return 0;
-+	return hapd->driver->ibf_dump(hapd->drv_priv, ibf_enable);
-+}
-\ No newline at end of file
-diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index ed3b4cf..2958661 100644
---- a/src/ap/ap_drv_ops.h
-+++ b/src/ap/ap_drv_ops.h
-@@ -151,6 +151,8 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value);
- int hostapd_drv_mu_ctrl(struct hostapd_data *hapd);
- int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
- int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
-+int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
-+int hostapd_drv_ibf_dump(struct hostapd_data *hapd, u8 *ibf_enable);
- 
- #include "drivers/driver.h"
- 
-diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index cad5d67..227580e 100644
---- a/src/ap/hostapd.c
-+++ b/src/ap/hostapd.c
-@@ -2521,6 +2521,8 @@ dfs_offload:
- 		goto fail;
- 	if (hostapd_drv_three_wire_ctrl(hapd) < 0)
- 		goto fail;
-+	if (hostapd_drv_ibf_ctrl(hapd) < 0)
-+		goto fail;
- 
- 	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
- 		   iface->bss[0]->conf->iface);
-diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 99ecbaf..9811f26 100644
---- a/src/common/mtk_vendor.h
-+++ b/src/common/mtk_vendor.h
-@@ -13,7 +13,8 @@ enum mtk_nl80211_vendor_subcmds {
- 	MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
- 	MTK_NL80211_VENDOR_SUBCMD_PHY_CAPA_CTRL= 0xc6,
- 	MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
--	MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8
-+	MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8,
-+	MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
- };
- 
- enum mtk_vendor_attr_edcca_ctrl {
-@@ -207,6 +208,38 @@ enum mtk_vendor_attr_mu_ctrl {
- 		NUM_MTK_VENDOR_ATTRS_MU_CTRL - 1
- };
- 
-+enum mtk_vendor_attr_ibf_ctrl {
-+	MTK_VENDOR_ATTR_IBF_CTRL_UNSPEC,
-+
-+	MTK_VENDOR_ATTR_IBF_CTRL_ENABLE,
-+
-+	/* keep last */
-+	NUM_MTK_VENDOR_ATTRS_IBF_CTRL,
-+	MTK_VENDOR_ATTR_IBF_CTRL_MAX =
-+		NUM_MTK_VENDOR_ATTRS_IBF_CTRL - 1
-+};
-+
-+enum mtk_vendor_attr_ibf_dump {
-+	MTK_VENDOR_ATTR_IBF_DUMP_UNSPEC,
-+
-+	MTK_VENDOR_ATTR_IBF_DUMP_ENABLE,
-+
-+	/* keep last */
-+	NUM_MTK_VENDOR_ATTRS_IBF_DUMP,
-+	MTK_VENDOR_ATTR_IBF_DUMP_MAX =
-+		NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
-+};
-+
-+static struct nla_policy
-+ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
-+	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
-+};
-+
-+static struct nla_policy
-+ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
-+	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
-+};
-+
- 
- #define CSI_MAX_COUNT 256
- #define ETH_ALEN 6
-diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 07af191..0a99078 100644
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -181,6 +181,11 @@ struct hostapd_channel_data {
- 	 * mu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
- 	 */
- 	u8 mu_onoff;
-+
-+	/**
-+	 * ibf_enable=<val>
-+	 */
-+	u8 ibf_enable;
- };
- 
- #define HE_MAC_CAPAB_0		0
-@@ -5127,6 +5132,20 @@ struct wpa_driver_ops {
- 	 *
- 	 */
- 	 int (*three_wire_ctrl)(void *priv, u8 three_wire_enable);
-+
-+	/**
-+	 * ibf_ctrl - ctrl disable/enable for ibf
-+	 * @priv: Private driver interface data
-+	 *
-+	 */
-+	int (*ibf_ctrl)(void *priv, u8 ibf_enable);
-+
-+	/**
-+	 * ibf_dump - dump ibf
-+	 * @priv: Private driver interface data
-+	 *
-+	 */
-+	int (*ibf_dump)(void *priv, u8 *ibf_enable);
- };
- 
- /**
-diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index cf1f2d0..a05e047 100644
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -14059,6 +14059,112 @@ static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
- 	return ret;
- }
- 
-+static int nl80211_ibf_enable(void *priv, u8 ibf_enable)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	struct nl_msg *msg;
-+	struct nlattr *data;
-+	int ret;
-+
-+	if (!drv->mtk_ibf_vendor_cmd_avail) {
-+		wpa_printf(MSG_INFO,
-+			   "nl80211: Driver does not support setting ibf control");
-+		return 0;
-+	}
-+
-+	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
-+	if (!msg)
-+		goto fail;
-+
-+	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
-+		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL))
-+		goto fail;
-+
-+	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
-+	if (!data)
-+		goto fail;
-+
-+	nla_put_u8(msg, MTK_VENDOR_ATTR_IBF_CTRL_ENABLE, ibf_enable);
-+
-+	nla_nest_end(msg, data);
-+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
-+	if (ret) {
-+		wpa_printf(MSG_ERROR, "Failed to set ibf_enable. ret=%d (%s)", ret, strerror(-ret));
-+	}
-+
-+	return ret;
-+
-+fail:
-+	nlmsg_free(msg);
-+	return -ENOBUFS;
-+}
-+
-+static int ibf_dump_handler(struct nl_msg *msg, void *arg)
-+{
-+	u8 *ibf_enable = (u8 *) arg;
-+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-+	struct nlattr *tb_vendor[MTK_VENDOR_ATTR_IBF_DUMP_MAX + 1];
-+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-+	struct nlattr *nl_vend, *attr;
-+
-+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-+			genlmsg_attrlen(gnlh, 0), NULL);
-+
-+	nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
-+	if (!nl_vend)
-+		return NL_SKIP;
-+
-+	nla_parse(tb_vendor, MTK_VENDOR_ATTR_IBF_DUMP_MAX,
-+			nla_data(nl_vend), nla_len(nl_vend), NULL);
-+
-+	attr = tb_vendor[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE];
-+	if (!attr) {
-+		wpa_printf(MSG_ERROR, "nl80211: cannot find MTK_VENDOR_ATTR_IBF_DUMP_ENABLE");
-+		return NL_SKIP;
-+	}
-+
-+	*ibf_enable = nla_get_u8(attr);
-+
-+	return NL_SKIP;
-+}
-+
-+static int
-+nl80211_ibf_dump(void *priv, u8 *ibf_enable)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	struct nl_msg *msg;
-+	struct nlattr *data;
-+	int ret;
-+
-+	msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_VENDOR);
-+	if (!msg)
-+		goto fail;
-+
-+	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
-+		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL))
-+		goto fail;
-+
-+	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
-+	if (!data)
-+		goto fail;
-+
-+	nla_nest_end(msg, data);
-+
-+	ret = send_and_recv_msgs(drv, msg, ibf_dump_handler, ibf_enable, NULL, NULL);
-+
-+	if (ret) {
-+		wpa_printf(MSG_ERROR, "Failed to dump ibf_enable. ret=%d (%s)", ret, strerror(-ret));
-+	}
-+
-+	return ret;
-+
-+fail:
-+	nlmsg_free(msg);
-+	return -ENOBUFS;
-+}
-+
- const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.name = "nl80211",
- 	.desc = "Linux nl80211/cfg80211",
-@@ -14221,4 +14327,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.configure_edcca_threshold = nl80211_configure_edcca_threshold,
- 	.get_edcca = nl80211_get_edcca,
- 	.three_wire_ctrl = nl80211_enable_three_wire,
-+	.ibf_ctrl = nl80211_ibf_enable,
-+	.ibf_dump = nl80211_ibf_dump,
- };
-diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 99af8b0..4e64e7d 100644
---- a/src/drivers/driver_nl80211.h
-+++ b/src/drivers/driver_nl80211.h
-@@ -205,6 +205,7 @@ struct wpa_driver_nl80211_data {
- 	unsigned int mtk_edcca_vendor_cmd_avail:1;
- 	unsigned int mtk_mu_vendor_cmd_avail:1;
- 	unsigned int mtk_3wire_vendor_cmd_avail:1;
-+	unsigned int mtk_ibf_vendor_cmd_avail:1;
- 
- 	u64 vendor_scan_cookie;
- 	u64 remain_on_chan_cookie;
-diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 3ff47f3..7ad15ba 100644
---- a/src/drivers/driver_nl80211_capa.c
-+++ b/src/drivers/driver_nl80211_capa.c
-@@ -1119,6 +1119,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
- 				case MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL :
- 					drv->mtk_3wire_vendor_cmd_avail = 1;
- 					break;
-+				case MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL:
-+					drv->mtk_ibf_vendor_cmd_avail = 1;
-+					break;
- 				}
- 			}
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0008-mtk-hostapd-Add-hostapd-iBF-control.patch
similarity index 92%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0008-mtk-hostapd-Add-hostapd-iBF-control.patch
index de3e848..8ff3fe9 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0008-mtk-hostapd-Add-hostapd-iBF-control.patch
@@ -1,7 +1,7 @@
-From 59a1d486171bd4976b39bcf076d7a5b50237de58 Mon Sep 17 00:00:00 2001
+From 23191149c4b3be30766166cd68db4beb6d57af78 Mon Sep 17 00:00:00 2001
 From: mtk27835 <shurong.wen@mediatek.com>
 Date: Wed, 7 Sep 2022 14:41:51 -0700
-Subject: [PATCH 08/38] hostapd: mtk: Add hostapd iBF control
+Subject: [PATCH 08/54] mtk: hostapd: Add hostapd iBF control
 
 Signed-off-by: mtk27835 <shurong.wen@mediatek.com>
 ---
@@ -21,7 +21,7 @@
  13 files changed, 224 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index d515b6e..f8560a7 100644
+index d515b6ea9..f8560a721 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4856,6 +4856,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -35,10 +35,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c5d92b0..7d7ebe3 100644
+index b10483652..cf7cc3923 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3545,6 +3545,30 @@ hostapd_ctrl_iface_get_mu(struct hostapd_data *hapd, char *buf,
+@@ -3549,6 +3549,30 @@ hostapd_ctrl_iface_get_mu(struct hostapd_data *hapd, char *buf,
  }
  
  
@@ -69,7 +69,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4109,6 +4133,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4113,6 +4137,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  							  reply_size);
  	} else if (os_strncmp(buf, "GET_MU", 6) == 0) {
  		reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
@@ -79,7 +79,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 98892ee..4fa2d32 100644
+index 98892ee9d..4fa2d323d 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1606,6 +1606,13 @@ static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
@@ -106,7 +106,7 @@
  };
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 8b11545..c9b9683 100644
+index 8b1154553..c9b9683bb 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -299,6 +299,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -118,7 +118,7 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 52df2e0..ffbc4fb 100644
+index 52df2e0c0..ffbc4fb4f 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1199,6 +1199,7 @@ struct hostapd_config {
@@ -138,7 +138,7 @@
  int hostapd_mac_comp(const void *a, const void *b);
  struct hostapd_config * hostapd_config_defaults(void);
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 2f15f99..41e76aa 100644
+index 2f15f99f4..41e76aa54 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1186,3 +1186,17 @@ int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd)
@@ -161,7 +161,7 @@
 +}
 \ No newline at end of file
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index ed3b4cf..2958661 100644
+index ed3b4cf11..295866134 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -151,6 +151,8 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value);
@@ -174,7 +174,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index cad5d67..227580e 100644
+index 5487c9489..15bc9f486 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2521,6 +2521,8 @@ dfs_offload:
@@ -187,7 +187,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 99ecbaf..9811f26 100644
+index 99ecbaf71..9811f266e 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -13,7 +13,8 @@ enum mtk_nl80211_vendor_subcmds {
@@ -240,7 +240,7 @@
  #define CSI_MAX_COUNT 256
  #define ETH_ALEN 6
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 07af191..0a99078 100644
+index 03d268b2e..58a681b7a 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
 @@ -181,6 +181,11 @@ struct hostapd_channel_data {
@@ -255,7 +255,7 @@
  };
  
  #define HE_MAC_CAPAB_0		0
-@@ -5127,6 +5132,20 @@ struct wpa_driver_ops {
+@@ -5130,6 +5135,20 @@ struct wpa_driver_ops {
  	 *
  	 */
  	 int (*three_wire_ctrl)(void *priv, u8 three_wire_enable);
@@ -277,10 +277,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index cf1f2d0..a05e047 100644
+index d5c0ea81a..daa05882f 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14059,6 +14059,112 @@ static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
+@@ -14079,6 +14079,112 @@ static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
  	return ret;
  }
  
@@ -393,7 +393,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14221,4 +14327,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14241,4 +14347,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.configure_edcca_threshold = nl80211_configure_edcca_threshold,
  	.get_edcca = nl80211_get_edcca,
  	.three_wire_ctrl = nl80211_enable_three_wire,
@@ -401,7 +401,7 @@
 +	.ibf_dump = nl80211_ibf_dump,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 99af8b0..4e64e7d 100644
+index 99af8b075..4e64e7d31 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -205,6 +205,7 @@ struct wpa_driver_nl80211_data {
@@ -413,10 +413,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 3ff47f3..7ad15ba 100644
+index 47ba17933..5b659f490 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1119,6 +1119,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1123,6 +1123,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL :
  					drv->mtk_3wire_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch
deleted file mode 100644
index ba1aa44..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From ddca5f55f8f0468f23d4e531b3b40d0ef7d63485 Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Thu, 22 Sep 2022 16:08:09 +0800
-Subject: [PATCH 09/38] hostapd: mtk: Do not include HE capab IE if associated
- sta's HE capab IE is invalid
-
----
- src/ap/ieee802_11.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index db404a6..110ad8c 100644
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -4863,7 +4863,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
- #endif /* CONFIG_IEEE80211AC */
- 
- #ifdef CONFIG_IEEE80211AX
--	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
-+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax &&
-+			sta->flags & WLAN_STA_HE) {
- 		p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP);
- 		p = hostapd_eid_he_operation(hapd, p);
- 		p = hostapd_eid_cca(hapd, p);
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0009-mtk-hostapd-Do-not-include-HE-capab-IE-if-associated.patch
similarity index 82%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0009-mtk-hostapd-Do-not-include-HE-capab-IE-if-associated.patch
index ba1aa44..e8ad881 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0009-mtk-hostapd-Do-not-include-HE-capab-IE-if-associated.patch
@@ -1,7 +1,7 @@
-From ddca5f55f8f0468f23d4e531b3b40d0ef7d63485 Mon Sep 17 00:00:00 2001
+From 037b1cdac457c03ba44a470a7df38798ba1d5d88 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Thu, 22 Sep 2022 16:08:09 +0800
-Subject: [PATCH 09/38] hostapd: mtk: Do not include HE capab IE if associated
+Subject: [PATCH 09/54] mtk: hostapd: Do not include HE capab IE if associated
  sta's HE capab IE is invalid
 
 ---
@@ -9,7 +9,7 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index db404a6..110ad8c 100644
+index db404a6c7..110ad8c2e 100644
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
 @@ -4863,7 +4863,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0010-mtk-hostapd-Add-DFS-detection-mode.patch
similarity index 91%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0010-mtk-hostapd-Add-DFS-detection-mode.patch
index 3049a6b..a0f9de1 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0010-mtk-hostapd-Add-DFS-detection-mode.patch
@@ -1,7 +1,7 @@
-From e825b01701aeb6536321a9bf1bd5b4760a0cdc04 Mon Sep 17 00:00:00 2001
+From 8ee7b5e713067c29aab2f7a4389cc806b545c5d8 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 14:55:49 +0800
-Subject: [PATCH 10/38] hostapd: mtk: Add DFS detection mode
+Subject: [PATCH 10/54] mtk: hostapd: Add DFS detection mode
 
 Add DFS detection mode for testing radar detection rate.
 If DFS detection mode is on, AP will not switch channels when receiving
@@ -17,7 +17,7 @@
  4 files changed, 50 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index f8560a7..50e2993 100644
+index f8560a721..50e299303 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4859,6 +4859,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -32,10 +32,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 7d7ebe3..d8f6663 100644
+index cf7cc3923..327533f80 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3569,6 +3569,26 @@ hostapd_ctrl_iface_get_ibf(struct hostapd_data *hapd, char *buf,
+@@ -3573,6 +3573,26 @@ hostapd_ctrl_iface_get_ibf(struct hostapd_data *hapd, char *buf,
  }
  
  
@@ -62,7 +62,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4135,6 +4155,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4139,6 +4159,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
  	} else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
  		reply_len = hostapd_ctrl_iface_get_ibf(hapd, reply, reply_size);
@@ -73,7 +73,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index ffbc4fb..6576d79 100644
+index ffbc4fb4f..6576d791d 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1200,6 +1200,7 @@ struct hostapd_config {
@@ -104,7 +104,7 @@
  	EDCCA_MODE_FORCE_DISABLE = 0,
  	EDCCA_MODE_AUTO = 1,
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 29d2683..2e138e2 100644
+index 29d268351..2e138e225 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1327,6 +1327,11 @@ hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0011-mtk-hostapd-Add-DFS-offchan-channel-switch.patch
similarity index 94%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0011-mtk-hostapd-Add-DFS-offchan-channel-switch.patch
index 39cb7f2..ae9c59e 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0011-mtk-hostapd-Add-DFS-offchan-channel-switch.patch
@@ -1,7 +1,7 @@
-From 34d1517322d42ea45b6b2a792b9d7f7dd256bef6 Mon Sep 17 00:00:00 2001
+From 60b4911627763adee4fba3107acd2979ff024f10 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 14:56:55 +0800
-Subject: [PATCH 11/38] hostapd: mtk: Add DFS offchan channel switch
+Subject: [PATCH 11/54] mtk: hostapd: Add DFS offchan channel switch
 
 Add DFS background chain channel switch command for testing purpose.
 This feature is implemented via hostapd_cli command.
@@ -16,10 +16,10 @@
  3 files changed, 96 insertions(+), 16 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index d8f6663..2399979 100644
+index 327533f80..84a6127d1 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3589,6 +3589,76 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
+@@ -3593,6 +3593,76 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
  }
  
  
@@ -96,7 +96,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4158,6 +4228,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4162,6 +4232,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
  		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
  								   reply, reply_size);
@@ -106,7 +106,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 2e138e2..23e6527 100644
+index 2e138e225..23e6527b3 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -19,13 +19,6 @@
@@ -156,7 +156,7 @@
  	if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax)
  		return;
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index 606c1b3..c2556d2 100644
+index 606c1b393..c2556d2d9 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -9,6 +9,12 @@
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
deleted file mode 100644
index de63341..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
+++ /dev/null
@@ -1,400 +0,0 @@
-From 2c3c314405d088440feccf8fb596849d99cce6f8 Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Fri, 16 Dec 2022 03:57:11 +0800
-Subject: [PATCH 12/38] hostapd: mtk: Add amsdu set get ctrl
-
----
- hostapd/config_file.c             |   9 +++
- hostapd/ctrl_iface.c              |  26 +++++++
- hostapd/hostapd_cli.c             |   9 +++
- src/ap/ap_config.c                |   1 +
- src/ap/ap_config.h                |   1 +
- src/ap/ap_drv_ops.c               |  14 ++++
- src/ap/ap_drv_ops.h               |   2 +
- src/ap/hostapd.c                  |   2 +
- src/common/mtk_vendor.h           |  17 ++++-
- src/drivers/driver.h              |   9 +++
- src/drivers/driver_nl80211.c      | 114 ++++++++++++++++++++++++++++++
- src/drivers/driver_nl80211.h      |   1 +
- src/drivers/driver_nl80211_capa.c |   3 +
- 13 files changed, 207 insertions(+), 1 deletion(-)
-
-diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 50e2993..0b2f3dc 100644
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -4863,6 +4863,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 		u8 en = strtol(pos, NULL, 10);
- 
- 		conf->dfs_detect_mode = en;
-+	} else if (os_strcmp(buf, "amsdu") == 0) {
-+		int val = atoi(pos);
-+		if (val < 0 || val > 1) {
-+			wpa_printf(MSG_ERROR,
-+					 "Line %d: invalid amsdu value",
-+					 line);
-+			return 1;
-+		}
-+		conf->amsdu = val;
- 	} else {
- 		wpa_printf(MSG_ERROR,
- 			   "Line %d: unknown configuration item '%s'",
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 2399979..c54cbb9 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -3659,6 +3659,30 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
- }
- 
- 
-+static int
-+hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
-+					 size_t buflen)
-+{
-+	u8 amsdu;
-+	int ret;
-+	char *pos, *end;
-+
-+	pos = buf;
-+	end = buf + buflen;
-+
-+	if (hostapd_drv_amsdu_dump(hapd, &amsdu) == 0) {
-+		hapd->iconf->amsdu = amsdu;
-+		ret = os_snprintf(pos, end - pos, "[hostapd_cli] AMSDU: %u\n",
-+					hapd->iconf->amsdu);
-+	}
-+
-+	if (os_snprintf_error(end - pos, ret))
-+		return 0;
-+
-+	return ret;
-+}
-+
-+
- static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 					      char *buf, char *reply,
- 					      int reply_size,
-@@ -4230,6 +4254,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 								   reply, reply_size);
- 	} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
- 		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
-+	} else if (os_strncmp(buf, "GET_AMSDU", 9) == 0) {
-+		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
- 	} else {
- 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
- 		reply_len = 16;
-diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 4fa2d32..d593730 100644
---- a/hostapd/hostapd_cli.c
-+++ b/hostapd/hostapd_cli.c
-@@ -1613,6 +1613,13 @@ static int hostapd_cli_cmd_get_ibf(struct wpa_ctrl *ctrl, int argc,
- }
- 
- 
-+static int hostapd_cli_cmd_get_amsdu(struct wpa_ctrl *ctrl, int argc,
-+					   char *argv[])
-+{
-+	return hostapd_cli_cmd(ctrl, "GET_AMSDU", 0, NULL, NULL);
-+}
-+
-+
- struct hostapd_cli_cmd {
- 	const char *cmd;
- 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
-@@ -1820,6 +1827,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
-           "<tx type(0/1/2)> <interval> = runtime set inband discovery" },
- 	{ "get_ibf", hostapd_cli_cmd_get_ibf, NULL,
- 	  " = show iBF state (enabled/disabled)"},
-+	{ "get_amsdu", hostapd_cli_cmd_get_amsdu, NULL,
-+		" = show AMSDU state"},
- 	{ NULL, NULL, NULL, NULL }
- };
- 
-diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index c9b9683..f519a76 100644
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -300,6 +300,7 @@ struct hostapd_config * hostapd_config_defaults(void)
- 	conf->edcca_compensation = EDCCA_DEFAULT_COMPENSATION;
- 	conf->three_wire_enable = THREE_WIRE_MODE_DISABLE;
- 	conf->ibf_enable = IBF_DEFAULT_ENABLE;
-+	conf->amsdu = 1;
- 
- 	return conf;
- }
-diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 6576d79..9f3cea2 100644
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -1201,6 +1201,7 @@ struct hostapd_config {
- 	u8 three_wire_enable;
- 	u8 ibf_enable;
- 	u8 dfs_detect_mode;
-+	u8 amsdu;
- };
- 
- enum three_wire_mode {
-diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 41e76aa..a7226cf 100644
---- a/src/ap/ap_drv_ops.c
-+++ b/src/ap/ap_drv_ops.c
-@@ -1199,4 +1199,18 @@ int hostapd_drv_ibf_dump(struct hostapd_data *hapd, u8 *ibf_enable)
- 	if (!hapd->driver || !hapd->driver->ibf_dump)
- 		return 0;
- 	return hapd->driver->ibf_dump(hapd->drv_priv, ibf_enable);
-+}
-+
-+int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd)
-+{
-+	if (!hapd->driver || !hapd->driver->amsdu_ctrl)
-+		return 0;
-+	return hapd->driver->amsdu_ctrl(hapd->drv_priv, hapd->iconf->amsdu);
-+}
-+
-+int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu)
-+{
-+	if (!hapd->driver || !hapd->driver->amsdu_dump)
-+		return 0;
-+	return hapd->driver->amsdu_dump(hapd->drv_priv, amsdu);
- }
-\ No newline at end of file
-diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 2958661..88bc430 100644
---- a/src/ap/ap_drv_ops.h
-+++ b/src/ap/ap_drv_ops.h
-@@ -153,6 +153,8 @@ int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
- int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
- int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
- int hostapd_drv_ibf_dump(struct hostapd_data *hapd, u8 *ibf_enable);
-+int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
-+int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu);
- 
- #include "drivers/driver.h"
- 
-diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 227580e..a166de4 100644
---- a/src/ap/hostapd.c
-+++ b/src/ap/hostapd.c
-@@ -2523,6 +2523,8 @@ dfs_offload:
- 		goto fail;
- 	if (hostapd_drv_ibf_ctrl(hapd) < 0)
- 		goto fail;
-+	if (hostapd_drv_amsdu_ctrl(hapd) < 0)
-+		goto fail;
- 
- 	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
- 		   iface->bss[0]->conf->iface);
-diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 9811f26..7b4d7c1 100644
---- a/src/common/mtk_vendor.h
-+++ b/src/common/mtk_vendor.h
-@@ -170,7 +170,6 @@ enum mtk_vendor_attr_wireless_ctrl {
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
--	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMPDU,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT,
- 
-@@ -180,6 +179,22 @@ enum mtk_vendor_attr_wireless_ctrl {
- 		NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL - 1
- };
- 
-+enum mtk_vendor_attr_wireless_dump {
-+	MTK_VENDOR_ATTR_WIRELESS_DUMP_UNSPEC,
-+
-+	MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU,
-+
-+	/* keep last */
-+	NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP,
-+	MTK_VENDOR_ATTR_WIRELESS_DUMP_MAX =
-+		NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
-+};
-+
-+static const struct nla_policy
-+wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
-+	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
-+};
-+
- enum mtk_vendor_attr_rfeature_ctrl {
- 	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
- 
-diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 0a99078..38f6e8b 100644
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -5146,6 +5146,15 @@ struct wpa_driver_ops {
- 	 *
- 	 */
- 	int (*ibf_dump)(void *priv, u8 *ibf_enable);
-+
-+	/**
-+	 * amsdu_ctrl - enable/disable amsdu
-+	 * amsdu_dump - get current amsdu status
-+	 * @priv: Private driver interface data
-+	 *
-+	 */
-+	int (*amsdu_ctrl)(void *priv, u8 amsdu);
-+	int (*amsdu_dump)(void *priv, u8 *amsdu);
- };
- 
- /**
-diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index a05e047..808db17 100644
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -14165,6 +14165,118 @@ fail:
- 	return -ENOBUFS;
- }
- 
-+static int nl80211_enable_amsdu(void *priv, u8 amsdu)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	struct nl_msg *msg;
-+	struct nlattr *data;
-+	int ret;
-+
-+	if (!drv->mtk_wireless_vendor_cmd_avail) {
-+		wpa_printf(MSG_INFO,
-+			   "nl80211: Driver does not support setting ap wireless control");
-+		return 0;
-+	}
-+
-+	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
-+	if (!msg)
-+		goto fail;
-+
-+	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
-+		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
-+		goto fail;
-+
-+	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
-+	if (!data)
-+		goto fail;
-+
-+	nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU, amsdu);
-+
-+	nla_nest_end(msg, data);
-+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
-+	if (ret) {
-+		wpa_printf(MSG_ERROR, "Failed to set amsdu. ret=%d (%s)", ret, strerror(-ret));
-+	}
-+
-+	return ret;
-+
-+fail:
-+	nlmsg_free(msg);
-+	return -ENOBUFS;
-+}
-+
-+static int dump_amsdu_handler(struct nl_msg *msg, void *arg)
-+{
-+	u8 *amsdu = (u8 *) arg;
-+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-+	struct nlattr *tb_vendor[MTK_VENDOR_ATTR_WIRELESS_DUMP_MAX + 1];
-+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-+	struct nlattr *nl_vend, *attr_amsdu;
-+
-+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-+			genlmsg_attrlen(gnlh, 0), NULL);
-+
-+	nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
-+	if (!nl_vend)
-+		return NL_SKIP;
-+
-+	nla_parse(tb_vendor, MTK_VENDOR_ATTR_WIRELESS_DUMP_MAX,
-+			nla_data(nl_vend), nla_len(nl_vend), NULL);
-+
-+	attr_amsdu = tb_vendor[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU];
-+	if (!attr_amsdu ){
-+		wpa_printf(MSG_ERROR, "nl80211: cannot find vendor attributes");
-+		return NL_SKIP;
-+	}
-+
-+	*amsdu = nla_get_u8(attr_amsdu);
-+
-+	return NL_SKIP;
-+}
-+
-+static int
-+nl80211_dump_amsdu(void *priv, u8 *amsdu)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	struct nl_msg *msg;
-+	struct nlattr *data;
-+	int ret;
-+
-+	if (!drv->mtk_wireless_vendor_cmd_avail) {
-+		wpa_printf(MSG_INFO,
-+				 "nl80211: Driver does not support ap_wireless control");
-+		return 0;
-+	}
-+
-+	msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_VENDOR);
-+	if (!msg)
-+		goto fail;
-+
-+	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
-+		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
-+		goto fail;
-+
-+	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
-+	if (!data)
-+		goto fail;
-+
-+	nla_nest_end(msg, data);
-+
-+	ret = send_and_recv_msgs(drv, msg, dump_amsdu_handler, amsdu, NULL, NULL);
-+
-+	if (ret) {
-+		wpa_printf(MSG_ERROR, "Failed to dump amsdu. ret=%d (%s)", ret, strerror(-ret));
-+	}
-+
-+	return ret;
-+
-+fail:
-+	nlmsg_free(msg);
-+	return -ENOBUFS;
-+}
-+
- const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.name = "nl80211",
- 	.desc = "Linux nl80211/cfg80211",
-@@ -14329,4 +14441,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.three_wire_ctrl = nl80211_enable_three_wire,
- 	.ibf_ctrl = nl80211_ibf_enable,
- 	.ibf_dump = nl80211_ibf_dump,
-+	.amsdu_ctrl = nl80211_enable_amsdu,
-+	.amsdu_dump = nl80211_dump_amsdu,
- };
-diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 4e64e7d..0100314 100644
---- a/src/drivers/driver_nl80211.h
-+++ b/src/drivers/driver_nl80211.h
-@@ -206,6 +206,7 @@ struct wpa_driver_nl80211_data {
- 	unsigned int mtk_mu_vendor_cmd_avail:1;
- 	unsigned int mtk_3wire_vendor_cmd_avail:1;
- 	unsigned int mtk_ibf_vendor_cmd_avail:1;
-+	unsigned int mtk_wireless_vendor_cmd_avail:1;
- 
- 	u64 vendor_scan_cookie;
- 	u64 remain_on_chan_cookie;
-diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 7ad15ba..f14706d 100644
---- a/src/drivers/driver_nl80211_capa.c
-+++ b/src/drivers/driver_nl80211_capa.c
-@@ -1122,6 +1122,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
- 				case MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL:
- 					drv->mtk_ibf_vendor_cmd_avail = 1;
- 					break;
-+				case MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL:
-+					drv->mtk_wireless_vendor_cmd_avail = 1;
-+					break;
- 				}
- 			}
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0012-mtk-hostapd-Add-amsdu-set-get-ctrl.patch
similarity index 92%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0012-mtk-hostapd-Add-amsdu-set-get-ctrl.patch
index de63341..f2d0484 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0012-mtk-hostapd-Add-amsdu-set-get-ctrl.patch
@@ -1,7 +1,7 @@
-From 2c3c314405d088440feccf8fb596849d99cce6f8 Mon Sep 17 00:00:00 2001
+From cfd3d079808b3a7d5585da349c1426351728b442 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 16 Dec 2022 03:57:11 +0800
-Subject: [PATCH 12/38] hostapd: mtk: Add amsdu set get ctrl
+Subject: [PATCH 12/54] mtk: hostapd: Add amsdu set get ctrl
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -20,7 +20,7 @@
  13 files changed, 207 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 50e2993..0b2f3dc 100644
+index 50e299303..0b2f3dc32 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4863,6 +4863,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -40,10 +40,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 2399979..c54cbb9 100644
+index 84a6127d1..57addb22d 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3659,6 +3659,30 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
+@@ -3663,6 +3663,30 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
  }
  
  
@@ -74,7 +74,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4230,6 +4254,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4234,6 +4258,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  								   reply, reply_size);
  	} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
  		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
@@ -84,7 +84,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 4fa2d32..d593730 100644
+index 4fa2d323d..d59373062 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1613,6 +1613,13 @@ static int hostapd_cli_cmd_get_ibf(struct wpa_ctrl *ctrl, int argc,
@@ -111,7 +111,7 @@
  };
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index c9b9683..f519a76 100644
+index c9b9683bb..f519a769b 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -300,6 +300,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -123,7 +123,7 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 6576d79..9f3cea2 100644
+index 6576d791d..9f3cea205 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1201,6 +1201,7 @@ struct hostapd_config {
@@ -135,7 +135,7 @@
  
  enum three_wire_mode {
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 41e76aa..a7226cf 100644
+index 41e76aa54..a7226cfa9 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1199,4 +1199,18 @@ int hostapd_drv_ibf_dump(struct hostapd_data *hapd, u8 *ibf_enable)
@@ -159,7 +159,7 @@
  }
 \ No newline at end of file
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 2958661..88bc430 100644
+index 295866134..88bc430d2 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -153,6 +153,8 @@ int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
@@ -172,7 +172,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 227580e..a166de4 100644
+index 15bc9f486..fcf346d36 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2523,6 +2523,8 @@ dfs_offload:
@@ -185,7 +185,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 9811f26..7b4d7c1 100644
+index 9811f266e..7b4d7c11a 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -170,7 +170,6 @@ enum mtk_vendor_attr_wireless_ctrl {
@@ -220,10 +220,10 @@
  	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 0a99078..38f6e8b 100644
+index 58a681b7a..577c34c07 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5146,6 +5146,15 @@ struct wpa_driver_ops {
+@@ -5149,6 +5149,15 @@ struct wpa_driver_ops {
  	 *
  	 */
  	int (*ibf_dump)(void *priv, u8 *ibf_enable);
@@ -240,10 +240,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index a05e047..808db17 100644
+index daa05882f..c1e3fcb69 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14165,6 +14165,118 @@ fail:
+@@ -14185,6 +14185,118 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -362,7 +362,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14329,4 +14441,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14349,4 +14461,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.three_wire_ctrl = nl80211_enable_three_wire,
  	.ibf_ctrl = nl80211_ibf_enable,
  	.ibf_dump = nl80211_ibf_dump,
@@ -370,7 +370,7 @@
 +	.amsdu_dump = nl80211_dump_amsdu,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 4e64e7d..0100314 100644
+index 4e64e7d31..0100314ba 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -206,6 +206,7 @@ struct wpa_driver_nl80211_data {
@@ -382,10 +382,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 7ad15ba..f14706d 100644
+index 5b659f490..0e70b7321 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1122,6 +1122,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1126,6 +1126,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL:
  					drv->mtk_ibf_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch
deleted file mode 100644
index 2182cc1..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 29d69687f1ef2150b1c81dc9a778755aa7095f2f Mon Sep 17 00:00:00 2001
-From: MeiChia Chiu <meichia.chiu@mediatek.com>
-Date: Thu, 12 Jan 2023 15:18:19 +0800
-Subject: [PATCH 13/38] hostapd: mtk: Add he_ldpc configuration
-
----
- hostapd/config_file.c        | 2 ++
- hostapd/hostapd.conf         | 5 +++++
- src/ap/ap_config.c           | 1 +
- src/ap/ap_config.h           | 1 +
- src/ap/ieee802_11_he.c       | 7 +++++++
- src/common/ieee802_11_defs.h | 3 +++
- 6 files changed, 19 insertions(+)
-
-diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 0b2f3dc..9e3dbb2 100644
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -3515,6 +3515,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 		conf->he_phy_capab.he_su_beamformee = atoi(pos);
- 	} else if (os_strcmp(buf, "he_mu_beamformer") == 0) {
- 		conf->he_phy_capab.he_mu_beamformer = atoi(pos);
-+	} else if (os_strcmp(buf, "he_ldpc") == 0) {
-+		conf->he_phy_capab.he_ldpc = atoi(pos);
- 	} else if (os_strcmp(buf, "he_bss_color") == 0) {
- 		conf->he_op.he_bss_color = atoi(pos) & 0x3f;
- 		conf->he_op.he_bss_color_disabled = 0;
-diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
-index bafc923..f16e3b0 100644
---- a/hostapd/hostapd.conf
-+++ b/hostapd/hostapd.conf
-@@ -833,6 +833,11 @@ wmm_ac_vo_acm=0
- # 1 = supported
- #he_mu_beamformer=1
- 
-+#he_ldpc: HE LDPC support
-+# 0 = not supported
-+# 1 = supported (default)
-+#he_ldpc=1
-+
- # he_bss_color: BSS color (1-63)
- #he_bss_color=1
- 
-diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index f519a76..223db56 100644
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -269,6 +269,7 @@ struct hostapd_config * hostapd_config_defaults(void)
- #endif /* CONFIG_ACS */
- 
- #ifdef CONFIG_IEEE80211AX
-+	conf->he_phy_capab.he_ldpc = 1;
- 	conf->he_op.he_rts_threshold = HE_OPERATION_RTS_THRESHOLD_MASK >>
- 		HE_OPERATION_RTS_THRESHOLD_OFFSET;
- 	/* Set default basic MCS/NSS set to single stream MCS 0-7 */
-diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 9f3cea2..d0e27b2 100644
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -959,6 +959,7 @@ struct hostapd_bss_config {
-  * struct he_phy_capabilities_info - HE PHY capabilities
-  */
- struct he_phy_capabilities_info {
-+	bool he_ldpc;
- 	bool he_su_beamformer;
- 	bool he_su_beamformee;
- 	bool he_mu_beamformer;
-diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
-index 548a448..9407dd6 100644
---- a/src/ap/ieee802_11_he.c
-+++ b/src/ap/ieee802_11_he.c
-@@ -138,6 +138,13 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid,
- 		os_memcpy(&cap->optional[mcs_nss_size],
- 			  mode->he_capab[opmode].ppet,  ppet_size);
- 
-+	if (hapd->iface->conf->he_phy_capab.he_ldpc)
-+		cap->he_phy_capab_info[HE_PHYCAP_LDPC_CODING_IN_PAYLOAD_IDX] |=
-+			HE_PHYCAP_LDPC_CODING_IN_PAYLOAD;
-+	else
-+		cap->he_phy_capab_info[HE_PHYCAP_LDPC_CODING_IN_PAYLOAD_IDX] &=
-+			~HE_PHYCAP_LDPC_CODING_IN_PAYLOAD;
-+
- 	if (hapd->iface->conf->he_phy_capab.he_su_beamformer)
- 		cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] |=
- 			HE_PHYCAP_SU_BEAMFORMER_CAPAB;
-diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
-index e7c3f17..69f1591 100644
---- a/src/common/ieee802_11_defs.h
-+++ b/src/common/ieee802_11_defs.h
-@@ -2358,6 +2358,9 @@ struct ieee80211_spatial_reuse {
- #define HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G	((u8) BIT(3))
- #define HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G	((u8) BIT(4))
- 
-+#define HE_PHYCAP_LDPC_CODING_IN_PAYLOAD_IDX	1
-+#define HE_PHYCAP_LDPC_CODING_IN_PAYLOAD	((u8) BIT(5))
-+
- #define HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX	3
- #define HE_PHYCAP_SU_BEAMFORMER_CAPAB		((u8) BIT(7))
- #define HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX	4
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0013-mtk-hostapd-Add-he_ldpc-configuration.patch
similarity index 90%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0013-mtk-hostapd-Add-he_ldpc-configuration.patch
index 2182cc1..32ee385 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0013-mtk-hostapd-Add-he_ldpc-configuration.patch
@@ -1,7 +1,7 @@
-From 29d69687f1ef2150b1c81dc9a778755aa7095f2f Mon Sep 17 00:00:00 2001
+From 6d57a4121c23048f3473991435aa8673b51763ad Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Thu, 12 Jan 2023 15:18:19 +0800
-Subject: [PATCH 13/38] hostapd: mtk: Add he_ldpc configuration
+Subject: [PATCH 13/54] mtk: hostapd: Add he_ldpc configuration
 
 ---
  hostapd/config_file.c        | 2 ++
@@ -13,7 +13,7 @@
  6 files changed, 19 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 0b2f3dc..9e3dbb2 100644
+index 0b2f3dc32..9e3dbb24a 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -3515,6 +3515,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -26,7 +26,7 @@
  		conf->he_op.he_bss_color = atoi(pos) & 0x3f;
  		conf->he_op.he_bss_color_disabled = 0;
 diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
-index bafc923..f16e3b0 100644
+index bafc9232b..f16e3b08d 100644
 --- a/hostapd/hostapd.conf
 +++ b/hostapd/hostapd.conf
 @@ -833,6 +833,11 @@ wmm_ac_vo_acm=0
@@ -42,7 +42,7 @@
  #he_bss_color=1
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index f519a76..223db56 100644
+index f519a769b..223db56eb 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -269,6 +269,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -54,7 +54,7 @@
  		HE_OPERATION_RTS_THRESHOLD_OFFSET;
  	/* Set default basic MCS/NSS set to single stream MCS 0-7 */
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 9f3cea2..d0e27b2 100644
+index 9f3cea205..d0e27b28d 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -959,6 +959,7 @@ struct hostapd_bss_config {
@@ -66,7 +66,7 @@
  	bool he_su_beamformee;
  	bool he_mu_beamformer;
 diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
-index 548a448..9407dd6 100644
+index 548a44821..9407dd6e5 100644
 --- a/src/ap/ieee802_11_he.c
 +++ b/src/ap/ieee802_11_he.c
 @@ -138,6 +138,13 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid,
@@ -84,7 +84,7 @@
  		cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] |=
  			HE_PHYCAP_SU_BEAMFORMER_CAPAB;
 diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
-index e7c3f17..69f1591 100644
+index e7c3f17e1..69f15913e 100644
 --- a/src/common/ieee802_11_defs.h
 +++ b/src/common/ieee802_11_defs.h
 @@ -2358,6 +2358,9 @@ struct ieee80211_spatial_reuse {
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch
deleted file mode 100644
index eac9292..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 318e4a89d2f1ab49916820cda2795aa1d9b719b9 Mon Sep 17 00:00:00 2001
-From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
-Date: Tue, 24 Jan 2023 19:06:44 +0800
-Subject: [PATCH 14/38] hostapd: mtk: Add vendor command attribute for RTS BW
- signaling.
-
-Signed-off-by: himanshu.goyal <himanshu.goyal@mediatek.com>
----
- src/common/mtk_vendor.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 7b4d7c1..ace993b 100644
---- a/src/common/mtk_vendor.h
-+++ b/src/common/mtk_vendor.h
-@@ -172,6 +172,7 @@ enum mtk_vendor_attr_wireless_ctrl {
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT,
-+	MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA,
- 
- 	/* keep last */
- 	NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL,
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0014-mtk-hostapd-Add-vendor-command-attribute-for-RTS-BW-.patch
similarity index 80%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0014-mtk-hostapd-Add-vendor-command-attribute-for-RTS-BW-.patch
index eac9292..cd53d89 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0014-mtk-hostapd-Add-vendor-command-attribute-for-RTS-BW-.patch
@@ -1,7 +1,7 @@
-From 318e4a89d2f1ab49916820cda2795aa1d9b719b9 Mon Sep 17 00:00:00 2001
+From 45bfb188573dae7bcc4c24fb22311c51c82a22d1 Mon Sep 17 00:00:00 2001
 From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
 Date: Tue, 24 Jan 2023 19:06:44 +0800
-Subject: [PATCH 14/38] hostapd: mtk: Add vendor command attribute for RTS BW
+Subject: [PATCH 14/54] mtk: hostapd: Add vendor command attribute for RTS BW
  signaling.
 
 Signed-off-by: himanshu.goyal <himanshu.goyal@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 1 insertion(+)
 
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 7b4d7c1..ace993b 100644
+index 7b4d7c11a..ace993bc8 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -172,6 +172,7 @@ enum mtk_vendor_attr_wireless_ctrl {
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch
deleted file mode 100644
index a955f11..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 38302b0ff51f0e666a2f47ef8851d0fe6e03daad Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Mon, 13 Feb 2023 11:03:53 +0800
-Subject: [PATCH 15/38] hostapd: mtk: 6G band does not require DFS
-
----
- src/ap/dfs.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 23e6527..0a8486a 100644
---- a/src/ap/dfs.c
-+++ b/src/ap/dfs.c
-@@ -1516,6 +1516,7 @@ int hostapd_is_dfs_required(struct hostapd_iface *iface)
- 	if ((!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
- 	     !iface->conf->ieee80211h) ||
- 	    !iface->current_mode ||
-+	    is_6ghz_freq(iface->freq) ||
- 	    iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
- 		return 0;
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0015-mtk-hostapd-6G-band-does-not-require-DFS.patch
similarity index 77%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0015-mtk-hostapd-6G-band-does-not-require-DFS.patch
index a955f11..653ca37 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0015-mtk-hostapd-6G-band-does-not-require-DFS.patch
@@ -1,14 +1,14 @@
-From 38302b0ff51f0e666a2f47ef8851d0fe6e03daad Mon Sep 17 00:00:00 2001
+From 808d6d8261761d9cab0cf1500eddd812344bf7bf Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Mon, 13 Feb 2023 11:03:53 +0800
-Subject: [PATCH 15/38] hostapd: mtk: 6G band does not require DFS
+Subject: [PATCH 15/54] mtk: hostapd: 6G band does not require DFS
 
 ---
  src/ap/dfs.c | 1 +
  1 file changed, 1 insertion(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 23e6527..0a8486a 100644
+index 23e6527b3..0a8486a1e 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1516,6 +1516,7 @@ int hostapd_is_dfs_required(struct hostapd_iface *iface)
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
deleted file mode 100644
index 76d6e0b..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From f0e980941ebf54811c89881ac1ea21f318751401 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Mon, 20 Feb 2023 11:01:18 +0800
-Subject: [PATCH 16/38] hostapd: mtk: Fix sending wrong VHT operation IE in CSA
- while using ZWDFS
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- src/ap/dfs.c | 14 +++++++++-----
- 1 file changed, 9 insertions(+), 5 deletions(-)
-
-diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 0a8486a..cfc3508 100644
---- a/src/ap/dfs.c
-+++ b/src/ap/dfs.c
-@@ -1120,6 +1120,14 @@ static int
- hostapd_dfs_start_channel_switch_background(struct hostapd_iface *iface)
- {
- 	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
-+	int ret;
-+
-+	ret = hostapd_dfs_request_channel_switch(iface, iface->radar_background.channel,
-+						 iface->radar_background.freq,
-+						 iface->radar_background.secondary_channel,
-+						 current_vht_oper_chwidth,
-+						 iface->radar_background.centr_freq_seg0_idx,
-+						 iface->radar_background.centr_freq_seg1_idx);
- 
- 	iface->conf->channel = iface->radar_background.channel;
- 	iface->freq = iface->radar_background.freq;
-@@ -1132,11 +1140,7 @@ hostapd_dfs_start_channel_switch_background(struct hostapd_iface *iface)
- 
- 	hostpad_dfs_update_background_chain(iface);
- 
--	return hostapd_dfs_request_channel_switch(
--		iface, iface->conf->channel, iface->freq,
--		iface->conf->secondary_channel, current_vht_oper_chwidth,
--		hostapd_get_oper_centr_freq_seg0_idx(iface->conf),
--		hostapd_get_oper_centr_freq_seg1_idx(iface->conf));
-+	return ret;
- }
- 
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0016-mtk-hostapd-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
similarity index 89%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0016-mtk-hostapd-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
index 76d6e0b..9e68c12 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0016-mtk-hostapd-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
@@ -1,7 +1,7 @@
-From f0e980941ebf54811c89881ac1ea21f318751401 Mon Sep 17 00:00:00 2001
+From bae45334df7f087ea31ddd4bc419610636ab45ea Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 11:01:18 +0800
-Subject: [PATCH 16/38] hostapd: mtk: Fix sending wrong VHT operation IE in CSA
+Subject: [PATCH 16/54] mtk: hostapd: Fix sending wrong VHT operation IE in CSA
  while using ZWDFS
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 9 insertions(+), 5 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 0a8486a..cfc3508 100644
+index 0a8486a1e..cfc350879 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1120,6 +1120,14 @@ static int
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch
deleted file mode 100644
index e29ecce..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-From aa33ef52222963f20b152120ad84b6614b8421a1 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Mon, 20 Feb 2023 10:51:47 +0800
-Subject: [PATCH 17/38] hostapd: mtk: Add sta-assisted DFS state update
- mechanism
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- src/ap/dfs.c                       | 20 ++++++++++++++++++++
- src/ap/dfs.h                       |  3 +++
- src/ap/drv_callbacks.c             | 28 ++++++++++++++++++++++++++++
- src/common/wpa_ctrl.h              |  1 +
- src/drivers/driver.h               | 14 ++++++++++++++
- src/drivers/driver_nl80211_event.c |  6 ++++++
- src/drivers/nl80211_copy.h         |  6 ++++++
- 7 files changed, 78 insertions(+)
-
-diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index cfc3508..9d002cf 100644
---- a/src/ap/dfs.c
-+++ b/src/ap/dfs.c
-@@ -1513,6 +1513,26 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
- }
- 
- 
-+int hostapd_dfs_sta_update_state(struct hostapd_iface *iface, int freq,
-+				 int ht_enabled, int chan_offset, int chan_width,
-+				 int cf1, int cf2, u32 state)
-+{
-+	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_STA_UPDATE
-+		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d state=%s",
-+		freq, ht_enabled, chan_offset, chan_width, cf1, cf2,
-+		(state == HOSTAPD_CHAN_DFS_AVAILABLE) ? "available" : "usable");
-+
-+	/* Proceed only if DFS is not offloaded to the driver */
-+	if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
-+		return 0;
-+
-+	set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width,
-+		      cf1, cf2, state);
-+
-+	return 0;
-+}
-+
-+
- int hostapd_is_dfs_required(struct hostapd_iface *iface)
- {
- 	int n_chans, n_chans1, start_chan_idx, start_chan_idx1, res;
-diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index c2556d2..25ba29c 100644
---- a/src/ap/dfs.h
-+++ b/src/ap/dfs.h
-@@ -30,6 +30,9 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
- int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
- 			     int ht_enabled,
- 			     int chan_offset, int chan_width, int cf1, int cf2);
-+int hostapd_dfs_sta_update_state(struct hostapd_iface *iface, int freq,
-+				 int ht_enabled, int chan_offset, int chan_width,
-+				 int cf1, int cf2, u32 state);
- int hostapd_is_dfs_required(struct hostapd_iface *iface);
- int hostapd_is_dfs_chan_available(struct hostapd_iface *iface);
- int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
-diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index f6093c1..e7f1f19 100644
---- a/src/ap/drv_callbacks.c
-+++ b/src/ap/drv_callbacks.c
-@@ -2086,6 +2086,24 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
- 			      radar->cf1, radar->cf2);
- }
- 
-+static void hostapd_event_dfs_sta_cac_skipped(struct hostapd_data *hapd,
-+					      struct dfs_event *radar)
-+{
-+	wpa_printf(MSG_DEBUG, "DFS CAC skipped (by STA) on %d MHz", radar->freq);
-+	hostapd_dfs_sta_update_state(hapd->iface, radar->freq, radar->ht_enabled,
-+				     radar->chan_offset, radar->chan_width,
-+				     radar->cf1, radar->cf2, HOSTAPD_CHAN_DFS_AVAILABLE);
-+}
-+
-+static void hostapd_event_dfs_sta_cac_expired(struct hostapd_data *hapd,
-+					      struct dfs_event *radar)
-+{
-+	wpa_printf(MSG_DEBUG, "DFS CAC expired (by STA) on %d MHz", radar->freq);
-+	hostapd_dfs_sta_update_state(hapd->iface, radar->freq, radar->ht_enabled,
-+				     radar->chan_offset, radar->chan_width,
-+				     radar->cf1, radar->cf2, HOSTAPD_CHAN_DFS_USABLE);
-+}
-+
- #endif /* NEED_AP_MLME */
- 
- 
-@@ -2407,6 +2425,16 @@ void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
- 			break;
- 		hostapd_event_dfs_nop_finished(hapd, &data->dfs_event);
- 		break;
-+	case EVENT_DFS_STA_CAC_SKIPPED:
-+		if (!data)
-+			break;
-+		hostapd_event_dfs_sta_cac_skipped(hapd, &data->dfs_event);
-+		break;
-+	case EVENT_DFS_STA_CAC_EXPIRED:
-+		if (!data)
-+			break;
-+		hostapd_event_dfs_sta_cac_expired(hapd, &data->dfs_event);
-+		break;
- 	case EVENT_CHANNEL_LIST_CHANGED:
- 		/* channel list changed (regulatory?), update channel list */
- 		/* TODO: check this. hostapd_get_hw_features() initializes
-diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
-index 416e0d6..62f042e 100644
---- a/src/common/wpa_ctrl.h
-+++ b/src/common/wpa_ctrl.h
-@@ -374,6 +374,7 @@ extern "C" {
- #define DFS_EVENT_CAC_COMPLETED "DFS-CAC-COMPLETED "
- #define DFS_EVENT_NOP_FINISHED "DFS-NOP-FINISHED "
- #define DFS_EVENT_PRE_CAC_EXPIRED "DFS-PRE-CAC-EXPIRED "
-+#define DFS_EVENT_STA_UPDATE "DFS-STA-UPDATE "
- 
- #define AP_CSA_FINISHED "AP-CSA-FINISHED "
- 
-diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 38f6e8b..0469694 100644
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -5782,6 +5782,20 @@ enum wpa_event_type {
- 	 * EVENT_LINK_RECONFIG - Notification that AP links removed
- 	 */
- 	EVENT_LINK_RECONFIG,
-+
-+	/**
-+	 * EVENT_DFS_STA_CAC_SKIPPED - Notification that CAC has been skipped
-+	 *
-+	 * The channel in the notification is now marked as available.
-+	 */
-+	EVENT_DFS_STA_CAC_SKIPPED,
-+
-+	/**
-+	 * EVENT_DFS_STA_CAC_EXPIRED - Notification that CAC has expired
-+	 *
-+	 * The channel in the notification is now marked as usable.
-+	 */
-+	EVENT_DFS_STA_CAC_EXPIRED,
- };
- 
- 
-diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
-index 701c32e..63d4401 100644
---- a/src/drivers/driver_nl80211_event.c
-+++ b/src/drivers/driver_nl80211_event.c
-@@ -2514,6 +2514,12 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
- 	case NL80211_RADAR_CAC_STARTED:
- 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
- 		break;
-+	case NL80211_RADAR_STA_CAC_SKIPPED:
-+		wpa_supplicant_event(drv->ctx, EVENT_DFS_STA_CAC_SKIPPED, &data);
-+		break;
-+	case NL80211_RADAR_STA_CAC_EXPIRED:
-+		wpa_supplicant_event(drv->ctx, EVENT_DFS_STA_CAC_EXPIRED, &data);
-+		break;
- 	default:
- 		wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
- 			   "received", event_type);
-diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index 82860ae..225864b 100644
---- a/src/drivers/nl80211_copy.h
-+++ b/src/drivers/nl80211_copy.h
-@@ -6643,6 +6643,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.
-+ * @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
-+ *	when STA is disconnected or leaving the channel
-  */
- enum nl80211_radar_event {
- 	NL80211_RADAR_DETECTED,
-@@ -6651,6 +6655,8 @@ enum nl80211_radar_event {
- 	NL80211_RADAR_NOP_FINISHED,
- 	NL80211_RADAR_PRE_CAC_EXPIRED,
- 	NL80211_RADAR_CAC_STARTED,
-+	NL80211_RADAR_STA_CAC_SKIPPED,
-+	NL80211_RADAR_STA_CAC_EXPIRED,
- };
- 
- /**
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0017-mtk-hostapd-Add-sta-assisted-DFS-state-update-mechan.patch
similarity index 93%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0017-mtk-hostapd-Add-sta-assisted-DFS-state-update-mechan.patch
index e29ecce..3c36b27 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0017-mtk-hostapd-Add-sta-assisted-DFS-state-update-mechan.patch
@@ -1,7 +1,7 @@
-From aa33ef52222963f20b152120ad84b6614b8421a1 Mon Sep 17 00:00:00 2001
+From 7782f39aa86e067030ee8277c7942423c6e64389 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 10:51:47 +0800
-Subject: [PATCH 17/38] hostapd: mtk: Add sta-assisted DFS state update
+Subject: [PATCH 17/54] mtk: hostapd: Add sta-assisted DFS state update
  mechanism
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,7 +16,7 @@
  7 files changed, 78 insertions(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index cfc3508..9d002cf 100644
+index cfc350879..9d002cfad 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1513,6 +1513,26 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
@@ -47,7 +47,7 @@
  {
  	int n_chans, n_chans1, start_chan_idx, start_chan_idx1, res;
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index c2556d2..25ba29c 100644
+index c2556d2d9..25ba29ca1 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -30,6 +30,9 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
@@ -61,7 +61,7 @@
  int hostapd_is_dfs_chan_available(struct hostapd_iface *iface);
  int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index f6093c1..e7f1f19 100644
+index f6093c11c..e7f1f19ce 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
 @@ -2086,6 +2086,24 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
@@ -107,7 +107,7 @@
  		/* channel list changed (regulatory?), update channel list */
  		/* TODO: check this. hostapd_get_hw_features() initializes
 diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
-index 416e0d6..62f042e 100644
+index 416e0d6a8..62f042e05 100644
 --- a/src/common/wpa_ctrl.h
 +++ b/src/common/wpa_ctrl.h
 @@ -374,6 +374,7 @@ extern "C" {
@@ -119,10 +119,10 @@
  #define AP_CSA_FINISHED "AP-CSA-FINISHED "
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 38f6e8b..0469694 100644
+index 577c34c07..24ab656fa 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5782,6 +5782,20 @@ enum wpa_event_type {
+@@ -5785,6 +5785,20 @@ enum wpa_event_type {
  	 * EVENT_LINK_RECONFIG - Notification that AP links removed
  	 */
  	EVENT_LINK_RECONFIG,
@@ -144,7 +144,7 @@
  
  
 diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
-index 701c32e..63d4401 100644
+index 701c32e7b..63d44017c 100644
 --- a/src/drivers/driver_nl80211_event.c
 +++ b/src/drivers/driver_nl80211_event.c
 @@ -2514,6 +2514,12 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
@@ -161,7 +161,7 @@
  		wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
  			   "received", event_type);
 diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index 82860ae..225864b 100644
+index 82860ae32..225864b94 100644
 --- a/src/drivers/nl80211_copy.h
 +++ b/src/drivers/nl80211_copy.h
 @@ -6643,6 +6643,10 @@ enum nl80211_smps_mode {
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-mtk-hostapd-Mark-DFS-channel-as-available-for-CSA.patch
similarity index 90%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-mtk-hostapd-Mark-DFS-channel-as-available-for-CSA.patch
index c2296fb..ef35c2d 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-mtk-hostapd-Mark-DFS-channel-as-available-for-CSA.patch
@@ -1,7 +1,7 @@
-From f3a98bc033de56fee900d0da3a33775165b714ad Mon Sep 17 00:00:00 2001
+From 8a52855a8e3425d62b7ffba05ccf1ddd08223f78 Mon Sep 17 00:00:00 2001
 From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
 Date: Fri, 3 Mar 2023 12:45:42 +0800
-Subject: [PATCH 18/38] hostapd: mtk: Mark DFS channel as available for CSA.
+Subject: [PATCH 18/54] mtk: hostapd: Mark DFS channel as available for CSA.
 
 ---
  hostapd/ctrl_iface.c   | 10 ++++++++++
@@ -10,7 +10,7 @@
  3 files changed, 12 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c54cbb9..aab5c0a 100644
+index 57addb22d..ba2137969 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -2751,6 +2751,16 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
@@ -31,7 +31,7 @@
  		dfs_range += hostapd_is_dfs_overlap(
  			iface, bandwidth, settings.freq_params.center_freq1);
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index d593730..0a374be 100644
+index d59373062..0a374be8e 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1715,7 +1715,7 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
@@ -44,7 +44,7 @@
  	{ "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL,
  	  "<addr> <url>\n"
 diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
-index 0e173f1..7bdefb4 100644
+index 0e173f174..7bdefb4cf 100644
 --- a/src/ap/ctrl_iface_ap.c
 +++ b/src/ap/ctrl_iface_ap.c
 @@ -1014,6 +1014,7 @@ int hostapd_parse_csa_settings(const char *pos,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0019-hostapd-mtk-Add-available-color-bitmap.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0019-mtk-hostapd-Add-available-color-bitmap.patch
similarity index 94%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0019-hostapd-mtk-Add-available-color-bitmap.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0019-mtk-hostapd-Add-available-color-bitmap.patch
index d4ce7cc..4f2c43b 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0019-hostapd-mtk-Add-available-color-bitmap.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0019-mtk-hostapd-Add-available-color-bitmap.patch
@@ -1,7 +1,7 @@
-From d77b2e1d3821e51f557f1292a0ccaa0a211ea11f Mon Sep 17 00:00:00 2001
+From 41e104c896bfa30a027924302a39401245e02767 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Thu, 26 Jan 2023 09:16:00 +0800
-Subject: [PATCH 19/38] hostapd: mtk: Add available color bitmap
+Subject: [PATCH 19/54] mtk: hostapd: Add available color bitmap
 
 Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 ---
@@ -17,10 +17,10 @@
  9 files changed, 324 insertions(+), 2 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index aab5c0a..a6be199 100644
+index ba2137969..e45e574be 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3692,6 +3692,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
+@@ -3696,6 +3696,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
  	return ret;
  }
  
@@ -97,7 +97,7 @@
  
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
-@@ -4266,6 +4336,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4270,6 +4340,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
  	} else if (os_strncmp(buf, "GET_AMSDU", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
@@ -109,7 +109,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 0a374be..e9e156d 100644
+index 0a374be8e..e9e156d28 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1598,6 +1598,20 @@ static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,
@@ -145,7 +145,7 @@
  	{ "driver", hostapd_cli_cmd_driver, NULL,
  	  "<driver sub command> [<hex formatted data>] = send driver command data" },
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index a7226cf..9615ca8 100644
+index a7226cfa9..9615ca8ce 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1213,4 +1213,12 @@ int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu)
@@ -164,7 +164,7 @@
 +	return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 88bc430..ecaa71f 100644
+index 88bc430d2..ecaa71f99 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -155,6 +155,8 @@ int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
@@ -177,7 +177,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index ace993b..e27fe69 100644
+index ace993bc8..e27fe69b3 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -15,6 +15,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -206,10 +206,10 @@
  #define CSI_MAX_COUNT 256
  #define ETH_ALEN 6
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 0469694..130143e 100644
+index 24ab656fa..869b0442f 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5155,6 +5155,14 @@ struct wpa_driver_ops {
+@@ -5158,6 +5158,14 @@ struct wpa_driver_ops {
  	 */
  	int (*amsdu_ctrl)(void *priv, u8 amsdu);
  	int (*amsdu_dump)(void *priv, u8 *amsdu);
@@ -225,10 +225,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 808db17..ee0912f 100644
+index c1e3fcb69..7b5a50ea6 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -12849,7 +12849,6 @@ static void nl80211_parse_btm_candidate_info(struct candidate_list *candidate,
+@@ -12869,7 +12869,6 @@ static void nl80211_parse_btm_candidate_info(struct candidate_list *candidate,
  		   num, MAC2STR(candidate->bssid), buf);
  }
  
@@ -236,7 +236,7 @@
  static int
  nl80211_get_bss_transition_status_handler(struct nl_msg *msg, void *arg)
  {
-@@ -14277,6 +14276,203 @@ fail:
+@@ -14297,6 +14296,203 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -440,14 +440,14 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14443,4 +14639,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14463,4 +14659,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.ibf_dump = nl80211_ibf_dump,
  	.amsdu_ctrl = nl80211_enable_amsdu,
  	.amsdu_dump = nl80211_dump_amsdu,
 +	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 0100314..fd1e57c 100644
+index 0100314ba..fd1e57cc2 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -207,6 +207,7 @@ struct wpa_driver_nl80211_data {
@@ -459,10 +459,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index f14706d..4f8e920 100644
+index 0e70b7321..3e8eb8cb1 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1125,6 +1125,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1129,6 +1129,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL:
  					drv->mtk_wireless_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch
deleted file mode 100644
index 84087de..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch
+++ /dev/null
@@ -1,210 +0,0 @@
-From 181312213a4e8a04be652734ae3ffad12c45b8ae Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Mon, 20 Mar 2023 16:08:30 +0800
-Subject: [PATCH 20/38] hostapd: mtk: Fix ZWDFS issue in BW 160
-
-When background radar is enabled and bandwidth is set to 160, AP will
-fail to startup due to the lack of non-DFS channel.
-Under this circumstance, AP should perform CAC itself, and the background
-chain could also perform CAC simultaneously.
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- src/ap/dfs.c | 98 ++++++++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 79 insertions(+), 19 deletions(-)
-
-diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 9d002cf..3b1df6d 100644
---- a/src/ap/dfs.c
-+++ b/src/ap/dfs.c
-@@ -69,15 +69,22 @@ static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
- static int dfs_channel_available(struct hostapd_channel_data *chan,
- 				 enum dfs_channel_type type)
- {
-+	int dfs_status = chan->flag & HOSTAPD_CHAN_DFS_MASK;
-+
-+	if (chan->flag & HOSTAPD_CHAN_DISABLED)
-+		return -1;
-+
- 	if (type == DFS_NO_CAC_YET) {
- 		/* Select only radar channel where CAC has not been
- 		 * performed yet
- 		 */
--		if ((chan->flag & HOSTAPD_CHAN_RADAR) &&
--		    (chan->flag & HOSTAPD_CHAN_DFS_MASK) ==
--		     HOSTAPD_CHAN_DFS_USABLE)
-+		if (!(chan->flag & HOSTAPD_CHAN_RADAR))
-+			return 0;
-+
-+		if (dfs_status == HOSTAPD_CHAN_DFS_USABLE)
- 			return 1;
--		return 0;
-+
-+		return -1;
- 	}
- 
- 	/*
-@@ -86,16 +93,14 @@ static int dfs_channel_available(struct hostapd_channel_data *chan,
- 	 * channel for CSA, unless they are available for immediate use.
- 	 */
- 	if (type == DFS_AVAILABLE && (chan->flag & HOSTAPD_CHAN_RADAR) &&
--	    ((chan->flag & HOSTAPD_CHAN_DFS_MASK) !=
--	     HOSTAPD_CHAN_DFS_AVAILABLE))
--		return 0;
-+	    (dfs_status != HOSTAPD_CHAN_DFS_AVAILABLE))
-+		return -1;
- 
--	if (chan->flag & HOSTAPD_CHAN_DISABLED)
--		return 0;
- 	if ((chan->flag & HOSTAPD_CHAN_RADAR) &&
--	    ((chan->flag & HOSTAPD_CHAN_DFS_MASK) ==
--	     HOSTAPD_CHAN_DFS_UNAVAILABLE))
--		return 0;
-+	    ((dfs_status == HOSTAPD_CHAN_DFS_UNAVAILABLE) ||
-+	    (dfs_status == HOSTAPD_CHAN_DFS_UNKNOWN)))
-+		return -1;
-+
- 	return 1;
- }
- 
-@@ -167,7 +172,7 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
- 				    enum dfs_channel_type type)
- {
- 	struct hostapd_channel_data *first_chan, *chan;
--	int i;
-+	int i, available = 0, ret = 0;
- 	u32 bw = num_chan_to_bw(num_chans);
- 
- 	if (first_chan_idx + num_chans > mode->num_channels) {
-@@ -203,14 +208,17 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
- 			return 0;
- 		}
- 
--		if (!dfs_channel_available(chan, type)) {
-+		ret = dfs_channel_available(chan, type);
-+		if (ret < 0) {
- 			wpa_printf(MSG_DEBUG, "DFS: channel not available %d",
- 				   first_chan->freq + i * 20);
- 			return 0;
- 		}
-+
-+		available |= ret;
- 	}
- 
--	return 1;
-+	return available;
- }
- 
- 
-@@ -836,8 +844,12 @@ static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
-  */
- int hostapd_handle_dfs(struct hostapd_iface *iface)
- {
-+	struct hostapd_channel_data *channel;
- 	int res, n_chans, n_chans1, start_chan_idx, start_chan_idx1;
--	int skip_radar = 0;
-+	int sec = 0, skip_radar = 0;
-+	u8 cf1 = 0, cf2 = 0;
-+	bool use_radar_background = dfs_use_radar_background(iface);
-+	enum dfs_channel_type channel_type = DFS_NO_CAC_YET;
- 
- 	if (is_6ghz_freq(iface->freq))
- 		return 1;
-@@ -900,7 +912,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
- 	/* Finally start CAC */
- 	hostapd_set_state(iface, HAPD_IFACE_DFS);
- 	wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz%s", iface->freq,
--		   dfs_use_radar_background(iface) ? " (background)" : "");
-+		   use_radar_background ? " (background)" : "");
- 	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
- 		"freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds",
- 		iface->freq,
-@@ -910,6 +922,16 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
- 		hostapd_get_oper_centr_freq_seg1_idx(iface->conf),
- 		iface->dfs_cac_ms / 1000);
- 
-+	if (use_radar_background) {
-+		channel = dfs_get_valid_channel(iface, &sec, &cf1, &cf2, DFS_AVAILABLE);
-+		/*
-+		 * AP cannot get any random available channel.
-+		 * Let AP and dedicated radar chain both perform CAC.
-+		 */
-+		if (!channel)
-+			use_radar_background = false;
-+	}
-+
- 	res = hostapd_start_dfs_cac(
- 		iface, iface->conf->hw_mode, iface->freq, iface->conf->channel,
- 		iface->conf->ieee80211n, iface->conf->ieee80211ac,
-@@ -918,14 +940,14 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
- 		hostapd_get_oper_chwidth(iface->conf),
- 		hostapd_get_oper_centr_freq_seg0_idx(iface->conf),
- 		hostapd_get_oper_centr_freq_seg1_idx(iface->conf),
--		dfs_use_radar_background(iface));
-+		use_radar_background);
- 
- 	if (res) {
- 		wpa_printf(MSG_ERROR, "DFS start_dfs_cac() failed, %d", res);
- 		return -1;
- 	}
- 
--	if (dfs_use_radar_background(iface)) {
-+	if (use_radar_background) {
- 		/* Cache background radar parameters. */
- 		iface->radar_background.channel = iface->conf->channel;
- 		iface->radar_background.secondary_channel =
-@@ -946,6 +968,35 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
- 
- 		iface->radar_background.temp_ch = 1;
- 		return 1;
-+	} else if (dfs_use_radar_background(iface)) {
-+		if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI)
-+			channel_type = DFS_ANY_CHANNEL;
-+
-+		channel = dfs_get_valid_channel(iface, &sec, &cf1, &cf2, channel_type);
-+
-+		if (!channel ||
-+		    (channel->chan == iface->conf->channel &&
-+		    cf1 == hostapd_get_oper_centr_freq_seg0_idx(iface->conf) &&
-+		    cf2 == hostapd_get_oper_centr_freq_seg1_idx(iface->conf))) {
-+			wpa_printf(MSG_ERROR, "Background radar could not get valid channel\n");
-+			iface->radar_background.channel = -1;
-+			return 0;
-+		}
-+
-+		hostapd_start_dfs_cac(iface, iface->conf->hw_mode,
-+				      channel->freq, channel->chan,
-+				      iface->conf->ieee80211n,
-+				      iface->conf->ieee80211ac,
-+				      iface->conf->ieee80211ax,
-+				      iface->conf->ieee80211be,
-+				      sec, hostapd_get_oper_chwidth(iface->conf),
-+				      cf1, cf2, true);
-+
-+		iface->radar_background.channel = channel->chan;
-+		iface->radar_background.freq = channel->freq;
-+		iface->radar_background.secondary_channel = sec;
-+		iface->radar_background.centr_freq_seg0_idx = cf1;
-+		iface->radar_background.centr_freq_seg1_idx = cf2;
- 	}
- 
- 	return 0;
-@@ -1195,6 +1246,15 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
- 				hostapd_setup_interface_complete(iface, 0);
- 				iface->cac_started = 0;
- 			}
-+
-+			/*
-+			 * When background radar is enabled but the CAC completion
-+			 * is not received from the background chain.
-+			 * Then, reset radar background chain.
-+			 */
-+			if (dfs_use_radar_background(iface) &&
-+			    iface->radar_background.channel == -1)
-+				hostpad_dfs_update_background_chain(iface);
- 		}
- 	} else if (hostapd_dfs_is_background_event(iface, freq)) {
- 		iface->radar_background.cac_started = 0;
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0020-mtk-hostapd-Fix-ZWDFS-issue-in-BW-160.patch
similarity index 97%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0020-mtk-hostapd-Fix-ZWDFS-issue-in-BW-160.patch
index 84087de..3e30ba2 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0020-mtk-hostapd-Fix-ZWDFS-issue-in-BW-160.patch
@@ -1,7 +1,7 @@
-From 181312213a4e8a04be652734ae3ffad12c45b8ae Mon Sep 17 00:00:00 2001
+From 0e01d6aa229b84b92c9462f7101314db62857b86 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Mar 2023 16:08:30 +0800
-Subject: [PATCH 20/38] hostapd: mtk: Fix ZWDFS issue in BW 160
+Subject: [PATCH 20/54] mtk: hostapd: Fix ZWDFS issue in BW 160
 
 When background radar is enabled and bandwidth is set to 160, AP will
 fail to startup due to the lack of non-DFS channel.
@@ -14,7 +14,7 @@
  1 file changed, 79 insertions(+), 19 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 9d002cf..3b1df6d 100644
+index 9d002cfad..3b1df6dc6 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -69,15 +69,22 @@ static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
deleted file mode 100644
index c6c039e..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
+++ /dev/null
@@ -1,394 +0,0 @@
-From 3e51ee9efe44904b7b41402fd40a25d5e34614f3 Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Fri, 17 Mar 2023 16:17:14 +0800
-Subject: [PATCH 21/38] hostapd: mtk: Add vendor for CAPI certification
- commands
-
----
- hostapd/ctrl_iface.c              | 97 +++++++++++++++++++++++++++++++
- src/ap/ap_drv_ops.c               | 21 +++++++
- src/ap/ap_drv_ops.h               |  3 +
- src/common/mtk_vendor.h           | 33 +----------
- src/drivers/driver.h              | 22 +++++++
- src/drivers/driver_nl80211.c      | 55 ++++++++++++++++++
- src/drivers/driver_nl80211.h      |  1 +
- src/drivers/driver_nl80211_capa.c |  3 +
- 8 files changed, 204 insertions(+), 31 deletions(-)
-
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index a6be199..92c94c0 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -69,6 +69,7 @@
- #include "config_file.h"
- #include "ctrl_iface.h"
- 
-+#include "common/mtk_vendor.h"
- 
- #define HOSTAPD_CLI_DUP_VALUE_MAX_LEN 256
- 
-@@ -3762,6 +3763,98 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
- 	return pos - buf;
- }
- 
-+static int
-+hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
-+					 char *buf, size_t buflen)
-+{
-+	char *pos, *value, *config = cmd;
-+	enum mtk_vendor_attr_wireless_ctrl sub_cmd;
-+
-+	pos = os_strchr(config, '=');
-+	if (pos == NULL)
-+		return -1;
-+	*pos++ = '\0';
-+
-+	if(pos == NULL)
-+		return -1;
-+	value = pos;
-+
-+	if (os_strncmp(config, "fixed_mcs", 9) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS;
-+	else if (os_strncmp(config, "ofdma", 5) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA;
-+	else if (os_strncmp(config, "ppdu_type", 9) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE;
-+	else if (os_strncmp(config, "nusers_ofdma", 12) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA;
-+	else if (os_strncmp(config, "add_ba_req_bufsize", 18) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE;
-+	else if (os_strncmp(config, "mimo", 4) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO;
-+	else if (os_strncmp(config, "cert", 4) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT ;
-+	else if (os_strncmp(config, "amsdu", 5) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU;
-+	else {
-+		wpa_printf(MSG_ERROR,
-+			"Unsupported parameter %s for ap_wireless", config);
-+		return -1;
-+	}
-+
-+	if (hostapd_drv_ap_wireless(hapd, (u8) sub_cmd, atoi(value)) != 0)
-+		return -1;
-+
-+	return os_snprintf(buf, buflen, "OK\n");
-+}
-+
-+static int
-+hostapd_ctrl_iface_ap_rfeatures(struct hostapd_data *hapd, char *cmd,
-+					 char *buf, size_t buflen)
-+{
-+	char *pos, *value, *type, *config = cmd;
-+	enum mtk_vendor_attr_rfeature_ctrl sub_cmd;
-+
-+	pos = os_strchr(config, '=');
-+	if (pos == NULL)
-+		return -1;
-+	*pos++ = '\0';
-+
-+	if(pos == NULL)
-+		return -1;
-+	value = pos;
-+
-+	if (os_strncmp(config, "he_gi", 5) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI;
-+	else if (os_strncmp(config, "he_ltf", 6) == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF;
-+	else if (os_strncmp(config, "trig_type", 9) == 0) {
-+		pos = os_strchr(value, ',');
-+		if (pos == NULL)
-+			return -1;
-+		*pos++ = '\0';
-+		if(pos == NULL)
-+			return -1;
-+		type = pos;
-+		goto trigtype;
-+	} else if (os_strcmp(config, "ack_policy") == 0)
-+		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY;
-+	else {
-+		wpa_printf(MSG_ERROR,
-+			"Unsupported parameter %s for ap_rfeatures", config);
-+		return -1;
-+	}
-+
-+	if (hostapd_drv_ap_rfeatures(hapd, (u8) sub_cmd, atoi(value)) != 0)
-+		return -1;
-+	goto exit;
-+
-+trigtype:
-+	if (hostapd_drv_ap_trig_type(hapd, atoi(value), atoi(type)) != 0)
-+		return -1;
-+
-+exit:
-+	return os_snprintf(buf, buflen, "OK\n");
-+}
- 
- static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 					      char *buf, char *reply,
-@@ -4340,6 +4433,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 		reply_len = hostapd_ctrl_iface_get_bss_color(hapd, reply, reply_size);
- 	} else if (os_strncmp(buf, "AVAL_COLOR_BMP", 14) == 0) {
- 		reply_len = hostapd_ctrl_iface_get_aval_color_bmp(hapd, reply, reply_size);
-+	} else if (os_strncmp(buf, "ap_wireless ", 12) == 0) {
-+		reply_len = hostapd_ctrl_iface_ap_wireless(hapd, buf + 12, reply, reply_size);
-+	} else if (os_strncmp(buf, "ap_rfeatures ", 13) == 0) {
-+		reply_len = hostapd_ctrl_iface_ap_rfeatures(hapd, buf + 13, reply, reply_size);
- 	} else {
- 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
- 		reply_len = 16;
-diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 9615ca8..11444c7 100644
---- a/src/ap/ap_drv_ops.c
-+++ b/src/ap/ap_drv_ops.c
-@@ -1222,3 +1222,24 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
- 		return 0;
- 	return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
- }
-+
-+int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
-+{
-+	if (!hapd->driver || !hapd->driver->ap_wireless)
-+		return 0;
-+	return hapd->driver->ap_wireless(hapd->drv_priv, sub_vendor_id, value);
-+}
-+
-+int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
-+{
-+	if (!hapd->driver || !hapd->driver->ap_rfeatures)
-+		return 0;
-+	return hapd->driver->ap_rfeatures(hapd->drv_priv, sub_vendor_id, value);
-+}
-+
-+int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type)
-+{
-+	if (!hapd->driver || !hapd->driver->ap_trigtype)
-+		return 0;
-+	return hapd->driver->ap_trigtype(hapd->drv_priv, enable, type);
-+}
-diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index ecaa71f..32e6fc1 100644
---- a/src/ap/ap_drv_ops.h
-+++ b/src/ap/ap_drv_ops.h
-@@ -157,6 +157,9 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
- int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu);
- int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd,
- 				       u64 *aval_color_bmp);
-+int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
-+int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
-+int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
- 
- #include "drivers/driver.h"
- 
-diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index e27fe69..0b23c76 100644
---- a/src/common/mtk_vendor.h
-+++ b/src/common/mtk_vendor.h
-@@ -50,17 +50,6 @@ enum mtk_vendor_attr_edcca_dump {
- 		NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP - 1
- };
- 
--
--static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
--	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
--	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
--	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
--	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
--	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
--	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
--	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC160_VAL] = { .type = NLA_U8 },
--};
--
- enum mtk_vendor_attr_3wire_ctrl {
- 	MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC,
- 
-@@ -72,10 +61,6 @@ enum mtk_vendor_attr_3wire_ctrl {
- 		NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1
- };
- 
--static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
--	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
--};
--
- enum mtk_vendor_attr_csi_ctrl {
- 	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
- 
-@@ -172,7 +157,7 @@ enum mtk_vendor_attr_wireless_ctrl {
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
--	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT,
-+	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
- 	MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA,
- 
- 	/* keep last */
-@@ -192,11 +177,6 @@ enum mtk_vendor_attr_wireless_dump {
- 		NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
- };
- 
--static const struct nla_policy
--wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
--	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
--};
--
- enum mtk_vendor_attr_rfeature_ctrl {
- 	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
- 
-@@ -206,6 +186,7 @@ enum mtk_vendor_attr_rfeature_ctrl {
- 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
- 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
- 	MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
-+	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
- 
- 	/* keep last */
- 	NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
-@@ -247,16 +228,6 @@ enum mtk_vendor_attr_ibf_dump {
- 		NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
- };
- 
--static struct nla_policy
--ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
--	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
--};
--
--static struct nla_policy
--ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
--	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
--};
--
- enum mtk_vendor_attr_bss_color_ctrl {
- 	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
- 
-diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 130143e..91aa9b1 100644
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -5163,6 +5163,28 @@ struct wpa_driver_ops {
- 	 *
- 	 */
- 	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
-+
-+	/**
-+	* ap_wireless - set wireless command
-+	* @priv: Private driver interface data
-+	* @value: value
-+	*/
-+	int (*ap_wireless)(void *priv, u8 mode, int value);
-+
-+	/**
-+	* ap_rfeatures - set ap rf features command
-+	* @priv: Private driver interface data
-+	* @value: value
-+	*/
-+	int (*ap_rfeatures)(void *priv, u8 mode, int value);
-+
-+	/**
-+	* ap_trigtype - set trigger type
-+	* @priv: Private driver interface data
-+	* @enable: enable or disable
-+	* @type: trigger type
-+	*/
-+	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
- };
- 
- /**
-diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index ee0912f..592435c 100644
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -76,6 +76,58 @@ enum nlmsgerr_attrs {
- #endif /* ANDROID */
- 
- 
-+static struct nla_policy
-+ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
-+	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
-+};
-+
-+static struct nla_policy
-+ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
-+	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
-+};
-+
-+static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
-+	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
-+};
-+
-+static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
-+	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC160_VAL] = { .type = NLA_U8 },
-+};
-+
-+static const struct nla_policy
-+wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
-+	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
-+};
-+
-+static const struct nla_policy
-+rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
-+	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
-+	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
-+};
-+
-+static const struct nla_policy
-+wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
-+	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA] = {.type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
-+	[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU] = {.type = NLA_U8 },
-+	[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
-+};
-+
- static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
- {
- 	struct nl_sock *handle;
-@@ -14640,4 +14692,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.amsdu_ctrl = nl80211_enable_amsdu,
- 	.amsdu_dump = nl80211_dump_amsdu,
- 	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
-+	.ap_wireless = nl80211_ap_wireless,
-+	.ap_rfeatures = nl80211_ap_rfeatures,
-+	.ap_trigtype = nl80211_ap_trigtype,
- };
-diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index fd1e57c..fc5217d 100644
---- a/src/drivers/driver_nl80211.h
-+++ b/src/drivers/driver_nl80211.h
-@@ -208,6 +208,7 @@ struct wpa_driver_nl80211_data {
- 	unsigned int mtk_ibf_vendor_cmd_avail:1;
- 	unsigned int mtk_wireless_vendor_cmd_avail:1;
- 	unsigned int mtk_bss_color_vendor_cmd_avail:1;
-+	unsigned int mtk_rfeatures_vendor_cmd_avail:1;
- 
- 	u64 vendor_scan_cookie;
- 	u64 remain_on_chan_cookie;
-diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 4f8e920..c1cf5b5 100644
---- a/src/drivers/driver_nl80211_capa.c
-+++ b/src/drivers/driver_nl80211_capa.c
-@@ -1128,6 +1128,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
- 				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
- 					drv->mtk_bss_color_vendor_cmd_avail = 1;
- 					break;
-+				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
-+					drv->mtk_rfeatures_vendor_cmd_avail = 1;
-+					break;
- 				}
- 			}
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0021-mtk-hostapd-Add-vendor-for-CAPI-certification-comman.patch
similarity index 91%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0021-mtk-hostapd-Add-vendor-for-CAPI-certification-comman.patch
index c6c039e..804aa16 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0021-mtk-hostapd-Add-vendor-for-CAPI-certification-comman.patch
@@ -1,22 +1,22 @@
-From 3e51ee9efe44904b7b41402fd40a25d5e34614f3 Mon Sep 17 00:00:00 2001
+From 6dee226e8db428c4434115b4c792f7ffd8a759dd Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 17 Mar 2023 16:17:14 +0800
-Subject: [PATCH 21/38] hostapd: mtk: Add vendor for CAPI certification
+Subject: [PATCH 21/54] mtk: hostapd: Add vendor for CAPI certification
  commands
 
 ---
- hostapd/ctrl_iface.c              | 97 +++++++++++++++++++++++++++++++
+ hostapd/ctrl_iface.c              | 99 +++++++++++++++++++++++++++++++
  src/ap/ap_drv_ops.c               | 21 +++++++
  src/ap/ap_drv_ops.h               |  3 +
  src/common/mtk_vendor.h           | 33 +----------
  src/drivers/driver.h              | 22 +++++++
- src/drivers/driver_nl80211.c      | 55 ++++++++++++++++++
+ src/drivers/driver_nl80211.c      | 55 +++++++++++++++++
  src/drivers/driver_nl80211.h      |  1 +
  src/drivers/driver_nl80211_capa.c |  3 +
- 8 files changed, 204 insertions(+), 31 deletions(-)
+ 8 files changed, 206 insertions(+), 31 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index a6be199..92c94c0 100644
+index e45e574be..05606eb43 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -69,6 +69,7 @@
@@ -27,7 +27,7 @@
  
  #define HOSTAPD_CLI_DUP_VALUE_MAX_LEN 256
  
-@@ -3762,6 +3763,98 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
+@@ -3766,6 +3767,100 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
  	return pos - buf;
  }
  
@@ -63,6 +63,8 @@
 +		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT ;
 +	else if (os_strncmp(config, "amsdu", 5) == 0)
 +		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU;
++	else if (os_strncmp(config, "rts_sigta", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA;
 +	else {
 +		wpa_printf(MSG_ERROR,
 +			"Unsupported parameter %s for ap_wireless", config);
@@ -126,7 +128,7 @@
  
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
-@@ -4340,6 +4433,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4344,6 +4439,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_get_bss_color(hapd, reply, reply_size);
  	} else if (os_strncmp(buf, "AVAL_COLOR_BMP", 14) == 0) {
  		reply_len = hostapd_ctrl_iface_get_aval_color_bmp(hapd, reply, reply_size);
@@ -138,7 +140,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 9615ca8..11444c7 100644
+index 9615ca8ce..11444c7eb 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1222,3 +1222,24 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
@@ -167,7 +169,7 @@
 +	return hapd->driver->ap_trigtype(hapd->drv_priv, enable, type);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index ecaa71f..32e6fc1 100644
+index ecaa71f99..32e6fc151 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -157,6 +157,9 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
@@ -181,7 +183,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index e27fe69..0b23c76 100644
+index e27fe69b3..0b23c76ad 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -50,17 +50,6 @@ enum mtk_vendor_attr_edcca_dump {
@@ -260,10 +262,10 @@
  	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 130143e..91aa9b1 100644
+index 869b0442f..2ef1a3fcd 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5163,6 +5163,28 @@ struct wpa_driver_ops {
+@@ -5166,6 +5166,28 @@ struct wpa_driver_ops {
  	 *
  	 */
  	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
@@ -293,12 +295,12 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index ee0912f..592435c 100644
+index 7b5a50ea6..3ee3ec1eb 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -76,6 +76,58 @@ enum nlmsgerr_attrs {
- #endif /* ANDROID */
- 
+@@ -86,6 +86,58 @@ static void handle_nl_debug_hook(struct nl_msg *msg, int tx)
+ 	wpa_netlink_hook(tx, nlh, nlh->nlmsg_len);
+ }
  
 +static struct nla_policy
 +ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
@@ -355,7 +357,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14640,4 +14692,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14660,4 +14712,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.amsdu_ctrl = nl80211_enable_amsdu,
  	.amsdu_dump = nl80211_dump_amsdu,
  	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
@@ -364,7 +366,7 @@
 +	.ap_trigtype = nl80211_ap_trigtype,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index fd1e57c..fc5217d 100644
+index fd1e57cc2..fc5217d61 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -208,6 +208,7 @@ struct wpa_driver_nl80211_data {
@@ -376,10 +378,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 4f8e920..c1cf5b5 100644
+index 3e8eb8cb1..16306a121 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1128,6 +1128,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1132,6 +1132,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
  					drv->mtk_bss_color_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0022-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0022-mtk-hostapd-Air-Monitor-support-in-hostapd-by-vendor.patch
similarity index 94%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0022-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0022-mtk-hostapd-Air-Monitor-support-in-hostapd-by-vendor.patch
index 7808d50..e2d1e7f 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0022-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0022-mtk-hostapd-Air-Monitor-support-in-hostapd-by-vendor.patch
@@ -1,7 +1,7 @@
-From 8fe238bed8756a0015567c41b9c31577755d1015 Mon Sep 17 00:00:00 2001
+From 8a578ff51002e783b4d9a64d24402c78529b244b Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 12 May 2023 05:18:48 +0800
-Subject: [PATCH 22/38] hostapd: mtk: Air Monitor support in hostapd by vendor
+Subject: [PATCH 22/54] mtk: hostapd: Air Monitor support in hostapd by vendor
 
 Signed-off-by: mtk23888 <dipanshu.mittal@mediatek.com>
 ---
@@ -17,10 +17,10 @@
  9 files changed, 352 insertions(+)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 92c94c0..1bb64ea 100644
+index 05606eb43..ab2768e76 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3803,6 +3803,44 @@ hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
+@@ -3809,6 +3809,44 @@ hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
  
  	if (hostapd_drv_ap_wireless(hapd, (u8) sub_cmd, atoi(value)) != 0)
  		return -1;
@@ -65,7 +65,7 @@
  
  	return os_snprintf(buf, buflen, "OK\n");
  }
-@@ -3856,6 +3894,75 @@ exit:
+@@ -3862,6 +3900,75 @@ exit:
  	return os_snprintf(buf, buflen, "OK\n");
  }
  
@@ -141,7 +141,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4437,6 +4544,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4443,6 +4550,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_ap_wireless(hapd, buf + 12, reply, reply_size);
  	} else if (os_strncmp(buf, "ap_rfeatures ", 13) == 0) {
  		reply_len = hostapd_ctrl_iface_ap_rfeatures(hapd, buf + 13, reply, reply_size);
@@ -155,7 +155,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index e9e156d..6d763f3 100644
+index e9e156d28..6d763f327 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1633,6 +1633,17 @@ static int hostapd_cli_cmd_get_amsdu(struct wpa_ctrl *ctrl, int argc,
@@ -188,7 +188,7 @@
  };
  
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 11444c7..b90dd57 100644
+index 11444c7eb..b90dd5722 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1243,3 +1243,17 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type)
@@ -210,7 +210,7 @@
 +	return hapd->driver->amnt_dump(hapd->drv_priv, amnt_idx, amnt_dump_buf);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 32e6fc1..8a97e0f 100644
+index 32e6fc151..8a97e0fea 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -161,6 +161,9 @@ int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int val
@@ -224,7 +224,7 @@
  
  int hostapd_drv_wnm_oper(struct hostapd_data *hapd,
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 0b23c76..dd1ca21 100644
+index 0b23c76ad..dd1ca2164 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -258,10 +258,18 @@ struct csi_data {
@@ -247,10 +247,10 @@
 +
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 91aa9b1..8733bb5 100644
+index 2ef1a3fcd..24c9b96df 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5185,6 +5185,22 @@ struct wpa_driver_ops {
+@@ -5188,6 +5188,22 @@ struct wpa_driver_ops {
  	* @type: trigger type
  	*/
  	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
@@ -274,10 +274,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 592435c..c55d034 100644
+index 3ee3ec1eb..3a1c32a6d 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -128,6 +128,19 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
+@@ -138,6 +138,19 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
  	[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
  };
  
@@ -297,7 +297,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14525,6 +14538,171 @@ fail:
+@@ -14545,6 +14558,171 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -469,7 +469,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14695,4 +14873,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14715,4 +14893,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.ap_wireless = nl80211_ap_wireless,
  	.ap_rfeatures = nl80211_ap_rfeatures,
  	.ap_trigtype = nl80211_ap_trigtype,
@@ -477,7 +477,7 @@
 +	.amnt_dump = nl80211_amnt_dump,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index fc5217d..0d85adf 100644
+index fc5217d61..0d85adfee 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -209,6 +209,7 @@ struct wpa_driver_nl80211_data {
@@ -489,10 +489,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index c1cf5b5..8c8b84e 100644
+index 16306a121..4bd15f348 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1127,6 +1127,8 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1131,6 +1131,8 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  					break;
  				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
  					drv->mtk_bss_color_vendor_cmd_avail = 1;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0023-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0023-mtk-hostapd-Fix-setting-wrong-seg0-index-for-5G-cent.patch
similarity index 84%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0023-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0023-mtk-hostapd-Fix-setting-wrong-seg0-index-for-5G-cent.patch
index 06ceae8..84be9e0 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0023-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0023-mtk-hostapd-Fix-setting-wrong-seg0-index-for-5G-cent.patch
@@ -1,7 +1,7 @@
-From be727db37e753f0041b2789af3ecc1eff8c0f5db Mon Sep 17 00:00:00 2001
+From da108d74412d83264355fe453a8d2ffc6f99fa86 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 12 May 2023 05:23:00 +0800
-Subject: [PATCH 23/38] hostapd: mtk: Fix setting wrong seg0 index for 5G
+Subject: [PATCH 23/54] mtk: hostapd: Fix setting wrong seg0 index for 5G
  center chan 159 BW40
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index d0e27b2..f03a957 100644
+index d0e27b28d..f03a957b7 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1308,7 +1308,8 @@ hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-muru-user-number-debug-command.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-mtk-hostapd-Add-muru-user-number-debug-command.patch
similarity index 92%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-muru-user-number-debug-command.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-mtk-hostapd-Add-muru-user-number-debug-command.patch
index 68d2e5b..d1c6e2c 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-muru-user-number-debug-command.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-mtk-hostapd-Add-muru-user-number-debug-command.patch
@@ -1,7 +1,7 @@
-From 5644beb4dc1a11a236d909d4a8f8ad4aa86c6c34 Mon Sep 17 00:00:00 2001
+From 906bc021d4e4ddd62edc985dd37d7ad61d39fdb7 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 12 May 2023 05:24:19 +0800
-Subject: [PATCH 24/38] hostapd: mtk: Add muru user number debug command
+Subject: [PATCH 24/54] mtk: hostapd: Add muru user number debug command
 
 ---
  hostapd/ctrl_iface.c         | 13 ++++++++++++-
@@ -14,7 +14,7 @@
  7 files changed, 55 insertions(+), 15 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 1bb64ea..f36c138 100644
+index ab2768e76..4515583cf 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -3398,6 +3398,8 @@ hostapd_ctrl_iface_set_edcca(struct hostapd_data *hapd, char *cmd,
@@ -58,7 +58,7 @@
  	} else {
  		return -1;
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index b90dd57..0aec9e9 100644
+index b90dd5722..0aec9e925 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1162,11 +1162,11 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
@@ -76,7 +76,7 @@
  
  int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 8a97e0f..464efba 100644
+index 8a97e0fea..464efbae1 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -148,7 +148,7 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
@@ -89,7 +89,7 @@
  int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
  int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index a166de4..28482c6 100644
+index fcf346d36..2d7fb6d39 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -57,6 +57,7 @@
@@ -110,7 +110,7 @@
  	if (hostapd_drv_three_wire_ctrl(hapd) < 0)
  		goto fail;
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index dd1ca21..99371bf 100644
+index dd1ca2164..99371bf73 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -199,6 +199,8 @@ enum mtk_vendor_attr_mu_ctrl {
@@ -133,10 +133,10 @@
 +};
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 8733bb5..a29b6ff 100644
+index 24c9b96df..83d347338 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5118,11 +5118,11 @@ struct wpa_driver_ops {
+@@ -5121,11 +5121,11 @@ struct wpa_driver_ops {
  	int (*get_edcca)(void *priv, const u8 mode, u8 *value);
  
  	/**
@@ -151,10 +151,10 @@
  
  	/**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index c55d034..fce3ec9 100644
+index 3a1c32a6d..8226bebc4 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13678,13 +13678,13 @@ fail:
+@@ -13698,13 +13698,13 @@ fail:
  
  
  #ifdef CONFIG_IEEE80211AX
@@ -170,7 +170,7 @@
  
  	if (!drv->mtk_mu_vendor_cmd_avail) {
  		wpa_printf(MSG_INFO,
-@@ -13695,17 +13695,38 @@ static int nl80211_mu_onoff(void *priv, u8 mu_onoff)
+@@ -13715,17 +13715,38 @@ static int nl80211_mu_onoff(void *priv, u8 mu_onoff)
  	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
  		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
  		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_MU_CTRL) ||
@@ -214,7 +214,7 @@
  }
  
  
-@@ -14849,7 +14870,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14869,7 +14890,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.update_connect_params = nl80211_update_connection_params,
  	.send_external_auth_status = nl80211_send_external_auth_status,
  	.set_4addr_mode = nl80211_set_4addr_mode,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0025-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0025-mtk-hostapd-add-connac3-PHY-MURU-manual-mode-config-.patch
similarity index 96%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0025-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0025-mtk-hostapd-add-connac3-PHY-MURU-manual-mode-config-.patch
index 2a2a578..db8ae73 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0025-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0025-mtk-hostapd-add-connac3-PHY-MURU-manual-mode-config-.patch
@@ -1,7 +1,7 @@
-From 033f4f509e60c698d9754057e194f4760af39845 Mon Sep 17 00:00:00 2001
+From 738370924d0153163300f44c87a68e19a5220272 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Sat, 3 Jun 2023 17:12:15 +0800
-Subject: [PATCH 25/38] hostapd: mtk: add connac3 PHY MURU manual mode config
+Subject: [PATCH 25/54] mtk: hostapd: add connac3 PHY MURU manual mode config
  support
 
 This commit supports read the following two formats to set MU/RU manual
@@ -47,7 +47,7 @@
  8 files changed, 390 insertions(+), 43 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index f36c138..c288352 100644
+index 4515583cf..ae61cf625 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
 @@ -3500,22 +3500,61 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
@@ -301,7 +301,7 @@
  }
  
  
-@@ -4534,8 +4716,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4540,8 +4722,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
  							  reply_size);
  	} else if (os_strncmp(buf, "SET_MU ", 7) == 0) {
@@ -311,7 +311,7 @@
  	} else if (os_strncmp(buf, "GET_MU", 6) == 0) {
  		reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
  	} else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
-@@ -4561,6 +4742,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4567,6 +4748,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
  							reply, reply_size);
@@ -327,7 +327,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index f03a957..7c0d12a 100644
+index f03a957b7..7c0d12a3b 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1203,6 +1203,7 @@ struct hostapd_config {
@@ -339,7 +339,7 @@
  
  enum three_wire_mode {
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 0aec9e9..721bfa0 100644
+index 0aec9e925..721bfa053 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1162,11 +1162,11 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
@@ -357,7 +357,7 @@
  
  int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 464efba..1e7ae7a 100644
+index 464efbae1..1e7ae7a8d 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -148,7 +148,7 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
@@ -370,7 +370,7 @@
  int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
  int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 28482c6..3e184b5 100644
+index 2d7fb6d39..a28466405 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2518,7 +2518,7 @@ dfs_offload:
@@ -383,7 +383,7 @@
  	if (hostapd_drv_three_wire_ctrl(hapd) < 0)
  		goto fail;
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 99371bf..e140de6 100644
+index 99371bf73..e140de60b 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -199,8 +199,11 @@ enum mtk_vendor_attr_mu_ctrl {
@@ -567,10 +567,10 @@
 +
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index a29b6ff..ebc1d27 100644
+index 83d347338..8da93e025 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5122,7 +5122,7 @@ struct wpa_driver_ops {
+@@ -5125,7 +5125,7 @@ struct wpa_driver_ops {
  	 * @priv: Private driver interface data
  	 *
  	 */
@@ -580,10 +580,10 @@
  
  	/**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index fce3ec9..25e5910 100644
+index 8226bebc4..b3897e61d 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13678,12 +13678,13 @@ fail:
+@@ -13698,12 +13698,13 @@ fail:
  
  
  #ifdef CONFIG_IEEE80211AX
@@ -598,7 +598,7 @@
  	int ret = -ENOBUFS;
  
  	if (!drv->mtk_mu_vendor_cmd_avail) {
-@@ -13700,17 +13701,16 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
+@@ -13720,17 +13721,16 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
  
  	switch (mode) {
  	case MU_CTRL_ONOFF:
@@ -623,7 +623,7 @@
  		ret = -EINVAL;
  		goto fail;
  	}
-@@ -13718,9 +13718,8 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
+@@ -13738,9 +13738,8 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
  	nla_nest_end(msg, data);
  
  	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch
deleted file mode 100644
index cc30d42..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From fac968ec3565072058dc92aa2f12e0c145a963e2 Mon Sep 17 00:00:00 2001
-From: MeiChia Chiu <meichia.chiu@mediatek.com>
-Date: Fri, 9 Jun 2023 09:03:05 +0800
-Subject: [PATCH 26/38] hostapd: mtk: Add HE capabilities check
-
-Add HE capabilities check.
-Since "HE capabilities" check has been removed by driver,
-add the support for "HE capabilities" check in hostapd.
----
- src/ap/hw_features.c | 26 ++++++++++++++++++++++++++
- 1 file changed, 26 insertions(+)
-
-diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
-index 9d22725..9a36bcb 100644
---- a/src/ap/hw_features.c
-+++ b/src/ap/hw_features.c
-@@ -709,6 +709,32 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
- #ifdef CONFIG_IEEE80211AX
- static int ieee80211ax_supported_he_capab(struct hostapd_iface *iface)
- {
-+	struct hostapd_hw_modes *mode = iface->current_mode;
-+	struct he_capabilities *he_cap = &mode->he_capab[IEEE80211_MODE_AP];
-+	struct hostapd_config *conf = iface->conf;
-+
-+#define HE_CAP_CHECK(hw_cap, field, phy_idx, cfg_cap)					\
-+	do {									\
-+		if (cfg_cap && !(hw_cap[phy_idx] & field)) {	\
-+			wpa_printf(MSG_ERROR, "Driver does not support configured" \
-+				     " HE capability [%s]", #field);		\
-+			return 0;						\
-+		}								\
-+	} while (0)
-+
-+	HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_LDPC_CODING_IN_PAYLOAD,
-+		     HE_PHYCAP_LDPC_CODING_IN_PAYLOAD_IDX,
-+		     conf->he_phy_capab.he_ldpc);
-+	HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_SU_BEAMFORMER_CAPAB,
-+		     HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX,
-+		     conf->he_phy_capab.he_su_beamformer);
-+	HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_SU_BEAMFORMEE_CAPAB,
-+		     HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX,
-+		     conf->he_phy_capab.he_su_beamformee);
-+	HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_MU_BEAMFORMER_CAPAB,
-+		     HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX,
-+		     conf->he_phy_capab.he_mu_beamformer);
-+
- 	return 1;
- }
- #endif /* CONFIG_IEEE80211AX */
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-mtk-hostapd-Add-HE-capabilities-check.patch
similarity index 91%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-mtk-hostapd-Add-HE-capabilities-check.patch
index cc30d42..3801eb3 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-mtk-hostapd-Add-HE-capabilities-check.patch
@@ -1,7 +1,7 @@
-From fac968ec3565072058dc92aa2f12e0c145a963e2 Mon Sep 17 00:00:00 2001
+From 1468c2bb212faf091cb4a0c0ba1394722eb2c94e Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Fri, 9 Jun 2023 09:03:05 +0800
-Subject: [PATCH 26/38] hostapd: mtk: Add HE capabilities check
+Subject: [PATCH 26/54] mtk: hostapd: Add HE capabilities check
 
 Add HE capabilities check.
 Since "HE capabilities" check has been removed by driver,
@@ -11,7 +11,7 @@
  1 file changed, 26 insertions(+)
 
 diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
-index 9d22725..9a36bcb 100644
+index 9d2272522..9a36bcb10 100644
 --- a/src/ap/hw_features.c
 +++ b/src/ap/hw_features.c
 @@ -709,6 +709,32 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch
deleted file mode 100644
index 0ba1a38..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From c1687a93fb5b8d72f7d68ea761a1fbaf80bf1de4 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Wed, 5 Jul 2023 10:44:15 +0800
-Subject: [PATCH 27/38] hostapd: mtk: Fix background channel overlapping
- operating channel issue
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- src/ap/dfs.c | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
-diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 3b1df6d..6f76354 100644
---- a/src/ap/dfs.c
-+++ b/src/ap/dfs.c
-@@ -812,6 +812,20 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
- }
- 
- 
-+static void dfs_check_background_overlapped(struct hostapd_iface *iface)
-+{
-+	int width = hostapd_get_oper_chwidth(iface->conf);
-+
-+	if (!dfs_use_radar_background(iface))
-+		return;
-+
-+	if (dfs_are_channels_overlapped(iface, iface->radar_background.freq,
-+					width, iface->radar_background.centr_freq_seg0_idx,
-+					iface->radar_background.centr_freq_seg1_idx))
-+		iface->radar_background.channel = -1;
-+}
-+
-+
- static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
- 				     int start_chan_idx, int n_chans)
- {
-@@ -1132,6 +1146,8 @@ static void hostpad_dfs_update_background_chain(struct hostapd_iface *iface)
- 						  &oper_centr_freq_seg1_idx,
- 						  &channel_type);
- 	if (!channel ||
-+	    channel->chan == iface->conf->channel ||
-+	    channel->chan == iface->radar_background.channel ||
- 	    hostapd_start_dfs_cac(iface, iface->conf->hw_mode,
- 				  channel->freq, channel->chan,
- 				  iface->conf->ieee80211n,
-@@ -1366,6 +1382,7 @@ static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
- 	hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
- 					     oper_centr_freq_seg1_idx);
- 	err = 0;
-+	dfs_check_background_overlapped(iface);
- 
- 	hostapd_setup_interface_complete(iface, err);
- 	return err;
-@@ -1493,6 +1510,7 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
- 			hostapd_set_oper_centr_freq_seg1_idx(
- 				iface->conf, oper_centr_freq_seg1_idx);
- 
-+			dfs_check_background_overlapped(iface);
- 			hostapd_disable_iface(iface);
- 			hostapd_enable_iface(iface);
- 			return 0;
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0027-mtk-hostapd-Fix-background-channel-overlapping-opera.patch
similarity index 92%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0027-mtk-hostapd-Fix-background-channel-overlapping-opera.patch
index 0ba1a38..6a98b5d 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0027-mtk-hostapd-Fix-background-channel-overlapping-opera.patch
@@ -1,7 +1,7 @@
-From c1687a93fb5b8d72f7d68ea761a1fbaf80bf1de4 Mon Sep 17 00:00:00 2001
+From 163efaffce1344a6c2611a2a75d863eb88b17137 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 10:44:15 +0800
-Subject: [PATCH 27/38] hostapd: mtk: Fix background channel overlapping
+Subject: [PATCH 27/54] mtk: hostapd: Fix background channel overlapping
  operating channel issue
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 18 insertions(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 3b1df6d..6f76354 100644
+index 3b1df6dc6..6f7635436 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -812,6 +812,20 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0028-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0028-mtk-hostapd-Fix-hostapd_dfs_start_cac-log.patch
similarity index 86%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0028-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0028-mtk-hostapd-Fix-hostapd_dfs_start_cac-log.patch
index 57395ca..84ca877 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0028-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0028-mtk-hostapd-Fix-hostapd_dfs_start_cac-log.patch
@@ -1,7 +1,7 @@
-From 57fd7fc979251fd178175c506e64a724433c8d6d Mon Sep 17 00:00:00 2001
+From fdbb7f5123ea8f3c5c568b4f5b311e33aa396e50 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 10:47:20 +0800
-Subject: [PATCH 28/38] hostapd: mtk: Fix hostapd_dfs_start_cac log
+Subject: [PATCH 28/54] mtk: hostapd: Fix hostapd_dfs_start_cac log
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -9,7 +9,7 @@
  1 file changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 6f76354..95119a3 100644
+index 6f7635436..95119a391 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -1655,9 +1655,11 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
deleted file mode 100644
index c247137..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 31d7b7fe98e3d5d0e2769bd7ea22e529a7f1295d Mon Sep 17 00:00:00 2001
-From: Michael Lee <michael-cy.lee@mediatek.com>
-Date: Thu, 13 Jul 2023 13:14:26 +0800
-Subject: [PATCH 29/38] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
- failed
-
-If ioctl returns EBUSY on command SIOCBRADDIF, the interface might
-already be bridged by others, and linux_br_add_if should not indicate an
-error in the case.
-
-This patch checks whether the interface is correctly brigded when ioctl
-returns EBUSY.
-
-Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
----
- src/drivers/linux_ioctl.c | 16 ++++++++++++++--
- 1 file changed, 14 insertions(+), 2 deletions(-)
-
-diff --git a/src/drivers/linux_ioctl.c b/src/drivers/linux_ioctl.c
-index 7edb9df..b8c1af2 100644
---- a/src/drivers/linux_ioctl.c
-+++ b/src/drivers/linux_ioctl.c
-@@ -150,7 +150,8 @@ int linux_br_del(int sock, const char *brname)
- int linux_br_add_if(int sock, const char *brname, const char *ifname)
- {
- 	struct ifreq ifr;
--	int ifindex;
-+	int ifindex, ret;
-+	char in_br[IFNAMSIZ];
- 
- 	ifindex = if_nametoindex(ifname);
- 	if (ifindex == 0)
-@@ -164,8 +165,19 @@ int linux_br_add_if(int sock, const char *brname, const char *ifname)
- 
- 		wpa_printf(MSG_DEBUG, "Could not add interface %s into bridge "
- 			   "%s: %s", ifname, brname, strerror(errno));
-+
-+		/* If ioctl returns -EBUSY when adding interface into bridge,
-+		 * the interface might already be added by netifd, so here we
-+		 * check whether the interface is currently on the right
-+		 * bridge. */
-+		if(errno == EBUSY && linux_br_get(in_br, ifname) == 0 &&
-+	           os_strcmp(in_br, brname) == 0)
-+			ret = 0;
-+		else
-+			ret = -1;
-+
- 		errno = saved_errno;
--		return -1;
-+		return ret;
- 	}
- 
- 	return 0;
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-mtk-hostapd-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
similarity index 90%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-mtk-hostapd-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
index c247137..57b8060 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-mtk-hostapd-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
@@ -1,7 +1,7 @@
-From 31d7b7fe98e3d5d0e2769bd7ea22e529a7f1295d Mon Sep 17 00:00:00 2001
+From a08f87c88e8abd539dc75b7fcb15fef786d5a61d Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Thu, 13 Jul 2023 13:14:26 +0800
-Subject: [PATCH 29/38] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
+Subject: [PATCH 29/54] mtk: hostapd: Check the bridge after ioctl SIOCBRADDIF
  failed
 
 If ioctl returns EBUSY on command SIOCBRADDIF, the interface might
@@ -17,7 +17,7 @@
  1 file changed, 14 insertions(+), 2 deletions(-)
 
 diff --git a/src/drivers/linux_ioctl.c b/src/drivers/linux_ioctl.c
-index 7edb9df..b8c1af2 100644
+index 7edb9df2e..b8c1af2e3 100644
 --- a/src/drivers/linux_ioctl.c
 +++ b/src/drivers/linux_ioctl.c
 @@ -150,7 +150,8 @@ int linux_br_del(int sock, const char *brname)
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-mtk-hostapd-Update-parameter_set_count-in-MU-EDCA-IE.patch
similarity index 83%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-mtk-hostapd-Update-parameter_set_count-in-MU-EDCA-IE.patch
index 50e4e63..28761c5 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-mtk-hostapd-Update-parameter_set_count-in-MU-EDCA-IE.patch
@@ -1,7 +1,7 @@
-From 65f2475fbf84a7b71e5dcba2b8f7ae77eee4f36d Mon Sep 17 00:00:00 2001
+From 8e8590fe62c5b1c9daceb7588798a96b95df6039 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Fri, 14 Jul 2023 17:19:13 +0800
-Subject: [PATCH 30/38] hostapd: mtk: Update parameter_set_count in MU EDCA IE
+Subject: [PATCH 30/54] mtk: hostapd: Update parameter_set_count in MU EDCA IE
 
 without this patch, MU EDCA Parameter update count not equal to
 WMM Parameter set count.
@@ -10,7 +10,7 @@
  1 file changed, 3 insertions(+)
 
 diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
-index 9407dd6..353e815 100644
+index 9407dd6e5..353e8156c 100644
 --- a/src/ap/ieee802_11_he.c
 +++ b/src/ap/ieee802_11_he.c
 @@ -316,6 +316,9 @@ u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid)
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch
deleted file mode 100644
index 2abbb0b..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 0b9d85b0e28ab0425d0c6742ce581efcfcad0ed6 Mon Sep 17 00:00:00 2001
-From: mtk20656 <chank.chen@mediatek.com>
-Date: Mon, 24 Jul 2023 11:30:27 +0800
-Subject: [PATCH 31/38] hostapd: mtk: add extension IE list for non-inherit IE
- in mbssid
-
-Certain clients do not scan all non tx profiles due to absence of
-element ID extension list which is mandatory field in non inheritance
-IE. Non inheritance Element ID is followed by extension element ID.
-Length is expected to be mentioned. Currently we do not support any
-extension element and hence filling length as 0.
-
-Signed-off-by: mtk20656 <chank.chen@mediatek.com>
----
- src/ap/ieee802_11.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
- mode change 100644 => 100755 src/ap/ieee802_11.c
-
-diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-old mode 100644
-new mode 100755
-index 110ad8c..e05a06b
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -7659,7 +7659,7 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
- 		else if (hapd->conf->xrates_supported)
- 			ie_count++;
- 		if (ie_count)
--			nontx_profile_len += 4 + ie_count;
-+			nontx_profile_len += 5 + ie_count;
- 
- 		if (len + nontx_profile_len > 255)
- 			break;
-@@ -7800,11 +7800,16 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
- 			non_inherit_ie[ie_count++] = WLAN_EID_EXT_SUPP_RATES;
- 		if (ie_count) {
- 			*eid++ = WLAN_EID_EXTENSION;
--			*eid++ = 2 + ie_count;
-+			*eid++ = 3 + ie_count;
- 			*eid++ = WLAN_EID_EXT_NON_INHERITANCE;
- 			*eid++ = ie_count;
- 			os_memcpy(eid, non_inherit_ie, ie_count);
- 			eid += ie_count;
-+			/* Element ID extension list is mandatory part of non inheritance IE.
-+			 * It has a length field followed by extension IEs. Currently no
-+			 * extension IEs are supported so filling length as 0.
-+			 */
-+			*eid++ = 0;
- 		}
- 
- 		*eid_len_pos = (eid - eid_len_pos) - 1;
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0031-mtk-hostapd-add-extension-IE-list-for-non-inherit-IE.patch
similarity index 91%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0031-mtk-hostapd-add-extension-IE-list-for-non-inherit-IE.patch
index 2abbb0b..0ad3c2d 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0031-mtk-hostapd-add-extension-IE-list-for-non-inherit-IE.patch
@@ -1,7 +1,7 @@
-From 0b9d85b0e28ab0425d0c6742ce581efcfcad0ed6 Mon Sep 17 00:00:00 2001
+From be61f9b1bd2f3c7bcd935968d8709565f6b231b5 Mon Sep 17 00:00:00 2001
 From: mtk20656 <chank.chen@mediatek.com>
 Date: Mon, 24 Jul 2023 11:30:27 +0800
-Subject: [PATCH 31/38] hostapd: mtk: add extension IE list for non-inherit IE
+Subject: [PATCH 31/54] mtk: hostapd: add extension IE list for non-inherit IE
  in mbssid
 
 Certain clients do not scan all non tx profiles due to absence of
@@ -19,7 +19,7 @@
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
 old mode 100644
 new mode 100755
-index 110ad8c..e05a06b
+index 110ad8c2e..e05a06b09
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
 @@ -7659,7 +7659,7 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-mtk-hostapd-Fix-rnr-ie-length-when-no-need-to-report.patch
similarity index 84%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-mtk-hostapd-Fix-rnr-ie-length-when-no-need-to-report.patch
index 52c74f9..15c97a8 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-mtk-hostapd-Fix-rnr-ie-length-when-no-need-to-report.patch
@@ -1,7 +1,7 @@
-From e9f856156f861845c160538d2d5907bf338fa489 Mon Sep 17 00:00:00 2001
+From fea4788692076f9c0701ecec68a85198a70d05c0 Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Mon, 7 Aug 2023 15:27:27 +0800
-Subject: [PATCH 32/38] hostapd: mtk: Fix rnr ie length when no need to report
+Subject: [PATCH 32/54] mtk: hostapd: Fix rnr ie length when no need to report
  bss
 
 Fix rnr ie length when no need to report bss. If we don't have content in
@@ -13,7 +13,7 @@
  1 file changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index e05a06b..7b6aabb 100755
+index e05a06b09..7b6aabbff 100755
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
 @@ -7511,8 +7511,10 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-mtk-hostapd-add-back-ht-vht-cap-missing-field-before.patch
similarity index 87%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-mtk-hostapd-add-back-ht-vht-cap-missing-field-before.patch
index 47e2970..ebc4408 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-mtk-hostapd-add-back-ht-vht-cap-missing-field-before.patch
@@ -1,7 +1,7 @@
-From 5b750f3f78cec3b64ebb9bb3b74def424c7d57fd Mon Sep 17 00:00:00 2001
+From 765215ac465b90e20c52dd48d51859d849834c80 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Tue, 8 Aug 2023 19:21:41 +0800
-Subject: [PATCH 33/38] hostapd: mtk: add back ht vht cap missing field before
+Subject: [PATCH 33/54] mtk: hostapd: add back ht vht cap missing field before
  dfs channel fallback
 
 hostapd_event_ch_switch would set / clear ht_capab and vht_capab, based
@@ -22,10 +22,10 @@
  1 file changed, 7 insertions(+)
 
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 3e184b5..b8ae8de 100644
+index a28466405..ec7677f6a 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
-@@ -4111,6 +4111,13 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+@@ -4112,6 +4112,13 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
  		break;
  	}
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-mtk-hostapd-update-op_class-when-AP-channel-switchin.patch
similarity index 88%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-mtk-hostapd-update-op_class-when-AP-channel-switchin.patch
index 5412153..6afdc0b 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-mtk-hostapd-update-op_class-when-AP-channel-switchin.patch
@@ -1,7 +1,7 @@
-From d46e85faec291f813d6b5578122cd267421e84fa Mon Sep 17 00:00:00 2001
+From 9a82dbf6c16899eeb6b98178cc6e341f164acfa6 Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Wed, 23 Aug 2023 17:44:50 +0800
-Subject: [PATCH 34/38] hostapd: mtk: update op_class when AP channel switching
+Subject: [PATCH 34/54] mtk: hostapd: update op_class when AP channel switching
 
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
 ---
@@ -9,7 +9,7 @@
  1 file changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index e7f1f19..f749b33 100644
+index e7f1f19ce..f749b33dc 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
 @@ -1041,7 +1041,7 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
deleted file mode 100644
index 4dad332..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 4b58cd9fc60093a0f4e9fe56cf47f05e9b1287fb Mon Sep 17 00:00:00 2001
-From: mtk23510 <rudra.shahi@mediatek.com>
-Date: Fri, 26 May 2023 14:52:35 +0800
-Subject: [PATCH 35/38] hostapd: mtk: Add support for gtk rekeying in hostapd
- cli
-
-Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
----
- hostapd/hostapd_cli.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
-diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 6d763f3..363a6bb 100644
---- a/hostapd/hostapd_cli.c
-+++ b/hostapd/hostapd_cli.c
-@@ -1256,6 +1256,15 @@ static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
- }
- 
- 
-+#ifdef CONFIG_TESTING_OPTIONS
-+static int hostapd_cli_cmd_rekey_gtk(struct wpa_ctrl *ctrl, int argc,
-+				      char *argv[])
-+{
-+	return wpa_ctrl_command(ctrl, "REKEY_GTK");
-+}
-+#endif
-+
-+
- static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- 	char cmd[256];
-@@ -1761,6 +1770,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
- 	  "= disable hostapd on current interface" },
- 	{ "update_beacon", hostapd_cli_cmd_update_beacon, NULL,
- 	  "= update Beacon frame contents\n"},
-+#ifdef CONFIG_TESTING_OPTIONS
-+	{ "rekey_gtk", hostapd_cli_cmd_rekey_gtk, NULL,
-+	  "= rekey gtk\n"},
-+#endif
- 	{ "erp_flush", hostapd_cli_cmd_erp_flush, NULL,
- 	  "= drop all ERP keys"},
- 	{ "log_level", hostapd_cli_cmd_log_level, NULL,
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-mtk-hostapd-Add-support-for-gtk-rekeying-in-hostapd-.patch
similarity index 88%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-mtk-hostapd-Add-support-for-gtk-rekeying-in-hostapd-.patch
index 4dad332..5d8edfd 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-mtk-hostapd-Add-support-for-gtk-rekeying-in-hostapd-.patch
@@ -1,7 +1,7 @@
-From 4b58cd9fc60093a0f4e9fe56cf47f05e9b1287fb Mon Sep 17 00:00:00 2001
+From aa65ab579fe3c032034b2ca641a91aa62285b59f Mon Sep 17 00:00:00 2001
 From: mtk23510 <rudra.shahi@mediatek.com>
 Date: Fri, 26 May 2023 14:52:35 +0800
-Subject: [PATCH 35/38] hostapd: mtk: Add support for gtk rekeying in hostapd
+Subject: [PATCH 35/54] mtk: hostapd: Add support for gtk rekeying in hostapd
  cli
 
 Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 13 insertions(+)
 
 diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
-index 6d763f3..363a6bb 100644
+index 6d763f327..363a6bb93 100644
 --- a/hostapd/hostapd_cli.c
 +++ b/hostapd/hostapd_cli.c
 @@ -1256,6 +1256,15 @@ static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
deleted file mode 100644
index 2b0f254..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From bf06bdd4ba98cebdb21408fc7c85b9adc813a956 Mon Sep 17 00:00:00 2001
-From: Michael Lee <michael-cy.lee@mediatek.com>
-Date: Tue, 11 Jul 2023 14:17:43 +0800
-Subject: [PATCH 36/38] hostapd: mtk: Set WMM and TX queue parameters for
- wpa_supplicant
-
-Since most of the time, wpa_supplicant will be used to setup an STA
-interface, it's default WMM and TX queue parameters should be set for
-STA.
-
-Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
----
- wpa_supplicant/config.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
-index 2652c8a..cd40258 100644
---- a/wpa_supplicant/config.c
-+++ b/wpa_supplicant/config.c
-@@ -4673,19 +4673,19 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
- 	const struct hostapd_wmm_ac_params ac_bk =
- 		{ aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
- 	const struct hostapd_wmm_ac_params ac_be =
--		{ aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
-+		{ aCWmin, aCWmin + 2, 3, 0, 0 }; /* best effort traffic */
- 	const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
--		{ aCWmin - 1, aCWmin, 2, 3008 / 32, 0 };
-+		{ aCWmin - 1, aCWmin, 1, 3008 / 32, 0 };
- 	const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
--		{ aCWmin - 2, aCWmin - 1, 2, 1504 / 32, 0 };
-+		{ aCWmin - 2, aCWmin - 1, 1, 1504 / 32, 0 };
- 	const struct hostapd_tx_queue_params txq_bk =
- 		{ 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 };
- 	const struct hostapd_tx_queue_params txq_be =
--		{ 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0 };
-+		{ 3, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 };
- 	const struct hostapd_tx_queue_params txq_vi =
--		{ 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30 };
-+		{ 2, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30 };
- 	const struct hostapd_tx_queue_params txq_vo =
--		{ 1, (ecw2cw(aCWmin) + 1) / 4 - 1,
-+		{ 2, (ecw2cw(aCWmin) + 1) / 4 - 1,
- 		  (ecw2cw(aCWmin) + 1) / 2 - 1, 15 };
- 
- #undef ecw2cw
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-mtk-hostapd-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
similarity index 91%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-mtk-hostapd-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
index 2b0f254..7fb99bd 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-mtk-hostapd-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
@@ -1,7 +1,7 @@
-From bf06bdd4ba98cebdb21408fc7c85b9adc813a956 Mon Sep 17 00:00:00 2001
+From a8d74e867652c6feda7332ee2cb40611635179f0 Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Tue, 11 Jul 2023 14:17:43 +0800
-Subject: [PATCH 36/38] hostapd: mtk: Set WMM and TX queue parameters for
+Subject: [PATCH 36/54] mtk: hostapd: Set WMM and TX queue parameters for
  wpa_supplicant
 
 Since most of the time, wpa_supplicant will be used to setup an STA
@@ -14,7 +14,7 @@
  1 file changed, 6 insertions(+), 6 deletions(-)
 
 diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
-index 2652c8a..cd40258 100644
+index 2652c8a97..cd4025884 100644
 --- a/wpa_supplicant/config.c
 +++ b/wpa_supplicant/config.c
 @@ -4673,19 +4673,19 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-mtk-hostapd-Set-STA-TX-queue-parameters-configuratio.patch
similarity index 92%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-mtk-hostapd-Set-STA-TX-queue-parameters-configuratio.patch
index a6a86d8..aab9689 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-mtk-hostapd-Set-STA-TX-queue-parameters-configuratio.patch
@@ -1,7 +1,7 @@
-From 33cbd77949640d337e4e39d462bbb6b575792de3 Mon Sep 17 00:00:00 2001
+From 7a02e5965652229833be92a9bd8f675e2015144a Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Fri, 7 Jul 2023 17:16:11 +0800
-Subject: [PATCH 37/38] hostapd: mtk: Set STA TX queue parameters configuration
+Subject: [PATCH 37/54] mtk: hostapd: Set STA TX queue parameters configuration
  after association
 
 This patch adds the way for wpa_supplicant to set driver's TX queue
@@ -17,7 +17,7 @@
  2 files changed, 28 insertions(+)
 
 diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
-index dcf5764..36ff854 100644
+index dcf576487..36ff854ad 100644
 --- a/wpa_supplicant/driver_i.h
 +++ b/wpa_supplicant/driver_i.h
 @@ -321,6 +321,18 @@ static inline int wpa_drv_set_country(struct wpa_supplicant *wpa_s,
@@ -40,7 +40,7 @@
  				    const u8 *data, size_t data_len, int noack,
  				    unsigned int freq, unsigned int wait)
 diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
-index 3b8596d..f5ac62e 100644
+index 3b8596d6f..f5ac62eda 100644
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
 @@ -3559,6 +3559,20 @@ out:
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
deleted file mode 100644
index e076eae..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 7a2d1d5e7d43fbd7ecf008447e08118c10905d63 Mon Sep 17 00:00:00 2001
-From: Michael-CY Lee <michael-cy.lee@mediatek.com>
-Date: Fri, 1 Sep 2023 15:31:24 +0800
-Subject: [PATCH 38/38] hostapd: mtk: avoid color switch when beacon is not set
-
-Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
----
- src/ap/hostapd.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index b8ae8de..a4fffd9 100644
---- a/src/ap/hostapd.c
-+++ b/src/ap/hostapd.c
-@@ -4249,7 +4249,7 @@ void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap)
- {
- 	struct os_reltime now;
- 
--	if (hapd->cca_in_progress)
-+	if (hapd->cca_in_progress || !hapd->beacon_set_done)
- 		return;
- 
- 	if (os_get_reltime(&now))
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-mtk-hostapd-avoid-color-switch-when-beacon-is-not-se.patch
similarity index 70%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-mtk-hostapd-avoid-color-switch-when-beacon-is-not-se.patch
index e076eae..23ca582 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-mtk-hostapd-avoid-color-switch-when-beacon-is-not-se.patch
@@ -1,7 +1,7 @@
-From 7a2d1d5e7d43fbd7ecf008447e08118c10905d63 Mon Sep 17 00:00:00 2001
+From 695e63f81f817c302e4594e44b49e1f7a8c7969c Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Fri, 1 Sep 2023 15:31:24 +0800
-Subject: [PATCH 38/38] hostapd: mtk: avoid color switch when beacon is not set
+Subject: [PATCH 38/54] mtk: hostapd: avoid color switch when beacon is not set
 
 Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
 ---
@@ -9,10 +9,10 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index b8ae8de..a4fffd9 100644
+index ec7677f6a..2b563a572 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
-@@ -4249,7 +4249,7 @@ void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap)
+@@ -4250,7 +4250,7 @@ void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap)
  {
  	struct os_reltime now;
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0039-mtk-hostapd-6g-bss-connect-do-not-consider-ht-operat.patch
similarity index 68%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0039-mtk-hostapd-6g-bss-connect-do-not-consider-ht-operat.patch
index 105e188..0a5a04f 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0039-mtk-hostapd-6g-bss-connect-do-not-consider-ht-operat.patch
@@ -1,20 +1,22 @@
-From d11dea1d3dee3577be404bfb6f7dc2460858242d Mon Sep 17 00:00:00 2001
+From 4fe45b586ebb86cfbdd61ab91d5ebef110ce74aa Mon Sep 17 00:00:00 2001
 From: mtk20656 <chank.chen@mediatek.com>
 Date: Wed, 13 Sep 2023 19:29:51 +0800
-Subject: [PATCH] [hostapd][mt76]6g bss connect do not consider ht operation
+Subject: [PATCH 39/54] mtk: hostapd: 6g bss connect do not consider ht
+ operation
 
 Signed-off-by: mtk20656 <chank.chen@mediatek.com>
 ---
  src/ap/ieee802_11.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
+ mode change 100755 => 100644 src/ap/ieee802_11.c
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
 old mode 100755
 new mode 100644
-index ef520c8..904b1b5
+index 7b6aabbff..38fce3e82
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -5434,7 +5434,8 @@ static void handle_assoc(struct hostapd_data *hapd,
+@@ -5451,7 +5451,8 @@ static void handle_assoc(struct hostapd_data *hapd,
  			ieee802_11_set_beacons(hapd->iface);
  	}
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0040-mtk-hostapd-avoid-unnecessary-beacon-update-for-6-GH.patch
similarity index 78%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0040-mtk-hostapd-avoid-unnecessary-beacon-update-for-6-GH.patch
index 1695996..7c3853f 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0040-mtk-hostapd-avoid-unnecessary-beacon-update-for-6-GH.patch
@@ -1,7 +1,7 @@
-From 53dbf487d72a05ae692d98930852c3b98cc6dad6 Mon Sep 17 00:00:00 2001
+From 49b5d37f77fa48f215b3abc9c3ce74c26bbabefc Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Wed, 4 Oct 2023 11:12:52 +0800
-Subject: [PATCH] hostapd: mtk: avoid unnecessary beacon update for 6 GHz
+Subject: [PATCH 40/54] mtk: hostapd: avoid unnecessary beacon update for 6 GHz
  co-location
 
 There are two reasons to update beacon for 6 GHz co-location:
@@ -24,13 +24,13 @@
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
 Signed-off-by: Money Wang <money.wang@mediatek.com>
 ---
- src/ap/beacon.c   | 8 +++++++-
+ src/ap/beacon.c   | 6 ++++++
  src/ap/beacon.h   | 1 +
  src/ap/bss_load.c | 2 +-
- 3 files changed, 9 insertions(+), 2 deletions(-)
+ 3 files changed, 8 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/beacon.c b/src/ap/beacon.c
-index d160675..684bdc0 100644
+index d160675cb..b74396a8d 100644
 --- a/src/ap/beacon.c
 +++ b/src/ap/beacon.c
 @@ -2216,6 +2216,12 @@ fail:
@@ -46,17 +46,8 @@
  int ieee802_11_set_beacon(struct hostapd_data *hapd)
  {
  	struct hostapd_iface *iface = hapd->iface;
-@@ -2246,7 +2252,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
- 			mld_ap = true;
- #endif /* CONFIG_IEEE80211BE */
- 
--		if (is_6g == is_6ghz_op_class(other->conf->op_class) &&
-+		if ((!is_6g || is_6ghz_op_class(other->conf->op_class)) &&
- 		    !mld_ap)
- 			continue;
- 
 diff --git a/src/ap/beacon.h b/src/ap/beacon.h
-index c320825..b32b2a7 100644
+index c320825f3..b32b2a7d0 100644
 --- a/src/ap/beacon.h
 +++ b/src/ap/beacon.h
 @@ -15,6 +15,7 @@ struct ieee80211_mgmt;
@@ -68,7 +59,7 @@
  int ieee802_11_set_beacons(struct hostapd_iface *iface);
  int ieee802_11_update_beacons(struct hostapd_iface *iface);
 diff --git a/src/ap/bss_load.c b/src/ap/bss_load.c
-index 725d3cd..e9baafc 100644
+index 725d3cd34..e9baafc96 100644
 --- a/src/ap/bss_load.c
 +++ b/src/ap/bss_load.c
 @@ -55,7 +55,7 @@ static void update_channel_utilization(void *eloop_data, void *user_data)
@@ -81,5 +72,5 @@
  	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
  		return;
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
deleted file mode 100644
index 105e188..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From d11dea1d3dee3577be404bfb6f7dc2460858242d Mon Sep 17 00:00:00 2001
-From: mtk20656 <chank.chen@mediatek.com>
-Date: Wed, 13 Sep 2023 19:29:51 +0800
-Subject: [PATCH] [hostapd][mt76]6g bss connect do not consider ht operation
-
-Signed-off-by: mtk20656 <chank.chen@mediatek.com>
----
- src/ap/ieee802_11.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-old mode 100755
-new mode 100644
-index ef520c8..904b1b5
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -5434,7 +5434,8 @@ static void handle_assoc(struct hostapd_data *hapd,
- 			ieee802_11_set_beacons(hapd->iface);
- 	}
- 
--	update_ht_state(hapd, sta);
-+	if (!is_6ghz_op_class(hapd->iconf->op_class))
-+		update_ht_state(hapd, sta);
- 
- 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
- 		       HOSTAPD_LEVEL_DEBUG,
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0041-mtk-hostapd-refactor-the-flow-to-create-Wide-Bandwid.patch
similarity index 95%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0041-mtk-hostapd-refactor-the-flow-to-create-Wide-Bandwid.patch
index f02f935..d1e24d5 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0041-mtk-hostapd-refactor-the-flow-to-create-Wide-Bandwid.patch
@@ -1,8 +1,8 @@
-From 92caaf40a058d4eac8061c0e3240f0b23aba69ce Mon Sep 17 00:00:00 2001
+From 5daee94e29d5d7a3db5b8c8f03b15aa4a914f85f Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Thu, 24 Aug 2023 10:04:15 +0800
-Subject: hostapd: mtk: refactor the flow to create Wide Bandwidth
- Channel Switch IE
+Subject: [PATCH 41/54] mtk: hostapd: refactor the flow to create Wide
+ Bandwidth Channel Switch IE
 
 This patch changes the flow to create Wide Bandwidth Channel Switch IE:
 1. 2 GHz: Wide Bandwidth Channel Switch IE should not present.
@@ -26,10 +26,10 @@
  1 file changed, 76 insertions(+), 23 deletions(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index ef520c8..5f4d78f 100755
+index 38fce3e82..d46c5a42b 100644
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -7065,57 +7065,110 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
+@@ -7083,57 +7083,110 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
  
  u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
  {
@@ -164,5 +164,5 @@
  	return eid;
  }
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
deleted file mode 100644
index 1695996..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 53dbf487d72a05ae692d98930852c3b98cc6dad6 Mon Sep 17 00:00:00 2001
-From: Michael-CY Lee <michael-cy.lee@mediatek.com>
-Date: Wed, 4 Oct 2023 11:12:52 +0800
-Subject: [PATCH] hostapd: mtk: avoid unnecessary beacon update for 6 GHz
- co-location
-
-There are two reasons to update beacon for 6 GHz co-location:
-1. 6 GHz out-of-band discovery
-2. MLD operational parameters update
-
-BSS load update is unrelated with the above two reasons, and therefore is
-not a case to update beacon for 6 GHz co-location.
-Moreover, updating beacon for 6 GHz co-location when BSS load update
-makes hostapd set beacon too frequently in a multiple BSSes case.
-
-Besides, it is also not necessary to update beacon for 6 GHz BSS when
-setting 2/5 GHz beacon. (i.e., no need for 2/5 GHz co-location)
-
-This patch adds an new function to update beacon only for current BSS,
-and uses the function duriong BSS load update.
-Also it changes the condition check to make beacon update only for 6 GHz
-co-location.
-
-Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
-Signed-off-by: Money Wang <money.wang@mediatek.com>
----
- src/ap/beacon.c   | 8 +++++++-
- src/ap/beacon.h   | 1 +
- src/ap/bss_load.c | 2 +-
- 3 files changed, 9 insertions(+), 2 deletions(-)
-
-diff --git a/src/ap/beacon.c b/src/ap/beacon.c
-index d160675..684bdc0 100644
---- a/src/ap/beacon.c
-+++ b/src/ap/beacon.c
-@@ -2216,6 +2216,12 @@ fail:
- }
- 
- 
-+void ieee802_11_set_beacon_per_bss_only(struct hostapd_data *hapd)
-+{
-+	__ieee802_11_set_beacon(hapd);
-+}
-+
-+
- int ieee802_11_set_beacon(struct hostapd_data *hapd)
- {
- 	struct hostapd_iface *iface = hapd->iface;
-@@ -2246,7 +2252,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
- 			mld_ap = true;
- #endif /* CONFIG_IEEE80211BE */
- 
--		if (is_6g == is_6ghz_op_class(other->conf->op_class) &&
-+		if ((!is_6g || is_6ghz_op_class(other->conf->op_class)) &&
- 		    !mld_ap)
- 			continue;
- 
-diff --git a/src/ap/beacon.h b/src/ap/beacon.h
-index c320825..b32b2a7 100644
---- a/src/ap/beacon.h
-+++ b/src/ap/beacon.h
-@@ -15,6 +15,7 @@ struct ieee80211_mgmt;
- void handle_probe_req(struct hostapd_data *hapd,
- 		      const struct ieee80211_mgmt *mgmt, size_t len,
- 		      int ssi_signal);
-+void ieee802_11_set_beacon_per_bss_only(struct hostapd_data *hapd);
- int ieee802_11_set_beacon(struct hostapd_data *hapd);
- int ieee802_11_set_beacons(struct hostapd_iface *iface);
- int ieee802_11_update_beacons(struct hostapd_iface *iface);
-diff --git a/src/ap/bss_load.c b/src/ap/bss_load.c
-index 725d3cd..e9baafc 100644
---- a/src/ap/bss_load.c
-+++ b/src/ap/bss_load.c
-@@ -55,7 +55,7 @@ static void update_channel_utilization(void *eloop_data, void *user_data)
- 		return;
- 	}
- 
--	ieee802_11_set_beacon(hapd);
-+	ieee802_11_set_beacon_per_bss_only(hapd);
- 
- 	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
- 		return;
--- 
-2.25.1
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0042-mtk-hostapd-Add-ACS-chanlist-info-in-get_config.patch
old mode 100755
new mode 100644
similarity index 88%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0042-mtk-hostapd-Add-ACS-chanlist-info-in-get_config.patch
index b699fc5..6508476
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0042-mtk-hostapd-Add-ACS-chanlist-info-in-get_config.patch
@@ -1,7 +1,7 @@
-From c515d269b08190aede080b9c59bf758f5d65e5a5 Mon Sep 17 00:00:00 2001
+From 5e51c981aa0540864803b5f5b68e715a8d98a338 Mon Sep 17 00:00:00 2001
 From: "fancy.liu" <fancy.liu@mediatek.com>
 Date: Sun, 8 Oct 2023 11:50:06 +0800
-Subject: [PATCH] hostapd: mtk: Add ACS chanlist info in get_config
+Subject: [PATCH 42/54] mtk: hostapd: Add ACS chanlist info in get_config
 
 This patch is used to add ACS chanlist info displaying
 for upper layer application obtaining.
@@ -15,10 +15,10 @@
  1 file changed, 59 insertions(+)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 537d5cf..2108198 100644
+index ae61cf625..aba22e1e6 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -1120,6 +1120,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
+@@ -1048,6 +1048,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
  {
  	int ret;
  	char *pos, *end;
@@ -26,7 +26,7 @@
  
  	pos = buf;
  	end = buf + buflen;
-@@ -1299,6 +1300,64 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
+@@ -1227,6 +1228,64 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
  		pos += ret;
  	}
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0043-mtk-hostapd-Fix-RSNXE-Interop-issue-with-STA.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0043-mtk-hostapd-Fix-RSNXE-Interop-issue-with-STA.patch
new file mode 100644
index 0000000..aae2359
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0043-mtk-hostapd-Fix-RSNXE-Interop-issue-with-STA.patch
@@ -0,0 +1,43 @@
+From c21e12bb63b9c3906143ffb368297e3b6a155eb3 Mon Sep 17 00:00:00 2001
+From: mtk25255 <rohit.kamat@mediatek.com>
+Date: Thu, 12 Oct 2023 14:29:23 +0800
+Subject: [PATCH 43/54] mtk: hostapd: Fix RSNXE Interop issue with STA
+
+---
+ src/ap/ieee802_11.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
+index d46c5a42b..1db66a783 100644
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -5181,6 +5181,7 @@ static void handle_assoc(struct hostapd_data *hapd,
+ 	int delay_assoc = 0;
+ #endif /* CONFIG_FILS */
+ 	int omit_rsnxe = 0;
++	bool sae_pk = false;
+ 
+ 	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
+ 				      sizeof(mgmt->u.assoc_req))) {
+@@ -5399,7 +5400,17 @@ static void handle_assoc(struct hostapd_data *hapd,
+ 	if (resp != WLAN_STATUS_SUCCESS)
+ 		goto fail;
+ 	omit_rsnxe = !get_ie(pos, left, WLAN_EID_RSNX);
+-
++#ifdef CONFIG_SAE_PK
++	sae_pk = hostapd_sae_pk_in_use(hapd->conf);
++#endif /* CONFIG_SAE_PK */
++	if (omit_rsnxe) {
++		if (!reassoc && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
++				(hapd->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
++				 hapd->conf->sae_pwe == SAE_PWE_BOTH || sae_pk ||
++				 wpa_key_mgmt_sae_ext_key(hapd->conf->wpa_key_mgmt))) {
++			omit_rsnxe = 0;
++		}
++	}
+ 	if (hostapd_get_aid(hapd, sta) < 0) {
+ 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
+ 			       HOSTAPD_LEVEL_INFO, "No room for more AIDs");
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
deleted file mode 100755
index b699fc5..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From c515d269b08190aede080b9c59bf758f5d65e5a5 Mon Sep 17 00:00:00 2001
-From: "fancy.liu" <fancy.liu@mediatek.com>
-Date: Sun, 8 Oct 2023 11:50:06 +0800
-Subject: [PATCH] hostapd: mtk: Add ACS chanlist info in get_config
-
-This patch is used to add ACS chanlist info displaying
-for upper layer application obtaining.
-
-Command format:
-hostapd_cli -i phy0-ap0 get_config
-
-Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
----
- hostapd/ctrl_iface.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 59 insertions(+)
-
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 537d5cf..2108198 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -1120,6 +1120,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
- {
- 	int ret;
- 	char *pos, *end;
-+	int i;
- 
- 	pos = buf;
- 	end = buf + buflen;
-@@ -1299,6 +1300,64 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
- 		pos += ret;
- 	}
- 
-+	/* dump chanlist */
-+	if (hapd->iface->conf->acs_ch_list.num > 0) {
-+		ret = os_snprintf(pos, end - pos, "chanlist=");
-+		if (os_snprintf_error(end - pos, ret))
-+			return pos - buf;
-+		pos += ret;
-+
-+		for (i = 0; i < hapd->iface->conf->acs_ch_list.num; i++) {
-+			if (i > 0) {
-+				ret = os_snprintf(pos, end - pos, ", ");
-+				if (os_snprintf_error(end - pos, ret))
-+					return pos - buf;
-+				pos += ret;
-+			}
-+
-+			ret = os_snprintf(pos, end - pos, "%d-%d",
-+				hapd->iface->conf->acs_ch_list.range[i].min,
-+				hapd->iface->conf->acs_ch_list.range[i].max);
-+			if (os_snprintf_error(end - pos, ret))
-+				return pos - buf;
-+			pos += ret;
-+		}
-+
-+		ret = os_snprintf(pos, end - pos, "\n");
-+		if (os_snprintf_error(end - pos, ret))
-+			return pos - buf;
-+		pos += ret;
-+	}
-+
-+	/* dump freqlist */
-+	if (hapd->iface->conf->acs_freq_list.num > 0) {
-+		ret = os_snprintf(pos, end - pos, "freqlist=");
-+		if (os_snprintf_error(end - pos, ret))
-+			return pos - buf;
-+		pos += ret;
-+
-+		for (i = 0; i < hapd->iface->conf->acs_freq_list.num; i++) {
-+			if (i > 0) {
-+				ret = os_snprintf(pos, end - pos, ", ");
-+				if (os_snprintf_error(end - pos, ret))
-+					return pos - buf;
-+				pos += ret;
-+			}
-+
-+			ret = os_snprintf(pos, end - pos, "%d-%d",
-+				hapd->iface->conf->acs_freq_list.range[i].min,
-+				hapd->iface->conf->acs_freq_list.range[i].max);
-+			if (os_snprintf_error(end - pos, ret))
-+				return pos - buf;
-+			pos += ret;
-+		}
-+
-+		ret = os_snprintf(pos, end - pos, "\n");
-+		if (os_snprintf_error(end - pos, ret))
-+			return pos - buf;
-+		pos += ret;
-+	}
-+
- 	return pos - buf;
- }
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0044-mtk-hostapd-Fix-chan_switch-to-usable-DFS-channel-fa.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0044-mtk-hostapd-Fix-chan_switch-to-usable-DFS-channel-fa.patch
new file mode 100644
index 0000000..2816120
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0044-mtk-hostapd-Fix-chan_switch-to-usable-DFS-channel-fa.patch
@@ -0,0 +1,44 @@
+From a56c6b0ea29d278bd7ec67e45c298eac8526a055 Mon Sep 17 00:00:00 2001
+From: "fancy.liu" <fancy.liu@mediatek.com>
+Date: Wed, 1 Nov 2023 19:58:05 +0800
+Subject: [PATCH 44/54] mtk: hostapd: Fix chan_switch to usable DFS channel
+ fail due to ACS
+
+Step and issue:
+1. Enable ACS in hostapd config;
+2. Bootup and then use hostapd_cli cmd switch channel to a DFS channel;
+3. Will do ACS again, and no work on channel specified in step 2.
+
+Root cause:
+When need do DFS-CAC, hostapd will do intf disable, then set the new
+channel into running config settings, and finally enable intf;
+In the test case, new DFS channel is set to runnint config settings, but
+another param "acs" is still 1 (enable), caused the ACS running when
+intf enabled.
+
+Solution:
+In the hostapd_switch_channel_fallback, need to disable acs if channel
+is valid.
+
+Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
+---
+ src/ap/hostapd.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index 2b563a572..f01f607f3 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -4121,6 +4121,9 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+ 
+ 	iface->freq = freq_params->freq;
+ 	iface->conf->channel = freq_params->channel;
++	if (iface->conf->channel != 0) /* If channel not zero, will disable acs. */
++		iface->conf->acs = 0;
++
+ 	iface->conf->secondary_channel = freq_params->sec_channel_offset;
+ 	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
+ 	hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0045-mtk-hostapd-update-eht-operation-element.patch
similarity index 83%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0045-mtk-hostapd-update-eht-operation-element.patch
index 5092a61..5b1c065 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0045-mtk-hostapd-update-eht-operation-element.patch
@@ -1,14 +1,14 @@
-From eaf03e5841437d268c929bd8215d8499fbdbfbb0 Mon Sep 17 00:00:00 2001
+From 9d81aac8e0c2a6e1aa968581a9c77cec7468cd60 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 10 May 2023 13:11:34 +0800
-Subject: [PATCH 1001/1005] hostapd: mtk: update eht operation element
+Subject: [PATCH 45/54] mtk: hostapd: update eht operation element
 
 ---
  src/ap/ieee802_11_eht.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c
-index 9a07f75..f132e1d 100644
+index 9a07f7501..f132e1d9c 100644
 --- a/src/ap/ieee802_11_eht.c
 +++ b/src/ap/ieee802_11_eht.c
 @@ -215,9 +215,9 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid)
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0046-mtk-hostapd-ucode-add-support-for-ucode-to-parse-BW3.patch
similarity index 64%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0046-mtk-hostapd-ucode-add-support-for-ucode-to-parse-BW3.patch
index 9c23287..be86061 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0046-mtk-hostapd-ucode-add-support-for-ucode-to-parse-BW3.patch
@@ -1,7 +1,7 @@
-From 5d04c65f6a625dea4b8ff7cfa35311dbfa2e4ae7 Mon Sep 17 00:00:00 2001
+From c73597bd17673ac6f33a314458cce14009a15fb0 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 30 Aug 2023 04:23:37 +0800
-Subject: [PATCH 1002/1005] hostapd: mtk: ucode: add support for ucode to parse
+Subject: [PATCH 46/54] mtk: hostapd: ucode: add support for ucode to parse
  BW320MHz info
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/src/utils/ucode.c b/src/utils/ucode.c
-index 2beeb9a..122c619 100644
+index 29c753c32..4b6ed3a94 100644
 --- a/src/utils/ucode.c
 +++ b/src/utils/ucode.c
-@@ -85,6 +85,10 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -144,6 +144,10 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
  	case 2:
  		chanwidth = CONF_OPER_CHWIDTH_160MHZ;
  		break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0047-mtk-hostapd-synchronize-bandwidth-in-AP-STA-support.patch
similarity index 94%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0047-mtk-hostapd-synchronize-bandwidth-in-AP-STA-support.patch
index 5a63279..c508d77 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0047-mtk-hostapd-synchronize-bandwidth-in-AP-STA-support.patch
@@ -1,7 +1,7 @@
-From 804f9b03e7f143d3a80741cb67721810e27ed2d8 Mon Sep 17 00:00:00 2001
+From 9238758c9fb0efb9b979eacef7d09914332186af Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
 Date: Mon, 11 Sep 2023 10:16:35 +0800
-Subject: [PATCH] hostapd: mtk: synchronize bandwidth in AP/STA support
+Subject: [PATCH 47/54] mtk: hostapd: synchronize bandwidth in AP/STA support
 
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
 ---
@@ -11,7 +11,7 @@
  3 files changed, 117 insertions(+), 18 deletions(-)
 
 diff --git a/src/ap/ucode.c b/src/ap/ucode.c
-index af97091..79d568f 100644
+index 16d1b5153..98b2a3bf2 100644
 --- a/src/ap/ucode.c
 +++ b/src/ap/ucode.c
 @@ -489,6 +489,9 @@ uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs)
@@ -105,10 +105,10 @@
  		ret = hostapd_switch_channel(iface->bss[i], &csa);
  
 diff --git a/src/utils/ucode.c b/src/utils/ucode.c
-index 122c619..0990e7b 100644
+index 4b6ed3a94..6f82382f3 100644
 --- a/src/utils/ucode.c
 +++ b/src/utils/ucode.c
-@@ -51,6 +51,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -110,6 +110,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
  	uc_value_t *freq = uc_fn_arg(0);
  	uc_value_t *sec = uc_fn_arg(1);
  	int width = ucv_uint64_get(uc_fn_arg(2));
@@ -116,7 +116,7 @@
  	int freq_val, center_idx, center_ofs;
  	enum oper_chan_width chanwidth;
  	enum hostapd_hw_mode hw_mode;
-@@ -88,6 +89,9 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -147,6 +148,9 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
  	case 9:
  		width = 3;
  		chanwidth = CONF_OPER_CHWIDTH_320MHZ;
@@ -126,7 +126,7 @@
  		break;
  	default:
  		return NULL;
-@@ -119,12 +123,16 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -178,12 +182,16 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
  	ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr)));
  	ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel));
  	ucv_object_add(ret, "frequency", ucv_int64_new(freq_val));
@@ -146,7 +146,7 @@
  		center_ofs = 20;
  	else
 diff --git a/wpa_supplicant/ucode.c b/wpa_supplicant/ucode.c
-index 6cba73d..d5489ea 100644
+index 397f85bde..542ca25c9 100644
 --- a/wpa_supplicant/ucode.c
 +++ b/wpa_supplicant/ucode.c
 @@ -7,6 +7,8 @@
@@ -275,5 +275,5 @@
  
  #ifdef CONFIG_MESH
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0048-mtk-hostapd-Add-support-for-updating-background-chan.patch
similarity index 96%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0048-mtk-hostapd-Add-support-for-updating-background-chan.patch
index 23aa563..ab4ff5b 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0048-mtk-hostapd-Add-support-for-updating-background-chan.patch
@@ -1,7 +1,7 @@
-From 00555b91d4d25c64eb556fe1b8815e522970b130 Mon Sep 17 00:00:00 2001
+From 8590ccd17827862e02b9f40ccca29a03dc3e0ab6 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 10:25:01 +0800
-Subject: [PATCH 1004/1005] hostapd: mtk: Add support for updating background
+Subject: [PATCH 48/54] mtk: hostapd: Add support for updating background
  channel by driver
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,7 +16,7 @@
  7 files changed, 160 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 95119a3..008596b 100644
+index 95119a391..008596bb2 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -814,11 +814,14 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
@@ -201,7 +201,7 @@
  			  int ht_enabled, int chan_offset, int chan_width,
  			  int cf1, int cf2)
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index 25ba29c..a1a2be5 100644
+index 25ba29ca1..a1a2be5ec 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -30,6 +30,9 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
@@ -215,7 +215,7 @@
  				 int ht_enabled, int chan_offset, int chan_width,
  				 int cf1, int cf2, u32 state);
 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index f749b33..12419c6 100644
+index f749b33dc..12419c6d4 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
 @@ -2089,6 +2089,18 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
@@ -255,7 +255,7 @@
  		if (!data)
  			break;
 diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
-index 1849f38..ea8d725 100644
+index 1849f38d8..ea8d7254a 100644
 --- a/src/ap/hostapd.h
 +++ b/src/ap/hostapd.h
 @@ -602,6 +602,11 @@ struct hostapd_iface {
@@ -271,10 +271,10 @@
  
  	u16 hw_flags;
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index ebc1d27..a9f48a1 100644
+index 8da93e025..b0a6e3514 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5842,6 +5842,18 @@ enum wpa_event_type {
+@@ -5845,6 +5845,18 @@ enum wpa_event_type {
  	 * The channel in the notification is now marked as usable.
  	 */
  	EVENT_DFS_STA_CAC_EXPIRED,
@@ -294,7 +294,7 @@
  
  
 diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
-index 63d4401..c1a65eb 100644
+index 63d44017c..c1a65eb4e 100644
 --- a/src/drivers/driver_nl80211_event.c
 +++ b/src/drivers/driver_nl80211_event.c
 @@ -2514,6 +2514,12 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
@@ -311,7 +311,7 @@
  		wpa_supplicant_event(drv->ctx, EVENT_DFS_STA_CAC_SKIPPED, &data);
  		break;
 diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index 225864b..9b0a817 100644
+index 225864b94..9b0a8171a 100644
 --- a/src/drivers/nl80211_copy.h
 +++ b/src/drivers/nl80211_copy.h
 @@ -6643,6 +6643,10 @@ enum nl80211_smps_mode {
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0049-mtk-hostapd-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
similarity index 91%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0049-mtk-hostapd-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
index fcfd0bf..623e3fc 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0049-mtk-hostapd-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
@@ -1,8 +1,7 @@
-From 5bcd4472062750b192c98d944b74e07b14ab3af5 Mon Sep 17 00:00:00 2001
+From e878e546ee5d1e86f174b2713b7a46fb05b6a7b9 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 2 Aug 2023 19:00:34 +0800
-Subject: [PATCH 1005/1005] hostapd: mtk: add zwdfs mode ctrl for eagle efem
- hwits
+Subject: [PATCH 49/54] mtk: hostapd: add zwdfs mode ctrl for eagle efem hwits
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -19,7 +18,7 @@
  10 files changed, 115 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 9e3dbb2..a751993 100644
+index 9e3dbb24a..a75199345 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -3183,6 +3183,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -32,10 +31,10 @@
  		int val = atoi(pos);
  
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index c288352..517ebd6 100644
+index aba22e1e6..f7c7a09f3 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -4156,6 +4156,33 @@ hostapd_ctrl_iface_dump_amnt(struct hostapd_data *hapd, char *cmd,
+@@ -4221,6 +4221,33 @@ hostapd_ctrl_iface_dump_amnt(struct hostapd_data *hapd, char *cmd,
  		return pos - buf;
  }
  
@@ -69,7 +68,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4750,6 +4777,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4815,6 +4842,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  		if (pos)
  			*pos = ' ';
  		reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 23, reply, reply_size);
@@ -80,7 +79,7 @@
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 7c0d12a..b6f05e7 100644
+index 7c0d12a3b..b6f05e7af 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1025,6 +1025,7 @@ struct hostapd_config {
@@ -104,7 +103,7 @@
  	DFS_DETECT_MODE_DISABLE,
  	DFS_DETECT_MODE_AP_ENABLE,
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 721bfa0..5b93ea6 100644
+index 721bfa053..5b93ea647 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1257,3 +1257,17 @@ int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_
@@ -126,7 +125,7 @@
 +						   hapd->iconf->background_radar_mode);
 +}
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 008596b..2564168 100644
+index 008596bb2..2564168bb 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -983,6 +983,9 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
@@ -150,7 +149,7 @@
  
  	return 0;
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index e140de6..5bc1e04 100644
+index e140de60b..5bc1e0444 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -16,6 +16,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -180,10 +179,10 @@
  #define ETH_ALEN 6
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index a9f48a1..bc82d28 100644
+index b0a6e3514..0c1b2e452 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5201,6 +5201,13 @@ struct wpa_driver_ops {
+@@ -5204,6 +5204,13 @@ struct wpa_driver_ops {
  	* @amnt_dump_buf: Buffer to print
  	*/
  	int (*amnt_dump)(void *priv, u8 amnt_idx, u8 *amnt_dump_buf);
@@ -198,10 +197,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 25e5910..73401fd 100644
+index b3897e61d..3cbf8610a 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14723,6 +14723,39 @@ fail:
+@@ -14743,6 +14743,39 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -241,14 +240,14 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14895,4 +14928,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14915,4 +14948,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.ap_trigtype = nl80211_ap_trigtype,
  	.amnt_set = nl80211_amnt_set,
  	.amnt_dump = nl80211_amnt_dump,
 +	.background_radar_mode = nl80211_background_radar_mode,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 0d85adf..74ee9b1 100644
+index 0d85adfee..74ee9b191 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -210,6 +210,7 @@ struct wpa_driver_nl80211_data {
@@ -260,10 +259,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 8c8b84e..90711b4 100644
+index 4bd15f348..74c3e0d86 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1133,6 +1133,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1137,6 +1137,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
  					drv->mtk_rfeatures_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0050-mtk-hostapd-add-support-enable-disable-preamble-punc.patch
similarity index 91%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0050-mtk-hostapd-add-support-enable-disable-preamble-punc.patch
index 4178b68..fc9a02d 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0050-mtk-hostapd-add-support-enable-disable-preamble-punc.patch
@@ -1,8 +1,8 @@
-From df3d6a354fc1243f8c862f2b61ee9ac09eabe482 Mon Sep 17 00:00:00 2001
+From d0f78e1b2efd0d0842c98a8733b06a7b59a9bd07 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Thu, 21 Sep 2023 10:29:46 +0800
-Subject: [PATCH] hostapd: mtk: add support enable/disable preamble puncture
- from mtk vendor command
+Subject: [PATCH 50/54] mtk: hostapd: add support enable/disable preamble
+ puncture from mtk vendor command
 
 This commit supports two ways to enable/disable preamble puncture
 feature.
@@ -40,7 +40,7 @@
  12 files changed, 161 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index a751993..278f6b3 100644
+index a75199345..278f6b347 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -4801,6 +4801,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
@@ -69,10 +69,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 517ebd6..7315d12 100644
+index f7c7a09f3..64bab0228 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -4183,6 +4183,59 @@ hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cm
+@@ -4248,6 +4248,59 @@ hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cm
  	return os_snprintf(buf, buflen, "OK\n");
  }
  
@@ -132,7 +132,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4769,6 +4822,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4834,6 +4887,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
  							reply, reply_size);
@@ -146,7 +146,7 @@
  		// Replace first ':' with a single space ' '
  		char *pos = buf + 23;
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 223db56..d8dd549 100644
+index 223db56eb..d8dd5495a 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -302,6 +302,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -158,7 +158,7 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index b6f05e7..9e39e82 100644
+index b6f05e7af..9e39e8285 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -1205,6 +1205,7 @@ struct hostapd_config {
@@ -183,7 +183,7 @@
  #define EDCCA_MIN_COMPENSATION -126
  #define EDCCA_MAX_COMPENSATION 126
 diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 5b93ea6..d0d8279 100644
+index 5b93ea647..d0d8279e2 100644
 --- a/src/ap/ap_drv_ops.c
 +++ b/src/ap/ap_drv_ops.c
 @@ -1271,3 +1271,12 @@ int hostapd_drv_background_radar_mode(struct hostapd_data *hapd)
@@ -200,7 +200,7 @@
 +					 hapd->iconf->pp_mode);
 +}
 diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 1e7ae7a..e4c2827 100644
+index 1e7ae7a8d..e4c2827bf 100644
 --- a/src/ap/ap_drv_ops.h
 +++ b/src/ap/ap_drv_ops.h
 @@ -163,6 +163,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
@@ -212,7 +212,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 2b563a5..90c6c26 100644
+index f01f607f3..2ffa3d4ea 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2526,6 +2526,8 @@ dfs_offload:
@@ -225,7 +225,7 @@
  	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
  		   iface->bss[0]->conf->iface);
 diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 5bc1e04..6275c14 100644
+index 5bc1e0444..6275c141d 100644
 --- a/src/common/mtk_vendor.h
 +++ b/src/common/mtk_vendor.h
 @@ -17,6 +17,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -255,10 +255,10 @@
  #define ETH_ALEN 6
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index bc82d28..261ed80 100644
+index 0c1b2e452..fb463aaac 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5208,6 +5208,12 @@ struct wpa_driver_ops {
+@@ -5211,6 +5211,12 @@ struct wpa_driver_ops {
  	 * @background_radar_mode: background radar mode
  	 */
  	int (*background_radar_mode)(void *priv, u8 background_radar_mode);
@@ -272,10 +272,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 2089ad6..3cc55dc 100644
+index 3cbf8610a..cbe793cc6 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -141,6 +141,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
+@@ -151,6 +151,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
  	[MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
  };
  
@@ -287,7 +287,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14756,6 +14761,49 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m
+@@ -14776,6 +14781,49 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m
  	return ret;
  }
  
@@ -337,14 +337,14 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14929,4 +14977,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14949,4 +14997,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.amnt_set = nl80211_amnt_set,
  	.amnt_dump = nl80211_amnt_dump,
  	.background_radar_mode = nl80211_background_radar_mode,
 +	.pp_mode_set = nl80211_pp_mode_set,
  };
 diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 74ee9b1..1bba5b1 100644
+index 74ee9b191..1bba5b14e 100644
 --- a/src/drivers/driver_nl80211.h
 +++ b/src/drivers/driver_nl80211.h
 @@ -211,6 +211,7 @@ struct wpa_driver_nl80211_data {
@@ -356,10 +356,10 @@
  	u64 vendor_scan_cookie;
  	u64 remain_on_chan_cookie;
 diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 90711b4..f2c42b9 100644
+index 74c3e0d86..0e044b03c 100644
 --- a/src/drivers/driver_nl80211_capa.c
 +++ b/src/drivers/driver_nl80211_capa.c
-@@ -1136,6 +1136,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+@@ -1140,6 +1140,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  				case MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL:
  					drv->mtk_background_radar_vendor_cmd_avail = 1;
  					break;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0051-mtk-hostapd-add-no_beacon-vendor-command-for-cert.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0051-mtk-hostapd-add-no_beacon-vendor-command-for-cert.patch
new file mode 100644
index 0000000..5f7489e
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0051-mtk-hostapd-add-no_beacon-vendor-command-for-cert.patch
@@ -0,0 +1,247 @@
+From 1ca50d17101a4812a424ed5eb6ae10d54635b055 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Wed, 22 Nov 2023 21:41:34 +0800
+Subject: [PATCH 51/54] mtk: hostapd: add no_beacon vendor command for cert
+
+Add the vendor command to disable/enable beacon
+
+[Usage]
+hostapd_cli -i <interface> no_beacon <value>
+ <value>
+ 0: enable beacon
+ 1: disable beacon
+
+Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
+---
+ hostapd/ctrl_iface.c              | 21 +++++++++++++++++++
+ hostapd/hostapd_cli.c             |  7 +++++++
+ src/ap/ap_drv_ops.c               |  8 ++++++++
+ src/ap/ap_drv_ops.h               |  1 +
+ src/common/mtk_vendor.h           | 12 +++++++++++
+ src/drivers/driver.h              |  7 +++++++
+ src/drivers/driver_nl80211.c      | 34 +++++++++++++++++++++++++++++++
+ src/drivers/driver_nl80211.h      |  1 +
+ src/drivers/driver_nl80211_capa.c |  3 +++
+ 9 files changed, 94 insertions(+)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index 64bab0228..7406aef38 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -4301,6 +4301,24 @@ hostapd_ctrl_iface_get_pp(struct hostapd_data *hapd, char *cmd, char *buf,
+ 	}
+ }
+ 
++static int
++hostapd_ctrl_iface_disable_beacon(struct hostapd_data *hapd, char *value,
++				  char *buf, size_t buflen)
++{
++	int disable_beacon = atoi(value);
++
++	if (disable_beacon < 0) {
++		wpa_printf(MSG_ERROR, "Invalid value for beacon ctrl");
++		return -1;
++	}
++
++	if (hostapd_drv_beacon_ctrl(hapd, !disable_beacon) == 0)
++		return os_snprintf(buf, buflen, "OK\n");
++	else
++		return -1;
++
++}
++
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+ 					      int reply_size,
+@@ -4904,6 +4922,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "SET_BACKGROUND_RADAR_MODE", 25) == 0) {
+ 		reply_len = hostapd_ctrl_iface_set_background_radar_mode(hapd, buf + 25,
+ 									 reply, reply_size);
++	} else if (os_strncmp(buf, "NO_BEACON ", 10) == 0) {
++		reply_len = hostapd_ctrl_iface_disable_beacon(hapd, buf + 10, reply,
++							      reply_size);
+ 	} else {
+ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ 		reply_len = 16;
+diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
+index 363a6bb93..d5b6d59f3 100644
+--- a/hostapd/hostapd_cli.c
++++ b/hostapd/hostapd_cli.c
+@@ -1422,6 +1422,11 @@ static int hostapd_cli_cmd_get_mu(struct wpa_ctrl *ctrl, int argc,
+ 	return hostapd_cli_cmd(ctrl, "GET_MU", 0, NULL, NULL);
+ }
+ 
++static int hostapd_cli_cmd_disable_beacon(struct wpa_ctrl *ctrl, int argc,
++					   char *argv[])
++{
++	return hostapd_cli_cmd(ctrl, "NO_BEACON", 1, argc, argv);
++}
+ 
+ #ifdef CONFIG_DPP
+ 
+@@ -1799,6 +1804,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
+ 		"<value> [0-15] bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0)"},
+ 	{ "get_mu", hostapd_cli_cmd_get_mu, NULL,
+ 		" = show mu onoff value in 0-15 bitmap"},
++	{ "no_beacon", hostapd_cli_cmd_disable_beacon, NULL,
++		"<value> 0: Enable beacon, 1: Disable beacon"},
+ #ifdef CONFIG_DPP
+ 	{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
+ 	  "report a scanned DPP URI from a QR Code" },
+diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
+index d0d8279e2..073c05de8 100644
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -1280,3 +1280,11 @@ int hostapd_drv_pp_mode_set(struct hostapd_data *hapd)
+ 	return hapd->driver->pp_mode_set(hapd->drv_priv,
+ 					 hapd->iconf->pp_mode);
+ }
++
++int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode)
++{
++	if (!hapd->driver || !hapd->driver->beacon_ctrl)
++		return 0;
++	return hapd->driver->beacon_ctrl(hapd->drv_priv, beacon_mode);
++}
++
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index e4c2827bf..6b9e454de 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -164,6 +164,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
+ int hostapd_drv_amnt_set(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_sta_mac);
+ int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_buf);
+ int hostapd_drv_pp_mode_set(struct hostapd_data *hapd);
++int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode);
+ 
+ #include "drivers/driver.h"
+ 
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index 6275c141d..5531802b8 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -18,6 +18,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ 	MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
+ 	MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
++	MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL = 0xcd,
+ };
+ 
+ enum mtk_vendor_attr_edcca_ctrl {
+@@ -268,6 +269,17 @@ enum mtk_vendor_attr_pp_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_PP_CTRL - 1
+ };
+ 
++enum mtk_vendor_attr_beacon_ctrl {
++	MTK_VENDOR_ATTR_BEACON_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_BEACON_CTRL_MODE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_BEACON_CTRL,
++	MTK_VENDOR_ATTR_BEACON_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_BEACON_CTRL - 1
++};
++
+ #define CSI_MAX_COUNT 256
+ #define ETH_ALEN 6
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index fb463aaac..40f6150d7 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -5128,6 +5128,13 @@ struct wpa_driver_ops {
+ 	 int (*mu_ctrl)(void *priv, u8 mode, void *config);
+ 	 int (*mu_dump)(void *priv, u8 *mu_onoff);
+ 
++	/**
++	 * beacon_ctrl - ctrl on off for beacon
++	 * @priv: Private driver interface data
++	 *
++	 */
++	int (*beacon_ctrl)(void *priv, u8 beacon_mode);
++
+ 	/**
+ 	 * three_wire_ctrl - set three_wire_ctrl mode
+ 	 * @priv: Private driver interface data
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index cbe793cc6..9a10a93f0 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -13827,6 +13827,39 @@ static int nl80211_mu_dump(void *priv, u8 *mu_onoff)
+ 
+ 	return ret;
+ }
++static int nl80211_beacon_ctrl(void *priv, u8 beacon_mode)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data;
++	int ret;
++
++	if (!drv->mtk_beacon_ctrl_vendor_cmd_avail) {
++		wpa_printf(MSG_ERROR,
++			   "nl80211: Driver does not support setting beacon control");
++		return 0;
++	}
++
++	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL) ||
++		!(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
++		nla_put_u8(msg, MTK_VENDOR_ATTR_BEACON_CTRL_MODE, beacon_mode)) {
++		nlmsg_free(msg);
++		return -ENOBUFS;
++	}
++
++	nla_nest_end(msg, data);
++
++	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
++
++	if (ret)
++		wpa_printf(MSG_ERROR, "Failed to set beacon_ctrl. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++}
++
+ #endif /* CONFIG_IEEE80211AX */
+ 
+ 
+@@ -14972,6 +15005,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.set_4addr_mode = nl80211_set_4addr_mode,
+ 	.mu_ctrl = nl80211_mu_ctrl,
+ 	.mu_dump = nl80211_mu_dump,
++	.beacon_ctrl = nl80211_beacon_ctrl,
+ #ifdef CONFIG_DPP
+ 	.dpp_listen = nl80211_dpp_listen,
+ #endif /* CONFIG_DPP */
+diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
+index 1bba5b14e..300c0d11a 100644
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -212,6 +212,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_amnt_vendor_cmd_avail:1;
+ 	unsigned int mtk_background_radar_vendor_cmd_avail:1;
+ 	unsigned int mtk_pp_vendor_cmd_avail:1;
++	unsigned int mtk_beacon_ctrl_vendor_cmd_avail:1;
+ 
+ 	u64 vendor_scan_cookie;
+ 	u64 remain_on_chan_cookie;
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index 0e044b03c..2f844053d 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1143,6 +1143,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+ 				case MTK_NL80211_VENDOR_SUBCMD_PP_CTRL:
+ 					drv->mtk_pp_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL :
++					drv->mtk_beacon_ctrl_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0052-mtk-hostapd-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
similarity index 75%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0052-mtk-hostapd-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
index d2b117c..f5b5c24 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0052-mtk-hostapd-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
@@ -1,7 +1,8 @@
-From 88f5a4c1c67f8fc40c8294c498faa72e1ceea470 Mon Sep 17 00:00:00 2001
+From 1f6c4857cb55c8ba81a50f3fe0a1465efee10513 Mon Sep 17 00:00:00 2001
 From: "fancy.liu" <fancy.liu@mediatek.com>
 Date: Thu, 28 Sep 2023 18:03:08 +0800
-Subject: [PATCH] hostapd: mtk: [ACS] Add EHT320 and HT40- support, fix issue
+Subject: [PATCH 52/54] mtk: hostapd: ACS: Add EHT320 and HT40- support, fix
+ issue
 
 1. Add 6G EHT320 support;
 2. Add 2.4G HT40- support;
@@ -9,11 +10,11 @@
 
 Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
 ---
- src/ap/acs.c | 222 +++++++++++++++++++++++++++++++--------------------
- 1 file changed, 136 insertions(+), 86 deletions(-)
+ src/ap/acs.c | 191 +++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 124 insertions(+), 67 deletions(-)
 
 diff --git a/src/ap/acs.c b/src/ap/acs.c
-index af31405..ed6a47b 100644
+index af3140542..e4871921f 100644
 --- a/src/ap/acs.c
 +++ b/src/ap/acs.c
 @@ -245,6 +245,7 @@ enum bw_type {
@@ -41,20 +42,7 @@
  };
  
  
-@@ -583,12 +590,6 @@ static void acs_survey_mode_interference_factor(
- 		    iface->conf->acs_exclude_dfs)
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
--
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
- 
-@@ -775,17 +776,29 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -775,10 +782,19 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  			 struct hostapd_channel_data **ideal_chan,
  			 long double *ideal_factor)
  {
@@ -75,9 +63,8 @@
  
  	for (i = 0; i < mode->num_channels; i++) {
  		double total_weight;
- 		struct acs_bias *bias, tmp_bias;
--		bool update_best = true;
-+		bool update_best = true, has_candidate = true;
+@@ -786,6 +802,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		bool update_best = true;
  
  		best = chan = &mode->channels[i];
 +		wpa_printf(MSG_INFO,
@@ -86,25 +73,7 @@
  
  		/* Since in the current ACS implementation the first channel is
  		 * always a primary channel, skip channels not available as
-@@ -804,11 +817,12 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 		    iface->conf->acs_exclude_dfs)
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
-+		if (!is_in_chanlist(iface, chan) || !is_in_freqlist(iface, chan)) {
-+			if (is_24ghz_mode(mode->mode))
-+				continue;
-+			else
-+				has_candidate = false;
-+		}
- 
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
-@@ -817,7 +831,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -817,7 +836,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  		    iface->conf->country[2] == 0x4f)
  			continue;
  
@@ -113,7 +82,7 @@
  			wpa_printf(MSG_DEBUG,
  				   "ACS: Channel %d: BW %u is not supported",
  				   chan->chan, bw);
-@@ -838,7 +852,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -838,7 +857,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  		}
  
  		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
@@ -123,7 +92,7 @@
  			if (hostapd_get_oper_chwidth(iface->conf) ==
  			    CONF_OPER_CHWIDTH_80MHZ &&
  			    !acs_usable_bw_chan(chan, ACS_BW80)) {
-@@ -856,63 +871,89 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -856,63 +876,86 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  					   chan->chan);
  				continue;
  			}
@@ -153,12 +122,12 @@
 +				continue;
  			}
 +		}
-+
-+		factor = 0;
-+		total_weight = 0;
  
 -			if (acs_usable_chan(adj_chan)) {
 -				factor += adj_chan->interference_factor;
++		factor = 0;
++		total_weight = 0;
++
 +		if (!is_24ghz_mode(mode->mode)) {
 +			/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
 +			 * crowded primary channel if one was found in the segment */
@@ -185,12 +154,8 @@
 -				   chan->chan);
 -			continue;
 -		}
-+				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
-+					wpa_printf(MSG_DEBUG,
-+						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
-+						   chan->chan, adj_chan->chan, bw);
++				if (!is_in_chanlist(iface, adj_chan) || !is_in_freqlist(iface, adj_chan))
 +					break;
-+				}
  
 -		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
 -		 * crowded primary channel if one was found in the segment */
@@ -203,30 +168,31 @@
 -				   best->interference_factor);
 -			chan = best;
 -		}
++				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
++					wpa_printf(MSG_DEBUG,
++						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
++						   chan->chan, adj_chan->chan, bw);
++					break;
++				}
++
 +				update_best = true;
 +				if (acs_usable_chan(adj_chan)) {
 +					factor += adj_chan->interference_factor;
 +					total_weight += 1;
-+
-+					if (!is_in_chanlist(iface, adj_chan) ||
-+						!is_in_freqlist(iface, adj_chan))
-+						update_best = false;
 +				} else {
 +					update_best = false;
 +				}
-+
-+				/* find the best channel in this segment */
-+				if (update_best && (!has_candidate ||
-+					adj_chan->interference_factor < best->interference_factor)) {
-+					best = adj_chan;
-+					has_candidate = true;
-+				}
-+			}
  
 -		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
 -		 * channel interference factor. */
 -		if (is_24ghz_mode(mode->mode)) {
-+			if (j != n_chans || !has_candidate) {
++				/* find the best channel in this segment */
++				if (update_best &&
++					adj_chan->interference_factor < best->interference_factor)
++					best = adj_chan;
++			}
++
++			if (j != n_chans) {
 +				wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
 +					   chan->chan);
 +				continue;
@@ -244,7 +210,7 @@
  			for (j = 0; j < n_chans; j++) {
 +				/* Will set primary_channel / secondary_channel(40M case) weight to 1 */
 +				tmp_chan = acs_find_chan(iface, chan->freq +
-+							 (j * 20) * sec_ch_factor);
++							 (j * sec_ch_factor * 20));
 +				if (tmp_chan && acs_usable_chan(tmp_chan)) {
 +					factor += tmp_chan->interference_factor;
 +					total_weight += 1;
@@ -254,38 +220,38 @@
 +				interference factor, separately for primary/secondary channel. */
  				adj_chan = acs_find_chan(iface, chan->freq +
 -							 (j * 20) - 5);
-+							 ((j * 20) - 5) * sec_ch_factor);
++							 (j * sec_ch_factor * 20) - 5);
  				if (adj_chan && acs_usable_chan(adj_chan)) {
  					factor += ACS_ADJ_WEIGHT *
  						adj_chan->interference_factor;
-@@ -920,7 +961,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -920,7 +963,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  				}
  
  				adj_chan = acs_find_chan(iface, chan->freq +
 -							 (j * 20) - 10);
-+							 ((j * 20) - 10) * sec_ch_factor);
++							 (j * sec_ch_factor * 20) - 10);
  				if (adj_chan && acs_usable_chan(adj_chan)) {
  					factor += ACS_NEXT_ADJ_WEIGHT *
  						adj_chan->interference_factor;
-@@ -928,7 +969,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -928,7 +971,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  				}
  
  				adj_chan = acs_find_chan(iface, chan->freq +
 -							 (j * 20) + 5);
-+							 ((j * 20) + 5) * sec_ch_factor);
++							 (j * sec_ch_factor * 20) + 5);
  				if (adj_chan && acs_usable_chan(adj_chan)) {
  					factor += ACS_ADJ_WEIGHT *
  						adj_chan->interference_factor;
-@@ -936,7 +977,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -936,7 +979,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  				}
  
  				adj_chan = acs_find_chan(iface, chan->freq +
 -							 (j * 20) + 10);
-+							 ((j * 20) + 10) * sec_ch_factor);
++							 (j * sec_ch_factor * 20) + 10);
  				if (adj_chan && acs_usable_chan(adj_chan)) {
  					factor += ACS_NEXT_ADJ_WEIGHT *
  						adj_chan->interference_factor;
-@@ -945,7 +986,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -945,7 +988,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  			}
  		}
  
@@ -295,7 +261,7 @@
  
  		bias = NULL;
  		if (iface->conf->acs_chan_bias) {
-@@ -964,11 +1006,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+@@ -964,11 +1008,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
  
  		if (bias) {
  			factor *= bias->bias;
@@ -309,7 +275,7 @@
  				   "ACS:  * channel %d: total interference = %Lg",
  				   chan->chan, factor);
  		}
-@@ -1021,19 +1063,12 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+@@ -1021,19 +1065,12 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
  		goto bw_selected;
  	}
  
@@ -331,7 +297,7 @@
  		switch (hostapd_get_oper_chwidth(iface->conf)) {
  		case CONF_OPER_CHWIDTH_80MHZ:
  			n_chans = 4;
-@@ -1043,6 +1078,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+@@ -1043,6 +1080,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
  			break;
  		default:
  			break;
@@ -339,7 +305,7 @@
  		}
  	}
  
-@@ -1063,7 +1099,7 @@ bw_selected:
+@@ -1063,7 +1101,7 @@ bw_selected:
  	}
  
  	if (ideal_chan) {
@@ -348,7 +314,7 @@
  			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
  
  #ifdef CONFIG_IEEE80211BE
-@@ -1078,6 +1114,21 @@ bw_selected:
+@@ -1078,6 +1116,21 @@ bw_selected:
  	return rand_chan;
  }
  
@@ -370,21 +336,16 @@
  
  static void acs_adjust_secondary(struct hostapd_iface *iface)
  {
-@@ -1104,10 +1155,11 @@ static void acs_adjust_secondary(struct hostapd_iface *iface)
- static void acs_adjust_center_freq(struct hostapd_iface *iface)
+@@ -1105,7 +1158,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
  {
  	int center;
-+ 	u8 bw = hostapd_get_oper_chwidth(iface->conf);
  
 -	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
 +	wpa_printf(MSG_DEBUG, "ACS: Adjusting center frequency");
  
--	switch (hostapd_get_oper_chwidth(iface->conf)) {
-+	switch (bw) {
+ 	switch (hostapd_get_oper_chwidth(iface->conf)) {
  	case CONF_OPER_CHWIDTH_USE_HT:
- 		if (iface->conf->secondary_channel &&
- 		    iface->freq >= 2400 && iface->freq < 2500)
-@@ -1121,6 +1173,9 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+@@ -1121,6 +1174,9 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
  	case CONF_OPER_CHWIDTH_80MHZ:
  		center = acs_get_bw_center_chan(iface->freq, ACS_BW80);
  		break;
@@ -394,7 +355,7 @@
  	case CONF_OPER_CHWIDTH_160MHZ:
  		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
  		break;
-@@ -1128,7 +1183,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+@@ -1128,7 +1184,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
  		/* TODO: How can this be calculated? Adjust
  		 * acs_find_ideal_chan() */
  		wpa_printf(MSG_INFO,
@@ -403,7 +364,7 @@
  		return;
  	}
  
-@@ -1191,7 +1246,8 @@ static void acs_study(struct hostapd_iface *iface)
+@@ -1191,7 +1247,8 @@ static void acs_study(struct hostapd_iface *iface)
  	iface->conf->punct_bitmap = ideal_chan->punct_bitmap;
  #endif /* CONFIG_IEEE80211BE */
  
@@ -413,19 +374,6 @@
  		acs_adjust_secondary(iface);
  		acs_adjust_center_freq(iface);
  	}
-@@ -1270,12 +1326,6 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
- 		     iface->conf->acs_exclude_dfs))
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
--
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
- 
 -- 
-2.25.1
+2.18.0
 
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0053-mtk-hostapd-add-eht_bw320_offset-configuration-optio.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0053-mtk-hostapd-add-eht_bw320_offset-configuration-optio.patch
new file mode 100644
index 0000000..77677d0
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0053-mtk-hostapd-add-eht_bw320_offset-configuration-optio.patch
@@ -0,0 +1,190 @@
+From cb9841c4361d5c1d236b7d257e2d513ecc1c7c91 Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Tue, 17 Oct 2023 11:11:40 +0800
+Subject: [PATCH 53/54] mtk: hostapd: add eht_bw320_offset configuration option
+
+This patch introduces a new configuration option, "eht_bw320_offset",
+which enables devices to specify a preferred channelization for 320 MHz
+BSSs when using automatic channel selection (ACS).
+This option is only applicable when the channel is not already decided
+and the bandwidth is set to 320 MHz.
+
+The value and meaning of the option:
+0: auto-detected by hostapd
+1: 320 MHz-1
+2: 320 MHz-2
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ hostapd/config_file.c  |  3 +++
+ hostapd/hostapd.conf   |  8 ++++++++
+ src/ap/ap_config.c     |  6 ++++++
+ src/ap/ap_config.h     | 37 +++++++++++++++++++++++++++++++++++++
+ src/ap/ctrl_iface_ap.c | 11 +++++++++++
+ src/ap/drv_callbacks.c |  2 ++
+ 6 files changed, 67 insertions(+)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index 278f6b347..721685baf 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -4822,6 +4822,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 				   line);
+ 			return 1;
+ 		}
++	} else if (os_strcmp(buf, "eht_bw320_offset") == 0) {
++		u8 val = atoi(pos);
++		conf->eht_bw320_offset = val;
+ #endif /* CONFIG_IEEE80211BE */
+ 	} else if (os_strcmp(buf, "edcca_threshold") == 0) {
+ 		if (hostapd_parse_intlist(&conf->edcca_threshold, pos) ||
+diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
+index f16e3b08d..290504317 100644
+--- a/hostapd/hostapd.conf
++++ b/hostapd/hostapd.conf
+@@ -1032,6 +1032,14 @@ wmm_ac_vo_acm=0
+ #eht_oper_chwidth (see vht_oper_chwidth)
+ #eht_oper_centr_freq_seg0_idx
+ 
++#eht_bw320_offset: For automatic channel selection (ACS) to indicate a prefered
++# 320 MHz channelization in EHT mode.
++# If the channel is decided or the bandwidth is not 320 MHz, this option is meaningless.
++# 0 = auto-detect by hostapd
++# 1 = 320 MHz-1
++# 2 = 320 MHz-2
++#eht_bw320_offset=0
++
+ # Disabled subchannel bitmap (16 bits) as per IEEE P802.11be/3.0,
+ # Figure 9-1002c (EHT Operation Information field format). Each bit corresponds
+ # to a 20 MHz channel, the lowest bit corresponds to the lowest frequency. A
+diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
+index d8dd5495a..3fb98d08f 100644
+--- a/src/ap/ap_config.c
++++ b/src/ap/ap_config.c
+@@ -304,6 +304,7 @@ struct hostapd_config * hostapd_config_defaults(void)
+ 	conf->amsdu = 1;
+ 	conf->pp_mode = PP_DISABLE;
+ 
++	hostapd_set_and_check_bw320_offset(conf, 0);
+ 	return conf;
+ }
+ 
+@@ -1515,6 +1516,7 @@ static int hostapd_config_check_cw(struct hostapd_config *conf, int queue)
+ int hostapd_config_check(struct hostapd_config *conf, int full_config)
+ {
+ 	size_t i;
++	u8 bw320_offset = 0;
+ 
+ 	if (full_config && is_6ghz_op_class(conf->op_class) &&
+ 	    !conf->hw_mode_set) {
+@@ -1566,6 +1568,8 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
+ 			   "Cannot set ieee80211be without ieee80211ax");
+ 		return -1;
+ 	}
++
++	bw320_offset = conf->eht_bw320_offset;
+ #endif /* CONFIG_IEEE80211BE */
+ 
+ 	if (full_config && conf->mbssid && !conf->ieee80211ax) {
+@@ -1574,6 +1578,8 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
+ 		return -1;
+ 	}
+ 
++	hostapd_set_and_check_bw320_offset(conf, bw320_offset);
++
+ 	for (i = 0; i < conf->num_bss; i++) {
+ 		if (hostapd_config_check_bss(conf->bss[i], conf, full_config))
+ 			return -1;
+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
+index 9e39e8285..3e0505594 100644
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -1184,6 +1184,7 @@ struct hostapd_config {
+ 	struct eht_phy_capabilities_info eht_phy_capab;
+ 	u16 punct_bitmap; /* a bitmap of disabled 20 MHz channels */
+ 	u8 punct_acs_threshold;
++	u8 eht_bw320_offset;
+ #endif /* CONFIG_IEEE80211BE */
+ 
+ 	/* EHT enable/disable config from CHAN_SWITCH */
+@@ -1355,6 +1356,42 @@ hostapd_set_oper_centr_freq_seg1_idx(struct hostapd_config *conf,
+ 	conf->vht_oper_centr_freq_seg1_idx = oper_centr_freq_seg1_idx;
+ }
+ 
++static inline u8
++hostapd_get_bw320_offset(struct hostapd_config *conf)
++{
++#ifdef CONFIG_IEEE80211BE
++	if (conf->ieee80211be && is_6ghz_op_class(conf->op_class) &&
++	    hostapd_get_oper_chwidth(conf) == CONF_OPER_CHWIDTH_320MHZ)
++		return conf->eht_bw320_offset;
++#endif /* CONFIG_IEEE80211BE */
++	return 0;
++}
++
++static inline void
++hostapd_set_and_check_bw320_offset(struct hostapd_config *conf,
++				   u8 bw320_offset)
++{
++#ifdef CONFIG_IEEE80211BE
++	if (conf->ieee80211be && is_6ghz_op_class(conf->op_class) &&
++	    hostapd_get_oper_chwidth(conf) == CONF_OPER_CHWIDTH_320MHZ) {
++		if (conf->channel) {
++			/* If the channel is set, then calculate bw320_offset
++			 * by center frequency segment 0.
++			 */
++			u8 seg0 = hostapd_get_oper_centr_freq_seg0_idx(conf);
++			conf->eht_bw320_offset = (seg0 - 31) % 64 ? 2 : 1;
++		} else {
++			/* If the channel is not set, bw320_offset indicates
++			 * prefered offset of 320 MHz.
++			 */
++			conf->eht_bw320_offset = bw320_offset;
++		}
++	} else {
++		conf->eht_bw320_offset = 0;
++	}
++#endif /* CONFIG_IEEE80211BE */
++}
++
+ #define IBF_DEFAULT_ENABLE 0
+ 
+ int hostapd_mac_comp(const void *a, const void *b);
+diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
+index 7bdefb4cf..e686fb8b7 100644
+--- a/src/ap/ctrl_iface_ap.c
++++ b/src/ap/ctrl_iface_ap.c
+@@ -831,6 +831,17 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
+ 		if (os_snprintf_error(buflen - len, ret))
+ 			return len;
+ 		len += ret;
++
++		if (is_6ghz_op_class(iface->conf->op_class) &&
++		    hostapd_get_oper_chwidth(iface->conf) ==
++		    CONF_OPER_CHWIDTH_320MHZ) {
++			ret = os_snprintf(buf + len, buflen - len,
++					  "eht_bw320_offset=%d\n",
++					  iface->conf->eht_bw320_offset);
++			if (os_snprintf_error(buflen - len, ret))
++				return len;
++			len += ret;
++		}
+ 	}
+ #endif /* CONFIG_IEEE80211BE */
+ 
+diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
+index 12419c6d4..b0d9420e8 100644
+--- a/src/ap/drv_callbacks.c
++++ b/src/ap/drv_callbacks.c
+@@ -1175,6 +1175,8 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
+ 	hostapd_set_oper_chwidth(hapd->iconf, chwidth);
+ 	hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx);
+ 	hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx);
++	/* Auto-detect new bw320_offset */
++	hostapd_set_and_check_bw320_offset(hapd->iconf, 0);
+ #ifdef CONFIG_IEEE80211BE
+ 	hapd->iconf->punct_bitmap = punct_bitmap;
+ #endif /* CONFIG_IEEE80211BE */
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0054-mtk-hostapd-WPS-added-change-to-configure-AP-PIN-loc.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0054-mtk-hostapd-WPS-added-change-to-configure-AP-PIN-loc.patch
new file mode 100644
index 0000000..fab7706
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0054-mtk-hostapd-WPS-added-change-to-configure-AP-PIN-loc.patch
@@ -0,0 +1,65 @@
+From 44d5b6d691a45b71d2e8896f3302b4b946ae4d33 Mon Sep 17 00:00:00 2001
+From: "amlendu.mishra" <amlendu.mishra@mediatek.com>
+Date: Wed, 13 Dec 2023 18:13:01 +0530
+Subject: [PATCH 54/54] mtk: hostapd: WPS added change to configure AP PIN lock
+ timout
+
+added config paramter ap_pin_lockout_time to configure
+AP PIN timeout from hosatpd.conf
+
+
+Signed-off-by: amlendu.mishra <amlendu.mishra@mediatek.com>
+---
+ hostapd/config_file.c | 2 ++
+ src/ap/ap_config.h    | 1 +
+ src/ap/wps_hostapd.c  | 9 ++++++---
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index 721685baf..9dd86e037 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -3709,6 +3709,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 		bss->wps_independent = atoi(pos);
+ 	} else if (os_strcmp(buf, "ap_setup_locked") == 0) {
+ 		bss->ap_setup_locked = atoi(pos);
++	} else if (os_strcmp(buf, "ap_pin_lockout_time") == 0) {
++		bss->ap_pin_lockout_time = atoi(pos);
+ 	} else if (os_strcmp(buf, "uuid") == 0) {
+ 		if (uuid_str2bin(pos, bss->uuid)) {
+ 			wpa_printf(MSG_ERROR, "Line %d: invalid UUID", line);
+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
+index 3e0505594..c03fa11b6 100644
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -491,6 +491,7 @@ struct hostapd_bss_config {
+ #ifdef CONFIG_WPS
+ 	int wps_independent;
+ 	int ap_setup_locked;
++	unsigned int ap_pin_lockout_time;
+ 	u8 uuid[16];
+ 	char *wps_pin_requests;
+ 	char *device_name;
+diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
+index 0c351af5f..ea2608917 100644
+--- a/src/ap/wps_hostapd.c
++++ b/src/ap/wps_hostapd.c
+@@ -768,9 +768,12 @@ static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx)
+ 		eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
+ 		wpa_printf(MSG_DEBUG, "WPS: AP PIN disabled indefinitely");
+ 	} else if (!hapd->conf->ap_setup_locked) {
+-		if (hapd->ap_pin_lockout_time == 0)
+-			hapd->ap_pin_lockout_time = 60;
+-		else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
++		if (hapd->ap_pin_lockout_time == 0) {
++			if (hapd->conf->ap_pin_lockout_time)
++				hapd->ap_pin_lockout_time = hapd->conf->ap_pin_lockout_time;
++			else
++				hapd->ap_pin_lockout_time = 60;
++		} else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
+ 			 (hapd->ap_pin_failures % 3) == 0)
+ 			hapd->ap_pin_lockout_time *= 2;
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch
deleted file mode 100644
index 5092a61..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1001-hostapd-mtk-update-eht-operation-element.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From eaf03e5841437d268c929bd8215d8499fbdbfbb0 Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Wed, 10 May 2023 13:11:34 +0800
-Subject: [PATCH 1001/1005] hostapd: mtk: update eht operation element
-
----
- src/ap/ieee802_11_eht.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c
-index 9a07f75..f132e1d 100644
---- a/src/ap/ieee802_11_eht.c
-+++ b/src/ap/ieee802_11_eht.c
-@@ -215,9 +215,9 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid)
- 
- 	/* TODO: Fill in appropriate EHT-MCS max Nss information */
- 	oper->basic_eht_mcs_nss_set[0] = 0x11;
--	oper->basic_eht_mcs_nss_set[1] = 0x00;
--	oper->basic_eht_mcs_nss_set[2] = 0x00;
--	oper->basic_eht_mcs_nss_set[3] = 0x00;
-+	oper->basic_eht_mcs_nss_set[1] = 0x11;
-+	oper->basic_eht_mcs_nss_set[2] = 0x11;
-+	oper->basic_eht_mcs_nss_set[3] = 0x11;
- 
- 	if (is_6ghz_op_class(conf->op_class))
- 		chwidth = op_class_to_ch_width(conf->op_class);
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch
deleted file mode 100644
index 9c23287..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 5d04c65f6a625dea4b8ff7cfa35311dbfa2e4ae7 Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Wed, 30 Aug 2023 04:23:37 +0800
-Subject: [PATCH 1002/1005] hostapd: mtk: ucode: add support for ucode to parse
- BW320MHz info
-
----
- src/utils/ucode.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/utils/ucode.c b/src/utils/ucode.c
-index 2beeb9a..122c619 100644
---- a/src/utils/ucode.c
-+++ b/src/utils/ucode.c
-@@ -85,6 +85,10 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
- 	case 2:
- 		chanwidth = CONF_OPER_CHWIDTH_160MHZ;
- 		break;
-+	case 9:
-+		width = 3;
-+		chanwidth = CONF_OPER_CHWIDTH_320MHZ;
-+		break;
- 	default:
- 		return NULL;
- 	}
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch
deleted file mode 100644
index 5a63279..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch
+++ /dev/null
@@ -1,279 +0,0 @@
-From 804f9b03e7f143d3a80741cb67721810e27ed2d8 Mon Sep 17 00:00:00 2001
-From: Michael-CY Lee <michael-cy.lee@mediatek.com>
-Date: Mon, 11 Sep 2023 10:16:35 +0800
-Subject: [PATCH] hostapd: mtk: synchronize bandwidth in AP/STA support
-
-Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
----
- src/ap/ucode.c         | 41 +++++++++++++++++++--
- src/utils/ucode.c      | 12 +++++--
- wpa_supplicant/ucode.c | 82 ++++++++++++++++++++++++++++++++++--------
- 3 files changed, 117 insertions(+), 18 deletions(-)
-
-diff --git a/src/ap/ucode.c b/src/ap/ucode.c
-index af97091..79d568f 100644
---- a/src/ap/ucode.c
-+++ b/src/ap/ucode.c
-@@ -489,6 +489,9 @@ uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs)
- 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
- 	int i;
- 
-+	wpa_printf(MSG_INFO, "ucode: mtk: stop iface for %s in state %s\n",
-+			iface->phy, hostapd_state_text(iface->state));
-+
- 	if (!iface)
- 		return NULL;
- 
-@@ -515,6 +518,9 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs)
- 	uint64_t intval;
- 	int i;
- 
-+	wpa_printf(MSG_INFO, "ucode: mtk: start iface for %s in state %s\n",
-+			iface->phy, hostapd_state_text(iface->state));
-+
- 	if (!iface)
- 		return NULL;
- 
-@@ -537,7 +543,13 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs)
- 	UPDATE_VAL(op_class, "op_class");
- 	UPDATE_VAL(hw_mode, "hw_mode");
- 	UPDATE_VAL(channel, "channel");
--	UPDATE_VAL(secondary_channel, "sec_channel");
-+
-+	intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL));
-+	if (!errno) {
-+		conf->secondary_channel = intval;
-+		changed = true;
-+	}
-+
- 	if (!changed &&
- 	    (iface->bss[0]->beacon_set_done ||
- 	     iface->state == HAPD_IFACE_DFS))
-@@ -583,6 +595,18 @@ out:
- 		return ucv_boolean_new(true);
- 	}
- 
-+	wpa_printf(MSG_INFO, "ucode: mtk: updated channel information:\n");
-+	wpa_printf(MSG_INFO, "    * channel: %d\n", conf->channel);
-+	wpa_printf(MSG_INFO, "    * op_class: %d\n", conf->op_class);
-+	wpa_printf(MSG_INFO, "    * secondary channel: %d\n",
-+			conf->secondary_channel);
-+	wpa_printf(MSG_INFO, "    * seg0: %d\n",
-+			hostapd_get_oper_centr_freq_seg0_idx(conf));
-+	wpa_printf(MSG_INFO, "    * seg1: %d\n",
-+			hostapd_get_oper_centr_freq_seg0_idx(conf));
-+	wpa_printf(MSG_INFO, "    * oper_chwidth: %d\n",
-+			hostapd_get_oper_chwidth(conf));
-+
- 	for (i = 0; i < iface->num_bss; i++) {
- 		struct hostapd_data *hapd = iface->bss[i];
- 		int ret;
-@@ -617,6 +641,7 @@ uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs)
- 	uint64_t intval;
- 	int i, ret = 0;
- 
-+	wpa_printf(MSG_INFO, "ucode: mtk: channel switch for %s\n", iface->phy);
- 	if (!iface || ucv_type(info) != UC_OBJECT)
- 		return NULL;
- 
-@@ -636,7 +661,8 @@ uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs)
- 	if (errno)
- 		intval = hostapd_get_oper_chwidth(conf);
- 	if (intval)
--		csa.freq_params.bandwidth = 40 << intval;
-+		csa.freq_params.bandwidth = 40 <<
-+			(intval == CONF_OPER_CHWIDTH_320MHZ ? 3 : intval);
- 	else
- 		csa.freq_params.bandwidth = csa.freq_params.sec_channel_offset ? 40 : 20;
- 
-@@ -647,6 +673,17 @@ uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs)
- 	if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq2", NULL))) && !errno)
- 		csa.freq_params.center_freq2 = intval;
- 
-+	wpa_printf(MSG_INFO, "ucode: mtk: switch channel information:\n");
-+	wpa_printf(MSG_INFO, "    * freq is %d\n", csa.freq_params.freq);
-+	wpa_printf(MSG_INFO, "    * bandwidth is %d\n",
-+			csa.freq_params.bandwidth);
-+	wpa_printf(MSG_INFO, "    * sec_chan_offset is %d\n",
-+			csa.freq_params.sec_channel_offset);
-+	wpa_printf(MSG_INFO, "    * center_freq1 is %d\n",
-+			csa.freq_params.center_freq1);
-+	wpa_printf(MSG_INFO, "    * center_freq2 is %d\n",
-+			csa.freq_params.center_freq2);
-+
- 	for (i = 0; i < iface->num_bss; i++)
- 		ret = hostapd_switch_channel(iface->bss[i], &csa);
- 
-diff --git a/src/utils/ucode.c b/src/utils/ucode.c
-index 122c619..0990e7b 100644
---- a/src/utils/ucode.c
-+++ b/src/utils/ucode.c
-@@ -51,6 +51,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
- 	uc_value_t *freq = uc_fn_arg(0);
- 	uc_value_t *sec = uc_fn_arg(1);
- 	int width = ucv_uint64_get(uc_fn_arg(2));
-+	int bw320_offset = 1;
- 	int freq_val, center_idx, center_ofs;
- 	enum oper_chan_width chanwidth;
- 	enum hostapd_hw_mode hw_mode;
-@@ -88,6 +89,9 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
- 	case 9:
- 		width = 3;
- 		chanwidth = CONF_OPER_CHWIDTH_320MHZ;
-+
-+		/* bw320_offset is 1 for 320 MHz-1, and 2 for 320 MHz-2 */
-+		bw320_offset = ucv_uint64_get(uc_fn_arg(3));
- 		break;
- 	default:
- 		return NULL;
-@@ -119,12 +123,16 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
- 	ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr)));
- 	ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel));
- 	ucv_object_add(ret, "frequency", ucv_int64_new(freq_val));
-+	ucv_object_add(ret, "oper_chwidth", ucv_int64_new(chanwidth));
- 
--	if (!sec_channel)
-+	if (chanwidth == CONF_OPER_CHWIDTH_USE_HT && !sec_channel) {
-+		ucv_object_add(ret, "center_seg0_idx", ucv_int64_new(channel));
-+		ucv_object_add(ret, "center_freq1", ucv_int64_new(freq_val));
- 		return ret;
-+	}
- 
- 	if (freq_val >= 5900)
--		center_ofs = 0;
-+		center_ofs = 32 * (1 - bw320_offset);
- 	else if (freq_val >= 5745)
- 		center_ofs = 20;
- 	else
-diff --git a/wpa_supplicant/ucode.c b/wpa_supplicant/ucode.c
-index 6cba73d..d5489ea 100644
---- a/wpa_supplicant/ucode.c
-+++ b/wpa_supplicant/ucode.c
-@@ -7,6 +7,8 @@
- #include "wps_supplicant.h"
- #include "bss.h"
- #include "ucode.h"
-+#include "driver_i.h"
-+#include "common/ieee802_11_common.h"
- 
- static struct wpa_global *wpa_global;
- static uc_resource_type_t *global_type, *iface_type;
-@@ -96,6 +98,8 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d
- {
- 	const char *state;
- 	uc_value_t *val;
-+	enum oper_chan_width ch_width;
-+	int center_freq1, bw320_offset = 1;
- 
- 	if (event != EVENT_CH_SWITCH_STARTED)
- 		return;
-@@ -114,11 +118,42 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d
- 	uc_value_push(ucv_get(val));
- 
- 	if (event == EVENT_CH_SWITCH_STARTED) {
-+		center_freq1 = data->ch_switch.cf1;
-+
-+		switch (data->ch_switch.ch_width) {
-+		case CHAN_WIDTH_80:
-+			ch_width = CONF_OPER_CHWIDTH_80MHZ;
-+			break;
-+		case CHAN_WIDTH_80P80:
-+			ch_width = CONF_OPER_CHWIDTH_80P80MHZ;
-+			break;
-+		case CHAN_WIDTH_160:
-+			ch_width = CONF_OPER_CHWIDTH_160MHZ;
-+			break;
-+		case CHAN_WIDTH_320:
-+			ch_width = CONF_OPER_CHWIDTH_320MHZ;
-+			break;
-+		case CHAN_WIDTH_20_NOHT:
-+		case CHAN_WIDTH_20:
-+		case CHAN_WIDTH_40:
-+		default:
-+			ch_width = CONF_OPER_CHWIDTH_USE_HT;
-+			break;
-+		}
-+
-+		/* Check bandwidth 320 MHz-2 */
-+		if (ch_width == CONF_OPER_CHWIDTH_320MHZ &&
-+		    (center_freq1 == 6265) || center_freq1 == 6585 ||
-+		     center_freq1 == 6905)
-+			bw320_offset = 2;
-+
- 		ucv_object_add(val, "csa_count", ucv_int64_new(data->ch_switch.count));
- 		ucv_object_add(val, "frequency", ucv_int64_new(data->ch_switch.freq));
- 		ucv_object_add(val, "sec_chan_offset", ucv_int64_new(data->ch_switch.ch_offset));
--		ucv_object_add(val, "center_freq1", ucv_int64_new(data->ch_switch.cf1));
-+		ucv_object_add(val, "center_freq1", ucv_int64_new(center_freq1));
- 		ucv_object_add(val, "center_freq2", ucv_int64_new(data->ch_switch.cf2));
-+		ucv_object_add(val, "ch_width", ucv_int64_new(ch_width));
-+		ucv_object_add(val, "bw320_offset", ucv_int64_new(bw320_offset));
- 	}
- 
- 	ucv_put(wpa_ucode_call(4));
-@@ -212,6 +247,11 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
- 	struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface");
- 	struct wpa_bss *bss;
- 	uc_value_t *ret, *val;
-+	struct wpa_channel_info ci;
-+	u8 op_class, channel;
-+	enum oper_chan_width ch_width;
-+	int center_freq1, bw320_offset = 1, is_24ghz;
-+	enum hostapd_hw_mode hw_mode;
- 
- 	if (!wpa_s)
- 		return NULL;
-@@ -224,23 +264,37 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
- 	bss = wpa_s->current_bss;
- 	if (bss) {
- 		int sec_chan = 0;
--		const u8 *ie;
--
--		ie = wpa_bss_get_ie(bss, WLAN_EID_HT_OPERATION);
--		if (ie && ie[1] >= 2) {
--			const struct ieee80211_ht_operation *ht_oper;
--			int sec;
--
--			ht_oper = (const void *) (ie + 2);
--			sec = ht_oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
--			if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
--				sec_chan = 1;
--			else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
--				sec_chan = -1;
-+
-+		hw_mode = ieee80211_freq_to_chan(bss->freq, &channel);
-+		is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
-+			hw_mode == HOSTAPD_MODE_IEEE80211B;
-+
-+		wpa_drv_channel_info(wpa_s, &ci);
-+		center_freq1 = ci.center_frq1;
-+
-+		if (bss->freq != center_freq1) {
-+			if (is_24ghz)
-+				sec_chan = (bss->freq < center_freq1) ? 1 : -1;
-+			else
-+				sec_chan = (bss->freq / 20) & 1 ? 1 : -1;
-+		}
-+
-+		if (ieee80211_chaninfo_to_channel(ci.frequency, ci.chanwidth,
-+						  sec_chan, &op_class, &channel))
-+			return NULL;
-+
-+		ch_width = op_class_to_ch_width(op_class);
-+		if (ch_width == CONF_OPER_CHWIDTH_320MHZ &&
-+		    (center_freq1 == 6265) || center_freq1 == 6585 ||
-+		     center_freq1 == 6905) {
-+			/* Bandwidth 320 MHz-2 */
-+			bw320_offset = 2;
- 		}
- 
- 		ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan));
- 		ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq));
-+		ucv_object_add(ret, "ch_width", ucv_int64_new(ch_width));
-+		ucv_object_add(ret, "bw320_offset", ucv_int64_new(bw320_offset));
- 	}
- 
- #ifdef CONFIG_MESH
--- 
-2.25.1
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
deleted file mode 100644
index 23aa563..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
+++ /dev/null
@@ -1,339 +0,0 @@
-From 00555b91d4d25c64eb556fe1b8815e522970b130 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Wed, 5 Jul 2023 10:25:01 +0800
-Subject: [PATCH 1004/1005] hostapd: mtk: Add support for updating background
- channel by driver
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- src/ap/dfs.c                       | 107 ++++++++++++++++++++++++++++-
- src/ap/dfs.h                       |   3 +
- src/ap/drv_callbacks.c             |  22 ++++++
- src/ap/hostapd.h                   |   5 ++
- src/drivers/driver.h               |  12 ++++
- src/drivers/driver_nl80211_event.c |   6 ++
- src/drivers/nl80211_copy.h         |   6 ++
- 7 files changed, 160 insertions(+), 1 deletion(-)
-
-diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 95119a3..008596b 100644
---- a/src/ap/dfs.c
-+++ b/src/ap/dfs.c
-@@ -814,11 +814,14 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
- 
- static void dfs_check_background_overlapped(struct hostapd_iface *iface)
- {
--	int width = hostapd_get_oper_chwidth(iface->conf);
-+	int width = iface->radar_background.new_chwidth;
- 
- 	if (!dfs_use_radar_background(iface))
- 		return;
- 
-+	if (!width)
-+		width = hostapd_get_oper_chwidth(iface->conf);
-+
- 	if (dfs_are_channels_overlapped(iface, iface->radar_background.freq,
- 					width, iface->radar_background.centr_freq_seg0_idx,
- 					iface->radar_background.centr_freq_seg1_idx))
-@@ -983,6 +986,15 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
- 		iface->radar_background.temp_ch = 1;
- 		return 1;
- 	} else if (dfs_use_radar_background(iface)) {
-+		/*
-+		 * AP is going to perform CAC, so reset temp_ch to 0,
-+		 * when dedicated rx has already started CAC.
-+		 */
-+		if (iface->radar_background.cac_started) {
-+			iface->radar_background.temp_ch = 0;
-+			return 0;
-+		}
-+
- 		if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI)
- 			channel_type = DFS_ANY_CHANNEL;
- 
-@@ -1116,6 +1128,8 @@ static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
- 	 * ch_switch_notify event is received */
- 	wpa_printf(MSG_DEBUG, "DFS waiting channel switch event");
- 
-+	hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth);
-+
- 	return 0;
- }
- 
-@@ -1167,6 +1181,9 @@ static void hostpad_dfs_update_background_chain(struct hostapd_iface *iface)
- 	iface->radar_background.secondary_channel = sec;
- 	iface->radar_background.centr_freq_seg0_idx = oper_centr_freq_seg0_idx;
- 	iface->radar_background.centr_freq_seg1_idx = oper_centr_freq_seg1_idx;
-+	/* if main channel do not require dfs, then set temp_ch = 1 */
-+	if (!hostapd_is_dfs_required(iface))
-+		iface->radar_background.temp_ch = 1;
- 
- 	wpa_printf(MSG_DEBUG,
- 		   "%s: setting background chain to chan %d (%d MHz)",
-@@ -1189,6 +1206,10 @@ hostapd_dfs_start_channel_switch_background(struct hostapd_iface *iface)
- 	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
- 	int ret;
- 
-+	if (iface->radar_background.new_chwidth) {
-+		hostapd_set_oper_chwidth(iface->conf, iface->radar_background.new_chwidth);
-+		iface->radar_background.new_chwidth = 0;
-+	}
- 	ret = hostapd_dfs_request_channel_switch(iface, iface->radar_background.channel,
- 						 iface->radar_background.freq,
- 						 iface->radar_background.secondary_channel,
-@@ -1211,6 +1232,52 @@ hostapd_dfs_start_channel_switch_background(struct hostapd_iface *iface)
- }
- 
- 
-+static void
-+hostapd_dfs_background_expand(struct hostapd_iface *iface, int chan_width)
-+{
-+	struct hostapd_hw_modes *mode = iface->current_mode;
-+	struct hostapd_channel_data *chan;
-+	int i, channel, width = channel_width_to_int(chan_width);
-+
-+	if (iface->conf->channel - iface->radar_background.channel == width / 5)
-+		channel = iface->radar_background.channel;
-+	else if (iface->radar_background.channel - iface->conf->channel == width / 5)
-+		channel = iface->conf->channel;
-+	else
-+		return;
-+
-+	for (i = 0; i < mode->num_channels; i++) {
-+		chan = &mode->channels[i];
-+		if (chan->chan == channel)
-+			break;
-+	}
-+
-+	if (i == mode->num_channels || !dfs_is_chan_allowed(chan, width / 10))
-+		return;
-+
-+	switch (chan_width) {
-+	case CHAN_WIDTH_20_NOHT:
-+	case CHAN_WIDTH_20:
-+		iface->radar_background.new_chwidth = CONF_OPER_CHWIDTH_USE_HT;
-+		break;
-+	case CHAN_WIDTH_40:
-+		iface->radar_background.new_chwidth = CONF_OPER_CHWIDTH_80MHZ;
-+		break;
-+	case CHAN_WIDTH_80:
-+		iface->radar_background.new_chwidth = CONF_OPER_CHWIDTH_160MHZ;
-+		break;
-+	default:
-+		return;
-+	}
-+
-+	iface->radar_background.freq = channel * 5 + 5000;
-+	iface->radar_background.channel = channel;
-+	iface->radar_background.centr_freq_seg0_idx = channel + width / 5 - 2;
-+	iface->radar_background.secondary_channel = 1;
-+	iface->radar_background.expand_ch = 0;
-+}
-+
-+
- int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
- 			     int ht_enabled, int chan_offset, int chan_width,
- 			     int cf1, int cf2)
-@@ -1244,6 +1311,10 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
- 					return 0;
- 
- 				iface->radar_background.temp_ch = 0;
-+
-+				if (iface->radar_background.expand_ch)
-+					hostapd_dfs_background_expand(iface, chan_width);
-+
- 				return hostapd_dfs_start_channel_switch_background(iface);
- 			}
- 
-@@ -1274,6 +1345,8 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
- 		}
- 	} else if (hostapd_dfs_is_background_event(iface, freq)) {
- 		iface->radar_background.cac_started = 0;
-+		iface->radar_background.temp_ch = 0;
-+		iface->radar_background.expand_ch = 0;
- 		hostpad_dfs_update_background_chain(iface);
- 	}
- 
-@@ -1406,6 +1479,9 @@ hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
- 	    iface->conf->dfs_detect_mode == DFS_DETECT_MODE_ALL_ENABLE)
- 		return 0;
- 
-+	iface->radar_background.temp_ch = 0;
-+	iface->radar_background.expand_ch = 0;
-+
- 	/* Check if CSA in progress */
- 	if (hostapd_csa_in_progress(iface))
- 		return 0;
-@@ -1640,6 +1716,35 @@ int hostapd_is_dfs_required(struct hostapd_iface *iface)
- }
- 
- 
-+int hostapd_dfs_background_chan_update(struct hostapd_iface *iface, int freq,
-+				       int ht_enabled, int chan_offset, int chan_width,
-+				       int cf1, int cf2, bool expand)
-+{
-+	switch (chan_width) {
-+	case CHAN_WIDTH_80:
-+		iface->radar_background.new_chwidth = CONF_OPER_CHWIDTH_80MHZ;
-+		break;
-+	case CHAN_WIDTH_160:
-+		iface->radar_background.new_chwidth = CONF_OPER_CHWIDTH_160MHZ;
-+		break;
-+	default:
-+		iface->radar_background.new_chwidth = CONF_OPER_CHWIDTH_USE_HT;
-+		break;
-+	};
-+
-+	iface->radar_background.freq = freq;
-+	iface->radar_background.channel = (freq - 5000) / 5;
-+	iface->radar_background.centr_freq_seg0_idx = (cf1 - 5000) / 5;
-+	iface->radar_background.centr_freq_seg1_idx = cf2 ? (cf2 - 5000) / 5 : 0;
-+	if (expand) {
-+		iface->radar_background.temp_ch = 1;
-+		iface->radar_background.expand_ch = 1;
-+	}
-+
-+	return 0;
-+}
-+
-+
- int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
- 			  int ht_enabled, int chan_offset, int chan_width,
- 			  int cf1, int cf2)
-diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index 25ba29c..a1a2be5 100644
---- a/src/ap/dfs.h
-+++ b/src/ap/dfs.h
-@@ -30,6 +30,9 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
- int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
- 			     int ht_enabled,
- 			     int chan_offset, int chan_width, int cf1, int cf2);
-+int hostapd_dfs_background_chan_update(struct hostapd_iface *iface, int freq,
-+				       int ht_enabled, int chan_offset, int chan_width,
-+				       int cf1, int cf2, bool expand);
- int hostapd_dfs_sta_update_state(struct hostapd_iface *iface, int freq,
- 				 int ht_enabled, int chan_offset, int chan_width,
- 				 int cf1, int cf2, u32 state);
-diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index f749b33..12419c6 100644
---- a/src/ap/drv_callbacks.c
-+++ b/src/ap/drv_callbacks.c
-@@ -2089,6 +2089,18 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
- 			      radar->cf1, radar->cf2);
- }
- 
-+
-+static void hostapd_event_dfs_background_chan_update(struct hostapd_data *hapd,
-+						     struct dfs_event *radar, bool expand)
-+{
-+	wpa_printf(MSG_DEBUG, "DFS background channel %s to %d MHz",
-+		   expand ? "expand" : "update", radar->freq);
-+	hostapd_dfs_background_chan_update(hapd->iface, radar->freq, radar->ht_enabled,
-+					   radar->chan_offset, radar->chan_width,
-+					   radar->cf1, radar->cf2, expand);
-+}
-+
-+
- static void hostapd_event_dfs_sta_cac_skipped(struct hostapd_data *hapd,
- 					      struct dfs_event *radar)
- {
-@@ -2428,6 +2440,16 @@ void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
- 			break;
- 		hostapd_event_dfs_nop_finished(hapd, &data->dfs_event);
- 		break;
-+	case EVENT_DFS_BACKGROUND_CHAN_UPDATE:
-+		if (!data)
-+			break;
-+		hostapd_event_dfs_background_chan_update(hapd, &data->dfs_event, false);
-+		break;
-+	case EVENT_DFS_BACKGROUND_CHAN_EXPAND:
-+		if (!data)
-+			break;
-+		hostapd_event_dfs_background_chan_update(hapd, &data->dfs_event, true);
-+		break;
- 	case EVENT_DFS_STA_CAC_SKIPPED:
- 		if (!data)
- 			break;
-diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
-index 1849f38..ea8d725 100644
---- a/src/ap/hostapd.h
-+++ b/src/ap/hostapd.h
-@@ -602,6 +602,11 @@ struct hostapd_iface {
- 		unsigned int temp_ch:1;
- 		/* CAC started on radar offchain */
- 		unsigned int cac_started:1;
-+		/* Main chain should expand its width according to the
-+		 * current offchain channel after CAC detection on radar offchain.
-+		 */
-+		unsigned int expand_ch:1;
-+		int new_chwidth;
- 	} radar_background;
- 
- 	u16 hw_flags;
-diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index ebc1d27..a9f48a1 100644
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -5842,6 +5842,18 @@ enum wpa_event_type {
- 	 * The channel in the notification is now marked as usable.
- 	 */
- 	EVENT_DFS_STA_CAC_EXPIRED,
-+
-+	/**
-+	 * EVENT_DFS_BACKGROUND_CHAN_UPDATE - Notification that background
-+	 * channel has been updated.
-+	 */
-+	EVENT_DFS_BACKGROUND_CHAN_UPDATE,
-+
-+	/**
-+	 * EVENT_DFS_BACKGROUND_CHAN_EXPAND - Notification that background
-+	 * channel has been updated and operating channel should expand its width.
-+	 */
-+	EVENT_DFS_BACKGROUND_CHAN_EXPAND,
- };
- 
- 
-diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
-index 63d4401..c1a65eb 100644
---- a/src/drivers/driver_nl80211_event.c
-+++ b/src/drivers/driver_nl80211_event.c
-@@ -2514,6 +2514,12 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
- 	case NL80211_RADAR_CAC_STARTED:
- 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
- 		break;
-+	case NL80211_RADAR_BACKGROUND_CHAN_UPDATE:
-+		wpa_supplicant_event(drv->ctx, EVENT_DFS_BACKGROUND_CHAN_UPDATE, &data);
-+		break;
-+	case NL80211_RADAR_BACKGROUND_CHAN_EXPAND:
-+		wpa_supplicant_event(drv->ctx, EVENT_DFS_BACKGROUND_CHAN_EXPAND, &data);
-+		break;
- 	case NL80211_RADAR_STA_CAC_SKIPPED:
- 		wpa_supplicant_event(drv->ctx, EVENT_DFS_STA_CAC_SKIPPED, &data);
- 		break;
-diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
-index 225864b..9b0a817 100644
---- a/src/drivers/nl80211_copy.h
-+++ b/src/drivers/nl80211_copy.h
-@@ -6643,6 +6643,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.
-+ * @NL80211_RADAR_BACKGROUND_CHAN_UPDATE: background channel is updated by the
-+ *	driver.
-+ * @NL80211_RADAR_BACKGROUND_CHAN_EXPAND: background channel is updated by the
-+ *	driver and required to expand main operating channel.
-  * @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
-@@ -6655,6 +6659,8 @@ enum nl80211_radar_event {
- 	NL80211_RADAR_NOP_FINISHED,
- 	NL80211_RADAR_PRE_CAC_EXPIRED,
- 	NL80211_RADAR_CAC_STARTED,
-+	NL80211_RADAR_BACKGROUND_CHAN_UPDATE,
-+	NL80211_RADAR_BACKGROUND_CHAN_EXPAND,
- 	NL80211_RADAR_STA_CAC_SKIPPED,
- 	NL80211_RADAR_STA_CAC_EXPIRED,
- };
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
deleted file mode 100644
index 4178b68..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
+++ /dev/null
@@ -1,374 +0,0 @@
-From df3d6a354fc1243f8c862f2b61ee9ac09eabe482 Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Thu, 21 Sep 2023 10:29:46 +0800
-Subject: [PATCH] hostapd: mtk: add support enable/disable preamble puncture
- from mtk vendor command
-
-This commit supports two ways to enable/disable preamble puncture
-feature.
-
-1. Add new hostapd configuration "pp_mode". The possible value could be
-1 to 3. When the value is 0, it means that the firmware will turn off
-the pp algorithm. When the value is 1, it means that the firmware will
-enable the pp algorithm, allowing the algorithm to determine whether pp
-could be applied on each txcmd. When the value is 2, it means that pp
-feature is manually configured by the user. Please noted that for
-current implementation, the default configuration is 0.
-
-2. $ hostapd_cli -i <intf_name> raw set_pp mode val
-The argument "val" could be 0 for PP feature disabled or 1 to configure
-PP feature as auto mode.
-
-This commit also let user check whether pp feature is enabled by
-hostapd_cli command. The usage shows as below:
-$ hostapd_cli -i <intf_name> raw get_pp mode
-
-Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
----
- hostapd/config_file.c             | 11 ++++++
- hostapd/ctrl_iface.c              | 59 +++++++++++++++++++++++++++++++
- src/ap/ap_config.c                |  1 +
- src/ap/ap_config.h                |  7 ++++
- src/ap/ap_drv_ops.c               |  9 +++++
- src/ap/ap_drv_ops.h               |  1 +
- src/ap/hostapd.c                  |  2 ++
- src/common/mtk_vendor.h           | 12 +++++++
- src/drivers/driver.h              |  6 ++++
- src/drivers/driver_nl80211.c      | 49 +++++++++++++++++++++++++
- src/drivers/driver_nl80211.h      |  1 +
- src/drivers/driver_nl80211_capa.c |  3 ++
- 12 files changed, 161 insertions(+)
-
-diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index a751993..278f6b3 100644
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -4801,6 +4801,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 		conf->eht_phy_capab.mu_beamformer = atoi(pos);
- 	} else if (os_strcmp(buf, "punct_bitmap") == 0) {
- 		conf->punct_bitmap = atoi(pos);
-+		conf->pp_mode = PP_MANUAL_MODE;
- 	} else if (os_strcmp(buf, "punct_acs_threshold") == 0) {
- 		int val = atoi(pos);
- 
-@@ -4876,6 +4877,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 			return 1;
- 		}
- 		conf->amsdu = val;
-+	} else if (os_strcmp(buf, "pp_mode") == 0) {
-+		int val = atoi(pos);
-+
-+		if ((val != PP_MANUAL_MODE && conf->punct_bitmap) ||
-+		    val < PP_DISABLE || val > PP_MANUAL_MODE) {
-+			wpa_printf(MSG_ERROR, "Line %d: invalid pp_mode value",
-+				   line);
-+			return 1;
-+		}
-+		conf->pp_mode = (u8) val;
- 	} else {
- 		wpa_printf(MSG_ERROR,
- 			   "Line %d: unknown configuration item '%s'",
-diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 517ebd6..7315d12 100644
---- a/hostapd/ctrl_iface.c
-+++ b/hostapd/ctrl_iface.c
-@@ -4183,6 +4183,59 @@ hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cm
- 	return os_snprintf(buf, buflen, "OK\n");
- }
- 
-+static int
-+hostapd_ctrl_iface_set_pp(struct hostapd_data *hapd, char *cmd, char *buf,
-+			  size_t buflen)
-+{
-+	char *pos, *config, *value;
-+
-+	config = cmd;
-+	pos = os_strchr(config, ' ');
-+	if (pos == NULL)
-+		return -1;
-+	*pos++ = '\0';
-+
-+	if (pos == NULL)
-+		return -1;
-+	value = pos;
-+
-+	if (os_strcmp(config, "mode") == 0) {
-+		int val = atoi(value);
-+
-+		if (val < PP_DISABLE || val > PP_AUTO_MODE) {
-+			wpa_printf(MSG_ERROR, "Invalid value for set_pp");
-+			return -1;
-+		}
-+		hapd->iconf->pp_mode = (u8) val;
-+		if (hostapd_drv_pp_mode_set(hapd) != 0)
-+			return -1;
-+	} else {
-+		wpa_printf(MSG_ERROR,
-+			   "Unsupported parameter %s for set_pp", config);
-+		return -1;
-+	}
-+	return os_snprintf(buf, buflen, "OK\n");
-+}
-+
-+static int
-+hostapd_ctrl_iface_get_pp(struct hostapd_data *hapd, char *cmd, char *buf,
-+			  size_t buflen)
-+{
-+	char *pos, *end;
-+
-+	pos = buf;
-+	end = buf + buflen;
-+
-+	if (os_strcmp(cmd, "mode") == 0) {
-+		return os_snprintf(pos, end - pos, "pp_mode: %d\n",
-+				   hapd->iconf->pp_mode);
-+	} else {
-+		wpa_printf(MSG_ERROR,
-+			   "Unsupported parameter %s for get_pp", cmd);
-+		return -1;
-+	}
-+}
-+
- static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 					      char *buf, char *reply,
- 					      int reply_size,
-@@ -4769,6 +4822,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
- 		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
- 							reply, reply_size);
-+	} else if (os_strncmp(buf, "set_pp", 6) == 0) {
-+		reply_len = hostapd_ctrl_iface_set_pp(hapd, buf + 7, reply,
-+						      reply_size);
-+	} else if (os_strncmp(buf, "get_pp", 6) == 0) {
-+		reply_len = hostapd_ctrl_iface_get_pp(hapd, buf + 7, reply,
-+						      reply_size);
- 	} else if (os_strncmp(buf, "set_muru_manual_config=", 23) == 0) {
- 		// Replace first ':' with a single space ' '
- 		char *pos = buf + 23;
-diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 223db56..d8dd549 100644
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -302,6 +302,7 @@ struct hostapd_config * hostapd_config_defaults(void)
- 	conf->three_wire_enable = THREE_WIRE_MODE_DISABLE;
- 	conf->ibf_enable = IBF_DEFAULT_ENABLE;
- 	conf->amsdu = 1;
-+	conf->pp_mode = PP_DISABLE;
- 
- 	return conf;
- }
-diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index b6f05e7..9e39e82 100644
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -1205,6 +1205,7 @@ struct hostapd_config {
- 	u8 dfs_detect_mode;
- 	u8 amsdu;
- 	void *muru_config;
-+	u8 pp_mode;
- };
- 
- enum three_wire_mode {
-@@ -1257,6 +1258,12 @@ enum mtk_vendor_attr_edcca_ctrl_mode {
- 	EDCCA_CTRL_NUM,
- };
- 
-+enum pp_mode {
-+	PP_DISABLE = 0,
-+	PP_AUTO_MODE,
-+	PP_MANUAL_MODE,
-+};
-+
- #define EDCCA_DEFAULT_COMPENSATION -6
- #define EDCCA_MIN_COMPENSATION -126
- #define EDCCA_MAX_COMPENSATION 126
-diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
-index 5b93ea6..d0d8279 100644
---- a/src/ap/ap_drv_ops.c
-+++ b/src/ap/ap_drv_ops.c
-@@ -1271,3 +1271,12 @@ int hostapd_drv_background_radar_mode(struct hostapd_data *hapd)
- 	return hapd->driver->background_radar_mode(hapd->drv_priv,
- 						   hapd->iconf->background_radar_mode);
- }
-+
-+int hostapd_drv_pp_mode_set(struct hostapd_data *hapd)
-+{
-+	if (!hapd->driver || !hapd->driver->pp_mode_set ||
-+	    hapd->iconf->pp_mode > PP_AUTO_MODE)
-+		return 0;
-+	return hapd->driver->pp_mode_set(hapd->drv_priv,
-+					 hapd->iconf->pp_mode);
-+}
-diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
-index 1e7ae7a..e4c2827 100644
---- a/src/ap/ap_drv_ops.h
-+++ b/src/ap/ap_drv_ops.h
-@@ -163,6 +163,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
- 
- int hostapd_drv_amnt_set(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_sta_mac);
- int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_buf);
-+int hostapd_drv_pp_mode_set(struct hostapd_data *hapd);
- 
- #include "drivers/driver.h"
- 
-diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 2b563a5..90c6c26 100644
---- a/src/ap/hostapd.c
-+++ b/src/ap/hostapd.c
-@@ -2526,6 +2526,8 @@ dfs_offload:
- 		goto fail;
- 	if (hostapd_drv_amsdu_ctrl(hapd) < 0)
- 		goto fail;
-+	if (hostapd_drv_pp_mode_set(hapd) < 0)
-+		goto fail;
- 
- 	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
- 		   iface->bss[0]->conf->iface);
-diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
-index 5bc1e04..6275c14 100644
---- a/src/common/mtk_vendor.h
-+++ b/src/common/mtk_vendor.h
-@@ -17,6 +17,7 @@ enum mtk_nl80211_vendor_subcmds {
- 	MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
- 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
- 	MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
-+	MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
- };
- 
- enum mtk_vendor_attr_edcca_ctrl {
-@@ -256,6 +257,17 @@ enum mtk_vendor_attr_background_radar_ctrl {
- 		NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL - 1
- };
- 
-+enum mtk_vendor_attr_pp_ctrl {
-+	MTK_VENDOR_ATTR_PP_CTRL_UNSPEC,
-+
-+	MTK_VENDOR_ATTR_PP_MODE,
-+
-+	/* keep last */
-+	NUM_MTK_VENDOR_ATTRS_PP_CTRL,
-+	MTK_VENDOR_ATTR_PP_CTRL_MAX =
-+		NUM_MTK_VENDOR_ATTRS_PP_CTRL - 1
-+};
-+
- #define CSI_MAX_COUNT 256
- #define ETH_ALEN 6
- 
-diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index bc82d28..261ed80 100644
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -5208,6 +5208,12 @@ struct wpa_driver_ops {
- 	 * @background_radar_mode: background radar mode
- 	 */
- 	int (*background_radar_mode)(void *priv, u8 background_radar_mode);
-+	/**
-+	 * pp_mode_set - Set preamble puncture operation mode
-+	 * @priv: Private driver interface data
-+	 * @pp_mode: Value is defined in enum pp_mode
-+	 */
-+	int (*pp_mode_set)(void *priv, const u8 pp_mode);
- };
- 
- /**
-diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 2089ad6..3cc55dc 100644
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -141,6 +141,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
- 	[MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
- };
- 
-+static struct nla_policy
-+pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = {
-+	[MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 },
-+};
-+
- static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
- {
- 	struct nl_sock *handle;
-@@ -14756,6 +14761,49 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m
- 	return ret;
- }
- 
-+static int nl80211_pp_mode_set(void *priv, const u8 pp_mode)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	struct nl_msg *msg;
-+	struct nlattr *data;
-+	int ret;
-+
-+	if (!drv->mtk_pp_vendor_cmd_avail) {
-+		wpa_printf(MSG_DEBUG,
-+			   "nl80211: Driver does not support setting preamble puncture");
-+		return 0;
-+	}
-+
-+	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
-+	if (!msg)
-+		goto fail;
-+
-+	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
-+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
-+			MTK_NL80211_VENDOR_SUBCMD_PP_CTRL))
-+		goto fail;
-+
-+	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
-+	if (!data)
-+		goto fail;
-+
-+	nla_put_u8(msg, MTK_VENDOR_ATTR_PP_MODE, pp_mode);
-+
-+	nla_nest_end(msg, data);
-+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
-+
-+	if (ret)
-+		wpa_printf(MSG_ERROR, "Failed to set pp_enable. ret=%d (%s)",
-+			   ret, strerror(-ret));
-+
-+	return ret;
-+
-+fail:
-+	nlmsg_free(msg);
-+	return -ENOBUFS;
-+}
-+
- const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.name = "nl80211",
- 	.desc = "Linux nl80211/cfg80211",
-@@ -14929,4 +14977,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.amnt_set = nl80211_amnt_set,
- 	.amnt_dump = nl80211_amnt_dump,
- 	.background_radar_mode = nl80211_background_radar_mode,
-+	.pp_mode_set = nl80211_pp_mode_set,
- };
-diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
-index 74ee9b1..1bba5b1 100644
---- a/src/drivers/driver_nl80211.h
-+++ b/src/drivers/driver_nl80211.h
-@@ -211,6 +211,7 @@ struct wpa_driver_nl80211_data {
- 	unsigned int mtk_rfeatures_vendor_cmd_avail:1;
- 	unsigned int mtk_amnt_vendor_cmd_avail:1;
- 	unsigned int mtk_background_radar_vendor_cmd_avail:1;
-+	unsigned int mtk_pp_vendor_cmd_avail:1;
- 
- 	u64 vendor_scan_cookie;
- 	u64 remain_on_chan_cookie;
-diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
-index 90711b4..f2c42b9 100644
---- a/src/drivers/driver_nl80211_capa.c
-+++ b/src/drivers/driver_nl80211_capa.c
-@@ -1136,6 +1136,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
- 				case MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL:
- 					drv->mtk_background_radar_vendor_cmd_avail = 1;
- 					break;
-+				case MTK_NL80211_VENDOR_SUBCMD_PP_CTRL:
-+					drv->mtk_pp_vendor_cmd_avail = 1;
-+					break;
- 				}
- 			}
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
deleted file mode 100644
index d2b117c..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
+++ /dev/null
@@ -1,431 +0,0 @@
-From 88f5a4c1c67f8fc40c8294c498faa72e1ceea470 Mon Sep 17 00:00:00 2001
-From: "fancy.liu" <fancy.liu@mediatek.com>
-Date: Thu, 28 Sep 2023 18:03:08 +0800
-Subject: [PATCH] hostapd: mtk: [ACS] Add EHT320 and HT40- support, fix issue
-
-1. Add 6G EHT320 support;
-2. Add 2.4G HT40- support;
-3. Fix issue: selected best channel is out of channels;
-
-Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
----
- src/ap/acs.c | 222 +++++++++++++++++++++++++++++++--------------------
- 1 file changed, 136 insertions(+), 86 deletions(-)
-
-diff --git a/src/ap/acs.c b/src/ap/acs.c
-index af31405..ed6a47b 100644
---- a/src/ap/acs.c
-+++ b/src/ap/acs.c
-@@ -245,6 +245,7 @@ enum bw_type {
- 	ACS_BW40,
- 	ACS_BW80,
- 	ACS_BW160,
-+	ACS_BW320,
- };
- 
- struct bw_item {
-@@ -286,10 +287,16 @@ static const struct bw_item bw_160[] = {
- 	{ 6435, 6575, 111 }, { 6595, 6735, 143 },
- 	{ 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
- };
-+static const struct bw_item bw_320[] = {
-+	{ 5955, 6255, 31 }, { 6115, 6415, 63 }, { 6275, 6575, 95 },
-+	{ 6435, 6735, 127 }, { 6595, 6895, 159 }, { 6755, 7055, 191 },
-+	{ -1, -1, -1 }
-+};
- static const struct bw_item *bw_desc[] = {
- 	[ACS_BW40] = bw_40,
- 	[ACS_BW80] = bw_80,
- 	[ACS_BW160] = bw_160,
-+	[ACS_BW320] = bw_320,
- };
- 
- 
-@@ -583,12 +590,6 @@ static void acs_survey_mode_interference_factor(
- 		    iface->conf->acs_exclude_dfs)
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
--
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
- 
-@@ -775,17 +776,29 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 			 struct hostapd_channel_data **ideal_chan,
- 			 long double *ideal_factor)
- {
--	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
-+	struct hostapd_channel_data *chan, *adj_chan = NULL, *tmp_chan = NULL, *best;
- 	long double factor;
- 	int i, j;
- 	unsigned int k;
-+	int ht40_plus = 1, sec_ch_factor = 1;
-+
-+	if (is_24ghz_mode(mode->mode)) {
-+		ht40_plus = (iface->conf->secondary_channel == -1) ? 0 : 1;
-+		sec_ch_factor = (iface->conf->secondary_channel == -1) ? -1 : 1;
-+	}
-+
-+	wpa_printf(MSG_INFO, "%s:%d, bw(%u), n_chans(%d), num_channels(%d), sec_ch(%d)",
-+		__func__, __LINE__, bw, n_chans, mode->num_channels, iface->conf->secondary_channel);
- 
- 	for (i = 0; i < mode->num_channels; i++) {
- 		double total_weight;
- 		struct acs_bias *bias, tmp_bias;
--		bool update_best = true;
-+		bool update_best = true, has_candidate = true;
- 
- 		best = chan = &mode->channels[i];
-+		wpa_printf(MSG_INFO,
-+			   "ACS: Channel[%d] %d: interference_factor %Lg",
-+			   i, chan->chan, chan->interference_factor);
- 
- 		/* Since in the current ACS implementation the first channel is
- 		 * always a primary channel, skip channels not available as
-@@ -804,11 +817,12 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 		    iface->conf->acs_exclude_dfs)
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
-+		if (!is_in_chanlist(iface, chan) || !is_in_freqlist(iface, chan)) {
-+			if (is_24ghz_mode(mode->mode))
-+				continue;
-+			else
-+				has_candidate = false;
-+		}
- 
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
-@@ -817,7 +831,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 		    iface->conf->country[2] == 0x4f)
- 			continue;
- 
--		if (!chan_bw_allowed(chan, bw, 1, 1)) {
-+		if (!chan_bw_allowed(chan, bw, ht40_plus, 1)) {
- 			wpa_printf(MSG_DEBUG,
- 				   "ACS: Channel %d: BW %u is not supported",
- 				   chan->chan, bw);
-@@ -838,7 +852,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 		}
- 
- 		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
--		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
-+		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
-+		     iface->conf->ieee80211be)) {
- 			if (hostapd_get_oper_chwidth(iface->conf) ==
- 			    CONF_OPER_CHWIDTH_80MHZ &&
- 			    !acs_usable_bw_chan(chan, ACS_BW80)) {
-@@ -856,63 +871,89 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 					   chan->chan);
- 				continue;
- 			}
--		}
- 
--		factor = 0;
--		if (acs_usable_chan(chan))
--			factor = chan->interference_factor;
--		total_weight = 1;
--
--		for (j = 1; j < n_chans; j++) {
--			adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
--			if (!adj_chan)
--				break;
--
--			if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
-+			if (iface->conf->ieee80211be &&
-+			    hostapd_get_oper_chwidth(iface->conf) ==
-+			    CONF_OPER_CHWIDTH_320MHZ &&
-+			    !acs_usable_bw_chan(chan, ACS_BW320)) {
- 				wpa_printf(MSG_DEBUG,
--					   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
--					   chan->chan, adj_chan->chan, bw);
--				break;
-+					   "ACS: Channel %d: not allowed as primary channel for 320 MHz bandwidth",
-+					   chan->chan);
-+				continue;
- 			}
-+		}
-+
-+		factor = 0;
-+		total_weight = 0;
- 
--			if (acs_usable_chan(adj_chan)) {
--				factor += adj_chan->interference_factor;
-+		if (!is_24ghz_mode(mode->mode)) {
-+			/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
-+			 * crowded primary channel if one was found in the segment */
-+			if (acs_usable_chan(chan)) {
-+				factor += chan->interference_factor;
- 				total_weight += 1;
--			} else {
--				update_best = false;
- 			}
- 
--			/* find the best channel in this segment */
--			if (update_best &&
--			    adj_chan->interference_factor <
--			    best->interference_factor)
--				best = adj_chan;
--		}
-+			for (j = 1; j < n_chans; j++) {
-+				adj_chan = acs_find_chan(iface, chan->freq + j * 20);
-+				if (!adj_chan)
-+					break;
- 
--		if (j != n_chans) {
--			wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
--				   chan->chan);
--			continue;
--		}
-+				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
-+					wpa_printf(MSG_DEBUG,
-+						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
-+						   chan->chan, adj_chan->chan, bw);
-+					break;
-+				}
- 
--		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
--		 * crowded primary channel if one was found in the segment */
--		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
--		    chan != best) {
--			wpa_printf(MSG_DEBUG,
--				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
--				   best->chan, chan->chan,
--				   chan->interference_factor,
--				   best->interference_factor);
--			chan = best;
--		}
-+				update_best = true;
-+				if (acs_usable_chan(adj_chan)) {
-+					factor += adj_chan->interference_factor;
-+					total_weight += 1;
-+
-+					if (!is_in_chanlist(iface, adj_chan) ||
-+						!is_in_freqlist(iface, adj_chan))
-+						update_best = false;
-+				} else {
-+					update_best = false;
-+				}
-+
-+				/* find the best channel in this segment */
-+				if (update_best && (!has_candidate ||
-+					adj_chan->interference_factor < best->interference_factor)) {
-+					best = adj_chan;
-+					has_candidate = true;
-+				}
-+			}
- 
--		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
--		 * channel interference factor. */
--		if (is_24ghz_mode(mode->mode)) {
-+			if (j != n_chans || !has_candidate) {
-+				wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
-+					   chan->chan);
-+				continue;
-+			}
-+
-+			if (chan != best) {
-+				wpa_printf(MSG_INFO,
-+					   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
-+					   best->chan, chan->chan,
-+					   chan->interference_factor,
-+					   best->interference_factor);
-+				chan = best;
-+			}
-+		} else {
- 			for (j = 0; j < n_chans; j++) {
-+				/* Will set primary_channel / secondary_channel(40M case) weight to 1 */
-+				tmp_chan = acs_find_chan(iface, chan->freq +
-+							 (j * 20) * sec_ch_factor);
-+				if (tmp_chan && acs_usable_chan(tmp_chan)) {
-+					factor += tmp_chan->interference_factor;
-+					total_weight += 1;
-+				}
-+
-+				/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent channel
-+				interference factor, separately for primary/secondary channel. */
- 				adj_chan = acs_find_chan(iface, chan->freq +
--							 (j * 20) - 5);
-+							 ((j * 20) - 5) * sec_ch_factor);
- 				if (adj_chan && acs_usable_chan(adj_chan)) {
- 					factor += ACS_ADJ_WEIGHT *
- 						adj_chan->interference_factor;
-@@ -920,7 +961,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 				}
- 
- 				adj_chan = acs_find_chan(iface, chan->freq +
--							 (j * 20) - 10);
-+							 ((j * 20) - 10) * sec_ch_factor);
- 				if (adj_chan && acs_usable_chan(adj_chan)) {
- 					factor += ACS_NEXT_ADJ_WEIGHT *
- 						adj_chan->interference_factor;
-@@ -928,7 +969,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 				}
- 
- 				adj_chan = acs_find_chan(iface, chan->freq +
--							 (j * 20) + 5);
-+							 ((j * 20) + 5) * sec_ch_factor);
- 				if (adj_chan && acs_usable_chan(adj_chan)) {
- 					factor += ACS_ADJ_WEIGHT *
- 						adj_chan->interference_factor;
-@@ -936,7 +977,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 				}
- 
- 				adj_chan = acs_find_chan(iface, chan->freq +
--							 (j * 20) + 10);
-+							 ((j * 20) + 10) * sec_ch_factor);
- 				if (adj_chan && acs_usable_chan(adj_chan)) {
- 					factor += ACS_NEXT_ADJ_WEIGHT *
- 						adj_chan->interference_factor;
-@@ -945,7 +986,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 			}
- 		}
- 
--		factor /= total_weight;
-+		if (total_weight)
-+			factor /= total_weight;
- 
- 		bias = NULL;
- 		if (iface->conf->acs_chan_bias) {
-@@ -964,11 +1006,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
- 
- 		if (bias) {
- 			factor *= bias->bias;
--			wpa_printf(MSG_DEBUG,
-+			wpa_printf(MSG_INFO,
- 				   "ACS:  * channel %d: total interference = %Lg (%f bias)",
- 				   chan->chan, factor, bias->bias);
- 		} else {
--			wpa_printf(MSG_DEBUG,
-+			wpa_printf(MSG_INFO,
- 				   "ACS:  * channel %d: total interference = %Lg",
- 				   chan->chan, factor);
- 		}
-@@ -1021,19 +1063,12 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
- 		goto bw_selected;
- 	}
- 
--	/* TODO: HT40- support */
--
--	if (iface->conf->ieee80211n &&
--	    iface->conf->secondary_channel == -1) {
--		wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
--		return NULL;
--	}
--
- 	if (iface->conf->ieee80211n &&
- 	    iface->conf->secondary_channel)
- 		n_chans = 2;
- 
--	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
-+	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
-+	    iface->conf->ieee80211be) {
- 		switch (hostapd_get_oper_chwidth(iface->conf)) {
- 		case CONF_OPER_CHWIDTH_80MHZ:
- 			n_chans = 4;
-@@ -1043,6 +1078,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
- 			break;
- 		default:
- 			break;
-+		/* 320 is supported only in 6GHz 11be mode */
- 		}
- 	}
- 
-@@ -1063,7 +1099,7 @@ bw_selected:
- 	}
- 
- 	if (ideal_chan) {
--		wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
-+		wpa_printf(MSG_INFO, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
- 			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
- 
- #ifdef CONFIG_IEEE80211BE
-@@ -1078,6 +1114,21 @@ bw_selected:
- 	return rand_chan;
- }
- 
-+static int acs_get_center_freq_320mhz(int channel)
-+{
-+	if (channel >= 1 && channel <= 45)
-+		return 31;
-+	else if (channel >= 49 && channel <= 77)
-+		return 63;
-+	else if (channel >= 81 && channel <= 109)
-+		return 95;
-+	else if (channel >= 113 && channel <= 141)
-+		return 127;
-+	else if (channel >= 145 && channel <= 173)
-+		return 159;
-+	else
-+		return 191;
-+}
- 
- static void acs_adjust_secondary(struct hostapd_iface *iface)
- {
-@@ -1104,10 +1155,11 @@ static void acs_adjust_secondary(struct hostapd_iface *iface)
- static void acs_adjust_center_freq(struct hostapd_iface *iface)
- {
- 	int center;
-+ 	u8 bw = hostapd_get_oper_chwidth(iface->conf);
- 
--	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
-+	wpa_printf(MSG_DEBUG, "ACS: Adjusting center frequency");
- 
--	switch (hostapd_get_oper_chwidth(iface->conf)) {
-+	switch (bw) {
- 	case CONF_OPER_CHWIDTH_USE_HT:
- 		if (iface->conf->secondary_channel &&
- 		    iface->freq >= 2400 && iface->freq < 2500)
-@@ -1121,6 +1173,9 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
- 	case CONF_OPER_CHWIDTH_80MHZ:
- 		center = acs_get_bw_center_chan(iface->freq, ACS_BW80);
- 		break;
-+	case CONF_OPER_CHWIDTH_320MHZ:
-+		center = acs_get_center_freq_320mhz(iface->conf->channel);
-+		break;
- 	case CONF_OPER_CHWIDTH_160MHZ:
- 		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
- 		break;
-@@ -1128,7 +1183,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
- 		/* TODO: How can this be calculated? Adjust
- 		 * acs_find_ideal_chan() */
- 		wpa_printf(MSG_INFO,
--			   "ACS: Only VHT20/40/80/160 is supported now");
-+			   "ACS: Only VHT20/40/80/160 EHT320 is supported now");
- 		return;
- 	}
- 
-@@ -1191,7 +1246,8 @@ static void acs_study(struct hostapd_iface *iface)
- 	iface->conf->punct_bitmap = ideal_chan->punct_bitmap;
- #endif /* CONFIG_IEEE80211BE */
- 
--	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
-+	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
-+		iface->conf->ieee80211be) {
- 		acs_adjust_secondary(iface);
- 		acs_adjust_center_freq(iface);
- 	}
-@@ -1270,12 +1326,6 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
- 		     iface->conf->acs_exclude_dfs))
- 			continue;
- 
--		if (!is_in_chanlist(iface, chan))
--			continue;
--
--		if (!is_in_freqlist(iface, chan))
--			continue;
--
- 		if (chan->max_tx_power < iface->conf->min_tx_power)
- 			continue;
- 
--- 
-2.25.1
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc
index 600fad1..8ad0077 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc
@@ -62,53 +62,58 @@
     file://990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch \
     file://991-Fix-OpenWrt-13156.patch \
     file://992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch \
-    file://mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch \
-    file://mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch \
-    file://mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch \
-    file://mtk-0004-hostapd-mtk-Add-mtk_vendor.h.patch \
-    file://mtk-0005-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch \
-    file://mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch \
-    file://mtk-0007-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch \
-    file://mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch \
-    file://mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch \
-    file://mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch \
-    file://mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
-    file://mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch \
-    file://mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch \
-    file://mtk-0014-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch \
-    file://mtk-0015-hostapd-mtk-6G-band-does-not-require-DFS.patch \
-    file://mtk-0016-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch \
-    file://mtk-0017-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch \
-    file://mtk-0018-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch \
-    file://mtk-0019-hostapd-mtk-Add-available-color-bitmap.patch \
-    file://mtk-0020-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch \
-    file://mtk-0021-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch \
-    file://mtk-0022-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch \
-    file://mtk-0023-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch \
-    file://mtk-0024-hostapd-mtk-Add-muru-user-number-debug-command.patch \
-    file://mtk-0025-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch \
-    file://mtk-0026-hostapd-mtk-Add-HE-capabilities-check.patch \
-    file://mtk-0027-hostapd-mtk-Fix-background-channel-overlapping-opera.patch \
-    file://mtk-0028-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch \
-    file://mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch \
-    file://mtk-0030-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch \
-    file://mtk-0031-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch \
-    file://mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch \
-    file://mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch \
-    file://mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch \
-    file://mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch \
-    file://mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch \
-    file://mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch \
-    file://mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch \
-    file://mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch \
-    file://mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch \
-    file://mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch \
-    file://mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch \
-    file://mtk-1001-hostapd-mtk-update-eht-operation-element.patch \
-    file://mtk-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch \
-    file://mtk-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch \
-    file://mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch \
-    file://mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch \
-    file://mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch \
-    file://mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch \
+    file://mtk-0001-mtk-hostapd-Add-neighbor-report-and-BSS-Termination-.patch \
+    file://mtk-0002-mtk-hostapd-print-sae-groups-by-hostapd-ctrl.patch \
+    file://mtk-0003-mtk-hostapd-add-support-for-runtime-set-in-band-disc.patch \
+    file://mtk-0004-mtk-hostapd-Add-mtk_vendor.h.patch \
+    file://mtk-0005-mtk-hostapd-Support-EDCCA-hostapd-configuration.patch \
+    file://mtk-0006-mtk-hostapd-Add-hostapd-MU-SET-GET-control.patch \
+    file://mtk-0007-mtk-hostapd-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch \
+    file://mtk-0008-mtk-hostapd-Add-hostapd-iBF-control.patch \
+    file://mtk-0009-mtk-hostapd-Do-not-include-HE-capab-IE-if-associated.patch \
+    file://mtk-0010-mtk-hostapd-Add-DFS-detection-mode.patch \
+    file://mtk-0011-mtk-hostapd-Add-DFS-offchan-channel-switch.patch \
+    file://mtk-0012-mtk-hostapd-Add-amsdu-set-get-ctrl.patch \
+    file://mtk-0013-mtk-hostapd-Add-he_ldpc-configuration.patch \
+    file://mtk-0014-mtk-hostapd-Add-vendor-command-attribute-for-RTS-BW-.patch \
+    file://mtk-0015-mtk-hostapd-6G-band-does-not-require-DFS.patch \
+    file://mtk-0016-mtk-hostapd-Fix-sending-wrong-VHT-operation-IE-in-CS.patch \
+    file://mtk-0017-mtk-hostapd-Add-sta-assisted-DFS-state-update-mechan.patch \
+    file://mtk-0018-mtk-hostapd-Mark-DFS-channel-as-available-for-CSA.patch \
+    file://mtk-0019-mtk-hostapd-Add-available-color-bitmap.patch \
+    file://mtk-0020-mtk-hostapd-Fix-ZWDFS-issue-in-BW-160.patch \
+    file://mtk-0021-mtk-hostapd-Add-vendor-for-CAPI-certification-comman.patch \
+    file://mtk-0022-mtk-hostapd-Air-Monitor-support-in-hostapd-by-vendor.patch \
+    file://mtk-0023-mtk-hostapd-Fix-setting-wrong-seg0-index-for-5G-cent.patch \
+    file://mtk-0024-mtk-hostapd-Add-muru-user-number-debug-command.patch \
+    file://mtk-0025-mtk-hostapd-add-connac3-PHY-MURU-manual-mode-config-.patch \
+    file://mtk-0026-mtk-hostapd-Add-HE-capabilities-check.patch \
+    file://mtk-0027-mtk-hostapd-Fix-background-channel-overlapping-opera.patch \
+    file://mtk-0028-mtk-hostapd-Fix-hostapd_dfs_start_cac-log.patch \
+    file://mtk-0029-mtk-hostapd-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch \
+    file://mtk-0030-mtk-hostapd-Update-parameter_set_count-in-MU-EDCA-IE.patch \
+    file://mtk-0031-mtk-hostapd-add-extension-IE-list-for-non-inherit-IE.patch \
+    file://mtk-0032-mtk-hostapd-Fix-rnr-ie-length-when-no-need-to-report.patch \
+    file://mtk-0033-mtk-hostapd-add-back-ht-vht-cap-missing-field-before.patch \
+    file://mtk-0034-mtk-hostapd-update-op_class-when-AP-channel-switchin.patch \
+    file://mtk-0035-mtk-hostapd-Add-support-for-gtk-rekeying-in-hostapd-.patch \
+    file://mtk-0036-mtk-hostapd-Set-WMM-and-TX-queue-parameters-for-wpa_.patch \
+    file://mtk-0037-mtk-hostapd-Set-STA-TX-queue-parameters-configuratio.patch \
+    file://mtk-0038-mtk-hostapd-avoid-color-switch-when-beacon-is-not-se.patch \
+    file://mtk-0039-mtk-hostapd-6g-bss-connect-do-not-consider-ht-operat.patch \
+    file://mtk-0040-mtk-hostapd-avoid-unnecessary-beacon-update-for-6-GH.patch \
+    file://mtk-0041-mtk-hostapd-refactor-the-flow-to-create-Wide-Bandwid.patch \
+    file://mtk-0042-mtk-hostapd-Add-ACS-chanlist-info-in-get_config.patch \
+    file://mtk-0043-mtk-hostapd-Fix-RSNXE-Interop-issue-with-STA.patch \
+    file://mtk-0044-mtk-hostapd-Fix-chan_switch-to-usable-DFS-channel-fa.patch \
+    file://mtk-0045-mtk-hostapd-update-eht-operation-element.patch \
+    file://mtk-0046-mtk-hostapd-ucode-add-support-for-ucode-to-parse-BW3.patch \
+    file://mtk-0047-mtk-hostapd-synchronize-bandwidth-in-AP-STA-support.patch \
+    file://mtk-0048-mtk-hostapd-Add-support-for-updating-background-chan.patch \
+    file://mtk-0049-mtk-hostapd-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch \
+    file://mtk-0050-mtk-hostapd-add-support-enable-disable-preamble-punc.patch \
+    file://mtk-0051-mtk-hostapd-add-no_beacon-vendor-command-for-cert.patch \
+    file://mtk-0052-mtk-hostapd-ACS-Add-EHT320-and-HT40-support-fix-issu.patch \
+    file://mtk-0053-mtk-hostapd-add-eht_bw320_offset-configuration-optio.patch \
+    file://mtk-0054-mtk-hostapd-WPS-added-change-to-configure-AP-PIN-loc.patch \
     "
diff --git a/recipes-wifi/wpa-supplicant/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch b/recipes-wifi/wpa-supplicant/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch
new file mode 100644
index 0000000..be0bc74
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch
@@ -0,0 +1,172 @@
+From 8df5520f49796e4e292de6895aa0bc518978b377 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:36:59 +0200
+Subject: [PATCH 01/50] ACS: Extract bw40/80/160 freqs out of
+ acs_usable_bwXXX_chan()
+
+This extracts the 3 lists of allowed channels for 40/80/160 MHz
+bandwidth out of their respective functions. It also adds for each
+segment the frequency of the segment's last channel and the index of the
+segment's "center" channel.
+
+This is preparative work to allow selecting a channel which is not the
+first of its segment for 40/80/160 MHz. In addition, this adds the 5 GHz
+160 MHz channel defined for 5735-5895 MHz (channels 149-177).
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 107 ++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 63 insertions(+), 44 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 4a0a4c7..60c90e9 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -241,6 +241,57 @@
+  * [1] http://en.wikipedia.org/wiki/Near_and_far_field
+  */
+ 
++enum bw_type {
++	ACS_BW40,
++	ACS_BW80,
++	ACS_BW160,
++};
++
++struct bw_item {
++	int first;
++	int last;
++	int center_chan;
++};
++
++static const struct bw_item bw_40[] = {
++	{ 5180, 5200, 38 }, { 5220, 5240, 46 }, { 5260, 5280, 54 },
++	{ 5300, 5320, 62 }, { 5500, 5520, 102 }, { 5540, 5560, 110 },
++	{ 5580, 5600, 110 }, { 5620, 5640, 126}, { 5660, 5680, 134 },
++	{ 5700, 5720, 142 }, { 5745, 5765, 151 }, { 5785, 5805, 159 },
++	{ 5825, 5845, 167 }, { 5865, 5885, 175 },
++	{ 5955, 5975, 3 }, { 5995, 6015, 11 }, { 6035, 6055, 19 },
++	{ 6075, 6095, 27 }, { 6115, 6135, 35 }, { 6155, 6175, 43 },
++	{ 6195, 6215, 51 }, { 6235, 6255, 59 }, { 6275, 6295, 67 },
++	{ 6315, 6335, 75 }, { 6355, 6375, 83 }, { 6395, 6415, 91 },
++	{ 6435, 6455, 99 }, { 6475, 6495, 107 }, { 6515, 6535, 115 },
++	{ 6555, 6575, 123 }, { 6595, 6615, 131 }, { 6635, 6655, 139 },
++	{ 6675, 6695, 147 }, { 6715, 6735, 155 }, { 6755, 6775, 163 },
++	{ 6795, 6815, 171 }, { 6835, 6855, 179 }, { 6875, 6895, 187 },
++	{ 6915, 6935, 195 }, { 6955, 6975, 203 }, { 6995, 7015, 211 },
++	{ 7035, 7055, 219 }, { 7075, 7095, 227}, { -1, -1, -1 }
++};
++static const struct bw_item bw_80[] = {
++	{ 5180, 5240, 42 }, { 5260, 5320, 58 }, { 5500, 5560, 106 },
++	{ 5580, 5640, 122 }, { 5660, 5720, 138 }, { 5745, 5805, 155 },
++	{ 5825, 5885, 171},
++	{ 5955, 6015, 7 }, { 6035, 6095, 23 }, { 6115, 6175, 39 },
++	{ 6195, 6255, 55 }, { 6275, 6335, 71 }, { 6355, 6415, 87 },
++	{ 6435, 6495, 103 }, { 6515, 6575, 119 }, { 6595, 6655, 135 },
++	{ 6675, 6735, 151 }, { 6755, 6815, 167 }, { 6835, 6895, 183 },
++	{ 6915, 6975, 199 }, { 6995, 7055, 215 }, { -1, -1, -1 }
++};
++static const struct bw_item bw_160[] = {
++	{ 5180, 5320, 50 }, { 5500, 5640, 114 }, { 5745, 5885, 163 },
++	{ 5955, 6095, 15 }, { 6115, 6255, 47 }, { 6275, 6415, 79 },
++	{ 6435, 6575, 111 }, { 6595, 6735, 143 },
++	{ 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
++};
++static const struct bw_item *bw_desc[] = {
++	[ACS_BW40] = bw_40,
++	[ACS_BW80] = bw_80,
++	[ACS_BW160] = bw_160,
++};
++
+ 
+ static int acs_request_scan(struct hostapd_iface *iface);
+ static int acs_survey_is_sufficient(struct freq_survey *survey);
+@@ -370,50 +421,18 @@ acs_survey_chan_interference_factor(struct hostapd_iface *iface,
+ }
+ 
+ 
+-static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
++static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan,
++			       enum bw_type bw)
+ {
+-	const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620,
+-				5660, 5745, 5785, 4920, 4960, 5955, 5995, 6035,
+-				6075, 6115, 6155, 6195, 6235, 6275, 6315, 6355,
+-				6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675,
+-				6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995,
+-				7035, 7075 };
+-	unsigned int i;
+-
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
+-
+-	return 0;
+-}
+-
+-
+-static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
+-{
+-	const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, 6035,
+-				6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675,
+-				6755, 6835, 6915, 6995 };
+-	unsigned int i;
+-
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
+-
+-	return 0;
+-}
+-
+-
+-static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
+-{
+-	const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755,
+-				6915 };
+-	unsigned int i;
++	unsigned int i = 0;
+ 
+-	for (i = 0; i < ARRAY_SIZE(allowed); i++)
+-		if (chan->freq == allowed[i])
+-			return 1;
++	while (bw_desc[bw][i].first != -1) {
++		if (chan->freq == bw_desc[bw][i].first)
++			return true;
++		i++;
++	}
+ 
+-	return 0;
++	return false;
+ }
+ 
+ 
+@@ -705,7 +724,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		    ((iface->conf->ieee80211n &&
+ 		      iface->conf->secondary_channel) ||
+ 		     is_6ghz_freq(chan->freq)) &&
+-		    !acs_usable_bw40_chan(chan)) {
++		    !acs_usable_bw_chan(chan, ACS_BW40)) {
+ 			wpa_printf(MSG_DEBUG,
+ 				   "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth",
+ 				   chan->chan);
+@@ -716,7 +735,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
+ 			if (hostapd_get_oper_chwidth(iface->conf) ==
+ 			    CONF_OPER_CHWIDTH_80MHZ &&
+-			    !acs_usable_bw80_chan(chan)) {
++			    !acs_usable_bw_chan(chan, ACS_BW80)) {
+ 				wpa_printf(MSG_DEBUG,
+ 					   "ACS: Channel %d: not allowed as primary channel for 80 MHz bandwidth",
+ 					   chan->chan);
+@@ -725,7 +744,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 
+ 			if (hostapd_get_oper_chwidth(iface->conf) ==
+ 			    CONF_OPER_CHWIDTH_160MHZ &&
+-			    !acs_usable_bw160_chan(chan)) {
++			    !acs_usable_bw_chan(chan, ACS_BW160)) {
+ 				wpa_printf(MSG_DEBUG,
+ 					   "ACS: Channel %d: not allowed as primary channel for 160 MHz bandwidth",
+ 					   chan->chan);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch b/recipes-wifi/wpa-supplicant/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch
new file mode 100644
index 0000000..15e8c98
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch
@@ -0,0 +1,87 @@
+From 3e2fa0f4ab02538c66e61058749272565d94d111 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:00 +0200
+Subject: [PATCH 02/50] ACS: Introduce acs_get_bw_center_chan()
+
+When using 40/80/160 MHz bandwidth, instead of computing the index of
+the segment center freq based on the selected channel, lets look it up
+in the bw_desc[] table.
+
+This is preparative work to allow selecting a primary channel which is
+not the first of the segment.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 33 +++++++++++++++++++++++++++------
+ 1 file changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 60c90e9..511200d 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -436,6 +436,21 @@ static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan,
+ }
+ 
+ 
++static int acs_get_bw_center_chan(int freq, enum bw_type bw)
++{
++	unsigned int i = 0;
++
++	while (bw_desc[bw][i].first != -1) {
++		if (freq >= bw_desc[bw][i].first &&
++		    freq <= bw_desc[bw][i].last)
++			return bw_desc[bw][i].center_chan;
++		i++;
++	}
++
++	return 0;
++}
++
++
+ static int acs_survey_is_sufficient(struct freq_survey *survey)
+ {
+ 	if (!(survey->filled & SURVEY_HAS_NF)) {
+@@ -936,19 +951,26 @@ bw_selected:
+ 
+ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ {
+-	int offset;
++	int center;
+ 
+ 	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
+ 
+ 	switch (hostapd_get_oper_chwidth(iface->conf)) {
+ 	case CONF_OPER_CHWIDTH_USE_HT:
+-		offset = 2 * iface->conf->secondary_channel;
++		if (iface->conf->secondary_channel &&
++		    iface->freq >= 2400 && iface->freq < 2500)
++			center = iface->conf->channel +
++				2 * iface->conf->secondary_channel;
++		else if (iface->conf->secondary_channel)
++			center = acs_get_bw_center_chan(iface->freq, ACS_BW40);
++		else
++			center = iface->conf->channel;
+ 		break;
+ 	case CONF_OPER_CHWIDTH_80MHZ:
+-		offset = 6;
++		center = acs_get_bw_center_chan(iface->freq, ACS_BW80);
+ 		break;
+ 	case CONF_OPER_CHWIDTH_160MHZ:
+-		offset = 14;
++		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
+ 		break;
+ 	default:
+ 		/* TODO: How can this be calculated? Adjust
+@@ -958,8 +980,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ 		return;
+ 	}
+ 
+-	hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
+-					     iface->conf->channel + offset);
++	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, center);
+ }
+ 
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch b/recipes-wifi/wpa-supplicant/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch
new file mode 100644
index 0000000..b4ac1f0
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/bp-0003-ACS-introduce-acs_adjust_secondary.patch
@@ -0,0 +1,92 @@
+From 03dd213b918218fec270e781d284ec394fb63ef1 Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:01 +0200
+Subject: [PATCH 03/50] ACS: introduce acs_adjust_secondary
+
+When using 40/80/160 MHz bandwidth on the 5 GHz or 6 GHz band, enforce
+the secondary channel to be the other channel of the corresponding 40
+MHz segment.
+
+Even if this is useless for now, this is preparatory work to allow ACS
+to select a primary channel which is not the first of its segment.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 45 insertions(+), 1 deletion(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 511200d..78d1feb 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -634,6 +634,26 @@ acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
+ }
+ 
+ 
++static enum hostapd_hw_mode
++acs_find_mode(struct hostapd_iface *iface, int freq)
++{
++	int i;
++	struct hostapd_hw_modes *mode;
++	struct hostapd_channel_data *chan;
++
++	for (i = 0; i < iface->num_hw_features; i++) {
++		mode = &iface->hw_features[i];
++		if (!hostapd_hw_skip_mode(iface, mode)) {
++			chan = acs_find_chan_mode(mode, freq);
++			if (chan)
++				return mode->mode;
++		}
++	}
++
++	return HOSTAPD_MODE_IEEE80211ANY;
++}
++
++
+ static struct hostapd_channel_data *
+ acs_find_chan(struct hostapd_iface *iface, int freq)
+ {
+@@ -949,6 +969,28 @@ bw_selected:
+ }
+ 
+ 
++static void acs_adjust_secondary(struct hostapd_iface *iface)
++{
++	unsigned int i;
++
++	/* When working with bandwidth over 20 MHz on the 5 GHz or 6 GHz band,
++	 * ACS can return a secondary channel which is not the first channel of
++	 * the segment and we need to adjust. */
++	if (!iface->conf->secondary_channel ||
++	    acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A)
++		return;
++
++	wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency");
++
++	for (i = 0; bw_desc[ACS_BW40][i].first != -1; i++) {
++		if (iface->freq == bw_desc[ACS_BW40][i].first)
++			iface->conf->secondary_channel = 1;
++		else if (iface->freq == bw_desc[ACS_BW40][i].last)
++			iface->conf->secondary_channel = -1;
++	}
++}
++
++
+ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ {
+ 	int center;
+@@ -1036,8 +1078,10 @@ static void acs_study(struct hostapd_iface *iface)
+ 	iface->conf->channel = ideal_chan->chan;
+ 	iface->freq = ideal_chan->freq;
+ 
+-	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax)
++	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
++		acs_adjust_secondary(iface);
+ 		acs_adjust_center_freq(iface);
++	}
+ 
+ 	err = 0;
+ fail:
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch b/recipes-wifi/wpa-supplicant/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch
new file mode 100644
index 0000000..8da5856
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch
@@ -0,0 +1,78 @@
+From a615aa302064919791f3912a5cf1a908390414df Mon Sep 17 00:00:00 2001
+From: Nicolas Escande <nico.escande@gmail.com>
+Date: Wed, 27 Apr 2022 15:37:02 +0200
+Subject: [PATCH 04/50] ACS: Allow selecting a better channel when using
+ 40/80/160 MHz
+
+When considering a channel for a bandwidth of 40/80/160 MHZ on the 5 GHz
+or 6 GHz band, allow selecting one of the other channels in the segment
+instead of the first one. This is done only if the other channel's
+interference_factor is lower than the first one's.
+
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+---
+ src/ap/acs.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 78d1feb..130e135 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -712,7 +712,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			 struct hostapd_channel_data **ideal_chan,
+ 			 long double *ideal_factor)
+ {
+-	struct hostapd_channel_data *chan, *adj_chan = NULL;
++	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
+ 	long double factor;
+ 	int i, j;
+ 	unsigned int k;
+@@ -720,8 +720,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 	for (i = 0; i < mode->num_channels; i++) {
+ 		double total_weight;
+ 		struct acs_bias *bias, tmp_bias;
++		bool update_best = true;
+ 
+-		chan = &mode->channels[i];
++		best = chan = &mode->channels[i];
+ 
+ 		/* Since in the current ACS implementation the first channel is
+ 		 * always a primary channel, skip channels not available as
+@@ -807,7 +808,15 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			if (acs_usable_chan(adj_chan)) {
+ 				factor += adj_chan->interference_factor;
+ 				total_weight += 1;
++			} else {
++				update_best = false;
+ 			}
++
++			/* find the best channel in this segment */
++			if (update_best &&
++			    adj_chan->interference_factor <
++			    best->interference_factor)
++				best = adj_chan;
+ 		}
+ 
+ 		if (j != n_chans) {
+@@ -816,6 +825,18 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			continue;
+ 		}
+ 
++		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
++		 * crowded primary channel if one was found in the segment */
++		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
++		    chan != best) {
++			wpa_printf(MSG_DEBUG,
++				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
++				   best->chan, chan->chan,
++				   chan->interference_factor,
++				   best->interference_factor);
++			chan = best;
++		}
++
+ 		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
+ 		 * channel interference factor. */
+ 		if (is_24ghz_mode(mode->mode)) {
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
index b3f4138..af6eaa5 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
@@ -1,11 +1,11 @@
-From 53a7b7af61b75ea0e3f9d12d3d6302cf40941a8a Mon Sep 17 00:00:00 2001
+From adc0d43ecd5ad2f8932c7a25c6b0e1dea336aef8 Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Tue, 9 Aug 2022 10:23:44 -0700
-Subject: [PATCH 06/37] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH] hostapd: mtk: Add hostapd MU SET/GET control
 
 ---
  hostapd/config_file.c             |   9 +++
- hostapd/ctrl_iface.c              |  62 +++++++++++++++++
+ hostapd/ctrl_iface.c              |  66 ++++++++++++++++++
  hostapd/hostapd_cli.c             |  18 +++++
  src/ap/ap_config.c                |   1 +
  src/ap/ap_config.h                |   1 +
@@ -17,7 +17,7 @@
  src/drivers/driver_nl80211.c      | 110 ++++++++++++++++++++++++++++++
  src/drivers/driver_nl80211.h      |   1 +
  src/drivers/driver_nl80211_capa.c |   3 +
- 13 files changed, 251 insertions(+)
+ 13 files changed, 255 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
 index b5024cc..62e8b33 100644
@@ -40,10 +40,10 @@
  	} else if (os_strcmp(buf, "max_listen_interval") == 0) {
  		bss->max_listen_interval = atoi(pos);
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 9c70d54..c72f336 100644
+index 9c70d54..894c47a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3441,6 +3441,63 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
+@@ -3441,6 +3441,67 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
  }
  
  
@@ -93,6 +93,10 @@
 +	pos = buf;
 +	end = buf + buflen;
 +
++	if (hapd->iface->state != HAPD_IFACE_ENABLED)
++		return os_snprintf(pos, end - pos, "Not allowed to get_mu when current state is %s\n",
++				   hostapd_state_text(hapd->iface->state));
++
 +	if (hostapd_drv_mu_dump(hapd, &mu_onoff) == 0) {
 +		hapd->iconf->mu_onoff = mu_onoff;
 +		return os_snprintf(pos, end - pos, "[hostapd_cli] = UL MU-MIMO: %d, DL MU-MIMO: %d, UL OFDMA: %d, DL OFDMA: %d\n",
@@ -107,7 +111,7 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -3993,6 +4050,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -3993,6 +4054,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  	} else if (os_strncmp(buf, "GET_EDCCA ", 10) == 0) {
  		reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
  							  reply_size);
@@ -156,7 +160,7 @@
  	{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
  	  "report a scanned DPP URI from a QR Code" },
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 344585a..1b0e990 100644
+index 344585a..9e5a2ec 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -280,6 +280,7 @@ struct hostapd_config * hostapd_config_defaults(void)
@@ -446,5 +450,5 @@
  			}
  
 -- 
-2.39.0
+2.18.0
 
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
index aa72f2a..03793bb 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
@@ -1,7 +1,7 @@
-From 9b82b5966b57403f389759b6dfb8318dd862b480 Mon Sep 17 00:00:00 2001
+From 8b9963570219d1ba217da21d02fa193ee8aef4ae Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 16 Dec 2022 03:57:11 +0800
-Subject: [PATCH 12/35] hostapd: mtk: Add amsdu set get ctrl
+Subject: [PATCH] hostapd: mtk: Add amsdu set get ctrl
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -40,10 +40,10 @@
  		wpa_printf(MSG_ERROR,
  			   "Line %d: unknown configuration item '%s'",
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 37a1b2a..61c9e80 100644
+index fcbc4ae..8ed56e4 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3612,6 +3612,30 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
+@@ -3542,6 +3542,30 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
  }
  
  
@@ -74,10 +74,10 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4176,6 +4200,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+@@ -4104,6 +4128,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
+ 		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
  								   reply, reply_size);
- 	} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
- 		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
 +	} else if (os_strncmp(buf, "GET_AMSDU", 9) == 0) {
 +		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
  	} else {
@@ -111,7 +111,7 @@
  };
  
 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index df90814..24fc0f5 100644
+index c47418a..b351edb 100644
 --- a/src/ap/ap_config.c
 +++ b/src/ap/ap_config.c
 @@ -299,6 +299,7 @@ struct hostapd_config * hostapd_config_defaults(void)
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
index 1b23579..6f4425f 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0022-hostapd-mtk-Add-available-color-bitmap.patch
@@ -1,7 +1,7 @@
-From 9b40b6ccf6fd2f4463b389df46d38610001df04e Mon Sep 17 00:00:00 2001
+From 2e7919e5e52fefa14a48e77fd739ef05371a26c9 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Thu, 26 Jan 2023 09:16:00 +0800
-Subject: [PATCH 22/35] hostapd: mtk: Add available color bitmap
+Subject: [PATCH] hostapd: mtk: Add available color bitmap
 
 Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 ---
@@ -17,10 +17,10 @@
  9 files changed, 192 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 9ba6992..e1e9270 100644
+index 2b7ac96..549c93a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3645,6 +3645,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
+@@ -3575,6 +3575,76 @@ hostapd_ctrl_iface_get_amsdu(struct hostapd_data *hapd, char *buf,
  	return ret;
  }
  
@@ -97,8 +97,8 @@
  
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
-@@ -4212,6 +4282,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
+@@ -4140,6 +4210,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 								   reply, reply_size);
  	} else if (os_strncmp(buf, "GET_AMSDU", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_get_amsdu(hapd, reply, reply_size);
 +	} else if (os_strncmp(buf, "GET_BSS_COLOR", 13) == 0) {
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch
new file mode 100644
index 0000000..d968859
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch
@@ -0,0 +1,283 @@
+From 920a20927f1537ae2a6ce9c7123ef189e83cd0a0 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Sat, 11 Nov 2023 11:42:59 +0800
+Subject: [PATCH] hostapd: mtk: ACS: Fix 2.4GHz HT40 case and channel switch
+ fail
+
+Issue#1. Add 2.4G HT40- support
+1. Add 2.4G HT40- support
+2. Fix issue: selected best channel is out of channels
+
+Issue#2. Fix chan_switch to usable DFS channel fail due to ACS
+
+Step and issue:
+1. Enable ACS in hostapd config;
+2. Bootup and then use hostapd_cli cmd switch channel to a DFS channel;
+3. Will do ACS again, and no work on channel specified in step 2.
+
+Root cause:
+When need do DFS-CAC, hostapd will do intf disable, then set the new
+channel into running config settings, and finally enable intf;
+In the test case, new DFS channel is set to runnint config settings, but
+another param "acs" is still 1 (enable), caused the ACS running when
+intf enabled.
+---
+ src/ap/acs.c     | 142 ++++++++++++++++++++++++++---------------------
+ src/ap/hostapd.c |   3 +
+ 2 files changed, 83 insertions(+), 62 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index 130e135..65573b9 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -712,10 +712,19 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			 struct hostapd_channel_data **ideal_chan,
+ 			 long double *ideal_factor)
+ {
+-	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
++	struct hostapd_channel_data *chan, *adj_chan = NULL, *tmp_chan = NULL, *best;
+ 	long double factor;
+ 	int i, j;
+ 	unsigned int k;
++	int ht40_plus = 1, sec_ch_factor = 1;
++
++	if (is_24ghz_mode(mode->mode)) {
++		ht40_plus = (iface->conf->secondary_channel == -1) ? 0 : 1;
++		sec_ch_factor = (iface->conf->secondary_channel == -1) ? -1 : 1;
++	}
++
++	wpa_printf(MSG_INFO, "%s:%d, bw(%u), n_chans(%d), num_channels(%d), sec_ch(%d)",
++		__func__, __LINE__, bw, n_chans, mode->num_channels, iface->conf->secondary_channel);
+ 
+ 	for (i = 0; i < mode->num_channels; i++) {
+ 		double total_weight;
+@@ -723,6 +732,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		bool update_best = true;
+ 
+ 		best = chan = &mode->channels[i];
++		wpa_printf(MSG_INFO,
++			   "ACS: Channel[%d] %d: interference_factor %Lg",
++			   i, chan->chan, chan->interference_factor);
+ 
+ 		/* Since in the current ACS implementation the first channel is
+ 		 * always a primary channel, skip channels not available as
+@@ -747,7 +759,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		if (chan->flag & HOSTAPD_CHAN_INDOOR_ONLY && iface->conf->country[2] == 0x4f)
+ 			continue;
+ 
+-		if (!chan_bw_allowed(chan, bw, 1, 1)) {
++		if (!chan_bw_allowed(chan, bw, ht40_plus, 1)) {
+ 			wpa_printf(MSG_DEBUG,
+ 				   "ACS: Channel %d: BW %u is not supported",
+ 				   chan->chan, bw);
+@@ -789,60 +801,73 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		}
+ 
+ 		factor = 0;
+-		if (acs_usable_chan(chan))
+-			factor = chan->interference_factor;
+-		total_weight = 1;
+-
+-		for (j = 1; j < n_chans; j++) {
+-			adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
+-			if (!adj_chan)
+-				break;
++		total_weight = 0;
+ 
+-			if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
+-				wpa_printf(MSG_DEBUG,
+-					   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
+-					   chan->chan, adj_chan->chan, bw);
+-				break;
+-			}
+-
+-			if (acs_usable_chan(adj_chan)) {
+-				factor += adj_chan->interference_factor;
++		if (!is_24ghz_mode(mode->mode)) {
++			/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
++			 * crowded primary channel if one was found in the segment */
++			if (acs_usable_chan(chan)) {
++				factor += chan->interference_factor;
+ 				total_weight += 1;
+-			} else {
+-				update_best = false;
+ 			}
+ 
+-			/* find the best channel in this segment */
+-			if (update_best &&
+-			    adj_chan->interference_factor <
+-			    best->interference_factor)
+-				best = adj_chan;
+-		}
++			for (j = 1; j < n_chans; j++) {
++				adj_chan = acs_find_chan(iface, chan->freq + j * 20);
++				if (!adj_chan)
++					break;
+ 
+-		if (j != n_chans) {
+-			wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
+-				   chan->chan);
+-			continue;
+-		}
++				if (!is_in_chanlist(iface, adj_chan) || !is_in_freqlist(iface, adj_chan))
++					break;
+ 
+-		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
+-		 * crowded primary channel if one was found in the segment */
+-		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+-		    chan != best) {
+-			wpa_printf(MSG_DEBUG,
+-				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
+-				   best->chan, chan->chan,
+-				   chan->interference_factor,
+-				   best->interference_factor);
+-			chan = best;
+-		}
++				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
++					wpa_printf(MSG_DEBUG,
++						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
++						   chan->chan, adj_chan->chan, bw);
++					break;
++				}
+ 
+-		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
+-		 * channel interference factor. */
+-		if (is_24ghz_mode(mode->mode)) {
++				update_best = true;
++				if (acs_usable_chan(adj_chan)) {
++					factor += adj_chan->interference_factor;
++					total_weight += 1;
++				} else {
++					update_best = false;
++				}
++
++				/* find the best channel in this segment */
++				if (update_best &&
++					adj_chan->interference_factor < best->interference_factor)
++					best = adj_chan;
++			}
++
++			if (j != n_chans) {
++				wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
++					   chan->chan);
++				continue;
++			}
++
++			if (chan != best) {
++				wpa_printf(MSG_INFO,
++					   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
++					   best->chan, chan->chan,
++					   chan->interference_factor,
++					   best->interference_factor);
++				chan = best;
++			}
++		} else {
+ 			for (j = 0; j < n_chans; j++) {
++				/* Will set primary_channel / secondary_channel(40M case) weight to 1 */
++				tmp_chan = acs_find_chan(iface, chan->freq +
++							 (j * sec_ch_factor * 20));
++				if (tmp_chan && acs_usable_chan(tmp_chan)) {
++					factor += tmp_chan->interference_factor;
++					total_weight += 1;
++				}
++
++				/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent channel
++				interference factor, separately for primary/secondary channel. */
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) - 5);
++							  (j * sec_ch_factor * 20) - 5);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -850,7 +875,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) - 10);
++							  (j * sec_ch_factor * 20) - 10);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_NEXT_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -858,7 +883,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) + 5);
++							 (j * sec_ch_factor * 20) + 5);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -866,7 +891,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) + 10);
++							 (j * sec_ch_factor * 20) + 10);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_NEXT_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -875,7 +900,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			}
+ 		}
+ 
+-		factor /= total_weight;
++		if (total_weight)
++			factor /= total_weight;
+ 
+ 		bias = NULL;
+ 		if (iface->conf->acs_chan_bias) {
+@@ -894,11 +920,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 
+ 		if (bias) {
+ 			factor *= bias->bias;
+-			wpa_printf(MSG_DEBUG,
++			wpa_printf(MSG_INFO,
+ 				   "ACS:  * channel %d: total interference = %Lg (%f bias)",
+ 				   chan->chan, factor, bias->bias);
+ 		} else {
+-			wpa_printf(MSG_DEBUG,
++			wpa_printf(MSG_INFO,
+ 				   "ACS:  * channel %d: total interference = %Lg",
+ 				   chan->chan, factor);
+ 		}
+@@ -939,14 +965,6 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+ 		goto bw_selected;
+ 	}
+ 
+-	/* TODO: HT40- support */
+-
+-	if (iface->conf->ieee80211n &&
+-	    iface->conf->secondary_channel == -1) {
+-		wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
+-		return NULL;
+-	}
+-
+ 	if (iface->conf->ieee80211n &&
+ 	    iface->conf->secondary_channel)
+ 		n_chans = 2;
+@@ -981,7 +999,7 @@ bw_selected:
+ 	}
+ 
+ 	if (ideal_chan) {
+-		wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
++		wpa_printf(MSG_INFO, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
+ 			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
+ 		return ideal_chan;
+ 	}
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index f2eb638..250c168 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -3895,6 +3895,9 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+ 
+ 	iface->freq = freq_params->freq;
+ 	iface->conf->channel = freq_params->channel;
++	if (iface->conf->channel != 0) /* If channel not zero, will disable acs. */
++		iface->conf->acs = 0;
++
+ 	iface->conf->secondary_channel = freq_params->sec_channel_offset;
+ 	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
+ 	hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch
similarity index 90%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
copy to recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch
index c247137..1937640 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch
@@ -1,8 +1,7 @@
-From 31d7b7fe98e3d5d0e2769bd7ea22e529a7f1295d Mon Sep 17 00:00:00 2001
+From 99159b174eb245a7162fe38900971cdff017cf75 Mon Sep 17 00:00:00 2001
 From: Michael Lee <michael-cy.lee@mediatek.com>
 Date: Thu, 13 Jul 2023 13:14:26 +0800
-Subject: [PATCH 29/38] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
- failed
+Subject: [PATCH] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF failed
 
 If ioctl returns EBUSY on command SIOCBRADDIF, the interface might
 already be bridged by others, and linux_br_add_if should not indicate an
@@ -52,5 +51,5 @@
  
  	return 0;
 -- 
-2.18.0
+2.25.1
 
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
new file mode 100644
index 0000000..82b66f4
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch
@@ -0,0 +1,135 @@
+From 018d87d5b9b53b3e630032bf2cb7e6eaeae09d71 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 15 Nov 2023 15:06:00 +0800
+Subject: [PATCH 47/49] hostapd: mtk: add support for channel switching to dfs
+ with csa sent
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ hostapd/ctrl_iface.c | 26 ++------------------------
+ src/ap/beacon.c      |  5 +++++
+ src/ap/dfs.c         | 16 ++++++++++++----
+ src/ap/ieee802_11.c  |  5 +++++
+ 4 files changed, 24 insertions(+), 28 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index b521a08..0afa6a2 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -2747,7 +2747,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 	int dfs_range = 0;
+ 	unsigned int i;
+ 	int bandwidth;
+-	u8 chan;
+ 
+ 	ret = hostapd_parse_csa_settings(pos, &settings);
+ 	if (ret)
+@@ -2809,29 +2808,8 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 			iface, bandwidth, settings.freq_params.center_freq2);
+ 
+ 	if (dfs_range) {
+-		ret = ieee80211_freq_to_chan(settings.freq_params.freq, &chan);
+-		if (ret == NUM_HOSTAPD_MODES) {
+-			wpa_printf(MSG_ERROR,
+-				   "Failed to get channel for (freq=%d, sec_channel_offset=%d, bw=%d)",
+-				   settings.freq_params.freq,
+-				   settings.freq_params.sec_channel_offset,
+-				   settings.freq_params.bandwidth);
+-			return -1;
+-		}
+-
+-		settings.freq_params.channel = chan;
+-
+-		wpa_printf(MSG_DEBUG,
+-			   "DFS/CAC to (channel=%u, freq=%d, sec_channel_offset=%d, bw=%d, center_freq1=%d)",
+-			   settings.freq_params.channel,
+-			   settings.freq_params.freq,
+-			   settings.freq_params.sec_channel_offset,
+-			   settings.freq_params.bandwidth,
+-			   settings.freq_params.center_freq1);
+-
+-		/* Perform CAC and switch channel */
+-		hostapd_switch_channel_fallback(iface, &settings.freq_params);
+-		return 0;
++		settings.cs_count = 5;
++		settings.block_tx = 1;
+ 	}
+ 
+ 	for (i = 0; i < iface->num_bss; i++) {
+diff --git a/src/ap/beacon.c b/src/ap/beacon.c
+index 02f4f87..f9c4924 100644
+--- a/src/ap/beacon.c
++++ b/src/ap/beacon.c
+@@ -2027,6 +2027,11 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
+ 		return -1;
+ 	}
+ 
++	if (iface->cac_started) {
++		wpa_printf(MSG_DEBUG, "Ignore set beacons during CAC period");
++		return 0;
++	}
++
+ 	hapd->beacon_set_done = 1;
+ 
+ 	if (ieee802_11_build_ap_params(hapd, &params) < 0)
+diff --git a/src/ap/dfs.c b/src/ap/dfs.c
+index 80d3605..012050c 100644
+--- a/src/ap/dfs.c
++++ b/src/ap/dfs.c
+@@ -1255,10 +1255,10 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
+ 			 * another radio.
+ 			 */
+ 			if (iface->state != HAPD_IFACE_ENABLED &&
+-			    hostapd_is_dfs_chan_available(iface)) {
++			    hostapd_is_dfs_chan_available(iface))
+ 				hostapd_setup_interface_complete(iface, 0);
+-				iface->cac_started = 0;
+-			}
++
++			iface->cac_started = 0;
+ 
+ 			/*
+ 			 * When background radar is enabled but the CAC completion
+@@ -1272,6 +1272,13 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
+ 	} else if (hostapd_dfs_is_background_event(iface, freq)) {
+ 		iface->radar_background.cac_started = 0;
+ 		hostpad_dfs_update_background_chain(iface);
++	} else {
++		int i;
++
++		iface->cac_started = 0;
++		/* Clear all CSA flags once channel switch to DFS channel fails */
++		for (i = 0; i < iface->num_bss; i++)
++			iface->bss[i]->csa_in_progress = 0;
+ 	}
+ 
+ 	return 0;
+@@ -1646,7 +1653,8 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+ 	} else {
+ 		/* This is called when the driver indicates that an offloaded
+ 		 * DFS has started CAC. */
+-		hostapd_set_state(iface, HAPD_IFACE_DFS);
++		if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
++			hostapd_set_state(iface, HAPD_IFACE_DFS);
+ 		iface->cac_started = 1;
+ 	}
+ 	/* TODO: How to check CAC time for ETSI weather channels? */
+diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
+index 01ceb79..dd477fd 100644
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -6352,6 +6352,11 @@ int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
+ 		return 1;
+ 	}
+ 
++	if (hapd->iface->cac_started) {
++		wpa_printf(MSG_DEBUG, "MGMT: Ignore management frame during CAC");
++		return 1;
++	}
++
+ 	if (stype == WLAN_FC_STYPE_PROBE_REQ) {
+ 		handle_probe_req(hapd, mgmt, len, ssi_signal);
+ 		return 1;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch
new file mode 100644
index 0000000..0dbdaca
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch
@@ -0,0 +1,409 @@
+From a0538a9373ec7def76048e020fcb6ecfec53f3db Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 16 Nov 2023 13:18:48 +0800
+Subject: [PATCH] hostapd: mtk: add support for channel switching with csa sent
+ when background radar is enabled
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ hostapd/ctrl_iface.c   |  82 +++++++++++++++++-----
+ src/ap/ctrl_iface_ap.c |   5 +-
+ src/ap/dfs.c           | 156 +++++++++++++++++++++++++++++++++++------
+ src/ap/dfs.h           |   9 ++-
+ 4 files changed, 212 insertions(+), 40 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index 0afa6a2..44903e0 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -2742,11 +2742,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 					  char *pos)
+ {
+ #ifdef NEED_AP_MLME
+-	struct csa_settings settings;
++	struct csa_settings settings, background_settings;
+ 	int ret;
+-	int dfs_range = 0;
++	int freq, state;
+ 	unsigned int i;
+-	int bandwidth;
++	int bandwidth, oper_chwidth;
++	bool background_radar, bw_changed, cac_required = false;
+ 
+ 	ret = hostapd_parse_csa_settings(pos, &settings);
+ 	if (ret)
+@@ -2762,21 +2763,28 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 	switch (settings.freq_params.bandwidth) {
+ 	case 40:
+ 		bandwidth = CHAN_WIDTH_40;
++		oper_chwidth = CONF_OPER_CHWIDTH_USE_HT;
+ 		break;
+ 	case 80:
+-		if (settings.freq_params.center_freq2)
++		if (settings.freq_params.center_freq2) {
+ 			bandwidth = CHAN_WIDTH_80P80;
+-		else
++			oper_chwidth = CONF_OPER_CHWIDTH_80P80MHZ;
++		} else {
+ 			bandwidth = CHAN_WIDTH_80;
++			oper_chwidth = CONF_OPER_CHWIDTH_80MHZ;
++		}
+ 		break;
+ 	case 160:
+ 		bandwidth = CHAN_WIDTH_160;
++		oper_chwidth = CONF_OPER_CHWIDTH_160MHZ;
+ 		break;
+ 	case 320:
+ 		bandwidth = CHAN_WIDTH_320;
++		oper_chwidth = CONF_OPER_CHWIDTH_320MHZ;
+ 		break;
+ 	default:
+ 		bandwidth = CHAN_WIDTH_20;
++		oper_chwidth = CONF_OPER_CHWIDTH_USE_HT;
+ 		break;
+ 	}
+ 
+@@ -2797,19 +2805,29 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 	}
+ 
+ 	if (settings.freq_params.center_freq1)
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.center_freq1);
++		freq = settings.freq_params.center_freq1;
+ 	else
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.freq);
+-
+-	if (settings.freq_params.center_freq2)
+-		dfs_range += hostapd_is_dfs_overlap(
+-			iface, bandwidth, settings.freq_params.center_freq2);
+-
+-	if (dfs_range) {
+-		settings.cs_count = 5;
+-		settings.block_tx = 1;
++		freq = settings.freq_params.freq;
++
++	bw_changed = oper_chwidth != hostapd_get_oper_chwidth(iface->conf);
++	state = hostapd_dfs_get_target_state(iface, bandwidth, freq,
++					     settings.freq_params.center_freq2);
++	switch (state) {
++	case HOSTAPD_CHAN_DFS_USABLE:
++		cac_required = true;
++		/* fallthrough */
++	case HOSTAPD_CHAN_DFS_AVAILABLE:
++		background_radar = hostapd_dfs_handle_csa(iface, &settings,
++							  &background_settings,
++							  cac_required,
++							  bw_changed);
++		break;
++	case HOSTAPD_CHAN_DFS_UNAVAILABLE:
++		wpa_printf(MSG_INFO,
++			   "chanswitch: target channel is UNAVAILABLE, so stop switching");
++		return -1;
++	default:
++		break;
+ 	}
+ 
+ 	for (i = 0; i < iface->num_bss; i++) {
+@@ -2826,6 +2844,36 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+ 		}
+ 	}
+ 
++	if (background_radar) {
++		u8 seg0, seg1;
++
++		ieee80211_freq_to_chan(background_settings.freq_params.center_freq1, &seg0);
++		ieee80211_freq_to_chan(background_settings.freq_params.center_freq2, &seg1);
++		ret = hostapd_start_dfs_cac(iface, iface->conf->hw_mode,
++					    background_settings.freq_params.freq,
++					    background_settings.freq_params.channel,
++					    background_settings.freq_params.ht_enabled,
++					    background_settings.freq_params.vht_enabled,
++					    background_settings.freq_params.he_enabled,
++					    background_settings.freq_params.eht_enabled,
++					    background_settings.freq_params.sec_channel_offset,
++					    oper_chwidth, seg0, seg1, true);
++		if (ret) {
++			wpa_printf(MSG_ERROR, "Background radar start dfs cac failed, %d",
++				   ret);
++			iface->radar_background.channel = -1;
++			return -1;
++		}
++
++		/* Cache background radar parameters. */
++		iface->radar_background.channel = background_settings.freq_params.channel;
++		iface->radar_background.secondary_channel =
++			background_settings.freq_params.sec_channel_offset;
++		iface->radar_background.freq = background_settings.freq_params.freq;
++		iface->radar_background.centr_freq_seg0_idx = seg0;
++		iface->radar_background.centr_freq_seg1_idx = seg1;
++	}
++
+ 	return 0;
+ #else /* NEED_AP_MLME */
+ 	return -1;
+diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
+index 86e8729..005c9fa 100644
+--- a/src/ap/ctrl_iface_ap.c
++++ b/src/ap/ctrl_iface_ap.c
+@@ -907,6 +907,7 @@ int hostapd_parse_csa_settings(const char *pos,
+ 			       struct csa_settings *settings)
+ {
+ 	char *end;
++	int ret;
+ 
+ 	os_memset(settings, 0, sizeof(*settings));
+ 	settings->cs_count = strtol(pos, &end, 10);
+@@ -916,7 +917,9 @@ int hostapd_parse_csa_settings(const char *pos,
+ 	}
+ 
+ 	settings->freq_params.freq = atoi(end);
+-	if (settings->freq_params.freq == 0) {
++	ret = ieee80211_freq_to_chan(settings->freq_params.freq,
++				     &settings->freq_params.channel);
++	if (ret == NUM_HOSTAPD_MODES) {
+ 		wpa_printf(MSG_ERROR, "chanswitch: invalid freq provided");
+ 		return -1;
+ 	}
+diff --git a/src/ap/dfs.c b/src/ap/dfs.c
+index 012050c..5108e0a 100644
+--- a/src/ap/dfs.c
++++ b/src/ap/dfs.c
+@@ -248,14 +248,15 @@ static int is_in_chanlist(struct hostapd_iface *iface,
+  */
+ static int dfs_find_channel(struct hostapd_iface *iface,
+ 			    struct hostapd_channel_data **ret_chan,
+-			    int idx, enum dfs_channel_type type)
++			    int n_chans, int idx, enum dfs_channel_type type)
+ {
+ 	struct hostapd_hw_modes *mode;
+ 	struct hostapd_channel_data *chan;
+-	int i, channel_idx = 0, n_chans, n_chans1;
++	int i, channel_idx = 0, n_chans1;
+ 
+ 	mode = iface->current_mode;
+-	n_chans = dfs_get_used_n_chans(iface, &n_chans1);
++	if (!n_chans)
++		n_chans = dfs_get_used_n_chans(iface, &n_chans1);
+ 
+ 	wpa_printf(MSG_DEBUG, "DFS new chan checking %d channels", n_chans);
+ 	for (i = 0; i < mode->num_channels; i++) {
+@@ -548,7 +549,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		return NULL;
+ 
+ 	/* Get the count first */
+-	num_available_chandefs = dfs_find_channel(iface, NULL, 0, type);
++	num_available_chandefs = dfs_find_channel(iface, NULL, 0, 0, type);
+ 	wpa_printf(MSG_DEBUG, "DFS: num_available_chandefs=%d",
+ 		   num_available_chandefs);
+ 	if (num_available_chandefs == 0)
+@@ -569,7 +570,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		return NULL;
+ 
+ 	chan_idx = _rand % num_available_chandefs;
+-	dfs_find_channel(iface, &chan, chan_idx, type);
++	dfs_find_channel(iface, &chan, 0, chan_idx, type);
+ 	if (!chan) {
+ 		wpa_printf(MSG_DEBUG, "DFS: no random channel found");
+ 		return NULL;
+@@ -599,7 +600,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
+ 		for (i = 0; i < num_available_chandefs - 1; i++) {
+ 			/* start from chan_idx + 1, end when chan_idx - 1 */
+ 			chan_idx2 = (chan_idx + 1 + i) % num_available_chandefs;
+-			dfs_find_channel(iface, &chan2, chan_idx2, type);
++			dfs_find_channel(iface, &chan2, 0, chan_idx2, type);
+ 			if (chan2 && abs(chan2->chan - chan->chan) > 12) {
+ 				/* two channels are not adjacent */
+ 				sec_chan_idx_80p80 = chan2->chan;
+@@ -1302,6 +1303,9 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq,
+ 	set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width,
+ 		      cf1, cf2, HOSTAPD_CHAN_DFS_USABLE);
+ 
++	if (dfs_use_radar_background(iface) && iface->radar_background.channel == -1)
++		hostpad_dfs_update_background_chain(iface);
++
+ 	return 0;
+ }
+ 
+@@ -1715,14 +1719,15 @@ int hostapd_handle_dfs_offload(struct hostapd_iface *iface)
+ }
+ 
+ 
+-int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+-			   int center_freq)
++int hostapd_dfs_get_target_state(struct hostapd_iface *iface, enum chan_width width,
++				 int center_freq, int center_freq2)
+ {
+ 	struct hostapd_channel_data *chan;
+ 	struct hostapd_hw_modes *mode = iface->current_mode;
+-	int half_width;
+-	int res = 0;
++	int half_width, chan_state, state = 0;
++	int upper, lower;
+ 	int i;
++	bool in_range;
+ 
+ 	if (!iface->conf->ieee80211h || !mode ||
+ 	    mode->mode != HOSTAPD_MODE_IEEE80211A)
+@@ -1755,18 +1760,129 @@ int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+ 		if (!(chan->flag & HOSTAPD_CHAN_RADAR))
+ 			continue;
+ 
+-		if ((chan->flag & HOSTAPD_CHAN_DFS_MASK) ==
+-		    HOSTAPD_CHAN_DFS_AVAILABLE)
+-			continue;
++		upper = chan->freq + half_width;
++		lower = chan->freq - half_width;
++		in_range = (lower < center_freq && center_freq < upper) ||
++			   (center_freq2 && (lower < center_freq2 && center_freq2 < upper));
++		if (in_range) {
++			chan_state = chan->flag & HOSTAPD_CHAN_DFS_MASK;
++			switch (chan_state) {
++			case HOSTAPD_CHAN_DFS_USABLE:
++				state = HOSTAPD_CHAN_DFS_USABLE;
++				break;
++			case HOSTAPD_CHAN_DFS_AVAILABLE:
++				if (state != HOSTAPD_CHAN_DFS_USABLE)
++					state = HOSTAPD_CHAN_DFS_AVAILABLE;
++				break;
++			case HOSTAPD_CHAN_DFS_UNKNOWN:
++				wpa_printf(MSG_WARNING, "chan %d DFS state: UNKNOWN",
++					   chan->freq);
++				/* fallthrough */
++			case HOSTAPD_CHAN_DFS_UNAVAILABLE:
++			default:
++				return HOSTAPD_CHAN_DFS_UNAVAILABLE;
++			}
++		}
++	}
+ 
+-		if (center_freq - chan->freq < half_width &&
+-		    chan->freq - center_freq < half_width)
+-			res++;
++	wpa_printf(MSG_DEBUG, "freq range (%d, %d) has DFS state %d",
++		   center_freq - half_width, center_freq + half_width, state);
++
++	return state;
++}
++
++
++static struct hostapd_channel_data *
++dfs_get_csa_channel(struct hostapd_iface *iface,
++		    int n_chans, int cur_center,
++		    enum dfs_channel_type type)
++{
++	struct hostapd_channel_data *chan;
++	int avail_chan_num;
++	u32 _rand, idx;
++
++	if (os_get_random((u8 *)&_rand, sizeof(_rand)) < 0)
++		return NULL;
++
++	avail_chan_num = dfs_find_channel(iface, NULL, n_chans, 0, type);
++	if (!avail_chan_num)
++		return NULL;
++
++	idx = _rand % avail_chan_num;
++	dfs_find_channel(iface, &chan, n_chans, idx, type);
++	if (cur_center == chan->freq + (n_chans - 1) * 10) {
++		if (avail_chan_num == 1)
++			return NULL;
++
++		/* Get the next channel if the found channel is same as current channel */
++		idx = (idx + 1) % avail_chan_num;
++		dfs_find_channel(iface, &chan, n_chans, idx, type);
+ 	}
+ 
+-	wpa_printf(MSG_DEBUG, "DFS CAC required: (%d, %d): in range: %s",
+-		   center_freq - half_width, center_freq + half_width,
+-		   res ? "yes" : "no");
++	return chan;
++}
+ 
+-	return res;
++
++/*
++ * DFS handler for CSA
++ * 1  - update background radar with the filled setting
++ * 0  - background radar is not enabled / background radar remain at the same channel /
++ *	disable background radar
++ */
++int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
++			   struct csa_settings *settings,
++			   struct csa_settings *background_settings,
++			   bool cac_required, bool bw_changed)
++{
++	struct hostapd_channel_data *chan;
++	struct hostapd_freq_params *freq_params = &settings->freq_params;
++	int center = settings->freq_params.center_freq1;
++	int background_center = 5000 + iface->radar_background.centr_freq_seg0_idx * 5;
++	int n_chans = settings->freq_params.bandwidth / 20;
++	bool update_background = false;
++
++	if (!dfs_use_radar_background(iface)) {
++		settings->cs_count = 5;
++		settings->block_tx = cac_required;
++		return 0;
++	}
++
++	if (!cac_required) {
++		if (!bw_changed && center != background_center)
++			return 0;
++		/* Update background radar due to bw change or channel overlapping */
++		update_background = true;
++	} else {
++		/*
++		* Get available channel for main channel.
++		* If no available channel for main channel, then perform
++		* the CAC of target channel on the main channel, and select
++		* an usable channel for background radar.
++		*/
++		iface->radar_background.temp_ch = 1;
++		chan = dfs_get_csa_channel(iface, n_chans, 0, DFS_AVAILABLE);
++		if (!chan)
++			update_background = true;
++	}
++
++	if (update_background) {
++		chan = dfs_get_csa_channel(iface, n_chans, center, DFS_NO_CAC_YET);
++		if (!chan)
++			goto bkg_disable;
++		freq_params = &background_settings->freq_params;
++		iface->radar_background.temp_ch = 0;
++	}
++
++	memcpy(background_settings, settings, sizeof(*settings));
++	freq_params->freq = chan->freq;
++	freq_params->channel = chan->chan;
++	freq_params->sec_channel_offset = 1;
++	freq_params->center_freq1 = chan->freq + (n_chans - 1) * 10;
++	freq_params->center_freq2 = 0;
++
++	return 1;
++
++bkg_disable:
++	iface->radar_background.channel = -1;
++	return 0;
+ }
+diff --git a/src/ap/dfs.h b/src/ap/dfs.h
+index 1a0791f..0a7c25d 100644
+--- a/src/ap/dfs.h
++++ b/src/ap/dfs.h
+@@ -33,7 +33,12 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+ 			  int ht_enabled, int chan_offset, int chan_width,
+ 			  int cf1, int cf2);
+ int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
+-int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+-			   int center_freq);
++int hostapd_dfs_get_target_state(struct hostapd_iface *iface, enum chan_width width,
++				 int center_freq, int center_freq2);
++int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
++			   struct csa_settings *settings,
++			   struct csa_settings *background_settings,
++			   bool cac_required, bool bw_changed);
++
+ 
+ #endif /* DFS_H */
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
similarity index 80%
rename from recipes-wifi/wpa-supplicant/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
rename to recipes-wifi/wpa-supplicant/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
index 69f3fa2..bfd66a3 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
@@ -1,7 +1,7 @@
-From b087dbc78f6911b16c9c00ac0a9246a89871225f Mon Sep 17 00:00:00 2001
+From 49f5a5c4430e59dec7dc135773636da2e889ce05 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 20 Feb 2023 14:56:55 +0800
-Subject: [PATCH 11/35] hostapd: mtk: Add DFS offchan channel switch
+Subject: [PATCH 49/49] hostapd: mtk: Add DFS offchan channel switch
 
 Add DFS background chain channel switch command for testing purpose.
 This feature is implemented via hostapd_cli command.
@@ -12,17 +12,17 @@
 ---
  hostapd/ctrl_iface.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
  src/ap/dfs.c         | 25 ++++++---------
- src/ap/dfs.h         | 15 +++++++++
- 3 files changed, 96 insertions(+), 16 deletions(-)
+ src/ap/dfs.h         | 16 +++++++++-
+ 3 files changed, 96 insertions(+), 17 deletions(-)
 
 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index fcbc4ae..37a1b2a 100644
+index 328f7c2..97d807a 100644
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -3542,6 +3542,76 @@ hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
+@@ -3951,6 +3951,76 @@ hostapd_ctrl_iface_dump_amnt(struct hostapd_data *hapd, char *cmd,
+ 		return pos - buf;
  }
  
- 
 +static int
 +hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
 +				    char *buf, size_t buflen)
@@ -48,9 +48,9 @@
 +	else
 +		return -1;
 +
-+	num_available_chandefs = dfs_find_channel(iface, NULL, 0, type);
++	num_available_chandefs = dfs_find_channel(iface, NULL, 0, 0, type);
 +	for (i = 0; i < num_available_chandefs; i++) {
-+		dfs_find_channel(iface, &chan, i, type);
++		dfs_find_channel(iface, &chan, 0, i, type);
 +		if (chan->chan == channel) {
 +			chan_found = true;
 +			break;
@@ -96,17 +96,17 @@
  static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
  					      char *buf, char *reply,
  					      int reply_size,
-@@ -4104,6 +4174,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
- 	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
- 		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
- 								   reply, reply_size);
+@@ -4529,6 +4599,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
+ 		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
+ 							reply, reply_size);
 +	} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
 +		reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
  	} else {
  		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  		reply_len = 16;
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 5cb7799..1c3f678 100644
+index a558d4e..bb5702b 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -19,13 +19,6 @@
@@ -123,20 +123,20 @@
  static struct hostapd_channel_data *
  dfs_downgrade_bandwidth(struct hostapd_iface *iface, int *secondary_channel,
  			u8 *oper_centr_freq_seg0_idx,
-@@ -238,9 +231,9 @@ static int is_in_chanlist(struct hostapd_iface *iface,
+@@ -246,9 +239,9 @@ static int is_in_chanlist(struct hostapd_iface *iface,
   *  - hapd->vht/he_oper_centr_freq_seg0_idx
   *  - hapd->vht/he_oper_centr_freq_seg1_idx
   */
 -static int dfs_find_channel(struct hostapd_iface *iface,
 -			    struct hostapd_channel_data **ret_chan,
--			    int idx, enum dfs_channel_type type)
+-			    int n_chans, int idx, enum dfs_channel_type type)
 +int dfs_find_channel(struct hostapd_iface *iface,
 +		     struct hostapd_channel_data **ret_chan,
-+		     int idx, enum dfs_channel_type type)
++		     int n_chans, int idx, enum dfs_channel_type type)
  {
  	struct hostapd_hw_modes *mode;
  	struct hostapd_channel_data *chan;
-@@ -299,12 +292,12 @@ static int dfs_find_channel(struct hostapd_iface *iface,
+@@ -308,12 +301,12 @@ static int dfs_find_channel(struct hostapd_iface *iface,
  }
  
  
@@ -156,7 +156,7 @@
  	if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax)
  		return;
 diff --git a/src/ap/dfs.h b/src/ap/dfs.h
-index 606c1b3..c2556d2 100644
+index 0a7c25d..e88ea24 100644
 --- a/src/ap/dfs.h
 +++ b/src/ap/dfs.h
 @@ -9,6 +9,12 @@
@@ -172,13 +172,14 @@
  int hostapd_handle_dfs(struct hostapd_iface *iface);
  
  int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
-@@ -32,5 +38,14 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
- int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
- int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
- 			   int center_freq);
+@@ -39,6 +45,14 @@ int hostapd_dfs_handle_csa(struct hostapd_iface *iface,
+ 			   struct csa_settings *settings,
+ 			   struct csa_settings *background_settings,
+ 			   bool cac_required, bool bw_changed);
+-
 +int dfs_find_channel(struct hostapd_iface *iface,
 +		     struct hostapd_channel_data **ret_chan,
-+		     int idx, enum dfs_channel_type type);
++		     int n_chans, int idx, enum dfs_channel_type type);
 +void dfs_adjust_center_freq(struct hostapd_iface *iface,
 +			    struct hostapd_channel_data *chan,
 +			    int secondary_channel,
diff --git a/recipes-wifi/wpa-supplicant/files/patches/patches.inc b/recipes-wifi/wpa-supplicant/files/patches/patches.inc
index 9121a2f..0a397fe 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/patches.inc
+++ b/recipes-wifi/wpa-supplicant/files/patches/patches.inc
@@ -62,6 +62,10 @@
     file://800-acs-don-t-select-indoor-channel-on-outdoor-operation.patch \
     file://990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch \
     file://992-openssl-include-rsa.patch \
+    file://bp-0001-ACS-Extract-bw40-80-160-freqs-out-of-acs_usable_bwXX.patch \
+    file://bp-0002-ACS-Introduce-acs_get_bw_center_chan.patch \
+    file://bp-0003-ACS-introduce-acs_adjust_secondary.patch \
+    file://bp-0004-ACS-Allow-selecting-a-better-channel-when-using-40-8.patch \
     file://mtk-0001-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch \
     file://mtk-0002-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch \
     file://mtk-0003-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch \
@@ -72,7 +76,6 @@
     file://mtk-0008-hostapd-mtk-Add-hostapd-iBF-control.patch \
     file://mtk-0009-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch \
     file://mtk-0010-hostapd-mtk-Add-DFS-detection-mode.patch \
-    file://mtk-0011-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
     file://mtk-0012-hostapd-mtk-Add-amsdu-set-get-ctrl.patch \
     file://mtk-0013-hostapd-mtk-Add-he_ldpc-configuration.patch \
     file://mtk-0014-hostapd-mtk-Add-the-broadcast-destination-address-of.patch \
@@ -107,4 +110,9 @@
     file://mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch \
     file://mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch \
     file://mtk-0045-hostapd-mtk-add-log-in-extender-mode.patch \
+    file://mtk-0046-hostapd-mtk-ACS-Fix-2.4GHz-HT40-case-and-channel-swi.patch \
+    file://mtk-0047-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF_new.patch \
+    file://mtk-0047-hostapd-mtk-add-support-for-channel-switching-to-dfs.patch \
+    file://mtk-0048-hostapd-mtk-add-support-for-channel-switching-with-c.patch \
+    file://mtk-0049-hostapd-mtk-Add-DFS-offchan-channel-switch.patch \
     "
diff --git a/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/ap/ucode.c b/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/ap/ucode.c
index af97091..16d1b51 100644
--- a/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/ap/ucode.c
+++ b/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/ap/ucode.c
@@ -711,6 +711,7 @@
 		{ "freq_info", uc_wpa_freq_info },
 		{ "add_iface", uc_hostapd_add_iface },
 		{ "remove_iface", uc_hostapd_remove_iface },
+		{ "udebug_set", uc_wpa_udebug_set },
 	};
 	static const uc_function_list_t bss_fns[] = {
 		{ "ctrl", uc_hostapd_bss_ctrl },
diff --git a/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/utils/ucode.c b/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/utils/ucode.c
index 2beeb9a..29c753c 100644
--- a/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/utils/ucode.c
+++ b/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/utils/ucode.c
@@ -4,12 +4,71 @@
 #include "crypto/crypto.h"
 #include "crypto/sha1.h"
 #include "common/ieee802_11_common.h"
+#include <linux/netlink.h>
+#include <linux/genetlink.h>
+#include <linux/nl80211.h>
 #include <libubox/uloop.h>
 #include <ucode/compiler.h>
+#include <udebug.h>
 
 static uc_value_t *registry;
 static uc_vm_t vm;
 static struct uloop_timeout gc_timer;
+static struct udebug ud;
+static struct udebug_buf ud_log, ud_nl[3];
+static const struct udebug_buf_meta meta_log = {
+	.name = "wpa_log",
+	.format = UDEBUG_FORMAT_STRING,
+};
+static const struct udebug_buf_meta meta_nl_ll = {
+	.name = "wpa_nl_ctrl",
+	.format = UDEBUG_FORMAT_PACKET,
+	.sub_format = UDEBUG_DLT_NETLINK,
+};
+static const struct udebug_buf_meta meta_nl_tx = {
+	.name = "wpa_nl_tx",
+	.format = UDEBUG_FORMAT_PACKET,
+	.sub_format = UDEBUG_DLT_NETLINK,
+};
+#define UDEBUG_FLAG_RX_FRAME	(1ULL << 0)
+static const struct udebug_buf_flag rx_flags[] = {
+	{  "rx_frame", UDEBUG_FLAG_RX_FRAME },
+};
+static const struct udebug_buf_meta meta_nl_rx = {
+	.name = "wpa_nl_rx",
+	.format = UDEBUG_FORMAT_PACKET,
+	.sub_format = UDEBUG_DLT_NETLINK,
+	.flags = rx_flags,
+	.n_flags = ARRAY_SIZE(rx_flags),
+};
+static struct udebug_ubus_ring udebug_rings[] = {
+	{
+		.buf = &ud_log,
+		.meta = &meta_log,
+		.default_entries = 1024,
+		.default_size = 64 * 1024
+	},
+	{
+		.buf = &ud_nl[0],
+		.meta = &meta_nl_rx,
+		.default_entries = 1024,
+		.default_size = 256 * 1024,
+	},
+	{
+		.buf = &ud_nl[1],
+		.meta = &meta_nl_tx,
+		.default_entries = 1024,
+		.default_size = 64 * 1024,
+	},
+	{
+		.buf = &ud_nl[2],
+		.meta = &meta_nl_ll,
+		.default_entries = 1024,
+		.default_size = 32 * 1024,
+	}
+};
+char *udebug_service;
+struct udebug_ubus ud_ubus;
 
 static void uc_gc_timer(struct uloop_timeout *timeout)
 {
@@ -251,6 +310,114 @@
 	return 0;
 }
 
+static void udebug_printf_hook(int level, const char *fmt, va_list ap)
+{
+	udebug_entry_init(&ud_log);
+	udebug_entry_vprintf(&ud_log, fmt, ap);
+	udebug_entry_add(&ud_log);
+}
+
+static void udebug_hexdump_hook(int level, const char *title,
+                const void *data, size_t len)
+{
+	char *buf;
+
+	udebug_entry_init(&ud_log);
+	udebug_entry_printf(&ud_log, "%s - hexdump:", title);
+	buf = udebug_entry_append(&ud_log, NULL, 3 * len);
+	for (size_t i = 0; i < len; i++)
+		buf += sprintf(buf, " %02x", *(uint8_t *)(data + i));
+	udebug_entry_add(&ud_log);
+}
+
+static void udebug_netlink_hook(int tx, const void *data, size_t len)
+{
+	struct {
+		uint16_t pkttype;
+		uint16_t arphdr;
+		uint16_t _pad[5];
+		uint16_t proto;
+	} hdr = {
+		.pkttype = host_to_be16(tx ? 7 : 6),
+		.arphdr = host_to_be16(824),
+		.proto = host_to_be16(16),
+	};
+	const struct nlmsghdr *nlh = data;
+	const struct genlmsghdr *gnlh = data + NLMSG_HDRLEN;
+	struct udebug_buf *buf = &ud_nl[!!tx];
+
+	if (nlh->nlmsg_type == 0x10)
+		buf = &ud_nl[2];
+	else if (!tx && gnlh->cmd == NL80211_CMD_FRAME &&
+	         !(udebug_buf_flags(buf) & UDEBUG_FLAG_RX_FRAME))
+		return;
+
+	if (!udebug_buf_valid(buf))
+		return;
+
+	udebug_entry_init(buf);
+	udebug_entry_append(buf, &hdr, sizeof(hdr));
+	udebug_entry_append(buf, data, len);
+	udebug_entry_add(buf);
+}
+
+static void
+wpa_udebug_config(struct udebug_ubus *ctx, struct blob_attr *data,
+		  bool enabled)
+{
+	udebug_ubus_apply_config(&ud, udebug_rings, ARRAY_SIZE(udebug_rings),
+				 data, enabled);
+
+	if (udebug_buf_valid(&ud_log)) {
+		wpa_printf_hook = udebug_printf_hook;
+		wpa_hexdump_hook = udebug_hexdump_hook;
+	} else {
+		wpa_printf_hook = NULL;
+		wpa_hexdump_hook = NULL;
+	}
+
+	if (udebug_buf_valid(&ud_nl[0]) ||
+	    udebug_buf_valid(&ud_nl[1]) ||
+	    udebug_buf_valid(&ud_nl[2]))
+		wpa_netlink_hook = udebug_netlink_hook;
+	else
+		wpa_netlink_hook = NULL;
+}
+
+uc_value_t *uc_wpa_udebug_set(uc_vm_t *vm, size_t nargs)
+{
+	uc_value_t *name = uc_fn_arg(0);
+	uc_value_t *ubus = uc_fn_arg(1);
+	static bool enabled = false;
+	struct ubus_context *ctx;
+	bool cur_en;
+
+	cur_en = ucv_type(name) == UC_STRING;
+	ctx = ucv_resource_data(ubus, "ubus.connection");
+	if (!ctx)
+		cur_en = false;
+
+	if (enabled == cur_en)
+		return ucv_boolean_new(true);
+
+	enabled = cur_en;
+	if (enabled) {
+		udebug_service = strdup(ucv_string_get(name));
+		udebug_init(&ud);
+		udebug_auto_connect(&ud, NULL);
+		udebug_ubus_init(&ud_ubus, ctx, udebug_service, wpa_udebug_config);
+	} else {
+		udebug_ubus_free(&ud_ubus);
+		for (size_t i = 0; i < ARRAY_SIZE(udebug_rings); i++)
+			if (udebug_buf_valid(udebug_rings[i].buf))
+				udebug_buf_free(udebug_rings[i].buf);
+		udebug_free(&ud);
+		free(udebug_service);
+	}
+
+	return ucv_boolean_new(true);
+}
+
 uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type)
 {
 	uc_value_t *global = uc_resource_new(global_type, NULL);
diff --git a/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/utils/ucode.h b/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/utils/ucode.h
index 2c18869..c083241 100644
--- a/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/utils/ucode.h
+++ b/recipes-wifi/wpa-supplicant/files/src-2.10.3/src/utils/ucode.h
@@ -21,6 +21,7 @@
 uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx);
 uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx);
 
+uc_value_t *uc_wpa_udebug_set(uc_vm_t *vm, size_t nargs);
 uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs);
 uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs);
 uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs);
diff --git a/recipes-wifi/wpa-supplicant/files/src-2.10.3/wpa_supplicant/ucode.c b/recipes-wifi/wpa-supplicant/files/src-2.10.3/wpa_supplicant/ucode.c
index 6cba73d..397f85b 100644
--- a/recipes-wifi/wpa-supplicant/files/src-2.10.3/wpa_supplicant/ucode.c
+++ b/recipes-wifi/wpa-supplicant/files/src-2.10.3/wpa_supplicant/ucode.c
@@ -262,6 +262,7 @@
 		{ "getpid", uc_wpa_getpid },
 		{ "add_iface", uc_wpas_add_iface },
 		{ "remove_iface", uc_wpas_remove_iface },
+		{ "udebug_set", uc_wpa_udebug_set },
 	};
 	static const uc_function_list_t iface_fns[] = {
 		{ "status", uc_wpas_iface_status },
diff --git a/recipes-wifi/wpa-supplicant/wpa-supplicant_2.10.3.bb b/recipes-wifi/wpa-supplicant/wpa-supplicant_2.10.3.bb
index e23b9c3..db56247 100644
--- a/recipes-wifi/wpa-supplicant/wpa-supplicant_2.10.3.bb
+++ b/recipes-wifi/wpa-supplicant/wpa-supplicant_2.10.3.bb
@@ -6,7 +6,7 @@
 LICENSE = "BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://hostapd/README;md5=c905478466c90f1cefc0df987c40e172"
 
-DEPENDS = "dbus libnl-tiny ubus ucode"
+DEPENDS = "dbus libnl-tiny ubus ucode udebug"
 FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
 FILESEXTRAPATHS_prepend := "${THISDIR}/files/patches-${PV}:"