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

[Description]
cc3c51c7 [MAC80211][wifi6][Release][Update MT7986 Firmware]
ea393925 [MAC80211[WiFi6/7]][hostapd][Avoid unnecessary beacon update]
6763be22 [MAC80211][wifi7][Misc][Sync Internal patches to External Release Folder]
d3ed9bc8 [mac80211][wifi7][mt76][Rebase WED patch due to Cheetah MT76 modifications]
2f4b03c3 [mac80211][wifi6][mt76][Bring-up hardware path for Cheetah MT76]
cb573d78 [MAC80211][WiFi7][app][Add ibf atenl support for eagle]
04fe6893 [mac80211][wifi6][mt76][Fix rebase errors]
c301e69a [MAC80211][WiFi7][mt76][Update Kite EEPROM bin files]
463b00fb [MAC80211][WiFi7][infra][Add slot1 for kite]
8774388d [MAC80211][WiFi7][misc][Prevent deadlock in a multiple AP+STA mode]
68d43fea [MAC80211][hostapd][show acs channels config]
5aca83c6 [MAC80211][hostapd][Prevent hostapd from setting beacon too frequently]
636da369 [MAC80211][wifi6/7][misc][use current epoch date]
9eb3456f [MAC80211][hostapd][refactor AP/STA CSA handling flow]
5543f3d8 [MAC80211][WiFi6][mt76][Refactor assignment of STA BSS group]
c5631fc2 [mac80211][mt76][wifi6][Add debugfs knob for RTS threshold]
6a92a2d4 [mac80211][wifi6][mt76][Bring-up software path for Cheetah MT76]
bf66c519 [MAC80211][netifd][Remove unnecessary netifd patch]
2f141c75 [mac80211][mt76][wifi6/7][Fix build failed]
cf30db1e [mac80211[hostapd][wifi7][Fix build fial]
dc391fc0 [MAC80211][wifi6][Release][Update MT7986 Firmware]
71a7b95a [MAC80211][WiFi7][mt76][Add kite fw & eeprom to eagle codebase]
5a7bd025 [MAC80211][WiFi6][misc][Add mt7981 default eeprom bin]
e40da697 [MAC80211][WED][Fix reinsert wifi module cause memory leak issue]
0a22f8f4 [MAC80211][WiFi7][misc][fix mt7988-mt7996-mac980211 release build fail]
25f3fe1c [[Eagle][SQC3.0][BE19000][MT7996][E2][MT7976_MT7977][256][ePA][MT7988A][WiFi] [MAP][SnS][Muti-client][UES]Traffic stuck in Agent2 with invalid tid 8 found]
f59b5dad [MAC80211][WiFi6][mt76][Add additional chain signal info in station dump for merlin]
fada400d [MAC80211][WiFi6/7][mt76][Add HT40- capab when enable ACS]
98e273af [MAC80211][WiFi6/7][app][Add SKU_EN & RSSI ATTR in atenl]
aaa8eb14 [MAC80211][WiFi6][mt76][Add rssi & sku_en in testmode]
eda14aac [MAC80211][core][Remove wrong assignment on the variable "changed" when changing beacon]
000329aa [MAC80211][netifd][Move netifd patch for wifi7 used only]
57bfe0c7 [MAC80211][WiFi6][misc][fix build fail due to mt76 upgration]
fa29bb39 [MAC80211][wifi6/7][mt76][update mt76 Makefile]
56f497ec [MAC80211][netifd][not to cache previous config to avoid wifi down failure]
be9abd4d [MAC80211][WiFi6][misc][fix build fail due to netifd]
af71e303 [MAC80211][WiFi6][mt76][Fix inconsistent BSS group setting of STA for VoW]
3e42972a [MAC80211][WiFi6][mt76][Fix txpower bbp CR]
81a68c03 [MAC80211][wifi7][hostapd][rebase internal hostapd patches]
336300b7 [MAC80211][WiFi6/7][hostapd][MAX 48 mbss 6G 连线概率连不上 ]
6bebc554 [MAC80211][wifi7][core][update for backports v6.5]
19daecfd [MAC80211][wifi7][ucode][Bandwidth Synchronization in AP/STA Mode]
ddf64afb [MAC80211][mt76][add debug log in SER flow]
44611a77 [mac80211][wifi6][mt76][Enhance debug log]

[Release-log]

Change-Id: Ibf5e835de5563fff4101a77e81056f696286670b
diff --git a/recipes-wifi/atenl/files/src/nl.c b/recipes-wifi/atenl/files/src/nl.c
index e0ad020..56c68f1 100644
--- a/recipes-wifi/atenl/files/src/nl.c
+++ b/recipes-wifi/atenl/files/src/nl.c
@@ -27,6 +27,7 @@
 	[MT76_TM_ATTR_MTD_PART] = { .type = NLA_STRING },
 	[MT76_TM_ATTR_MTD_OFFSET] = { .type = NLA_U32 },
 	[MT76_TM_ATTR_BAND_IDX] = { .type = NLA_U8 },
+	[MT76_TM_ATTR_SKU_EN] = { .type = NLA_U8 },
 	[MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 },
 	[MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 },
 	[MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 },
@@ -55,6 +56,7 @@
 static struct nla_policy rx_policy[NUM_MT76_TM_RX_ATTRS] = {
 	[MT76_TM_RX_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
 	[MT76_TM_RX_ATTR_RCPI] = { .type = NLA_NESTED },
+	[MT76_TM_RX_ATTR_RSSI] = { .type = NLA_NESTED },
 	[MT76_TM_RX_ATTR_IB_RSSI] = { .type = NLA_NESTED },
 	[MT76_TM_RX_ATTR_WB_RSSI] = { .type = NLA_NESTED },
 	[MT76_TM_RX_ATTR_SNR] = { .type = NLA_U8 },
@@ -829,15 +831,20 @@
 void
 atenl_get_ibf_cal_result(struct atenl *an)
 {
-	u16 offset;
+	u16 offset, group_size = 40;
 
 	if (an->adie_id == 0x7975)
 		offset = 0x651;
 	else if (an->adie_id == 0x7976)
 		offset = 0x60a;
 
-	/* per group size = 40, for group 0-8 */
-	atenl_eeprom_read_from_driver(an, offset, 40 * 9);
+	if (is_mt7996(an)) {
+		offset = 0xc00;
+		group_size = 46;
+	}
+
+	/* per group size = 40 or 46, for group 0-8 */
+	atenl_eeprom_read_from_driver(an, offset, group_size * 9);
 }
 
 static int
@@ -895,9 +902,11 @@
 		 * so maintain a temp variable to allow mcs update in anthor action.
 		 */
 		an->ibf_mcs = val[0];
-		an->ibf_ant = tmp_ant;
 		nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_IDX, an->ibf_mcs);
-		nla_put_u8(msg, MT76_TM_ATTR_TX_ANTENNA, an->ibf_ant);
+		if (!is_mt7996(an)) {
+			an->ibf_ant = tmp_ant;
+			nla_put_u8(msg, MT76_TM_ATTR_TX_ANTENNA, an->ibf_ant);
+		}
 		break;
 	case TXBF_ACT_TX_ANT:
 		nla_put_u8(msg, MT76_TM_ATTR_TX_ANTENNA, val[0]);
@@ -935,9 +944,11 @@
 		a = nla_nest_start(msg, MT76_TM_ATTR_TXBF_PARAM);
 		if (!a)
 			return -ENOMEM;
-		/* Note: litepoint may send random number for lna_gain_level, reset to 0 */
+		/* Note: litepoint may send random number for lna_gain_level,
+		 * reset to 1 (mid gain) and 0 for wifi 7 and wifi 6, respectively
+		 */
 		if (action == TXBF_ACT_IBF_PHASE_CAL)
-			val[4] = 0;
+			val[4] = is_mt7996(an) ? 1 : 0;
 		for (i = 0; i < 5; i++)
 			nla_put_u16(msg, i, val[i]);
 		/* Used to distinguish between command mode and HQADLL mode */
diff --git a/recipes-wifi/atenl/files/src/nl.h b/recipes-wifi/atenl/files/src/nl.h
index bfd8fb8..7d9b20d 100644
--- a/recipes-wifi/atenl/files/src/nl.h
+++ b/recipes-wifi/atenl/files/src/nl.h
@@ -16,6 +16,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)
  *
+ * @MT76_TM_ATTR_SKU_EN: config txpower sku is enabled or disabled in testmode (u8)
  * @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)
@@ -88,6 +89,7 @@
 	MT76_TM_ATTR_MTD_OFFSET,
 	MT76_TM_ATTR_BAND_IDX,
 
+	MT76_TM_ATTR_SKU_EN,
 	MT76_TM_ATTR_TX_COUNT,
 	MT76_TM_ATTR_TX_LENGTH,
 	MT76_TM_ATTR_TX_RATE_MODE,
@@ -179,6 +181,7 @@
  *
  * @MT76_TM_RX_ATTR_FREQ_OFFSET: frequency offset (s32)
  * @MT76_TM_RX_ATTR_RCPI: received channel power indicator (array, u8)
+ * @MT76_TM_RX_ATTR_RSSI: received signal strength indicator (array, s8)
  * @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)
@@ -188,6 +191,7 @@
 
 	MT76_TM_RX_ATTR_FREQ_OFFSET,
 	MT76_TM_RX_ATTR_RCPI,
+	MT76_TM_RX_ATTR_RSSI,
 	MT76_TM_RX_ATTR_IB_RSSI,
 	MT76_TM_RX_ATTR_WB_RSSI,
 	MT76_TM_RX_ATTR_SNR,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/011-mesh-use-deterministic-channel-on-channel-switch.patch b/recipes-wifi/hostapd/files/patches-2.10.3/011-mesh-use-deterministic-channel-on-channel-switch.patch
index 9b11f0e..07b7a59 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/011-mesh-use-deterministic-channel-on-channel-switch.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/011-mesh-use-deterministic-channel-on-channel-switch.patch
@@ -29,7 +29,7 @@
  
  
  enum dfs_channel_type {
-@@ -521,9 +522,14 @@ dfs_get_valid_channel(struct hostapd_ifa
+@@ -526,9 +527,14 @@ dfs_get_valid_channel(struct hostapd_ifa
  	int num_available_chandefs;
  	int chan_idx, chan_idx2;
  	int sec_chan_idx_80p80 = -1;
@@ -44,7 +44,7 @@
  	wpa_printf(MSG_DEBUG, "DFS: Selecting random channel");
  	*secondary_channel = 0;
  	*oper_centr_freq_seg0_idx = 0;
-@@ -543,8 +549,20 @@ dfs_get_valid_channel(struct hostapd_ifa
+@@ -548,8 +554,20 @@ dfs_get_valid_channel(struct hostapd_ifa
  	if (num_available_chandefs == 0)
  		return NULL;
  
@@ -68,7 +68,7 @@
  	if (!chan) {
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -10977,6 +10977,10 @@ static int nl80211_switch_channel(void *
+@@ -11017,6 +11017,10 @@ static int nl80211_switch_channel(void *
  	if (ret)
  		goto error;
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/021-fix-sta-add-after-previous-connection.patch b/recipes-wifi/hostapd/files/patches-2.10.3/021-fix-sta-add-after-previous-connection.patch
index 4ee43b5..edf599e 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/021-fix-sta-add-after-previous-connection.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/021-fix-sta-add-after-previous-connection.patch
@@ -1,6 +1,6 @@
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -4601,6 +4601,13 @@ static int add_associated_sta(struct hos
+@@ -4621,6 +4621,13 @@ static int add_associated_sta(struct hos
  	 * drivers to accept the STA parameter configuration. Since this is
  	 * after a new FT-over-DS exchange, a new TK has been derived, so key
  	 * reinstallation is not a concern for this case.
@@ -14,7 +14,7 @@
  	 */
  	wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR
  		   " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
-@@ -4614,7 +4621,8 @@ static int add_associated_sta(struct hos
+@@ -4634,7 +4641,8 @@ static int add_associated_sta(struct hos
  	    (!(sta->flags & WLAN_STA_AUTHORIZED) ||
  	     (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) ||
  	     (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) &&
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch b/recipes-wifi/hostapd/files/patches-2.10.3/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch
index 19248e8..ef2bb40 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch
@@ -92,7 +92,7 @@
  
  	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
  		wpa_printf(MSG_DEBUG,
-@@ -11843,13 +11840,14 @@ static int wpa_driver_br_add_ip_neigh(vo
+@@ -11883,13 +11880,14 @@ static int wpa_driver_br_add_ip_neigh(vo
  				      const u8 *ipaddr, int prefixlen,
  				      const u8 *addr)
  {
@@ -112,7 +112,7 @@
  	int res;
  
  	if (!ipaddr || prefixlen == 0 || !addr)
-@@ -11868,85 +11866,66 @@ static int wpa_driver_br_add_ip_neigh(vo
+@@ -11908,85 +11906,66 @@ static int wpa_driver_br_add_ip_neigh(vo
  	}
  
  	if (version == 4) {
@@ -220,7 +220,7 @@
  		addrsize = 16;
  	} else {
  		return -EINVAL;
-@@ -11964,41 +11943,30 @@ static int wpa_driver_br_delete_ip_neigh
+@@ -12004,41 +11983,30 @@ static int wpa_driver_br_delete_ip_neigh
  		return -1;
  	}
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/040-mesh-allow-processing-authentication-frames-in-block.patch b/recipes-wifi/hostapd/files/patches-2.10.3/040-mesh-allow-processing-authentication-frames-in-block.patch
index f98d380..b7bf9e3 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/040-mesh-allow-processing-authentication-frames-in-block.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/040-mesh-allow-processing-authentication-frames-in-block.patch
@@ -16,7 +16,7 @@
 
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -3012,15 +3012,6 @@ static void handle_auth(struct hostapd_d
+@@ -3020,15 +3020,6 @@ static void handle_auth(struct hostapd_d
  				       seq_ctrl);
  			return;
  		}
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch b/recipes-wifi/hostapd/files/patches-2.10.3/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch
index 148c268..e967cff 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch
@@ -903,7 +903,7 @@
      for exp, flags in tests:
          hapd.disable()
          hapd.set("tls_flags", flags)
-@@ -7115,6 +7173,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde
+@@ -7138,6 +7196,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde
  def test_eap_tls_ext_cert_check(dev, apdev):
      """EAP-TLS and external server certification validation"""
      # With internal server certificate chain validation
@@ -911,7 +911,7 @@
      id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS",
                          identity="tls user",
                          ca_cert="auth_serv/ca.pem",
-@@ -7127,6 +7186,7 @@ def test_eap_tls_ext_cert_check(dev, apd
+@@ -7150,6 +7209,7 @@ def test_eap_tls_ext_cert_check(dev, apd
  def test_eap_ttls_ext_cert_check(dev, apdev):
      """EAP-TTLS and external server certification validation"""
      # Without internal server certificate chain validation
@@ -919,7 +919,7 @@
      id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
                          identity="pap user", anonymous_identity="ttls",
                          password="password", phase2="auth=PAP",
-@@ -7137,6 +7197,7 @@ def test_eap_ttls_ext_cert_check(dev, ap
+@@ -7160,6 +7220,7 @@ def test_eap_ttls_ext_cert_check(dev, ap
  def test_eap_peap_ext_cert_check(dev, apdev):
      """EAP-PEAP and external server certification validation"""
      # With internal server certificate chain validation
@@ -927,7 +927,7 @@
      id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP",
                          identity="user", anonymous_identity="peap",
                          ca_cert="auth_serv/ca.pem",
-@@ -7147,6 +7208,7 @@ def test_eap_peap_ext_cert_check(dev, ap
+@@ -7170,6 +7231,7 @@ def test_eap_peap_ext_cert_check(dev, ap
  
  def test_eap_fast_ext_cert_check(dev, apdev):
      """EAP-FAST and external server certification validation"""
@@ -935,7 +935,7 @@
      check_eap_capa(dev[0], "FAST")
      # With internal server certificate chain validation
      dev[0].request("SET blob fast_pac_auth_ext ")
-@@ -7161,10 +7223,6 @@ def test_eap_fast_ext_cert_check(dev, ap
+@@ -7184,10 +7246,6 @@ def test_eap_fast_ext_cert_check(dev, ap
      run_ext_cert_check(dev, apdev, id)
  
  def run_ext_cert_check(dev, apdev, net_id):
@@ -948,7 +948,7 @@
  
 --- a/tests/hwsim/test_ap_ft.py
 +++ b/tests/hwsim/test_ap_ft.py
-@@ -2471,11 +2471,11 @@ def test_ap_ft_ap_oom5(dev, apdev):
+@@ -2474,11 +2474,11 @@ def test_ap_ft_ap_oom5(dev, apdev):
          # This will fail to roam
          dev[0].roam(bssid1, check_bssid=False)
  
@@ -1138,7 +1138,7 @@
      heavy_groups = [14, 15, 16]
      suitable_groups = [15, 16, 17, 18, 19, 20, 21]
      groups = [str(g) for g in sae_groups]
-@@ -2188,6 +2193,8 @@ def run_sae_pwe_group(dev, apdev, group)
+@@ -2193,6 +2198,8 @@ def run_sae_pwe_group(dev, apdev, group)
              logger.info("Add Brainpool EC groups since OpenSSL is new enough")
          elif tls.startswith("wolfSSL"):
              logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL")
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch b/recipes-wifi/hostapd/files/patches-2.10.3/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch
index 710a3c8..b0151b0 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch
@@ -120,7 +120,7 @@
  		 * Convert 80+80 MHz channel width to new style as interop
 --- a/src/common/hw_features_common.c
 +++ b/src/common/hw_features_common.c
-@@ -808,6 +808,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co
+@@ -811,6 +811,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co
  	VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB);
  	VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN);
  	VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN);
@@ -130,7 +130,7 @@
  #undef VHT_CAP_CHECK_MAX
 --- a/src/common/ieee802_11_defs.h
 +++ b/src/common/ieee802_11_defs.h
-@@ -1348,6 +1348,8 @@ struct ieee80211_ampe_ie {
+@@ -1349,6 +1349,8 @@ struct ieee80211_ampe_ie {
  #define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB     ((u32) BIT(26) | BIT(27))
  #define VHT_CAP_RX_ANTENNA_PATTERN                  ((u32) BIT(28))
  #define VHT_CAP_TX_ANTENNA_PATTERN                  ((u32) BIT(29))
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch b/recipes-wifi/hostapd/files/patches-2.10.3/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch
deleted file mode 100644
index 7b0435a..0000000
--- a/recipes-wifi/hostapd/files/patches-2.10.3/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 7 Aug 2023 21:55:57 +0200
-Subject: [PATCH] BSS coloring: fix CCA with multiple BSS
-
-Pass bss->ctx instead of drv->ctx in order to avoid multiple reports for
-the first bss. The first report would otherwise clear hapd->cca_color and
-subsequent reports would cause the iface bss color to be set to 0.
-In order to avoid any issues with cancellations, only overwrite the color
-based on hapd->cca_color if it was actually set.
-
-Fixes: 33c4dd26cd11 ("BSS coloring: Handle the collision and CCA events coming from the kernel")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/src/ap/drv_callbacks.c
-+++ b/src/ap/drv_callbacks.c
-@@ -2260,7 +2260,8 @@ void wpa_supplicant_event(void *ctx, enu
- 	case EVENT_CCA_NOTIFY:
- 		wpa_printf(MSG_DEBUG, "CCA finished on on %s",
- 			   hapd->conf->iface);
--		hapd->iface->conf->he_op.he_bss_color = hapd->cca_color;
-+		if (hapd->cca_color)
-+			hapd->iface->conf->he_op.he_bss_color = hapd->cca_color;
- 		hostapd_cleanup_cca_params(hapd);
- 		break;
- #endif /* CONFIG_IEEE80211AX */
---- a/src/drivers/driver_nl80211_event.c
-+++ b/src/drivers/driver_nl80211_event.c
-@@ -3653,7 +3653,7 @@ static void nl80211_assoc_comeback(struc
- 
- #ifdef CONFIG_IEEE80211AX
- 
--static void nl80211_obss_color_collision(struct wpa_driver_nl80211_data *drv,
-+static void nl80211_obss_color_collision(struct i802_bss *bss,
- 					 struct nlattr *tb[])
- {
- 	union wpa_event_data data;
-@@ -3667,37 +3667,37 @@ static void nl80211_obss_color_collision
- 
- 	wpa_printf(MSG_DEBUG, "nl80211: BSS color collision - bitmap %08llx",
- 		   (long long unsigned int) data.bss_color_collision.bitmap);
--	wpa_supplicant_event(drv->ctx, EVENT_BSS_COLOR_COLLISION, &data);
-+	wpa_supplicant_event(bss->ctx, EVENT_BSS_COLOR_COLLISION, &data);
- }
- 
- 
- static void
--nl80211_color_change_announcement_started(struct wpa_driver_nl80211_data *drv)
-+nl80211_color_change_announcement_started(struct i802_bss *bss)
- {
- 	union wpa_event_data data = {};
- 
- 	wpa_printf(MSG_DEBUG, "nl80211: CCA started");
--	wpa_supplicant_event(drv->ctx, EVENT_CCA_STARTED_NOTIFY, &data);
-+	wpa_supplicant_event(bss->ctx, EVENT_CCA_STARTED_NOTIFY, &data);
- }
- 
- 
- static void
--nl80211_color_change_announcement_aborted(struct wpa_driver_nl80211_data *drv)
-+nl80211_color_change_announcement_aborted(struct i802_bss *bss)
- {
- 	union wpa_event_data data = {};
- 
- 	wpa_printf(MSG_DEBUG, "nl80211: CCA aborted");
--	wpa_supplicant_event(drv->ctx, EVENT_CCA_ABORTED_NOTIFY, &data);
-+	wpa_supplicant_event(bss->ctx, EVENT_CCA_ABORTED_NOTIFY, &data);
- }
- 
- 
- static void
--nl80211_color_change_announcement_completed(struct wpa_driver_nl80211_data *drv)
-+nl80211_color_change_announcement_completed(struct i802_bss *bss)
- {
- 	union wpa_event_data data = {};
- 
- 	wpa_printf(MSG_DEBUG, "nl80211: CCA completed");
--	wpa_supplicant_event(drv->ctx, EVENT_CCA_NOTIFY, &data);
-+	wpa_supplicant_event(bss->ctx, EVENT_CCA_NOTIFY, &data);
- }
- 
- #endif /* CONFIG_IEEE80211AX */
-@@ -3957,16 +3957,16 @@ static void do_process_drv_event(struct
- 		break;
- #ifdef CONFIG_IEEE80211AX
- 	case NL80211_CMD_OBSS_COLOR_COLLISION:
--		nl80211_obss_color_collision(drv, tb);
-+		nl80211_obss_color_collision(bss, tb);
- 		break;
- 	case NL80211_CMD_COLOR_CHANGE_STARTED:
--		nl80211_color_change_announcement_started(drv);
-+		nl80211_color_change_announcement_started(bss);
- 		break;
- 	case NL80211_CMD_COLOR_CHANGE_ABORTED:
--		nl80211_color_change_announcement_aborted(drv);
-+		nl80211_color_change_announcement_aborted(bss);
- 		break;
- 	case NL80211_CMD_COLOR_CHANGE_COMPLETED:
--		nl80211_color_change_announcement_completed(drv);
-+		nl80211_color_change_announcement_completed(bss);
- 		break;
- #endif /* CONFIG_IEEE80211AX */
- 	default:
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch b/recipes-wifi/hostapd/files/patches-2.10.3/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch
new file mode 100644
index 0000000..4929c58
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch
@@ -0,0 +1,20 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 14 Sep 2023 10:53:50 +0200
+Subject: [PATCH] driver_nl80211: fix setting QoS map on secondary BSSs
+
+The setting is per-BSS, not per PHY
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -11341,7 +11341,7 @@ static int nl80211_set_qos_map(void *pri
+ 	wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
+ 		    qos_map_set, qos_map_set_len);
+ 
+-	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_QOS_MAP)) ||
++	if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_QOS_MAP)) ||
+ 	    nla_put(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set)) {
+ 		nlmsg_free(msg);
+ 		return -ENOBUFS;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch b/recipes-wifi/hostapd/files/patches-2.10.3/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch
new file mode 100644
index 0000000..adfb21f
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch
@@ -0,0 +1,18 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 14 Sep 2023 11:28:03 +0200
+Subject: [PATCH] driver_nl80211: update drv->ifindex on removing the first
+ BSS
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -8867,6 +8867,7 @@ static int wpa_driver_nl80211_if_remove(
+ 		if (drv->first_bss->next) {
+ 			drv->first_bss = drv->first_bss->next;
+ 			drv->ctx = drv->first_bss->ctx;
++			drv->ifindex = drv->first_bss->ifindex;
+ 			os_free(bss);
+ 		} else {
+ 			wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch b/recipes-wifi/hostapd/files/patches-2.10.3/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch
new file mode 100644
index 0000000..395c645
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch
@@ -0,0 +1,34 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 18 Sep 2023 16:47:41 +0200
+Subject: [PATCH] nl80211: move nl80211_put_freq_params call outside of
+ 802.11ax #ifdef
+
+The relevance of this call is not specific to 802.11ax, so it should be done
+even with CONFIG_IEEE80211AX disabled.
+
+Fixes: b3921db426ea ("nl80211: Add frequency info in start AP command")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -5226,6 +5226,9 @@ static int wpa_driver_nl80211_set_ap(voi
+ 		nla_nest_end(msg, ftm);
+ 	}
+ 
++	if (params->freq && nl80211_put_freq_params(msg, params->freq) < 0)
++		goto fail;
++
+ #ifdef CONFIG_IEEE80211AX
+ 	if (params->he_spr_ctrl) {
+ 		struct nlattr *spr;
+@@ -5260,9 +5263,6 @@ static int wpa_driver_nl80211_set_ap(voi
+ 		nla_nest_end(msg, spr);
+ 	}
+ 
+-	if (params->freq && nl80211_put_freq_params(msg, params->freq) < 0)
+-		goto fail;
+-
+ 	if (params->freq && params->freq->he_enabled) {
+ 		struct nlattr *bss_color;
+ 
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch b/recipes-wifi/hostapd/files/patches-2.10.3/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch
new file mode 100644
index 0000000..fe81318
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch
@@ -0,0 +1,28 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 20 Sep 2023 13:41:10 +0200
+Subject: [PATCH] hostapd: cancel channel_list_update_timeout in
+ hostapd_cleanup_iface_partial
+
+Fixes a crash when disabling an interface during channel list update
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -569,6 +569,7 @@ static void sta_track_deinit(struct host
+ void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
+ {
+ 	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
++	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
+ #ifdef NEED_AP_MLME
+ 	hostapd_stop_setup_timers(iface);
+ #endif /* NEED_AP_MLME */
+@@ -598,7 +599,6 @@ void hostapd_cleanup_iface_partial(struc
+ static void hostapd_cleanup_iface(struct hostapd_iface *iface)
+ {
+ 	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+-	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
+ 	eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
+ 			     NULL);
+ 
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/200-multicall.patch b/recipes-wifi/hostapd/files/patches-2.10.3/200-multicall.patch
index 8ebbed0..e3ed00f 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/200-multicall.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/200-multicall.patch
@@ -156,7 +156,7 @@
  wpa_cli.exe: wpa_cli
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -6651,8 +6651,8 @@ union wpa_event_data {
+@@ -6667,8 +6667,8 @@ union wpa_event_data {
   * Driver wrapper code should call this function whenever an event is received
   * from the driver.
   */
@@ -167,7 +167,7 @@
  
  /**
   * wpa_supplicant_event_global - Report a driver event for wpa_supplicant
-@@ -6664,7 +6664,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -6680,7 +6680,7 @@ void wpa_supplicant_event(void *ctx, enu
   * Same as wpa_supplicant_event(), but we search for the interface in
   * wpa_global.
   */
@@ -178,7 +178,7 @@
  /*
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -1994,8 +1994,8 @@ err:
+@@ -2184,8 +2184,8 @@ err:
  #endif /* CONFIG_OWE */
  
  
@@ -189,7 +189,7 @@
  {
  	struct hostapd_data *hapd = ctx;
  #ifndef CONFIG_NO_STDOUT_DEBUG
-@@ -2272,7 +2272,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -2489,7 +2489,7 @@ void wpa_supplicant_event(void *ctx, enu
  }
  
  
@@ -231,7 +231,7 @@
  	os_memset(&global, 0, sizeof(global));
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
-@@ -5345,8 +5345,8 @@ static void wpas_link_reconfig(struct wp
+@@ -5353,8 +5353,8 @@ static void wpas_link_reconfig(struct wp
  }
  
  
@@ -242,7 +242,7 @@
  {
  	struct wpa_supplicant *wpa_s = ctx;
  	int resched;
-@@ -6264,7 +6264,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -6272,7 +6272,7 @@ void wpa_supplicant_event(void *ctx, enu
  }
  
  
@@ -253,7 +253,7 @@
  	struct wpa_supplicant *wpa_s;
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -7435,7 +7435,6 @@ struct wpa_interface * wpa_supplicant_ma
+@@ -7462,7 +7462,6 @@ struct wpa_interface * wpa_supplicant_ma
  	return NULL;
  }
  
@@ -261,7 +261,7 @@
  /**
   * wpa_supplicant_match_existing - Match existing interfaces
   * @global: Pointer to global data from wpa_supplicant_init()
-@@ -7470,6 +7469,11 @@ static int wpa_supplicant_match_existing
+@@ -7497,6 +7496,11 @@ static int wpa_supplicant_match_existing
  
  #endif /* CONFIG_MATCH_IFACE */
  
@@ -273,7 +273,7 @@
  
  /**
   * wpa_supplicant_add_iface - Add a new network interface
-@@ -7726,6 +7730,8 @@ struct wpa_global * wpa_supplicant_init(
+@@ -7753,6 +7757,8 @@ struct wpa_global * wpa_supplicant_init(
  #ifndef CONFIG_NO_WPA_MSG
  	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
  #endif /* CONFIG_NO_WPA_MSG */
@@ -284,7 +284,7 @@
  		wpa_debug_open_file(params->wpa_debug_file_path);
 --- a/hostapd/main.c
 +++ b/hostapd/main.c
-@@ -685,6 +685,11 @@ fail:
+@@ -698,6 +698,11 @@ fail:
  	return -1;
  }
  
@@ -296,7 +296,7 @@
  
  #ifdef CONFIG_WPS
  static int gen_uuid(const char *txt_addr)
-@@ -778,6 +783,8 @@ int main(int argc, char *argv[])
+@@ -791,6 +796,8 @@ int main(int argc, char *argv[])
  		return -1;
  #endif /* CONFIG_DPP */
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/300-noscan.patch b/recipes-wifi/hostapd/files/patches-2.10.3/300-noscan.patch
index 1ea8904..3b5f432 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/300-noscan.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/300-noscan.patch
@@ -13,7 +13,7 @@
  	} else if (os_strcmp(buf, "ht_capab") == 0) {
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1072,6 +1072,8 @@ struct hostapd_config {
+@@ -1075,6 +1075,8 @@ struct hostapd_config {
  
  	int ht_op_mode_fixed;
  	u16 ht_capab;
@@ -24,7 +24,7 @@
  	int no_pri_sec_switch;
 --- a/src/ap/hw_features.c
 +++ b/src/ap/hw_features.c
-@@ -517,7 +517,8 @@ static int ieee80211n_check_40mhz(struct
+@@ -546,7 +546,8 @@ static int ieee80211n_check_40mhz(struct
  	int ret;
  
  	/* Check that HT40 is used and PRI / SEC switch is allowed */
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/310-rescan_immediately.patch b/recipes-wifi/hostapd/files/patches-2.10.3/310-rescan_immediately.patch
index a47546d..e12b205 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/310-rescan_immediately.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/310-rescan_immediately.patch
@@ -1,6 +1,6 @@
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -5740,7 +5740,7 @@ wpa_supplicant_alloc(struct wpa_supplica
+@@ -5767,7 +5767,7 @@ wpa_supplicant_alloc(struct wpa_supplica
  	if (wpa_s == NULL)
  		return NULL;
  	wpa_s->scan_req = INITIAL_SCAN_REQ;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/380-disable_ctrl_iface_mib.patch b/recipes-wifi/hostapd/files/patches-2.10.3/380-disable_ctrl_iface_mib.patch
index 54a736f..f7720fc 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/380-disable_ctrl_iface_mib.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/380-disable_ctrl_iface_mib.patch
@@ -51,7 +51,7 @@
  		if (wpa_s->ap_iface) {
  			pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
  							    end - pos,
-@@ -11964,6 +11964,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12087,6 +12087,7 @@ char * wpa_supplicant_ctrl_iface_process
  			reply_len = -1;
  	} else if (os_strncmp(buf, "NOTE ", 5) == 0) {
  		wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
@@ -59,7 +59,7 @@
  	} else if (os_strcmp(buf, "MIB") == 0) {
  		reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
  		if (reply_len >= 0) {
-@@ -11976,6 +11977,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12099,6 +12100,7 @@ char * wpa_supplicant_ctrl_iface_process
  				reply_size - reply_len);
  #endif /* CONFIG_MACSEC */
  		}
@@ -67,7 +67,7 @@
  	} else if (os_strncmp(buf, "STATUS", 6) == 0) {
  		reply_len = wpa_supplicant_ctrl_iface_status(
  			wpa_s, buf + 6, reply, reply_size);
-@@ -12464,6 +12466,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12587,6 +12589,7 @@ char * wpa_supplicant_ctrl_iface_process
  		reply_len = wpa_supplicant_ctrl_iface_bss(
  			wpa_s, buf + 4, reply, reply_size);
  #ifdef CONFIG_AP
@@ -75,7 +75,7 @@
  	} else if (os_strcmp(buf, "STA-FIRST") == 0) {
  		reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
  	} else if (os_strncmp(buf, "STA ", 4) == 0) {
-@@ -12472,12 +12475,15 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12595,12 +12598,15 @@ char * wpa_supplicant_ctrl_iface_process
  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
  		reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
  						   reply_size);
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/390-wpa_ie_cap_workaround.patch b/recipes-wifi/hostapd/files/patches-2.10.3/390-wpa_ie_cap_workaround.patch
index 40c39ff..4592c34 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/390-wpa_ie_cap_workaround.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/390-wpa_ie_cap_workaround.patch
@@ -1,6 +1,6 @@
 --- a/src/common/wpa_common.c
 +++ b/src/common/wpa_common.c
-@@ -2719,6 +2719,31 @@ u32 wpa_akm_to_suite(int akm)
+@@ -2841,6 +2841,31 @@ u32 wpa_akm_to_suite(int akm)
  }
  
  
@@ -32,7 +32,7 @@
  int wpa_compare_rsn_ie(int ft_initial_assoc,
  		       const u8 *ie1, size_t ie1len,
  		       const u8 *ie2, size_t ie2len)
-@@ -2726,8 +2751,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
+@@ -2848,8 +2873,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
  	if (ie1 == NULL || ie2 == NULL)
  		return -1;
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/420-indicate-features.patch b/recipes-wifi/hostapd/files/patches-2.10.3/420-indicate-features.patch
index 3b28b6e..07df8e5 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/420-indicate-features.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/420-indicate-features.patch
@@ -9,7 +9,7 @@
  
  struct hapd_global {
  	void **drv_priv;
-@@ -786,7 +786,7 @@ int main(int argc, char *argv[])
+@@ -799,7 +799,7 @@ int main(int argc, char *argv[])
  	wpa_supplicant_event = hostapd_wpa_event;
  	wpa_supplicant_event_global = hostapd_wpa_event_global;
  	for (;;) {
@@ -18,7 +18,7 @@
  		if (c < 0)
  			break;
  		switch (c) {
-@@ -823,6 +823,8 @@ int main(int argc, char *argv[])
+@@ -836,6 +836,8 @@ int main(int argc, char *argv[])
  			break;
  #endif /* CONFIG_DEBUG_LINUX_TRACING */
  		case 'v':
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/recipes-wifi/hostapd/files/patches-2.10.3/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
index e50c609..c6fe54e 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
@@ -174,7 +174,7 @@
  	 * macsec_policy - Determines the policy for MACsec secure session
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -4149,6 +4149,12 @@ static void wpas_start_assoc_cb(struct w
+@@ -4175,6 +4175,12 @@ static void wpas_start_assoc_cb(struct w
  			params.beacon_int = ssid->beacon_int;
  		else
  			params.beacon_int = wpa_s->conf->beacon_int;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/463-add-mcast_rate-to-11s.patch b/recipes-wifi/hostapd/files/patches-2.10.3/463-add-mcast_rate-to-11s.patch
index be9e050..daa36c2 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/463-add-mcast_rate-to-11s.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/463-add-mcast_rate-to-11s.patch
@@ -29,7 +29,7 @@
  struct wpa_driver_set_key_params {
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -11626,6 +11626,18 @@ static int nl80211_put_mesh_id(struct nl
+@@ -11667,6 +11667,18 @@ static int nl80211_put_mesh_id(struct nl
  }
  
  
@@ -48,7 +48,7 @@
  static int nl80211_put_mesh_config(struct nl_msg *msg,
  				   struct wpa_driver_mesh_bss_params *params)
  {
-@@ -11687,6 +11699,7 @@ static int nl80211_join_mesh(struct i802
+@@ -11728,6 +11740,7 @@ static int nl80211_join_mesh(struct i802
  	    nl80211_put_basic_rates(msg, params->basic_rates) ||
  	    nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
  	    nl80211_put_beacon_int(msg, params->beacon_int) ||
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/600-ubus_support.patch b/recipes-wifi/hostapd/files/patches-2.10.3/600-ubus_support.patch
index 5b2745a..bc80ef0 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/600-ubus_support.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/600-ubus_support.patch
@@ -84,7 +84,7 @@
  		   __func__, driver, drv_priv);
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -2778,7 +2778,7 @@ static void handle_auth(struct hostapd_d
+@@ -2786,7 +2786,7 @@ static void handle_auth(struct hostapd_d
  	u16 auth_alg, auth_transaction, status_code;
  	u16 resp = WLAN_STATUS_SUCCESS;
  	struct sta_info *sta = NULL;
@@ -93,7 +93,7 @@
  	u16 fc;
  	const u8 *challenge = NULL;
  	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
-@@ -2787,6 +2787,11 @@ static void handle_auth(struct hostapd_d
+@@ -2795,6 +2795,11 @@ static void handle_auth(struct hostapd_d
  	struct radius_sta rad_info;
  	const u8 *dst, *sa, *bssid;
  	bool mld_sta = false;
@@ -105,7 +105,7 @@
  
  	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
  		wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
-@@ -2978,6 +2983,13 @@ static void handle_auth(struct hostapd_d
+@@ -2986,6 +2991,13 @@ static void handle_auth(struct hostapd_d
  		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
  		goto fail;
  	}
@@ -119,7 +119,7 @@
  	if (res == HOSTAPD_ACL_PENDING)
  		return;
  
-@@ -5141,7 +5153,7 @@ static void handle_assoc(struct hostapd_
+@@ -5161,7 +5173,7 @@ static void handle_assoc(struct hostapd_
  	int resp = WLAN_STATUS_SUCCESS;
  	u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
  	const u8 *pos;
@@ -128,7 +128,7 @@
  	struct sta_info *sta;
  	u8 *tmp = NULL;
  #ifdef CONFIG_FILS
-@@ -5354,6 +5366,11 @@ static void handle_assoc(struct hostapd_
+@@ -5374,6 +5386,11 @@ static void handle_assoc(struct hostapd_
  		left = res;
  	}
  #endif /* CONFIG_FILS */
@@ -140,7 +140,7 @@
  
  	/* followed by SSID and Supported rates; and HT capabilities if 802.11n
  	 * is used */
-@@ -5452,6 +5469,13 @@ static void handle_assoc(struct hostapd_
+@@ -5472,6 +5489,13 @@ static void handle_assoc(struct hostapd_
  	}
  #endif /* CONFIG_FILS */
  
@@ -154,7 +154,7 @@
   fail:
  
  	/*
-@@ -5733,6 +5757,7 @@ static void handle_disassoc(struct hosta
+@@ -5753,6 +5777,7 @@ static void handle_disassoc(struct hosta
  			   (unsigned long) len);
  		return;
  	}
@@ -162,7 +162,7 @@
  
  	sta = ap_get_sta(hapd, mgmt->sa);
  	if (!sta) {
-@@ -5764,6 +5789,8 @@ static void handle_deauth(struct hostapd
+@@ -5784,6 +5809,8 @@ static void handle_deauth(struct hostapd
  	/* Clear the PTKSA cache entries for PASN */
  	ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
  
@@ -201,7 +201,7 @@
  
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -260,6 +260,10 @@ int hostapd_notif_assoc(struct hostapd_d
  	u16 reason = WLAN_REASON_UNSPECIFIED;
  	int status = WLAN_STATUS_SUCCESS;
  	const u8 *p2p_dev_addr = NULL;
@@ -212,7 +212,7 @@
  
  	if (addr == NULL) {
  		/*
-@@ -237,6 +241,12 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -396,6 +400,12 @@ int hostapd_notif_assoc(struct hostapd_d
  		goto fail;
  	}
  
@@ -348,7 +348,7 @@
  CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -7566,6 +7566,8 @@ struct wpa_supplicant * wpa_supplicant_a
+@@ -7593,6 +7593,8 @@ struct wpa_supplicant * wpa_supplicant_a
  	}
  #endif /* CONFIG_P2P */
  
@@ -357,7 +357,7 @@
  	return wpa_s;
  }
  
-@@ -7592,6 +7594,8 @@ int wpa_supplicant_remove_iface(struct w
+@@ -7619,6 +7621,8 @@ int wpa_supplicant_remove_iface(struct w
  	struct wpa_supplicant *parent = wpa_s->parent;
  #endif /* CONFIG_MESH */
  
@@ -366,7 +366,7 @@
  	/* Remove interface from the global list of interfaces */
  	prev = global->ifaces;
  	if (prev == wpa_s) {
-@@ -7938,8 +7942,12 @@ int wpa_supplicant_run(struct wpa_global
+@@ -7965,8 +7969,12 @@ int wpa_supplicant_run(struct wpa_global
  	eloop_register_signal_terminate(wpa_supplicant_terminate, global);
  	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
  
@@ -398,7 +398,7 @@
  };
  
  
-@@ -650,6 +653,7 @@ struct wpa_supplicant {
+@@ -685,6 +688,7 @@ struct wpa_supplicant {
  	unsigned char own_addr[ETH_ALEN];
  	unsigned char perm_addr[ETH_ALEN];
  	char ifname[100];
@@ -508,7 +508,7 @@
  
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1211,6 +1211,8 @@ int hostapd_dfs_pre_cac_expired(struct h
+@@ -1216,6 +1216,8 @@ int hostapd_dfs_pre_cac_expired(struct h
  		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
  		freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
  
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 e0bbf13..de182b9 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
@@ -26,7 +26,7 @@
  ifdef CONFIG_CODE_COVERAGE
 --- a/hostapd/main.c
 +++ b/hostapd/main.c
-@@ -994,6 +994,7 @@ int main(int argc, char *argv[])
+@@ -1007,6 +1007,7 @@ int main(int argc, char *argv[])
  	}
  
  	hostapd_global_ctrl_iface_init(&interfaces);
@@ -34,7 +34,7 @@
  
  	if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
  		wpa_printf(MSG_ERROR, "Failed to start eloop");
-@@ -1003,6 +1004,7 @@ int main(int argc, char *argv[])
+@@ -1016,6 +1017,7 @@ int main(int argc, char *argv[])
  	ret = 0;
  
   out:
@@ -107,14 +107,14 @@
  	hostapd_ubus_free_bss(hapd);
  	accounting_deinit(hapd);
  	hostapd_deinit_wpa(hapd);
-@@ -599,6 +602,7 @@ void hostapd_cleanup_iface_partial(struc
+@@ -600,6 +603,7 @@ void hostapd_cleanup_iface_partial(struc
  static void hostapd_cleanup_iface(struct hostapd_iface *iface)
  {
  	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
 +	hostapd_ucode_free_iface(iface);
- 	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
  	eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
  			     NULL);
+ 
 @@ -1189,6 +1193,7 @@ static int hostapd_start_beacon(struct h
  		hapd->driver->set_operstate(hapd->drv_priv, 1);
  
@@ -142,6 +142,16 @@
  {
  	if (!hapd)
  		return;
+@@ -3491,7 +3495,8 @@ int hostapd_remove_iface(struct hapd_int
+ 		hapd_iface = interfaces->iface[i];
+ 		if (hapd_iface == NULL)
+ 			return -1;
+-		if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
++		if (!os_strcmp(hapd_iface->phy, buf) ||
++		    !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
+ 			wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
+ 			hapd_iface->driver_ap_teardown =
+ 				!!(hapd_iface->drv_flags &
 --- a/wpa_supplicant/Makefile
 +++ b/wpa_supplicant/Makefile
 @@ -195,8 +195,20 @@ endif
@@ -186,7 +196,7 @@
  
  #ifdef CONFIG_BGSCAN
  	if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid)
-@@ -7567,6 +7568,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);
@@ -194,7 +204,7 @@
  
  	return wpa_s;
  }
-@@ -7594,6 +7596,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 */
  
@@ -202,7 +212,7 @@
  	wpas_ubus_free_bss(wpa_s);
  
  	/* Remove interface from the global list of interfaces */
-@@ -7904,6 +7907,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);
@@ -210,7 +220,7 @@
  
  	return global;
  }
-@@ -7942,12 +7946,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);
  
@@ -223,7 +233,7 @@
  	return 0;
  }
  
-@@ -7980,6 +7980,8 @@ void wpa_supplicant_deinit(struct wpa_gl
+@@ -8007,6 +8007,8 @@ void wpa_supplicant_deinit(struct wpa_gl
  
  	wpas_notify_supplicant_deinitialized(global);
  
@@ -242,7 +252,7 @@
  
  extern const char *const wpa_supplicant_version;
  extern const char *const wpa_supplicant_license;
-@@ -654,6 +655,7 @@ struct wpa_supplicant {
+@@ -689,6 +690,7 @@ struct wpa_supplicant {
  	unsigned char perm_addr[ETH_ALEN];
  	char ifname[100];
  	struct wpas_ubus_bss ubus;
@@ -270,7 +280,33 @@
  
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -6426,6 +6426,7 @@ union wpa_event_data {
+@@ -3787,6 +3787,25 @@ struct wpa_driver_ops {
+ 			 const char *ifname);
+ 
+ 	/**
++	 * if_rename - Rename a virtual interface
++	 * @priv: Private driver interface data
++	 * @type: Interface type
++	 * @ifname: Interface name of the virtual interface to be renamed
++	 *	    (NULL when renaming the AP BSS interface)
++	 * @new_name: New interface name of the virtual interface
++	 * Returns: 0 on success, -1 on failure
++	 */
++	int (*if_rename)(void *priv, enum wpa_driver_if_type type,
++			 const char *ifname, const char *new_name);
++
++	/**
++	 * set_first_bss - Make a virtual interface the first (primary) bss
++	 * @priv: Private driver interface data
++	 * Returns: 0 on success, -1 on failure
++	 */
++	int (*set_first_bss)(void *priv);
++
++	/**
+ 	 * set_sta_vlan - Bind a station into a specific interface (AP only)
+ 	 * @priv: Private driver interface data
+ 	 * @ifname: Interface (main or virtual BSS or VLAN)
+@@ -6440,6 +6459,7 @@ union wpa_event_data {
  
  	/**
  	 * struct ch_switch
@@ -278,7 +314,7 @@
  	 * @freq: Frequency of new channel in MHz
  	 * @ht_enabled: Whether this is an HT channel
  	 * @ch_offset: Secondary channel offset
-@@ -6436,6 +6437,7 @@ union wpa_event_data {
+@@ -6450,6 +6470,7 @@ union wpa_event_data {
  	 * @punct_bitmap: Puncturing bitmap
  	 */
  	struct ch_switch {
@@ -305,7 +341,7 @@
  
  	if (finished)
  		bss->flink->freq = data.ch_switch.freq;
-@@ -3848,6 +3851,7 @@ static void do_process_drv_event(struct
+@@ -3912,6 +3915,7 @@ static void do_process_drv_event(struct
  				     tb[NL80211_ATTR_CENTER_FREQ1],
  				     tb[NL80211_ATTR_CENTER_FREQ2],
  				     tb[NL80211_ATTR_PUNCT_BITMAP],
@@ -313,7 +349,7 @@
  				     0);
  		break;
  	case NL80211_CMD_CH_SWITCH_NOTIFY:
-@@ -3860,6 +3864,7 @@ static void do_process_drv_event(struct
+@@ -3924,6 +3928,7 @@ static void do_process_drv_event(struct
  				     tb[NL80211_ATTR_CENTER_FREQ1],
  				     tb[NL80211_ATTR_CENTER_FREQ2],
  				     tb[NL80211_ATTR_PUNCT_BITMAP],
@@ -323,7 +359,7 @@
  	case NL80211_CMD_DISCONNECT:
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
-@@ -5381,6 +5381,7 @@ void supplicant_event(void *ctx, enum wp
+@@ -5389,6 +5389,7 @@ void supplicant_event(void *ctx, enum wp
  		event_to_string(event), event);
  #endif /* CONFIG_NO_STDOUT_DEBUG */
  
@@ -331,3 +367,187 @@
  	switch (event) {
  	case EVENT_AUTH:
  #ifdef CONFIG_FST
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -393,6 +393,23 @@ static inline int hostapd_drv_stop_ap(st
+ 	return hapd->driver->stop_ap(hapd->drv_priv);
+ }
+ 
++static inline int hostapd_drv_if_rename(struct hostapd_data *hapd,
++					enum wpa_driver_if_type type,
++					const char *ifname,
++					const char *new_name)
++{
++	if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv)
++		return -1;
++	return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name);
++}
++
++static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd)
++{
++	if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv)
++		return 0;
++	return hapd->driver->set_first_bss(hapd->drv_priv);
++}
++
+ static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
+ 					   struct wpa_channel_info *ci)
+ {
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -1333,7 +1333,7 @@ static void wpa_driver_nl80211_event_rtm
+ 		}
+ 		wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
+ 			   namebuf, ifname);
+-		if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
++		if (drv->first_bss->ifindex != ifi->ifi_index) {
+ 			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
+ 		}
+ 		wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
+ 			   namebuf, ifname);
+-		if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
++		if (drv->first_bss->ifindex != ifi->ifi_index) {
+ 			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
+ 	char master_ifname[IFNAMSIZ];
+ 	int ifindex, br_ifindex = 0;
+ 	int br_added = 0;
++	int err;
+ 
+ 	bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
+ 					  params->global_priv, 1,
+@@ -8491,21 +8492,17 @@ static void *i802_init(struct hostapd_da
+ 	    (params->num_bridge == 0 || !params->bridge[0]))
+ 		add_ifidx(drv, br_ifindex, drv->ifindex);
+ 
+-	if (bss->added_if_into_bridge || bss->already_in_bridge) {
+-		int err;
+-
+-		drv->rtnl_sk = nl_socket_alloc();
+-		if (drv->rtnl_sk == NULL) {
+-			wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
+-			goto failed;
+-		}
++	drv->rtnl_sk = nl_socket_alloc();
++	if (drv->rtnl_sk == NULL) {
++		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
++		goto failed;
++	}
+ 
+-		err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
+-		if (err) {
+-			wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
+-				   nl_geterror(err));
+-			goto failed;
+-		}
++	err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
++	if (err) {
++		wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
++			   nl_geterror(err));
++		goto failed;
+ 	}
+ 
+ 	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
+@@ -8875,6 +8872,50 @@ static int wpa_driver_nl80211_if_remove(
+ 	return 0;
+ }
+ 
++static int wpa_driver_nl80211_if_rename(struct i802_bss *bss,
++					enum wpa_driver_if_type type,
++					const char *ifname, const char *new_name)
++{
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct ifinfomsg ifi = {
++		.ifi_family = AF_UNSPEC,
++		.ifi_index = bss->ifindex,
++	};
++	struct nl_msg *msg;
++	int res = -ENOMEM;
++
++	if (ifname)
++		ifi.ifi_index = if_nametoindex(ifname);
++
++	msg = nlmsg_alloc_simple(RTM_SETLINK, 0);
++	if (!msg)
++		return res;
++
++	if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
++		goto out;
++
++	if (nla_put_string(msg, IFLA_IFNAME, new_name))
++		goto out;
++
++	res = nl_send_auto_complete(drv->rtnl_sk, msg);
++	if (res < 0)
++		goto out;
++
++	res = nl_wait_for_ack(drv->rtnl_sk);
++	if (res) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Renaming device %s to %s failed: %s",
++			   ifname ? ifname : bss->ifname, new_name, nl_geterror(res));
++		goto out;
++	}
++
++	if (type == WPA_IF_AP_BSS && !ifname)
++		os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname));
++
++out:
++	nlmsg_free(msg);
++	return res;
++}
+ 
+ static int cookie_handler(struct nl_msg *msg, void *arg)
+ {
+@@ -10513,6 +10554,37 @@ static int driver_nl80211_if_remove(void
+ }
+ 
+ 
++static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type,
++				    const char *ifname, const char *new_name)
++{
++	struct i802_bss *bss = priv;
++	return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name);
++}
++
++
++static int driver_nl80211_set_first_bss(void *priv)
++{
++	struct i802_bss *bss = priv, *tbss;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++
++	if (drv->first_bss == bss)
++		return 0;
++
++	for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
++		if (tbss->next != bss)
++			continue;
++
++		tbss->next = bss->next;
++		bss->next = drv->first_bss;
++		drv->first_bss = bss;
++		drv->ctx = bss->ctx;
++		return 0;
++	}
++
++	return -1;
++}
++
++
+ 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
+ 	.set_acl = wpa_driver_nl80211_set_acl,
+ 	.if_add = wpa_driver_nl80211_if_add,
+ 	.if_remove = driver_nl80211_if_remove,
++	.if_rename = driver_nl80211_if_rename,
++	.set_first_bss = driver_nl80211_set_first_bss,
+ 	.send_mlme = driver_nl80211_send_mlme,
+ 	.get_hw_feature_data = nl80211_get_hw_feature_data,
+ 	.sta_add = wpa_driver_nl80211_sta_add,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/701-reload_config_inline.patch b/recipes-wifi/hostapd/files/patches-2.10.3/701-reload_config_inline.patch
index 44c8892..3c62bf6 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/701-reload_config_inline.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/701-reload_config_inline.patch
@@ -1,6 +1,6 @@
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4810,7 +4810,12 @@ struct hostapd_config * hostapd_config_r
+@@ -4816,7 +4816,12 @@ struct hostapd_config * hostapd_config_r
  	int errors = 0;
  	size_t i;
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/720-iface_max_num_sta.patch b/recipes-wifi/hostapd/files/patches-2.10.3/720-iface_max_num_sta.patch
index 1aa4456..089c1dd 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/720-iface_max_num_sta.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/720-iface_max_num_sta.patch
@@ -70,7 +70,7 @@
  			   " since no room for additional STA",
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1036,6 +1036,8 @@ struct hostapd_config {
+@@ -1039,6 +1039,8 @@ struct hostapd_config {
  	unsigned int track_sta_max_num;
  	unsigned int track_sta_max_age;
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/740-snoop_iface.patch b/recipes-wifi/hostapd/files/patches-2.10.3/740-snoop_iface.patch
index 6b6cc0f..ce64513 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/740-snoop_iface.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/740-snoop_iface.patch
@@ -10,7 +10,7 @@
  	int bridge_hairpin; /* hairpin_mode on bridge members */
 --- a/src/ap/x_snoop.c
 +++ b/src/ap/x_snoop.c
-@@ -33,14 +33,16 @@ int x_snoop_init(struct hostapd_data *ha
+@@ -33,28 +33,31 @@ int x_snoop_init(struct hostapd_data *ha
  
  	hapd->x_snoop_initialized = true;
  
@@ -29,13 +29,20 @@
  		wpa_printf(MSG_DEBUG,
  			   "x_snoop: Failed to enable proxyarp on the bridge port");
  		return -1;
-@@ -54,7 +56,8 @@ int x_snoop_init(struct hostapd_data *ha
  	}
  
+ 	if (hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT,
+-					 1)) {
++					 conf->snoop_iface[0] ? conf->snoop_iface : NULL, 1)) {
+ 		wpa_printf(MSG_DEBUG,
+ 			   "x_snoop: Failed to enable accepting gratuitous ARP on the bridge");
+ 		return -1;
+ 	}
+ 
  #ifdef CONFIG_IPV6
 -	if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) {
 +	if (!conf->snoop_iface[0] &&
-+	    hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) {
++	    hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, NULL, 1)) {
  		wpa_printf(MSG_DEBUG,
  			   "x_snoop: Failed to enable multicast snooping on the bridge");
  		return -1;
@@ -44,15 +51,29 @@
  	struct hostapd_bss_config *conf = hapd->conf;
  	struct l2_packet_data *l2;
 +	const char *ifname = conf->bridge;
- 
--	l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1);
++
 +	if (conf->snoop_iface[0])
 +		ifname = conf->snoop_iface;
-+
+ 
+-	l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1);
 +	l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1);
  	if (l2 == NULL) {
  		wpa_printf(MSG_DEBUG,
  			   "x_snoop: Failed to initialize L2 packet processing %s",
+@@ -127,9 +134,12 @@ void x_snoop_mcast_to_ucast_convert_send
+ 
+ void x_snoop_deinit(struct hostapd_data *hapd)
+ {
++	struct hostapd_bss_config *conf = hapd->conf;
++
+ 	if (!hapd->x_snoop_initialized)
+ 		return;
+-	hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, 0);
++	hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT,
++				     conf->snoop_iface[0] ? conf->snoop_iface : NULL, 0);
+ 	hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 0);
+ 	hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 0);
+ 	hapd->x_snoop_initialized = false;
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -2322,6 +2322,8 @@ static int hostapd_config_fill(struct ho
@@ -64,3 +85,55 @@
  	} else if (os_strcmp(buf, "vlan_bridge") == 0) {
  		os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
  	} else if (os_strcmp(buf, "wds_bridge") == 0) {
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -366,12 +366,12 @@ static inline int hostapd_drv_br_port_se
+ 
+ static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd,
+ 					       enum drv_br_net_param param,
+-					       unsigned int val)
++					       const char *ifname, unsigned int val)
+ {
+ 	if (hapd->driver == NULL || hapd->drv_priv == NULL ||
+ 	    hapd->driver->br_set_net_param == NULL)
+ 		return -1;
+-	return hapd->driver->br_set_net_param(hapd->drv_priv, param, val);
++	return hapd->driver->br_set_net_param(hapd->drv_priv, param, ifname, val);
+ }
+ 
+ static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd,
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -4209,7 +4209,7 @@ struct wpa_driver_ops {
+ 	 * Returns: 0 on success, negative (<0) on failure
+ 	 */
+ 	int (*br_set_net_param)(void *priv, enum drv_br_net_param param,
+-				unsigned int val);
++				const char *ifname, unsigned int val);
+ 
+ 	/**
+ 	 * get_wowlan - Get wake-on-wireless status
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -12168,7 +12168,7 @@ static const char * drv_br_net_param_str
+ 
+ 
+ static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
+-				       unsigned int val)
++				       const char *ifname, unsigned int val)
+ {
+ 	struct i802_bss *bss = priv;
+ 	char path[128];
+@@ -12194,8 +12194,11 @@ static int wpa_driver_br_set_net_param(v
+ 			return -EINVAL;
+ 	}
+ 
++	if (!ifname)
++		ifname = bss->brname;
++
+ 	os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s",
+-		    ip_version, bss->brname, param_txt);
++		    ip_version, ifname, param_txt);
+ 
+ set_val:
+ 	if (linux_write_system_file(path, val))
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/770-radius_server.patch b/recipes-wifi/hostapd/files/patches-2.10.3/770-radius_server.patch
index e4690c7..8837a26 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/770-radius_server.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/770-radius_server.patch
@@ -21,7 +21,7 @@
  
  #ifndef CONFIG_NO_HOSTAPD_LOGGER
  static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
-@@ -758,6 +759,11 @@ int main(int argc, char *argv[])
+@@ -771,6 +772,11 @@ int main(int argc, char *argv[])
  	if (os_program_init())
  		return -1;
  
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch b/recipes-wifi/hostapd/files/patches-2.10.3/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch
index 51690de..5809a3b 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch
@@ -13,7 +13,7 @@
 
 --- a/wpa_supplicant/ctrl_iface.c
 +++ b/wpa_supplicant/ctrl_iface.c
-@@ -12640,7 +12640,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12763,7 +12763,7 @@ char * wpa_supplicant_ctrl_iface_process
  		if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18))
  			reply_len = -1;
  #endif /* CONFIG_WNM */
@@ -22,7 +22,7 @@
  	} else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) {
  		if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18))
  			reply_len = -1;
-@@ -12650,7 +12650,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12773,7 +12773,7 @@ char * wpa_supplicant_ctrl_iface_process
  	} else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) {
  		if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11))
  			reply_len = -1;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/991-Fix-OpenWrt-13156.patch b/recipes-wifi/hostapd/files/patches-2.10.3/991-Fix-OpenWrt-13156.patch
index 3f10fb1..097d62a 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/991-Fix-OpenWrt-13156.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/991-Fix-OpenWrt-13156.patch
@@ -20,7 +20,7 @@
 
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
-@@ -3563,6 +3563,8 @@ int hostapd_remove_iface(struct hapd_int
+@@ -3564,6 +3564,8 @@ int hostapd_remove_iface(struct hapd_int
  void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
  			   int reassoc)
  {
@@ -29,7 +29,7 @@
  	if (hapd->tkip_countermeasures) {
  		hostapd_drv_sta_deauth(hapd, sta->addr,
  				       WLAN_REASON_MICHAEL_MIC_FAILURE);
-@@ -3570,10 +3572,16 @@ void hostapd_new_assoc_sta(struct hostap
+@@ -3571,10 +3573,16 @@ void hostapd_new_assoc_sta(struct hostap
  	}
  
  #ifdef CONFIG_IEEE80211BE
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-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch
index ebd951f..7c00526 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-hostapd-mtk-Add-neighbor-report-and-BSS-Termination-.patch
@@ -1,7 +1,7 @@
-From 66102db35a595a1b2754e13a95123e55d378332e Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add neighbor report and BSS Termination
+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 ()
@@ -59,7 +59,7 @@
  
  
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 44b62f8..774f64e 100644
+index 0790478..82338e2 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -558,6 +558,7 @@ struct hostapd_bss_config {
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-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch
index 70486da..d9b0cba 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-hostapd-mtk-print-sae-groups-by-hostapd-ctrl.patch
@@ -1,7 +1,7 @@
-From a915b2e10f342705ab26158efebaa7a7024042ae Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: print sae groups by hostapd ctrl
+Subject: [PATCH 02/38] hostapd: mtk: print sae groups by hostapd ctrl
 
 ---
  hostapd/ctrl_iface.c | 13 +++++++++++++
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-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch
index 377b04a..85ffb3b 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-hostapd-mtk-add-support-for-runtime-set-in-band-disc.patch
@@ -1,7 +1,7 @@
-From e2ecc047a72c3069c9f05975e612a37864da5885 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: add support for runtime set in-band
+Subject: [PATCH 03/38] hostapd: mtk: add support for runtime set in-band
  discovery
 
 Usage:
@@ -143,7 +143,7 @@
  };
  
 diff --git a/src/ap/beacon.c b/src/ap/beacon.c
-index 9454cdf..3dc217f 100644
+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,
@@ -166,7 +166,7 @@
  						  &params->fd_frame_tmpl_len);
  
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 99870a6..7867e69 100644
+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,
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-hostapd-mtk-Add-mtk_vendor.h.patch
index 11971cd..13a7d1d 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-hostapd-mtk-Add-mtk_vendor.h.patch
@@ -1,7 +1,7 @@
-From bb0f79fb5a04b7ba10bf3ff03634110dd25aa31f Mon Sep 17 00:00:00 2001
+From 86553b9434ad98e4ec3dd19fbc5589ca24501f4d 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/40] hostapd: mtk: Add mtk_vendor.h
+Subject: [PATCH 04/38] hostapd: mtk: Add mtk_vendor.h
 
 ---
  src/common/mtk_vendor.h | 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-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch
index 272ebf8..868adca 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-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch
@@ -1,7 +1,7 @@
-From 6b321709940a2feaa79a5e6d63f19a83bde83bb7 Mon Sep 17 00:00:00 2001
+From 906a70c7df5918c40c9552e078690ab7305ed40e 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/40] hostapd: mtk: Support EDCCA hostapd configuration
+Subject: [PATCH 05/38] hostapd: mtk: Support EDCCA hostapd configuration
 
 edcca_enable and edcca_compensation and implement edcca related handlers.
 ---
@@ -20,12 +20,12 @@
  12 files changed, 428 insertions(+), 6 deletions(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 3557bef..1fc6456 100644
+index 4b0f99f..d281026 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4803,6 +4803,40 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 	} else if (os_strcmp(buf, "mld_id") == 0) {
- 		bss->mld_id = atoi(pos);
+@@ -4809,6 +4809,40 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 			return 1;
+ 		}
  #endif /* CONFIG_IEEE80211BE */
 +	} else if (os_strcmp(buf, "edcca_threshold") == 0) {
 +		if (hostapd_parse_intlist(&conf->edcca_threshold, pos) ||
@@ -237,10 +237,10 @@
  	wpabuf_free(conf->civic);
  
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 774f64e..0e829c0 100644
+index 82338e2..24d540d 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1190,8 +1190,38 @@ struct hostapd_config {
+@@ -1193,8 +1193,38 @@ struct hostapd_config {
  		MBSSID_ENABLED = 1,
  		ENHANCED_MBSSID_ENABLED = 2,
  	} mbssid;
@@ -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 331b0ea..8806217 100644
+index 96c8c4e..6ca693b 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 96ab02b..b34c9d2 100644
+index 6746de2..1b9ce6f 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2511,6 +2511,13 @@ dfs_offload:
@@ -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 969cbda..443c4a7 100644
+index cc49011..fca2035 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5080,6 +5080,10 @@ struct wpa_driver_ops {
+@@ -5102,6 +5102,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 7867e69..5a3e208 100644
+index c7745b6..0a159d5 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
-@@ -13632,6 +13634,174 @@ static int testing_nl80211_radio_disable(void *priv, int disabled)
+@@ -13748,6 +13750,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",
-@@ -13786,4 +13956,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -13904,4 +14074,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 */
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-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
index 7ae38e3..43f214c 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-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
@@ -1,7 +1,7 @@
-From 2ae0d6fb6b676f76081a9edd3416d93b26091400 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH 06/38] hostapd: mtk: Add hostapd MU SET/GET control
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -20,7 +20,7 @@
  13 files changed, 251 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 1fc6456..0e67796 100644
+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,
@@ -168,10 +168,10 @@
  
  	/* 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 0e829c0..0bd6254 100644
+index 24d540d..421e6a6 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1143,6 +1143,7 @@ struct hostapd_config {
+@@ -1146,6 +1146,7 @@ struct hostapd_config {
  	u8 he_6ghz_tx_ant_pat;
  	u8 he_6ghz_reg_pwr_type;
  	bool require_he;
@@ -202,7 +202,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 8806217..6e0cf81 100644
+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);
@@ -215,7 +215,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index b34c9d2..4251699 100644
+index 1b9ce6f..865991e 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2517,6 +2517,8 @@ dfs_offload:
@@ -261,7 +261,7 @@
  #define ETH_ALEN 6
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 443c4a7..1471ba2 100644
+index fca2035..542dd45 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
 @@ -176,6 +176,11 @@ struct hostapd_channel_data {
@@ -276,7 +276,7 @@
  };
  
  #define HE_MAC_CAPAB_0		0
-@@ -5084,6 +5089,14 @@ struct wpa_driver_ops {
+@@ -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);
@@ -292,10 +292,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 5a3e208..8e8a4fd 100644
+index 0a159d5..07c72f5 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13497,6 +13497,114 @@ fail:
+@@ -13613,6 +13613,114 @@ fail:
  }
  
  
@@ -410,7 +410,7 @@
  #ifdef CONFIG_DPP
  static int nl80211_dpp_listen(void *priv, bool enable)
  {
-@@ -13947,6 +14055,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
index 0488ba3..5967879 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-hostapd-mtk-Add-three-wire-PTA-ctrl-hostapd-vendor-c.patch
@@ -1,7 +1,7 @@
-From 74fde855e7d167f93908a70b50b029c42b796be8 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add three wire PTA ctrl hostapd vendor
+Subject: [PATCH 07/38] hostapd: mtk: Add three wire PTA ctrl hostapd vendor
  command
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -20,10 +20,10 @@
  11 files changed, 93 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 0e67796..c716630 100644
+index ec3b41a..d515b6e 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4846,6 +4846,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+@@ -4852,6 +4852,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
  			return 1;
  		}
  		conf->edcca_compensation = (s8) val;
@@ -47,10 +47,10 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 0bd6254..8f4f79e 100644
+index 421e6a6..52df2e0 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1195,6 +1195,19 @@ struct hostapd_config {
+@@ -1198,6 +1198,19 @@ struct hostapd_config {
  	u8 edcca_enable;
  	s8 edcca_compensation;
  	int *edcca_threshold;
@@ -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 6e0cf81..960a110 100644
+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,
@@ -102,7 +102,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 4251699..798852e 100644
+index 865991e..cad5d67 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2519,6 +2519,8 @@ dfs_offload:
@@ -149,10 +149,10 @@
  	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 1471ba2..cd7afef 100644
+index 542dd45..07af191 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5097,6 +5097,14 @@ struct wpa_driver_ops {
+@@ -5119,6 +5119,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 8e8a4fd..621515d 100644
+index 07c72f5..cf1f2d0 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13910,6 +13910,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
+@@ -14026,6 +14026,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
  	return ret;
  }
  
@@ -210,7 +210,7 @@
  
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
-@@ -14070,4 +14102,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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-hostapd-mtk-Add-hostapd-iBF-control.patch
index 6d807ee..de3e848 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-hostapd-mtk-Add-hostapd-iBF-control.patch
@@ -1,7 +1,7 @@
-From a527e4f9a557f751fa0b3ef8b3d40e5edef56d38 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add hostapd iBF control
+Subject: [PATCH 08/38] hostapd: mtk: Add hostapd iBF control
 
 Signed-off-by: mtk27835 <shurong.wen@mediatek.com>
 ---
@@ -21,10 +21,10 @@
  13 files changed, 224 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index c716630..dea124a 100644
+index d515b6e..f8560a7 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4850,6 +4850,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+@@ -4856,6 +4856,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
  		u8 en = atoi(pos);
  
  		conf->three_wire_enable = en;
@@ -118,10 +118,10 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 8f4f79e..9758439 100644
+index 52df2e0..ffbc4fb 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1196,6 +1196,7 @@ struct hostapd_config {
+@@ -1199,6 +1199,7 @@ struct hostapd_config {
  	s8 edcca_compensation;
  	int *edcca_threshold;
  	u8 three_wire_enable;
@@ -129,7 +129,7 @@
  };
  
  enum three_wire_mode {
-@@ -1321,6 +1322,7 @@ hostapd_set_oper_centr_freq_seg1_idx(struct hostapd_config *conf,
+@@ -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;
  }
  
@@ -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 960a110..3f1df5d 100644
+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);
@@ -174,7 +174,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 798852e..a513236 100644
+index cad5d67..227580e 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2521,6 +2521,8 @@ dfs_offload:
@@ -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 cd7afef..7ac0284 100644
+index 07af191..0a99078 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
-@@ -5105,6 +5110,20 @@ struct wpa_driver_ops {
+@@ -5127,6 +5132,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 621515d..936a4f8 100644
+index cf1f2d0..a05e047 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13943,6 +13943,112 @@ static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
+@@ -14059,6 +14059,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",
-@@ -14103,4 +14209,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch
index 40fccf5..ba1aa44 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-hostapd-mtk-Do-not-include-HE-capab-IE-if-associated.patch
@@ -1,7 +1,7 @@
-From 46e29c26ddaa503b6af4dc33784a2998c453d6c9 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Do not include HE capab IE if associated
+Subject: [PATCH 09/38] hostapd: mtk: Do not include HE capab IE if associated
  sta's HE capab IE is invalid
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index db48b7c..1bf5bea 100644
+index db404a6..110ad8c 100644
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -4843,7 +4843,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
+@@ -4863,7 +4863,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
  #endif /* CONFIG_IEEE80211AC */
  
  #ifdef CONFIG_IEEE80211AX
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-hostapd-mtk-Add-DFS-detection-mode.patch
index 1b4dadf..3049a6b 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-hostapd-mtk-Add-DFS-detection-mode.patch
@@ -1,7 +1,7 @@
-From a257091386c0bf12de2934730b874d240f34d1bb Mon Sep 17 00:00:00 2001
+From e825b01701aeb6536321a9bf1bd5b4760a0cdc04 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/40] hostapd: mtk: Add DFS detection mode
+Subject: [PATCH 10/38] hostapd: mtk: 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,10 +17,10 @@
  4 files changed, 50 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index dea124a..a4a8e71 100644
+index f8560a7..50e2993 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4853,6 +4853,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+@@ -4859,6 +4859,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
  	} else if (os_strcmp(buf, "ibf_enable") == 0) { /*ibf setting is per device*/
  		int val = atoi(pos);
  		conf->ibf_enable = !!val;
@@ -73,10 +73,10 @@
  		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 9758439..c50c2e2 100644
+index ffbc4fb..6576d79 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1197,6 +1197,7 @@ struct hostapd_config {
+@@ -1200,6 +1200,7 @@ struct hostapd_config {
  	int *edcca_threshold;
  	u8 three_wire_enable;
  	u8 ibf_enable;
@@ -84,7 +84,7 @@
  };
  
  enum three_wire_mode {
-@@ -1211,6 +1212,18 @@ enum three_wire_mode {
+@@ -1214,6 +1215,18 @@ enum three_wire_mode {
  		NUM_THREE_WIRE_MODE - 1
  };
  
@@ -104,10 +104,10 @@
  	EDCCA_MODE_FORCE_DISABLE = 0,
  	EDCCA_MODE_AUTO = 1,
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index a19afb0..644a7ea 100644
+index 29d2683..2e138e2 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1322,6 +1322,11 @@ hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
+@@ -1327,6 +1327,11 @@ hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
  		   __func__, iface->radar_background.cac_started ? "yes" : "no",
  		   hostapd_csa_in_progress(iface) ? "yes" : "no");
  
@@ -119,7 +119,7 @@
  	/* Check if CSA in progress */
  	if (hostapd_csa_in_progress(iface))
  		return 0;
-@@ -1370,6 +1375,11 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
+@@ -1375,6 +1380,11 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
  		   __func__, iface->cac_started ? "yes" : "no",
  		   hostapd_csa_in_progress(iface) ? "yes" : "no");
  
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-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
index 11b11fc..39cb7f2 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-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
@@ -1,7 +1,7 @@
-From 4802aabaad0a2e7a02d32a365f6d8fec344d264c Mon Sep 17 00:00:00 2001
+From 34d1517322d42ea45b6b2a792b9d7f7dd256bef6 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/40] hostapd: mtk: Add DFS offchan channel switch
+Subject: [PATCH 11/38] 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.
@@ -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 644a7ea..48c5fc9 100644
+index 2e138e2..23e6527 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -19,13 +19,6 @@
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-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
index aa32d0f..de63341 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-hostapd-mtk-Add-amsdu-set-get-ctrl.patch
@@ -1,7 +1,7 @@
-From 4f54451e436ca42946b3f0f294b6e784d2f61862 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add amsdu set get ctrl
+Subject: [PATCH 12/38] hostapd: mtk: Add amsdu set get ctrl
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -20,10 +20,10 @@
  13 files changed, 207 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index a4a8e71..d17e50e 100644
+index 50e2993..0b2f3dc 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4857,6 +4857,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+@@ -4863,6 +4863,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
  		u8 en = strtol(pos, NULL, 10);
  
  		conf->dfs_detect_mode = en;
@@ -123,10 +123,10 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index c50c2e2..b8f6680 100644
+index 6576d79..9f3cea2 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1198,6 +1198,7 @@ struct hostapd_config {
+@@ -1201,6 +1201,7 @@ struct hostapd_config {
  	u8 three_wire_enable;
  	u8 ibf_enable;
  	u8 dfs_detect_mode;
@@ -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 3f1df5d..422cb52 100644
+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);
@@ -172,7 +172,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index a513236..24e5df8 100644
+index 227580e..a166de4 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2523,6 +2523,8 @@ dfs_offload:
@@ -220,10 +220,10 @@
  	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 7ac0284..87a5a9b 100644
+index 0a99078..38f6e8b 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5124,6 +5124,15 @@ struct wpa_driver_ops {
+@@ -5146,6 +5146,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 936a4f8..ce09d9f 100644
+index a05e047..808db17 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14049,6 +14049,118 @@ fail:
+@@ -14165,6 +14165,118 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -362,7 +362,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14211,4 +14323,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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-hostapd-mtk-Add-he_ldpc-configuration.patch
index dd96623..2182cc1 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-hostapd-mtk-Add-he_ldpc-configuration.patch
@@ -1,7 +1,7 @@
-From ea7da2297d396febe75de0d7cf77cba9d2eab778 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add he_ldpc configuration
+Subject: [PATCH 13/38] hostapd: mtk: 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 d17e50e..04ca433 100644
+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,
@@ -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 30fb06d..fd42c50 100644
+index bafc923..f16e3b0 100644
 --- a/hostapd/hostapd.conf
 +++ b/hostapd/hostapd.conf
 @@ -833,6 +833,11 @@ wmm_ac_vo_acm=0
@@ -54,10 +54,10 @@
  		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 b8f6680..5b2dbff 100644
+index 9f3cea2..d0e27b2 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -956,6 +956,7 @@ struct hostapd_bss_config {
+@@ -959,6 +959,7 @@ struct hostapd_bss_config {
   * struct he_phy_capabilities_info - HE PHY capabilities
   */
  struct he_phy_capabilities_info {
@@ -84,10 +84,10 @@
  		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 0b7b776..cf3ef98 100644
+index e7c3f17..69f1591 100644
 --- a/src/common/ieee802_11_defs.h
 +++ b/src/common/ieee802_11_defs.h
-@@ -2357,6 +2357,9 @@ struct ieee80211_spatial_reuse {
+@@ -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))
  
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-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch
index 6003cfb..eac9292 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-hostapd-mtk-Add-vendor-command-attribute-for-RTS-BW-.patch
@@ -1,7 +1,7 @@
-From 41ccc468e3ce6727b237390bcedf1ab734d749e4 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add vendor command attribute for RTS BW
+Subject: [PATCH 14/38] hostapd: mtk: Add vendor command attribute for RTS BW
  signaling.
 
 Signed-off-by: himanshu.goyal <himanshu.goyal@mediatek.com>
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-hostapd-mtk-6G-band-does-not-require-DFS.patch
index 3b19e78..a955f11 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-hostapd-mtk-6G-band-does-not-require-DFS.patch
@@ -1,17 +1,17 @@
-From 0381565e342ecf407ffb6a32212c6d7123417c73 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: 6G band does not require DFS
+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 48c5fc9..dcf89ce 100644
+index 23e6527..0a8486a 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1511,6 +1511,7 @@ int hostapd_is_dfs_required(struct hostapd_iface *iface)
+@@ -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 ||
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-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
index 206a8d3..76d6e0b 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-hostapd-mtk-Fix-sending-wrong-VHT-operation-IE-in-CS.patch
@@ -1,7 +1,7 @@
-From b810754f20e0bad1b1be74bd71fc96f6b74b8c4d Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Fix sending wrong VHT operation IE in CSA
+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>
@@ -10,10 +10,10 @@
  1 file changed, 9 insertions(+), 5 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index dcf89ce..e5ed645 100644
+index 0a8486a..cfc3508 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1115,6 +1115,14 @@ static int
+@@ -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);
@@ -28,7 +28,7 @@
  
  	iface->conf->channel = iface->radar_background.channel;
  	iface->freq = iface->radar_background.freq;
-@@ -1127,11 +1135,7 @@ hostapd_dfs_start_channel_switch_background(struct hostapd_iface *iface)
+@@ -1132,11 +1140,7 @@ hostapd_dfs_start_channel_switch_background(struct hostapd_iface *iface)
  
  	hostpad_dfs_update_background_chain(iface);
  
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-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch
index f2e966a..e29ecce 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-hostapd-mtk-Add-sta-assisted-DFS-state-update-mechan.patch
@@ -1,7 +1,7 @@
-From 20f21e3ff3c5d5db5daea650e22c6fa8ca6071a4 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add sta-assisted DFS state update
+Subject: [PATCH 17/38] hostapd: mtk: Add sta-assisted DFS state update
  mechanism
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,10 +16,10 @@
  7 files changed, 78 insertions(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index e5ed645..d52a60e 100644
+index cfc3508..9d002cf 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1508,6 +1508,26 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
+@@ -1513,6 +1513,26 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
  }
  
  
@@ -61,10 +61,10 @@
  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 903eab3..c3fc419 100644
+index f6093c1..e7f1f19 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -1912,6 +1912,24 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
+@@ -2086,6 +2086,24 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
  			      radar->cf1, radar->cf2);
  }
  
@@ -89,7 +89,7 @@
  #endif /* NEED_AP_MLME */
  
  
-@@ -2190,6 +2208,16 @@ void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
+@@ -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;
@@ -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 ccff0ee..e209ac6 100644
+index 416e0d6..62f042e 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 87a5a9b..592f506 100644
+index 38f6e8b..0469694 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5760,6 +5760,20 @@ enum wpa_event_type {
+@@ -5782,6 +5782,20 @@ enum wpa_event_type {
  	 * EVENT_LINK_RECONFIG - Notification that AP links removed
  	 */
  	EVENT_LINK_RECONFIG,
@@ -144,10 +144,10 @@
  
  
 diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
-index 8566b2a..ab988fa 100644
+index 701c32e..63d4401 100644
 --- a/src/drivers/driver_nl80211_event.c
 +++ b/src/drivers/driver_nl80211_event.c
-@@ -2447,6 +2447,12 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
+@@ -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;
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-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch
index a9c1842..c2296fb 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-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch
@@ -1,7 +1,7 @@
-From 2471c86d25da6898dd8840b7267211a5dba036b1 Mon Sep 17 00:00:00 2001
+From f3a98bc033de56fee900d0da3a33775165b714ad 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/40] hostapd: mtk: Mark DFS channel as available for CSA.
+Subject: [PATCH 18/38] hostapd: mtk: Mark DFS channel as available for CSA.
 
 ---
  hostapd/ctrl_iface.c   | 10 ++++++++++
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-hostapd-mtk-Add-available-color-bitmap.patch
index 01aa4d5..d4ce7cc 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-hostapd-mtk-Add-available-color-bitmap.patch
@@ -1,7 +1,7 @@
-From 236e82d01cd015135468166e6d00b05b16e4c5f8 Mon Sep 17 00:00:00 2001
+From d77b2e1d3821e51f557f1292a0ccaa0a211ea11f 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/40] hostapd: mtk: Add available color bitmap
+Subject: [PATCH 19/38] hostapd: mtk: Add available color bitmap
 
 Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 ---
@@ -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 422cb52..136ea23 100644
+index 88bc430..ecaa71f 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);
@@ -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 592f506..91cb475 100644
+index 0469694..130143e 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5133,6 +5133,14 @@ struct wpa_driver_ops {
+@@ -5155,6 +5155,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 ce09d9f..8b8ddfa 100644
+index 808db17..ee0912f 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -12733,7 +12733,6 @@ static void nl80211_parse_btm_candidate_info(struct candidate_list *candidate,
+@@ -12849,7 +12849,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)
  {
-@@ -14161,6 +14160,203 @@ fail:
+@@ -14277,6 +14276,203 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -440,7 +440,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14325,4 +14521,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14443,4 +14639,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,
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-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch
index 67950bf..84087de 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-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch
@@ -1,7 +1,7 @@
-From 4518e45497260d319663621eca8cea4c0f79b668 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Fix ZWDFS issue in BW 160
+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.
@@ -14,7 +14,7 @@
  1 file changed, 79 insertions(+), 19 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index d52a60e..2f5c86e 100644
+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)
@@ -96,7 +96,7 @@
  }
  
  
-@@ -831,8 +839,12 @@ static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
+@@ -836,8 +844,12 @@ static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
   */
  int hostapd_handle_dfs(struct hostapd_iface *iface)
  {
@@ -110,7 +110,7 @@
  
  	if (is_6ghz_freq(iface->freq))
  		return 1;
-@@ -895,7 +907,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+@@ -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,
@@ -119,7 +119,7 @@
  	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,
-@@ -905,6 +917,16 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+@@ -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);
  
@@ -136,7 +136,7 @@
  	res = hostapd_start_dfs_cac(
  		iface, iface->conf->hw_mode, iface->freq, iface->conf->channel,
  		iface->conf->ieee80211n, iface->conf->ieee80211ac,
-@@ -913,14 +935,14 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+@@ -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),
@@ -153,7 +153,7 @@
  		/* Cache background radar parameters. */
  		iface->radar_background.channel = iface->conf->channel;
  		iface->radar_background.secondary_channel =
-@@ -941,6 +963,35 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+@@ -946,6 +968,35 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
  
  		iface->radar_background.temp_ch = 1;
  		return 1;
@@ -189,7 +189,7 @@
  	}
  
  	return 0;
-@@ -1190,6 +1241,15 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
+@@ -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;
  			}
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-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
index 43905c6..c6c039e 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-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
@@ -1,7 +1,7 @@
-From 014cf359542aeefc995d936ab4843491c4a3b8b6 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add vendor for CAPI certification
+Subject: [PATCH 21/38] hostapd: mtk: Add vendor for CAPI certification
  commands
 
 ---
@@ -167,7 +167,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 136ea23..946ee2d 100644
+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);
@@ -260,10 +260,10 @@
  	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 91cb475..3efea9f 100644
+index 130143e..91aa9b1 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5141,6 +5141,28 @@ struct wpa_driver_ops {
+@@ -5163,6 +5163,28 @@ struct wpa_driver_ops {
  	 *
  	 */
  	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
@@ -293,7 +293,7 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 8b8ddfa..6a42633 100644
+index ee0912f..592435c 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
 @@ -76,6 +76,58 @@ enum nlmsgerr_attrs {
@@ -355,7 +355,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14522,4 +14574,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch
index 90f9965..7808d50 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-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch
@@ -1,7 +1,7 @@
-From 7e2055111b854c61eaa7ad485ebd3bf171b93df5 Mon Sep 17 00:00:00 2001
+From 8fe238bed8756a0015567c41b9c31577755d1015 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/40] hostapd: mtk: Air Monitor support in hostapd by vendor
+Subject: [PATCH 22/38] hostapd: mtk: Air Monitor support in hostapd by vendor
 
 Signed-off-by: mtk23888 <dipanshu.mittal@mediatek.com>
 ---
@@ -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 946ee2d..1e2a92a 100644
+index 32e6fc1..8a97e0f 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
@@ -247,10 +247,10 @@
 +
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 3efea9f..5c70ec7 100644
+index 91aa9b1..8733bb5 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5163,6 +5163,22 @@ struct wpa_driver_ops {
+@@ -5185,6 +5185,22 @@ struct wpa_driver_ops {
  	* @type: trigger type
  	*/
  	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
@@ -274,7 +274,7 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 6a42633..3d8cb95 100644
+index 592435c..c55d034 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] = {
@@ -297,7 +297,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14409,6 +14422,171 @@ fail:
+@@ -14525,6 +14538,171 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -469,7 +469,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14577,4 +14755,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14695,4 +14873,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,
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-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch
index cd30f92..06ceae8 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-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch
@@ -1,7 +1,7 @@
-From a397fa2ee7a72fafbfa5480adfacad75352d7d2a Mon Sep 17 00:00:00 2001
+From be727db37e753f0041b2789af3ecc1eff8c0f5db 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/40] hostapd: mtk: Fix setting wrong seg0 index for 5G
+Subject: [PATCH 23/38] hostapd: mtk: Fix setting wrong seg0 index for 5G
  center chan 159 BW40
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 5b2dbff..b329e81 100644
+index d0e27b2..f03a957 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1305,7 +1305,8 @@ hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf,
+@@ -1308,7 +1308,8 @@ hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf,
  #ifdef CONFIG_IEEE80211BE
  	if (conf->ieee80211be)
  		conf->eht_oper_centr_freq_seg0_idx = oper_centr_freq_seg0_idx;
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-hostapd-mtk-Add-muru-user-number-debug-command.patch
index 95dae39..68d2e5b 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-hostapd-mtk-Add-muru-user-number-debug-command.patch
@@ -1,7 +1,7 @@
-From de53629544ee0f9508554049bc5927ce2f04fcf9 Mon Sep 17 00:00:00 2001
+From 5644beb4dc1a11a236d909d4a8f8ad4aa86c6c34 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/40] hostapd: mtk: Add muru user number debug command
+Subject: [PATCH 24/38] hostapd: mtk: Add muru user number debug command
 
 ---
  hostapd/ctrl_iface.c         | 13 ++++++++++++-
@@ -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 1e2a92a..5dd701e 100644
+index 8a97e0f..464efba 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 24e5df8..25ae08f 100644
+index a166de4..28482c6 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -57,6 +57,7 @@
@@ -133,10 +133,10 @@
 +};
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 5c70ec7..84387a6 100644
+index 8733bb5..a29b6ff 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5096,11 +5096,11 @@ struct wpa_driver_ops {
+@@ -5118,11 +5118,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 3d8cb95..b682620 100644
+index c55d034..fce3ec9 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13562,13 +13562,13 @@ fail:
+@@ -13678,13 +13678,13 @@ fail:
  
  
  #ifdef CONFIG_IEEE80211AX
@@ -170,7 +170,7 @@
  
  	if (!drv->mtk_mu_vendor_cmd_avail) {
  		wpa_printf(MSG_INFO,
-@@ -13579,17 +13579,38 @@ static int nl80211_mu_onoff(void *priv, u8 mu_onoff)
+@@ -13695,17 +13695,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 @@
  }
  
  
-@@ -14731,7 +14752,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14849,7 +14870,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-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch
index 19a3c79..2a2a578 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-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch
@@ -1,7 +1,7 @@
-From 7f1a652729514a0f9a885be30185810c18110c4d Mon Sep 17 00:00:00 2001
+From 033f4f509e60c698d9754057e194f4760af39845 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/40] hostapd: mtk: add connac3 PHY MURU manual mode config
+Subject: [PATCH 25/38] hostapd: mtk: add connac3 PHY MURU manual mode config
  support
 
 This commit supports read the following two formats to set MU/RU manual
@@ -327,10 +327,10 @@
  		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 b329e81..d43f1a6 100644
+index f03a957..7c0d12a 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1200,6 +1200,7 @@ struct hostapd_config {
+@@ -1203,6 +1203,7 @@ struct hostapd_config {
  	u8 ibf_enable;
  	u8 dfs_detect_mode;
  	u8 amsdu;
@@ -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 5dd701e..741fdab 100644
+index 464efba..1e7ae7a 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 25ae08f..0dc86bf 100644
+index 28482c6..3e184b5 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2518,7 +2518,7 @@ dfs_offload:
@@ -567,10 +567,10 @@
 +
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 84387a6..9ec0e96 100644
+index a29b6ff..ebc1d27 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5100,7 +5100,7 @@ struct wpa_driver_ops {
+@@ -5122,7 +5122,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 b682620..22c56f9 100644
+index fce3ec9..25e5910 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13562,12 +13562,13 @@ fail:
+@@ -13678,12 +13678,13 @@ fail:
  
  
  #ifdef CONFIG_IEEE80211AX
@@ -598,7 +598,7 @@
  	int ret = -ENOBUFS;
  
  	if (!drv->mtk_mu_vendor_cmd_avail) {
-@@ -13584,17 +13585,16 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
+@@ -13700,17 +13701,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;
  	}
-@@ -13602,9 +13602,8 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
+@@ -13718,9 +13718,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-hostapd-mtk-Add-HE-capabilities-check.patch
index a93ae69..cc30d42 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-hostapd-mtk-Add-HE-capabilities-check.patch
@@ -1,7 +1,7 @@
-From 963b6800d4416d5a88053097128a33d8bdc8f56b Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add HE capabilities check
+Subject: [PATCH 26/38] hostapd: mtk: Add HE capabilities check
 
 Add HE capabilities check.
 Since "HE capabilities" check has been removed by driver,
@@ -11,10 +11,10 @@
  1 file changed, 26 insertions(+)
 
 diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
-index 828b926..991af2c 100644
+index 9d22725..9a36bcb 100644
 --- a/src/ap/hw_features.c
 +++ b/src/ap/hw_features.c
-@@ -680,6 +680,32 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
+@@ -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)
  {
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-hostapd-mtk-Fix-background-channel-overlapping-opera.patch
index 1134253..0ba1a38 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-hostapd-mtk-Fix-background-channel-overlapping-opera.patch
@@ -1,7 +1,7 @@
-From b79b625e3790f0d9152f736629fbc0dcd826bf62 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Fix background channel overlapping
+Subject: [PATCH 27/38] hostapd: mtk: Fix background channel overlapping
  operating channel issue
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 18 insertions(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 2f5c86e..c9a9c6c 100644
+index 3b1df6d..6f76354 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -807,6 +807,20 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
+@@ -812,6 +812,20 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
  }
  
  
@@ -34,7 +34,7 @@
  static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
  				     int start_chan_idx, int n_chans)
  {
-@@ -1127,6 +1141,8 @@ static void hostpad_dfs_update_background_chain(struct hostapd_iface *iface)
+@@ -1132,6 +1146,8 @@ static void hostpad_dfs_update_background_chain(struct hostapd_iface *iface)
  						  &oper_centr_freq_seg1_idx,
  						  &channel_type);
  	if (!channel ||
@@ -43,7 +43,7 @@
  	    hostapd_start_dfs_cac(iface, iface->conf->hw_mode,
  				  channel->freq, channel->chan,
  				  iface->conf->ieee80211n,
-@@ -1361,6 +1377,7 @@ static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
+@@ -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;
@@ -51,7 +51,7 @@
  
  	hostapd_setup_interface_complete(iface, err);
  	return err;
-@@ -1488,6 +1505,7 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
+@@ -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);
  
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-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch
index b85fdca..57395ca 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-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch
@@ -1,7 +1,7 @@
-From aeabc47685135ee69cdeca5f5753c4057ca0f608 Mon Sep 17 00:00:00 2001
+From 57fd7fc979251fd178175c506e64a724433c8d6d 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/40] hostapd: mtk: Fix hostapd_dfs_start_cac log
+Subject: [PATCH 28/38] hostapd: mtk: Fix hostapd_dfs_start_cac log
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -9,10 +9,10 @@
  1 file changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index c9a9c6c..593a468 100644
+index 6f76354..95119a3 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1650,9 +1650,11 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+@@ -1655,9 +1655,11 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
  	/* TODO: How to check CAC time for ETSI weather channels? */
  	iface->dfs_cac_ms = 60000;
  	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
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-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
index 3d6f958..c247137 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-hostapd-mtk-Check-the-bridge-after-ioctl-SIOCBRADDIF.patch
@@ -1,7 +1,7 @@
-From 1bc32b7308d9460116954f048eca89f02204825c Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
+Subject: [PATCH 29/38] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
  failed
 
 If ioctl returns EBUSY on command SIOCBRADDIF, the interface might
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-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch
index 8073974..50e4e63 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-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch
@@ -1,7 +1,7 @@
-From c6557f76857bc80128d2d02e615ce32de8a0c998 Mon Sep 17 00:00:00 2001
+From 65f2475fbf84a7b71e5dcba2b8f7ae77eee4f36d 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/40] hostapd: mtk: Update parameter_set_count in MU EDCA IE
+Subject: [PATCH 30/38] hostapd: mtk: Update parameter_set_count in MU EDCA IE
 
 without this patch, MU EDCA Parameter update count not equal to
 WMM Parameter set count.
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-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch
index 52deb06..2abbb0b 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-hostapd-mtk-add-extension-IE-list-for-non-inherit-IE.patch
@@ -1,7 +1,7 @@
-From de15bbc394a478d141e416114297213d4e4b027d Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: add extension IE list for non-inherit IE
+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
@@ -19,10 +19,10 @@
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
 old mode 100644
 new mode 100755
-index 1bf5bea..d36798e
+index 110ad8c..e05a06b
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -7639,7 +7639,7 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
+@@ -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)
@@ -31,7 +31,7 @@
  
  		if (len + nontx_profile_len > 255)
  			break;
-@@ -7780,11 +7780,16 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
+@@ -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;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-11vmbss-aid-using-wrong-pool.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-11vmbss-aid-using-wrong-pool.patch
deleted file mode 100644
index 7eb42ad..0000000
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-11vmbss-aid-using-wrong-pool.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From b99fd7f0b86a87fc82d63ec809fd9a73f308dd08 Mon Sep 17 00:00:00 2001
-From: "Allen.Ye" <allen.ye@mediatek.com>
-Date: Wed, 2 Aug 2023 18:33:31 +0800
-Subject: [PATCH 32/40] hostapd: mtk: Fix 11vmbss aid using wrong pool
-
-Fix 11vmbss aid using wrong pool.
-All STAs use the aid pool in transmitted bss.
-
-Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
----
- src/ap/ieee802_11.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index d36798e..f20073c 100755
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -3307,6 +3307,9 @@ int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
- {
- 	int i, j = 32, aid;
- 
-+	if (hapd->iconf->mbssid)
-+		hapd = hostapd_mbssid_get_tx_bss(hapd);
-+
- 	/* get a unique AID */
- 	if (sta->aid > 0) {
- 		wpa_printf(MSG_DEBUG, "  old AID %d", sta->aid);
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
similarity index 78%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
index c9df793..52c74f9 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
@@ -1,7 +1,7 @@
-From ee4aa23d0c87c8fe69f8ba28fe5faf95bf0103d8 Mon Sep 17 00:00:00 2001
+From e9f856156f861845c160538d2d5907bf338fa489 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 33/40] hostapd: mtk: Fix rnr ie length when no need to report
+Subject: [PATCH 32/38] hostapd: mtk: 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,10 +13,10 @@
  1 file changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index f20073c..ef520c8 100755
+index e05a06b..7b6aabb 100755
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -7494,8 +7494,10 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
+@@ -7511,8 +7511,10 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
  		}
  
  		start = i;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
similarity index 91%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
index 80b7589..47e2970 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
@@ -1,7 +1,7 @@
-From 26e0cd2739dc56e02cc7e1b5582220d0fcde795b Mon Sep 17 00:00:00 2001
+From 5b750f3f78cec3b64ebb9bb3b74def424c7d57fd 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 34/40] hostapd: mtk: add back ht vht cap missing field before
+Subject: [PATCH 33/38] hostapd: mtk: 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,7 +22,7 @@
  1 file changed, 7 insertions(+)
 
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 0dc86bf..2283b19 100644
+index 3e184b5..b8ae8de 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -4111,6 +4111,13 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
similarity index 74%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
index 05b2121..5412153 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
@@ -1,7 +1,7 @@
-From ef5f744c72f2e6ec6b7d4ec1ce4f233470ff7689 Mon Sep 17 00:00:00 2001
+From d46e85faec291f813d6b5578122cd267421e84fa 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 35/40] hostapd: mtk: update op_class when AP channel switching
+Subject: [PATCH 34/38] hostapd: mtk: update op_class when AP channel switching
 
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
 ---
@@ -9,10 +9,10 @@
  1 file changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index c3fc419..1911f85 100644
+index e7f1f19..f749b33 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -873,7 +873,7 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
+@@ -1041,7 +1041,7 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
  {
  #ifdef NEED_AP_MLME
  	int channel, chwidth, is_dfs0, is_dfs;
@@ -21,7 +21,7 @@
  	size_t i;
  
  	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
-@@ -995,6 +995,9 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
+@@ -1169,6 +1169,9 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
  		hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
  
  	hapd->iconf->secondary_channel = offset;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
similarity index 90%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
index 3dd5457..4dad332 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
@@ -1,7 +1,7 @@
-From eaff9afb87f172b09eac63237b099f7c4e5def3c Mon Sep 17 00:00:00 2001
+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 36/40] hostapd: mtk: Add support for gtk rekeying in hostapd
+Subject: [PATCH 35/38] hostapd: mtk: Add support for gtk rekeying in hostapd
  cli
 
 Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
similarity index 93%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
index 27beaf7..2b0f254 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
@@ -1,7 +1,7 @@
-From b52a1f04b4a897e88b5a14f61befd71f65cdc062 Mon Sep 17 00:00:00 2001
+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 38/40] hostapd: mtk: Set WMM and TX queue parameters for
+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
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Fix-wpa_supplicant-configuration-parsing.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Fix-wpa_supplicant-configuration-parsing.patch
deleted file mode 100644
index f7f22d8..0000000
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Fix-wpa_supplicant-configuration-parsing.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From a1fd2056b0e3820920778fd9252cec645cbb6389 Mon Sep 17 00:00:00 2001
-From: Michael Lee <michael-cy.lee@mediatek.com>
-Date: Fri, 7 Jul 2023 17:14:40 +0800
-Subject: [PATCH 37/40] hostapd: mtk: Fix wpa_supplicant configuration parsing
- error
-
-In the original flow, after hostapd_config_tx_queue successfully
-parses a tx_queue variable, it would not return immediately. Then it
-would print out "unknow global field" later and set return val to -1.
-
-This patch returns immediately after hostapd_config_tx_queue
-successfully parses a tx_queue variable.
-
-Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
----
- wpa_supplicant/config.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
-index 325ab8d..2652c8a 100644
---- a/wpa_supplicant/config.c
-+++ b/wpa_supplicant/config.c
-@@ -5715,6 +5715,7 @@ int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
- 					   line);
- 				return -1;
- 			}
-+			return ret;
- 		}
- 
- 		if (os_strncmp(pos, "wmm_ac_", 7) == 0) {
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0039-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
similarity index 89%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0039-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
index 9c8c63b..a6a86d8 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0039-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
@@ -1,7 +1,7 @@
-From 55837ad406c9af8a398d6073809151f7a3779b74 Mon Sep 17 00:00:00 2001
+From 33cbd77949640d337e4e39d462bbb6b575792de3 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 39/40] hostapd: mtk: Set STA TX queue parameters configuration
+Subject: [PATCH 37/38] hostapd: mtk: 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 48953c1..0699689 100644
+index dcf5764..36ff854 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,10 +40,10 @@
  				    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 03442f5..5eb5248 100644
+index 3b8596d..f5ac62e 100644
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
-@@ -3557,6 +3557,20 @@ out:
+@@ -3559,6 +3559,20 @@ out:
  	return wpa_sm_set_mlo_params(wpa_s->wpa, &wpa_mlo);
  }
  
@@ -64,7 +64,7 @@
  
  static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
  				       union wpa_event_data *data)
-@@ -3884,6 +3898,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
+@@ -3886,6 +3900,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
  
  	if (wpa_s->current_ssid && wpa_s->current_ssid->enable_4addr_mode)
  		wpa_supplicant_set_4addr_mode(wpa_s);
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0040-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
similarity index 79%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0040-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
index d31b6c2..e076eae 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0040-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
@@ -1,7 +1,7 @@
-From 100dae9224afa0c9dbd1117ab97b60e427657afc Mon Sep 17 00:00:00 2001
+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 40/40] hostapd: mtk: avoid color switch when beacon is not set
+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>
 ---
@@ -9,7 +9,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 2283b19..6d86993 100644
+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)
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-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
new file mode 100644
index 0000000..105e188
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
@@ -0,0 +1,29 @@
+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/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-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
new file mode 100644
index 0000000..1695996
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
@@ -0,0 +1,85 @@
+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-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch
new file mode 100644
index 0000000..f02f935
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch
@@ -0,0 +1,168 @@
+From 92caaf40a058d4eac8061c0e3240f0b23aba69ce 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
+
+This patch changes the flow to create Wide Bandwidth Channel Switch IE:
+1. 2 GHz: Wide Bandwidth Channel Switch IE should not present.
+2. 5 GHz: fill the subfields according to VHT operation.
+3. 6 GHz: fill the subfields according to VHT operation and HE operation
+   in HE mode and EHT mode, respectively.
+   This is because the definition of the subfields of Wide Bandwidth
+   Channel Switch IE is ambiguous:
+   1. 802.11ac: the definition of subfields follows VHT operation
+      (IEEE80211-2020 9.4.2.160)
+   2. 802.11ax: the definition of subfields is not specified
+   3. 802.11be: the definition of subfields follows VHT operation in 5
+      GHz and HE operation in 6 GHz (IEEE P802.11be D3.2 9.4.2.159)
+
+To support 320 MHz
+   channel switch, set width to 4
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ src/ap/ieee802_11.c | 99 ++++++++++++++++++++++++++++++++++-----------
+ 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
+--- 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)
+ 
+ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
+ {
+-	u8 bw, chan1, chan2 = 0;
+-	int freq1;
++	u8 new_bw_field, ccfs0_chan, ccfs1_chan = 0;
++	int ccfs0_freq = 0, ccfs1_freq = 0;
++	int control_freq, center_freq1, center_freq2, bandwidth;
++	int base_freq, offset;
++	bool is_6ghz, use_he_oper;
+ 
+ 	if (!hapd->cs_freq_params.channel ||
++	    hapd->cs_freq_params.bandwidth == 20 ||
+ 	    (!hapd->cs_freq_params.vht_enabled &&
+ 	     !hapd->cs_freq_params.he_enabled &&
+ 	     !hapd->cs_freq_params.eht_enabled))
+ 		return eid;
+ 
+-	/* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80, 4: 320 */
+-	switch (hapd->cs_freq_params.bandwidth) {
++	control_freq = hapd->cs_freq_params.freq;
++	center_freq1 = hapd->cs_freq_params.center_freq1;
++	center_freq2 = hapd->cs_freq_params.center_freq2;
++	bandwidth = hapd->cs_freq_params.bandwidth;
++
++	/* center_freq2 is used if and only if bandwidth is
++	 * 80+80 MHz and phy mode is not EHT
++	 */
++	if (center_freq2 &&
++	    (bandwidth != 80 || hapd->cs_freq_params.eht_enabled))
++		return eid;
++
++	is_6ghz = is_6ghz_freq(control_freq);
++	use_he_oper = is_6ghz && hapd->cs_freq_params.eht_enabled;
++	base_freq = is_6ghz ? 5955 : 5180;
++
++	/* About the subfields of the Wide Bandwidth Channel Switch IE,
++	 * IEEE802.11-2020 9.4.2.160 specifies that the subfields New
++	 * Channel Width, New Channel Center Frequency Segment 0 and New
++	 * Channel Center Frequency Segment 1 have the same definition as
++	 * they are in the VHT operation information field.
++	 * However, the standard does not specify the definition of these
++	 * subfields when it comes to HE phy-mode in 6 GHz.
++	 * And in IEEE P802.11be D3.2 9.4.2.159, it specifies that the
++	 * defition should follow VHT operation in 5 GHz, and follow HE
++	 * oepration in 6 GHz.
++	 * Problem happens here for some HE STAs in 6 GHz, they might still
++	 * use VHT operation to parse these subfields.
++	 *
++	 * Here we follow the new Standard to build the IE, meanwhile we have
++	 * a workaround for HE mode in 6 GHz.
++	 *
++	 * 5 GHz: VHT operation
++	 * HE mode in 6 GHz: VHT operation
++	 * EHT mode in 6 GHz: HE operation
++	 */
++	ccfs0_freq = center_freq1;
++	ccfs1_freq = center_freq2;
++	switch (bandwidth) {
+ 	case 40:
+-		bw = 0;
++		new_bw_field = use_he_oper ? 1 : 0;
+ 		break;
+ 	case 80:
+-		/* check if it's 80+80 */
+-		if (!hapd->cs_freq_params.center_freq2)
+-			bw = 1;
++		if (ccfs1_freq)
++			new_bw_field = use_he_oper ? 3 : 1;
+ 		else
+-			bw = 3;
++			new_bw_field = use_he_oper ? 2 : 1;
+ 		break;
+ 	case 160:
+-		bw = 2;
++		new_bw_field = use_he_oper ? 3 : 1;
++
++		/* ccfs0 is primary 80 MHz
++		 * ccfs1 is center frequency
++		 */
++		offset = (control_freq - base_freq) / 20;
++		ccfs0_freq = control_freq + 30 - (offset & 3) * 20;
++		ccfs1_freq = center_freq1;
+ 		break;
+ 	case 320:
+-		bw = 4;
++		/* TODO switch to bandwidth 320 MHz should be
++		 * indicated by Bandwidth indication IE.
++		 */
++		new_bw_field = 4;
++
++		/* ccfs0 is primary 160 MHz
++		 * ccfs1 is center frequency
++		 */
++		offset = (control_freq - base_freq) / 20;
++		ccfs0_freq = control_freq + 70 - (offset & 7) * 20;
++		ccfs1_freq = center_freq1;
+ 		break;
+ 	default:
+-		/* not valid VHT bandwidth or not in CSA */
++		/* not a valid VHT/HE bandwidth or not in CSA */
+ 		return eid;
+ 	}
+ 
+-	freq1 = hapd->cs_freq_params.center_freq1 ?
+-		hapd->cs_freq_params.center_freq1 :
+-		hapd->cs_freq_params.freq;
+-	if (ieee80211_freq_to_chan(freq1, &chan1) !=
+-	    HOSTAPD_MODE_IEEE80211A)
++	if (ieee80211_freq_to_chan(ccfs0_freq, &ccfs0_chan) !=
++			HOSTAPD_MODE_IEEE80211A)
+ 		return eid;
+ 
+-	if (hapd->cs_freq_params.center_freq2 &&
+-	    ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2,
+-				   &chan2) != HOSTAPD_MODE_IEEE80211A)
++	if (ccfs1_freq && ieee80211_freq_to_chan(ccfs1_freq, &ccfs1_chan) !=
++			HOSTAPD_MODE_IEEE80211A)
+ 		return eid;
+ 
+ 	*eid++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER;
+ 	*eid++ = 5; /* Length of Channel Switch Wrapper */
+ 	*eid++ = WLAN_EID_WIDE_BW_CHSWITCH;
+ 	*eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */
+-	*eid++ = bw; /* New Channel Width */
+-	*eid++ = chan1; /* New Channel Center Frequency Segment 0 */
+-	*eid++ = chan2; /* New Channel Center Frequency Segment 1 */
++	*eid++ = new_bw_field; /* New Channel Width */
++	*eid++ = ccfs0_chan; /* New Channel Center Frequency Segment 0 */
++	*eid++ = ccfs1_chan; /* New Channel Center Frequency Segment 1 */
+ 
+ 	return eid;
+ }
+-- 
+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/hostapd/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
new file mode 100755
index 0000000..b699fc5
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
@@ -0,0 +1,96 @@
+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/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-1001-hostapd-mtk-update-eht-operation-element.patch
index e2c6d87..5092a61 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-1001-hostapd-mtk-update-eht-operation-element.patch
@@ -1,7 +1,7 @@
-From 3b4b9812c97b0b75579829c96a19e8a8cc0bfa7b Mon Sep 17 00:00:00 2001
+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/1004] hostapd: mtk: update eht operation element
+Subject: [PATCH 1001/1005] hostapd: mtk: update eht operation element
 
 ---
  src/ap/ieee802_11_eht.c | 6 +++---
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-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch
index 1b51a28..9c23287 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-1002-hostapd-mtk-ucode-add-support-for-ucode-to-parse-BW3.patch
@@ -1,7 +1,7 @@
-From 5ed678c7562b1acf04f1b6c63ab25a5f3043325f Mon Sep 17 00:00:00 2001
+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/1004] hostapd: mtk: ucode: add support for ucode to parse
+Subject: [PATCH 1002/1005] hostapd: mtk: ucode: add support for ucode to parse
  BW320MHz info
 
 ---
@@ -9,7 +9,7 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/src/utils/ucode.c b/src/utils/ucode.c
-index 896ef46..4448738 100644
+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)
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-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch
index 74c685b..5a63279 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-1003-hostapd-mtk-synchronize-bandwidth-in-AP-STA-support.patch
@@ -1,61 +1,279 @@
-From 25b1c0f5e4f674ea2b72949bce83c05204d19653 Mon Sep 17 00:00:00 2001
+From 804f9b03e7f143d3a80741cb67721810e27ed2d8 Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
-Date: Thu, 24 Aug 2023 16:44:30 +0800
+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/utils/ucode.c      |  1 +
- wpa_supplicant/ucode.c | 10 ++++++++++
- 2 files changed, 11 insertions(+)
+ 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 44169f0..41c19fb 100644
+index 122c619..0990e7b 100644
 --- a/src/utils/ucode.c
 +++ b/src/utils/ucode.c
-@@ -115,6 +115,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -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 (!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 d0a78d1..dbf57fa 100644
+index 6cba73d..d5489ea 100644
 --- a/wpa_supplicant/ucode.c
 +++ b/wpa_supplicant/ucode.c
-@@ -6,6 +6,7 @@
+@@ -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;
-@@ -194,6 +195,9 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
+@@ -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;
-@@ -222,6 +226,12 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
- 
- 		ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan));
- 		ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq));
+@@ -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);
-+		ieee80211_chaninfo_to_channel(ci.frequency, ci.chanwidth,
-+					      sec_chan, &op_class, &channel);
++		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));
  	}
  
- 	return ret;
+ #ifdef CONFIG_MESH
 -- 
 2.25.1
 
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-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
new file mode 100644
index 0000000..23aa563
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
@@ -0,0 +1,339 @@
+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/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-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
new file mode 100644
index 0000000..fcfd0bf
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
@@ -0,0 +1,278 @@
+From 5bcd4472062750b192c98d944b74e07b14ab3af5 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
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ hostapd/config_file.c             |  2 ++
+ hostapd/ctrl_iface.c              | 30 +++++++++++++++++++++++++++
+ src/ap/ap_config.h                |  6 ++++++
+ src/ap/ap_drv_ops.c               | 14 +++++++++++++
+ src/ap/dfs.c                      |  6 ++++++
+ 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 +++
+ 10 files changed, 115 insertions(+)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index 9e3dbb2..a751993 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -3183,6 +3183,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 		conf->acs_exclude_6ghz_non_psc = atoi(pos);
+ 	} else if (os_strcmp(buf, "enable_background_radar") == 0) {
+ 		conf->enable_background_radar = atoi(pos);
++	} else if (os_strcmp(buf, "background_radar_mode") == 0) {
++		conf->background_radar_mode = atoi(pos);
+ 	} else if (os_strcmp(buf, "min_tx_power") == 0) {
+ 		int val = atoi(pos);
+ 
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index c288352..517ebd6 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,
+ 		return pos - buf;
+ }
+ 
++static int
++hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cmd,
++					     char *buf, size_t buflen)
++{
++	struct hostapd_iface *iface = hapd->iface;
++	char *pos, *param;
++
++	param = os_strchr(cmd, ' ');
++	if (!param)
++		return -1;
++	*param++ = '\0';
++
++	pos = os_strstr(param, "mode=");
++	if (!pos)
++		return -1;
++
++	if (os_strncmp(pos + 5, "cert", 4) == 0)
++		iface->conf->background_radar_mode = BACKGROUND_RADAR_CERT_MODE;
++	else if (os_strncmp(pos + 5, "normal", 6) == 0)
++		iface->conf->background_radar_mode = BACKGROUND_RADAR_NORMAL_MODE;
++
++	if (hostapd_drv_background_radar_mode(hapd) < 0)
++		return -1;
++
++	return os_snprintf(buf, buflen, "OK\n");
++}
++
+ 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,
+ 		if (pos)
+ 			*pos = ' ';
+ 		reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 23, reply, reply_size);
++	} 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 {
+ 		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
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -1025,6 +1025,7 @@ struct hostapd_config {
+ 	bool hw_mode_set;
+ 	int acs_exclude_6ghz_non_psc;
+ 	int enable_background_radar;
++	int background_radar_mode;
+ 	enum {
+ 		LONG_PREAMBLE = 0,
+ 		SHORT_PREAMBLE = 1
+@@ -1218,6 +1219,11 @@ enum three_wire_mode {
+ 		NUM_THREE_WIRE_MODE - 1
+ };
+ 
++enum background_radar_mode {
++	BACKGROUND_RADAR_NORMAL_MODE,
++	BACKGROUND_RADAR_CERT_MODE,
++};
++
+ enum dfs_mode {
+ 	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
+--- 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_
+ 		return 0;
+ 	return hapd->driver->amnt_dump(hapd->drv_priv, amnt_idx, amnt_dump_buf);
+ }
++
++int hostapd_drv_background_radar_mode(struct hostapd_data *hapd)
++{
++	if (!hapd->driver || !hapd->driver->background_radar_mode ||
++	    !(hapd->iface->drv_flags2 & WPA_DRIVER_RADAR_BACKGROUND) ||
++	    !hapd->iface->conf->enable_background_radar)
++		return 0;
++	if (hapd->iconf->background_radar_mode > BACKGROUND_RADAR_CERT_MODE) {
++		wpa_printf(MSG_INFO, "Invalid value for background radar mode\n");
++		return 0;
++	}
++	return hapd->driver->background_radar_mode(hapd->drv_priv,
++						   hapd->iconf->background_radar_mode);
++}
+diff --git a/src/ap/dfs.c b/src/ap/dfs.c
+index 008596b..2564168 100644
+--- a/src/ap/dfs.c
++++ b/src/ap/dfs.c
+@@ -983,6 +983,9 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+ 		if (res < 0)
+ 			return res;
+ 
++		if (hostapd_drv_background_radar_mode(iface->bss[0]) < 0)
++			return -1;
++
+ 		iface->radar_background.temp_ch = 1;
+ 		return 1;
+ 	} else if (dfs_use_radar_background(iface)) {
+@@ -1023,6 +1026,9 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+ 		iface->radar_background.secondary_channel = sec;
+ 		iface->radar_background.centr_freq_seg0_idx = cf1;
+ 		iface->radar_background.centr_freq_seg1_idx = cf2;
++
++		if (hostapd_drv_background_radar_mode(iface->bss[0]) < 0)
++			return -1;
+ 	}
+ 
+ 	return 0;
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index e140de6..5bc1e04 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -16,6 +16,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 {
+@@ -244,6 +245,17 @@ enum mtk_vendor_attr_bss_color_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL - 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
++};
++
+ #define CSI_MAX_COUNT 256
+ #define ETH_ALEN 6
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index a9f48a1..bc82d28 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -5201,6 +5201,13 @@ struct wpa_driver_ops {
+ 	* @amnt_dump_buf: Buffer to print
+ 	*/
+ 	int (*amnt_dump)(void *priv, u8 amnt_idx, u8 *amnt_dump_buf);
++
++	/**
++	 * background_radar_mode - set background radar mode
++	 * @priv: Private driver interface data
++	 * @background_radar_mode: background radar mode
++	 */
++	int (*background_radar_mode)(void *priv, u8 background_radar_mode);
+ };
+ 
+ /**
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index 25e5910..73401fd 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -14723,6 +14723,39 @@ fail:
+ 	return -ENOBUFS;
+ }
+ 
++static int nl80211_background_radar_mode(void *priv, const u8 background_radar_mode)
++{
++	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_background_radar_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting background radar mode");
++		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_BACKGROUND_RADAR_CTRL) ||
++	    !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
++	    nla_put_u8(msg, MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MODE, background_radar_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 background radar mode. ret=%d (%s) ",
++			   ret, strerror(-ret));
++	}
++	return ret;
++}
++
+ 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 = {
+ 	.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
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -210,6 +210,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_bss_color_vendor_cmd_avail:1;
+ 	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;
+ 
+ 	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
+--- 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)
+ 				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
+ 					drv->mtk_rfeatures_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL:
++					drv->mtk_background_radar_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
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-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
new file mode 100644
index 0000000..4178b68
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
@@ -0,0 +1,374 @@
+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/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-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
new file mode 100644
index 0000000..d2b117c
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
@@ -0,0 +1,431 @@
+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/hostapd/files/patches-2.10.3/patches.inc b/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
index 02810bf..4c214c1 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
@@ -16,7 +16,10 @@
     file://150-add-NULL-checks-encountered-during-tests-hwsim.patch \
     file://160-dpp_pkex-EC-point-mul-w-value-prime.patch \
     file://170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch \
-    file://180-BSS-coloring-fix-CCA-with-multiple-BSS.patch \
+    file://180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch \
+    file://181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch \
+    file://182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch \
+    file://183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch \
     file://200-multicall.patch \
     file://300-noscan.patch \
     file://301-mesh-noscan.patch \
@@ -88,16 +91,22 @@
     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-11vmbss-aid-using-wrong-pool.patch \
-    file://mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch \
-    file://mtk-0034-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch \
-    file://mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch \
-    file://mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch \
-    file://mtk-0037-hostapd-mtk-Fix-wpa_supplicant-configuration-parsing.patch \
-    file://mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch \
-    file://mtk-0039-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch \
-    file://mtk-0040-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.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 \
     "
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch b/recipes-wifi/hostapd/files/patches/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
new file mode 100644
index 0000000..105e188
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
@@ -0,0 +1,29 @@
+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/hostapd/files/patches/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch b/recipes-wifi/hostapd/files/patches/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
new file mode 100644
index 0000000..277f5fa
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
@@ -0,0 +1,85 @@
+From 401cb8a661c5e7d796a17bb289209663a6c42741 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 c67d08b..02f4f87 100644
+--- a/src/ap/beacon.c
++++ b/src/ap/beacon.c
+@@ -2098,6 +2098,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;
+@@ -2121,7 +2127,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
+ 		if (colocated == iface || !colocated || !colocated->conf)
+ 			continue;
+ 
+-		if (is_6g == is_6ghz_op_class(colocated->conf->op_class))
++		if (!is_6g || is_6ghz_op_class(colocated->conf->op_class))
+ 			continue;
+ 
+ 		for (i = 0; i < colocated->num_bss; i++) {
+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 78fd9d8..9e247da 100644
+--- a/src/ap/bss_load.c
++++ b/src/ap/bss_load.c
+@@ -58,7 +58,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 (hapd->conf->chan_util_avg_period) {
+ 		iface->chan_util_samples_sum += iface->channel_utilization;
+-- 
+2.25.1
+
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch b/recipes-wifi/hostapd/files/patches/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
new file mode 100755
index 0000000..2ad19e1
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
@@ -0,0 +1,96 @@
+From 6b4c9657caeafecd1fc5c796327c5e6689ef1f24 Mon Sep 17 00:00:00 2001
+From: "fancy.liu" <fancy.liu@mediatek.com>
+Date: Sun, 8 Oct 2023 15:16:55 +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 bf5eeb7..89594ec 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -1119,6 +1119,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
+ {
+ 	int ret;
+ 	char *pos, *end;
++	int i;
+ 
+ 	pos = buf;
+ 	end = buf + buflen;
+@@ -1290,6 +1291,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/hostapd/files/patches/patches.inc b/recipes-wifi/hostapd/files/patches/patches.inc
index 34e183e..0574840 100644
--- a/recipes-wifi/hostapd/files/patches/patches.inc
+++ b/recipes-wifi/hostapd/files/patches/patches.inc
@@ -103,4 +103,7 @@
     file://mtk-0037-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch \
     file://mtk-0038-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch \
     file://mtk-0039-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-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch \
     "
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 0326f6f..af97091 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
@@ -8,6 +8,7 @@
 #include "hw_features.h"
 #include "ap_drv_ops.h"
 #include "dfs.h"
+#include "acs.h"
 #include <libubox/uloop.h>
 
 static uc_resource_type_t *global_type, *bss_type, *iface_type;
@@ -110,6 +111,94 @@
 	return NULL;
 }
 
+static struct hostapd_vlan *
+bss_conf_find_vlan(struct hostapd_bss_config *bss, int id)
+{
+	struct hostapd_vlan *vlan;
+
+	for (vlan = bss->vlan; vlan; vlan = vlan->next)
+		if (vlan->vlan_id == id)
+			return vlan;
+
+	return NULL;
+}
+
+static int
+bss_conf_rename_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
+		     const char *ifname)
+{
+	if (!strcmp(ifname, vlan->ifname))
+		return 0;
+
+	hostapd_drv_if_rename(hapd, WPA_IF_AP_VLAN, vlan->ifname, ifname);
+	os_strlcpy(vlan->ifname, ifname, sizeof(vlan->ifname));
+
+	return 0;
+}
+
+static int
+bss_reload_vlans(struct hostapd_data *hapd, struct hostapd_bss_config *bss)
+{
+	struct hostapd_bss_config *old_bss = hapd->conf;
+	struct hostapd_vlan *vlan, *vlan_new, *wildcard;
+	char ifname[IFNAMSIZ + 1], vlan_ifname[IFNAMSIZ + 1], *pos;
+	int ret;
+
+	vlan = bss_conf_find_vlan(old_bss, VLAN_ID_WILDCARD);
+	wildcard = bss_conf_find_vlan(bss, VLAN_ID_WILDCARD);
+	if (!!vlan != !!wildcard)
+		return -1;
+
+	if (vlan && wildcard && strcmp(vlan->ifname, wildcard->ifname) != 0)
+		strcpy(vlan->ifname, wildcard->ifname);
+	else
+		wildcard = NULL;
+
+	for (vlan = bss->vlan; vlan; vlan = vlan->next) {
+		if (vlan->vlan_id == VLAN_ID_WILDCARD ||
+		    vlan->dynamic_vlan > 0)
+			continue;
+
+		if (!bss_conf_find_vlan(old_bss, vlan->vlan_id))
+			return -1;
+	}
+
+	for (vlan = old_bss->vlan; vlan; vlan = vlan->next) {
+		if (vlan->vlan_id == VLAN_ID_WILDCARD)
+			continue;
+
+		if (vlan->dynamic_vlan == 0) {
+			vlan_new = bss_conf_find_vlan(bss, vlan->vlan_id);
+			if (!vlan_new)
+				return -1;
+
+			if (bss_conf_rename_vlan(hapd, vlan, vlan_new->ifname))
+				return -1;
+
+			continue;
+		}
+
+		if (!wildcard)
+			continue;
+
+		os_strlcpy(ifname, wildcard->ifname, sizeof(ifname));
+		pos = os_strchr(ifname, '#');
+		if (!pos)
+			return -1;
+
+		*pos++ = '\0';
+		ret = os_snprintf(vlan_ifname, sizeof(vlan_ifname), "%s%d%s",
+				  ifname, vlan->vlan_id, pos);
+	        if (os_snprintf_error(sizeof(vlan_ifname), ret))
+			return -1;
+
+		if (bss_conf_rename_vlan(hapd, vlan, vlan_ifname))
+			return -1;
+	}
+
+	return 0;
+}
+
 static uc_value_t *
 uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
 {
@@ -119,6 +208,7 @@
 	struct hostapd_config *conf;
 	uc_value_t *file = uc_fn_arg(0);
 	uc_value_t *index = uc_fn_arg(1);
+	uc_value_t *files_only = uc_fn_arg(2);
 	unsigned int i, idx = 0;
 	int ret = -1;
 
@@ -130,9 +220,28 @@
 
 	iface = hapd->iface;
 	conf = interfaces->config_read_cb(ucv_string_get(file));
-	if (!conf || idx > conf->num_bss || !conf->bss[idx])
+	if (!conf)
 		goto out;
 
+	if (idx > conf->num_bss || !conf->bss[idx])
+		goto free;
+
+	if (ucv_boolean_get(files_only)) {
+		struct hostapd_bss_config *bss = conf->bss[idx];
+		struct hostapd_bss_config *old_bss = hapd->conf;
+
+#define swap_field(name)				\
+	do {								\
+		void *ptr = old_bss->name;		\
+		old_bss->name = bss->name;		\
+		bss->name = ptr;				\
+	} while (0)
+
+		swap_field(ssid.wpa_psk_file);
+		ret = bss_reload_vlans(hapd, bss);
+		goto done;
+	}
+
 	hostapd_bss_deinit_no_free(hapd);
 	hostapd_drv_stop_ap(hapd);
 	hostapd_free_hapd_data(hapd);
@@ -143,12 +252,14 @@
 			iface->conf->bss[i] = conf->bss[idx];
 	hapd->conf = conf->bss[idx];
 	conf->bss[idx] = old_bss;
-	hostapd_config_free(conf);
 
-	hostapd_setup_bss(hapd, hapd == iface->bss[0], !iface->conf->mbssid);
+	hostapd_setup_bss(hapd, hapd == iface->bss[0], true);
+	hostapd_ucode_update_interfaces();
 
+done:
 	ret = 0;
-
+free:
+	hostapd_config_free(conf);
 out:
 	return ucv_int64_new(ret);
 }
@@ -179,10 +290,15 @@
 	struct hostapd_iface *iface;
 	int i, idx;
 
-	if (!hapd || hapd == hapd->iface->bss[0])
+	if (!hapd)
 		return NULL;
 
 	iface = hapd->iface;
+	if (iface->num_bss == 1) {
+		wpa_printf(MSG_ERROR, "trying to delete last bss of an iface: %s\n", hapd->conf->iface);
+		return NULL;
+	}
+
 	for (idx = 0; idx < iface->num_bss; idx++)
 		if (iface->bss[idx] == hapd)
 			break;
@@ -192,8 +308,13 @@
 
 	for (i = idx + 1; i < iface->num_bss; i++)
 		iface->bss[i - 1] = iface->bss[i];
+
 	iface->num_bss--;
 
+	iface->bss[0]->interface_added = 0;
+	hostapd_drv_set_first_bss(iface->bss[0]);
+	hapd->interface_added = 1;
+
 	hostapd_drv_stop_ap(hapd);
 	hostapd_bss_deinit(hapd);
 	hostapd_remove_iface_bss_conf(iface->conf, hapd->conf);
@@ -268,6 +389,58 @@
 }
 
 static uc_value_t *
+uc_hostapd_iface_set_bss_order(uc_vm_t *vm, size_t nargs)
+{
+	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
+	uc_value_t *bss_list = uc_fn_arg(0);
+	struct hostapd_data **new_bss;
+	struct hostapd_bss_config **new_conf;
+
+	if (!iface)
+		return NULL;
+
+	if (ucv_type(bss_list) != UC_ARRAY ||
+	    ucv_array_length(bss_list) != iface->num_bss)
+		return NULL;
+
+	new_bss = calloc(iface->num_bss, sizeof(*new_bss));
+	new_conf = calloc(iface->num_bss, sizeof(*new_conf));
+	for (size_t i = 0; i < iface->num_bss; i++) {
+		struct hostapd_data *bss;
+
+		bss = ucv_resource_data(ucv_array_get(bss_list, i), "hostapd.bss");
+		if (bss->iface != iface)
+			goto free;
+
+		for (size_t k = 0; k < i; k++)
+			if (new_bss[k] == bss)
+				goto free;
+
+		new_bss[i] = bss;
+		new_conf[i] = bss->conf;
+	}
+
+	new_bss[0]->interface_added = 0;
+	for (size_t i = 1; i < iface->num_bss; i++)
+		new_bss[i]->interface_added = 1;
+
+	free(iface->bss);
+	iface->bss = new_bss;
+
+	free(iface->conf->bss);
+	iface->conf->bss = new_conf;
+	iface->conf->num_bss = iface->num_bss;
+	hostapd_drv_set_first_bss(iface->bss[0]);
+
+	return ucv_boolean_new(true);
+
+free:
+	free(new_bss);
+	free(new_conf);
+	return NULL;
+}
+
+static uc_value_t *
 uc_hostapd_bss_ctrl(uc_vm_t *vm, size_t nargs)
 {
 	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
@@ -292,18 +465,44 @@
 	return ucv_string_new_length(reply, reply_len);
 }
 
+static void
+uc_hostapd_disable_iface(struct hostapd_iface *iface)
+{
+	switch (iface->state) {
+	case HAPD_IFACE_DISABLED:
+		break;
+#ifdef CONFIG_ACS
+	case HAPD_IFACE_ACS:
+		acs_cleanup(iface);
+		iface->scan_cb = NULL;
+		/* fallthrough */
+#endif
+	default:
+		hostapd_disable_iface(iface);
+		break;
+	}
+}
+
 static uc_value_t *
 uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs)
 {
 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
 	int i;
 
+	if (!iface)
+		return NULL;
+
+	if (iface->state != HAPD_IFACE_ENABLED)
+		uc_hostapd_disable_iface(iface);
+
 	for (i = 0; i < iface->num_bss; i++) {
 		struct hostapd_data *hapd = iface->bss[i];
 
 		hostapd_drv_stop_ap(hapd);
-		hapd->started = 0;
+		hapd->beacon_set_done = 0;
 	}
+
+	return NULL;
 }
 
 static uc_value_t *
@@ -312,27 +511,37 @@
 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
 	uc_value_t *info = uc_fn_arg(0);
 	struct hostapd_config *conf;
+	bool changed = false;
 	uint64_t intval;
 	int i;
 
 	if (!iface)
 		return NULL;
 
-	if (!info)
+	if (!info) {
+		iface->freq = 0;
 		goto out;
+	}
 
 	if (ucv_type(info) != UC_OBJECT)
 		return NULL;
 
+#define UPDATE_VAL(field, name)							\
+	if ((intval = ucv_int64_get(ucv_object_get(info, name, NULL))) &&	\
+		!errno && intval != conf->field) do {				\
+		conf->field = intval;						\
+		changed = true;							\
+	} while(0)
+
 	conf = iface->conf;
-	if ((intval = ucv_int64_get(ucv_object_get(info, "op_class", NULL))) &&	!errno)
-		conf->op_class = intval;
-	if ((intval = ucv_int64_get(ucv_object_get(info, "hw_mode", NULL))) && !errno)
-		conf->hw_mode = intval;
-	if ((intval = ucv_int64_get(ucv_object_get(info, "channel", NULL))) && !errno)
-		conf->channel = intval;
-	if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno)
-		conf->secondary_channel = intval;
+	UPDATE_VAL(op_class, "op_class");
+	UPDATE_VAL(hw_mode, "hw_mode");
+	UPDATE_VAL(channel, "channel");
+	UPDATE_VAL(secondary_channel, "sec_channel");
+	if (!changed &&
+	    (iface->bss[0]->beacon_set_done ||
+	     iface->state == HAPD_IFACE_DFS))
+		return ucv_boolean_new(true);
 
 	intval = ucv_int64_get(ucv_object_get(info, "center_seg0_idx", NULL));
 	if (!errno)
@@ -346,13 +555,30 @@
 	if (!errno)
 		hostapd_set_oper_chwidth(conf, intval);
 
+	intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL));
+	if (!errno)
+		iface->freq = intval;
+	else
+		iface->freq = 0;
+	conf->acs = 0;
+
 out:
-	if (conf->channel)
+	switch (iface->state) {
+	case HAPD_IFACE_ENABLED:
+		if (!hostapd_is_dfs_required(iface) ||
+			hostapd_is_dfs_chan_available(iface))
+			break;
+		wpa_printf(MSG_INFO, "DFS CAC required on new channel, restart interface");
+		/* fallthrough */
+	default:
+		uc_hostapd_disable_iface(iface);
+		break;
+	}
+
+	if (conf->channel && !iface->freq)
 		iface->freq = hostapd_hw_get_freq(iface->bss[0], conf->channel);
 
-	if (hostapd_is_dfs_required(iface) && !hostapd_is_dfs_chan_available(iface)) {
-		wpa_printf(MSG_INFO, "DFS CAC required on new channel, restart interface");
-		hostapd_disable_iface(iface);
+	if (iface->state != HAPD_IFACE_ENABLED) {
 		hostapd_enable_iface(iface);
 		return ucv_boolean_new(true);
 	}
@@ -361,7 +587,6 @@
 		struct hostapd_data *hapd = iface->bss[i];
 		int ret;
 
-		hapd->started = 1;
 		hapd->conf->start_disabled = 0;
 		hostapd_set_freq(hapd, conf->hw_mode, iface->freq,
 				 conf->channel,
@@ -428,6 +653,55 @@
 	return ucv_boolean_new(!ret);
 }
 
+static uc_value_t *
+uc_hostapd_bss_rename(uc_vm_t *vm, size_t nargs)
+{
+	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
+	uc_value_t *ifname_arg = uc_fn_arg(0);
+	char prev_ifname[IFNAMSIZ + 1];
+	struct sta_info *sta;
+	const char *ifname;
+	int ret;
+
+	if (!hapd || ucv_type(ifname_arg) != UC_STRING)
+		return NULL;
+
+	os_strlcpy(prev_ifname, hapd->conf->iface, sizeof(prev_ifname));
+	ifname = ucv_string_get(ifname_arg);
+
+	hostapd_ubus_free_bss(hapd);
+	if (interfaces->ctrl_iface_deinit)
+		interfaces->ctrl_iface_deinit(hapd);
+
+	ret = hostapd_drv_if_rename(hapd, WPA_IF_AP_BSS, NULL, ifname);
+	if (ret)
+		goto out;
+
+	for (sta = hapd->sta_list; sta; sta = sta->next) {
+		char cur_name[IFNAMSIZ + 1], new_name[IFNAMSIZ + 1];
+
+		if (!(sta->flags & WLAN_STA_WDS) || sta->pending_wds_enable)
+			continue;
+
+		snprintf(cur_name, sizeof(cur_name), "%s.sta%d", prev_ifname, sta->aid);
+		snprintf(new_name, sizeof(new_name), "%s.sta%d", ifname, sta->aid);
+		hostapd_drv_if_rename(hapd, WPA_IF_AP_VLAN, cur_name, new_name);
+	}
+
+	if (!strncmp(hapd->conf->ssid.vlan, hapd->conf->iface, sizeof(hapd->conf->ssid.vlan)))
+		os_strlcpy(hapd->conf->ssid.vlan, ifname, sizeof(hapd->conf->ssid.vlan));
+	os_strlcpy(hapd->conf->iface, ifname, sizeof(hapd->conf->iface));
+	hostapd_ubus_add_bss(hapd);
+
+	hostapd_ucode_update_interfaces();
+out:
+	if (interfaces->ctrl_iface_init)
+		interfaces->ctrl_iface_init(hapd);
+
+	return ret ? NULL : ucv_boolean_new(true);
+}
+
+
 int hostapd_ucode_init(struct hapd_interfaces *ifaces)
 {
 	static const uc_function_list_t global_fns[] = {
@@ -441,9 +715,11 @@
 	static const uc_function_list_t bss_fns[] = {
 		{ "ctrl", uc_hostapd_bss_ctrl },
 		{ "set_config", uc_hostapd_bss_set_config },
+		{ "rename", uc_hostapd_bss_rename },
 		{ "delete", uc_hostapd_bss_delete },
 	};
 	static const uc_function_list_t iface_fns[] = {
+		{ "set_bss_order", uc_hostapd_iface_set_bss_order },
 		{ "add_bss", uc_hostapd_iface_add_bss },
 		{ "stop", uc_hostapd_iface_stop },
 		{ "start", uc_hostapd_iface_start },
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 896ef46..2beeb9a 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
@@ -298,9 +298,15 @@
 uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx)
 {
 	uc_value_t *val = wpa_ucode_registry_get(reg, idx);
+	void **dataptr;
+
+	if (!val)
+		return NULL;
 
-	if (val)
-		ucv_array_set(reg, idx - 1, NULL);
+	ucv_array_set(reg, idx - 1, NULL);
+	dataptr = ucv_resource_dataptr(val, NULL);
+	if (dataptr)
+		*dataptr = NULL;
 
 	return val;
 }
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 d120ed6..6cba73d 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
@@ -2,6 +2,7 @@
 #include "utils/common.h"
 #include "utils/ucode.h"
 #include "drivers/driver.h"
+#include "ap/hostapd.h"
 #include "wpa_supplicant_i.h"
 #include "wps_supplicant.h"
 #include "bss.h"
@@ -135,6 +136,7 @@
 uc_wpas_add_iface(uc_vm_t *vm, size_t nargs)
 {
 	uc_value_t *info = uc_fn_arg(0);
+	uc_value_t *driver = ucv_object_get(info, "driver", NULL);
 	uc_value_t *ifname = ucv_object_get(info, "iface", NULL);
 	uc_value_t *bridge = ucv_object_get(info, "bridge", NULL);
 	uc_value_t *config = ucv_object_get(info, "config", NULL);
@@ -153,6 +155,22 @@
 		.ctrl_interface = ucv_string_get(ctrl),
 	};
 
+	if (driver) {
+		const char *drvname;
+		if (ucv_type(driver) != UC_STRING)
+			goto out;
+
+		iface.driver = NULL;
+		drvname = ucv_string_get(driver);
+		for (int i = 0; wpa_drivers[i]; i++) {
+			if (!strcmp(drvname, wpa_drivers[i]->name))
+				iface.driver = wpa_drivers[i]->name;
+		}
+
+		if (!iface.driver)
+			goto out;
+	}
+
 	if (!iface.ifname || !iface.confname)
 		goto out;
 
@@ -224,6 +242,15 @@
 		ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan));
 		ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq));
 	}
+
+#ifdef CONFIG_MESH
+	if (wpa_s->ifmsh) {
+		struct hostapd_iface *ifmsh = wpa_s->ifmsh;
+
+		ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(ifmsh->conf->secondary_channel));
+		ucv_object_add(ret, "frequency", ucv_int64_new(ifmsh->freq));
+	}
+#endif
 
 	return ret;
 }
diff --git a/recipes-wifi/hostapd/hostapd_2.10.3.bb b/recipes-wifi/hostapd/hostapd_2.10.3.bb
index cc9809a..b97c3b5 100644
--- a/recipes-wifi/hostapd/hostapd_2.10.3.bb
+++ b/recipes-wifi/hostapd/hostapd_2.10.3.bb
@@ -12,7 +12,7 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
 FILESEXTRAPATHS_prepend := "${THISDIR}/files/patches-${PV}:"
 
-SRCREV ?= "599d00be9de2846c6ea18c1487d8329522ade22b"
+SRCREV ?= "e5ccbfc69ecf297590341ae8b461edba9d8e964c"
 SRC_URI = " \
     git://w1.fi/hostap.git;protocol=https;branch=main \
     file://hostapd-full.config \
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/060-no_local_ssb_bcma.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/060-no_local_ssb_bcma.patch
index 4ad2ac0..451d0b7 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/build/060-no_local_ssb_bcma.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/060-no_local_ssb_bcma.patch
@@ -1,6 +1,6 @@
 --- a/local-symbols
 +++ b/local-symbols
-@@ -470,43 +470,6 @@ USB_VL600=
+@@ -491,43 +491,6 @@ USB_VL600=
  USB_NET_CH9200=
  USB_NET_AQC111=
  USB_RTL8153_ECM=
@@ -171,7 +171,7 @@
  	depends on CORDIC
 --- a/Kconfig.local
 +++ b/Kconfig.local
-@@ -1414,117 +1414,6 @@ config BACKPORTED_USB_NET_AQC111
+@@ -1477,117 +1477,6 @@ config BACKPORTED_USB_NET_AQC111
  config BACKPORTED_USB_RTL8153_ECM
  	tristate
  	default USB_RTL8153_ECM
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/080-resv_start_op.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/080-resv_start_op.patch
index 40b8e94..802a0e3 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/build/080-resv_start_op.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/080-resv_start_op.patch
@@ -1,18 +1,18 @@
---- a/drivers/net/wireless/mac80211_hwsim.c
-+++ b/drivers/net/wireless/mac80211_hwsim.c
-@@ -5363,7 +5363,9 @@ static struct genl_family hwsim_genl_fam
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -6179,7 +6179,9 @@ static struct genl_family hwsim_genl_fam
  	.module = THIS_MODULE,
  	.small_ops = hwsim_ops,
  	.n_small_ops = ARRAY_SIZE(hwsim_ops),
 +#if LINUX_VERSION_IS_GEQ(6,1,0)
- 	.resv_start_op = HWSIM_CMD_DEL_MAC_ADDR + 1,
+ 	.resv_start_op = HWSIM_CMD_REPORT_PMSR + 1, // match with __HWSIM_CMD_MAX
 +#endif
  	.mcgrps = hwsim_mcgrps,
  	.n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
  };
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -17233,7 +17233,9 @@ static struct genl_family nl80211_fam __
+@@ -17509,7 +17509,9 @@ static struct genl_family nl80211_fam __
  	.n_ops = ARRAY_SIZE(nl80211_ops),
  	.small_ops = nl80211_small_ops,
  	.n_small_ops = ARRAY_SIZE(nl80211_small_ops),
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/110-backport_namepace_const.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/110-backport_namepace_const.patch
new file mode 100644
index 0000000..6dca708
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/110-backport_namepace_const.patch
@@ -0,0 +1,14 @@
+--- a/net/wireless/sysfs.c
++++ b/net/wireless/sysfs.c
+@@ -154,7 +154,11 @@ static SIMPLE_DEV_PM_OPS(wiphy_pm_ops, w
+ #define WIPHY_PM_OPS NULL
+ #endif
+ 
++#if LINUX_VERSION_IS_GEQ(6,2,0)
+ static const void *wiphy_namespace(const struct device *d)
++#else
++static const void *wiphy_namespace(struct device *d)
++#endif
+ {
+ 	struct wiphy *wiphy = container_of(d, struct wiphy, dev);
+ 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/110-backport_napi_build_skb.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/110-backport_napi_build_skb.patch
deleted file mode 100644
index 1e152fe..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/build/110-backport_napi_build_skb.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/backport-include/linux/skbuff.h
-+++ b/backport-include/linux/skbuff.h
-@@ -144,4 +144,8 @@ static inline u64 skb_get_kcov_handle(st
- #define napi_build_skb build_skb
- #endif
- 
-+#if LINUX_VERSION_IS_LESS(5,11,0)
-+#define napi_build_skb build_skb
-+#endif
-+
- #endif /* __BACKPORT_SKBUFF_H */
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/120-headers_version_fix.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/120-headers_version_fix.patch
new file mode 100644
index 0000000..9a8c474
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/120-headers_version_fix.patch
@@ -0,0 +1,25 @@
+--- a/backport-include/linux/random.h
++++ b/backport-include/linux/random.h
+@@ -23,7 +23,7 @@ static inline u16 get_random_u16(void)
+ }
+ #endif
+ 
+-#if LINUX_VERSION_IS_LESS(6,2,0)
++#if LINUX_VERSION_IS_LESS(6,1,4)
+ static inline u32 __get_random_u32_below(u32 ceil)
+ {
+ 	/*
+--- a/backport-include/net/dropreason.h
++++ b/backport-include/net/dropreason.h
+@@ -3,10 +3,9 @@
+ 
+ #include <linux/version.h>
+ 
++#include <net/dropreason-core.h>
+ #if LINUX_VERSION_IS_GEQ(6,0,0)
+ #include_next <net/dropreason.h>
+-#else
+-#include <net/dropreason-core.h>
+ #endif
+ 
+ #if LINUX_VERSION_IS_LESS(6,4,0)
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/130-iommu_backport.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/130-iommu_backport.patch
new file mode 100644
index 0000000..2d3ef88
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/130-iommu_backport.patch
@@ -0,0 +1,26 @@
+--- /dev/null
++++ b/backport-include/linux/iommu.h
+@@ -0,0 +1,23 @@
++#ifndef __BACKPORT_LINUX_IOMMU_H
++#define __BACKPORT_LINUX_IOMMU_H
++
++#include_next <linux/iommu.h>
++#include <linux/version.h>
++
++#if LINUX_VERSION_IS_LESS(6,3,0)
++
++static inline int LINUX_BACKPORT(iommu_map)(struct iommu_domain *domain,
++					    unsigned long iova,
++					    phys_addr_t paddr, size_t size,
++					    int prot, gfp_t gfp)
++{
++	if (gfp == GFP_ATOMIC)
++		return iommu_map_atomic(domain, iova, paddr, size, prot);
++
++	return iommu_map(domain, iova, paddr, size, prot);
++}
++#define iommu_map LINUX_BACKPORT(iommu_map)
++
++#endif /* < 6.3 */
++
++#endif
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/200-Revert-wifi-iwlwifi-Use-generic-thermal_zone_get_tri.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/200-Revert-wifi-iwlwifi-Use-generic-thermal_zone_get_tri.patch
new file mode 100644
index 0000000..3a5285d
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/200-Revert-wifi-iwlwifi-Use-generic-thermal_zone_get_tri.patch
@@ -0,0 +1,159 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 17 Apr 2023 19:42:38 +0200
+Subject: [PATCH] Revert "wifi: iwlwifi: Use generic thermal_zone_get_trip()
+ function"
+
+This reverts commit 3d2f20ad46f83b333025f5e8e4afc34be8f13c4c.
+---
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -531,7 +531,7 @@ struct iwl_mvm_tt_mgmt {
+  * @tzone: thermal zone device data
+ */
+ struct iwl_mvm_thermal_device {
+-	struct thermal_trip trips[IWL_MAX_DTS_TRIPS];
++	s16 temp_trips[IWL_MAX_DTS_TRIPS];
+ 	u8 fw_trips_index[IWL_MAX_DTS_TRIPS];
+ 	struct thermal_zone_device *tzone;
+ };
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+@@ -573,11 +573,11 @@ int iwl_mvm_send_temp_report_ths_cmd(str
+ 	 * and uncompressed, the FW should get it compressed and sorted
+ 	 */
+ 
+-	/* compress trips to cmd array, remove uninitialized values*/
++	/* compress temp_trips to cmd array, remove uninitialized values*/
+ 	for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
+-		if (mvm->tz_device.trips[i].temperature != INT_MIN) {
++		if (mvm->tz_device.temp_trips[i] != S16_MIN) {
+ 			cmd.thresholds[idx++] =
+-				cpu_to_le16((s16)(mvm->tz_device.trips[i].temperature / 1000));
++				cpu_to_le16(mvm->tz_device.temp_trips[i]);
+ 		}
+ 	}
+ 	cmd.num_temps = cpu_to_le32(idx);
+@@ -593,8 +593,8 @@ int iwl_mvm_send_temp_report_ths_cmd(str
+ 	 */
+ 	for (i = 0; i < idx; i++) {
+ 		for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) {
+-			if ((int)(le16_to_cpu(cmd.thresholds[i]) * 1000) ==
+-			    mvm->tz_device.trips[j].temperature)
++			if (le16_to_cpu(cmd.thresholds[i]) ==
++				mvm->tz_device.temp_trips[j])
+ 				mvm->tz_device.fw_trips_index[i] = j;
+ 		}
+ 	}
+@@ -638,12 +638,37 @@ out:
+ 	return ret;
+ }
+ 
++static int iwl_mvm_tzone_get_trip_temp(struct thermal_zone_device *device,
++				       int trip, int *temp)
++{
++	struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
++
++	if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
++		return -EINVAL;
++
++	*temp = mvm->tz_device.temp_trips[trip] * 1000;
++
++	return 0;
++}
++
++static int iwl_mvm_tzone_get_trip_type(struct thermal_zone_device *device,
++				       int trip, enum thermal_trip_type *type)
++{
++	if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
++		return -EINVAL;
++
++	*type = THERMAL_TRIP_PASSIVE;
++
++	return 0;
++}
++
+ static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
+ 				       int trip, int temp)
+ {
+ 	struct iwl_mvm *mvm = thermal_zone_device_priv(device);
+ 	struct iwl_mvm_thermal_device *tzone;
+-	int ret;
++	int i, ret;
++	s16 temperature;
+ 
+ 	mutex_lock(&mvm->mutex);
+ 
+@@ -653,17 +678,40 @@ static int iwl_mvm_tzone_set_trip_temp(s
+ 		goto out;
+ 	}
+ 
++	if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) {
++		ret = -EINVAL;
++		goto out;
++	}
++
+ 	if ((temp / 1000) > S16_MAX) {
+ 		ret = -EINVAL;
+ 		goto out;
+ 	}
+ 
++	temperature = (s16)(temp / 1000);
+ 	tzone = &mvm->tz_device;
++
+ 	if (!tzone) {
+ 		ret = -EIO;
+ 		goto out;
+ 	}
+ 
++	/* no updates*/
++	if (tzone->temp_trips[trip] == temperature) {
++		ret = 0;
++		goto out;
++	}
++
++	/* already existing temperature */
++	for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
++		if (tzone->temp_trips[i] == temperature) {
++			ret = -EINVAL;
++			goto out;
++		}
++	}
++
++	tzone->temp_trips[trip] = temperature;
++
+ 	ret = iwl_mvm_send_temp_report_ths_cmd(mvm);
+ out:
+ 	mutex_unlock(&mvm->mutex);
+@@ -672,6 +720,8 @@ out:
+ 
+ static  struct thermal_zone_device_ops tzone_ops = {
+ 	.get_temp = iwl_mvm_tzone_get_temp,
++	.get_trip_temp = iwl_mvm_tzone_get_trip_temp,
++	.get_trip_type = iwl_mvm_tzone_get_trip_type,
+ 	.set_trip_temp = iwl_mvm_tzone_set_trip_temp,
+ };
+ 
+@@ -693,8 +743,7 @@ static void iwl_mvm_thermal_zone_registe
+ 	BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
+ 
+ 	sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
+-	mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
+-							mvm->tz_device.trips,
++	mvm->tz_device.tzone = thermal_zone_device_register(name,
+ 							IWL_MAX_DTS_TRIPS,
+ 							IWL_WRITABLE_TRIPS_MSK,
+ 							mvm, &tzone_ops,
+@@ -717,10 +766,8 @@ static void iwl_mvm_thermal_zone_registe
+ 	/* 0 is a valid temperature,
+ 	 * so initialize the array with S16_MIN which invalid temperature
+ 	 */
+-	for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) {
+-		mvm->tz_device.trips[i].temperature = INT_MIN;
+-		mvm->tz_device.trips[i].type = THERMAL_TRIP_PASSIVE;
+-	}
++	for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++)
++		mvm->tz_device.temp_trips[i] = S16_MIN;
+ }
+ 
+ static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/210-revert-split-op.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/210-revert-split-op.patch
new file mode 100644
index 0000000..a1fae5e
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/210-revert-split-op.patch
@@ -0,0 +1,22 @@
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -16400,8 +16400,7 @@ static u32 nl80211_internal_flags[] = {
+ #undef SELECTOR
+ };
+ 
+-static int nl80211_pre_doit(const struct genl_split_ops *ops,
+-			    struct sk_buff *skb,
++static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
+ 			    struct genl_info *info)
+ {
+ 	struct cfg80211_registered_device *rdev = NULL;
+@@ -16502,8 +16501,7 @@ out_unlock:
+ 	return err;
+ }
+ 
+-static void nl80211_post_doit(const struct genl_split_ops *ops,
+-			      struct sk_buff *skb,
++static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
+ 			      struct genl_info *info)
+ {
+ 	u32 internal_flags = nl80211_internal_flags[ops->internal_flags];
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 dbdb7b7..39a6ecc 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
@@ -10,5 +10,9 @@
     file://080-resv_start_op.patch \
     file://090-bcma-otp.patch \
     file://100-backports-drop-QRTR-and-MHI.patch \
-    file://110-backport_napi_build_skb.patch \
+    file://110-backport_namepace_const.patch \
+    file://120-headers_version_fix.patch \
+    file://130-iommu_backport.patch \
+    file://200-Revert-wifi-iwlwifi-Use-generic-thermal_zone_get_tri.patch \
+    file://210-revert-split-op.patch \
     "
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/110-mac80211_keep_keys_on_stop_ap.patch
index 4d4a2a8..e3349da 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/110-mac80211_keep_keys_on_stop_ap.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/110-mac80211_keep_keys_on_stop_ap.patch
@@ -9,7 +9,7 @@
 
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1519,7 +1519,6 @@ static int ieee80211_stop_ap(struct wiph
+@@ -1632,7 +1632,6 @@ static int ieee80211_stop_ap(struct wiph
  	link_conf->bssid_indicator = 0;
  
  	__sta_info_flush(sdata, true);
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/130-disable_auto_vif.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/130-disable_auto_vif.patch
new file mode 100644
index 0000000..9d8f781
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/130-disable_auto_vif.patch
@@ -0,0 +1,27 @@
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1396,24 +1396,6 @@ int ieee80211_register_hw(struct ieee802
+ 	debugfs_hw_add(local);
+ 	rate_control_add_debugfs(local);
+ 
+-	rtnl_lock();
+-	wiphy_lock(hw->wiphy);
+-
+-	/* add one default STA interface if supported */
+-	if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) &&
+-	    !ieee80211_hw_check(hw, NO_AUTO_VIF)) {
+-		struct vif_params params = {0};
+-
+-		result = ieee80211_if_add(local, "wlan%d", NET_NAME_ENUM, NULL,
+-					  NL80211_IFTYPE_STATION, &params);
+-		if (result)
+-			wiphy_warn(local->hw.wiphy,
+-				   "Failed to add default virtual iface\n");
+-	}
+-
+-	wiphy_unlock(hw->wiphy);
+-	rtnl_unlock();
+-
+ #ifdef CONFIG_INET
+ 	local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
+ 	result = register_inetaddr_notifier(&local->ifa_notifier);
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/210-ap_scan.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/210-ap_scan.patch
index 10b842d..25b844a 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/210-ap_scan.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/210-ap_scan.patch
@@ -8,7 +8,7 @@
 
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2727,6 +2727,8 @@ static int ieee80211_scan(struct wiphy *
+@@ -2843,6 +2843,8 @@ static int ieee80211_scan(struct wiphy *
  		 */
  		fallthrough;
  	case NL80211_IFTYPE_AP:
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch
index 63b2177..ffa5c17 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch
@@ -28,7 +28,7 @@
 
 --- a/net/mac80211/sta_info.c
 +++ b/net/mac80211/sta_info.c
-@@ -554,6 +554,7 @@ __sta_info_alloc(struct ieee80211_sub_if
+@@ -558,6 +558,7 @@ __sta_info_alloc(struct ieee80211_sub_if
  	INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
  	INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
  	mutex_init(&sta->ampdu_mlme.mtx);
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch
index 0ac9729..a27925e 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch
@@ -12,7 +12,7 @@
 
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -90,6 +90,8 @@ extern const u8 ieee80211_ac_to_qos_mask
+@@ -92,6 +92,8 @@ extern const u8 ieee80211_ac_to_qos_mask
   */
  #define AIRTIME_ACTIVE_DURATION (HZ / 10)
  
@@ -23,7 +23,7 @@
  
 --- a/net/mac80211/tx.c
 +++ b/net/mac80211/tx.c
-@@ -3984,7 +3984,7 @@ struct ieee80211_txq *ieee80211_next_txq
+@@ -4059,7 +4059,7 @@ struct ieee80211_txq *ieee80211_next_txq
  
  		if (deficit < 0)
  			sta->airtime[txqi->txq.ac].deficit +=
@@ -32,7 +32,7 @@
  
  		if (deficit < 0 || !aql_check) {
  			list_move_tail(&txqi->schedule_order,
-@@ -4127,7 +4127,8 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -4202,7 +4202,8 @@ bool ieee80211_txq_may_transmit(struct i
  		}
  		sta = container_of(iter->txq.sta, struct sta_info, sta);
  		if (ieee80211_sta_deficit(sta, ac) < 0)
@@ -42,7 +42,7 @@
  		list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
  	}
  
-@@ -4135,7 +4136,7 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -4210,7 +4211,7 @@ bool ieee80211_txq_may_transmit(struct i
  	if (sta->airtime[ac].deficit >= 0)
  		goto out;
  
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch
deleted file mode 100644
index d14ba05..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-From: Alexander Wetzel <alexander@wetzel-home.de>
-Date: Sun, 9 Oct 2022 18:30:38 +0200
-Subject: [PATCH] wifi: mac80211: add internal handler for wake_tx_queue
-
-Start to align the TX handling to only use internal TX queues (iTXQs):
-
-Provide a handler for drivers not having a custom wake_tx_queue
-callback and update the documentation.
-
-Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -89,15 +89,13 @@
- /**
-  * DOC: mac80211 software tx queueing
-  *
-- * mac80211 provides an optional intermediate queueing implementation designed
-- * to allow the driver to keep hardware queues short and provide some fairness
-- * between different stations/interfaces.
-- * In this model, the driver pulls data frames from the mac80211 queue instead
-- * of letting mac80211 push them via drv_tx().
-- * Other frames (e.g. control or management) are still pushed using drv_tx().
-+ * mac80211 uses an intermediate queueing implementation, designed to allow the
-+ * driver to keep hardware queues short and to provide some fairness between
-+ * different stations/interfaces.
-  *
-- * Drivers indicate that they use this model by implementing the .wake_tx_queue
-- * driver operation.
-+ * Drivers must provide the .wake_tx_queue driver operation by either
-+ * linking it to ieee80211_handle_wake_tx_queue() or implementing a custom
-+ * handler.
-  *
-  * Intermediate queues (struct ieee80211_txq) are kept per-sta per-tid, with
-  * another per-sta for non-data/non-mgmt and bufferable management frames, and
-@@ -106,9 +104,12 @@
-  * The driver is expected to initialize its private per-queue data for stations
-  * and interfaces in the .add_interface and .sta_add ops.
-  *
-- * The driver can't access the queue directly. To dequeue a frame from a
-- * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a
-- * queue, it calls the .wake_tx_queue driver op.
-+ * The driver can't access the internal TX queues (iTXQs) directly.
-+ * Whenever mac80211 adds a new frame to a queue, it calls the .wake_tx_queue
-+ * driver op.
-+ * Drivers implementing a custom .wake_tx_queue op can get them by calling
-+ * ieee80211_tx_dequeue(). Drivers using ieee80211_handle_wake_tx_queue() will
-+ * simply get the individual frames pushed via the .tx driver operation.
-  *
-  * Drivers can optionally delegate responsibility for scheduling queues to
-  * mac80211, to take advantage of airtime fairness accounting. In this case, to
-@@ -2248,8 +2249,8 @@ struct ieee80211_link_sta {
-  *	For non MLO STA it will point to the deflink data. For MLO STA
-  *	ieee80211_sta_recalc_aggregates() must be called to update it.
-  * @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not.
-- * @txq: per-TID data TX queues (if driver uses the TXQ abstraction); note that
-- *	the last entry (%IEEE80211_NUM_TIDS) is used for non-data frames
-+ * @txq: per-TID data TX queues; note that the last entry (%IEEE80211_NUM_TIDS)
-+ *	is used for non-data frames
-  * @deflink: This holds the default link STA information, for non MLO STA all link
-  *	specific STA information is accessed through @deflink or through
-  *	link[0] which points to address of @deflink. For MLO Link STA
-@@ -5687,7 +5688,7 @@ void ieee80211_key_replay(struct ieee802
-  * @hw: pointer as obtained from ieee80211_alloc_hw().
-  * @queue: queue number (counted from zero).
-  *
-- * Drivers should use this function instead of netif_wake_queue.
-+ * Drivers must use this function instead of netif_wake_queue.
-  */
- void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue);
- 
-@@ -5696,7 +5697,7 @@ void ieee80211_wake_queue(struct ieee802
-  * @hw: pointer as obtained from ieee80211_alloc_hw().
-  * @queue: queue number (counted from zero).
-  *
-- * Drivers should use this function instead of netif_stop_queue.
-+ * Drivers must use this function instead of netif_stop_queue.
-  */
- void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue);
- 
-@@ -5705,7 +5706,7 @@ void ieee80211_stop_queue(struct ieee802
-  * @hw: pointer as obtained from ieee80211_alloc_hw().
-  * @queue: queue number (counted from zero).
-  *
-- * Drivers should use this function instead of netif_stop_queue.
-+ * Drivers must use this function instead of netif_queue_stopped.
-  *
-  * Return: %true if the queue is stopped. %false otherwise.
-  */
-@@ -5716,7 +5717,7 @@ int ieee80211_queue_stopped(struct ieee8
-  * ieee80211_stop_queues - stop all queues
-  * @hw: pointer as obtained from ieee80211_alloc_hw().
-  *
-- * Drivers should use this function instead of netif_stop_queue.
-+ * Drivers must use this function instead of netif_tx_stop_all_queues.
-  */
- void ieee80211_stop_queues(struct ieee80211_hw *hw);
- 
-@@ -5724,7 +5725,7 @@ void ieee80211_stop_queues(struct ieee80
-  * ieee80211_wake_queues - wake all queues
-  * @hw: pointer as obtained from ieee80211_alloc_hw().
-  *
-- * Drivers should use this function instead of netif_wake_queue.
-+ * Drivers must use this function instead of netif_tx_wake_all_queues.
-  */
- void ieee80211_wake_queues(struct ieee80211_hw *hw);
- 
-@@ -6946,6 +6947,18 @@ static inline struct sk_buff *ieee80211_
- }
- 
- /**
-+ * ieee80211_handle_wake_tx_queue - mac80211 handler for wake_tx_queue callback
-+ *
-+ * @hw: pointer as obtained from wake_tx_queue() callback().
-+ * @txq: pointer as obtained from wake_tx_queue() callback().
-+ *
-+ * Drivers can use this function for the mandatory mac80211 wake_tx_queue
-+ * callback in struct ieee80211_ops. They should not call this function.
-+ */
-+void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
-+				    struct ieee80211_txq *txq);
-+
-+/**
-  * ieee80211_next_txq - get next tx queue to pull packets from
-  *
-  * @hw: pointer as obtained from ieee80211_alloc_hw()
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -288,6 +288,52 @@ __le16 ieee80211_ctstoself_duration(stru
- }
- EXPORT_SYMBOL(ieee80211_ctstoself_duration);
- 
-+static void wake_tx_push_queue(struct ieee80211_local *local,
-+			       struct ieee80211_sub_if_data *sdata,
-+			       struct ieee80211_txq *queue)
-+{
-+	int q = sdata->vif.hw_queue[queue->ac];
-+	struct ieee80211_tx_control control = {
-+		.sta = queue->sta,
-+	};
-+	struct sk_buff *skb;
-+	unsigned long flags;
-+	bool q_stopped;
-+
-+	while (1) {
-+		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-+		q_stopped = local->queue_stop_reasons[q];
-+		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-+
-+		if (q_stopped)
-+			break;
-+
-+		skb = ieee80211_tx_dequeue(&local->hw, queue);
-+		if (!skb)
-+			break;
-+
-+		drv_tx(local, &control, skb);
-+	}
-+}
-+
-+/* wake_tx_queue handler for driver not implementing a custom one*/
-+void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
-+				    struct ieee80211_txq *txq)
-+{
-+	struct ieee80211_local *local = hw_to_local(hw);
-+	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
-+	struct ieee80211_txq *queue;
-+
-+	/* Use ieee80211_next_txq() for airtime fairness accounting */
-+	ieee80211_txq_schedule_start(hw, txq->ac);
-+	while ((queue = ieee80211_next_txq(hw, txq->ac))) {
-+		wake_tx_push_queue(local, sdata, queue);
-+		ieee80211_return_txq(hw, queue, false);
-+	}
-+	ieee80211_txq_schedule_end(hw, txq->ac);
-+}
-+EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue);
-+
- static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
- {
- 	struct ieee80211_local *local = sdata->local;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch
deleted file mode 100644
index fee038d..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch
+++ /dev/null
@@ -1,396 +0,0 @@
-From: Alexander Wetzel <alexander@wetzel-home.de>
-Date: Sun, 9 Oct 2022 18:30:39 +0200
-Subject: [PATCH] wifi: mac80211: add wake_tx_queue callback to drivers
-
-mac80211 is fully switching over to the internal TX queue (iTXQ)
-implementation. Update all drivers not yet providing the now mandatory
-wake_tx_queue() callback.
-
-As an side effect the netdev interfaces of all updated drivers will
-switch to the noqueue qdisc.
-
-Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
-[add staging drivers]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/drivers/net/wireless/admtek/adm8211.c
-+++ b/drivers/net/wireless/admtek/adm8211.c
-@@ -1760,6 +1760,7 @@ static int adm8211_alloc_rings(struct ie
- 
- static const struct ieee80211_ops adm8211_ops = {
- 	.tx			= adm8211_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= adm8211_start,
- 	.stop			= adm8211_stop,
- 	.add_interface		= adm8211_add_interface,
---- a/drivers/net/wireless/ath/ar5523/ar5523.c
-+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
-@@ -1361,6 +1361,7 @@ static const struct ieee80211_ops ar5523
- 	.start			= ar5523_start,
- 	.stop			= ar5523_stop,
- 	.tx			= ar5523_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.set_rts_threshold	= ar5523_set_rts_threshold,
- 	.add_interface		= ar5523_add_interface,
- 	.remove_interface	= ar5523_remove_interface,
---- a/drivers/net/wireless/ath/ath11k/mac.c
-+++ b/drivers/net/wireless/ath/ath11k/mac.c
-@@ -8587,6 +8587,7 @@ err_fallback:
- 
- static const struct ieee80211_ops ath11k_ops = {
- 	.tx				= ath11k_mac_op_tx,
-+	.wake_tx_queue			= ieee80211_handle_wake_tx_queue,
- 	.start                          = ath11k_mac_op_start,
- 	.stop                           = ath11k_mac_op_stop,
- 	.reconfig_complete              = ath11k_mac_op_reconfig_complete,
---- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-@@ -781,6 +781,7 @@ static int ath5k_set_ringparam(struct ie
- 
- const struct ieee80211_ops ath5k_hw_ops = {
- 	.tx			= ath5k_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= ath5k_start,
- 	.stop			= ath5k_stop,
- 	.add_interface		= ath5k_add_interface,
---- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
-+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
-@@ -1870,6 +1870,7 @@ static void ath9k_htc_channel_switch_bea
- 
- struct ieee80211_ops ath9k_htc_ops = {
- 	.tx                 = ath9k_htc_tx,
-+	.wake_tx_queue      = ieee80211_handle_wake_tx_queue,
- 	.start              = ath9k_htc_start,
- 	.stop               = ath9k_htc_stop,
- 	.add_interface      = ath9k_htc_add_interface,
---- a/drivers/net/wireless/ath/carl9170/main.c
-+++ b/drivers/net/wireless/ath/carl9170/main.c
-@@ -1715,6 +1715,7 @@ static const struct ieee80211_ops carl91
- 	.start			= carl9170_op_start,
- 	.stop			= carl9170_op_stop,
- 	.tx			= carl9170_op_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.flush			= carl9170_op_flush,
- 	.add_interface		= carl9170_op_add_interface,
- 	.remove_interface	= carl9170_op_remove_interface,
---- a/drivers/net/wireless/ath/wcn36xx/main.c
-+++ b/drivers/net/wireless/ath/wcn36xx/main.c
-@@ -1362,6 +1362,7 @@ static const struct ieee80211_ops wcn36x
- 	.prepare_multicast	= wcn36xx_prepare_multicast,
- 	.configure_filter       = wcn36xx_configure_filter,
- 	.tx			= wcn36xx_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.set_key		= wcn36xx_set_key,
- 	.hw_scan		= wcn36xx_hw_scan,
- 	.cancel_hw_scan		= wcn36xx_cancel_hw_scan,
---- a/drivers/net/wireless/atmel/at76c50x-usb.c
-+++ b/drivers/net/wireless/atmel/at76c50x-usb.c
-@@ -2187,6 +2187,7 @@ static int at76_set_key(struct ieee80211
- 
- static const struct ieee80211_ops at76_ops = {
- 	.tx = at76_mac80211_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.add_interface = at76_add_interface,
- 	.remove_interface = at76_remove_interface,
- 	.config = at76_config,
---- a/drivers/net/wireless/broadcom/b43/main.c
-+++ b/drivers/net/wireless/broadcom/b43/main.c
-@@ -5171,6 +5171,7 @@ static int b43_op_get_survey(struct ieee
- 
- static const struct ieee80211_ops b43_hw_ops = {
- 	.tx			= b43_op_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.conf_tx		= b43_op_conf_tx,
- 	.add_interface		= b43_op_add_interface,
- 	.remove_interface	= b43_op_remove_interface,
---- a/drivers/net/wireless/broadcom/b43legacy/main.c
-+++ b/drivers/net/wireless/broadcom/b43legacy/main.c
-@@ -3532,6 +3532,7 @@ static int b43legacy_op_get_survey(struc
- 
- static const struct ieee80211_ops b43legacy_hw_ops = {
- 	.tx			= b43legacy_op_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.conf_tx		= b43legacy_op_conf_tx,
- 	.add_interface		= b43legacy_op_add_interface,
- 	.remove_interface	= b43legacy_op_remove_interface,
---- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
-@@ -962,6 +962,7 @@ static int brcms_ops_beacon_set_tim(stru
- 
- static const struct ieee80211_ops brcms_ops = {
- 	.tx = brcms_ops_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.start = brcms_ops_start,
- 	.stop = brcms_ops_stop,
- 	.add_interface = brcms_ops_add_interface,
---- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
-+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
-@@ -3439,6 +3439,7 @@ static const struct attribute_group il39
- 
- static struct ieee80211_ops il3945_mac_ops __ro_after_init = {
- 	.tx = il3945_mac_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.start = il3945_mac_start,
- 	.stop = il3945_mac_stop,
- 	.add_interface = il_mac_add_interface,
---- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
-+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
-@@ -6308,6 +6308,7 @@ il4965_tx_queue_set_status(struct il_pri
- 
- static const struct ieee80211_ops il4965_mac_ops = {
- 	.tx = il4965_mac_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.start = il4965_mac_start,
- 	.stop = il4965_mac_stop,
- 	.add_interface = il_mac_add_interface,
---- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
-+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
-@@ -1571,6 +1571,7 @@ static void iwlagn_mac_sta_notify(struct
- 
- const struct ieee80211_ops iwlagn_hw_ops = {
- 	.tx = iwlagn_mac_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.start = iwlagn_mac_start,
- 	.stop = iwlagn_mac_stop,
- #ifdef CONFIG_PM_SLEEP
---- a/drivers/net/wireless/intersil/p54/main.c
-+++ b/drivers/net/wireless/intersil/p54/main.c
-@@ -705,6 +705,7 @@ static void p54_set_coverage_class(struc
- 
- static const struct ieee80211_ops p54_ops = {
- 	.tx			= p54_tx_80211,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= p54_start,
- 	.stop			= p54_stop,
- 	.add_interface		= p54_add_interface,
---- a/drivers/net/wireless/mac80211_hwsim.c
-+++ b/drivers/net/wireless/mac80211_hwsim.c
-@@ -3109,6 +3109,7 @@ static int mac80211_hwsim_change_sta_lin
- 
- #define HWSIM_COMMON_OPS					\
- 	.tx = mac80211_hwsim_tx,				\
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,	\
- 	.start = mac80211_hwsim_start,				\
- 	.stop = mac80211_hwsim_stop,				\
- 	.add_interface = mac80211_hwsim_add_interface,		\
---- a/drivers/net/wireless/marvell/libertas_tf/main.c
-+++ b/drivers/net/wireless/marvell/libertas_tf/main.c
-@@ -474,6 +474,7 @@ static int lbtf_op_get_survey(struct iee
- 
- static const struct ieee80211_ops lbtf_ops = {
- 	.tx			= lbtf_op_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= lbtf_op_start,
- 	.stop			= lbtf_op_stop,
- 	.add_interface		= lbtf_op_add_interface,
---- a/drivers/net/wireless/marvell/mwl8k.c
-+++ b/drivers/net/wireless/marvell/mwl8k.c
-@@ -5611,6 +5611,7 @@ static void mwl8k_sw_scan_complete(struc
- 
- static const struct ieee80211_ops mwl8k_ops = {
- 	.tx			= mwl8k_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= mwl8k_start,
- 	.stop			= mwl8k_stop,
- 	.add_interface		= mwl8k_add_interface,
---- a/drivers/net/wireless/mediatek/mt7601u/main.c
-+++ b/drivers/net/wireless/mediatek/mt7601u/main.c
-@@ -406,6 +406,7 @@ out:
- 
- const struct ieee80211_ops mt7601u_ops = {
- 	.tx = mt7601u_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.start = mt7601u_start,
- 	.stop = mt7601u_stop,
- 	.add_interface = mt7601u_add_interface,
---- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
-@@ -1706,6 +1706,7 @@ static int rt2400pci_tx_last_beacon(stru
- 
- static const struct ieee80211_ops rt2400pci_mac80211_ops = {
- 	.tx			= rt2x00mac_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rt2x00mac_start,
- 	.stop			= rt2x00mac_stop,
- 	.add_interface		= rt2x00mac_add_interface,
---- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
-@@ -2004,6 +2004,7 @@ static int rt2500pci_tx_last_beacon(stru
- 
- static const struct ieee80211_ops rt2500pci_mac80211_ops = {
- 	.tx			= rt2x00mac_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rt2x00mac_start,
- 	.stop			= rt2x00mac_stop,
- 	.add_interface		= rt2x00mac_add_interface,
---- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
-@@ -1795,6 +1795,7 @@ static int rt2500usb_probe_hw(struct rt2
- 
- static const struct ieee80211_ops rt2500usb_mac80211_ops = {
- 	.tx			= rt2x00mac_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rt2x00mac_start,
- 	.stop			= rt2x00mac_stop,
- 	.add_interface		= rt2x00mac_add_interface,
---- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
-@@ -288,6 +288,7 @@ static int rt2800pci_read_eeprom(struct
- 
- static const struct ieee80211_ops rt2800pci_mac80211_ops = {
- 	.tx			= rt2x00mac_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rt2x00mac_start,
- 	.stop			= rt2x00mac_stop,
- 	.add_interface		= rt2x00mac_add_interface,
---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
-@@ -133,6 +133,7 @@ static int rt2800soc_write_firmware(stru
- 
- static const struct ieee80211_ops rt2800soc_mac80211_ops = {
- 	.tx			= rt2x00mac_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rt2x00mac_start,
- 	.stop			= rt2x00mac_stop,
- 	.add_interface		= rt2x00mac_add_interface,
---- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
-@@ -630,6 +630,7 @@ static int rt2800usb_probe_hw(struct rt2
- 
- static const struct ieee80211_ops rt2800usb_mac80211_ops = {
- 	.tx			= rt2x00mac_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rt2x00mac_start,
- 	.stop			= rt2x00mac_stop,
- 	.add_interface		= rt2x00mac_add_interface,
---- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
-@@ -2873,6 +2873,7 @@ static u64 rt61pci_get_tsf(struct ieee80
- 
- static const struct ieee80211_ops rt61pci_mac80211_ops = {
- 	.tx			= rt2x00mac_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rt2x00mac_start,
- 	.stop			= rt2x00mac_stop,
- 	.add_interface		= rt2x00mac_add_interface,
---- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
-@@ -2292,6 +2292,7 @@ static u64 rt73usb_get_tsf(struct ieee80
- 
- static const struct ieee80211_ops rt73usb_mac80211_ops = {
- 	.tx			= rt2x00mac_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rt2x00mac_start,
- 	.stop			= rt2x00mac_stop,
- 	.add_interface		= rt2x00mac_add_interface,
---- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
-+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
-@@ -1608,6 +1608,7 @@ static void rtl8180_configure_filter(str
- 
- static const struct ieee80211_ops rtl8180_ops = {
- 	.tx			= rtl8180_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rtl8180_start,
- 	.stop			= rtl8180_stop,
- 	.add_interface		= rtl8180_add_interface,
---- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
-+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
-@@ -1378,6 +1378,7 @@ static int rtl8187_conf_tx(struct ieee80
- 
- static const struct ieee80211_ops rtl8187_ops = {
- 	.tx			= rtl8187_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= rtl8187_start,
- 	.stop			= rtl8187_stop,
- 	.add_interface		= rtl8187_add_interface,
---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
-@@ -6548,6 +6548,7 @@ static void rtl8xxxu_stop(struct ieee802
- 
- static const struct ieee80211_ops rtl8xxxu_ops = {
- 	.tx = rtl8xxxu_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.add_interface = rtl8xxxu_add_interface,
- 	.remove_interface = rtl8xxxu_remove_interface,
- 	.config = rtl8xxxu_config,
---- a/drivers/net/wireless/realtek/rtlwifi/core.c
-+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
-@@ -1912,6 +1912,7 @@ const struct ieee80211_ops rtl_ops = {
- 	.start = rtl_op_start,
- 	.stop = rtl_op_stop,
- 	.tx = rtl_op_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.add_interface = rtl_op_add_interface,
- 	.remove_interface = rtl_op_remove_interface,
- 	.change_interface = rtl_op_change_interface,
---- a/drivers/net/wireless/realtek/rtw88/mac80211.c
-+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
-@@ -896,6 +896,7 @@ static void rtw_ops_sta_rc_update(struct
- 
- const struct ieee80211_ops rtw_ops = {
- 	.tx			= rtw_ops_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.wake_tx_queue		= rtw_ops_wake_tx_queue,
- 	.start			= rtw_ops_start,
- 	.stop			= rtw_ops_stop,
---- a/drivers/net/wireless/realtek/rtw89/mac80211.c
-+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
-@@ -918,6 +918,7 @@ static int rtw89_ops_set_tid_config(stru
- 
- const struct ieee80211_ops rtw89_ops = {
- 	.tx			= rtw89_ops_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.wake_tx_queue		= rtw89_ops_wake_tx_queue,
- 	.start			= rtw89_ops_start,
- 	.stop			= rtw89_ops_stop,
---- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
-+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
-@@ -1958,6 +1958,7 @@ static int rsi_mac80211_resume(struct ie
- 
- static const struct ieee80211_ops mac80211_ops = {
- 	.tx = rsi_mac80211_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.start = rsi_mac80211_start,
- 	.stop = rsi_mac80211_stop,
- 	.add_interface = rsi_mac80211_add_interface,
---- a/drivers/net/wireless/st/cw1200/main.c
-+++ b/drivers/net/wireless/st/cw1200/main.c
-@@ -209,6 +209,7 @@ static const struct ieee80211_ops cw1200
- 	.remove_interface	= cw1200_remove_interface,
- 	.change_interface	= cw1200_change_interface,
- 	.tx			= cw1200_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.hw_scan		= cw1200_hw_scan,
- 	.set_tim		= cw1200_set_tim,
- 	.sta_notify		= cw1200_sta_notify,
---- a/drivers/net/wireless/ti/wl1251/main.c
-+++ b/drivers/net/wireless/ti/wl1251/main.c
-@@ -1359,6 +1359,7 @@ static const struct ieee80211_ops wl1251
- 	.prepare_multicast = wl1251_op_prepare_multicast,
- 	.configure_filter = wl1251_op_configure_filter,
- 	.tx = wl1251_op_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.set_key = wl1251_op_set_key,
- 	.hw_scan = wl1251_op_hw_scan,
- 	.bss_info_changed = wl1251_op_bss_info_changed,
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -5942,6 +5942,7 @@ static const struct ieee80211_ops wl1271
- 	.prepare_multicast = wl1271_op_prepare_multicast,
- 	.configure_filter = wl1271_op_configure_filter,
- 	.tx = wl1271_op_tx,
-+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
- 	.set_key = wlcore_op_set_key,
- 	.hw_scan = wl1271_op_hw_scan,
- 	.cancel_hw_scan = wl1271_op_cancel_hw_scan,
---- a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c
-+++ b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c
-@@ -1344,6 +1344,7 @@ static u64 zd_op_get_tsf(struct ieee8021
- 
- static const struct ieee80211_ops zd_ops = {
- 	.tx			= zd_op_tx,
-+	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.start			= zd_op_start,
- 	.stop			= zd_op_stop,
- 	.add_interface		= zd_op_add_interface,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch
deleted file mode 100644
index f9f9977..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch
+++ /dev/null
@@ -1,683 +0,0 @@
-From: Alexander Wetzel <alexander@wetzel-home.de>
-Date: Sun, 9 Oct 2022 18:30:40 +0200
-Subject: [PATCH] wifi: mac80211: Drop support for TX push path
-
-All drivers are now using mac80211 internal queues (iTXQs).
-Drop mac80211 internal support for the old push path.
-
-Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -4346,9 +4346,6 @@ static int ieee80211_get_txq_stats(struc
- 	struct ieee80211_sub_if_data *sdata;
- 	int ret = 0;
- 
--	if (!local->ops->wake_tx_queue)
--		return 1;
--
- 	spin_lock_bh(&local->fq.lock);
- 	rcu_read_lock();
- 
---- a/net/mac80211/debugfs.c
-+++ b/net/mac80211/debugfs.c
-@@ -663,9 +663,7 @@ void debugfs_hw_add(struct ieee80211_loc
- 	DEBUGFS_ADD_MODE(force_tx_status, 0600);
- 	DEBUGFS_ADD_MODE(aql_enable, 0600);
- 	DEBUGFS_ADD(aql_pending);
--
--	if (local->ops->wake_tx_queue)
--		DEBUGFS_ADD_MODE(aqm, 0600);
-+	DEBUGFS_ADD_MODE(aqm, 0600);
- 
- 	DEBUGFS_ADD_MODE(airtime_flags, 0600);
- 
---- a/net/mac80211/debugfs_netdev.c
-+++ b/net/mac80211/debugfs_netdev.c
-@@ -677,8 +677,7 @@ static void add_common_files(struct ieee
- 	DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz);
- 	DEBUGFS_ADD(hw_queues);
- 
--	if (sdata->local->ops->wake_tx_queue &&
--	    sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
-+	if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
- 	    sdata->vif.type != NL80211_IFTYPE_NAN)
- 		DEBUGFS_ADD(aqm);
- }
---- a/net/mac80211/debugfs_sta.c
-+++ b/net/mac80211/debugfs_sta.c
-@@ -1057,10 +1057,8 @@ void ieee80211_sta_debugfs_add(struct st
- 	DEBUGFS_ADD_COUNTER(rx_fragments, deflink.rx_stats.fragments);
- 	DEBUGFS_ADD_COUNTER(tx_filtered, deflink.status_stats.filtered);
- 
--	if (local->ops->wake_tx_queue) {
--		DEBUGFS_ADD(aqm);
--		DEBUGFS_ADD(airtime);
--	}
-+	DEBUGFS_ADD(aqm);
-+	DEBUGFS_ADD(airtime);
- 
- 	if (wiphy_ext_feature_isset(local->hw.wiphy,
- 				    NL80211_EXT_FEATURE_AQL))
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -2294,7 +2294,6 @@ void ieee80211_wake_queue_by_reason(stru
- void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
- 				    enum queue_stop_reason reason,
- 				    bool refcounted);
--void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue);
- void ieee80211_add_pending_skb(struct ieee80211_local *local,
- 			       struct sk_buff *skb);
- void ieee80211_add_pending_skbs(struct ieee80211_local *local,
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -460,12 +460,6 @@ static void ieee80211_do_stop(struct iee
- 	if (cancel_scan)
- 		ieee80211_scan_cancel(local);
- 
--	/*
--	 * Stop TX on this interface first.
--	 */
--	if (!local->ops->wake_tx_queue && sdata->dev)
--		netif_tx_stop_all_queues(sdata->dev);
--
- 	ieee80211_roc_purge(local, sdata);
- 
- 	switch (sdata->vif.type) {
-@@ -813,13 +807,6 @@ static void ieee80211_uninit(struct net_
- 	ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
- }
- 
--static u16 ieee80211_netdev_select_queue(struct net_device *dev,
--					 struct sk_buff *skb,
--					 struct net_device *sb_dev)
--{
--	return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
--}
--
- static void
- ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
- {
-@@ -833,7 +820,6 @@ static const struct net_device_ops ieee8
- 	.ndo_start_xmit		= ieee80211_subif_start_xmit,
- 	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
- 	.ndo_set_mac_address 	= ieee80211_change_mac,
--	.ndo_select_queue	= ieee80211_netdev_select_queue,
- 	.ndo_get_stats64	= ieee80211_get_stats64,
- };
- 
-@@ -941,7 +927,6 @@ static const struct net_device_ops ieee8
- 	.ndo_start_xmit		= ieee80211_subif_start_xmit_8023,
- 	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
- 	.ndo_set_mac_address	= ieee80211_change_mac,
--	.ndo_select_queue	= ieee80211_netdev_select_queue,
- 	.ndo_get_stats64	= ieee80211_get_stats64,
- 	.ndo_fill_forward_path	= ieee80211_netdev_fill_forward_path,
- };
-@@ -1443,35 +1428,6 @@ int ieee80211_do_open(struct wireless_de
- 
- 	ieee80211_recalc_ps(local);
- 
--	if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
--	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
--	    local->ops->wake_tx_queue) {
--		/* XXX: for AP_VLAN, actually track AP queues */
--		if (dev)
--			netif_tx_start_all_queues(dev);
--	} else if (dev) {
--		unsigned long flags;
--		int n_acs = IEEE80211_NUM_ACS;
--		int ac;
--
--		if (local->hw.queues < IEEE80211_NUM_ACS)
--			n_acs = 1;
--
--		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
--		if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE ||
--		    (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 &&
--		     skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) {
--			for (ac = 0; ac < n_acs; ac++) {
--				int ac_queue = sdata->vif.hw_queue[ac];
--
--				if (local->queue_stop_reasons[ac_queue] == 0 &&
--				    skb_queue_empty(&local->pending[ac_queue]))
--					netif_start_subqueue(dev, ac);
--			}
--		}
--		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
--	}
--
- 	set_bit(SDATA_STATE_RUNNING, &sdata->state);
- 
- 	return 0;
-@@ -1501,17 +1457,12 @@ static void ieee80211_if_setup(struct ne
- {
- 	ether_setup(dev);
- 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
-+	dev->priv_flags |= IFF_NO_QUEUE;
- 	dev->netdev_ops = &ieee80211_dataif_ops;
- 	dev->needs_free_netdev = true;
- 	dev->priv_destructor = ieee80211_if_free;
- }
- 
--static void ieee80211_if_setup_no_queue(struct net_device *dev)
--{
--	ieee80211_if_setup(dev);
--	dev->priv_flags |= IFF_NO_QUEUE;
--}
--
- static void ieee80211_iface_process_skb(struct ieee80211_local *local,
- 					struct ieee80211_sub_if_data *sdata,
- 					struct sk_buff *skb)
-@@ -2096,9 +2047,7 @@ int ieee80211_if_add(struct ieee80211_lo
- 	struct net_device *ndev = NULL;
- 	struct ieee80211_sub_if_data *sdata = NULL;
- 	struct txq_info *txqi;
--	void (*if_setup)(struct net_device *dev);
- 	int ret, i;
--	int txqs = 1;
- 
- 	ASSERT_RTNL();
- 
-@@ -2121,30 +2070,18 @@ int ieee80211_if_add(struct ieee80211_lo
- 				 sizeof(void *));
- 		int txq_size = 0;
- 
--		if (local->ops->wake_tx_queue &&
--		    type != NL80211_IFTYPE_AP_VLAN &&
-+		if (type != NL80211_IFTYPE_AP_VLAN &&
- 		    (type != NL80211_IFTYPE_MONITOR ||
- 		     (params->flags & MONITOR_FLAG_ACTIVE)))
- 			txq_size += sizeof(struct txq_info) +
- 				    local->hw.txq_data_size;
- 
--		if (local->ops->wake_tx_queue) {
--			if_setup = ieee80211_if_setup_no_queue;
--		} else {
--			if_setup = ieee80211_if_setup;
--			if (local->hw.queues >= IEEE80211_NUM_ACS)
--				txqs = IEEE80211_NUM_ACS;
--		}
--
- 		ndev = alloc_netdev_mqs(size + txq_size,
- 					name, name_assign_type,
--					if_setup, txqs, 1);
-+					ieee80211_if_setup, 1, 1);
- 		if (!ndev)
- 			return -ENOMEM;
- 
--		if (!local->ops->wake_tx_queue && local->hw.wiphy->tx_queue_len)
--			ndev->tx_queue_len = local->hw.wiphy->tx_queue_len;
--
- 		dev_net_set(ndev, wiphy_net(local->hw.wiphy));
- 
- 		ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -630,7 +630,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
- 
- 	if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config ||
- 		    !ops->add_interface || !ops->remove_interface ||
--		    !ops->configure_filter))
-+		    !ops->configure_filter || !ops->wake_tx_queue))
- 		return NULL;
- 
- 	if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove)))
-@@ -719,9 +719,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
- 	if (!ops->set_key)
- 		wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
- 
--	if (ops->wake_tx_queue)
--		wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS);
--
-+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS);
- 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM);
- 
- 	wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
-@@ -834,10 +832,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
- 		atomic_set(&local->agg_queue_stop[i], 0);
- 	}
- 	tasklet_setup(&local->tx_pending_tasklet, ieee80211_tx_pending);
--
--	if (ops->wake_tx_queue)
--		tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs);
--
-+	tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs);
- 	tasklet_setup(&local->tasklet, ieee80211_tasklet_handler);
- 
- 	skb_queue_head_init(&local->skb_queue);
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1571,9 +1571,6 @@ static void sta_ps_start(struct sta_info
- 
- 	ieee80211_clear_fast_xmit(sta);
- 
--	if (!sta->sta.txq[0])
--		return;
--
- 	for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) {
- 		struct ieee80211_txq *txq = sta->sta.txq[tid];
- 		struct txq_info *txqi = to_txq_info(txq);
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -140,17 +140,15 @@ static void __cleanup_single_sta(struct
- 		atomic_dec(&ps->num_sta_ps);
- 	}
- 
--	if (sta->sta.txq[0]) {
--		for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
--			struct txq_info *txqi;
-+	for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
-+		struct txq_info *txqi;
- 
--			if (!sta->sta.txq[i])
--				continue;
-+		if (!sta->sta.txq[i])
-+			continue;
- 
--			txqi = to_txq_info(sta->sta.txq[i]);
-+		txqi = to_txq_info(sta->sta.txq[i]);
- 
--			ieee80211_txq_purge(local, txqi);
--		}
-+		ieee80211_txq_purge(local, txqi);
- 	}
- 
- 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-@@ -425,8 +423,7 @@ void sta_info_free(struct ieee80211_loca
- 
- 	sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
- 
--	if (sta->sta.txq[0])
--		kfree(to_txq_info(sta->sta.txq[0]));
-+	kfree(to_txq_info(sta->sta.txq[0]));
- 	kfree(rcu_dereference_raw(sta->sta.rates));
- #ifdef CPTCFG_MAC80211_MESH
- 	kfree(sta->mesh);
-@@ -527,6 +524,8 @@ __sta_info_alloc(struct ieee80211_sub_if
- 	struct ieee80211_local *local = sdata->local;
- 	struct ieee80211_hw *hw = &local->hw;
- 	struct sta_info *sta;
-+	void *txq_data;
-+	int size;
- 	int i;
- 
- 	sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
-@@ -597,21 +596,18 @@ __sta_info_alloc(struct ieee80211_sub_if
- 
- 	sta->last_connected = ktime_get_seconds();
- 
--	if (local->ops->wake_tx_queue) {
--		void *txq_data;
--		int size = sizeof(struct txq_info) +
--			   ALIGN(hw->txq_data_size, sizeof(void *));
-+	size = sizeof(struct txq_info) +
-+	       ALIGN(hw->txq_data_size, sizeof(void *));
- 
--		txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp);
--		if (!txq_data)
--			goto free;
-+	txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp);
-+	if (!txq_data)
-+		goto free;
- 
--		for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
--			struct txq_info *txq = txq_data + i * size;
-+	for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
-+		struct txq_info *txq = txq_data + i * size;
- 
--			/* might not do anything for the bufferable MMPDU TXQ */
--			ieee80211_txq_init(sdata, sta, txq, i);
--		}
-+		/* might not do anything for the (bufferable) MMPDU TXQ */
-+		ieee80211_txq_init(sdata, sta, txq, i);
- 	}
- 
- 	if (sta_prepare_rate_control(local, sta, gfp))
-@@ -685,8 +681,7 @@ __sta_info_alloc(struct ieee80211_sub_if
- 	return sta;
- 
- free_txq:
--	if (sta->sta.txq[0])
--		kfree(to_txq_info(sta->sta.txq[0]));
-+	kfree(to_txq_info(sta->sta.txq[0]));
- free:
- 	sta_info_free_link(&sta->deflink);
- #ifdef CPTCFG_MAC80211_MESH
-@@ -1960,9 +1955,6 @@ ieee80211_sta_ps_deliver_response(struct
- 		 * TIM recalculation.
- 		 */
- 
--		if (!sta->sta.txq[0])
--			return;
--
- 		for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
- 			if (!sta->sta.txq[tid] ||
- 			    !(driver_release_tids & BIT(tid)) ||
-@@ -2447,7 +2439,7 @@ static void sta_set_tidstats(struct sta_
- 		tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid];
- 	}
- 
--	if (local->ops->wake_tx_queue && tid < IEEE80211_NUM_TIDS) {
-+	if (tid < IEEE80211_NUM_TIDS) {
- 		spin_lock_bh(&local->fq.lock);
- 		rcu_read_lock();
- 
-@@ -2775,9 +2767,6 @@ unsigned long ieee80211_sta_last_active(
- 
- static void sta_update_codel_params(struct sta_info *sta, u32 thr)
- {
--	if (!sta->sdata->local->ops->wake_tx_queue)
--		return;
--
- 	if (thr && thr < STA_SLOW_THRESHOLD * sta->local->num_sta) {
- 		sta->cparams.target = MS2TIME(50);
- 		sta->cparams.interval = MS2TIME(300);
---- a/net/mac80211/tdls.c
-+++ b/net/mac80211/tdls.c
-@@ -1016,7 +1016,6 @@ ieee80211_tdls_prep_mgmt_packet(struct w
- 		skb->priority = 256 + 5;
- 		break;
- 	}
--	skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb));
- 
- 	/*
- 	 * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress.
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1600,9 +1600,6 @@ int ieee80211_txq_setup_flows(struct iee
- 	bool supp_vht = false;
- 	enum nl80211_band band;
- 
--	if (!local->ops->wake_tx_queue)
--		return 0;
--
- 	ret = fq_init(fq, 4096);
- 	if (ret)
- 		return ret;
-@@ -1650,9 +1647,6 @@ void ieee80211_txq_teardown_flows(struct
- {
- 	struct fq *fq = &local->fq;
- 
--	if (!local->ops->wake_tx_queue)
--		return;
--
- 	kfree(local->cvars);
- 	local->cvars = NULL;
- 
-@@ -1669,8 +1663,7 @@ static bool ieee80211_queue_skb(struct i
- 	struct ieee80211_vif *vif;
- 	struct txq_info *txqi;
- 
--	if (!local->ops->wake_tx_queue ||
--	    sdata->vif.type == NL80211_IFTYPE_MONITOR)
-+	if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
- 		return false;
- 
- 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-@@ -4193,12 +4186,7 @@ void __ieee80211_subif_start_xmit(struct
- 	if (IS_ERR(sta))
- 		sta = NULL;
- 
--	if (local->ops->wake_tx_queue) {
--		u16 queue = __ieee80211_select_queue(sdata, sta, skb);
--		skb_set_queue_mapping(skb, queue);
--		skb_get_hash(skb);
--	}
--
-+	skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
- 	ieee80211_aggr_check(sdata, sta, skb);
- 
- 	sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
-@@ -4509,11 +4497,7 @@ static void ieee80211_8023_xmit(struct i
- 	struct tid_ampdu_tx *tid_tx;
- 	u8 tid;
- 
--	if (local->ops->wake_tx_queue) {
--		u16 queue = __ieee80211_select_queue(sdata, sta, skb);
--		skb_set_queue_mapping(skb, queue);
--		skb_get_hash(skb);
--	}
-+	skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
- 
- 	if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) &&
- 	    test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
-@@ -4767,9 +4751,6 @@ void ieee80211_tx_pending(struct tasklet
- 			if (!txok)
- 				break;
- 		}
--
--		if (skb_queue_empty(&local->pending[i]))
--			ieee80211_propagate_queue_wake(local, i);
- 	}
- 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
- 
-@@ -5962,10 +5943,9 @@ int ieee80211_tx_control_port(struct wip
- 	}
- 
- 	if (!IS_ERR(sta)) {
--		u16 queue = __ieee80211_select_queue(sdata, sta, skb);
-+		u16 queue = ieee80211_select_queue(sdata, sta, skb);
- 
- 		skb_set_queue_mapping(skb, queue);
--		skb_get_hash(skb);
- 
- 		/*
- 		 * for MLO STA, the SA should be the AP MLD address, but
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -444,39 +444,6 @@ void ieee80211_wake_txqs(struct tasklet_
- 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
- }
- 
--void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
--{
--	struct ieee80211_sub_if_data *sdata;
--	int n_acs = IEEE80211_NUM_ACS;
--
--	if (local->ops->wake_tx_queue)
--		return;
--
--	if (local->hw.queues < IEEE80211_NUM_ACS)
--		n_acs = 1;
--
--	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
--		int ac;
--
--		if (!sdata->dev)
--			continue;
--
--		if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE &&
--		    local->queue_stop_reasons[sdata->vif.cab_queue] != 0)
--			continue;
--
--		for (ac = 0; ac < n_acs; ac++) {
--			int ac_queue = sdata->vif.hw_queue[ac];
--
--			if (ac_queue == queue ||
--			    (sdata->vif.cab_queue == queue &&
--			     local->queue_stop_reasons[ac_queue] == 0 &&
--			     skb_queue_empty(&local->pending[ac_queue])))
--				netif_wake_subqueue(sdata->dev, ac);
--		}
--	}
--}
--
- static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
- 				   enum queue_stop_reason reason,
- 				   bool refcounted,
-@@ -507,11 +474,7 @@ static void __ieee80211_wake_queue(struc
- 		/* someone still has this queue stopped */
- 		return;
- 
--	if (skb_queue_empty(&local->pending[queue])) {
--		rcu_read_lock();
--		ieee80211_propagate_queue_wake(local, queue);
--		rcu_read_unlock();
--	} else
-+	if (!skb_queue_empty(&local->pending[queue]))
- 		tasklet_schedule(&local->tx_pending_tasklet);
- 
- 	/*
-@@ -521,12 +484,10 @@ static void __ieee80211_wake_queue(struc
- 	 * release someone's lock, but it is fine because all the callers of
- 	 * __ieee80211_wake_queue call it right before releasing the lock.
- 	 */
--	if (local->ops->wake_tx_queue) {
--		if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER)
--			tasklet_schedule(&local->wake_txqs_tasklet);
--		else
--			_ieee80211_wake_txqs(local, flags);
--	}
-+	if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER)
-+		tasklet_schedule(&local->wake_txqs_tasklet);
-+	else
-+		_ieee80211_wake_txqs(local, flags);
- }
- 
- void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
-@@ -554,8 +515,6 @@ static void __ieee80211_stop_queue(struc
- 				   bool refcounted)
- {
- 	struct ieee80211_local *local = hw_to_local(hw);
--	struct ieee80211_sub_if_data *sdata;
--	int n_acs = IEEE80211_NUM_ACS;
- 
- 	trace_stop_queue(local, queue, reason);
- 
-@@ -567,27 +526,7 @@ static void __ieee80211_stop_queue(struc
- 	else
- 		local->q_stop_reasons[queue][reason]++;
- 
--	if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue]))
--		return;
--
--	if (local->hw.queues < IEEE80211_NUM_ACS)
--		n_acs = 1;
--
--	rcu_read_lock();
--	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
--		int ac;
--
--		if (!sdata->dev)
--			continue;
--
--		for (ac = 0; ac < n_acs; ac++) {
--			if (!local->ops->wake_tx_queue &&
--			    (sdata->vif.hw_queue[ac] == queue ||
--			     sdata->vif.cab_queue == queue))
--				netif_stop_subqueue(sdata->dev, ac);
--		}
--	}
--	rcu_read_unlock();
-+	set_bit(reason, &local->queue_stop_reasons[queue]);
- }
- 
- void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
---- a/net/mac80211/wme.c
-+++ b/net/mac80211/wme.c
-@@ -122,6 +122,9 @@ u16 ieee80211_select_queue_80211(struct
- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- 	u8 *p;
- 
-+	/* Ensure hash is set prior to potential SW encryption */
-+	skb_get_hash(skb);
-+
- 	if ((info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER) ||
- 	    local->hw.queues < IEEE80211_NUM_ACS)
- 		return 0;
-@@ -141,13 +144,16 @@ u16 ieee80211_select_queue_80211(struct
- 	return ieee80211_downgrade_queue(sdata, NULL, skb);
- }
- 
--u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
--			     struct sta_info *sta, struct sk_buff *skb)
-+u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
-+			   struct sta_info *sta, struct sk_buff *skb)
- {
- 	const struct ethhdr *eth = (void *)skb->data;
- 	struct mac80211_qos_map *qos_map;
- 	bool qos;
- 
-+	/* Ensure hash is set prior to potential SW encryption */
-+	skb_get_hash(skb);
-+
- 	/* all mesh/ocb stations are required to support WME */
- 	if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT &&
- 	    !is_multicast_ether_addr(eth->h_dest)) ||
-@@ -178,59 +184,6 @@ u16 __ieee80211_select_queue(struct ieee
- 	return ieee80211_downgrade_queue(sdata, sta, skb);
- }
- 
--
--/* Indicate which queue to use. */
--u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
--			   struct sk_buff *skb)
--{
--	struct ieee80211_local *local = sdata->local;
--	struct sta_info *sta = NULL;
--	const u8 *ra = NULL;
--	u16 ret;
--
--	/* when using iTXQ, we can do this later */
--	if (local->ops->wake_tx_queue)
--		return 0;
--
--	if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
--		skb->priority = 0; /* required for correct WPA/11i MIC */
--		return 0;
--	}
--
--	rcu_read_lock();
--	switch (sdata->vif.type) {
--	case NL80211_IFTYPE_AP_VLAN:
--		sta = rcu_dereference(sdata->u.vlan.sta);
--		if (sta)
--			break;
--		fallthrough;
--	case NL80211_IFTYPE_AP:
--		ra = skb->data;
--		break;
--	case NL80211_IFTYPE_STATION:
--		/* might be a TDLS station */
--		sta = sta_info_get(sdata, skb->data);
--		if (sta)
--			break;
--
--		ra = sdata->deflink.u.mgd.bssid;
--		break;
--	case NL80211_IFTYPE_ADHOC:
--		ra = skb->data;
--		break;
--	default:
--		break;
--	}
--
--	if (!sta && ra && !is_multicast_ether_addr(ra))
--		sta = sta_info_get(sdata, ra);
--
--	ret = __ieee80211_select_queue(sdata, sta, skb);
--
--	rcu_read_unlock();
--	return ret;
--}
--
- /**
-  * ieee80211_set_qos_hdr - Fill in the QoS header if there is one.
-  *
---- a/net/mac80211/wme.h
-+++ b/net/mac80211/wme.h
-@@ -13,10 +13,8 @@
- u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
- 				 struct sk_buff *skb,
- 				 struct ieee80211_hdr *hdr);
--u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
--			     struct sta_info *sta, struct sk_buff *skb);
- u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
--			   struct sk_buff *skb);
-+			   struct sta_info *sta, struct sk_buff *skb);
- void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
- 			   struct sk_buff *skb);
- 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch
deleted file mode 100644
index f0dfc75..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Mon, 10 Oct 2022 19:17:46 +0200
-Subject: [PATCH] wifi: realtek: remove duplicated wake_tx_queue
-
-By accident, the previous patch duplicated the initialization
-of the wake_tx_queue callback. Fix that by removing the new
-initializations.
-
-Fixes: a790cc3a4fad ("wifi: mac80211: add wake_tx_queue callback to drivers")
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/drivers/net/wireless/realtek/rtw88/mac80211.c
-+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
-@@ -896,7 +896,6 @@ static void rtw_ops_sta_rc_update(struct
- 
- const struct ieee80211_ops rtw_ops = {
- 	.tx			= rtw_ops_tx,
--	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.wake_tx_queue		= rtw_ops_wake_tx_queue,
- 	.start			= rtw_ops_start,
- 	.stop			= rtw_ops_stop,
---- a/drivers/net/wireless/realtek/rtw89/mac80211.c
-+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
-@@ -918,7 +918,6 @@ static int rtw89_ops_set_tid_config(stru
- 
- const struct ieee80211_ops rtw89_ops = {
- 	.tx			= rtw89_ops_tx,
--	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
- 	.wake_tx_queue		= rtw89_ops_wake_tx_queue,
- 	.start			= rtw89_ops_start,
- 	.stop			= rtw89_ops_stop,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/310-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch
similarity index 94%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/310-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch
index f7391a5..f362751 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/310-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch
@@ -14,7 +14,7 @@
 
 --- a/net/mac80211/mesh.c
 +++ b/net/mac80211/mesh.c
-@@ -703,6 +703,9 @@ bool ieee80211_mesh_xmit_fast(struct iee
+@@ -765,6 +765,9 @@ bool ieee80211_mesh_xmit_fast(struct iee
  			      struct sk_buff *skb, u32 ctrl_flags)
  {
  	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -24,7 +24,7 @@
  	struct ieee80211_mesh_fast_tx *entry;
  	struct ieee80211s_hdr *meshhdr;
  	u8 sa[ETH_ALEN] __aligned(2);
-@@ -738,7 +741,10 @@ bool ieee80211_mesh_xmit_fast(struct iee
+@@ -800,7 +803,10 @@ bool ieee80211_mesh_xmit_fast(struct iee
  			return false;
  	}
  
@@ -38,7 +38,7 @@
  
 --- a/net/mac80211/mesh.h
 +++ b/net/mac80211/mesh.h
-@@ -133,9 +133,33 @@ struct mesh_path {
+@@ -134,9 +134,33 @@ struct mesh_path {
  #define MESH_FAST_TX_CACHE_TIMEOUT		8000 /* msecs */
  
  /**
@@ -73,7 +73,7 @@
   * @fast_tx: base fast_tx data
   * @hdr: cached mesh and rfc1042 headers
   * @hdrlen: length of mesh + rfc1042
-@@ -146,7 +170,7 @@ struct mesh_path {
+@@ -147,7 +171,7 @@ struct mesh_path {
   */
  struct ieee80211_mesh_fast_tx {
  	struct rhash_head rhash;
@@ -82,7 +82,7 @@
  
  	struct ieee80211_fast_tx fast_tx;
  	u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)];
-@@ -329,7 +353,8 @@ void mesh_path_tx_root_frame(struct ieee
+@@ -334,7 +358,8 @@ void mesh_path_tx_root_frame(struct ieee
  
  bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
  struct ieee80211_mesh_fast_tx *
@@ -189,7 +189,7 @@
  
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -2726,7 +2726,10 @@ ieee80211_rx_mesh_fast_forward(struct ie
+@@ -2727,7 +2727,10 @@ ieee80211_rx_mesh_fast_forward(struct ie
  			       struct sk_buff *skb, int hdrlen)
  {
  	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -201,7 +201,7 @@
  	struct ieee80211s_hdr *mesh_hdr;
  	struct tid_ampdu_tx *tid_tx;
  	struct sta_info *sta;
-@@ -2735,9 +2738,13 @@ ieee80211_rx_mesh_fast_forward(struct ie
+@@ -2736,9 +2739,13 @@ ieee80211_rx_mesh_fast_forward(struct ie
  
  	mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth));
  	if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch
deleted file mode 100644
index 812b121..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch
+++ /dev/null
@@ -1,506 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 9 Oct 2022 20:15:46 +0200
-Subject: [PATCH] mac80211: add support for restricting netdev features per vif
-
-This can be used to selectively disable feature flags for checksum offload,
-scatter/gather or GSO by changing vif->netdev_features.
-Removing features from vif->netdev_features does not affect the netdev
-features themselves, but instead fixes up skbs in the tx path so that the
-offloads are not needed in the driver.
-
-Aside from making it easier to deal with vif type based hardware limitations,
-this also makes it possible to optimize performance on hardware without native
-GSO support by declaring GSO support in hw->netdev_features and removing it
-from vif->netdev_features. This allows mac80211 to handle GSO segmentation
-after the sta lookup, but before itxq enqueue, thus reducing the number of
-unnecessary sta lookups, as well as some other per-packet processing.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/fq_impl.h
-+++ b/include/net/fq_impl.h
-@@ -200,6 +200,7 @@ static void fq_tin_enqueue(struct fq *fq
- 			   fq_skb_free_t free_func)
- {
- 	struct fq_flow *flow;
-+	struct sk_buff *next;
- 	bool oom;
- 
- 	lockdep_assert_held(&fq->lock);
-@@ -214,11 +215,15 @@ static void fq_tin_enqueue(struct fq *fq
- 	}
- 
- 	flow->tin = tin;
--	flow->backlog += skb->len;
--	tin->backlog_bytes += skb->len;
--	tin->backlog_packets++;
--	fq->memory_usage += skb->truesize;
--	fq->backlog++;
-+	skb_list_walk_safe(skb, skb, next) {
-+		skb_mark_not_on_list(skb);
-+		flow->backlog += skb->len;
-+		tin->backlog_bytes += skb->len;
-+		tin->backlog_packets++;
-+		fq->memory_usage += skb->truesize;
-+		fq->backlog++;
-+		__skb_queue_tail(&flow->queue, skb);
-+	}
- 
- 	if (list_empty(&flow->flowchain)) {
- 		flow->deficit = fq->quantum;
-@@ -226,7 +231,6 @@ static void fq_tin_enqueue(struct fq *fq
- 			      &tin->new_flows);
- 	}
- 
--	__skb_queue_tail(&flow->queue, skb);
- 	oom = (fq->memory_usage > fq->memory_limit);
- 	while (fq->backlog > fq->limit || oom) {
- 		flow = fq_find_fattest_flow(fq);
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1807,6 +1807,10 @@ struct ieee80211_vif_cfg {
-  * @addr: address of this interface
-  * @p2p: indicates whether this AP or STA interface is a p2p
-  *	interface, i.e. a GO or p2p-sta respectively
-+ * @netdev_features: tx netdev features supported by the hardware for this
-+ *	vif. mac80211 initializes this to hw->netdev_features, and the driver
-+ *	can mask out specific tx features. mac80211 will handle software fixup
-+ *	for masked offloads (GSO, CSUM)
-  * @driver_flags: flags/capabilities the driver has for this interface,
-  *	these need to be set (or cleared) when the interface is added
-  *	or, if supported by the driver, the interface type is changed
-@@ -1846,6 +1850,7 @@ struct ieee80211_vif {
- 
- 	struct ieee80211_txq *txq;
- 
-+	netdev_features_t netdev_features;
- 	u32 driver_flags;
- 	u32 offload_flags;
- 
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -2181,6 +2181,7 @@ int ieee80211_if_add(struct ieee80211_lo
- 		ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
- 		ndev->hw_features |= ndev->features &
- 					MAC80211_SUPPORTED_FEATURES_TX;
-+		sdata->vif.netdev_features = local->hw.netdev_features;
- 
- 		netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
- 
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1356,7 +1356,11 @@ static struct txq_info *ieee80211_get_tx
- 
- static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb)
- {
--	IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
-+	struct sk_buff *next;
-+	codel_time_t now = codel_get_time();
-+
-+	skb_list_walk_safe(skb, skb, next)
-+		IEEE80211_SKB_CB(skb)->control.enqueue_time = now;
- }
- 
- static u32 codel_skb_len_func(const struct sk_buff *skb)
-@@ -3579,55 +3583,79 @@ ieee80211_xmit_fast_finish(struct ieee80
- 	return TX_CONTINUE;
- }
- 
--static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
--				struct sta_info *sta,
--				struct ieee80211_fast_tx *fast_tx,
--				struct sk_buff *skb)
-+static netdev_features_t
-+ieee80211_sdata_netdev_features(struct ieee80211_sub_if_data *sdata)
- {
--	struct ieee80211_local *local = sdata->local;
--	u16 ethertype = (skb->data[12] << 8) | skb->data[13];
--	int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
--	int hw_headroom = sdata->local->hw.extra_tx_headroom;
--	struct ethhdr eth;
--	struct ieee80211_tx_info *info;
--	struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
--	struct ieee80211_tx_data tx;
--	ieee80211_tx_result r;
--	struct tid_ampdu_tx *tid_tx = NULL;
--	u8 tid = IEEE80211_NUM_TIDS;
-+	if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
-+		return sdata->vif.netdev_features;
- 
--	/* control port protocol needs a lot of special handling */
--	if (cpu_to_be16(ethertype) == sdata->control_port_protocol)
--		return false;
-+	if (!sdata->bss)
-+		return 0;
- 
--	/* only RFC 1042 SNAP */
--	if (ethertype < ETH_P_802_3_MIN)
--		return false;
-+	sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
-+	return sdata->vif.netdev_features;
-+}
- 
--	/* don't handle TX status request here either */
--	if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)
--		return false;
-+static struct sk_buff *
-+ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features)
-+{
-+	if (skb_is_gso(skb)) {
-+		struct sk_buff *segs;
- 
--	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
--		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
--		tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
--		if (tid_tx) {
--			if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state))
--				return false;
--			if (tid_tx->timeout)
--				tid_tx->last_tx = jiffies;
--		}
-+		segs = skb_gso_segment(skb, features);
-+		if (!segs)
-+			return skb;
-+		if (IS_ERR(segs))
-+			goto free;
-+
-+		consume_skb(skb);
-+		return segs;
- 	}
- 
--	/* after this point (skb is modified) we cannot return false */
-+	if (skb_needs_linearize(skb, features) && __skb_linearize(skb))
-+		goto free;
-+
-+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-+		int ofs = skb_checksum_start_offset(skb);
-+
-+		if (skb->encapsulation)
-+			skb_set_inner_transport_header(skb, ofs);
-+		else
-+			skb_set_transport_header(skb, ofs);
-+
-+		if (skb_csum_hwoffload_help(skb, features))
-+			goto free;
-+	}
-+
-+	skb_mark_not_on_list(skb);
-+	return skb;
-+
-+free:
-+	kfree_skb(skb);
-+	return NULL;
-+}
-+
-+static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
-+				  struct sta_info *sta,
-+				  struct ieee80211_fast_tx *fast_tx,
-+				  struct sk_buff *skb, u8 tid, bool ampdu)
-+{
-+	struct ieee80211_local *local = sdata->local;
-+	struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
-+	struct ieee80211_tx_info *info;
-+	struct ieee80211_tx_data tx;
-+	ieee80211_tx_result r;
-+	int hw_headroom = sdata->local->hw.extra_tx_headroom;
-+	int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
-+	struct ethhdr eth;
- 
- 	skb = skb_share_check(skb, GFP_ATOMIC);
- 	if (unlikely(!skb))
--		return true;
-+		return;
- 
- 	if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) &&
- 	    ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb))
--		return true;
-+		return;
- 
- 	/* will not be crypto-handled beyond what we do here, so use false
- 	 * as the may-encrypt argument for the resize to not account for
-@@ -3636,10 +3664,8 @@ static bool ieee80211_xmit_fast(struct i
- 	if (unlikely(ieee80211_skb_resize(sdata, skb,
- 					  max_t(int, extra_head + hw_headroom -
- 						     skb_headroom(skb), 0),
--					  ENCRYPT_NO))) {
--		kfree_skb(skb);
--		return true;
--	}
-+					  ENCRYPT_NO)))
-+		goto free;
- 
- 	memcpy(&eth, skb->data, ETH_HLEN - 2);
- 	hdr = skb_push(skb, extra_head);
-@@ -3653,7 +3679,7 @@ static bool ieee80211_xmit_fast(struct i
- 	info->control.vif = &sdata->vif;
- 	info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT |
- 		      IEEE80211_TX_CTL_DONTFRAG |
--		      (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0);
-+		      (ampdu ? IEEE80211_TX_CTL_AMPDU : 0);
- 	info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT |
- 			      u32_encode_bits(IEEE80211_LINK_UNSPECIFIED,
- 					      IEEE80211_TX_CTRL_MLO_LINK);
-@@ -3677,16 +3703,14 @@ static bool ieee80211_xmit_fast(struct i
- 	tx.key = fast_tx->key;
- 
- 	if (ieee80211_queue_skb(local, sdata, sta, skb))
--		return true;
-+		return;
- 
- 	tx.skb = skb;
- 	r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs,
- 				       fast_tx->key, &tx);
- 	tx.skb = NULL;
--	if (r == TX_DROP) {
--		kfree_skb(skb);
--		return true;
--	}
-+	if (r == TX_DROP)
-+		goto free;
- 
- 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- 		sdata = container_of(sdata->bss,
-@@ -3694,6 +3718,56 @@ static bool ieee80211_xmit_fast(struct i
- 
- 	__skb_queue_tail(&tx.skbs, skb);
- 	ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false);
-+	return;
-+
-+free:
-+	kfree_skb(skb);
-+}
-+
-+static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
-+				struct sta_info *sta,
-+				struct ieee80211_fast_tx *fast_tx,
-+				struct sk_buff *skb)
-+{
-+	u16 ethertype = (skb->data[12] << 8) | skb->data[13];
-+	struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
-+	struct tid_ampdu_tx *tid_tx = NULL;
-+	struct sk_buff *next;
-+	u8 tid = IEEE80211_NUM_TIDS;
-+
-+	/* control port protocol needs a lot of special handling */
-+	if (cpu_to_be16(ethertype) == sdata->control_port_protocol)
-+		return false;
-+
-+	/* only RFC 1042 SNAP */
-+	if (ethertype < ETH_P_802_3_MIN)
-+		return false;
-+
-+	/* don't handle TX status request here either */
-+	if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)
-+		return false;
-+
-+	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
-+		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-+		tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
-+		if (tid_tx) {
-+			if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state))
-+				return false;
-+			if (tid_tx->timeout)
-+				tid_tx->last_tx = jiffies;
-+		}
-+	}
-+
-+	/* after this point (skb is modified) we cannot return false */
-+	skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata));
-+	if (!skb)
-+		return true;
-+
-+	skb_list_walk_safe(skb, skb, next) {
-+		skb_mark_not_on_list(skb);
-+		__ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx);
-+	}
-+
- 	return true;
- }
- 
-@@ -4201,31 +4275,14 @@ void __ieee80211_subif_start_xmit(struct
- 			goto out;
- 	}
- 
--	if (skb_is_gso(skb)) {
--		struct sk_buff *segs;
--
--		segs = skb_gso_segment(skb, 0);
--		if (IS_ERR(segs)) {
--			goto out_free;
--		} else if (segs) {
--			consume_skb(skb);
--			skb = segs;
--		}
--	} else {
--		/* we cannot process non-linear frames on this path */
--		if (skb_linearize(skb))
--			goto out_free;
--
--		/* the frame could be fragmented, software-encrypted, and other
--		 * things so we cannot really handle checksum offload with it -
--		 * fix it up in software before we handle anything else.
--		 */
--		if (skb->ip_summed == CHECKSUM_PARTIAL) {
--			skb_set_transport_header(skb,
--						 skb_checksum_start_offset(skb));
--			if (skb_checksum_help(skb))
--				goto out_free;
--		}
-+	/* the frame could be fragmented, software-encrypted, and other
-+	 * things so we cannot really handle checksum or GSO offload.
-+	 * fix it up in software before we handle anything else.
-+	 */
-+	skb = ieee80211_tx_skb_fixup(skb, 0);
-+	if (!skb) {
-+		len = 0;
-+		goto out;
- 	}
- 
- 	skb_list_walk_safe(skb, skb, next) {
-@@ -4443,9 +4500,11 @@ normal:
- 	return NETDEV_TX_OK;
- }
- 
--static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
--			      struct sk_buff *skb, struct sta_info *sta,
--			      bool txpending)
-+
-+
-+static bool __ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
-+				struct sk_buff *skb, struct sta_info *sta,
-+				bool txpending)
- {
- 	struct ieee80211_local *local = sdata->local;
- 	struct ieee80211_tx_control control = {};
-@@ -4454,14 +4513,6 @@ static bool ieee80211_tx_8023(struct iee
- 	unsigned long flags;
- 	int q = info->hw_queue;
- 
--	if (sta)
--		sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift);
--
--	ieee80211_tpt_led_trig_tx(local, skb->len);
--
--	if (ieee80211_queue_skb(local, sdata, sta, skb))
--		return true;
--
- 	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
- 
- 	if (local->queue_stop_reasons[q] ||
-@@ -4488,6 +4539,26 @@ static bool ieee80211_tx_8023(struct iee
- 	return true;
- }
- 
-+static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
-+			      struct sk_buff *skb, struct sta_info *sta,
-+			      bool txpending)
-+{
-+	struct ieee80211_local *local = sdata->local;
-+	struct sk_buff *next;
-+	bool ret = true;
-+
-+	if (ieee80211_queue_skb(local, sdata, sta, skb))
-+		return true;
-+
-+	skb_list_walk_safe(skb, skb, next) {
-+		skb_mark_not_on_list(skb);
-+		if (!__ieee80211_tx_8023(sdata, skb, sta, txpending))
-+			ret = false;
-+	}
-+
-+	return ret;
-+}
-+
- static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
- 				struct net_device *dev, struct sta_info *sta,
- 				struct ieee80211_key *key, struct sk_buff *skb)
-@@ -4495,9 +4566,13 @@ static void ieee80211_8023_xmit(struct i
- 	struct ieee80211_tx_info *info;
- 	struct ieee80211_local *local = sdata->local;
- 	struct tid_ampdu_tx *tid_tx;
-+	struct sk_buff *seg, *next;
-+	unsigned int skbs = 0, len = 0;
-+	u16 queue;
- 	u8 tid;
- 
--	skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
-+	queue = ieee80211_select_queue(sdata, sta, skb);
-+	skb_set_queue_mapping(skb, queue);
- 
- 	if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) &&
- 	    test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
-@@ -4507,9 +4582,6 @@ static void ieee80211_8023_xmit(struct i
- 	if (unlikely(!skb))
- 		return;
- 
--	info = IEEE80211_SKB_CB(skb);
--	memset(info, 0, sizeof(*info));
--
- 	ieee80211_aggr_check(sdata, sta, skb);
- 
- 	tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-@@ -4523,22 +4595,20 @@ static void ieee80211_8023_xmit(struct i
- 			return;
- 		}
- 
--		info->flags |= IEEE80211_TX_CTL_AMPDU;
- 		if (tid_tx->timeout)
- 			tid_tx->last_tx = jiffies;
- 	}
- 
--	if (unlikely(skb->sk &&
--		     skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS))
--		info->ack_frame_id = ieee80211_store_ack_skb(local, skb,
--							     &info->flags, NULL);
-+	skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata));
-+	if (!skb)
-+		return;
- 
--	info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
-+	info = IEEE80211_SKB_CB(skb);
-+	memset(info, 0, sizeof(*info));
-+	if (tid_tx)
-+		info->flags |= IEEE80211_TX_CTL_AMPDU;
- 
--	dev_sw_netstats_tx_add(dev, 1, skb->len);
--
--	sta->deflink.tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
--	sta->deflink.tx_stats.packets[skb_get_queue_mapping(skb)]++;
-+	info->hw_queue = sdata->vif.hw_queue[queue];
- 
- 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- 		sdata = container_of(sdata->bss,
-@@ -4550,6 +4620,24 @@ static void ieee80211_8023_xmit(struct i
- 	if (key)
- 		info->control.hw_key = &key->conf;
- 
-+	skb_list_walk_safe(skb, seg, next) {
-+		skbs++;
-+		len += seg->len;
-+		if (seg != skb)
-+			memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info));
-+	}
-+
-+	if (unlikely(skb->sk &&
-+		     skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS))
-+		info->ack_frame_id = ieee80211_store_ack_skb(local, skb,
-+							     &info->flags, NULL);
-+
-+	dev_sw_netstats_tx_add(dev, skbs, len);
-+	sta->deflink.tx_stats.packets[queue] += skbs;
-+	sta->deflink.tx_stats.bytes[queue] += len;
-+
-+	ieee80211_tpt_led_trig_tx(local, len);
-+
- 	ieee80211_tx_8023(sdata, skb, sta, false);
- 
- 	return;
-@@ -4591,6 +4679,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8
- 		    key->conf.cipher == WLAN_CIPHER_SUITE_TKIP))
- 		goto skip_offload;
- 
-+	sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
- 	ieee80211_8023_xmit(sdata, dev, sta, key, skb);
- 	goto out;
- 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/311-mac80211-fix-mesh-id-corruption-on-32-bit-systems.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/311-mac80211-fix-mesh-id-corruption-on-32-bit-systems.patch
new file mode 100644
index 0000000..c0c774a
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/311-mac80211-fix-mesh-id-corruption-on-32-bit-systems.patch
@@ -0,0 +1,62 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Tue, 12 Sep 2023 15:09:27 +0200
+Subject: [PATCH] mac80211: fix mesh id corruption on 32 bit systems
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since the changed field size was increased to u64, mesh_bss_info_changed
+pulls invalid bits from the first 3 bytes of the mesh id, clears them, and
+passes them on to ieee80211_link_info_change_notify, because
+ifmsh->mbss_changed was not updated to match its size.
+Fix this by turning into ifmsh->mbss_changed into an unsigned long array with
+64 bit size.
+
+Fixes: 15ddba5f4311 ("wifi: mac80211: consistently use u64 for BSS changes")
+Reported-by: Thomas Hühn <thomas.huehn@hs-nordhausen.de>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -678,7 +678,7 @@ struct ieee80211_if_mesh {
+ 	struct timer_list mesh_path_root_timer;
+ 
+ 	unsigned long wrkq_flags;
+-	unsigned long mbss_changed;
++	unsigned long mbss_changed[64 / BITS_PER_LONG];
+ 
+ 	bool userspace_handles_dfs;
+ 
+--- a/net/mac80211/mesh.c
++++ b/net/mac80211/mesh.c
+@@ -1181,7 +1181,7 @@ void ieee80211_mbss_info_change_notify(s
+ 
+ 	/* if we race with running work, worst case this work becomes a noop */
+ 	for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
+-		set_bit(bit, &ifmsh->mbss_changed);
++		set_bit(bit, ifmsh->mbss_changed);
+ 	set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags);
+ 	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
+ }
+@@ -1263,7 +1263,7 @@ void ieee80211_stop_mesh(struct ieee8021
+ 
+ 	/* clear any mesh work (for next join) we may have accrued */
+ 	ifmsh->wrkq_flags = 0;
+-	ifmsh->mbss_changed = 0;
++	memset(ifmsh->mbss_changed, 0, sizeof(ifmsh->mbss_changed));
+ 
+ 	local->fif_other_bss--;
+ 	atomic_dec(&local->iff_allmultis);
+@@ -1730,9 +1730,9 @@ static void mesh_bss_info_changed(struct
+ 	u32 bit;
+ 	u64 changed = 0;
+ 
+-	for_each_set_bit(bit, &ifmsh->mbss_changed,
++	for_each_set_bit(bit, ifmsh->mbss_changed,
+ 			 sizeof(changed) * BITS_PER_BYTE) {
+-		clear_bit(bit, &ifmsh->mbss_changed);
++		clear_bit(bit, ifmsh->mbss_changed);
+ 		changed |= BIT(bit);
+ 	}
+ 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch
deleted file mode 100644
index 804b02e..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 1 Dec 2022 14:57:30 +0100
-Subject: [PATCH] wifi: mac80211: fix and simplify unencrypted drop check for
- mesh
-
-ieee80211_drop_unencrypted is called from ieee80211_rx_h_mesh_fwding and
-ieee80211_frame_allowed.
-
-Since ieee80211_rx_h_mesh_fwding can forward packets for other mesh nodes
-and is called earlier, it needs to check the decryptions status and if the
-packet is using the control protocol on its own, instead of deferring to
-the later call from ieee80211_frame_allowed.
-
-Because of that, ieee80211_drop_unencrypted has a mesh specific check
-that skips over the mesh header in order to check the payload protocol.
-This code is invalid when called from ieee80211_frame_allowed, since that
-happens after the 802.11->802.3 conversion.
-
-Fix this by moving the mesh specific check directly into
-ieee80211_rx_h_mesh_fwding.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-Link: https://lore.kernel.org/r/20221201135730.19723-1-nbd@nbd.name
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2403,7 +2403,6 @@ static int ieee80211_802_1x_port_control
- 
- static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
- {
--	struct ieee80211_hdr *hdr = (void *)rx->skb->data;
- 	struct sk_buff *skb = rx->skb;
- 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
- 
-@@ -2414,31 +2413,6 @@ static int ieee80211_drop_unencrypted(st
- 	if (status->flag & RX_FLAG_DECRYPTED)
- 		return 0;
- 
--	/* check mesh EAPOL frames first */
--	if (unlikely(rx->sta && ieee80211_vif_is_mesh(&rx->sdata->vif) &&
--		     ieee80211_is_data(fc))) {
--		struct ieee80211s_hdr *mesh_hdr;
--		u16 hdr_len = ieee80211_hdrlen(fc);
--		u16 ethertype_offset;
--		__be16 ethertype;
--
--		if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr))
--			goto drop_check;
--
--		/* make sure fixed part of mesh header is there, also checks skb len */
--		if (!pskb_may_pull(rx->skb, hdr_len + 6))
--			goto drop_check;
--
--		mesh_hdr = (struct ieee80211s_hdr *)(skb->data + hdr_len);
--		ethertype_offset = hdr_len + ieee80211_get_mesh_hdrlen(mesh_hdr) +
--				   sizeof(rfc1042_header);
--
--		if (skb_copy_bits(rx->skb, ethertype_offset, &ethertype, 2) == 0 &&
--		    ethertype == rx->sdata->control_port_protocol)
--			return 0;
--	}
--
--drop_check:
- 	/* Drop unencrypted frames if key is set. */
- 	if (unlikely(!ieee80211_has_protected(fc) &&
- 		     !ieee80211_is_any_nullfunc(fc) &&
-@@ -2892,8 +2866,16 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
- 	hdr = (struct ieee80211_hdr *) skb->data;
- 	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
- 
--	if (ieee80211_drop_unencrypted(rx, hdr->frame_control))
--		return RX_DROP_MONITOR;
-+	if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) {
-+		int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) +
-+			     sizeof(rfc1042_header);
-+		__be16 ethertype;
-+
-+		if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) ||
-+		    skb_copy_bits(rx->skb, offset, &ethertype, 2) != 0 ||
-+		    ethertype != rx->sdata->control_port_protocol)
-+			return RX_DROP_MONITOR;
-+	}
- 
- 	/* frame is in RMC, don't forward */
- 	if (ieee80211_is_data(hdr->frame_control) &&
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch
deleted file mode 100644
index f668905..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 2 Dec 2022 13:53:11 +0100
-Subject: [PATCH] wifi: cfg80211: move A-MSDU check in
- ieee80211_data_to_8023_exthdr
-
-When parsing the outer A-MSDU header, don't check for inner bridge tunnel
-or RFC1042 headers. This is handled by ieee80211_amsdu_to_8023s already.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -631,8 +631,9 @@ int ieee80211_data_to_8023_exthdr(struct
- 		break;
- 	}
- 
--	if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
--	           ((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) &&
-+	if (likely(!is_amsdu &&
-+		   skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
-+	           ((ether_addr_equal(payload.hdr, rfc1042_header) &&
- 		     payload.proto != htons(ETH_P_AARP) &&
- 		     payload.proto != htons(ETH_P_IPX)) ||
- 		    ether_addr_equal(payload.hdr, bridge_tunnel_header)))) {
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/312-wifi-cfg80211-annotate-iftype_data-pointer-with-spar.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/312-wifi-cfg80211-annotate-iftype_data-pointer-with-spar.patch
new file mode 100644
index 0000000..18420a8
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/312-wifi-cfg80211-annotate-iftype_data-pointer-with-spar.patch
@@ -0,0 +1,467 @@
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Mon, 28 Aug 2023 09:54:39 +0200
+Subject: [PATCH] wifi: cfg80211: annotate iftype_data pointer with sparse
+
+There were are a number of cases in mac80211 and iwlwifi (at
+least) that used the sband->iftype_data pointer directly,
+instead of using the accessors to find the right array entry
+to use.
+
+Make sparse warn when such a thing is done.
+
+To not have a lot of casts, add two helper functions/macros
+
+ - ieee80211_set_sband_iftype_data()
+ - for_each_sband_iftype_data()
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -5893,8 +5893,9 @@ static void ath11k_mac_setup_he_cap(stru
+ 					       ar->mac.iftype[NL80211_BAND_2GHZ],
+ 					       NL80211_BAND_2GHZ);
+ 		band = &ar->mac.sbands[NL80211_BAND_2GHZ];
+-		band->iftype_data = ar->mac.iftype[NL80211_BAND_2GHZ];
+-		band->n_iftype_data = count;
++		_ieee80211_set_sband_iftype_data(band,
++						 ar->mac.iftype[NL80211_BAND_2GHZ],
++						 count);
+ 	}
+ 
+ 	if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
+@@ -5902,8 +5903,9 @@ static void ath11k_mac_setup_he_cap(stru
+ 					       ar->mac.iftype[NL80211_BAND_5GHZ],
+ 					       NL80211_BAND_5GHZ);
+ 		band = &ar->mac.sbands[NL80211_BAND_5GHZ];
+-		band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
+-		band->n_iftype_data = count;
++		_ieee80211_set_sband_iftype_data(band,
++						 ar->mac.iftype[NL80211_BAND_5GHZ],
++						 count);
+ 	}
+ 
+ 	if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
+@@ -5912,8 +5914,9 @@ static void ath11k_mac_setup_he_cap(stru
+ 					       ar->mac.iftype[NL80211_BAND_6GHZ],
+ 					       NL80211_BAND_6GHZ);
+ 		band = &ar->mac.sbands[NL80211_BAND_6GHZ];
+-		band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ];
+-		band->n_iftype_data = count;
++		_ieee80211_set_sband_iftype_data(band,
++						 ar->mac.iftype[NL80211_BAND_6GHZ],
++						 count);
+ 	}
+ }
+ 
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+@@ -1075,8 +1075,8 @@ static void iwl_init_he_hw_capab(struct
+ 
+ 	memcpy(iftype_data, iwl_he_eht_capa, sizeof(iwl_he_eht_capa));
+ 
+-	sband->iftype_data = iftype_data;
+-	sband->n_iftype_data = ARRAY_SIZE(iwl_he_eht_capa);
++	_ieee80211_set_sband_iftype_data(sband, iftype_data,
++					 ARRAY_SIZE(iwl_he_eht_capa));
+ 
+ 	for (i = 0; i < sband->n_iftype_data; i++)
+ 		iwl_nvm_fixup_sband_iftd(trans, data, sband, &iftype_data[i],
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -1119,8 +1119,7 @@ void mt7915_set_stream_he_caps(struct mt
+ 		n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);
+ 
+ 		band = &phy->mt76->sband_2g.sband;
+-		band->iftype_data = data;
+-		band->n_iftype_data = n;
++		_ieee80211_set_sband_iftype_data(band, data, n);
+ 	}
+ 
+ 	if (phy->mt76->cap.has_5ghz) {
+@@ -1128,8 +1127,7 @@ void mt7915_set_stream_he_caps(struct mt
+ 		n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);
+ 
+ 		band = &phy->mt76->sband_5g.sband;
+-		band->iftype_data = data;
+-		band->n_iftype_data = n;
++		_ieee80211_set_sband_iftype_data(band, data, n);
+ 	}
+ 
+ 	if (phy->mt76->cap.has_6ghz) {
+@@ -1137,8 +1135,7 @@ void mt7915_set_stream_he_caps(struct mt
+ 		n = mt7915_init_he_caps(phy, NL80211_BAND_6GHZ, data);
+ 
+ 		band = &phy->mt76->sband_6g.sband;
+-		band->iftype_data = data;
+-		band->n_iftype_data = n;
++		_ieee80211_set_sband_iftype_data(band, data, n);
+ 	}
+ }
+ 
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -196,8 +196,7 @@ void mt7921_set_stream_he_caps(struct mt
+ 		n = mt7921_init_he_caps(phy, NL80211_BAND_2GHZ, data);
+ 
+ 		band = &phy->mt76->sband_2g.sband;
+-		band->iftype_data = data;
+-		band->n_iftype_data = n;
++		_ieee80211_set_sband_iftype_data(band, data, n);
+ 	}
+ 
+ 	if (phy->mt76->cap.has_5ghz) {
+@@ -205,16 +204,14 @@ void mt7921_set_stream_he_caps(struct mt
+ 		n = mt7921_init_he_caps(phy, NL80211_BAND_5GHZ, data);
+ 
+ 		band = &phy->mt76->sband_5g.sband;
+-		band->iftype_data = data;
+-		band->n_iftype_data = n;
++		_ieee80211_set_sband_iftype_data(band, data, n);
+ 
+ 		if (phy->mt76->cap.has_6ghz) {
+ 			data = phy->iftype[NL80211_BAND_6GHZ];
+ 			n = mt7921_init_he_caps(phy, NL80211_BAND_6GHZ, data);
+ 
+ 			band = &phy->mt76->sband_6g.sband;
+-			band->iftype_data = data;
+-			band->n_iftype_data = n;
++			_ieee80211_set_sband_iftype_data(band, data, n);
+ 		}
+ 	}
+ }
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+@@ -823,8 +823,7 @@ __mt7996_set_stream_he_eht_caps(struct m
+ 		n++;
+ 	}
+ 
+-	sband->iftype_data = data;
+-	sband->n_iftype_data = n;
++	_ieee80211_set_sband_iftype_data(sband, data, n);
+ }
+ 
+ void mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy)
+--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
+@@ -1335,7 +1335,7 @@ static int qtnf_cmd_band_fill_iftype(con
+ 		return -EINVAL;
+ 	}
+ 
+-	kfree(band->iftype_data);
++	kfree((__force void *)band->iftype_data);
+ 	band->iftype_data = NULL;
+ 	band->n_iftype_data = tlv->n_iftype_data;
+ 	if (band->n_iftype_data == 0)
+@@ -1347,7 +1347,8 @@ static int qtnf_cmd_band_fill_iftype(con
+ 		band->n_iftype_data = 0;
+ 		return -ENOMEM;
+ 	}
+-	band->iftype_data = iftype_data;
++
++	_ieee80211_set_sband_iftype_data(band, iftype_data, tlv->n_iftype_data);
+ 
+ 	for (i = 0; i < band->n_iftype_data; i++)
+ 		qtnf_cmd_conv_iftype(iftype_data++, &tlv->iftype_data[i]);
+--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
+@@ -549,7 +549,7 @@ static void qtnf_core_mac_detach(struct
+ 		if (!wiphy->bands[band])
+ 			continue;
+ 
+-		kfree(wiphy->bands[band]->iftype_data);
++		kfree((__force void *)wiphy->bands[band]->iftype_data);
+ 		wiphy->bands[band]->n_iftype_data = 0;
+ 
+ 		kfree(wiphy->bands[band]->channels);
+--- a/drivers/net/wireless/realtek/rtw89/core.c
++++ b/drivers/net/wireless/realtek/rtw89/core.c
+@@ -3328,8 +3328,7 @@ static void rtw89_init_he_cap(struct rtw
+ 		idx++;
+ 	}
+ 
+-	sband->iftype_data = iftype_data;
+-	sband->n_iftype_data = idx;
++	_ieee80211_set_sband_iftype_data(sband, iftype_data, idx);
+ }
+ 
+ static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev)
+@@ -3374,11 +3373,11 @@ err:
+ 	hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
+ 	hw->wiphy->bands[NL80211_BAND_6GHZ] = NULL;
+ 	if (sband_2ghz)
+-		kfree(sband_2ghz->iftype_data);
++		kfree((__force void *)sband_2ghz->iftype_data);
+ 	if (sband_5ghz)
+-		kfree(sband_5ghz->iftype_data);
++		kfree((__force void *)sband_5ghz->iftype_data);
+ 	if (sband_6ghz)
+-		kfree(sband_6ghz->iftype_data);
++		kfree((__force void *)sband_6ghz->iftype_data);
+ 	kfree(sband_2ghz);
+ 	kfree(sband_5ghz);
+ 	kfree(sband_6ghz);
+@@ -3390,11 +3389,11 @@ static void rtw89_core_clr_supported_ban
+ 	struct ieee80211_hw *hw = rtwdev->hw;
+ 
+ 	if (hw->wiphy->bands[NL80211_BAND_2GHZ])
+-		kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data);
++		kfree((__force void *)hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data);
+ 	if (hw->wiphy->bands[NL80211_BAND_5GHZ])
+-		kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data);
++		kfree((__force void *)hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data);
+ 	if (hw->wiphy->bands[NL80211_BAND_6GHZ])
+-		kfree(hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data);
++		kfree((__force void *)hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data);
+ 	kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]);
+ 	kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]);
+ 	kfree(hw->wiphy->bands[NL80211_BAND_6GHZ]);
+--- a/drivers/net/wireless/realtek/rtw89/regd.c
++++ b/drivers/net/wireless/realtek/rtw89/regd.c
+@@ -376,7 +376,7 @@ bottom:
+ 		return;
+ 
+ 	wiphy->bands[NL80211_BAND_6GHZ] = NULL;
+-	kfree(sband->iftype_data);
++	kfree((__force void *)sband->iftype_data);
+ 	kfree(sband);
+ }
+ 
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -4900,25 +4900,19 @@ static const struct ieee80211_sband_ifty
+ 
+ static void mac80211_hwsim_sband_capab(struct ieee80211_supported_band *sband)
+ {
+-	u16 n_iftype_data;
+-
+-	if (sband->band == NL80211_BAND_2GHZ) {
+-		n_iftype_data = ARRAY_SIZE(sband_capa_2ghz);
+-		sband->iftype_data =
+-			(struct ieee80211_sband_iftype_data *)sband_capa_2ghz;
+-	} else if (sband->band == NL80211_BAND_5GHZ) {
+-		n_iftype_data = ARRAY_SIZE(sband_capa_5ghz);
+-		sband->iftype_data =
+-			(struct ieee80211_sband_iftype_data *)sband_capa_5ghz;
+-	} else if (sband->band == NL80211_BAND_6GHZ) {
+-		n_iftype_data = ARRAY_SIZE(sband_capa_6ghz);
+-		sband->iftype_data =
+-			(struct ieee80211_sband_iftype_data *)sband_capa_6ghz;
+-	} else {
+-		return;
++	switch (sband->band) {
++	case NL80211_BAND_2GHZ:
++		ieee80211_set_sband_iftype_data(sband, sband_capa_2ghz);
++		break;
++	case NL80211_BAND_5GHZ:
++		ieee80211_set_sband_iftype_data(sband, sband_capa_5ghz);
++		break;
++	case NL80211_BAND_6GHZ:
++		ieee80211_set_sband_iftype_data(sband, sband_capa_6ghz);
++		break;
++	default:
++		break;
+ 	}
+-
+-	sband->n_iftype_data = n_iftype_data;
+ }
+ 
+ #ifdef CPTCFG_MAC80211_MESH
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -415,6 +415,19 @@ struct ieee80211_sta_eht_cap {
+ 	u8 eht_ppe_thres[IEEE80211_EHT_PPE_THRES_MAX_LEN];
+ };
+ 
++/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
++#ifdef __CHECKER__
++/*
++ * This is used to mark the sband->iftype_data pointer which is supposed
++ * to be an array with special access semantics (per iftype), but a lot
++ * of code got it wrong in the past, so with this marking sparse will be
++ * noisy when the pointer is used directly.
++ */
++# define __iftd		__attribute__((noderef, address_space(__iftype_data)))
++#else
++# define __iftd
++#endif /* __CHECKER__ */
++
+ /**
+  * struct ieee80211_sband_iftype_data - sband data per interface type
+  *
+@@ -548,10 +561,48 @@ struct ieee80211_supported_band {
+ 	struct ieee80211_sta_s1g_cap s1g_cap;
+ 	struct ieee80211_edmg edmg_cap;
+ 	u16 n_iftype_data;
+-	const struct ieee80211_sband_iftype_data *iftype_data;
++	const struct ieee80211_sband_iftype_data __iftd *iftype_data;
+ };
+ 
+ /**
++ * _ieee80211_set_sband_iftype_data - set sband iftype data array
++ * @sband: the sband to initialize
++ * @iftd: the iftype data array pointer
++ * @n_iftd: the length of the iftype data array
++ *
++ * Set the sband iftype data array; use this where the length cannot
++ * be derived from the ARRAY_SIZE() of the argument, but prefer
++ * ieee80211_set_sband_iftype_data() where it can be used.
++ */
++static inline void
++_ieee80211_set_sband_iftype_data(struct ieee80211_supported_band *sband,
++				 const struct ieee80211_sband_iftype_data *iftd,
++				 u16 n_iftd)
++{
++	sband->iftype_data = (const void __iftd __force *)iftd;
++	sband->n_iftype_data = n_iftd;
++}
++
++/**
++ * ieee80211_set_sband_iftype_data - set sband iftype data array
++ * @sband: the sband to initialize
++ * @iftd: the iftype data array
++ */
++#define ieee80211_set_sband_iftype_data(sband, iftd)	\
++	_ieee80211_set_sband_iftype_data(sband, iftd, ARRAY_SIZE(iftd))
++
++/**
++ * for_each_sband_iftype_data - iterate sband iftype data entries
++ * @sband: the sband whose iftype_data array to iterate
++ * @i: iterator counter
++ * @iftd: iftype data pointer to set
++ */
++#define for_each_sband_iftype_data(sband, i, iftd)				\
++	for (i = 0, iftd = (const void __force *)&(sband)->iftype_data[i];	\
++	     i < (sband)->n_iftype_data;					\
++	     i++, iftd = (const void __force *)&(sband)->iftype_data[i])
++
++/**
+  * ieee80211_get_sband_iftype_data - return sband data for a given iftype
+  * @sband: the sband to search for the STA on
+  * @iftype: enum nl80211_iftype
+@@ -562,6 +613,7 @@ static inline const struct ieee80211_sba
+ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
+ 				u8 iftype)
+ {
++	const struct ieee80211_sband_iftype_data *data;
+ 	int i;
+ 
+ 	if (WARN_ON(iftype >= NL80211_IFTYPE_MAX))
+@@ -570,10 +622,7 @@ ieee80211_get_sband_iftype_data(const st
+ 	if (iftype == NL80211_IFTYPE_AP_VLAN)
+ 		iftype = NL80211_IFTYPE_AP;
+ 
+-	for (i = 0; i < sband->n_iftype_data; i++)  {
+-		const struct ieee80211_sband_iftype_data *data =
+-			&sband->iftype_data[i];
+-
++	for_each_sband_iftype_data(sband, i, data) {
+ 		if (data->types_mask & BIT(iftype))
+ 			return data;
+ 	}
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1055,6 +1055,7 @@ int ieee80211_register_hw(struct ieee802
+ 	supp_he = false;
+ 	supp_eht = false;
+ 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
++		const struct ieee80211_sband_iftype_data *iftd;
+ 		struct ieee80211_supported_band *sband;
+ 
+ 		sband = local->hw.wiphy->bands[band];
+@@ -1101,11 +1102,7 @@ int ieee80211_register_hw(struct ieee802
+ 		supp_ht = supp_ht || sband->ht_cap.ht_supported;
+ 		supp_vht = supp_vht || sband->vht_cap.vht_supported;
+ 
+-		for (i = 0; i < sband->n_iftype_data; i++) {
+-			const struct ieee80211_sband_iftype_data *iftd;
+-
+-			iftd = &sband->iftype_data[i];
+-
++		for_each_sband_iftype_data(sband, i, iftd) {
+ 			supp_he = supp_he || iftd->he_cap.has_he;
+ 			supp_eht = supp_eht || iftd->eht_cap.has_eht;
+ 		}
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -6,7 +6,7 @@
+  *
+  * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
+  * Copyright 2013-2014  Intel Mobile Communications GmbH
+- * Copyright 2018-2022	Intel Corporation
++ * Copyright 2018-2023	Intel Corporation
+  */
+ 
+ #include <linux/export.h>
+@@ -1162,8 +1162,7 @@ bool cfg80211_chandef_usable(struct wiph
+ 		if (!sband)
+ 			return false;
+ 
+-		for (i = 0; i < sband->n_iftype_data; i++) {
+-			iftd = &sband->iftype_data[i];
++		for_each_sband_iftype_data(sband, i, iftd) {
+ 			if (!iftd->eht_cap.has_eht)
+ 				continue;
+ 
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -5,7 +5,7 @@
+  * Copyright 2006-2010		Johannes Berg <johannes@sipsolutions.net>
+  * Copyright 2013-2014  Intel Mobile Communications GmbH
+  * Copyright 2015-2017	Intel Deutschland GmbH
+- * Copyright (C) 2018-2022 Intel Corporation
++ * Copyright (C) 2018-2023 Intel Corporation
+  */
+ 
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+@@ -817,6 +817,7 @@ int wiphy_register(struct wiphy *wiphy)
+ 
+ 	/* sanity check supported bands/channels */
+ 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
++		const struct ieee80211_sband_iftype_data *iftd;
+ 		u16 types = 0;
+ 		bool have_he = false;
+ 
+@@ -873,14 +874,11 @@ int wiphy_register(struct wiphy *wiphy)
+ 				return -EINVAL;
+ 		}
+ 
+-		for (i = 0; i < sband->n_iftype_data; i++) {
+-			const struct ieee80211_sband_iftype_data *iftd;
++		for_each_sband_iftype_data(sband, i, iftd) {
+ 			bool has_ap, has_non_ap;
+ 			u32 ap_bits = BIT(NL80211_IFTYPE_AP) |
+ 				      BIT(NL80211_IFTYPE_P2P_GO);
+ 
+-			iftd = &sband->iftype_data[i];
+-
+ 			if (WARN_ON(!iftd->types_mask))
+ 				return -EINVAL;
+ 			if (WARN_ON(types & iftd->types_mask))
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -1906,20 +1906,20 @@ static int nl80211_send_band_rateinfo(st
+ 		struct nlattr *nl_iftype_data =
+ 			nla_nest_start_noflag(msg,
+ 					      NL80211_BAND_ATTR_IFTYPE_DATA);
++		const struct ieee80211_sband_iftype_data *iftd;
+ 		int err;
+ 
+ 		if (!nl_iftype_data)
+ 			return -ENOBUFS;
+ 
+-		for (i = 0; i < sband->n_iftype_data; i++) {
++		for_each_sband_iftype_data(sband, i, iftd) {
+ 			struct nlattr *iftdata;
+ 
+ 			iftdata = nla_nest_start_noflag(msg, i + 1);
+ 			if (!iftdata)
+ 				return -ENOBUFS;
+ 
+-			err = nl80211_send_iftype_data(msg, sband,
+-						       &sband->iftype_data[i]);
++			err = nl80211_send_iftype_data(msg, sband, iftd);
+ 			if (err)
+ 				return err;
+ 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch
deleted file mode 100644
index 8641057..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 2 Dec 2022 13:54:15 +0100
-Subject: [PATCH] wifi: cfg80211: factor out bridge tunnel / RFC1042 header
- check
-
-The same check is done in multiple places, unify it.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -542,6 +542,21 @@ unsigned int ieee80211_get_mesh_hdrlen(s
- }
- EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
- 
-+static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
-+{
-+	const __be16 *hdr_proto = hdr + ETH_ALEN;
-+
-+	if (!(ether_addr_equal(hdr, rfc1042_header) &&
-+	      *hdr_proto != htons(ETH_P_AARP) &&
-+	      *hdr_proto != htons(ETH_P_IPX)) &&
-+	    !ether_addr_equal(hdr, bridge_tunnel_header))
-+		return false;
-+
-+	*proto = *hdr_proto;
-+
-+	return true;
-+}
-+
- int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
- 				  const u8 *addr, enum nl80211_iftype iftype,
- 				  u8 data_offset, bool is_amsdu)
-@@ -633,14 +648,9 @@ int ieee80211_data_to_8023_exthdr(struct
- 
- 	if (likely(!is_amsdu &&
- 		   skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
--	           ((ether_addr_equal(payload.hdr, rfc1042_header) &&
--		     payload.proto != htons(ETH_P_AARP) &&
--		     payload.proto != htons(ETH_P_IPX)) ||
--		    ether_addr_equal(payload.hdr, bridge_tunnel_header)))) {
--		/* remove RFC1042 or Bridge-Tunnel encapsulation and
--		 * replace EtherType */
-+		   ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) {
-+		/* remove RFC1042 or Bridge-Tunnel encapsulation */
- 		hdrlen += ETH_ALEN + 2;
--		tmp.h_proto = payload.proto;
- 		skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2);
- 	} else {
- 		tmp.h_proto = htons(skb->len - hdrlen);
-@@ -756,8 +766,6 @@ void ieee80211_amsdu_to_8023s(struct sk_
- {
- 	unsigned int hlen = ALIGN(extra_headroom, 4);
- 	struct sk_buff *frame = NULL;
--	u16 ethertype;
--	u8 *payload;
- 	int offset = 0, remaining;
- 	struct ethhdr eth;
- 	bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
-@@ -811,14 +819,8 @@ void ieee80211_amsdu_to_8023s(struct sk_
- 		frame->dev = skb->dev;
- 		frame->priority = skb->priority;
- 
--		payload = frame->data;
--		ethertype = (payload[6] << 8) | payload[7];
--		if (likely((ether_addr_equal(payload, rfc1042_header) &&
--			    ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
--			   ether_addr_equal(payload, bridge_tunnel_header))) {
--			eth.h_proto = htons(ethertype);
-+		if (likely(ieee80211_get_8023_tunnel_proto(frame->data, &eth.h_proto)))
- 			skb_pull(frame, ETH_ALEN + 2);
--		}
- 
- 		memcpy(skb_push(frame, sizeof(eth)), &eth, sizeof(eth));
- 		__skb_queue_tail(list, frame);
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/313-wifi-cfg80211-export-DFS-CAC-time-and-usable-state-h.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/313-wifi-cfg80211-export-DFS-CAC-time-and-usable-state-h.patch
new file mode 100644
index 0000000..78ec030
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/313-wifi-cfg80211-export-DFS-CAC-time-and-usable-state-h.patch
@@ -0,0 +1,111 @@
+From 30ca8b0c4d6c9fb1d76e5894b1e8bf7c6a12224d Mon Sep 17 00:00:00 2001
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Date: Tue, 12 Sep 2023 10:48:55 +0530
+Subject: [PATCH] wifi: cfg80211: export DFS CAC time and usable state helper
+ functions
+
+cfg80211 has cfg80211_chandef_dfs_usable() function to know whether
+at least one channel in the chandef is in usable state or not. Also,
+cfg80211_chandef_dfs_cac_time() function is there which tells the CAC
+time required for the given chandef.
+
+Make these two functions visible to drivers by exporting their symbol
+to global list of kernel symbols.
+
+Lower level drivers can make use of these two functions to be aware
+if CAC is required on the given chandef and for how long. For example
+drivers which maintains the CAC state internally can make use of these.
+
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Link: https://lore.kernel.org/r/20230912051857.2284-2-quic_adisi@quicinc.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+ include/net/cfg80211.h | 24 ++++++++++++++++++++++++
+ net/wireless/chan.c    |  2 ++
+ net/wireless/core.h    | 17 -----------------
+ 3 files changed, 26 insertions(+), 17 deletions(-)
+
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -1008,6 +1008,30 @@ int cfg80211_chandef_dfs_required(struct
+ 				  enum nl80211_iftype iftype);
+ 
+ /**
++ * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable and we
++ *				 can/need start CAC on such channel
++ * @wiphy: the wiphy to validate against
++ * @chandef: the channel definition to check
++ *
++ * Return: true if all channels available and at least
++ *	   one channel requires CAC (NL80211_DFS_USABLE)
++ */
++bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
++				 const struct cfg80211_chan_def *chandef);
++
++/**
++ * cfg80211_chandef_dfs_cac_time - get the DFS CAC time (in ms) for given
++ *				   channel definition
++ * @wiphy: the wiphy to validate against
++ * @chandef: the channel definition to check
++ *
++ * Returns: DFS CAC time (in ms) which applies for this channel definition
++ */
++unsigned int
++cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
++			      const struct cfg80211_chan_def *chandef);
++
++/**
+  * nl80211_send_chandef - sends the channel definition.
+  * @msg: the msg to send channel definition
+  * @chandef: the channel definition to check
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -666,6 +666,7 @@ bool cfg80211_chandef_dfs_usable(struct
+ 
+ 	return (r1 + r2 > 0);
+ }
++EXPORT_SYMBOL(cfg80211_chandef_dfs_usable);
+ 
+ /*
+  * Checks if center frequency of chan falls with in the bandwidth
+@@ -965,6 +966,7 @@ cfg80211_chandef_dfs_cac_time(struct wip
+ 
+ 	return max(t1, t2);
+ }
++EXPORT_SYMBOL(cfg80211_chandef_dfs_cac_time);
+ 
+ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
+ 					u32 center_freq, u32 bandwidth,
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -469,29 +469,12 @@ int cfg80211_scan(struct cfg80211_regist
+ 
+ extern struct work_struct cfg80211_disconnect_work;
+ 
+-/**
+- * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable
+- * @wiphy: the wiphy to validate against
+- * @chandef: the channel definition to check
+- *
+- * Checks if chandef is usable and we can/need start CAC on such channel.
+- *
+- * Return: true if all channels available and at least
+- *	   one channel requires CAC (NL80211_DFS_USABLE)
+- */
+-bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
+-				 const struct cfg80211_chan_def *chandef);
+-
+ void cfg80211_set_dfs_state(struct wiphy *wiphy,
+ 			    const struct cfg80211_chan_def *chandef,
+ 			    enum nl80211_dfs_state dfs_state);
+ 
+ void cfg80211_dfs_channels_update_work(struct work_struct *work);
+ 
+-unsigned int
+-cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
+-			      const struct cfg80211_chan_def *chandef);
+-
+ void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
+ 
+ int
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch
deleted file mode 100644
index 515176f..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 2 Dec 2022 17:01:46 +0100
-Subject: [PATCH] wifi: mac80211: remove mesh forwarding congestion check
-
-Now that all drivers use iTXQ, it does not make sense to check to drop
-tx forwarding packets when the driver has stopped the queues.
-fq_codel will take care of dropping packets when the queues fill up
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/debugfs_netdev.c
-+++ b/net/mac80211/debugfs_netdev.c
-@@ -603,8 +603,6 @@ IEEE80211_IF_FILE(fwded_mcast, u.mesh.ms
- IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
- IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
- IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
--IEEE80211_IF_FILE(dropped_frames_congestion,
--		  u.mesh.mshstats.dropped_frames_congestion, DEC);
- IEEE80211_IF_FILE(dropped_frames_no_route,
- 		  u.mesh.mshstats.dropped_frames_no_route, DEC);
- 
-@@ -740,7 +738,6 @@ static void add_mesh_stats(struct ieee80
- 	MESHSTATS_ADD(fwded_frames);
- 	MESHSTATS_ADD(dropped_frames_ttl);
- 	MESHSTATS_ADD(dropped_frames_no_route);
--	MESHSTATS_ADD(dropped_frames_congestion);
- #undef MESHSTATS_ADD
- }
- 
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -329,7 +329,6 @@ struct mesh_stats {
- 	__u32 fwded_frames;		/* Mesh total forwarded frames */
- 	__u32 dropped_frames_ttl;	/* Not transmitted since mesh_ttl == 0*/
- 	__u32 dropped_frames_no_route;	/* Not transmitted, no route found */
--	__u32 dropped_frames_congestion;/* Not forwarded due to congestion */
- };
- 
- #define PREQ_Q_F_START		0x1
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2926,11 +2926,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
- 		return RX_CONTINUE;
- 
- 	ac = ieee802_1d_to_ac[skb->priority];
--	q = sdata->vif.hw_queue[ac];
--	if (ieee80211_queue_stopped(&local->hw, q)) {
--		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
--		return RX_DROP_MONITOR;
--	}
- 	skb_set_queue_mapping(skb, ac);
- 
- 	if (!--mesh_hdr->ttl) {
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch
deleted file mode 100644
index 59b799b..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch
+++ /dev/null
@@ -1,762 +0,0 @@
-From 986e43b19ae9176093da35e0a844e65c8bf9ede7 Mon Sep 17 00:00:00 2001
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 13 Feb 2023 11:08:54 +0100
-Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh
- interfaces
-
-The current mac80211 mesh A-MSDU receive path fails to parse A-MSDU packets
-on mesh interfaces, because it assumes that the Mesh Control field is always
-directly after the 802.11 header.
-802.11-2020 9.3.2.2.2 Figure 9-70 shows that the Mesh Control field is
-actually part of the A-MSDU subframe header.
-This makes more sense, since it allows packets for multiple different
-destinations to be included in the same A-MSDU, as long as RA and TID are
-still the same.
-Another issue is the fact that the A-MSDU subframe length field was apparently
-accidentally defined as little-endian in the standard.
-
-In order to fix this, the mesh forwarding path needs happen at a different
-point in the receive path.
-
-ieee80211_data_to_8023_exthdr is changed to ignore the mesh control field
-and leave it in after the ethernet header. This also affects the source/dest
-MAC address fields, which now in the case of mesh point to the mesh SA/DA.
-
-ieee80211_amsdu_to_8023s is changed to deal with the endian difference and
-to add the Mesh Control length to the subframe length, since it's not covered
-by the MSDU length field.
-
-With these changes, the mac80211 will get the same packet structure for
-converted regular data packets and unpacked A-MSDU subframes.
-
-The mesh forwarding checks are now only performed after the A-MSDU decap.
-For locally received packets, the Mesh Control header is stripped away.
-For forwarded packets, a new 802.11 header gets added.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-Link: https://lore.kernel.org/r/20230213100855.34315-4-nbd@nbd.name
-[fix fortify build error]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- .../wireless/marvell/mwifiex/11n_rxreorder.c  |   2 +-
- include/net/cfg80211.h                        |  27 +-
- net/mac80211/rx.c                             | 350 ++++++++++--------
- net/wireless/util.c                           | 120 +++---
- 4 files changed, 297 insertions(+), 202 deletions(-)
-
---- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
-+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
-@@ -33,7 +33,7 @@ static int mwifiex_11n_dispatch_amsdu_pk
- 		skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length));
- 
- 		ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
--					 priv->wdev.iftype, 0, NULL, NULL);
-+					 priv->wdev.iftype, 0, NULL, NULL, false);
- 
- 		while (!skb_queue_empty(&list)) {
- 			struct rx_packet_hdr *rx_hdr;
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -6208,11 +6208,36 @@ static inline int ieee80211_data_to_8023
-  * @extra_headroom: The hardware extra headroom for SKBs in the @list.
-  * @check_da: DA to check in the inner ethernet header, or NULL
-  * @check_sa: SA to check in the inner ethernet header, or NULL
-+ * @mesh_control: A-MSDU subframe header includes the mesh control field
-  */
- void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
- 			      const u8 *addr, enum nl80211_iftype iftype,
- 			      const unsigned int extra_headroom,
--			      const u8 *check_da, const u8 *check_sa);
-+			      const u8 *check_da, const u8 *check_sa,
-+			      bool mesh_control);
-+
-+/**
-+ * ieee80211_get_8023_tunnel_proto - get RFC1042 or bridge tunnel encap protocol
-+ *
-+ * Check for RFC1042 or bridge tunnel header and fetch the encapsulated
-+ * protocol.
-+ *
-+ * @hdr: pointer to the MSDU payload
-+ * @proto: destination pointer to store the protocol
-+ * Return: true if encapsulation was found
-+ */
-+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto);
-+
-+/**
-+ * ieee80211_strip_8023_mesh_hdr - strip mesh header from converted 802.3 frames
-+ *
-+ * Strip the mesh header, which was left in by ieee80211_data_to_8023 as part
-+ * of the MSDU data. Also move any source/destination addresses from the mesh
-+ * header to the ethernet header (if present).
-+ *
-+ * @skb: The 802.3 frame with embedded mesh header
-+ */
-+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb);
- 
- /**
-  * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2720,6 +2720,174 @@ ieee80211_deliver_skb(struct ieee80211_r
- 	}
- }
- 
-+static ieee80211_rx_result
-+ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta,
-+		       struct sk_buff *skb)
-+{
-+#ifdef CPTCFG_MAC80211_MESH
-+	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-+	struct ieee80211_local *local = sdata->local;
-+	uint16_t fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
-+	struct ieee80211_hdr hdr = {
-+		.frame_control = cpu_to_le16(fc)
-+	};
-+	struct ieee80211_hdr *fwd_hdr;
-+	struct ieee80211s_hdr *mesh_hdr;
-+	struct ieee80211_tx_info *info;
-+	struct sk_buff *fwd_skb;
-+	struct ethhdr *eth;
-+	bool multicast;
-+	int tailroom = 0;
-+	int hdrlen, mesh_hdrlen;
-+	u8 *qos;
-+
-+	if (!ieee80211_vif_is_mesh(&sdata->vif))
-+		return RX_CONTINUE;
-+
-+	if (!pskb_may_pull(skb, sizeof(*eth) + 6))
-+		return RX_DROP_MONITOR;
-+
-+	mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(*eth));
-+	mesh_hdrlen = ieee80211_get_mesh_hdrlen(mesh_hdr);
-+
-+	if (!pskb_may_pull(skb, sizeof(*eth) + mesh_hdrlen))
-+		return RX_DROP_MONITOR;
-+
-+	eth = (struct ethhdr *)skb->data;
-+	multicast = is_multicast_ether_addr(eth->h_dest);
-+
-+	mesh_hdr = (struct ieee80211s_hdr *)(eth + 1);
-+	if (!mesh_hdr->ttl)
-+		return RX_DROP_MONITOR;
-+
-+	/* frame is in RMC, don't forward */
-+	if (is_multicast_ether_addr(eth->h_dest) &&
-+	    mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
-+		return RX_DROP_MONITOR;
-+
-+	/* Frame has reached destination.  Don't forward */
-+	if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
-+		goto rx_accept;
-+
-+	if (!ifmsh->mshcfg.dot11MeshForwarding) {
-+		if (is_multicast_ether_addr(eth->h_dest))
-+			goto rx_accept;
-+
-+		return RX_DROP_MONITOR;
-+	}
-+
-+	/* forward packet */
-+	if (sdata->crypto_tx_tailroom_needed_cnt)
-+		tailroom = IEEE80211_ENCRYPT_TAILROOM;
-+
-+	if (!--mesh_hdr->ttl) {
-+		if (multicast)
-+			goto rx_accept;
-+
-+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
-+		return RX_DROP_MONITOR;
-+	}
-+
-+	if (mesh_hdr->flags & MESH_FLAGS_AE) {
-+		struct mesh_path *mppath;
-+		char *proxied_addr;
-+
-+		if (multicast)
-+			proxied_addr = mesh_hdr->eaddr1;
-+		else if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
-+			/* has_a4 already checked in ieee80211_rx_mesh_check */
-+			proxied_addr = mesh_hdr->eaddr2;
-+		else
-+			return RX_DROP_MONITOR;
-+
-+		rcu_read_lock();
-+		mppath = mpp_path_lookup(sdata, proxied_addr);
-+		if (!mppath) {
-+			mpp_path_add(sdata, proxied_addr, eth->h_source);
-+		} else {
-+			spin_lock_bh(&mppath->state_lock);
-+			if (!ether_addr_equal(mppath->mpp, eth->h_source))
-+				memcpy(mppath->mpp, eth->h_source, ETH_ALEN);
-+			mppath->exp_time = jiffies;
-+			spin_unlock_bh(&mppath->state_lock);
-+		}
-+		rcu_read_unlock();
-+	}
-+
-+	skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
-+
-+	ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control,
-+				      eth->h_dest, eth->h_source);
-+	hdrlen = ieee80211_hdrlen(hdr.frame_control);
-+	if (multicast) {
-+		int extra_head = sizeof(struct ieee80211_hdr) - sizeof(*eth);
-+
-+		fwd_skb = skb_copy_expand(skb, local->tx_headroom + extra_head +
-+					       IEEE80211_ENCRYPT_HEADROOM,
-+					  tailroom, GFP_ATOMIC);
-+		if (!fwd_skb)
-+			goto rx_accept;
-+	} else {
-+		fwd_skb = skb;
-+		skb = NULL;
-+
-+		if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
-+			return RX_DROP_UNUSABLE;
-+	}
-+
-+	fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
-+	memcpy(fwd_hdr, &hdr, hdrlen - 2);
-+	qos = ieee80211_get_qos_ctl(fwd_hdr);
-+	qos[0] = qos[1] = 0;
-+
-+	skb_reset_mac_header(fwd_skb);
-+	hdrlen += mesh_hdrlen;
-+	if (ieee80211_get_8023_tunnel_proto(fwd_skb->data + hdrlen,
-+					    &fwd_skb->protocol))
-+		hdrlen += ETH_ALEN;
-+	else
-+		fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
-+	skb_set_network_header(fwd_skb, hdrlen);
-+
-+	info = IEEE80211_SKB_CB(fwd_skb);
-+	memset(info, 0, sizeof(*info));
-+	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
-+	info->control.vif = &sdata->vif;
-+	info->control.jiffies = jiffies;
-+	if (multicast) {
-+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
-+		memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
-+		/* update power mode indication when forwarding */
-+		ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
-+	} else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
-+		/* mesh power mode flags updated in mesh_nexthop_lookup */
-+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
-+	} else {
-+		/* unable to resolve next hop */
-+		if (sta)
-+			mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
-+					   hdr.addr3, 0,
-+					   WLAN_REASON_MESH_PATH_NOFORWARD,
-+					   sta->sta.addr);
-+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
-+		kfree_skb(fwd_skb);
-+		goto rx_accept;
-+	}
-+
-+	IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
-+	fwd_skb->dev = sdata->dev;
-+	ieee80211_add_pending_skb(local, fwd_skb);
-+
-+rx_accept:
-+	if (!skb)
-+		return RX_QUEUED;
-+
-+	ieee80211_strip_8023_mesh_hdr(skb);
-+#endif
-+
-+	return RX_CONTINUE;
-+}
-+
- static ieee80211_rx_result debug_noinline
- __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
- {
-@@ -2728,8 +2896,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- 	__le16 fc = hdr->frame_control;
- 	struct sk_buff_head frame_list;
-+	static ieee80211_rx_result res;
- 	struct ethhdr ethhdr;
- 	const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
-+	bool mesh = false;
- 
- 	if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
- 		check_da = NULL;
-@@ -2746,6 +2916,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
- 			break;
- 		case NL80211_IFTYPE_MESH_POINT:
- 			check_sa = NULL;
-+			check_da = NULL;
-+			mesh = true;
- 			break;
- 		default:
- 			break;
-@@ -2763,17 +2935,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
- 	ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
- 				 rx->sdata->vif.type,
- 				 rx->local->hw.extra_tx_headroom,
--				 check_da, check_sa);
-+				 check_da, check_sa, mesh);
- 
- 	while (!skb_queue_empty(&frame_list)) {
- 		rx->skb = __skb_dequeue(&frame_list);
- 
--		if (!ieee80211_frame_allowed(rx, fc)) {
--			dev_kfree_skb(rx->skb);
-+		res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
-+		switch (res) {
-+		case RX_QUEUED:
- 			continue;
-+		case RX_CONTINUE:
-+			break;
-+		default:
-+			goto free;
- 		}
- 
-+		if (!ieee80211_frame_allowed(rx, fc))
-+			goto free;
-+
- 		ieee80211_deliver_skb(rx);
-+		continue;
-+
-+free:
-+		dev_kfree_skb(rx->skb);
- 	}
- 
- 	return RX_QUEUED;
-@@ -2806,6 +2990,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
- 			if (!rx->sdata->u.mgd.use_4addr)
- 				return RX_DROP_UNUSABLE;
- 			break;
-+		case NL80211_IFTYPE_MESH_POINT:
-+			break;
- 		default:
- 			return RX_DROP_UNUSABLE;
- 		}
-@@ -2834,155 +3020,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
- 	return __ieee80211_rx_h_amsdu(rx, 0);
- }
- 
--#ifdef CPTCFG_MAC80211_MESH
--static ieee80211_rx_result
--ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
--{
--	struct ieee80211_hdr *fwd_hdr, *hdr;
--	struct ieee80211_tx_info *info;
--	struct ieee80211s_hdr *mesh_hdr;
--	struct sk_buff *skb = rx->skb, *fwd_skb;
--	struct ieee80211_local *local = rx->local;
--	struct ieee80211_sub_if_data *sdata = rx->sdata;
--	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
--	u16 ac, q, hdrlen;
--	int tailroom = 0;
--
--	hdr = (struct ieee80211_hdr *) skb->data;
--	hdrlen = ieee80211_hdrlen(hdr->frame_control);
--
--	/* make sure fixed part of mesh header is there, also checks skb len */
--	if (!pskb_may_pull(rx->skb, hdrlen + 6))
--		return RX_DROP_MONITOR;
--
--	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
--
--	/* make sure full mesh header is there, also checks skb len */
--	if (!pskb_may_pull(rx->skb,
--			   hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
--		return RX_DROP_MONITOR;
--
--	/* reload pointers */
--	hdr = (struct ieee80211_hdr *) skb->data;
--	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
--
--	if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) {
--		int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) +
--			     sizeof(rfc1042_header);
--		__be16 ethertype;
--
--		if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) ||
--		    skb_copy_bits(rx->skb, offset, &ethertype, 2) != 0 ||
--		    ethertype != rx->sdata->control_port_protocol)
--			return RX_DROP_MONITOR;
--	}
--
--	/* frame is in RMC, don't forward */
--	if (ieee80211_is_data(hdr->frame_control) &&
--	    is_multicast_ether_addr(hdr->addr1) &&
--	    mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr))
--		return RX_DROP_MONITOR;
--
--	if (!ieee80211_is_data(hdr->frame_control))
--		return RX_CONTINUE;
--
--	if (!mesh_hdr->ttl)
--		return RX_DROP_MONITOR;
--
--	if (mesh_hdr->flags & MESH_FLAGS_AE) {
--		struct mesh_path *mppath;
--		char *proxied_addr;
--		char *mpp_addr;
--
--		if (is_multicast_ether_addr(hdr->addr1)) {
--			mpp_addr = hdr->addr3;
--			proxied_addr = mesh_hdr->eaddr1;
--		} else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
--			    MESH_FLAGS_AE_A5_A6) {
--			/* has_a4 already checked in ieee80211_rx_mesh_check */
--			mpp_addr = hdr->addr4;
--			proxied_addr = mesh_hdr->eaddr2;
--		} else {
--			return RX_DROP_MONITOR;
--		}
--
--		rcu_read_lock();
--		mppath = mpp_path_lookup(sdata, proxied_addr);
--		if (!mppath) {
--			mpp_path_add(sdata, proxied_addr, mpp_addr);
--		} else {
--			spin_lock_bh(&mppath->state_lock);
--			if (!ether_addr_equal(mppath->mpp, mpp_addr))
--				memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
--			mppath->exp_time = jiffies;
--			spin_unlock_bh(&mppath->state_lock);
--		}
--		rcu_read_unlock();
--	}
--
--	/* Frame has reached destination.  Don't forward */
--	if (!is_multicast_ether_addr(hdr->addr1) &&
--	    ether_addr_equal(sdata->vif.addr, hdr->addr3))
--		return RX_CONTINUE;
--
--	ac = ieee802_1d_to_ac[skb->priority];
--	skb_set_queue_mapping(skb, ac);
--
--	if (!--mesh_hdr->ttl) {
--		if (!is_multicast_ether_addr(hdr->addr1))
--			IEEE80211_IFSTA_MESH_CTR_INC(ifmsh,
--						     dropped_frames_ttl);
--		goto out;
--	}
--
--	if (!ifmsh->mshcfg.dot11MeshForwarding)
--		goto out;
--
--	if (sdata->crypto_tx_tailroom_needed_cnt)
--		tailroom = IEEE80211_ENCRYPT_TAILROOM;
--
--	fwd_skb = skb_copy_expand(skb, local->tx_headroom +
--				       IEEE80211_ENCRYPT_HEADROOM,
--				  tailroom, GFP_ATOMIC);
--	if (!fwd_skb)
--		goto out;
--
--	fwd_skb->dev = sdata->dev;
--	fwd_hdr =  (struct ieee80211_hdr *) fwd_skb->data;
--	fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
--	info = IEEE80211_SKB_CB(fwd_skb);
--	memset(info, 0, sizeof(*info));
--	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
--	info->control.vif = &rx->sdata->vif;
--	info->control.jiffies = jiffies;
--	if (is_multicast_ether_addr(fwd_hdr->addr1)) {
--		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
--		memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
--		/* update power mode indication when forwarding */
--		ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
--	} else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
--		/* mesh power mode flags updated in mesh_nexthop_lookup */
--		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
--	} else {
--		/* unable to resolve next hop */
--		mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
--				   fwd_hdr->addr3, 0,
--				   WLAN_REASON_MESH_PATH_NOFORWARD,
--				   fwd_hdr->addr2);
--		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
--		kfree_skb(fwd_skb);
--		return RX_DROP_MONITOR;
--	}
--
--	IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
--	ieee80211_add_pending_skb(local, fwd_skb);
-- out:
--	if (is_multicast_ether_addr(hdr->addr1))
--		return RX_CONTINUE;
--	return RX_DROP_MONITOR;
--}
--#endif
--
- static ieee80211_rx_result debug_noinline
- ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
- {
-@@ -2991,6 +3028,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_
- 	struct net_device *dev = sdata->dev;
- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
- 	__le16 fc = hdr->frame_control;
-+	static ieee80211_rx_result res;
- 	bool port_control;
- 	int err;
- 
-@@ -3017,6 +3055,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_
- 	if (unlikely(err))
- 		return RX_DROP_UNUSABLE;
- 
-+	res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
-+	if (res != RX_CONTINUE)
-+		return res;
-+
- 	if (!ieee80211_frame_allowed(rx, fc))
- 		return RX_DROP_MONITOR;
- 
-@@ -3987,10 +4029,6 @@ static void ieee80211_rx_handlers(struct
- 		CALL_RXH(ieee80211_rx_h_defragment);
- 		CALL_RXH(ieee80211_rx_h_michael_mic_verify);
- 		/* must be after MMIC verify so header is counted in MPDU mic */
--#ifdef CPTCFG_MAC80211_MESH
--		if (ieee80211_vif_is_mesh(&rx->sdata->vif))
--			CALL_RXH(ieee80211_rx_h_mesh_fwding);
--#endif
- 		CALL_RXH(ieee80211_rx_h_amsdu);
- 		CALL_RXH(ieee80211_rx_h_data);
- 
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -542,7 +542,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s
- }
- EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
- 
--static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
-+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
- {
- 	const __be16 *hdr_proto = hdr + ETH_ALEN;
- 
-@@ -556,6 +556,49 @@ static bool ieee80211_get_8023_tunnel_pr
- 
- 	return true;
- }
-+EXPORT_SYMBOL(ieee80211_get_8023_tunnel_proto);
-+
-+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb)
-+{
-+	const void *mesh_addr;
-+	struct {
-+		struct ethhdr eth;
-+		u8 flags;
-+	} payload;
-+	int hdrlen;
-+	int ret;
-+
-+	ret = skb_copy_bits(skb, 0, &payload, sizeof(payload));
-+	if (ret)
-+		return ret;
-+
-+	hdrlen = sizeof(payload.eth) + __ieee80211_get_mesh_hdrlen(payload.flags);
-+
-+	if (likely(pskb_may_pull(skb, hdrlen + 8) &&
-+		   ieee80211_get_8023_tunnel_proto(skb->data + hdrlen,
-+						   &payload.eth.h_proto)))
-+		hdrlen += ETH_ALEN + 2;
-+	else if (!pskb_may_pull(skb, hdrlen))
-+		return -EINVAL;
-+
-+	mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN;
-+	switch (payload.flags & MESH_FLAGS_AE) {
-+	case MESH_FLAGS_AE_A4:
-+		memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN);
-+		break;
-+	case MESH_FLAGS_AE_A5_A6:
-+		memcpy(&payload.eth, mesh_addr, 2 * ETH_ALEN);
-+		break;
-+	default:
-+		break;
-+	}
-+
-+	pskb_pull(skb, hdrlen - sizeof(payload.eth));
-+	memcpy(skb->data, &payload.eth, sizeof(payload.eth));
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL(ieee80211_strip_8023_mesh_hdr);
- 
- int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
- 				  const u8 *addr, enum nl80211_iftype iftype,
-@@ -568,7 +611,6 @@ int ieee80211_data_to_8023_exthdr(struct
- 	} payload;
- 	struct ethhdr tmp;
- 	u16 hdrlen;
--	u8 mesh_flags = 0;
- 
- 	if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
- 		return -1;
-@@ -589,12 +631,6 @@ int ieee80211_data_to_8023_exthdr(struct
- 	memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN);
- 	memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN);
- 
--	if (iftype == NL80211_IFTYPE_MESH_POINT &&
--	    skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0)
--		return -1;
--
--	mesh_flags &= MESH_FLAGS_AE;
--
- 	switch (hdr->frame_control &
- 		cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
- 	case cpu_to_le16(IEEE80211_FCTL_TODS):
-@@ -608,17 +644,6 @@ int ieee80211_data_to_8023_exthdr(struct
- 			     iftype != NL80211_IFTYPE_AP_VLAN &&
- 			     iftype != NL80211_IFTYPE_STATION))
- 			return -1;
--		if (iftype == NL80211_IFTYPE_MESH_POINT) {
--			if (mesh_flags == MESH_FLAGS_AE_A4)
--				return -1;
--			if (mesh_flags == MESH_FLAGS_AE_A5_A6 &&
--			    skb_copy_bits(skb, hdrlen +
--					  offsetof(struct ieee80211s_hdr, eaddr1),
--					  tmp.h_dest, 2 * ETH_ALEN) < 0)
--				return -1;
--
--			hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
--		}
- 		break;
- 	case cpu_to_le16(IEEE80211_FCTL_FROMDS):
- 		if ((iftype != NL80211_IFTYPE_STATION &&
-@@ -627,16 +652,6 @@ int ieee80211_data_to_8023_exthdr(struct
- 		    (is_multicast_ether_addr(tmp.h_dest) &&
- 		     ether_addr_equal(tmp.h_source, addr)))
- 			return -1;
--		if (iftype == NL80211_IFTYPE_MESH_POINT) {
--			if (mesh_flags == MESH_FLAGS_AE_A5_A6)
--				return -1;
--			if (mesh_flags == MESH_FLAGS_AE_A4 &&
--			    skb_copy_bits(skb, hdrlen +
--					  offsetof(struct ieee80211s_hdr, eaddr1),
--					  tmp.h_source, ETH_ALEN) < 0)
--				return -1;
--			hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
--		}
- 		break;
- 	case cpu_to_le16(0):
- 		if (iftype != NL80211_IFTYPE_ADHOC &&
-@@ -646,7 +661,7 @@ int ieee80211_data_to_8023_exthdr(struct
- 		break;
- 	}
- 
--	if (likely(!is_amsdu &&
-+	if (likely(!is_amsdu && iftype != NL80211_IFTYPE_MESH_POINT &&
- 		   skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
- 		   ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) {
- 		/* remove RFC1042 or Bridge-Tunnel encapsulation */
-@@ -722,7 +737,8 @@ __ieee80211_amsdu_copy_frag(struct sk_bu
- 
- static struct sk_buff *
- __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen,
--		       int offset, int len, bool reuse_frag)
-+		       int offset, int len, bool reuse_frag,
-+		       int min_len)
- {
- 	struct sk_buff *frame;
- 	int cur_len = len;
-@@ -736,7 +752,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s
- 	 * in the stack later.
- 	 */
- 	if (reuse_frag)
--		cur_len = min_t(int, len, 32);
-+		cur_len = min_t(int, len, min_len);
- 
- 	/*
- 	 * Allocate and reserve two bytes more for payload
-@@ -746,6 +762,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s
- 	if (!frame)
- 		return NULL;
- 
-+	frame->priority = skb->priority;
- 	skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2);
- 	skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len);
- 
-@@ -762,23 +779,37 @@ __ieee80211_amsdu_copy(struct sk_buff *s
- void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
- 			      const u8 *addr, enum nl80211_iftype iftype,
- 			      const unsigned int extra_headroom,
--			      const u8 *check_da, const u8 *check_sa)
-+			      const u8 *check_da, const u8 *check_sa,
-+			      bool mesh_control)
- {
- 	unsigned int hlen = ALIGN(extra_headroom, 4);
- 	struct sk_buff *frame = NULL;
- 	int offset = 0, remaining;
--	struct ethhdr eth;
-+	struct {
-+		struct ethhdr eth;
-+		uint8_t flags;
-+	} hdr;
- 	bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
- 	bool reuse_skb = false;
- 	bool last = false;
-+	int copy_len = sizeof(hdr.eth);
-+
-+	if (iftype == NL80211_IFTYPE_MESH_POINT)
-+		copy_len = sizeof(hdr);
- 
- 	while (!last) {
- 		unsigned int subframe_len;
--		int len;
-+		int len, mesh_len = 0;
- 		u8 padding;
- 
--		skb_copy_bits(skb, offset, &eth, sizeof(eth));
--		len = ntohs(eth.h_proto);
-+		skb_copy_bits(skb, offset, &hdr, copy_len);
-+		if (iftype == NL80211_IFTYPE_MESH_POINT)
-+			mesh_len = __ieee80211_get_mesh_hdrlen(hdr.flags);
-+		if (mesh_control)
-+			len = le16_to_cpu(*(__le16 *)&hdr.eth.h_proto) + mesh_len;
-+		else
-+			len = ntohs(hdr.eth.h_proto);
-+
- 		subframe_len = sizeof(struct ethhdr) + len;
- 		padding = (4 - subframe_len) & 0x3;
- 
-@@ -787,16 +818,16 @@ void ieee80211_amsdu_to_8023s(struct sk_
- 		if (subframe_len > remaining)
- 			goto purge;
- 		/* mitigate A-MSDU aggregation injection attacks */
--		if (ether_addr_equal(eth.h_dest, rfc1042_header))
-+		if (ether_addr_equal(hdr.eth.h_dest, rfc1042_header))
- 			goto purge;
- 
- 		offset += sizeof(struct ethhdr);
- 		last = remaining <= subframe_len + padding;
- 
- 		/* FIXME: should we really accept multicast DA? */
--		if ((check_da && !is_multicast_ether_addr(eth.h_dest) &&
--		     !ether_addr_equal(check_da, eth.h_dest)) ||
--		    (check_sa && !ether_addr_equal(check_sa, eth.h_source))) {
-+		if ((check_da && !is_multicast_ether_addr(hdr.eth.h_dest) &&
-+		     !ether_addr_equal(check_da, hdr.eth.h_dest)) ||
-+		    (check_sa && !ether_addr_equal(check_sa, hdr.eth.h_source))) {
- 			offset += len + padding;
- 			continue;
- 		}
-@@ -808,7 +839,7 @@ void ieee80211_amsdu_to_8023s(struct sk_
- 			reuse_skb = true;
- 		} else {
- 			frame = __ieee80211_amsdu_copy(skb, hlen, offset, len,
--						       reuse_frag);
-+						       reuse_frag, 32 + mesh_len);
- 			if (!frame)
- 				goto purge;
- 
-@@ -819,10 +850,11 @@ void ieee80211_amsdu_to_8023s(struct sk_
- 		frame->dev = skb->dev;
- 		frame->priority = skb->priority;
- 
--		if (likely(ieee80211_get_8023_tunnel_proto(frame->data, &eth.h_proto)))
-+		if (likely(iftype != NL80211_IFTYPE_MESH_POINT &&
-+			   ieee80211_get_8023_tunnel_proto(frame->data, &hdr.eth.h_proto)))
- 			skb_pull(frame, ETH_ALEN + 2);
- 
--		memcpy(skb_push(frame, sizeof(eth)), &eth, sizeof(eth));
-+		memcpy(skb_push(frame, sizeof(hdr.eth)), &hdr.eth, sizeof(hdr.eth));
- 		__skb_queue_tail(list, frame);
- 	}
- 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch
deleted file mode 100644
index 6dc98ae..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 9 Dec 2022 21:15:04 +0100
-Subject: [PATCH] wifi: mac80211: add a workaround for receiving
- non-standard mesh A-MSDU
-
-At least ath10k and ath11k supported hardware (maybe more) does not implement
-mesh A-MSDU aggregation in a standard compliant way.
-802.11-2020 9.3.2.2.2 declares that the Mesh Control field is part of the
-A-MSDU header. As such, its length must not be included in the subframe
-length field.
-Hardware affected by this bug treats the mesh control field as part of the
-MSDU data and sets the length accordingly.
-In order to avoid packet loss, keep track of which stations are affected
-by this and take it into account when converting A-MSDU to 802.3 + mesh control
-packets.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -6194,6 +6194,19 @@ static inline int ieee80211_data_to_8023
- }
- 
- /**
-+ * ieee80211_is_valid_amsdu - check if subframe lengths of an A-MSDU are valid
-+ *
-+ * This is used to detect non-standard A-MSDU frames, e.g. the ones generated
-+ * by ath10k and ath11k, where the subframe length includes the length of the
-+ * mesh control field.
-+ *
-+ * @skb: The input A-MSDU frame without any headers.
-+ * @mesh_hdr: use standard compliant mesh A-MSDU subframe header
-+ * Returns: true if subframe header lengths are valid for the @mesh_hdr mode
-+ */
-+bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr);
-+
-+/**
-  * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame
-  *
-  * Decode an IEEE 802.11 A-MSDU and convert it to a list of 802.3 frames.
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2899,7 +2899,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
- 	static ieee80211_rx_result res;
- 	struct ethhdr ethhdr;
- 	const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
--	bool mesh = false;
- 
- 	if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
- 		check_da = NULL;
-@@ -2917,7 +2916,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
- 		case NL80211_IFTYPE_MESH_POINT:
- 			check_sa = NULL;
- 			check_da = NULL;
--			mesh = true;
- 			break;
- 		default:
- 			break;
-@@ -2932,10 +2930,21 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
- 					  data_offset, true))
- 		return RX_DROP_UNUSABLE;
- 
-+	if (rx->sta && rx->sta->amsdu_mesh_control < 0) {
-+		bool valid_std = ieee80211_is_valid_amsdu(skb, true);
-+		bool valid_nonstd = ieee80211_is_valid_amsdu(skb, false);
-+
-+		if (valid_std && !valid_nonstd)
-+			rx->sta->amsdu_mesh_control = 1;
-+		else if (valid_nonstd && !valid_std)
-+			rx->sta->amsdu_mesh_control = 0;
-+	}
-+
- 	ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
- 				 rx->sdata->vif.type,
- 				 rx->local->hw.extra_tx_headroom,
--				 check_da, check_sa, mesh);
-+				 check_da, check_sa,
-+				 rx->sta->amsdu_mesh_control);
- 
- 	while (!skb_queue_empty(&frame_list)) {
- 		rx->skb = __skb_dequeue(&frame_list);
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -591,6 +591,9 @@ __sta_info_alloc(struct ieee80211_sub_if
- 
- 	sta->sta_state = IEEE80211_STA_NONE;
- 
-+	if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
-+		sta->amsdu_mesh_control = -1;
-+
- 	/* Mark TID as unreserved */
- 	sta->reserved_tid = IEEE80211_TID_UNRESERVED;
- 
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -702,6 +702,7 @@ struct sta_info {
- 	struct codel_params cparams;
- 
- 	u8 reserved_tid;
-+	s8 amsdu_mesh_control;
- 
- 	struct cfg80211_chan_def tdls_chandef;
- 
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -776,6 +776,38 @@ __ieee80211_amsdu_copy(struct sk_buff *s
- 	return frame;
- }
- 
-+bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr)
-+{
-+	int offset = 0, remaining, subframe_len, padding;
-+
-+	for (offset = 0; offset < skb->len; offset += subframe_len + padding) {
-+		struct {
-+		    __be16 len;
-+		    u8 mesh_flags;
-+		} hdr;
-+		u16 len;
-+
-+		if (skb_copy_bits(skb, offset + 2 * ETH_ALEN, &hdr, sizeof(hdr)) < 0)
-+			return false;
-+
-+		if (mesh_hdr)
-+			len = le16_to_cpu(*(__le16 *)&hdr.len) +
-+			      __ieee80211_get_mesh_hdrlen(hdr.mesh_flags);
-+		else
-+			len = ntohs(hdr.len);
-+
-+		subframe_len = sizeof(struct ethhdr) + len;
-+		padding = (4 - subframe_len) & 0x3;
-+		remaining = skb->len - offset;
-+
-+		if (subframe_len > remaining)
-+			return false;
-+	}
-+
-+	return true;
-+}
-+EXPORT_SYMBOL(ieee80211_is_valid_amsdu);
-+
- void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
- 			      const u8 *addr, enum nl80211_iftype iftype,
- 			      const unsigned int extra_headroom,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch
deleted file mode 100644
index 7d01ffd..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 15 Feb 2023 15:21:37 +0100
-Subject: [PATCH] wifi: mac80211: fix race in mesh sequence number
- assignment
-
-Since the sequence number is shared across different tx queues, it needs
-to be atomic in order to avoid accidental duplicate assignment
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -696,7 +696,7 @@ struct ieee80211_if_mesh {
- 	struct mesh_stats mshstats;
- 	struct mesh_config mshcfg;
- 	atomic_t estab_plinks;
--	u32 mesh_seqnum;
-+	atomic_t mesh_seqnum;
- 	bool accepting_plinks;
- 	int num_gates;
- 	struct beacon_data __rcu *beacon;
---- a/net/mac80211/mesh.c
-+++ b/net/mac80211/mesh.c
-@@ -752,10 +752,8 @@ unsigned int ieee80211_new_mesh_header(s
- 
- 	meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
- 
--	/* FIXME: racy -- TX on multiple queues can be concurrent */
--	put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
--	sdata->u.mesh.mesh_seqnum++;
--
-+	put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum),
-+			   &meshhdr->seqnum);
- 	if (addr4or5 && !addr6) {
- 		meshhdr->flags |= MESH_FLAGS_AE_A4;
- 		memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch
deleted file mode 100644
index 968d288..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch
+++ /dev/null
@@ -1,850 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 26 Feb 2023 13:53:08 +0100
-Subject: [PATCH] wifi: mac80211: mesh fast xmit support
-
-Previously, fast xmit only worked on interface types where initially a
-sta lookup is performed, and a cached header can be attached to the sta,
-requiring only some fields to be updated at runtime.
-
-This technique is not directly applicable for a mesh device type due
-to the dynamic nature of the topology and protocol. There are more
-addresses that need to be filled, and there is an extra header with a
-dynamic length based on the addressing mode.
-
-Change the code to cache entries contain a copy of the mesh subframe header +
-bridge tunnel header, as well as an embedded struct ieee80211_fast_tx, which
-contains the information for building the 802.11 header.
-
-Add a mesh specific early fast xmit call, which looks up a cached entry and
-adds only the mesh subframe header, before passing it over to the generic
-fast xmit code.
-
-To ensure the changes in network are reflected in these cached headers,
-flush affected cached entries on path changes, as well as other conditions
-that currently trigger a fast xmit check in other modes (key changes etc.)
-
-This code is loosely based on a previous implementation by:
-Sriram R <quic_srirrama@quicinc.com>
-
-Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -37,6 +37,7 @@
- extern const struct cfg80211_ops mac80211_config_ops;
- 
- struct ieee80211_local;
-+struct ieee80211_mesh_fast_tx;
- 
- /* Maximum number of broadcast/multicast frames to buffer when some of the
-  * associated stations are using power saving. */
-@@ -656,6 +657,19 @@ struct mesh_table {
- 	atomic_t entries;		/* Up to MAX_MESH_NEIGHBOURS */
- };
- 
-+/**
-+ * struct mesh_tx_cache - mesh fast xmit header cache
-+ *
-+ * @rht: hash table containing struct ieee80211_mesh_fast_tx, using skb DA as key
-+ * @walk_head: linked list containing all ieee80211_mesh_fast_tx objects
-+ * @walk_lock: lock protecting walk_head and rht
-+ */
-+struct mesh_tx_cache {
-+	struct rhashtable rht;
-+	struct hlist_head walk_head;
-+	spinlock_t walk_lock;
-+};
-+
- struct ieee80211_if_mesh {
- 	struct timer_list housekeeping_timer;
- 	struct timer_list mesh_path_timer;
-@@ -734,6 +748,7 @@ struct ieee80211_if_mesh {
- 	struct mesh_table mpp_paths; /* Store paths for MPP&MAP */
- 	int mesh_paths_generation;
- 	int mpp_paths_generation;
-+	struct mesh_tx_cache tx_cache;
- };
- 
- #ifdef CPTCFG_MAC80211_MESH
-@@ -2002,6 +2017,11 @@ int ieee80211_tx_control_port(struct wip
- 			      int link_id, u64 *cookie);
- int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
- 			      const u8 *buf, size_t len);
-+void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
-+			   struct sta_info *sta,
-+			   struct ieee80211_fast_tx *fast_tx,
-+			   struct sk_buff *skb, bool ampdu,
-+			   const u8 *da, const u8 *sa);
- 
- /* HT */
- void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
---- a/net/mac80211/mesh.c
-+++ b/net/mac80211/mesh.c
-@@ -10,6 +10,7 @@
- #include <asm/unaligned.h>
- #include "ieee80211_i.h"
- #include "mesh.h"
-+#include "wme.h"
- #include "driver-ops.h"
- 
- static int mesh_allocated;
-@@ -698,6 +699,95 @@ ieee80211_mesh_update_bss_params(struct
- 			__le32_to_cpu(he_oper->he_oper_params);
- }
- 
-+bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
-+			      struct sk_buff *skb, u32 ctrl_flags)
-+{
-+	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-+	struct ieee80211_mesh_fast_tx *entry;
-+	struct ieee80211s_hdr *meshhdr;
-+	u8 sa[ETH_ALEN] __aligned(2);
-+	struct tid_ampdu_tx *tid_tx;
-+	struct sta_info *sta;
-+	bool copy_sa = false;
-+	u16 ethertype;
-+	u8 tid;
-+
-+	if (ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP)
-+		return false;
-+
-+	if (ifmsh->mshcfg.dot11MeshNolearn)
-+		return false;
-+
-+	/* Add support for these cases later */
-+	if (ifmsh->ps_peers_light_sleep || ifmsh->ps_peers_deep_sleep)
-+		return false;
-+
-+	if (is_multicast_ether_addr(skb->data))
-+		return false;
-+
-+	ethertype = (skb->data[12] << 8) | skb->data[13];
-+	if (ethertype < ETH_P_802_3_MIN)
-+		return false;
-+
-+	if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)
-+		return false;
-+
-+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-+		skb_set_transport_header(skb, skb_checksum_start_offset(skb));
-+		if (skb_checksum_help(skb))
-+			return false;
-+	}
-+
-+	entry = mesh_fast_tx_get(sdata, skb->data);
-+	if (!entry)
-+		return false;
-+
-+	if (skb_headroom(skb) < entry->hdrlen + entry->fast_tx.hdr_len)
-+		return false;
-+
-+	sta = rcu_dereference(entry->mpath->next_hop);
-+	if (!sta)
-+		return false;
-+
-+	tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-+	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
-+	if (tid_tx) {
-+		if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state))
-+			return false;
-+		if (tid_tx->timeout)
-+			tid_tx->last_tx = jiffies;
-+	}
-+
-+	skb = skb_share_check(skb, GFP_ATOMIC);
-+	if (!skb)
-+		return true;
-+
-+	skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
-+
-+	meshhdr = (struct ieee80211s_hdr *)entry->hdr;
-+	if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) {
-+		/* preserve SA from eth header for 6-addr frames */
-+		ether_addr_copy(sa, skb->data + ETH_ALEN);
-+		copy_sa = true;
-+	}
-+
-+	memcpy(skb_push(skb, entry->hdrlen - 2 * ETH_ALEN), entry->hdr,
-+	       entry->hdrlen);
-+
-+	meshhdr = (struct ieee80211s_hdr *)skb->data;
-+	put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum),
-+			   &meshhdr->seqnum);
-+	meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
-+	if (copy_sa)
-+	    ether_addr_copy(meshhdr->eaddr2, sa);
-+
-+	skb_push(skb, 2 * ETH_ALEN);
-+	__ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx,
-+			      entry->mpath->dst, sdata->vif.addr);
-+
-+	return true;
-+}
-+
- /**
-  * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
-  * @hdr:	802.11 frame header
-@@ -780,6 +870,8 @@ static void ieee80211_mesh_housekeeping(
- 	changed = mesh_accept_plinks_update(sdata);
- 	ieee80211_mbss_info_change_notify(sdata, changed);
- 
-+	mesh_fast_tx_gc(sdata);
-+
- 	mod_timer(&ifmsh->housekeeping_timer,
- 		  round_jiffies(jiffies +
- 				IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
---- a/net/mac80211/mesh.h
-+++ b/net/mac80211/mesh.h
-@@ -122,11 +122,41 @@ struct mesh_path {
- 	u8 rann_snd_addr[ETH_ALEN];
- 	u32 rann_metric;
- 	unsigned long last_preq_to_root;
-+	unsigned long fast_tx_check;
- 	bool is_root;
- 	bool is_gate;
- 	u32 path_change_count;
- };
- 
-+#define MESH_FAST_TX_CACHE_MAX_SIZE		512
-+#define MESH_FAST_TX_CACHE_THRESHOLD_SIZE	384
-+#define MESH_FAST_TX_CACHE_TIMEOUT		8000 /* msecs */
-+
-+/**
-+ * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry
-+ * @rhash: rhashtable pointer
-+ * @addr_key: The Ethernet DA which is the key for this entry
-+ * @fast_tx: base fast_tx data
-+ * @hdr: cached mesh and rfc1042 headers
-+ * @hdrlen: length of mesh + rfc1042
-+ * @walk_list: list containing all the fast tx entries
-+ * @mpath: mesh path corresponding to the Mesh DA
-+ * @mppath: MPP entry corresponding to this DA
-+ * @timestamp: Last used time of this entry
-+ */
-+struct ieee80211_mesh_fast_tx {
-+	struct rhash_head rhash;
-+	u8 addr_key[ETH_ALEN] __aligned(2);
-+
-+	struct ieee80211_fast_tx fast_tx;
-+	u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)];
-+	u16 hdrlen;
-+
-+	struct mesh_path *mpath, *mppath;
-+	struct hlist_node walk_list;
-+	unsigned long timestamp;
-+};
-+
- /* Recent multicast cache */
- /* RMC_BUCKETS must be a power of 2, maximum 256 */
- #define RMC_BUCKETS		256
-@@ -298,6 +328,20 @@ void mesh_path_discard_frame(struct ieee
- void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
- 
- bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
-+struct ieee80211_mesh_fast_tx *
-+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr);
-+bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
-+			      struct sk_buff *skb, u32 ctrl_flags);
-+void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
-+			struct sk_buff *skb, struct mesh_path *mpath);
-+void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata);
-+void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata,
-+			     const u8 *addr);
-+void mesh_fast_tx_flush_mpath(struct mesh_path *mpath);
-+void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata,
-+			    struct sta_info *sta);
-+void mesh_path_refresh(struct ieee80211_sub_if_data *sdata,
-+		       struct mesh_path *mpath, const u8 *addr);
- 
- #ifdef CPTCFG_MAC80211_MESH
- static inline
---- a/net/mac80211/mesh_hwmp.c
-+++ b/net/mac80211/mesh_hwmp.c
-@@ -394,6 +394,7 @@ static u32 hwmp_route_info_get(struct ie
- 	u32 orig_sn, orig_metric;
- 	unsigned long orig_lifetime, exp_time;
- 	u32 last_hop_metric, new_metric;
-+	bool flush_mpath = false;
- 	bool process = true;
- 	u8 hopcount;
- 
-@@ -491,8 +492,10 @@ static u32 hwmp_route_info_get(struct ie
- 		}
- 
- 		if (fresh_info) {
--			if (rcu_access_pointer(mpath->next_hop) != sta)
-+			if (rcu_access_pointer(mpath->next_hop) != sta) {
- 				mpath->path_change_count++;
-+				flush_mpath = true;
-+			}
- 			mesh_path_assign_nexthop(mpath, sta);
- 			mpath->flags |= MESH_PATH_SN_VALID;
- 			mpath->metric = new_metric;
-@@ -502,6 +505,8 @@ static u32 hwmp_route_info_get(struct ie
- 			mpath->hop_count = hopcount;
- 			mesh_path_activate(mpath);
- 			spin_unlock_bh(&mpath->state_lock);
-+			if (flush_mpath)
-+				mesh_fast_tx_flush_mpath(mpath);
- 			ewma_mesh_fail_avg_init(&sta->mesh->fail_avg);
- 			/* init it at a low value - 0 start is tricky */
- 			ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1);
-@@ -539,8 +544,10 @@ static u32 hwmp_route_info_get(struct ie
- 		}
- 
- 		if (fresh_info) {
--			if (rcu_access_pointer(mpath->next_hop) != sta)
-+			if (rcu_access_pointer(mpath->next_hop) != sta) {
- 				mpath->path_change_count++;
-+				flush_mpath = true;
-+			}
- 			mesh_path_assign_nexthop(mpath, sta);
- 			mpath->metric = last_hop_metric;
- 			mpath->exp_time = time_after(mpath->exp_time, exp_time)
-@@ -548,6 +555,8 @@ static u32 hwmp_route_info_get(struct ie
- 			mpath->hop_count = 1;
- 			mesh_path_activate(mpath);
- 			spin_unlock_bh(&mpath->state_lock);
-+			if (flush_mpath)
-+				mesh_fast_tx_flush_mpath(mpath);
- 			ewma_mesh_fail_avg_init(&sta->mesh->fail_avg);
- 			/* init it at a low value - 0 start is tricky */
- 			ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1);
-@@ -1215,6 +1224,20 @@ static int mesh_nexthop_lookup_nolearn(s
- 	return 0;
- }
- 
-+void mesh_path_refresh(struct ieee80211_sub_if_data *sdata,
-+		       struct mesh_path *mpath, const u8 *addr)
-+{
-+	if (mpath->flags & (MESH_PATH_REQ_QUEUED | MESH_PATH_FIXED |
-+			    MESH_PATH_RESOLVING))
-+		return;
-+
-+	if (time_after(jiffies,
-+		       mpath->exp_time -
-+		       msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
-+	    (!addr || ether_addr_equal(sdata->vif.addr, addr)))
-+		mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
-+}
-+
- /**
-  * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
-  * this function is considered "using" the associated mpath, so preempt a path
-@@ -1242,19 +1265,15 @@ int mesh_nexthop_lookup(struct ieee80211
- 	if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE))
- 		return -ENOENT;
- 
--	if (time_after(jiffies,
--		       mpath->exp_time -
--		       msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
--	    ether_addr_equal(sdata->vif.addr, hdr->addr4) &&
--	    !(mpath->flags & MESH_PATH_RESOLVING) &&
--	    !(mpath->flags & MESH_PATH_FIXED))
--		mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
-+	mesh_path_refresh(sdata, mpath, hdr->addr4);
- 
- 	next_hop = rcu_dereference(mpath->next_hop);
- 	if (next_hop) {
- 		memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
- 		memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
- 		ieee80211_mps_set_frame_flags(sdata, next_hop, hdr);
-+		if (ieee80211_hw_check(&sdata->local->hw, SUPPORT_FAST_XMIT))
-+			mesh_fast_tx_cache(sdata, skb, mpath);
- 		return 0;
- 	}
- 
---- a/net/mac80211/mesh_pathtbl.c
-+++ b/net/mac80211/mesh_pathtbl.c
-@@ -14,6 +14,7 @@
- #include "wme.h"
- #include "ieee80211_i.h"
- #include "mesh.h"
-+#include <linux/rhashtable.h>
- 
- static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath);
- 
-@@ -32,6 +33,41 @@ static const struct rhashtable_params me
- 	.hashfn = mesh_table_hash,
- };
- 
-+static const struct rhashtable_params fast_tx_rht_params = {
-+	.nelem_hint = 10,
-+	.automatic_shrinking = true,
-+	.key_len = ETH_ALEN,
-+	.key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key),
-+	.head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash),
-+	.hashfn = mesh_table_hash,
-+};
-+
-+static void __mesh_fast_tx_entry_free(void *ptr, void *tblptr)
-+{
-+	struct ieee80211_mesh_fast_tx *entry = ptr;
-+
-+	kfree_rcu(entry, fast_tx.rcu_head);
-+}
-+
-+static void mesh_fast_tx_deinit(struct ieee80211_sub_if_data *sdata)
-+{
-+	struct mesh_tx_cache *cache;
-+
-+	cache = &sdata->u.mesh.tx_cache;
-+	rhashtable_free_and_destroy(&cache->rht,
-+				    __mesh_fast_tx_entry_free, NULL);
-+}
-+
-+static void mesh_fast_tx_init(struct ieee80211_sub_if_data *sdata)
-+{
-+	struct mesh_tx_cache *cache;
-+
-+	cache = &sdata->u.mesh.tx_cache;
-+	rhashtable_init(&cache->rht, &fast_tx_rht_params);
-+	INIT_HLIST_HEAD(&cache->walk_head);
-+	spin_lock_init(&cache->walk_lock);
-+}
-+
- static inline bool mpath_expired(struct mesh_path *mpath)
- {
- 	return (mpath->flags & MESH_PATH_ACTIVE) &&
-@@ -381,6 +417,243 @@ struct mesh_path *mesh_path_new(struct i
- 	return new_mpath;
- }
- 
-+static void mesh_fast_tx_entry_free(struct mesh_tx_cache *cache,
-+				    struct ieee80211_mesh_fast_tx *entry)
-+{
-+	hlist_del_rcu(&entry->walk_list);
-+	rhashtable_remove_fast(&cache->rht, &entry->rhash, fast_tx_rht_params);
-+	kfree_rcu(entry, fast_tx.rcu_head);
-+}
-+
-+struct ieee80211_mesh_fast_tx *
-+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr)
-+{
-+	struct ieee80211_mesh_fast_tx *entry;
-+	struct mesh_tx_cache *cache;
-+
-+	cache = &sdata->u.mesh.tx_cache;
-+	entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
-+	if (!entry)
-+		return NULL;
-+
-+	if (!(entry->mpath->flags & MESH_PATH_ACTIVE) ||
-+	    mpath_expired(entry->mpath)) {
-+		spin_lock_bh(&cache->walk_lock);
-+		entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
-+		if (entry)
-+		    mesh_fast_tx_entry_free(cache, entry);
-+		spin_unlock_bh(&cache->walk_lock);
-+		return NULL;
-+	}
-+
-+	mesh_path_refresh(sdata, entry->mpath, NULL);
-+	if (entry->mppath)
-+		entry->mppath->exp_time = jiffies;
-+	entry->timestamp = jiffies;
-+
-+	return entry;
-+}
-+
-+void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
-+			struct sk_buff *skb, struct mesh_path *mpath)
-+{
-+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+	struct ieee80211_mesh_fast_tx *entry, *prev;
-+	struct ieee80211_mesh_fast_tx build = {};
-+	struct ieee80211s_hdr *meshhdr;
-+	struct mesh_tx_cache *cache;
-+	struct ieee80211_key *key;
-+	struct mesh_path *mppath;
-+	struct sta_info *sta;
-+	u8 *qc;
-+
-+	if (sdata->noack_map ||
-+	    !ieee80211_is_data_qos(hdr->frame_control))
-+		return;
-+
-+	build.fast_tx.hdr_len = ieee80211_hdrlen(hdr->frame_control);
-+	meshhdr = (struct ieee80211s_hdr *)(skb->data + build.fast_tx.hdr_len);
-+	build.hdrlen = ieee80211_get_mesh_hdrlen(meshhdr);
-+
-+	cache = &sdata->u.mesh.tx_cache;
-+	if (atomic_read(&cache->rht.nelems) >= MESH_FAST_TX_CACHE_MAX_SIZE)
-+		return;
-+
-+	sta = rcu_dereference(mpath->next_hop);
-+	if (!sta)
-+		return;
-+
-+	if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) {
-+		/* This is required to keep the mppath alive */
-+		mppath = mpp_path_lookup(sdata, meshhdr->eaddr1);
-+		if (!mppath)
-+			return;
-+		build.mppath = mppath;
-+	} else if (ieee80211_has_a4(hdr->frame_control)) {
-+		mppath = mpath;
-+	} else {
-+		return;
-+	}
-+
-+	/* rate limit, in case fast xmit can't be enabled */
-+	if (mppath->fast_tx_check == jiffies)
-+		return;
-+
-+	mppath->fast_tx_check = jiffies;
-+
-+	/*
-+	 * Same use of the sta lock as in ieee80211_check_fast_xmit, in order
-+	 * to protect against concurrent sta key updates.
-+	 */
-+	spin_lock_bh(&sta->lock);
-+	key = rcu_access_pointer(sta->ptk[sta->ptk_idx]);
-+	if (!key)
-+		key = rcu_access_pointer(sdata->default_unicast_key);
-+	build.fast_tx.key = key;
-+
-+	if (key) {
-+		bool gen_iv, iv_spc;
-+
-+		gen_iv = key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV;
-+		iv_spc = key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE;
-+
-+		if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) ||
-+		    (key->flags & KEY_FLAG_TAINTED))
-+			goto unlock_sta;
-+
-+		switch (key->conf.cipher) {
-+		case WLAN_CIPHER_SUITE_CCMP:
-+		case WLAN_CIPHER_SUITE_CCMP_256:
-+			if (gen_iv)
-+				build.fast_tx.pn_offs = build.fast_tx.hdr_len;
-+			if (gen_iv || iv_spc)
-+				build.fast_tx.hdr_len += IEEE80211_CCMP_HDR_LEN;
-+			break;
-+		case WLAN_CIPHER_SUITE_GCMP:
-+		case WLAN_CIPHER_SUITE_GCMP_256:
-+			if (gen_iv)
-+				build.fast_tx.pn_offs = build.fast_tx.hdr_len;
-+			if (gen_iv || iv_spc)
-+				build.fast_tx.hdr_len += IEEE80211_GCMP_HDR_LEN;
-+			break;
-+		default:
-+			goto unlock_sta;
-+		}
-+	}
-+
-+	memcpy(build.addr_key, mppath->dst, ETH_ALEN);
-+	build.timestamp = jiffies;
-+	build.fast_tx.band = info->band;
-+	build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3);
-+	build.fast_tx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
-+	build.mpath = mpath;
-+	memcpy(build.hdr, meshhdr, build.hdrlen);
-+	memcpy(build.hdr + build.hdrlen, rfc1042_header, sizeof(rfc1042_header));
-+	build.hdrlen += sizeof(rfc1042_header);
-+	memcpy(build.fast_tx.hdr, hdr, build.fast_tx.hdr_len);
-+
-+	hdr = (struct ieee80211_hdr *)build.fast_tx.hdr;
-+	if (build.fast_tx.key)
-+		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-+
-+	qc = ieee80211_get_qos_ctl(hdr);
-+	qc[1] |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8;
-+
-+	entry = kmemdup(&build, sizeof(build), GFP_ATOMIC);
-+	if (!entry)
-+		goto unlock_sta;
-+
-+	spin_lock(&cache->walk_lock);
-+	prev = rhashtable_lookup_get_insert_fast(&cache->rht,
-+						 &entry->rhash,
-+						 fast_tx_rht_params);
-+	if (unlikely(IS_ERR(prev))) {
-+		kfree(entry);
-+		goto unlock_cache;
-+	}
-+
-+	/*
-+	 * replace any previous entry in the hash table, in case we're
-+	 * replacing it with a different type (e.g. mpath -> mpp)
-+	 */
-+	if (unlikely(prev)) {
-+		rhashtable_replace_fast(&cache->rht, &prev->rhash,
-+					&entry->rhash, fast_tx_rht_params);
-+		hlist_del_rcu(&prev->walk_list);
-+		kfree_rcu(prev, fast_tx.rcu_head);
-+	}
-+
-+	hlist_add_head(&entry->walk_list, &cache->walk_head);
-+
-+unlock_cache:
-+	spin_unlock(&cache->walk_lock);
-+unlock_sta:
-+	spin_unlock_bh(&sta->lock);
-+}
-+
-+void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata)
-+{
-+	unsigned long timeout = msecs_to_jiffies(MESH_FAST_TX_CACHE_TIMEOUT);
-+	struct mesh_tx_cache *cache;
-+	struct ieee80211_mesh_fast_tx *entry;
-+	struct hlist_node *n;
-+
-+	cache = &sdata->u.mesh.tx_cache;
-+	if (atomic_read(&cache->rht.nelems) < MESH_FAST_TX_CACHE_THRESHOLD_SIZE)
-+		return;
-+
-+	spin_lock_bh(&cache->walk_lock);
-+	hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list)
-+		if (!time_is_after_jiffies(entry->timestamp + timeout))
-+			mesh_fast_tx_entry_free(cache, entry);
-+	spin_unlock_bh(&cache->walk_lock);
-+}
-+
-+void mesh_fast_tx_flush_mpath(struct mesh_path *mpath)
-+{
-+	struct ieee80211_sub_if_data *sdata = mpath->sdata;
-+	struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache;
-+	struct ieee80211_mesh_fast_tx *entry;
-+	struct hlist_node *n;
-+
-+	cache = &sdata->u.mesh.tx_cache;
-+	spin_lock_bh(&cache->walk_lock);
-+	hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list)
-+		if (entry->mpath == mpath)
-+			mesh_fast_tx_entry_free(cache, entry);
-+	spin_unlock_bh(&cache->walk_lock);
-+}
-+
-+void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata,
-+			    struct sta_info *sta)
-+{
-+	struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache;
-+	struct ieee80211_mesh_fast_tx *entry;
-+	struct hlist_node *n;
-+
-+	cache = &sdata->u.mesh.tx_cache;
-+	spin_lock_bh(&cache->walk_lock);
-+	hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list)
-+		if (rcu_access_pointer(entry->mpath->next_hop) == sta)
-+			mesh_fast_tx_entry_free(cache, entry);
-+	spin_unlock_bh(&cache->walk_lock);
-+}
-+
-+void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata,
-+			     const u8 *addr)
-+{
-+	struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache;
-+	struct ieee80211_mesh_fast_tx *entry;
-+
-+	cache = &sdata->u.mesh.tx_cache;
-+	spin_lock_bh(&cache->walk_lock);
-+	entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
-+	if (entry)
-+		mesh_fast_tx_entry_free(cache, entry);
-+	spin_unlock_bh(&cache->walk_lock);
-+}
-+
- /**
-  * mesh_path_add - allocate and add a new path to the mesh path table
-  * @dst: destination address of the path (ETH_ALEN length)
-@@ -464,6 +737,8 @@ int mpp_path_add(struct ieee80211_sub_if
- 
- 	if (ret)
- 		kfree(new_mpath);
-+	else
-+		mesh_fast_tx_flush_addr(sdata, dst);
- 
- 	sdata->u.mesh.mpp_paths_generation++;
- 	return ret;
-@@ -523,6 +798,10 @@ static void __mesh_path_del(struct mesh_
- {
- 	hlist_del_rcu(&mpath->walk_list);
- 	rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params);
-+	if (tbl == &mpath->sdata->u.mesh.mpp_paths)
-+		mesh_fast_tx_flush_addr(mpath->sdata, mpath->dst);
-+	else
-+		mesh_fast_tx_flush_mpath(mpath);
- 	mesh_path_free_rcu(tbl, mpath);
- }
- 
-@@ -747,6 +1026,7 @@ void mesh_path_fix_nexthop(struct mesh_p
- 	mpath->exp_time = 0;
- 	mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;
- 	mesh_path_activate(mpath);
-+	mesh_fast_tx_flush_mpath(mpath);
- 	spin_unlock_bh(&mpath->state_lock);
- 	ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg);
- 	/* init it at a low value - 0 start is tricky */
-@@ -758,6 +1038,7 @@ void mesh_pathtbl_init(struct ieee80211_
- {
- 	mesh_table_init(&sdata->u.mesh.mesh_paths);
- 	mesh_table_init(&sdata->u.mesh.mpp_paths);
-+	mesh_fast_tx_init(sdata);
- }
- 
- static
-@@ -785,6 +1066,7 @@ void mesh_path_expire(struct ieee80211_s
- 
- void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata)
- {
-+	mesh_fast_tx_deinit(sdata);
- 	mesh_table_free(&sdata->u.mesh.mesh_paths);
- 	mesh_table_free(&sdata->u.mesh.mpp_paths);
- }
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2791,6 +2791,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 	if (mesh_hdr->flags & MESH_FLAGS_AE) {
- 		struct mesh_path *mppath;
- 		char *proxied_addr;
-+		bool update = false;
- 
- 		if (multicast)
- 			proxied_addr = mesh_hdr->eaddr1;
-@@ -2806,11 +2807,18 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 			mpp_path_add(sdata, proxied_addr, eth->h_source);
- 		} else {
- 			spin_lock_bh(&mppath->state_lock);
--			if (!ether_addr_equal(mppath->mpp, eth->h_source))
-+			if (!ether_addr_equal(mppath->mpp, eth->h_source)) {
- 				memcpy(mppath->mpp, eth->h_source, ETH_ALEN);
-+				update = true;
-+			}
- 			mppath->exp_time = jiffies;
- 			spin_unlock_bh(&mppath->state_lock);
- 		}
-+
-+		/* flush fast xmit cache if the address path changed */
-+		if (update)
-+			mesh_fast_tx_flush_addr(sdata, proxied_addr);
-+
- 		rcu_read_unlock();
- 	}
- 
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3022,6 +3022,9 @@ void ieee80211_check_fast_xmit(struct st
- 	if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT))
- 		return;
- 
-+	if (ieee80211_vif_is_mesh(&sdata->vif))
-+		mesh_fast_tx_flush_sta(sdata, sta);
-+
- 	/* Locking here protects both the pointer itself, and against concurrent
- 	 * invocations winning data access races to, e.g., the key pointer that
- 	 * is used.
-@@ -3403,6 +3406,9 @@ static bool ieee80211_amsdu_aggregate(st
- 	if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
- 		return false;
- 
-+	if (ieee80211_vif_is_mesh(&sdata->vif))
-+		return false;
-+
- 	if (skb_is_gso(skb))
- 		return false;
- 
-@@ -3635,10 +3641,11 @@ free:
- 	return NULL;
- }
- 
--static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
--				  struct sta_info *sta,
--				  struct ieee80211_fast_tx *fast_tx,
--				  struct sk_buff *skb, u8 tid, bool ampdu)
-+void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
-+			   struct sta_info *sta,
-+			   struct ieee80211_fast_tx *fast_tx,
-+			   struct sk_buff *skb, bool ampdu,
-+			   const u8 *da, const u8 *sa)
- {
- 	struct ieee80211_local *local = sdata->local;
- 	struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
-@@ -3647,7 +3654,6 @@ static void __ieee80211_xmit_fast(struct
- 	ieee80211_tx_result r;
- 	int hw_headroom = sdata->local->hw.extra_tx_headroom;
- 	int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
--	struct ethhdr eth;
- 
- 	skb = skb_share_check(skb, GFP_ATOMIC);
- 	if (unlikely(!skb))
-@@ -3667,11 +3673,10 @@ static void __ieee80211_xmit_fast(struct
- 					  ENCRYPT_NO)))
- 		goto free;
- 
--	memcpy(&eth, skb->data, ETH_HLEN - 2);
- 	hdr = skb_push(skb, extra_head);
- 	memcpy(skb->data, fast_tx->hdr, fast_tx->hdr_len);
--	memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN);
--	memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN);
-+	memcpy(skb->data + fast_tx->da_offs, da, ETH_ALEN);
-+	memcpy(skb->data + fast_tx->sa_offs, sa, ETH_ALEN);
- 
- 	info = IEEE80211_SKB_CB(skb);
- 	memset(info, 0, sizeof(*info));
-@@ -3690,7 +3695,8 @@ static void __ieee80211_xmit_fast(struct
- #endif
- 
- 	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
--		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-+		u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-+
- 		*ieee80211_get_qos_ctl(hdr) = tid;
- 	}
- 
-@@ -3733,6 +3739,7 @@ static bool ieee80211_xmit_fast(struct i
- 	struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
- 	struct tid_ampdu_tx *tid_tx = NULL;
- 	struct sk_buff *next;
-+	struct ethhdr eth;
- 	u8 tid = IEEE80211_NUM_TIDS;
- 
- 	/* control port protocol needs a lot of special handling */
-@@ -3758,6 +3765,8 @@ static bool ieee80211_xmit_fast(struct i
- 		}
- 	}
- 
-+	memcpy(&eth, skb->data, ETH_HLEN - 2);
-+
- 	/* after this point (skb is modified) we cannot return false */
- 	skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata));
- 	if (!skb)
-@@ -3765,7 +3774,8 @@ static bool ieee80211_xmit_fast(struct i
- 
- 	skb_list_walk_safe(skb, skb, next) {
- 		skb_mark_not_on_list(skb);
--		__ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx);
-+		__ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid_tx,
-+				      eth.h_dest, eth.h_source);
- 	}
- 
- 	return true;
-@@ -4252,8 +4262,15 @@ void __ieee80211_subif_start_xmit(struct
- 		return;
- 	}
- 
-+	sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
-+
- 	rcu_read_lock();
- 
-+	if (ieee80211_vif_is_mesh(&sdata->vif) &&
-+	    ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT) &&
-+	    ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags))
-+		goto out;
-+
- 	if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
- 		goto out_free;
- 
-@@ -4263,8 +4280,6 @@ void __ieee80211_subif_start_xmit(struct
- 	skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
- 	ieee80211_aggr_check(sdata, sta, skb);
- 
--	sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
--
- 	if (sta) {
- 		struct ieee80211_fast_tx *fast_tx;
- 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/320-cfg80211-allow-grace-period-for-DFS-available-after-.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/320-cfg80211-allow-grace-period-for-DFS-available-after-.patch
new file mode 100644
index 0000000..28e2144
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/320-cfg80211-allow-grace-period-for-DFS-available-after-.patch
@@ -0,0 +1,149 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 14 Sep 2023 13:17:16 +0200
+Subject: [PATCH] cfg80211: allow grace period for DFS available after beacon
+ shutdown
+
+Fixes reconfiguring an AP on a DFS channel in non-ETSI regdomain
+
+Fixes: b35a51c7dd25 ("cfg80211: Make pre-CAC results valid only for ETSI domain")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -175,6 +175,8 @@ enum ieee80211_channel_flags {
+  * @dfs_state: current state of this channel. Only relevant if radar is required
+  *	on this channel.
+  * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
++ * @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 {
+@@ -191,6 +193,7 @@ 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;
+ };
+ 
+--- a/net/wireless/ap.c
++++ b/net/wireless/ap.c
+@@ -30,6 +30,9 @@ static int ___cfg80211_stop_ap(struct cf
+ 	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;
+@@ -41,9 +44,6 @@ static int ___cfg80211_stop_ap(struct cf
+ 		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);
+ 	}
+ 
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -461,6 +461,8 @@ static void cfg80211_set_chans_dfs_state
+ 
+ 		c->dfs_state = dfs_state;
+ 		c->dfs_state_entered = jiffies;
++		if (dfs_state == NL80211_DFS_AVAILABLE)
++			c->dfs_state_last_available = jiffies;
+ 	}
+ }
+ 
+@@ -874,6 +876,49 @@ static bool cfg80211_get_chans_dfs_avail
+ 	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)
+ {
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -474,6 +474,8 @@ void cfg80211_set_dfs_state(struct 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);
+ 
+ void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
+ 
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -915,6 +915,8 @@ void cfg80211_dfs_channels_update_work(s
+ 			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))
+@@ -922,11 +924,10 @@ void cfg80211_dfs_channels_update_work(s
+ 
+ 				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;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch
deleted file mode 100644
index 28b1ff1..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 16 Feb 2023 11:07:30 +0100
-Subject: [PATCH] wifi: mac80211: use mesh header cache to speed up mesh
- forwarding
-
-Significantly reduces mesh forwarding path CPU usage and enables the
-direct use of iTXQ.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2720,6 +2720,65 @@ ieee80211_deliver_skb(struct ieee80211_r
- 	}
- }
- 
-+#ifdef CPTCFG_MAC80211_MESH
-+static bool
-+ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata,
-+			       struct sk_buff *skb, int hdrlen)
-+{
-+	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-+	struct ieee80211_mesh_fast_tx *entry = NULL;
-+	struct ieee80211s_hdr *mesh_hdr;
-+	struct tid_ampdu_tx *tid_tx;
-+	struct sta_info *sta;
-+	struct ethhdr eth;
-+	u8 tid;
-+
-+	mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth));
-+	if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
-+		entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1);
-+	else if (!(mesh_hdr->flags & MESH_FLAGS_AE))
-+		entry = mesh_fast_tx_get(sdata, skb->data);
-+	if (!entry)
-+		return false;
-+
-+	sta = rcu_dereference(entry->mpath->next_hop);
-+	if (!sta)
-+		return false;
-+
-+	if (skb_linearize(skb))
-+		return false;
-+
-+	tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-+	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
-+	if (tid_tx) {
-+		if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state))
-+			return false;
-+
-+		if (tid_tx->timeout)
-+			tid_tx->last_tx = jiffies;
-+	}
-+
-+	ieee80211_aggr_check(sdata, sta, skb);
-+
-+	if (ieee80211_get_8023_tunnel_proto(skb->data + hdrlen,
-+					    &skb->protocol))
-+		hdrlen += ETH_ALEN;
-+	else
-+		skb->protocol = htons(skb->len - hdrlen);
-+	skb_set_network_header(skb, hdrlen + 2);
-+
-+	skb->dev = sdata->dev;
-+	memcpy(&eth, skb->data, ETH_HLEN - 2);
-+	skb_pull(skb, 2);
-+	__ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx,
-+			      eth.h_dest, eth.h_source);
-+	IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
-+	IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
-+
-+	return true;
-+}
-+#endif
-+
- static ieee80211_rx_result
- ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta,
- 		       struct sk_buff *skb)
-@@ -2824,6 +2883,10 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 
- 	skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
- 
-+	if (!multicast &&
-+	    ieee80211_rx_mesh_fast_forward(sdata, skb, mesh_hdrlen))
-+		return RX_QUEUED;
-+
- 	ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control,
- 				      eth->h_dest, eth->h_source);
- 	hdrlen = ieee80211_hdrlen(hdr.frame_control);
-@@ -2862,6 +2925,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
- 	info->control.vif = &sdata->vif;
- 	info->control.jiffies = jiffies;
-+	fwd_skb->dev = sdata->dev;
- 	if (multicast) {
- 		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
- 		memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
-@@ -2883,7 +2947,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 	}
- 
- 	IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
--	fwd_skb->dev = sdata->dev;
- 	ieee80211_add_pending_skb(local, fwd_skb);
- 
- rx_accept:
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -2022,6 +2022,8 @@ void __ieee80211_xmit_fast(struct ieee80
- 			   struct ieee80211_fast_tx *fast_tx,
- 			   struct sk_buff *skb, bool ampdu,
- 			   const u8 *da, const u8 *sa);
-+void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
-+			  struct sta_info *sta, struct sk_buff *skb);
- 
- /* HT */
- void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1191,10 +1191,8 @@ static bool ieee80211_tx_prep_agg(struct
- 	return queued;
- }
- 
--static void
--ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
--		     struct sta_info *sta,
--		     struct sk_buff *skb)
-+void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
-+			  struct sta_info *sta, struct sk_buff *skb)
- {
- 	struct rate_control_ref *ref = sdata->local->rate_ctrl;
- 	u16 tid;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/321-mac80211-fix-mesh-forwarding.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/321-mac80211-fix-mesh-forwarding.patch
deleted file mode 100644
index e2b268a..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/321-mac80211-fix-mesh-forwarding.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 20 Feb 2023 12:50:50 +0100
-Subject: [PATCH] mac80211: fix mesh forwarding
-
-Linearize packets (needed for forwarding A-MSDU subframes).
-Fix network header offset to fix flow dissector (and fair queueing).
-
-Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2904,6 +2904,9 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 
- 		if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
- 			return RX_DROP_UNUSABLE;
-+
-+		if (skb_linearize(fwd_skb))
-+			return RX_DROP_UNUSABLE;
- 	}
- 
- 	fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
-@@ -2918,7 +2921,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 		hdrlen += ETH_ALEN;
- 	else
- 		fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
--	skb_set_network_header(fwd_skb, hdrlen);
-+	skb_set_network_header(fwd_skb, hdrlen + 2);
- 
- 	info = IEEE80211_SKB_CB(fwd_skb);
- 	memset(info, 0, sizeof(*info));
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch
deleted file mode 100644
index 292a89e..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 26 Feb 2023 20:30:20 +0100
-Subject: [PATCH] wifi: mac80211: fix mesh path discovery based on unicast
- packets
-
-If a packet has reached its intended destination, it was bumped to the code
-that accepts it, without first checking if a mesh_path needs to be created
-based on the discovered source.
-Fix this by moving the destination address check further down
-
-Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2824,17 +2824,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 	    mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
- 		return RX_DROP_MONITOR;
- 
--	/* Frame has reached destination.  Don't forward */
--	if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
--		goto rx_accept;
--
--	if (!ifmsh->mshcfg.dot11MeshForwarding) {
--		if (is_multicast_ether_addr(eth->h_dest))
--			goto rx_accept;
--
--		return RX_DROP_MONITOR;
--	}
--
- 	/* forward packet */
- 	if (sdata->crypto_tx_tailroom_needed_cnt)
- 		tailroom = IEEE80211_ENCRYPT_TAILROOM;
-@@ -2881,6 +2870,17 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 		rcu_read_unlock();
- 	}
- 
-+	/* Frame has reached destination.  Don't forward */
-+	if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
-+		goto rx_accept;
-+
-+	if (!ifmsh->mshcfg.dot11MeshForwarding) {
-+		if (is_multicast_ether_addr(eth->h_dest))
-+			goto rx_accept;
-+
-+		return RX_DROP_MONITOR;
-+	}
-+
- 	skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
- 
- 	if (!multicast &&
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch
deleted file mode 100644
index e23dc4d..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From: Muna Sinada <quic_msinada@quicinc.com>
-Date: Wed, 5 Oct 2022 14:54:45 -0700
-Subject: [PATCH] wifi: mac80211: Add VHT MU-MIMO related flags in
- ieee80211_bss_conf
-
-Adding flags for SU Beamformer, SU Beamformee, MU Beamformer and
-MU Beamformee for VHT. This is utilized to pass MU-MIMO
-configurations from user space to driver in AP mode.
-
-Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
-Link: https://lore.kernel.org/r/1665006886-23874-1-git-send-email-quic_msinada@quicinc.com
-[fixed indentation, removed redundant !!]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -653,6 +653,14 @@ struct ieee80211_fils_discovery {
-  *	write-protected by sdata_lock and local->mtx so holding either is fine
-  *	for read access.
-  * @color_change_color: the bss color that will be used after the change.
-+ * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU
-+ *	beamformer
-+ * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU
-+ *	beamformee
-+ * @vht_mu_beamformer: in AP mode, does this BSS support operation as an VHT MU
-+ *	beamformer
-+ * @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU
-+ *	beamformee
-  */
- struct ieee80211_bss_conf {
- 	const u8 *bssid;
-@@ -726,6 +734,11 @@ struct ieee80211_bss_conf {
- 
- 	bool color_change_active;
- 	u8 color_change_color;
-+
-+	bool vht_su_beamformer;
-+	bool vht_su_beamformee;
-+	bool vht_mu_beamformer;
-+	bool vht_mu_beamformee;
- };
- 
- /**
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1252,6 +1252,21 @@ static int ieee80211_start_ap(struct wip
- 	prev_beacon_int = link_conf->beacon_int;
- 	link_conf->beacon_int = params->beacon_interval;
- 
-+	if (params->vht_cap) {
-+		link_conf->vht_su_beamformer =
-+			params->vht_cap->vht_cap_info &
-+				cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
-+		link_conf->vht_su_beamformee =
-+			params->vht_cap->vht_cap_info &
-+				cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
-+		link_conf->vht_mu_beamformer =
-+			params->vht_cap->vht_cap_info &
-+				cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);
-+		link_conf->vht_mu_beamformee =
-+			params->vht_cap->vht_cap_info &
-+				cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
-+	}
-+
- 	if (params->he_cap && params->he_oper) {
- 		link_conf->he_support = true;
- 		link_conf->htc_trig_based_pkt_ext =
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch
deleted file mode 100644
index f843dba..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From: Muna Sinada <quic_msinada@quicinc.com>
-Date: Wed, 5 Oct 2022 14:54:46 -0700
-Subject: [PATCH] wifi: mac80211: Add HE MU-MIMO related flags in
- ieee80211_bss_conf
-
-Adding flags for SU Beamformer, SU Beamformee, MU Beamformer and Full
-Bandwidth UL MU-MIMO for HE. This is utilized to pass MU-MIMO
-configurations from user space to driver in AP mode.
-
-Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
-Link: https://lore.kernel.org/r/1665006886-23874-2-git-send-email-quic_msinada@quicinc.com
-[fixed indentation, removed redundant !!]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -661,6 +661,15 @@ struct ieee80211_fils_discovery {
-  *	beamformer
-  * @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU
-  *	beamformee
-+ * @he_su_beamformer: in AP-mode, does this BSS support operation as an HE SU
-+ *	beamformer
-+ * @he_su_beamformee: in AP-mode, does this BSS support operation as an HE SU
-+ *	beamformee
-+ * @he_mu_beamformer: in AP-mode, does this BSS support operation as an HE MU
-+ *	beamformer
-+ * @he_full_ul_mumimo: does this BSS support the reception (AP) or transmission
-+ *	(non-AP STA) of an HE TB PPDU on an RU that spans the entire PPDU
-+ *	bandwidth
-  */
- struct ieee80211_bss_conf {
- 	const u8 *bssid;
-@@ -739,6 +748,10 @@ struct ieee80211_bss_conf {
- 	bool vht_su_beamformee;
- 	bool vht_mu_beamformer;
- 	bool vht_mu_beamformee;
-+	bool he_su_beamformer;
-+	bool he_su_beamformee;
-+	bool he_mu_beamformer;
-+	bool he_full_ul_mumimo;
- };
- 
- /**
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1281,6 +1281,21 @@ static int ieee80211_start_ap(struct wip
- 			changed |= BSS_CHANGED_HE_BSS_COLOR;
- 	}
- 
-+	if (params->he_cap) {
-+		link_conf->he_su_beamformer =
-+			params->he_cap->phy_cap_info[3] &
-+				IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
-+		link_conf->he_su_beamformee =
-+			params->he_cap->phy_cap_info[4] &
-+				IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE;
-+		link_conf->he_mu_beamformer =
-+			params->he_cap->phy_cap_info[4] &
-+				IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
-+		link_conf->he_full_ul_mumimo =
-+			params->he_cap->phy_cap_info[2] &
-+				IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO;
-+	}
-+
- 	if (sdata->vif.type == NL80211_IFTYPE_AP &&
- 	    params->mbssid_config.tx_wdev) {
- 		err = ieee80211_set_ap_mbssid_options(sdata,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch
deleted file mode 100644
index 1be5fcf..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From: Ryder Lee <ryder.lee@mediatek.com>
-Date: Sat, 18 Feb 2023 01:50:05 +0800
-Subject: [PATCH] wifi: mac80211: introduce
- ieee80211_refresh_tx_agg_session_timer()
-
-This allows low level drivers to refresh the tx agg session timer, based on
-querying stats from the firmware usually. Especially for some mt76 devices
-support .net_fill_forward_path would bypass mac80211, which leads to tx BA
-session timeout for certain clients.
-
-Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -5964,6 +5964,18 @@ void ieee80211_queue_delayed_work(struct
- 				  unsigned long delay);
- 
- /**
-+ * ieee80211_refresh_tx_agg_session_timer - Refresh a tx agg session timer.
-+ * @sta: the station for which to start a BA session
-+ * @tid: the TID to BA on.
-+ *
-+ * This function allows low level driver to refresh tx agg session timer
-+ * to maintain BA session, the session level will still be managed by the
-+ * mac80211.
-+ */
-+void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *sta,
-+					    u16 tid);
-+
-+/**
-  * ieee80211_start_tx_ba_session - Start a tx Block Ack session.
-  * @sta: the station for which to start a BA session
-  * @tid: the TID to BA on.
---- a/net/mac80211/agg-tx.c
-+++ b/net/mac80211/agg-tx.c
-@@ -554,6 +554,23 @@ void ieee80211_tx_ba_session_handle_star
- 	ieee80211_send_addba_with_timeout(sta, tid_tx);
- }
- 
-+void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta,
-+					    u16 tid)
-+{
-+	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
-+	struct tid_ampdu_tx *tid_tx;
-+
-+	if (WARN_ON_ONCE(tid >= IEEE80211_NUM_TIDS))
-+		return;
-+
-+	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
-+	if (!tid_tx)
-+		return;
-+
-+	tid_tx->last_tx = jiffies;
-+}
-+EXPORT_SYMBOL(ieee80211_refresh_tx_agg_session_timer);
-+
- /*
-  * After accepting the AddBA Response we activated a timer,
-  * resetting it after each frame that we send.
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch
deleted file mode 100644
index 11f39c2..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 2 Mar 2023 13:52:29 +0100
-Subject: [PATCH] wifi: mac80211: add mesh fast-rx support
-
-This helps bring down rx CPU usage by avoiding calls to the rx handlers in
-the slow path. Supports forwarding and local rx, including A-MSDU.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -4564,6 +4564,12 @@ void ieee80211_check_fast_rx(struct sta_
- 		}
- 
- 		break;
-+	case NL80211_IFTYPE_MESH_POINT:
-+		fastrx.expected_ds_bits = cpu_to_le16(IEEE80211_FCTL_FROMDS |
-+						      IEEE80211_FCTL_TODS);
-+		fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3);
-+		fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
-+		break;
- 	default:
- 		goto clear;
- 	}
-@@ -4772,6 +4778,7 @@ static bool ieee80211_invoke_fast_rx(str
- 	struct sk_buff *skb = rx->skb;
- 	struct ieee80211_hdr *hdr = (void *)skb->data;
- 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-+	static ieee80211_rx_result res;
- 	int orig_len = skb->len;
- 	int hdrlen = ieee80211_hdrlen(hdr->frame_control);
- 	int snap_offs = hdrlen;
-@@ -4833,7 +4840,8 @@ static bool ieee80211_invoke_fast_rx(str
- 		snap_offs += IEEE80211_CCMP_HDR_LEN;
- 	}
- 
--	if (!(status->rx_flags & IEEE80211_RX_AMSDU)) {
-+	if (!ieee80211_vif_is_mesh(&rx->sdata->vif) &&
-+	    !(status->rx_flags & IEEE80211_RX_AMSDU)) {
- 		if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
- 			return false;
- 
-@@ -4872,13 +4880,29 @@ static bool ieee80211_invoke_fast_rx(str
- 	/* do the header conversion - first grab the addresses */
- 	ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
- 	ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
--	skb_postpull_rcsum(skb, skb->data + snap_offs,
--			   sizeof(rfc1042_header) + 2);
--	/* remove the SNAP but leave the ethertype */
--	skb_pull(skb, snap_offs + sizeof(rfc1042_header));
-+	if (ieee80211_vif_is_mesh(&rx->sdata->vif)) {
-+	    skb_pull(skb, snap_offs - 2);
-+	    put_unaligned_be16(skb->len - 2, skb->data);
-+	} else {
-+	    skb_postpull_rcsum(skb, skb->data + snap_offs,
-+			       sizeof(rfc1042_header) + 2);
-+
-+	    /* remove the SNAP but leave the ethertype */
-+	    skb_pull(skb, snap_offs + sizeof(rfc1042_header));
-+	}
- 	/* push the addresses in front */
- 	memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs));
- 
-+	res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
-+	switch (res) {
-+	case RX_QUEUED:
-+		return true;
-+	case RX_CONTINUE:
-+		break;
-+	default:
-+		goto drop;
-+	}
-+
- 	ieee80211_rx_8023(rx, fast_rx, orig_len);
- 
- 	return true;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch
deleted file mode 100644
index ac290b5..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 20 Mar 2023 14:28:08 +0100
-Subject: [PATCH] wifi: mac80211: add support for letting drivers register tc
- offload support
-
-On newer MediaTek SoCs (e.g. MT7986), WLAN->WLAN or WLAN->Ethernet flows can
-be offloaded by the SoC. In order to support that, the .ndo_setup_tc op is
-needed.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -4192,6 +4192,10 @@ struct ieee80211_prep_tx_info {
-  *	Note that a sta can also be inserted or removed with valid links,
-  *	i.e. passed to @sta_add/@sta_state with sta->valid_links not zero.
-  *	In fact, cannot change from having valid_links and not having them.
-+ * @net_setup_tc: Called from .ndo_setup_tc in order to prepare hardware
-+ *	flow offloading for flows originating from the vif.
-+ *	Note that the driver must not assume that the vif driver_data is valid
-+ *	at this point, since the callback can be called during netdev teardown.
-  */
- struct ieee80211_ops {
- 	void (*tx)(struct ieee80211_hw *hw,
-@@ -4547,6 +4551,11 @@ struct ieee80211_ops {
- 				struct ieee80211_vif *vif,
- 				struct ieee80211_sta *sta,
- 				u16 old_links, u16 new_links);
-+	int (*net_setup_tc)(struct ieee80211_hw *hw,
-+			    struct ieee80211_vif *vif,
-+			    struct net_device *dev,
-+			    enum tc_setup_type type,
-+			    void *type_data);
- };
- 
- /**
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -1470,6 +1470,23 @@ static inline int drv_net_fill_forward_p
- 	return ret;
- }
- 
-+static inline int drv_net_setup_tc(struct ieee80211_local *local,
-+				   struct ieee80211_sub_if_data *sdata,
-+				   struct net_device *dev,
-+				   enum tc_setup_type type, void *type_data)
-+{
-+	int ret = -EOPNOTSUPP;
-+
-+	sdata = get_bss_sdata(sdata);
-+	trace_drv_net_setup_tc(local, sdata, type);
-+	if (local->ops->net_setup_tc)
-+		ret = local->ops->net_setup_tc(&local->hw, &sdata->vif, dev,
-+					       type, type_data);
-+	trace_drv_return_int(local, ret);
-+
-+	return ret;
-+}
-+
- int drv_change_vif_links(struct ieee80211_local *local,
- 			 struct ieee80211_sub_if_data *sdata,
- 			 u16 old_links, u16 new_links,
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1939,7 +1939,8 @@ void ieee80211_color_collision_detection
- /* interface handling */
- #define MAC80211_SUPPORTED_FEATURES_TX	(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
- 					 NETIF_F_HW_CSUM | NETIF_F_SG | \
--					 NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE)
-+					 NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \
-+					 NETIF_F_HW_TC)
- #define MAC80211_SUPPORTED_FEATURES_RX	(NETIF_F_RXCSUM)
- #define MAC80211_SUPPORTED_FEATURES	(MAC80211_SUPPORTED_FEATURES_TX | \
- 					 MAC80211_SUPPORTED_FEATURES_RX)
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -813,6 +813,21 @@ ieee80211_get_stats64(struct net_device
- 	dev_fetch_sw_netstats(stats, dev->tstats);
- }
- 
-+static int ieee80211_netdev_setup_tc(struct net_device *dev,
-+				     enum tc_setup_type type, void *type_data)
-+{
-+	struct ieee80211_sub_if_data *sdata;
-+	struct ieee80211_local *local;
-+
-+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	local = sdata->local;
-+
-+	if (!local->ops->net_setup_tc)
-+		return -EOPNOTSUPP;
-+
-+	return drv_net_setup_tc(local, sdata, dev, type, type_data);
-+}
-+
- static const struct net_device_ops ieee80211_dataif_ops = {
- 	.ndo_open		= ieee80211_open,
- 	.ndo_stop		= ieee80211_stop,
-@@ -821,6 +836,7 @@ static const struct net_device_ops ieee8
- 	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
- 	.ndo_set_mac_address 	= ieee80211_change_mac,
- 	.ndo_get_stats64	= ieee80211_get_stats64,
-+	.ndo_setup_tc		= ieee80211_netdev_setup_tc,
- };
- 
- static u16 ieee80211_monitor_select_queue(struct net_device *dev,
-@@ -929,6 +945,7 @@ static const struct net_device_ops ieee8
- 	.ndo_set_mac_address	= ieee80211_change_mac,
- 	.ndo_get_stats64	= ieee80211_get_stats64,
- 	.ndo_fill_forward_path	= ieee80211_netdev_fill_forward_path,
-+	.ndo_setup_tc		= ieee80211_netdev_setup_tc,
- };
- 
- static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype)
---- a/net/mac80211/trace.h
-+++ b/net/mac80211/trace.h
-@@ -2478,6 +2478,31 @@ DEFINE_EVENT(sta_event, drv_net_fill_for
- 	TP_ARGS(local, sdata, sta)
- );
- 
-+TRACE_EVENT(drv_net_setup_tc,
-+	TP_PROTO(struct ieee80211_local *local,
-+		 struct ieee80211_sub_if_data *sdata,
-+		 u8 type),
-+
-+	TP_ARGS(local, sdata, type),
-+
-+	TP_STRUCT__entry(
-+		LOCAL_ENTRY
-+		VIF_ENTRY
-+		__field(u8, type)
-+	),
-+
-+	TP_fast_assign(
-+		LOCAL_ASSIGN;
-+		VIF_ASSIGN;
-+		__entry->type = type;
-+	),
-+
-+	TP_printk(
-+		LOCAL_PR_FMT VIF_PR_FMT " type:%d\n",
-+		LOCAL_PR_ARG, VIF_PR_ARG, __entry->type
-+	)
-+);
-+
- TRACE_EVENT(drv_change_vif_links,
- 	TP_PROTO(struct ieee80211_local *local,
- 		 struct ieee80211_sub_if_data *sdata,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch
deleted file mode 100644
index 6882694..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 26 Mar 2023 17:11:34 +0200
-Subject: [PATCH] wifi: mac80211: fix receiving mesh packets in forwarding=0
- networks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When forwarding is set to 0, frames are typically sent with ttl=1.
-Move the ttl decrement check below the check for local receive in order to
-fix packet drops.
-
-Reported-by: Thomas Hühn <thomas.huehn@hs-nordhausen.de>
-Reported-by: Nick Hainke <vincent@systemli.org>
-Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2828,14 +2828,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 	if (sdata->crypto_tx_tailroom_needed_cnt)
- 		tailroom = IEEE80211_ENCRYPT_TAILROOM;
- 
--	if (!--mesh_hdr->ttl) {
--		if (multicast)
--			goto rx_accept;
--
--		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
--		return RX_DROP_MONITOR;
--	}
--
- 	if (mesh_hdr->flags & MESH_FLAGS_AE) {
- 		struct mesh_path *mppath;
- 		char *proxied_addr;
-@@ -2874,6 +2866,14 @@ ieee80211_rx_mesh_data(struct ieee80211_
- 	if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
- 		goto rx_accept;
- 
-+	if (!--mesh_hdr->ttl) {
-+		if (multicast)
-+			goto rx_accept;
-+
-+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
-+		return RX_DROP_MONITOR;
-+	}
-+
- 	if (!ifmsh->mshcfg.dot11MeshForwarding) {
- 		if (is_multicast_ether_addr(eth->h_dest))
- 			goto rx_accept;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch
deleted file mode 100644
index 079dd2a..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch
+++ /dev/null
@@ -1,134 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Wed, 29 Mar 2023 16:46:26 +0200
-Subject: [PATCH] wifi: ieee80211: correctly mark FTM frames non-bufferable
-
-The checks of whether or not a frame is bufferable were not
-taking into account that some action frames aren't, such as
-FTM. Check this, which requires some changes to the function
-ieee80211_is_bufferable_mmpdu() since we need the whole skb
-for the checks now.
-
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
-Reviewed-by: Peer, Ilan <ilan.peer@intel.com>
----
-
---- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
-+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
-@@ -601,8 +601,9 @@ static void iwl_mvm_skb_prepare_status(s
- 
- static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm,
- 				      struct ieee80211_tx_info *info,
--				      struct ieee80211_hdr *hdr)
-+				      struct sk_buff *skb)
- {
-+	struct ieee80211_hdr *hdr = (void *)skb->data;
- 	struct iwl_mvm_vif *mvmvif =
- 		iwl_mvm_vif_from_mac80211(info->control.vif);
- 	__le16 fc = hdr->frame_control;
-@@ -621,7 +622,7 @@ static int iwl_mvm_get_ctrl_vif_queue(st
- 		 * reason 7 ("Class 3 frame received from nonassociated STA").
- 		 */
- 		if (ieee80211_is_mgmt(fc) &&
--		    (!ieee80211_is_bufferable_mmpdu(fc) ||
-+		    (!ieee80211_is_bufferable_mmpdu(skb) ||
- 		     ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc)))
- 			return mvm->probe_queue;
- 
-@@ -740,7 +741,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv
- 			else
- 				sta_id = mvmvif->mcast_sta.sta_id;
- 
--			queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, hdr);
-+			queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, skb);
- 		} else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) {
- 			queue = mvm->snif_queue;
- 			sta_id = mvm->snif_sta.sta_id;
---- a/include/linux/ieee80211.h
-+++ b/include/linux/ieee80211.h
-@@ -772,20 +772,6 @@ static inline bool ieee80211_is_any_null
- }
- 
- /**
-- * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
-- * @fc: frame control field in little-endian byteorder
-- */
--static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc)
--{
--	/* IEEE 802.11-2012, definition of "bufferable management frame";
--	 * note that this ignores the IBSS special case. */
--	return ieee80211_is_mgmt(fc) &&
--	       (ieee80211_is_action(fc) ||
--		ieee80211_is_disassoc(fc) ||
--		ieee80211_is_deauth(fc));
--}
--
--/**
-  * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
-  * @seq_ctrl: frame sequence control bytes in little-endian byteorder
-  */
-@@ -4121,6 +4107,44 @@ static inline u8 *ieee80211_get_DA(struc
- }
- 
- /**
-+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
-+ * @skb: the skb to check, starting with the 802.11 header
-+ */
-+static inline bool ieee80211_is_bufferable_mmpdu(struct sk_buff *skb)
-+{
-+	struct ieee80211_mgmt *mgmt = (void *)skb->data;
-+	__le16 fc = mgmt->frame_control;
-+
-+	/*
-+	 * IEEE 802.11 REVme D2.0 definition of bufferable MMPDU;
-+	 * note that this ignores the IBSS special case.
-+	 */
-+	if (!ieee80211_is_mgmt(fc))
-+		return false;
-+
-+	if (ieee80211_is_disassoc(fc) || ieee80211_is_deauth(fc))
-+		return true;
-+
-+	if (!ieee80211_is_action(fc))
-+		return false;
-+
-+	if (skb->len < offsetofend(typeof(*mgmt), u.action.u.ftm.action_code))
-+		return true;
-+
-+	/* action frame - additionally check for non-bufferable FTM */
-+
-+	if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
-+	    mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION)
-+		return true;
-+
-+	if (mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_REQUEST ||
-+	    mgmt->u.action.u.ftm.action_code == WLAN_PUBLIC_ACTION_FTM_RESPONSE)
-+		return false;
-+
-+	return true;
-+}
-+
-+/**
-  * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
-  * @hdr: the frame (buffer must include at least the first octet of payload)
-  */
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -488,7 +488,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- 		int ac = skb_get_queue_mapping(tx->skb);
- 
- 		if (ieee80211_is_mgmt(hdr->frame_control) &&
--		    !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
-+		    !ieee80211_is_bufferable_mmpdu(tx->skb)) {
- 			info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
- 			return TX_CONTINUE;
- 		}
-@@ -1326,7 +1326,7 @@ static struct txq_info *ieee80211_get_tx
- 	if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
- 	    unlikely(!ieee80211_is_data_present(hdr->frame_control))) {
- 		if ((!ieee80211_is_mgmt(hdr->frame_control) ||
--		     ieee80211_is_bufferable_mmpdu(hdr->frame_control) ||
-+		     ieee80211_is_bufferable_mmpdu(skb) ||
- 		     vif->type == NL80211_IFTYPE_STATION) &&
- 		    sta && sta->uploaded) {
- 			/*
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch
deleted file mode 100644
index 00232ec..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Mon, 13 Mar 2023 11:42:12 +0100
-Subject: [PATCH] wifi: mac80211: flush queues on STA removal
-
-When we remove a station, we first make it unreachable,
-then we (must) remove its keys, and then remove the
-station itself. Depending on the hardware design, if
-we have hardware crypto at all, frames still sitting
-on hardware queues may then be transmitted without a
-valid key, possibly unencrypted or with a fixed key.
-
-Fix this by flushing the queues when removing stations
-so this cannot happen.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
----
-
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -1271,6 +1271,14 @@ static void __sta_info_destroy_part2(str
- 		WARN_ON_ONCE(ret);
- 	}
- 
-+	/* Flush queues before removing keys, as that might remove them
-+	 * from hardware, and then depending on the offload method, any
-+	 * frames sitting on hardware queues might be sent out without
-+	 * any encryption at all.
-+	 */
-+	if (local->ops->set_key)
-+		ieee80211_flush_queues(local, sta->sdata, false);
-+
- 	/* now keys can no longer be reached */
- 	ieee80211_free_sta_keys(local, sta);
- 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch
deleted file mode 100644
index 3c31dfe..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Mon, 13 Mar 2023 12:02:58 +0100
-Subject: [PATCH] wifi: iwlwifi: mvm: support flush on AP interfaces
-
-Support TX flush on AP interfaces so that we will do a
-proper flush for frames on the queue before keys are
-removed.
-
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
----
-
---- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
-+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
-@@ -4854,9 +4854,6 @@ static void iwl_mvm_mac_flush(struct iee
- 		return;
- 	}
- 
--	if (vif->type != NL80211_IFTYPE_STATION)
--		return;
--
- 	/* Make sure we're done with the deferred traffic before flushing */
- 	flush_work(&mvm->add_stream_wk);
- 
-@@ -4874,9 +4871,6 @@ static void iwl_mvm_mac_flush(struct iee
- 		if (mvmsta->vif != vif)
- 			continue;
- 
--		/* make sure only TDLS peers or the AP are flushed */
--		WARN_ON(i != mvmvif->ap_sta_id && !sta->tdls);
--
- 		if (drop) {
- 			if (iwl_mvm_flush_sta(mvm, mvmsta, false))
- 				IWL_ERR(mvm, "flush request fail\n");
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/333-wifi-mac80211-add-flush_sta-method.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/333-wifi-mac80211-add-flush_sta-method.patch
deleted file mode 100644
index 3bba0b7..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/333-wifi-mac80211-add-flush_sta-method.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Mon, 13 Mar 2023 11:53:51 +0100
-Subject: [PATCH] wifi: mac80211: add flush_sta method
-
-Some drivers like iwlwifi might have per-STA queues, so we
-may want to flush/drop just those queues rather than all
-when removing a station. Add a separate method for that.
-
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -3918,6 +3918,10 @@ struct ieee80211_prep_tx_info {
-  *	Note that vif can be NULL.
-  *	The callback can sleep.
-  *
-+ * @flush_sta: Flush or drop all pending frames from the hardware queue(s) for
-+ *	the given station, as it's about to be removed.
-+ *	The callback can sleep.
-+ *
-  * @channel_switch: Drivers that need (or want) to offload the channel
-  *	switch operation for CSAs received from the AP may implement this
-  *	callback. They must then call ieee80211_chswitch_done() to indicate
-@@ -4372,6 +4376,8 @@ struct ieee80211_ops {
- #endif
- 	void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 		      u32 queues, bool drop);
-+	void (*flush_sta)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+			  struct ieee80211_sta *sta);
- 	void (*channel_switch)(struct ieee80211_hw *hw,
- 			       struct ieee80211_vif *vif,
- 			       struct ieee80211_channel_switch *ch_switch);
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -617,6 +617,21 @@ static inline void drv_flush(struct ieee
- 	trace_drv_return_void(local);
- }
- 
-+static inline void drv_flush_sta(struct ieee80211_local *local,
-+				 struct ieee80211_sub_if_data *sdata,
-+				 struct sta_info *sta)
-+{
-+	might_sleep();
-+
-+	if (sdata && !check_sdata_in_driver(sdata))
-+		return;
-+
-+	trace_drv_flush_sta(local, sdata, &sta->sta);
-+	if (local->ops->flush_sta)
-+		local->ops->flush_sta(&local->hw, &sdata->vif, &sta->sta);
-+	trace_drv_return_void(local);
-+}
-+
- static inline void drv_channel_switch(struct ieee80211_local *local,
- 				      struct ieee80211_sub_if_data *sdata,
- 				      struct ieee80211_channel_switch *ch_switch)
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -1276,8 +1276,12 @@ static void __sta_info_destroy_part2(str
- 	 * frames sitting on hardware queues might be sent out without
- 	 * any encryption at all.
- 	 */
--	if (local->ops->set_key)
--		ieee80211_flush_queues(local, sta->sdata, false);
-+	if (local->ops->set_key) {
-+		if (local->ops->flush_sta)
-+			drv_flush_sta(local, sta->sdata, sta);
-+		else
-+			ieee80211_flush_queues(local, sta->sdata, false);
-+	}
- 
- 	/* now keys can no longer be reached */
- 	ieee80211_free_sta_keys(local, sta);
---- a/net/mac80211/trace.h
-+++ b/net/mac80211/trace.h
-@@ -1177,6 +1177,13 @@ TRACE_EVENT(drv_flush,
- 	)
- );
- 
-+DEFINE_EVENT(sta_event, drv_flush_sta,
-+	TP_PROTO(struct ieee80211_local *local,
-+		 struct ieee80211_sub_if_data *sdata,
-+		 struct ieee80211_sta *sta),
-+	TP_ARGS(local, sdata, sta)
-+);
-+
- TRACE_EVENT(drv_channel_switch,
- 	TP_PROTO(struct ieee80211_local *local,
- 		 struct ieee80211_sub_if_data *sdata,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch
deleted file mode 100644
index 18f39d5..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Mon, 13 Mar 2023 12:05:35 +0100
-Subject: [PATCH] wifi: iwlwifi: mvm: support new flush_sta method
-
-For iwlwifi this is simple to implement, and on newer hardware
-it's an improvement since we have per-station queues.
-
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
----
-
---- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
-+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
-@@ -4890,6 +4890,31 @@ static void iwl_mvm_mac_flush(struct iee
- 		iwl_trans_wait_tx_queues_empty(mvm->trans, msk);
- }
- 
-+static void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw,
-+				  struct ieee80211_vif *vif,
-+				  struct ieee80211_sta *sta)
-+{
-+	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-+	int i;
-+
-+	mutex_lock(&mvm->mutex);
-+	for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
-+		struct iwl_mvm_sta *mvmsta;
-+		struct ieee80211_sta *tmp;
-+
-+		tmp = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
-+						lockdep_is_held(&mvm->mutex));
-+		if (tmp != sta)
-+			continue;
-+
-+		mvmsta = iwl_mvm_sta_from_mac80211(sta);
-+
-+		if (iwl_mvm_flush_sta(mvm, mvmsta, false))
-+			IWL_ERR(mvm, "flush request fail\n");
-+	}
-+	mutex_unlock(&mvm->mutex);
-+}
-+
- static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
- 				  struct survey_info *survey)
- {
-@@ -5417,6 +5442,7 @@ const struct ieee80211_ops iwl_mvm_hw_op
- 	.mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx,
- 	.mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover,
- 	.flush = iwl_mvm_mac_flush,
-+	.flush_sta = iwl_mvm_mac_flush_sta,
- 	.sched_scan_start = iwl_mvm_mac_sched_scan_start,
- 	.sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
- 	.set_key = iwl_mvm_mac_set_key,
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch
deleted file mode 100644
index 1b379b7..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From: Ryder Lee <ryder.lee@mediatek.com>
-Date: Sat, 18 Feb 2023 01:49:25 +0800
-Subject: [PATCH] wifi: mac80211: add LDPC related flags in ieee80211_bss_conf
-
-This is utilized to pass LDPC configurations from user space
-(i.e. hostapd) to driver.
-
-Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
-Link: https://lore.kernel.org/r/1de696aaa34efd77a926eb657b8c0fda05aaa177.1676628065.git.ryder.lee@mediatek.com
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -653,6 +653,9 @@ struct ieee80211_fils_discovery {
-  *	write-protected by sdata_lock and local->mtx so holding either is fine
-  *	for read access.
-  * @color_change_color: the bss color that will be used after the change.
-+ * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability.
-+ * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability.
-+ * @he_ldpc: in AP mode, indicates interface has HE LDPC capability.
-  * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU
-  *	beamformer
-  * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU
-@@ -744,6 +747,9 @@ struct ieee80211_bss_conf {
- 	bool color_change_active;
- 	u8 color_change_color;
- 
-+	bool ht_ldpc;
-+	bool vht_ldpc;
-+	bool he_ldpc;
- 	bool vht_su_beamformer;
- 	bool vht_su_beamformee;
- 	bool vht_mu_beamformer;
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1252,7 +1252,15 @@ static int ieee80211_start_ap(struct wip
- 	prev_beacon_int = link_conf->beacon_int;
- 	link_conf->beacon_int = params->beacon_interval;
- 
-+	if (params->ht_cap)
-+		link_conf->ht_ldpc =
-+			params->ht_cap->cap_info &
-+				cpu_to_le16(IEEE80211_HT_CAP_LDPC_CODING);
-+
- 	if (params->vht_cap) {
-+		link_conf->vht_ldpc =
-+			params->vht_cap->vht_cap_info &
-+				cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC);
- 		link_conf->vht_su_beamformer =
- 			params->vht_cap->vht_cap_info &
- 				cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
-@@ -1282,6 +1290,9 @@ static int ieee80211_start_ap(struct wip
- 	}
- 
- 	if (params->he_cap) {
-+		link_conf->he_ldpc =
-+			params->he_cap->phy_cap_info[1] &
-+				IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
- 		link_conf->he_su_beamformer =
- 			params->he_cap->phy_cap_info[3] &
- 				IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch
deleted file mode 100644
index 088f468..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch
+++ /dev/null
@@ -1,372 +0,0 @@
-From bd54f3c29077f23dad92ef82a78061b40be30c65 Mon Sep 17 00:00:00 2001
-From: Aloka Dixit <quic_alokad@quicinc.com>
-Date: Mon, 5 Dec 2022 16:50:37 -0800
-Subject: [PATCH] wifi: mac80211: generate EMA beacons in AP mode
-
-Add APIs to generate an array of beacons for an EMA AP (enhanced
-multiple BSSID advertisements), each including a single MBSSID element.
-EMA profile periodicity equals the count of elements.
-
-- ieee80211_beacon_get_template_ema_list() - Generate and return all
-EMA beacon templates. Drivers must call ieee80211_beacon_free_ema_list()
-to free the memory. No change in the prototype for the existing API,
-ieee80211_beacon_get_template(), which should be used for non-EMA AP.
-
-- ieee80211_beacon_get_template_ema_index() - Generate a beacon which
-includes the multiple BSSID element at the given index. Drivers can use
-this function in a loop until NULL is returned which indicates end of
-available MBSSID elements.
-
-- ieee80211_beacon_free_ema_list() - free the memory allocated for the
-list of EMA beacon templates.
-
-Modify existing functions ieee80211_beacon_get_ap(),
-ieee80211_get_mbssid_beacon_len() and ieee80211_beacon_add_mbssid()
-to accept a new parameter for EMA index.
-
-Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
-Co-developed-by: John Crispin <john@phrozen.org>
-Signed-off-by: John Crispin <john@phrozen.org>
-Link: https://lore.kernel.org/r/20221206005040.3177-2-quic_alokad@quicinc.com
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/mac80211.h     |  68 +++++++++++++++++++
- net/mac80211/cfg.c         |  11 +--
- net/mac80211/ieee80211_i.h |  10 ++-
- net/mac80211/tx.c          | 134 ++++++++++++++++++++++++++++++++++---
- 4 files changed, 205 insertions(+), 18 deletions(-)
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -5252,6 +5252,74 @@ ieee80211_beacon_get_template(struct iee
- 			      unsigned int link_id);
- 
- /**
-+ * ieee80211_beacon_get_template_ema_index - EMA beacon template generation
-+ * @hw: pointer obtained from ieee80211_alloc_hw().
-+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-+ * @offs: &struct ieee80211_mutable_offsets pointer to struct that will
-+ *	receive the offsets that may be updated by the driver.
-+ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP).
-+ * @ema_index: index of the beacon in the EMA set.
-+ *
-+ * This function follows the same rules as ieee80211_beacon_get_template()
-+ * but returns a beacon template which includes multiple BSSID element at the
-+ * requested index.
-+ *
-+ * Return: The beacon template. %NULL indicates the end of EMA templates.
-+ */
-+struct sk_buff *
-+ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw,
-+					struct ieee80211_vif *vif,
-+					struct ieee80211_mutable_offsets *offs,
-+					unsigned int link_id, u8 ema_index);
-+
-+/**
-+ * struct ieee80211_ema_beacons - List of EMA beacons
-+ * @cnt: count of EMA beacons.
-+ *
-+ * @bcn: array of EMA beacons.
-+ * @bcn.skb: the skb containing this specific beacon
-+ * @bcn.offs: &struct ieee80211_mutable_offsets pointer to struct that will
-+ *	receive the offsets that may be updated by the driver.
-+ */
-+struct ieee80211_ema_beacons {
-+	u8 cnt;
-+	struct {
-+		struct sk_buff *skb;
-+		struct ieee80211_mutable_offsets offs;
-+	} bcn[];
-+};
-+
-+/**
-+ * ieee80211_beacon_get_template_ema_list - EMA beacon template generation
-+ * @hw: pointer obtained from ieee80211_alloc_hw().
-+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-+ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP)
-+ *
-+ * This function follows the same rules as ieee80211_beacon_get_template()
-+ * but allocates and returns a pointer to list of all beacon templates required
-+ * to cover all profiles in the multiple BSSID set. Each template includes only
-+ * one multiple BSSID element.
-+ *
-+ * Driver must call ieee80211_beacon_free_ema_list() to free the memory.
-+ *
-+ * Return: EMA beacon templates of type struct ieee80211_ema_beacons *.
-+ *	%NULL on error.
-+ */
-+struct ieee80211_ema_beacons *
-+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
-+				       struct ieee80211_vif *vif,
-+				       unsigned int link_id);
-+
-+/**
-+ * ieee80211_beacon_free_ema_list - free an EMA beacon template list
-+ * @ema_beacons: list of EMA beacons of type &struct ieee80211_ema_beacons pointers.
-+ *
-+ * This function will free a list previously acquired by calling
-+ * ieee80211_beacon_get_template_ema_list()
-+ */
-+void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons);
-+
-+/**
-  * ieee80211_beacon_get_tim - beacon generation function
-  * @hw: pointer obtained from ieee80211_alloc_hw().
-  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1122,11 +1122,11 @@ static int ieee80211_assign_beacon(struc
- 	if (params->mbssid_ies) {
- 		mbssid = params->mbssid_ies;
- 		size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
--		size += ieee80211_get_mbssid_beacon_len(mbssid);
-+		size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt);
- 	} else if (old && old->mbssid_ies) {
- 		mbssid = old->mbssid_ies;
- 		size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
--		size += ieee80211_get_mbssid_beacon_len(mbssid);
-+		size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt);
- 	}
- 
- 	new = kzalloc(size, GFP_KERNEL);
-@@ -3384,8 +3384,11 @@ cfg80211_beacon_dup(struct cfg80211_beac
- 
- 	len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len +
- 	      beacon->proberesp_ies_len + beacon->assocresp_ies_len +
--	      beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len +
--	      ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies);
-+	      beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len;
-+
-+	if (beacon->mbssid_ies)
-+		len += ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies,
-+						       beacon->mbssid_ies->cnt);
- 
- 	new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL);
- 	if (!new_beacon)
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1182,13 +1182,17 @@ ieee80211_vif_get_shift(struct ieee80211
- }
- 
- static inline int
--ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems)
-+ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, u8 i)
- {
--	int i, len = 0;
-+	int len = 0;
- 
--	if (!elems)
-+	if (!elems || !elems->cnt || i > elems->cnt)
- 		return 0;
- 
-+	if (i < elems->cnt)
-+		return elems->elem[i].len;
-+
-+	/* i == elems->cnt, calculate total length of all MBSSID elements */
- 	for (i = 0; i < elems->cnt; i++)
- 		len += elems->elem[i].len;
- 
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -5205,13 +5205,20 @@ ieee80211_beacon_get_finish(struct ieee8
- }
- 
- static void
--ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon)
-+ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon,
-+			    u8 i)
- {
--	int i;
-+	if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt ||
-+	    i > beacon->mbssid_ies->cnt)
-+		return;
- 
--	if (!beacon->mbssid_ies)
-+	if (i < beacon->mbssid_ies->cnt) {
-+		skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
-+			     beacon->mbssid_ies->elem[i].len);
- 		return;
-+	}
- 
-+	/* i == beacon->mbssid_ies->cnt, include all MBSSID elements */
- 	for (i = 0; i < beacon->mbssid_ies->cnt; i++)
- 		skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
- 			     beacon->mbssid_ies->elem[i].len);
-@@ -5224,7 +5231,8 @@ ieee80211_beacon_get_ap(struct ieee80211
- 			struct ieee80211_mutable_offsets *offs,
- 			bool is_template,
- 			struct beacon_data *beacon,
--			struct ieee80211_chanctx_conf *chanctx_conf)
-+			struct ieee80211_chanctx_conf *chanctx_conf,
-+			u8 ema_index)
- {
- 	struct ieee80211_local *local = hw_to_local(hw);
- 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-@@ -5243,7 +5251,9 @@ ieee80211_beacon_get_ap(struct ieee80211
- 	/* headroom, head length,
- 	 * tail length, maximum TIM length and multiple BSSID length
- 	 */
--	mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies);
-+	mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies,
-+						     ema_index);
-+
- 	skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
- 			    beacon->tail_len + 256 +
- 			    local->hw.extra_beacon_tailroom + mbssid_len);
-@@ -5261,7 +5271,7 @@ ieee80211_beacon_get_ap(struct ieee80211
- 		offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
- 
- 		if (mbssid_len) {
--			ieee80211_beacon_add_mbssid(skb, beacon);
-+			ieee80211_beacon_add_mbssid(skb, beacon, ema_index);
- 			offs->mbssid_off = skb->len - mbssid_len;
- 		}
- 
-@@ -5280,12 +5290,51 @@ ieee80211_beacon_get_ap(struct ieee80211
- 	return skb;
- }
- 
-+static struct ieee80211_ema_beacons *
-+ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw,
-+				 struct ieee80211_vif *vif,
-+				 struct ieee80211_link_data *link,
-+				 struct ieee80211_mutable_offsets *offs,
-+				 bool is_template, struct beacon_data *beacon,
-+				 struct ieee80211_chanctx_conf *chanctx_conf)
-+{
-+	struct ieee80211_ema_beacons *ema = NULL;
-+
-+	if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt)
-+		return NULL;
-+
-+	ema = kzalloc(struct_size(ema, bcn, beacon->mbssid_ies->cnt),
-+		      GFP_ATOMIC);
-+	if (!ema)
-+		return NULL;
-+
-+	for (ema->cnt = 0; ema->cnt < beacon->mbssid_ies->cnt; ema->cnt++) {
-+		ema->bcn[ema->cnt].skb =
-+			ieee80211_beacon_get_ap(hw, vif, link,
-+						&ema->bcn[ema->cnt].offs,
-+						is_template, beacon,
-+						chanctx_conf, ema->cnt);
-+		if (!ema->bcn[ema->cnt].skb)
-+			break;
-+	}
-+
-+	if (ema->cnt == beacon->mbssid_ies->cnt)
-+		return ema;
-+
-+	ieee80211_beacon_free_ema_list(ema);
-+	return NULL;
-+}
-+
-+#define IEEE80211_INCLUDE_ALL_MBSSID_ELEMS -1
-+
- static struct sk_buff *
- __ieee80211_beacon_get(struct ieee80211_hw *hw,
- 		       struct ieee80211_vif *vif,
- 		       struct ieee80211_mutable_offsets *offs,
- 		       bool is_template,
--		       unsigned int link_id)
-+		       unsigned int link_id,
-+		       int ema_index,
-+		       struct ieee80211_ema_beacons **ema_beacons)
- {
- 	struct ieee80211_local *local = hw_to_local(hw);
- 	struct beacon_data *beacon = NULL;
-@@ -5314,8 +5363,29 @@ __ieee80211_beacon_get(struct ieee80211_
- 		if (!beacon)
- 			goto out;
- 
--		skb = ieee80211_beacon_get_ap(hw, vif, link, offs, is_template,
--					      beacon, chanctx_conf);
-+		if (ema_beacons) {
-+			*ema_beacons =
-+				ieee80211_beacon_get_ap_ema_list(hw, vif, link,
-+								 offs,
-+								 is_template,
-+								 beacon,
-+								 chanctx_conf);
-+		} else {
-+			if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) {
-+				if (ema_index >= beacon->mbssid_ies->cnt)
-+					goto out; /* End of MBSSID elements */
-+
-+				if (ema_index <= IEEE80211_INCLUDE_ALL_MBSSID_ELEMS)
-+					ema_index = beacon->mbssid_ies->cnt;
-+			} else {
-+				ema_index = 0;
-+			}
-+
-+			skb = ieee80211_beacon_get_ap(hw, vif, link, offs,
-+						      is_template, beacon,
-+						      chanctx_conf,
-+						      ema_index);
-+		}
- 	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- 		struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
- 		struct ieee80211_hdr *hdr;
-@@ -5403,10 +5473,50 @@ ieee80211_beacon_get_template(struct iee
- 			      struct ieee80211_mutable_offsets *offs,
- 			      unsigned int link_id)
- {
--	return __ieee80211_beacon_get(hw, vif, offs, true, link_id);
-+	return __ieee80211_beacon_get(hw, vif, offs, true, link_id,
-+				      IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, NULL);
- }
- EXPORT_SYMBOL(ieee80211_beacon_get_template);
- 
-+struct sk_buff *
-+ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw,
-+					struct ieee80211_vif *vif,
-+					struct ieee80211_mutable_offsets *offs,
-+					unsigned int link_id, u8 ema_index)
-+{
-+	return __ieee80211_beacon_get(hw, vif, offs, true, link_id, ema_index,
-+				      NULL);
-+}
-+EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_index);
-+
-+void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons)
-+{
-+	u8 i;
-+
-+	if (!ema_beacons)
-+		return;
-+
-+	for (i = 0; i < ema_beacons->cnt; i++)
-+		kfree_skb(ema_beacons->bcn[i].skb);
-+
-+	kfree(ema_beacons);
-+}
-+EXPORT_SYMBOL(ieee80211_beacon_free_ema_list);
-+
-+struct ieee80211_ema_beacons *
-+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
-+				       struct ieee80211_vif *vif,
-+				       unsigned int link_id)
-+{
-+	struct ieee80211_ema_beacons *ema_beacons = NULL;
-+
-+	WARN_ON(__ieee80211_beacon_get(hw, vif, NULL, false, link_id, 0,
-+				       &ema_beacons));
-+
-+	return ema_beacons;
-+}
-+EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_list);
-+
- struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
- 					 struct ieee80211_vif *vif,
- 					 u16 *tim_offset, u16 *tim_length,
-@@ -5414,7 +5524,9 @@ struct sk_buff *ieee80211_beacon_get_tim
- {
- 	struct ieee80211_mutable_offsets offs = {};
- 	struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false,
--						     link_id);
-+						     link_id,
-+						     IEEE80211_INCLUDE_ALL_MBSSID_ELEMS,
-+						     NULL);
- 	struct sk_buff *copy;
- 	int shift;
- 
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch
deleted file mode 100644
index 67b4284..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 22 Jun 2023 18:02:25 +0200
-Subject: [PATCH] mac80211: fix sband iftype data lookup for AP_VLAN
-
-AP_VLAN interfaces are virtual, so doesn't really exist as a type for
-capabilities. When passed in as a type, AP is the one that's really intended.
-
-Fixes: c4cbaf7973a7 ("cfg80211: Add support for HE")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -567,6 +567,9 @@ ieee80211_get_sband_iftype_data(const st
- 	if (WARN_ON(iftype >= NL80211_IFTYPE_MAX))
- 		return NULL;
- 
-+	if (iftype == NL80211_IFTYPE_AP_VLAN)
-+		iftype = NL80211_IFTYPE_AP;
-+
- 	for (i = 0; i < sband->n_iftype_data; i++)  {
- 		const struct ieee80211_sband_iftype_data *data =
- 			&sband->iftype_data[i];
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch
deleted file mode 100644
index e32c6ae..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 11 Jul 2023 13:30:12 +0200
-Subject: [PATCH] wifi: cfg80211: fix receving mesh packets without RFC1042
- header
-
-Fix ethernet header length field after stripping the mesh header
-
-Cc: stable@vger.kernel.org
-Link: https://lore.kernel.org/all/CT5GNZSK28AI.2K6M69OXM9RW5@syracuse/
-Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
-Reported-by: Nicolas Escande <nico.escande@gmail.com>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -580,6 +580,8 @@ int ieee80211_strip_8023_mesh_hdr(struct
- 		hdrlen += ETH_ALEN + 2;
- 	else if (!pskb_may_pull(skb, hdrlen))
- 		return -EINVAL;
-+	else
-+		payload.eth.h_proto = htons(skb->len - hdrlen);
- 
- 	mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN;
- 	switch (payload.flags & MESH_FLAGS_AE) {
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/400-allow-ibss-mixed.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/400-allow-ibss-mixed.patch
index c38fa13..ad24dfd 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/400-allow-ibss-mixed.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/400-allow-ibss-mixed.patch
@@ -16,7 +16,7 @@
 
 --- a/net/wireless/core.c
 +++ b/net/wireless/core.c
-@@ -614,21 +614,6 @@ static int wiphy_verify_combinations(str
+@@ -649,21 +649,6 @@ static int wiphy_verify_combinations(str
  				    c->limits[j].max > 1))
  				return -EINVAL;
  
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-Revert-mac80211-use-the-new-drop-reasons-infrastruct.patch
new file mode 100644
index 0000000..8e924dc
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0001-Revert-mac80211-use-the-new-drop-reasons-infrastruct.patch
@@ -0,0 +1,381 @@
+From e6a3cf0e4fd98f36be9352b92d40cfeb79993fc9 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
+
+---
+ net/mac80211/drop.h        | 56 --------------------------------------
+ net/mac80211/ieee80211_i.h |  8 +++++-
+ net/mac80211/main.c        | 31 ---------------------
+ net/mac80211/rx.c          | 55 +++++++++++++++++++------------------
+ net/mac80211/wpa.c         | 24 ++++++++--------
+ 5 files changed, 48 insertions(+), 126 deletions(-)
+ delete mode 100644 net/mac80211/drop.h
+
+diff --git a/net/mac80211/drop.h b/net/mac80211/drop.h
+deleted file mode 100644
+index 49dc809..0000000
+--- a/net/mac80211/drop.h
++++ /dev/null
+@@ -1,56 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
+-/*
+- * mac80211 drop reason list
+- *
+- * Copyright (C) 2023 Intel Corporation
+- */
+-
+-#ifndef MAC80211_DROP_H
+-#define MAC80211_DROP_H
+-#include <net/dropreason.h>
+-
+-typedef unsigned int __bitwise ieee80211_rx_result;
+-
+-#define MAC80211_DROP_REASONS_MONITOR(R)	\
+-	R(RX_DROP_M_UNEXPECTED_4ADDR_FRAME)	\
+-	R(RX_DROP_M_BAD_BCN_KEYIDX)		\
+-	R(RX_DROP_M_BAD_MGMT_KEYIDX)		\
+-/* this line for the trailing \ - add before this */
+-
+-#define MAC80211_DROP_REASONS_UNUSABLE(R)	\
+-	R(RX_DROP_U_MIC_FAIL)			\
+-	R(RX_DROP_U_REPLAY)			\
+-	R(RX_DROP_U_BAD_MMIE)			\
+-/* this line for the trailing \ - add before this */
+-
+-/* having two enums allows for checking ieee80211_rx_result use with sparse */
+-enum ___mac80211_drop_reason {
+-/* if we get to the end of handlers with RX_CONTINUE this will be the reason */
+-	___RX_CONTINUE	= SKB_CONSUMED,
+-
+-/* this never gets used as an argument to kfree_skb_reason() */
+-	___RX_QUEUED	= SKB_NOT_DROPPED_YET,
+-
+-#define ENUM(x) ___ ## x,
+-	___RX_DROP_MONITOR = SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR <<
+-		SKB_DROP_REASON_SUBSYS_SHIFT,
+-	MAC80211_DROP_REASONS_MONITOR(ENUM)
+-
+-	___RX_DROP_UNUSABLE = SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE <<
+-		SKB_DROP_REASON_SUBSYS_SHIFT,
+-	MAC80211_DROP_REASONS_UNUSABLE(ENUM)
+-#undef ENUM
+-};
+-
+-enum mac80211_drop_reason {
+-	RX_CONTINUE	 = (__force ieee80211_rx_result)___RX_CONTINUE,
+-	RX_QUEUED	 = (__force ieee80211_rx_result)___RX_QUEUED,
+-	RX_DROP_MONITOR	 = (__force ieee80211_rx_result)___RX_DROP_MONITOR,
+-	RX_DROP_UNUSABLE = (__force ieee80211_rx_result)___RX_DROP_UNUSABLE,
+-#define DEF(x) x = (__force ieee80211_rx_result)___ ## x,
+-	MAC80211_DROP_REASONS_MONITOR(DEF)
+-	MAC80211_DROP_REASONS_UNUSABLE(DEF)
+-#undef DEF
+-};
+-
+-#endif /* MAC80211_DROP_H */
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index 9fdfd11..7ca2482 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -33,7 +33,6 @@
+ #include "key.h"
+ #include "sta_info.h"
+ #include "debug.h"
+-#include "drop.h"
+ 
+ extern const struct cfg80211_ops mac80211_config_ops;
+ 
+@@ -171,6 +170,13 @@ struct ieee80211_tx_data {
+ 	unsigned int flags;
+ };
+ 
++
++typedef unsigned __bitwise ieee80211_rx_result;
++#define RX_CONTINUE		((__force ieee80211_rx_result) 0u)
++#define RX_DROP_UNUSABLE	((__force ieee80211_rx_result) 1u)
++#define RX_DROP_MONITOR		((__force ieee80211_rx_result) 2u)
++#define RX_QUEUED		((__force ieee80211_rx_result) 3u)
++
+ /**
+  * 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
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -22,7 +22,6 @@
+ #include <linux/bitmap.h>
+ #include <linux/inetdevice.h>
+ #include <net/net_namespace.h>
+-#include <net/dropreason.h>
+ #include <net/cfg80211.h>
+ #include <net/addrconf.h>
+ 
+@@ -1544,28 +1543,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
+ }
+ EXPORT_SYMBOL(ieee80211_free_hw);
+ 
+-static const char * const drop_reasons_monitor[] = {
+-#define V(x)	#x,
+-	[0] = "RX_DROP_MONITOR",
+-	MAC80211_DROP_REASONS_MONITOR(V)
+-};
+-
+-static struct drop_reason_list drop_reason_list_monitor = {
+-	.reasons = drop_reasons_monitor,
+-	.n_reasons = ARRAY_SIZE(drop_reasons_monitor),
+-};
+-
+-static const char * const drop_reasons_unusable[] = {
+-	[0] = "RX_DROP_UNUSABLE",
+-	MAC80211_DROP_REASONS_UNUSABLE(V)
+-#undef V
+-};
+-
+-static struct drop_reason_list drop_reason_list_unusable = {
+-	.reasons = drop_reasons_unusable,
+-	.n_reasons = ARRAY_SIZE(drop_reasons_unusable),
+-};
+-
+ static int __init ieee80211_init(void)
+ {
+ 	struct sk_buff *skb;
+@@ -1583,11 +1560,6 @@ static int __init ieee80211_init(void)
+ 	if (ret)
+ 		goto err_netdev;
+ 
+-	drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR,
+-				     &drop_reason_list_monitor);
+-	drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE,
+-				     &drop_reason_list_unusable);
+-
+ 	return 0;
+  err_netdev:
+ 	rc80211_minstrel_exit();
+@@ -1603,9 +1575,6 @@ static void __exit ieee80211_exit(void)
+ 
+ 	ieee80211_iface_exit();
+ 
+-	drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR);
+-	drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE);
+-
+ 	rcu_barrier();
+ }
+ 
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 491047d..8ffe90d 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)
+ 				cfg80211_rx_unexpected_4addr_frame(
+ 					rx->sdata->dev, sta->sta.addr,
+ 					GFP_ATOMIC);
+-			return RX_DROP_M_UNEXPECTED_4ADDR_FRAME;
++			return RX_DROP_MONITOR;
+ 		}
+ 		/*
+ 		 * Update counter and free packet here to avoid
+@@ -1963,7 +1963,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
+ 				cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
+ 							     skb->data,
+ 							     skb->len);
+-			return RX_DROP_M_BAD_BCN_KEYIDX;
++			return RX_DROP_MONITOR; /* unexpected BIP keyidx */
+ 		}
+ 
+ 		rx->key = ieee80211_rx_get_bigtk(rx, mmie_keyidx);
+@@ -1977,7 +1977,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
+ 
+ 		if (mmie_keyidx < NUM_DEFAULT_KEYS ||
+ 		    mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
+-			return RX_DROP_M_BAD_MGMT_KEYIDX; /* unexpected BIP keyidx */
++			return RX_DROP_MONITOR; /* unexpected BIP keyidx */
+ 		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)
+ }
+ 
+ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
+-					struct ieee80211_rate *rate,
+-					ieee80211_rx_result reason)
++					struct ieee80211_rate *rate)
+ {
+ 	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,
+ 	}
+ 
+  out_free_skb:
+-	kfree_skb_reason(skb, (__force u32)reason);
++	dev_kfree_skb(skb);
+ }
+ 
+ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
+ 					 ieee80211_rx_result res)
+ {
+-	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+-	struct ieee80211_supported_band *sband;
+-	struct ieee80211_rate *rate = NULL;
+-
+-	if (res == RX_QUEUED) {
+-		I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
+-		return;
+-	}
+-
+-	if (res != RX_CONTINUE) {
++	switch (res) {
++	case RX_DROP_MONITOR:
+ 		I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+ 		if (rx->sta)
+ 			rx->link_sta->rx_stats.dropped++;
+-	}
++		fallthrough;
++	case RX_CONTINUE: {
++		struct ieee80211_rate *rate = NULL;
++		struct ieee80211_supported_band *sband;
++		struct ieee80211_rx_status *status;
+ 
+-	if (u32_get_bits((__force u32)res, SKB_DROP_REASON_SUBSYS_MASK) ==
+-			SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE) {
+-		kfree_skb_reason(rx->skb, (__force u32)res);
+-		return;
+-	}
++		status = IEEE80211_SKB_RXCB((rx->skb));
+ 
+-	sband = rx->local->hw.wiphy->bands[status->band];
+-	if (status->encoding == RX_ENC_LEGACY)
+-		rate = &sband->bitrates[status->rate_idx];
++		sband = rx->local->hw.wiphy->bands[status->band];
++		if (status->encoding == RX_ENC_LEGACY)
++			rate = &sband->bitrates[status->rate_idx];
+ 
+-	ieee80211_rx_cooked_monitor(rx, rate, res);
++		ieee80211_rx_cooked_monitor(rx, rate);
++		break;
++		}
++	case RX_DROP_UNUSABLE:
++		I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
++		if (rx->sta)
++			rx->link_sta->rx_stats.dropped++;
++		dev_kfree_skb(rx->skb);
++		break;
++	case RX_QUEUED:
++		I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
++		break;
++	}
+ }
+ 
+ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
+diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
+index 4133496..20f742b 100644
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -550,7 +550,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
+ 		if (res < 0 ||
+ 		    (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
+ 			key->u.ccmp.replays++;
+-			return RX_DROP_U_REPLAY;
++			return RX_DROP_UNUSABLE;
+ 		}
+ 
+ 		if (!(status->flag & RX_FLAG_DECRYPTED)) {
+@@ -564,7 +564,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
+ 				    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
+ 				    data_len,
+ 				    skb->data + skb->len - mic_len))
+-				return RX_DROP_U_MIC_FAIL;
++				return RX_DROP_UNUSABLE;
+ 		}
+ 
+ 		memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
+@@ -746,7 +746,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
+ 		if (res < 0 ||
+ 		    (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
+ 			key->u.gcmp.replays++;
+-			return RX_DROP_U_REPLAY;
++			return RX_DROP_UNUSABLE;
+ 		}
+ 
+ 		if (!(status->flag & RX_FLAG_DECRYPTED)) {
+@@ -761,7 +761,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
+ 				    data_len,
+ 				    skb->data + skb->len -
+ 				    IEEE80211_GCMP_MIC_LEN))
+-				return RX_DROP_U_MIC_FAIL;
++				return RX_DROP_UNUSABLE;
+ 		}
+ 
+ 		memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN);
+@@ -930,13 +930,13 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
+ 		(skb->data + skb->len - sizeof(*mmie));
+ 	if (mmie->element_id != WLAN_EID_MMIE ||
+ 	    mmie->length != sizeof(*mmie) - 2)
+-		return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */
++		return RX_DROP_UNUSABLE; /* Invalid MMIE */
+ 
+ 	bip_ipn_swap(ipn, mmie->sequence_number);
+ 
+ 	if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
+ 		key->u.aes_cmac.replays++;
+-		return RX_DROP_U_REPLAY;
++		return RX_DROP_UNUSABLE;
+ 	}
+ 
+ 	if (!(status->flag & RX_FLAG_DECRYPTED)) {
+@@ -946,7 +946,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
+ 				   skb->data + 24, skb->len - 24, mic);
+ 		if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
+ 			key->u.aes_cmac.icverrors++;
+-			return RX_DROP_U_MIC_FAIL;
++			return RX_DROP_UNUSABLE;
+ 		}
+ 	}
+ 
+@@ -986,7 +986,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
+ 
+ 	if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
+ 		key->u.aes_cmac.replays++;
+-		return RX_DROP_U_REPLAY;
++		return RX_DROP_UNUSABLE;
+ 	}
+ 
+ 	if (!(status->flag & RX_FLAG_DECRYPTED)) {
+@@ -996,7 +996,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
+ 				       skb->data + 24, skb->len - 24, mic);
+ 		if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
+ 			key->u.aes_cmac.icverrors++;
+-			return RX_DROP_U_MIC_FAIL;
++			return RX_DROP_UNUSABLE;
+ 		}
+ 	}
+ 
+@@ -1079,13 +1079,13 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
+ 		(skb->data + skb->len - sizeof(*mmie));
+ 	if (mmie->element_id != WLAN_EID_MMIE ||
+ 	    mmie->length != sizeof(*mmie) - 2)
+-		return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */
++		return RX_DROP_UNUSABLE; /* Invalid MMIE */
+ 
+ 	bip_ipn_swap(ipn, mmie->sequence_number);
+ 
+ 	if (memcmp(ipn, key->u.aes_gmac.rx_pn, 6) <= 0) {
+ 		key->u.aes_gmac.replays++;
+-		return RX_DROP_U_REPLAY;
++		return RX_DROP_UNUSABLE;
+ 	}
+ 
+ 	if (!(status->flag & RX_FLAG_DECRYPTED)) {
+@@ -1104,7 +1104,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
+ 		    crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
+ 			key->u.aes_gmac.icverrors++;
+ 			kfree(mic);
+-			return RX_DROP_U_MIC_FAIL;
++			return RX_DROP_UNUSABLE;
+ 		}
+ 		kfree(mic);
+ 	}
+-- 
+2.39.2
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0002-mac80211-support-minimal-EHT-rate-reporting-on-RX.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0002-mac80211-support-minimal-EHT-rate-reporting-on-RX.patch
deleted file mode 100644
index c063f3e..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0002-mac80211-support-minimal-EHT-rate-reporting-on-RX.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From 2ff2e76bdbbbe8fa6923c274f276110f86acfb6a Mon Sep 17 00:00:00 2001
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Mon, 9 Jan 2023 13:07:21 +0200
-Subject: [PATCH 2/9] mac80211: support minimal EHT rate reporting on RX
-
-Add minimal support for RX EHT rate reporting, not yet
-adding (modifying) any radiotap headers, just statistics
-for cfg80211.
-
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/mac80211.h  | 19 ++++++++++++++++---
- net/mac80211/rx.c       |  9 +++++++++
- net/mac80211/sta_info.c |  9 ++++++++-
- net/mac80211/sta_info.h | 24 ++++++++++++++++++------
- net/mac80211/util.c     | 13 +++++++++++++
- 5 files changed, 64 insertions(+), 10 deletions(-)
-
-diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 9c59eb8..3388cc7 100644
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1468,6 +1468,7 @@ enum mac80211_rx_encoding {
- 	RX_ENC_HT,
- 	RX_ENC_VHT,
- 	RX_ENC_HE,
-+	RX_ENC_EHT,
- };
- 
- /**
-@@ -1501,7 +1502,7 @@ enum mac80211_rx_encoding {
-  * @antenna: antenna used
-  * @rate_idx: index of data rate into band's supported rates or MCS index if
-  *	HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
-- * @nss: number of streams (VHT and HE only)
-+ * @nss: number of streams (VHT, HE and EHT only)
-  * @flag: %RX_FLAG_\*
-  * @encoding: &enum mac80211_rx_encoding
-  * @bw: &enum rate_info_bw
-@@ -1509,6 +1510,8 @@ enum mac80211_rx_encoding {
-  * @he_ru: HE RU, from &enum nl80211_he_ru_alloc
-  * @he_gi: HE GI, from &enum nl80211_he_gi
-  * @he_dcm: HE DCM value
-+ * @eht.ru: EHT RU, from &enum nl80211_eht_ru_alloc
-+ * @eht.gi: EHT GI, from &enum nl80211_eht_gi
-  * @rx_flags: internal RX flags for mac80211
-  * @ampdu_reference: A-MPDU reference number, must be a different value for
-  *	each A-MPDU but the same for each subframe within one A-MPDU
-@@ -1530,8 +1533,18 @@ struct ieee80211_rx_status {
- 	u32 flag;
- 	u16 freq: 13, freq_offset: 1;
- 	u8 enc_flags;
--	u8 encoding:2, bw:3, he_ru:3;
--	u8 he_gi:2, he_dcm:1;
-+	u8 encoding:3, bw:4;
-+	union {
-+		struct {
-+			u8 he_ru:3;
-+			u8 he_gi:2;
-+			u8 he_dcm:1;
-+		};
-+		struct {
-+			u8 ru:4;
-+			u8 gi:2;
-+		} eht;
-+	};
- 	u8 rate_idx;
- 	u8 nss;
- 	u8 rx_flags;
-diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 46ae9e9..fadf2be 100644
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -5328,6 +5328,15 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
- 				      status->rate_idx, status->nss))
- 				goto drop;
- 			break;
-+		case RX_ENC_EHT:
-+			if (WARN_ONCE(status->rate_idx > 15 ||
-+				      !status->nss ||
-+				      status->nss > 8 ||
-+				      status->eht.gi > NL80211_RATE_INFO_EHT_GI_3_2,
-+				      "Rate marked as an EHT rate but data is invalid: MCS:%d, NSS:%d, GI:%d\n",
-+				      status->rate_idx, status->nss, status->eht.gi))
-+				goto drop;
-+			break;
- 		default:
- 			WARN_ON_ONCE(1);
- 			fallthrough;
-diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
-index a13a8fb..50daa22 100644
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -4,7 +4,7 @@
-  * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
-  * Copyright 2013-2014  Intel Mobile Communications GmbH
-  * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
-- * Copyright (C) 2018-2021 Intel Corporation
-+ * Copyright (C) 2018-2022 Intel Corporation
-  */
- 
- #include <linux/module.h>
-@@ -2384,6 +2384,13 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
- 		rinfo->he_ru_alloc = STA_STATS_GET(HE_RU, rate);
- 		rinfo->he_dcm = STA_STATS_GET(HE_DCM, rate);
- 		break;
-+	case STA_STATS_RATE_TYPE_EHT:
-+		rinfo->flags = RATE_INFO_FLAGS_EHT_MCS;
-+		rinfo->mcs = STA_STATS_GET(EHT_MCS, rate);
-+		rinfo->nss = STA_STATS_GET(EHT_NSS, rate);
-+		rinfo->eht_gi = STA_STATS_GET(EHT_GI, rate);
-+		rinfo->eht_ru_alloc = STA_STATS_GET(EHT_RU, rate);
-+		break;
- 	}
- }
- 
-diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
-index 759a1a8..ec8dff0 100644
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -930,6 +930,7 @@ enum sta_stats_type {
- 	STA_STATS_RATE_TYPE_VHT,
- 	STA_STATS_RATE_TYPE_HE,
- 	STA_STATS_RATE_TYPE_S1G,
-+	STA_STATS_RATE_TYPE_EHT,
- };
- 
- #define STA_STATS_FIELD_HT_MCS		GENMASK( 7,  0)
-@@ -939,12 +940,16 @@ enum sta_stats_type {
- #define STA_STATS_FIELD_VHT_NSS		GENMASK( 7,  4)
- #define STA_STATS_FIELD_HE_MCS		GENMASK( 3,  0)
- #define STA_STATS_FIELD_HE_NSS		GENMASK( 7,  4)
--#define STA_STATS_FIELD_BW		GENMASK(11,  8)
--#define STA_STATS_FIELD_SGI		GENMASK(12, 12)
--#define STA_STATS_FIELD_TYPE		GENMASK(15, 13)
--#define STA_STATS_FIELD_HE_RU		GENMASK(18, 16)
--#define STA_STATS_FIELD_HE_GI		GENMASK(20, 19)
--#define STA_STATS_FIELD_HE_DCM		GENMASK(21, 21)
-+#define STA_STATS_FIELD_EHT_MCS		GENMASK( 3,  0)
-+#define STA_STATS_FIELD_EHT_NSS		GENMASK( 7,  4)
-+#define STA_STATS_FIELD_BW		GENMASK(12,  8)
-+#define STA_STATS_FIELD_SGI		GENMASK(13, 13)
-+#define STA_STATS_FIELD_TYPE		GENMASK(16, 14)
-+#define STA_STATS_FIELD_HE_RU		GENMASK(19, 17)
-+#define STA_STATS_FIELD_HE_GI		GENMASK(21, 20)
-+#define STA_STATS_FIELD_HE_DCM		GENMASK(22, 22)
-+#define STA_STATS_FIELD_EHT_RU		GENMASK(20, 17)
-+#define STA_STATS_FIELD_EHT_GI		GENMASK(22, 21)
- 
- #define STA_STATS_FIELD(_n, _v)		FIELD_PREP(STA_STATS_FIELD_ ## _n, _v)
- #define STA_STATS_GET(_n, _v)		FIELD_GET(STA_STATS_FIELD_ ## _n, _v)
-@@ -983,6 +988,13 @@ static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s)
- 		r |= STA_STATS_FIELD(HE_RU, s->he_ru);
- 		r |= STA_STATS_FIELD(HE_DCM, s->he_dcm);
- 		break;
-+	case RX_ENC_EHT:
-+		r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_EHT);
-+		r |= STA_STATS_FIELD(EHT_NSS, s->nss);
-+		r |= STA_STATS_FIELD(EHT_MCS, s->rate_idx);
-+		r |= STA_STATS_FIELD(EHT_GI, s->eht.gi);
-+		r |= STA_STATS_FIELD(EHT_RU, s->eht.ru);
-+		break;
- 	default:
- 		WARN_ON(1);
- 		return STA_STATS_RATE_INVALID;
-diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index 83f6c56..5a6c091 100644
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -3900,6 +3900,19 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
- 
- 	/* Fill cfg80211 rate info */
- 	switch (status->encoding) {
-+	case RX_ENC_EHT:
-+		ri.flags |= RATE_INFO_FLAGS_EHT_MCS;
-+		ri.mcs = status->rate_idx;
-+		ri.nss = status->nss;
-+		ri.eht_ru_alloc = status->eht.ru;
-+		if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
-+			ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
-+		/* TODO/FIXME: is this right? handle other PPDUs */
-+		if (status->flag & RX_FLAG_MACTIME_PLCP_START) {
-+			mpdu_offset += 2;
-+			ts += 36;
-+		}
-+		break;
- 	case RX_ENC_HE:
- 		ri.flags |= RATE_INFO_FLAGS_HE_MCS;
- 		ri.mcs = status->rate_idx;
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0003-cfg80211-Update-Transition-Disable-policy-during-por.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0003-cfg80211-Update-Transition-Disable-policy-during-por.patch
deleted file mode 100644
index a3f6dda..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0003-cfg80211-Update-Transition-Disable-policy-during-por.patch
+++ /dev/null
@@ -1,208 +0,0 @@
-From e0756f54dea42f1833e40ddfb0deb5d0b8e6dda4 Mon Sep 17 00:00:00 2001
-From: Vinayak Yadawad <vinayak.yadawad@broadcom.com>
-Date: Wed, 7 Sep 2022 18:14:48 +0530
-Subject: [PATCH 3/9] cfg80211: Update Transition Disable policy during port
- authorization
-
-In case of 4way handshake offload, transition disable policy
-updated by the AP during EAPOL 3/4 is not updated to the upper layer.
-This results in mismatch between transition disable policy
-between the upper layer and the driver. This patch addresses this
-issue by updating transition disable policy as part of port
-authorization indication.
-
-Signed-off-by: Vinayak Yadawad <vinayak.yadawad@broadcom.com>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c  |  2 +-
- include/net/cfg80211.h                               |  4 +++-
- include/uapi/linux/nl80211.h                         |  3 +++
- net/wireless/core.h                                  |  5 ++++-
- net/wireless/nl80211.c                               |  8 +++++++-
- net/wireless/nl80211.h                               |  3 ++-
- net/wireless/sme.c                                   | 12 ++++++++----
- net/wireless/util.c                                  |  4 +++-
- 8 files changed, 31 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-index ea8409e..bddc0af 100644
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -6005,7 +6005,7 @@ done:
- 	brcmf_dbg(CONN, "Report roaming result\n");
- 
- 	if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
--		cfg80211_port_authorized(ndev, profile->bssid, GFP_KERNEL);
-+		cfg80211_port_authorized(ndev, profile->bssid, NULL, 0, GFP_KERNEL);
- 		brcmf_dbg(CONN, "Report port authorized\n");
- 	}
- 
-diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 803949b..9420086 100644
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -7717,6 +7717,8 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
-  *
-  * @dev: network device
-  * @bssid: the BSSID of the AP
-+ * @td_bitmap: transition disable policy
-+ * @td_bitmap_len: Length of transition disable policy
-  * @gfp: allocation flags
-  *
-  * This function should be called by a driver that supports 4 way handshake
-@@ -7727,7 +7729,7 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
-  * indicate the 802.11 association.
-  */
- void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
--			      gfp_t gfp);
-+			      const u8* td_bitmap, u8 td_bitmap_len, gfp_t gfp);
- 
- /**
-  * cfg80211_disconnected - notify cfg80211 that connection was dropped
-diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
-index c32e761..c14a91b 100644
---- a/include/uapi/linux/nl80211.h
-+++ b/include/uapi/linux/nl80211.h
-@@ -2749,6 +2749,8 @@ enum nl80211_commands {
-  *	When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX
-  *	timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates
-  *	the incoming frame RX timestamp.
-+ * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
-+ *	(re)associations.
-  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
-  * @NL80211_ATTR_MAX: highest attribute number currently defined
-  * @__NL80211_ATTR_AFTER_LAST: internal use
-@@ -3276,6 +3278,7 @@ enum nl80211_attrs {
- 
- 	NL80211_ATTR_TX_HW_TIMESTAMP,
- 	NL80211_ATTR_RX_HW_TIMESTAMP,
-+	NL80211_ATTR_TD_BITMAP,
- 
- 	/* add attributes here, update the policy in nl80211.c */
- 
-diff --git a/net/wireless/core.h b/net/wireless/core.h
-index f4d3b83..382455c 100644
---- a/net/wireless/core.h
-+++ b/net/wireless/core.h
-@@ -271,6 +271,8 @@ struct cfg80211_event {
- 		} ij;
- 		struct {
- 			u8 bssid[ETH_ALEN];
-+			const u8 *td_bitmap;
-+			u8 td_bitmap_len;
- 		} pa;
- 	};
- };
-@@ -409,7 +411,8 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
- 			bool wextev);
- void __cfg80211_roamed(struct wireless_dev *wdev,
- 		       struct cfg80211_roam_info *info);
--void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid);
-+void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
-+				const u8 *td_bitmap, u8 td_bitmap_len);
- int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
- 			      struct wireless_dev *wdev);
- void cfg80211_autodisconnect_wk(struct work_struct *work);
-diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 777c141..6a97e52 100644
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -17936,7 +17936,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
- }
- 
- void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
--				  struct net_device *netdev, const u8 *bssid)
-+				  struct net_device *netdev, const u8 *bssid,
-+				  const u8 *td_bitmap, u8 td_bitmap_len)
- {
- 	struct sk_buff *msg;
- 	void *hdr;
-@@ -17956,6 +17957,11 @@ void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
- 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
- 		goto nla_put_failure;
- 
-+	if ((td_bitmap_len > 0) && td_bitmap)
-+		if (nla_put(msg, NL80211_ATTR_TD_BITMAP,
-+			    td_bitmap_len, td_bitmap))
-+			goto nla_put_failure;
-+
- 	genlmsg_end(msg, hdr);
- 
- 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
-diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
-index 855d540..ba9457e 100644
---- a/net/wireless/nl80211.h
-+++ b/net/wireless/nl80211.h
-@@ -83,7 +83,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
- 			 struct net_device *netdev,
- 			 struct cfg80211_roam_info *info, gfp_t gfp);
- void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
--				  struct net_device *netdev, const u8 *bssid);
-+				  struct net_device *netdev, const u8 *bssid,
-+				  const u8 *td_bitmap, u8 td_bitmap_len);
- void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
- 			       struct net_device *netdev, u16 reason,
- 			       const u8 *ie, size_t ie_len, bool from_ap);
-diff --git a/net/wireless/sme.c b/net/wireless/sme.c
-index 05e4f29..1ee4408 100644
---- a/net/wireless/sme.c
-+++ b/net/wireless/sme.c
-@@ -1266,7 +1266,8 @@ out:
- }
- EXPORT_SYMBOL(cfg80211_roamed);
- 
--void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid)
-+void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
-+					const u8 *td_bitmap, u8 td_bitmap_len)
- {
- 	ASSERT_WDEV_LOCK(wdev);
- 
-@@ -1279,11 +1280,11 @@ void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid)
- 		return;
- 
- 	nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev,
--				     bssid);
-+				     bssid, td_bitmap, td_bitmap_len);
- }
- 
- void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
--			      gfp_t gfp)
-+			      const u8 *td_bitmap, u8 td_bitmap_len, gfp_t gfp)
- {
- 	struct wireless_dev *wdev = dev->ieee80211_ptr;
- 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
-@@ -1293,12 +1294,15 @@ void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
- 	if (WARN_ON(!bssid))
- 		return;
- 
--	ev = kzalloc(sizeof(*ev), gfp);
-+	ev = kzalloc(sizeof(*ev) + td_bitmap_len, gfp);
- 	if (!ev)
- 		return;
- 
- 	ev->type = EVENT_PORT_AUTHORIZED;
- 	memcpy(ev->pa.bssid, bssid, ETH_ALEN);
-+	ev->pa.td_bitmap = ((u8 *)ev) + sizeof(*ev);
-+	ev->pa.td_bitmap_len = td_bitmap_len;
-+	memcpy((void *)ev->pa.td_bitmap, td_bitmap, td_bitmap_len);
- 
- 	/*
- 	 * Use the wdev event list so that if there are pending
-diff --git a/net/wireless/util.c b/net/wireless/util.c
-index 769f8fe..fdc140e 100644
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -1057,7 +1057,9 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
- 			__cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
- 			break;
- 		case EVENT_PORT_AUTHORIZED:
--			__cfg80211_port_authorized(wdev, ev->pa.bssid);
-+			__cfg80211_port_authorized(wdev, ev->pa.bssid,
-+						   ev->pa.td_bitmap,
-+						   ev->pa.td_bitmap_len);
- 			break;
- 		}
- 		wdev_unlock(wdev);
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0004-wifi-mac80211-mlme-handle-EHT-channel-puncturing.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0004-wifi-mac80211-mlme-handle-EHT-channel-puncturing.patch
deleted file mode 100644
index d455dd0..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0004-wifi-mac80211-mlme-handle-EHT-channel-puncturing.patch
+++ /dev/null
@@ -1,400 +0,0 @@
-From 67ce530e39e0372f11006c5695f682e71152f7b7 Mon Sep 17 00:00:00 2001
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Fri, 27 Jan 2023 12:39:31 +0100
-Subject: [PATCH 4/9] wifi: mac80211: mlme: handle EHT channel puncturing
-
-Handle the Puncturing info received from the AP in the
-EHT Operation element in beacons.
-
-If the info is invalid:
- - during association: disable EHT connection for the AP
- - after association: disconnect
-
-This commit includes many (internal) bugfixes and spec
-updates various people.
-
-Co-developed-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
-Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
-Link: https://lore.kernel.org/r/20230127123930.4fbc74582331.I3547481d49f958389f59dfeba3fcc75e72b0aa6e@changeid
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/mac80211.h     |   5 +-
- net/mac80211/cfg.c         |   2 +-
- net/mac80211/chan.c        |   2 +-
- net/mac80211/ieee80211_i.h |   2 +-
- net/mac80211/mlme.c        | 224 ++++++++++++++++++++++++++++++++++++-
- 5 files changed, 228 insertions(+), 7 deletions(-)
-
-diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 3388cc7..8fb38c9 100644
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -340,7 +340,7 @@ struct ieee80211_vif_chanctx_switch {
-  * @BSS_CHANGED_FILS_DISCOVERY: FILS discovery status changed.
-  * @BSS_CHANGED_UNSOL_BCAST_PROBE_RESP: Unsolicited broadcast probe response
-  *	status changed.
-- *
-+ * @BSS_CHANGED_EHT_PUNCTURING: The channel puncturing bitmap changed.
-  */
- enum ieee80211_bss_change {
- 	BSS_CHANGED_ASSOC		= 1<<0,
-@@ -375,6 +375,7 @@ enum ieee80211_bss_change {
- 	BSS_CHANGED_HE_BSS_COLOR	= 1<<29,
- 	BSS_CHANGED_FILS_DISCOVERY      = 1<<30,
- 	BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = 1<<31,
-+	BSS_CHANGED_EHT_PUNCTURING	= BIT_ULL(32),
- 
- 	/* when adding here, make sure to change ieee80211_reconfig */
- };
-@@ -640,6 +641,7 @@ struct ieee80211_fils_discovery {
-  * @tx_pwr_env_num: number of @tx_pwr_env.
-  * @pwr_reduction: power constraint of BSS.
-  * @eht_support: does this BSS support EHT
-+ * @eht_puncturing: bitmap to indicate which channels are punctured in this BSS
-  * @csa_active: marks whether a channel switch is going on. Internally it is
-  *	write-protected by sdata_lock and local->mtx so holding either is fine
-  *	for read access.
-@@ -739,6 +741,7 @@ struct ieee80211_bss_conf {
- 	u8 tx_pwr_env_num;
- 	u8 pwr_reduction;
- 	bool eht_support;
-+	u16 eht_puncturing;
- 
- 	bool csa_active;
- 	bool mu_mimo_owner;
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 7a5e459..5bb43de 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -4181,7 +4181,7 @@ static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy,
- 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- 	struct ieee80211_link_data *link;
- 	int ret;
--	u32 changed = 0;
-+	u64 changed = 0;
- 
- 	link = sdata_dereference(sdata->link[link_id], sdata);
- 
-diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
-index e72cf07..dbc34fb 100644
---- a/net/mac80211/chan.c
-+++ b/net/mac80211/chan.c
-@@ -1916,7 +1916,7 @@ int ieee80211_link_use_reserved_context(struct ieee80211_link_data *link)
- 
- int ieee80211_link_change_bandwidth(struct ieee80211_link_data *link,
- 				    const struct cfg80211_chan_def *chandef,
--				    u32 *changed)
-+				    u64 *changed)
- {
- 	struct ieee80211_sub_if_data *sdata = link->sdata;
- 	struct ieee80211_bss_conf *link_conf = link->conf;
-diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
-index a4fab9a..04128d5 100644
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -2487,7 +2487,7 @@ int ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link);
- int __must_check
- ieee80211_link_change_bandwidth(struct ieee80211_link_data *link,
- 				const struct cfg80211_chan_def *chandef,
--				u32 *changed);
-+				u64 *changed);
- void ieee80211_link_release_channel(struct ieee80211_link_data *link);
- void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link);
- void ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link,
-diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 0125b3e..8c69fd6 100644
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -8,7 +8,7 @@
-  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
-  * Copyright 2013-2014  Intel Mobile Communications GmbH
-  * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
-- * Copyright (C) 2018 - 2022 Intel Corporation
-+ * Copyright (C) 2018 - 2023 Intel Corporation
-  */
- 
- #include <linux/delay.h>
-@@ -88,6 +88,141 @@ MODULE_PARM_DESC(probe_wait_ms,
-  */
- #define IEEE80211_SIGNAL_AVE_MIN_COUNT	4
- 
-+struct ieee80211_per_bw_puncturing_values {
-+	u8 len;
-+	const u16 *valid_values;
-+};
-+
-+static const u16 puncturing_values_80mhz[] = {
-+	0x8, 0x4, 0x2, 0x1
-+};
-+
-+static const u16 puncturing_values_160mhz[] = {
-+	 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
-+};
-+
-+static const u16 puncturing_values_320mhz[] = {
-+	0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
-+	0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
-+	0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
-+};
-+
-+#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
-+	{ \
-+		.len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
-+		.valid_values = puncturing_values_ ## _bw ## mhz \
-+	}
-+
-+static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = {
-+	IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80),
-+	IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160),
-+	IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320)
-+};
-+
-+static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap,
-+						      enum nl80211_chan_width bw)
-+{
-+	u32 idx, i;
-+
-+	switch (bw) {
-+	case NL80211_CHAN_WIDTH_80:
-+		idx = 0;
-+		break;
-+	case NL80211_CHAN_WIDTH_160:
-+		idx = 1;
-+		break;
-+	case NL80211_CHAN_WIDTH_320:
-+		idx = 2;
-+		break;
-+	default:
-+		*bitmap = 0;
-+		break;
-+	}
-+
-+	if (!*bitmap)
-+		return true;
-+
-+	for (i = 0; i < per_bw_puncturing[idx].len; i++)
-+		if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
-+			return true;
-+
-+	return false;
-+}
-+
-+/*
-+ * Extract from the given disabled subchannel bitmap (raw format
-+ * from the EHT Operation Element) the bits for the subchannel
-+ * we're using right now.
-+ */
-+static u16
-+ieee80211_extract_dis_subch_bmap(const struct ieee80211_eht_operation *eht_oper,
-+				 struct cfg80211_chan_def *chandef, u16 bitmap)
-+{
-+	struct ieee80211_eht_operation_info *info = (void *)eht_oper->optional;
-+	struct cfg80211_chan_def ap_chandef = *chandef;
-+	u32 ap_center_freq, local_center_freq;
-+	u32 ap_bw, local_bw;
-+	int ap_start_freq, local_start_freq;
-+	u16 shift, mask;
-+
-+	if (!(eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT) ||
-+	    !(eht_oper->params &
-+	      IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT))
-+		return 0;
-+
-+	/* set 160/320 supported to get the full AP definition */
-+	ieee80211_chandef_eht_oper(eht_oper, true, true, &ap_chandef);
-+	ap_center_freq = ap_chandef.center_freq1;
-+	ap_bw = 20 * BIT(u8_get_bits(info->control,
-+				     IEEE80211_EHT_OPER_CHAN_WIDTH));
-+	ap_start_freq = ap_center_freq - ap_bw / 2;
-+	local_center_freq = chandef->center_freq1;
-+	local_bw = 20 * BIT(ieee80211_chan_width_to_rx_bw(chandef->width));
-+	local_start_freq = local_center_freq - local_bw / 2;
-+	shift = (local_start_freq - ap_start_freq) / 20;
-+	mask = BIT(local_bw / 20) - 1;
-+
-+	return (bitmap >> shift) & mask;
-+}
-+
-+/*
-+ * Handle the puncturing bitmap, possibly downgrading bandwidth to get a
-+ * valid bitmap.
-+ */
-+static void
-+ieee80211_handle_puncturing_bitmap(struct ieee80211_link_data *link,
-+				   const struct ieee80211_eht_operation *eht_oper,
-+				   u16 bitmap, u64 *changed)
-+{
-+	struct cfg80211_chan_def *chandef = &link->conf->chandef;
-+	u16 extracted;
-+	u64 _changed = 0;
-+
-+	if (!changed)
-+		changed = &_changed;
-+
-+	while (chandef->width > NL80211_CHAN_WIDTH_40) {
-+		extracted =
-+			ieee80211_extract_dis_subch_bmap(eht_oper, chandef,
-+							 bitmap);
-+
-+		if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
-+							      chandef->width))
-+			break;
-+		link->u.mgd.conn_flags |=
-+			ieee80211_chandef_downgrade(chandef);
-+		*changed |= BSS_CHANGED_BANDWIDTH;
-+	}
-+
-+	if (chandef->width <= NL80211_CHAN_WIDTH_40)
-+		extracted = 0;
-+
-+	if (link->conf->eht_puncturing != extracted) {
-+		link->conf->eht_puncturing = extracted;
-+		*changed |= BSS_CHANGED_EHT_PUNCTURING;
-+	}
-+}
-+
- /*
-  * We can have multiple work items (and connection probing)
-  * scheduling this timer, but we need to take care to only
-@@ -413,7 +548,7 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,
- 			       const struct ieee80211_he_operation *he_oper,
- 			       const struct ieee80211_eht_operation *eht_oper,
- 			       const struct ieee80211_s1g_oper_ie *s1g_oper,
--			       const u8 *bssid, u32 *changed)
-+			       const u8 *bssid, u64 *changed)
- {
- 	struct ieee80211_sub_if_data *sdata = link->sdata;
- 	struct ieee80211_local *local = sdata->local;
-@@ -4111,6 +4246,7 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
- 							    link_sta);
- 
- 			bss_conf->eht_support = link_sta->pub->eht_cap.has_eht;
-+			*changed |= BSS_CHANGED_EHT_PUNCTURING;
- 		} else {
- 			bss_conf->eht_support = false;
- 		}
-@@ -5423,6 +5559,45 @@ static bool ieee80211_rx_our_beacon(const u8 *tx_bssid,
- 	return ether_addr_equal(tx_bssid, bss->transmitted_bss->bssid);
- }
- 
-+static bool ieee80211_config_puncturing(struct ieee80211_link_data *link,
-+					const struct ieee80211_eht_operation *eht_oper,
-+					u64 *changed)
-+{
-+	u16 bitmap = 0, extracted;
-+
-+	if ((eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT) &&
-+	    (eht_oper->params &
-+	     IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT)) {
-+		const struct ieee80211_eht_operation_info *info =
-+			(void *)eht_oper->optional;
-+		const u8 *disable_subchannel_bitmap = info->optional;
-+
-+		bitmap = get_unaligned_le16(disable_subchannel_bitmap);
-+	}
-+
-+	extracted = ieee80211_extract_dis_subch_bmap(eht_oper,
-+						     &link->conf->chandef,
-+						     bitmap);
-+
-+	/* accept if there are no changes */
-+	if (!(*changed & BSS_CHANGED_BANDWIDTH) &&
-+	    extracted == link->conf->eht_puncturing)
-+		return true;
-+
-+	if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap,
-+						       link->conf->chandef.width)) {
-+		link_info(link,
-+			  "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n",
-+			  link->u.mgd.bssid,
-+			  bitmap,
-+			  link->conf->chandef.width);
-+		return false;
-+	}
-+
-+	ieee80211_handle_puncturing_bitmap(link, eht_oper, bitmap, changed);
-+	return true;
-+}
-+
- static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
- 				     struct ieee80211_hdr *hdr, size_t len,
- 				     struct ieee80211_rx_status *rx_status)
-@@ -5439,7 +5614,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
- 	struct ieee80211_channel *chan;
- 	struct link_sta_info *link_sta;
- 	struct sta_info *sta;
--	u32 changed = 0;
-+	u64 changed = 0;
- 	bool erp_valid;
- 	u8 erp_value = 0;
- 	u32 ncrc = 0;
-@@ -5731,6 +5906,21 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
- 					       elems->pwr_constr_elem,
- 					       elems->cisco_dtpc_elem);
- 
-+	if (elems->eht_operation &&
-+	    !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_EHT)) {
-+		if (!ieee80211_config_puncturing(link, elems->eht_operation,
-+						 &changed)) {
-+			ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
-+					       WLAN_REASON_DEAUTH_LEAVING,
-+					       true, deauth_buf);
-+			ieee80211_report_disconnect(sdata, deauth_buf,
-+						    sizeof(deauth_buf), true,
-+						    WLAN_REASON_DEAUTH_LEAVING,
-+						    false);
-+			goto free;
-+		}
-+	}
-+
- 	ieee80211_link_info_change_notify(sdata, link, changed);
- free:
- 	kfree(elems);
-@@ -6832,9 +7022,12 @@ ieee80211_setup_assoc_link(struct ieee80211_sub_if_data *sdata,
- 		ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
- 	}
- 
-+	link->conf->eht_puncturing = 0;
-+
- 	rcu_read_lock();
- 	beacon_ies = rcu_dereference(cbss->beacon_ies);
- 	if (beacon_ies) {
-+		const struct ieee80211_eht_operation *eht_oper;
- 		const struct element *elem;
- 		u8 dtim_count = 0;
- 
-@@ -6863,6 +7056,31 @@ ieee80211_setup_assoc_link(struct ieee80211_sub_if_data *sdata,
- 			link->conf->ema_ap = true;
- 		else
- 			link->conf->ema_ap = false;
-+
-+		elem = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_OPERATION,
-+					      beacon_ies->data, beacon_ies->len);
-+		eht_oper = (const void *)(elem->data + 1);
-+
-+		if (elem &&
-+		    ieee80211_eht_oper_size_ok((const void *)(elem->data + 1),
-+					       elem->datalen - 1) &&
-+		    (eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT) &&
-+		    (eht_oper->params & IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT)) {
-+			const struct ieee80211_eht_operation_info *info =
-+				(void *)eht_oper->optional;
-+			const u8 *disable_subchannel_bitmap = info->optional;
-+			u16 bitmap;
-+
-+			bitmap = get_unaligned_le16(disable_subchannel_bitmap);
-+			if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
-+								      link->conf->chandef.width))
-+				ieee80211_handle_puncturing_bitmap(link,
-+								   eht_oper,
-+								   bitmap,
-+								   NULL);
-+			else
-+				conn_flags |= IEEE80211_CONN_DISABLE_EHT;
-+		}
- 	}
- 	rcu_read_unlock();
- 
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0005-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0005-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch
deleted file mode 100644
index 2a7cd07..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0005-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch
+++ /dev/null
@@ -1,228 +0,0 @@
-From 40e52a97b1bc7b280198cb63e11663d784bd48c8 Mon Sep 17 00:00:00 2001
-From: Aloka Dixit <quic_alokad@quicinc.com>
-Date: Mon, 30 Jan 2023 16:12:24 -0800
-Subject: [PATCH 5/9] wifi: cfg80211: move puncturing bitmap validation from
- mac80211
-
-- Move ieee80211_valid_disable_subchannel_bitmap() from mlme.c to
-  chan.c, rename it as cfg80211_valid_disable_subchannel_bitmap()
-  and export it.
-- Modify the prototype to include struct cfg80211_chan_def instead
-  of only bandwidth to support a check which returns false if the
-  primary channel is punctured.
-
-Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
-Link: https://lore.kernel.org/r/20230131001227.25014-2-quic_alokad@quicinc.com
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/cfg80211.h | 12 +++++++
- net/mac80211/mlme.c    | 73 ++++--------------------------------------
- net/wireless/chan.c    | 69 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 87 insertions(+), 67 deletions(-)
-
-diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 9420086..d532612 100644
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -8948,4 +8948,16 @@ static inline int cfg80211_color_change_notify(struct net_device *dev)
- 					 0, 0);
- }
- 
-+/**
-+ * cfg80211_valid_disable_subchannel_bitmap - validate puncturing bitmap
-+ * @bitmap: bitmap to be validated
-+ * @chandef: channel definition
-+ *
-+ * Validate the puncturing bitmap.
-+ *
-+ * Return: %true if the bitmap is valid. %false otherwise.
-+ */
-+bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
-+					      const struct cfg80211_chan_def *chandef);
-+
- #endif /* __NET_CFG80211_H */
-diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 8c69fd6..2716ae0 100644
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -88,67 +88,6 @@ MODULE_PARM_DESC(probe_wait_ms,
-  */
- #define IEEE80211_SIGNAL_AVE_MIN_COUNT	4
- 
--struct ieee80211_per_bw_puncturing_values {
--	u8 len;
--	const u16 *valid_values;
--};
--
--static const u16 puncturing_values_80mhz[] = {
--	0x8, 0x4, 0x2, 0x1
--};
--
--static const u16 puncturing_values_160mhz[] = {
--	 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
--};
--
--static const u16 puncturing_values_320mhz[] = {
--	0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
--	0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
--	0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
--};
--
--#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
--	{ \
--		.len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
--		.valid_values = puncturing_values_ ## _bw ## mhz \
--	}
--
--static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = {
--	IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80),
--	IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160),
--	IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320)
--};
--
--static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap,
--						      enum nl80211_chan_width bw)
--{
--	u32 idx, i;
--
--	switch (bw) {
--	case NL80211_CHAN_WIDTH_80:
--		idx = 0;
--		break;
--	case NL80211_CHAN_WIDTH_160:
--		idx = 1;
--		break;
--	case NL80211_CHAN_WIDTH_320:
--		idx = 2;
--		break;
--	default:
--		*bitmap = 0;
--		break;
--	}
--
--	if (!*bitmap)
--		return true;
--
--	for (i = 0; i < per_bw_puncturing[idx].len; i++)
--		if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
--			return true;
--
--	return false;
--}
--
- /*
-  * Extract from the given disabled subchannel bitmap (raw format
-  * from the EHT Operation Element) the bits for the subchannel
-@@ -206,8 +145,8 @@ ieee80211_handle_puncturing_bitmap(struct ieee80211_link_data *link,
- 			ieee80211_extract_dis_subch_bmap(eht_oper, chandef,
- 							 bitmap);
- 
--		if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
--							      chandef->width))
-+		if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
-+							     chandef))
- 			break;
- 		link->u.mgd.conn_flags |=
- 			ieee80211_chandef_downgrade(chandef);
-@@ -5584,8 +5523,8 @@ static bool ieee80211_config_puncturing(struct ieee80211_link_data *link,
- 	    extracted == link->conf->eht_puncturing)
- 		return true;
- 
--	if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap,
--						       link->conf->chandef.width)) {
-+	if (!cfg80211_valid_disable_subchannel_bitmap(&bitmap,
-+						      &link->conf->chandef)) {
- 		link_info(link,
- 			  "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n",
- 			  link->u.mgd.bssid,
-@@ -7072,8 +7011,8 @@ ieee80211_setup_assoc_link(struct ieee80211_sub_if_data *sdata,
- 			u16 bitmap;
- 
- 			bitmap = get_unaligned_le16(disable_subchannel_bitmap);
--			if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
--								      link->conf->chandef.width))
-+			if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
-+								     &link->conf->chandef))
- 				ieee80211_handle_puncturing_bitmap(link,
- 								   eht_oper,
- 								   bitmap,
-diff --git a/net/wireless/chan.c b/net/wireless/chan.c
-index 29b5c2f..d5ed976 100644
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -1460,3 +1460,72 @@ struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev,
- 	}
- }
- EXPORT_SYMBOL(wdev_chandef);
-+
-+struct cfg80211_per_bw_puncturing_values {
-+	u8 len;
-+	const u16 *valid_values;
-+};
-+
-+static const u16 puncturing_values_80mhz[] = {
-+	0x8, 0x4, 0x2, 0x1
-+};
-+
-+static const u16 puncturing_values_160mhz[] = {
-+	 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
-+};
-+
-+static const u16 puncturing_values_320mhz[] = {
-+	0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
-+	0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
-+	0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
-+};
-+
-+#define CFG80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
-+	{ \
-+		.len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
-+		.valid_values = puncturing_values_ ## _bw ## mhz \
-+	}
-+
-+static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = {
-+	CFG80211_PER_BW_VALID_PUNCTURING_VALUES(80),
-+	CFG80211_PER_BW_VALID_PUNCTURING_VALUES(160),
-+	CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320)
-+};
-+
-+bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
-+					      const struct cfg80211_chan_def *chandef)
-+{
-+	u32 idx, i, start_freq;
-+
-+	switch (chandef->width) {
-+	case NL80211_CHAN_WIDTH_80:
-+		idx = 0;
-+		start_freq = chandef->center_freq1 - 40;
-+		break;
-+	case NL80211_CHAN_WIDTH_160:
-+		idx = 1;
-+		start_freq = chandef->center_freq1 - 80;
-+		break;
-+	case NL80211_CHAN_WIDTH_320:
-+		idx = 2;
-+		start_freq = chandef->center_freq1 - 160;
-+		break;
-+	default:
-+		*bitmap = 0;
-+		break;
-+	}
-+
-+	if (!*bitmap)
-+		return true;
-+
-+	/* check if primary channel is punctured */
-+	if (*bitmap & (u16)BIT((chandef->chan->center_freq - start_freq) / 20))
-+		return false;
-+
-+	for (i = 0; i < per_bw_puncturing[idx].len; i++)
-+		if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
-+			return true;
-+
-+	return false;
-+}
-+EXPORT_SYMBOL(cfg80211_valid_disable_subchannel_bitmap);
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0006-wifi-nl80211-validate-and-configure-puncturing-bitma.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0006-wifi-nl80211-validate-and-configure-puncturing-bitma.patch
deleted file mode 100644
index 75fe1bb..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0006-wifi-nl80211-validate-and-configure-puncturing-bitma.patch
+++ /dev/null
@@ -1,178 +0,0 @@
-From 63bd8cc91635ad129587df0227be49074538b36e Mon Sep 17 00:00:00 2001
-From: Aloka Dixit <quic_alokad@quicinc.com>
-Date: Mon, 30 Jan 2023 16:12:25 -0800
-Subject: [PATCH 6/9] wifi: nl80211: validate and configure puncturing bitmap
-
-- New feature flag, NL80211_EXT_FEATURE_PUNCT, to advertise
-  driver support for preamble puncturing in AP mode.
-- New attribute, NL80211_ATTR_PUNCT_BITMAP, to receive a puncturing
-  bitmap from the userspace during AP bring up (NL80211_CMD_START_AP)
-  and channel switch (NL80211_CMD_CHANNEL_SWITCH) operations. Each bit
-  corresponds to a 20 MHz channel in the operating bandwidth, lowest
-  bit for the lowest channel. Bit set to 1 indicates that the channel
-  is punctured. Higher 16 bits are reserved.
-- New members added to structures cfg80211_ap_settings and
-  cfg80211_csa_settings to propagate the bitmap to the driver after
-  validation.
-
-Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
-Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
-Link: https://lore.kernel.org/r/20230131001227.25014-3-quic_alokad@quicinc.com
-[move validation against 0xffff into policy]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/cfg80211.h       |  8 ++++++++
- include/uapi/linux/nl80211.h | 11 +++++++++++
- net/wireless/nl80211.c       | 32 ++++++++++++++++++++++++++++++++
- 3 files changed, 51 insertions(+)
-
-diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index d532612..9c65eda 100644
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -1327,6 +1327,9 @@ struct cfg80211_unsol_bcast_probe_resp {
-  * @fils_discovery: FILS discovery transmission parameters
-  * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters
-  * @mbssid_config: AP settings for multiple bssid
-+ * @punct_bitmap: Preamble puncturing bitmap. Each bit represents
-+ *	a 20 MHz channel, lowest bit corresponding to the lowest channel.
-+ *	Bit set to 1 indicates that the channel is punctured.
-  */
- struct cfg80211_ap_settings {
- 	struct cfg80211_chan_def chandef;
-@@ -1361,6 +1364,7 @@ struct cfg80211_ap_settings {
- 	struct cfg80211_fils_discovery fils_discovery;
- 	struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp;
- 	struct cfg80211_mbssid_config mbssid_config;
-+	u16 punct_bitmap;
- };
- 
- /**
-@@ -1378,6 +1382,9 @@ struct cfg80211_ap_settings {
-  * @radar_required: whether radar detection is required on the new channel
-  * @block_tx: whether transmissions should be blocked while changing
-  * @count: number of beacons until switch
-+ * @punct_bitmap: Preamble puncturing bitmap. Each bit represents
-+ *	a 20 MHz channel, lowest bit corresponding to the lowest channel.
-+ *	Bit set to 1 indicates that the channel is punctured.
-  */
- struct cfg80211_csa_settings {
- 	struct cfg80211_chan_def chandef;
-@@ -1390,6 +1397,7 @@ struct cfg80211_csa_settings {
- 	bool radar_required;
- 	bool block_tx;
- 	u8 count;
-+	u16 punct_bitmap;
- };
- 
- /**
-diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
-index c14a91b..173aef8 100644
---- a/include/uapi/linux/nl80211.h
-+++ b/include/uapi/linux/nl80211.h
-@@ -2751,6 +2751,12 @@ enum nl80211_commands {
-  *	the incoming frame RX timestamp.
-  * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
-  *	(re)associations.
-+ *
-+ * @NL80211_ATTR_PUNCT_BITMAP: (u32) Preamble puncturing bitmap, lowest
-+ *	bit corresponds to the lowest 20 MHz channel. Each bit set to 1
-+ *	indicates that the sub-channel is punctured. Higher 16 bits are
-+ *	reserved.
-+ *
-  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
-  * @NL80211_ATTR_MAX: highest attribute number currently defined
-  * @__NL80211_ATTR_AFTER_LAST: internal use
-@@ -3280,6 +3286,8 @@ enum nl80211_attrs {
- 	NL80211_ATTR_RX_HW_TIMESTAMP,
- 	NL80211_ATTR_TD_BITMAP,
- 
-+	NL80211_ATTR_PUNCT_BITMAP,
-+
- 	/* add attributes here, update the policy in nl80211.c */
- 
- 	__NL80211_ATTR_AFTER_LAST,
-@@ -6294,6 +6302,8 @@ enum nl80211_feature_flags {
-  *	might apply, e.g. no scans in progress, no offchannel operations
-  *	in progress, and no active connections.
-  *
-+ * @NL80211_EXT_FEATURE_PUNCT: Driver supports preamble puncturing in AP mode.
-+ *
-  * @NUM_NL80211_EXT_FEATURES: number of extended features.
-  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
-  */
-@@ -6362,6 +6372,7 @@ enum nl80211_ext_feature_index {
- 	NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
- 	NL80211_EXT_FEATURE_RADAR_BACKGROUND,
- 	NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
-+	NL80211_EXT_FEATURE_PUNCT,
- 
- 	/* add new features before the definition below */
- 	NUM_NL80211_EXT_FEATURES,
-diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 6a97e52..4cc095d 100644
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -799,6 +799,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
- 	[NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
- 	[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
- 	[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
-+	[NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff),
- };
- 
- /* policy for the key attributes */
-@@ -3167,6 +3168,21 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
- 		wdev->iftype == NL80211_IFTYPE_P2P_GO;
- }
- 
-+static int nl80211_parse_punct_bitmap(struct cfg80211_registered_device *rdev,
-+				      struct genl_info *info,
-+				      const struct cfg80211_chan_def *chandef,
-+				      u16 *punct_bitmap)
-+{
-+	if (!wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_PUNCT))
-+		return -EINVAL;
-+
-+	*punct_bitmap = nla_get_u32(info->attrs[NL80211_ATTR_PUNCT_BITMAP]);
-+	if (!cfg80211_valid_disable_subchannel_bitmap(punct_bitmap, chandef))
-+		return -EINVAL;
-+
-+	return 0;
-+}
-+
- int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
- 			  struct genl_info *info,
- 			  struct cfg80211_chan_def *chandef)
-@@ -5912,6 +5928,14 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
- 		goto out;
- 	}
- 
-+	if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
-+		err = nl80211_parse_punct_bitmap(rdev, info,
-+						 &params->chandef,
-+						 &params->punct_bitmap);
-+		if (err)
-+			goto out;
-+	}
-+
- 	if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params->chandef,
- 					   wdev->iftype)) {
- 		err = -EINVAL;
-@@ -10050,6 +10074,14 @@ skip_beacons:
- 	if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
- 		params.block_tx = true;
- 
-+	if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
-+		err = nl80211_parse_punct_bitmap(rdev, info,
-+						 &params.chandef,
-+						 &params.punct_bitmap);
-+		if (err)
-+			goto free;
-+	}
-+
- 	wdev_lock(wdev);
- 	err = rdev_channel_switch(rdev, dev, &params);
- 	wdev_unlock(wdev);
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0007-wifi-cfg80211-include-puncturing-bitmap-in-channel-s.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0007-wifi-cfg80211-include-puncturing-bitmap-in-channel-s.patch
deleted file mode 100644
index 73498f0..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0007-wifi-cfg80211-include-puncturing-bitmap-in-channel-s.patch
+++ /dev/null
@@ -1,282 +0,0 @@
-From a0306fbf2adb7074815390d6adbe58fb72533556 Mon Sep 17 00:00:00 2001
-From: Aloka Dixit <quic_alokad@quicinc.com>
-Date: Mon, 30 Jan 2023 16:12:26 -0800
-Subject: [PATCH 7/9] wifi: cfg80211: include puncturing bitmap in channel
- switch events
-
-Add puncturing bitmap in channel switch notifications
-and corresponding trace functions.
-
-Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
-Link: https://lore.kernel.org/r/20230131001227.25014-4-quic_alokad@quicinc.com
-[fix qtnfmac]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- drivers/net/wireless/ath/ath6kl/cfg80211.c    |  2 +-
- drivers/net/wireless/marvell/mwifiex/11h.c    |  2 +-
- .../net/wireless/quantenna/qtnfmac/event.c    |  2 +-
- include/net/cfg80211.h                        |  6 +++--
- net/mac80211/cfg.c                            |  5 ++--
- net/mac80211/mlme.c                           |  4 ++--
- net/wireless/nl80211.c                        | 20 ++++++++++------
- net/wireless/trace.h                          | 24 ++++++++++++-------
- 8 files changed, 41 insertions(+), 24 deletions(-)
-
-diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
-index 07de0bd..576c449 100644
---- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
-+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
-@@ -1119,7 +1119,7 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
- 					NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
- 
- 	mutex_lock(&vif->wdev.mtx);
--	cfg80211_ch_switch_notify(vif->ndev, &chandef, 0);
-+	cfg80211_ch_switch_notify(vif->ndev, &chandef, 0, 0);
- 	mutex_unlock(&vif->wdev.mtx);
- }
- 
-diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c
-index 6a9d7bc..b0c40a7 100644
---- a/drivers/net/wireless/marvell/mwifiex/11h.c
-+++ b/drivers/net/wireless/marvell/mwifiex/11h.c
-@@ -292,6 +292,6 @@ void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work)
- 	mwifiex_dbg(priv->adapter, MSG,
- 		    "indicating channel switch completion to kernel\n");
- 	mutex_lock(&priv->wdev.mtx);
--	cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef, 0);
-+	cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef, 0, 0);
- 	mutex_unlock(&priv->wdev.mtx);
- }
-diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
-index 4fafe37..0e336ff 100644
---- a/drivers/net/wireless/quantenna/qtnfmac/event.c
-+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
-@@ -478,7 +478,7 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
- 			continue;
- 
- 		mutex_lock(&vif->wdev.mtx);
--		cfg80211_ch_switch_notify(vif->netdev, &chandef, 0);
-+		cfg80211_ch_switch_notify(vif->netdev, &chandef, 0, 0);
- 		mutex_unlock(&vif->wdev.mtx);
- 	}
- 
-diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 9c65eda..8d72357 100644
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -8322,13 +8322,14 @@ bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
-  * @dev: the device which switched channels
-  * @chandef: the new channel definition
-  * @link_id: the link ID for MLO, must be 0 for non-MLO
-+ * @punct_bitmap: the new puncturing bitmap
-  *
-  * Caller must acquire wdev_lock, therefore must only be called from sleepable
-  * driver context!
-  */
- void cfg80211_ch_switch_notify(struct net_device *dev,
- 			       struct cfg80211_chan_def *chandef,
--			       unsigned int link_id);
-+			       unsigned int link_id, u16 punct_bitmap);
- 
- /*
-  * cfg80211_ch_switch_started_notify - notify channel switch start
-@@ -8337,6 +8338,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
-  * @link_id: the link ID for MLO, must be 0 for non-MLO
-  * @count: the number of TBTTs until the channel switch happens
-  * @quiet: whether or not immediate quiet was requested by the AP
-+ * @punct_bitmap: the future puncturing bitmap
-  *
-  * Inform the userspace about the channel switch that has just
-  * started, so that it can take appropriate actions (eg. starting
-@@ -8345,7 +8347,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
- void cfg80211_ch_switch_started_notify(struct net_device *dev,
- 				       struct cfg80211_chan_def *chandef,
- 				       unsigned int link_id, u8 count,
--				       bool quiet);
-+				       bool quiet, u16 punct_bitmap);
- 
- /**
-  * ieee80211_operating_class_to_band - convert operating class to band
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 5bb43de..17d1e71 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -3597,7 +3597,8 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
- 	if (err)
- 		return err;
- 
--	cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0);
-+	cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0,
-+				  0);
- 
- 	return 0;
- }
-@@ -3869,7 +3870,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- 
- 	cfg80211_ch_switch_started_notify(sdata->dev,
- 					  &sdata->deflink.csa_chandef, 0,
--					  params->count, params->block_tx);
-+					  params->count, params->block_tx, 0);
- 
- 	if (changed) {
- 		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
-diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 2716ae0..d63434b 100644
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -1778,7 +1778,7 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_link_data *link)
- 		return;
- 	}
- 
--	cfg80211_ch_switch_notify(sdata->dev, &link->reserved_chandef, 0);
-+	cfg80211_ch_switch_notify(sdata->dev, &link->reserved_chandef, 0, 0);
- }
- 
- void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
-@@ -1988,7 +1988,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
- 	mutex_unlock(&local->mtx);
- 
- 	cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef, 0,
--					  csa_ie.count, csa_ie.mode);
-+					  csa_ie.count, csa_ie.mode, 0);
- 
- 	if (local->ops->channel_switch) {
- 		/* use driver's channel switch callback */
-diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 4cc095d..f3b2fc4 100644
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -18973,7 +18973,7 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
- 				     struct cfg80211_chan_def *chandef,
- 				     gfp_t gfp,
- 				     enum nl80211_commands notif,
--				     u8 count, bool quiet)
-+				     u8 count, bool quiet, u16 punct_bitmap)
- {
- 	struct wireless_dev *wdev = netdev->ieee80211_ptr;
- 	struct sk_buff *msg;
-@@ -19007,6 +19007,9 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
- 			goto nla_put_failure;
- 	}
- 
-+	if (nla_put_u32(msg, NL80211_ATTR_PUNCT_BITMAP, punct_bitmap))
-+		goto nla_put_failure;
-+
- 	genlmsg_end(msg, hdr);
- 
- 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
-@@ -19019,7 +19022,7 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
- 
- void cfg80211_ch_switch_notify(struct net_device *dev,
- 			       struct cfg80211_chan_def *chandef,
--			       unsigned int link_id)
-+			       unsigned int link_id, u16 punct_bitmap)
- {
- 	struct wireless_dev *wdev = dev->ieee80211_ptr;
- 	struct wiphy *wiphy = wdev->wiphy;
-@@ -19028,7 +19031,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
- 	ASSERT_WDEV_LOCK(wdev);
- 	WARN_INVALID_LINK_ID(wdev, link_id);
- 
--	trace_cfg80211_ch_switch_notify(dev, chandef, link_id);
-+	trace_cfg80211_ch_switch_notify(dev, chandef, link_id, punct_bitmap);
- 
- 	switch (wdev->iftype) {
- 	case NL80211_IFTYPE_STATION:
-@@ -19056,14 +19059,15 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
- 	cfg80211_sched_dfs_chan_update(rdev);
- 
- 	nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL,
--				 NL80211_CMD_CH_SWITCH_NOTIFY, 0, false);
-+				 NL80211_CMD_CH_SWITCH_NOTIFY, 0, false,
-+				 punct_bitmap);
- }
- EXPORT_SYMBOL(cfg80211_ch_switch_notify);
- 
- void cfg80211_ch_switch_started_notify(struct net_device *dev,
- 				       struct cfg80211_chan_def *chandef,
- 				       unsigned int link_id, u8 count,
--				       bool quiet)
-+				       bool quiet, u16 punct_bitmap)
- {
- 	struct wireless_dev *wdev = dev->ieee80211_ptr;
- 	struct wiphy *wiphy = wdev->wiphy;
-@@ -19072,11 +19076,13 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev,
- 	ASSERT_WDEV_LOCK(wdev);
- 	WARN_INVALID_LINK_ID(wdev, link_id);
- 
--	trace_cfg80211_ch_switch_started_notify(dev, chandef, link_id);
-+	trace_cfg80211_ch_switch_started_notify(dev, chandef, link_id,
-+						punct_bitmap);
-+
- 
- 	nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL,
- 				 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,
--				 count, quiet);
-+				 count, quiet, punct_bitmap);
- }
- EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
- 
-diff --git a/net/wireless/trace.h b/net/wireless/trace.h
-index 8e7c00f..4a7d0ae 100644
---- a/net/wireless/trace.h
-+++ b/net/wireless/trace.h
-@@ -3245,39 +3245,47 @@ TRACE_EVENT(cfg80211_chandef_dfs_required,
- TRACE_EVENT(cfg80211_ch_switch_notify,
- 	TP_PROTO(struct net_device *netdev,
- 		 struct cfg80211_chan_def *chandef,
--		 unsigned int link_id),
--	TP_ARGS(netdev, chandef, link_id),
-+		 unsigned int link_id,
-+		 u16 punct_bitmap),
-+	TP_ARGS(netdev, chandef, link_id, punct_bitmap),
- 	TP_STRUCT__entry(
- 		NETDEV_ENTRY
- 		CHAN_DEF_ENTRY
- 		__field(unsigned int, link_id)
-+		__field(u16, punct_bitmap)
- 	),
- 	TP_fast_assign(
- 		NETDEV_ASSIGN;
- 		CHAN_DEF_ASSIGN(chandef);
- 		__entry->link_id = link_id;
-+		__entry->punct_bitmap = punct_bitmap;
- 	),
--	TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d",
--		  NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id)
-+	TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d, punct_bitmap:%u",
-+		  NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id,
-+		  __entry->punct_bitmap)
- );
- 
- TRACE_EVENT(cfg80211_ch_switch_started_notify,
- 	TP_PROTO(struct net_device *netdev,
- 		 struct cfg80211_chan_def *chandef,
--		 unsigned int link_id),
--	TP_ARGS(netdev, chandef, link_id),
-+		 unsigned int link_id,
-+		 u16 punct_bitmap),
-+	TP_ARGS(netdev, chandef, link_id, punct_bitmap),
- 	TP_STRUCT__entry(
- 		NETDEV_ENTRY
- 		CHAN_DEF_ENTRY
- 		__field(unsigned int, link_id)
-+		__field(u16, punct_bitmap)
- 	),
- 	TP_fast_assign(
- 		NETDEV_ASSIGN;
- 		CHAN_DEF_ASSIGN(chandef);
- 		__entry->link_id = link_id;
-+		__entry->punct_bitmap = punct_bitmap;
- 	),
--	TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d",
--		  NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id)
-+	TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d, punct_bitmap:%u",
-+		  NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id,
-+		  __entry->punct_bitmap)
- );
- 
- TRACE_EVENT(cfg80211_radar_event,
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0008-wifi-mac80211-configure-puncturing-bitmap.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0008-wifi-mac80211-configure-puncturing-bitmap.patch
deleted file mode 100644
index 80c4b61..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0008-wifi-mac80211-configure-puncturing-bitmap.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From b5bdd1f773d65d640844f4b8a3e63c25057f1b46 Mon Sep 17 00:00:00 2001
-From: Aloka Dixit <quic_alokad@quicinc.com>
-Date: Mon, 30 Jan 2023 16:12:27 -0800
-Subject: [PATCH 8/9] wifi: mac80211: configure puncturing bitmap
-
-- Configure the bitmap in link_conf and notify the driver.
-- Modify 'change' in ieee80211_start_ap() from u32 to u64 to support
-BSS_CHANGED_EHT_PUNCTURING.
-- Propagate the bitmap in channel switch events to userspace.
-
-Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
-Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
-Link: https://lore.kernel.org/r/20230131001227.25014-5-quic_alokad@quicinc.com
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/mac80211.h |  3 +++
- net/mac80211/cfg.c     | 22 +++++++++++++++++++---
- 2 files changed, 22 insertions(+), 3 deletions(-)
-
-diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 8fb38c9..c4ff6a3 100644
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -645,6 +645,7 @@ struct ieee80211_fils_discovery {
-  * @csa_active: marks whether a channel switch is going on. Internally it is
-  *	write-protected by sdata_lock and local->mtx so holding either is fine
-  *	for read access.
-+ * @csa_punct_bitmap: new puncturing bitmap for channel switch
-  * @mu_mimo_owner: indicates interface owns MU-MIMO capability
-  * @chanctx_conf: The channel context this interface is assigned to, or %NULL
-  *	when it is not assigned. This pointer is RCU-protected due to the TX
-@@ -744,6 +745,8 @@ struct ieee80211_bss_conf {
- 	u16 eht_puncturing;
- 
- 	bool csa_active;
-+	u16 csa_punct_bitmap;
-+
- 	bool mu_mimo_owner;
- 	struct ieee80211_chanctx_conf __rcu *chanctx_conf;
- 
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 17d1e71..6defc1d 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1220,7 +1220,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
- 	struct ieee80211_local *local = sdata->local;
- 	struct beacon_data *old;
- 	struct ieee80211_sub_if_data *vlan;
--	u32 changed = BSS_CHANGED_BEACON_INT |
-+	u64 changed = BSS_CHANGED_BEACON_INT |
- 		      BSS_CHANGED_BEACON_ENABLED |
- 		      BSS_CHANGED_BEACON |
- 		      BSS_CHANGED_P2P_PS |
-@@ -1307,6 +1307,11 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
- 				IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO;
- 	}
- 
-+	if (params->eht_cap) {
-+		link_conf->eht_puncturing = params->punct_bitmap;
-+		changed |= BSS_CHANGED_EHT_PUNCTURING;
-+	}
-+
- 	if (sdata->vif.type == NL80211_IFTYPE_AP &&
- 	    params->mbssid_config.tx_wdev) {
- 		err = ieee80211_set_ap_mbssid_options(sdata,
-@@ -3556,6 +3561,12 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
- 	lockdep_assert_held(&local->mtx);
- 	lockdep_assert_held(&local->chanctx_mtx);
- 
-+	if (sdata->vif.bss_conf.eht_puncturing != sdata->vif.bss_conf.csa_punct_bitmap) {
-+		sdata->vif.bss_conf.eht_puncturing =
-+					sdata->vif.bss_conf.csa_punct_bitmap;
-+		changed |= BSS_CHANGED_EHT_PUNCTURING;
-+	}
-+
- 	/*
- 	 * using reservation isn't immediate as it may be deferred until later
- 	 * with multi-vif. once reservation is complete it will re-schedule the
-@@ -3598,7 +3609,7 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
- 		return err;
- 
- 	cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0,
--				  0);
-+				  sdata->vif.bss_conf.eht_puncturing);
- 
- 	return 0;
- }
-@@ -3860,9 +3871,13 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- 		goto out;
- 	}
- 
-+	if (params->punct_bitmap && !sdata->vif.bss_conf.eht_support)
-+		goto out;
-+
- 	sdata->deflink.csa_chandef = params->chandef;
- 	sdata->deflink.csa_block_tx = params->block_tx;
- 	sdata->vif.bss_conf.csa_active = true;
-+	sdata->vif.bss_conf.csa_punct_bitmap = params->punct_bitmap;
- 
- 	if (sdata->deflink.csa_block_tx)
- 		ieee80211_stop_vif_queues(local, sdata,
-@@ -3870,7 +3885,8 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- 
- 	cfg80211_ch_switch_started_notify(sdata->dev,
- 					  &sdata->deflink.csa_chandef, 0,
--					  params->count, params->block_tx, 0);
-+					  params->count, params->block_tx,
-+					  sdata->vif.bss_conf.csa_punct_bitmap);
- 
- 	if (changed) {
- 		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0009-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0009-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch
deleted file mode 100644
index 74c0d07..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/bp-0009-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 4244ed072fedc6f391ddad20fbc70bbb9dfb7c2c Mon Sep 17 00:00:00 2001
-From: Ryder Lee <ryder.lee@mediatek.com>
-Date: Sat, 18 Feb 2023 01:48:59 +0800
-Subject: [PATCH 9/9] wifi: mac80211: add EHT MU-MIMO related flags in
- ieee80211_bss_conf
-
-Similar to VHT/HE. This is utilized to pass MU-MIMO configurations
-from user space (i.e. hostapd) to driver.
-
-Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
-Link: https://lore.kernel.org/r/8d9966c4c1e77cb1ade77d42bdc49905609192e9.1676628065.git.ryder.lee@mediatek.com
-[move into combined if statement, reset on !eht]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
- include/net/mac80211.h |  9 +++++++++
- net/mac80211/cfg.c     | 16 ++++++++++++++++
- 2 files changed, 25 insertions(+)
-
-diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index c4ff6a3..24d2a66 100644
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -676,6 +676,12 @@ struct ieee80211_fils_discovery {
-  * @he_full_ul_mumimo: does this BSS support the reception (AP) or transmission
-  *	(non-AP STA) of an HE TB PPDU on an RU that spans the entire PPDU
-  *	bandwidth
-+ * @eht_su_beamformer: in AP-mode, does this BSS enable operation as an EHT SU
-+ *	beamformer
-+ * @eht_su_beamformee: in AP-mode, does this BSS enable operation as an EHT SU
-+ *	beamformee
-+ * @eht_mu_beamformer: in AP-mode, does this BSS enable operation as an EHT MU
-+ *	beamformer
-  */
- struct ieee80211_bss_conf {
- 	const u8 *bssid;
-@@ -764,6 +770,9 @@ struct ieee80211_bss_conf {
- 	bool he_su_beamformee;
- 	bool he_mu_beamformer;
- 	bool he_full_ul_mumimo;
-+	bool eht_su_beamformer;
-+	bool eht_su_beamformee;
-+	bool eht_mu_beamformer;
- };
- 
- /**
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 6defc1d..49760bf 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1310,6 +1310,22 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
- 	if (params->eht_cap) {
- 		link_conf->eht_puncturing = params->punct_bitmap;
- 		changed |= BSS_CHANGED_EHT_PUNCTURING;
-+
-+		link_conf->eht_su_beamformer =
-+			params->eht_cap->fixed.phy_cap_info[0] &
-+				IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER;
-+		link_conf->eht_su_beamformee =
-+			params->eht_cap->fixed.phy_cap_info[0] &
-+				IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
-+		link_conf->eht_mu_beamformer =
-+			params->eht_cap->fixed.phy_cap_info[7] &
-+				(IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ |
-+				 IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ |
-+				 IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ);
-+	} else {
-+		link_conf->eht_su_beamformer = false;
-+		link_conf->eht_su_beamformee = false;
-+		link_conf->eht_mu_beamformer = false;
- 	}
- 
- 	if (sdata->vif.type == NL80211_IFTYPE_AP &&
--- 
-2.39.2
-
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-mac80211-mtk-do-not-setup-twt-when-twt-responder-is-.patch
index c75457d..c52c759 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-mac80211-mtk-do-not-setup-twt-when-twt-responder-is-.patch
@@ -1,7 +1,7 @@
-From 635092a3fd448ecca927e72882f05dc52bb1d21b Mon Sep 17 00:00:00 2001
+From 5369b107bbb17d2152f7690f3fc91a135f05a88c 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/14] mac80211: mtk: do not setup twt when twt responder is
+Subject: [PATCH 01/21] mac80211: mtk: 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 fadf2be..54dcaf6 100644
+index 8ffe90d..56abe67 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3400,6 +3400,9 @@ ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
+@@ -3416,6 +3416,9 @@ ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
  	if (sdata->vif.type != NL80211_IFTYPE_AP)
  		return false;
  
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-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch
index e3288e4..2a60dc4 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-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch
@@ -1,7 +1,8 @@
-From a1d6921a833c7d85170cb54145bfcf98d7f11283 Mon Sep 17 00:00:00 2001
+From 9b4ed2d99cc24c50bef088ee2bc48047d4e17c97 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] cfg80211: mtk: extend CAC time for weather radar channels
+Subject: [PATCH 02/21] cfg80211: mtk: extend CAC time for weather radar
+ channels
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -12,7 +13,7 @@
  3 files changed, 11 insertions(+)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 98a2971..28c0a5f 100644
+index 3e0a190..32df498 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
 @@ -149,6 +149,7 @@ enum ieee80211_channel_flags {
@@ -24,7 +25,7 @@
  
  /**
 diff --git a/net/wireless/chan.c b/net/wireless/chan.c
-index d5ed976..62f0169 100644
+index d5ed976..caa5acc 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,
@@ -42,10 +43,10 @@
  			dfs_cac_ms = c->dfs_cac_ms;
  	}
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index f3b2fc4..215a603 100644
+index 6d62c81..3ec073a 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -9817,6 +9817,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+@@ -9992,6 +9992,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
  	if (WARN_ON(!cac_time_ms))
  		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
  
@@ -56,5 +57,5 @@
  	if (!err) {
  		wdev->links[0].ap.chandef = chandef;
 -- 
-2.18.0
+2.39.2
 
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-mac80211-mtk-it-s-invalid-case-when-frag_threshold-i.patch
index b31ba64..a68441f 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-mac80211-mtk-it-s-invalid-case-when-frag_threshold-i.patch
@@ -1,7 +1,7 @@
-From efac6783560b2859f49f0a5d3dceff0e388431cf Mon Sep 17 00:00:00 2001
+From 395e1cebc680455965b24fe771efaae400439acc 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/14] mac80211: mtk: it's invalid case when frag_threshold is
+Subject: [PATCH 03/21] mac80211: mtk: it's invalid case when frag_threshold is
  greater than 2346
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 3 insertions(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 0430bbe..c5620f3 100644
+index 3ec073a..e0ee534 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -3614,6 +3614,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+@@ -3650,6 +3650,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
  			goto out;
  		}
  
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
index 5a81d9b..5eb6ee7 100644
--- 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
@@ -1,7 +1,7 @@
-From f88d59e107e1d962ebf77be9e1d0b35b188c8185 Mon Sep 17 00:00:00 2001
+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/14] mac80211: mtk: airtime_flags depends on
+Subject: [PATCH 04/21] mac80211: mtk: airtime_flags depends on
  NL80211_EXT_FEATURE
 
 Signed-off-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 3 insertions(+), 2 deletions(-)
 
 diff --git a/net/mac80211/main.c b/net/mac80211/main.c
-index dfb9f4b..06d111d 100644
+index e2f7ae5..0188e6a 100644
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
-@@ -797,8 +797,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
+@@ -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);
  	}
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-0005-mac80211-mtk-add-support-for-runtime-set-inband-disc.patch
index 0bbbfe0..66a784d 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-0005-mac80211-mtk-add-support-for-runtime-set-inband-disc.patch
@@ -1,23 +1,22 @@
-From 5deaaa36bfeb7a68bbcce8770011ef49be6a6991 Mon Sep 17 00:00:00 2001
+From f6907ff7ff3669e73f64f802de10346bfd1d24d8 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 05/14] mac80211: mtk: add support for runtime set inband
- discovery
+Subject: [PATCH] mac80211: mtk: add support for runtime set inband discovery
 
 Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
 ---
  include/net/cfg80211.h       |  1 +
  include/net/mac80211.h       |  1 +
  include/uapi/linux/nl80211.h |  1 +
- net/mac80211/cfg.c           | 33 ++++++++++++++++++++++++++++++++-
- net/wireless/nl80211.c       | 31 +++++++++++++++++++++++++++----
- 5 files changed, 62 insertions(+), 5 deletions(-)
+ net/mac80211/cfg.c           | 30 +++++++++++++++++++++++++++++-
+ net/wireless/nl80211.c       | 33 ++++++++++++++++++++++++++++-----
+ 5 files changed, 60 insertions(+), 6 deletions(-)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 8d72357..450de58 100644
+index 072a787..02e342e 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -1268,6 +1268,7 @@ struct cfg80211_fils_discovery {
+@@ -1309,6 +1309,7 @@ struct cfg80211_fils_discovery {
  	u32 max_interval;
  	size_t tmpl_len;
  	const u8 *tmpl;
@@ -26,7 +25,7 @@
  
  /**
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 24d2a66..09fad2b 100644
+index 2e5b5c6..96e4ec9 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
 @@ -526,6 +526,7 @@ struct ieee80211_ftm_responder_params {
@@ -38,10 +37,10 @@
  
  /**
 diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
-index 173aef8..bd26a06 100644
+index 88eb85c..72ef4d9 100644
 --- a/include/uapi/linux/nl80211.h
 +++ b/include/uapi/linux/nl80211.h
-@@ -7513,6 +7513,7 @@ enum nl80211_fils_discovery_attributes {
+@@ -7619,6 +7619,7 @@ enum nl80211_fils_discovery_attributes {
  	NL80211_FILS_DISCOVERY_ATTR_INT_MIN,
  	NL80211_FILS_DISCOVERY_ATTR_INT_MAX,
  	NL80211_FILS_DISCOVERY_ATTR_TMPL,
@@ -50,10 +49,10 @@
  	/* keep last */
  	__NL80211_FILS_DISCOVERY_ATTR_LAST,
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 49760bf..97f7905 100644
+index f4649d1..baff0e6 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -984,6 +984,7 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
+@@ -990,6 +990,7 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
  	fd = &link_conf->fils_discovery;
  	fd->min_interval = params->min_interval;
  	fd->max_interval = params->max_interval;
@@ -61,23 +60,23 @@
  
  	old = sdata_dereference(link->u.ap.fils_discovery, sdata);
  	new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
-@@ -1466,6 +1467,9 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
+@@ -1513,9 +1514,11 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
  	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  	struct ieee80211_link_data *link;
  	struct beacon_data *old;
 +	struct cfg80211_ap_settings *ap_params;
 +	struct ieee80211_supported_band *sband;
-+	u32 changed;
++	u64 changed = 0;
  	int err;
  	struct ieee80211_bss_conf *link_conf;
+-	u64 changed = 0;
  
-@@ -1497,7 +1501,34 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
- 		err |= BSS_CHANGED_HE_BSS_COLOR;
+ 	sdata_assert_lock(sdata);
+ 
+@@ -1546,6 +1549,31 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
+ 		changed |= BSS_CHANGED_HE_BSS_COLOR;
  	}
  
--	ieee80211_link_info_change_notify(sdata, link, err);
-+	changed = err;
-+
 +	sband = ieee80211_get_sband(sdata);
 +	if (!sband)
 +		return -EINVAL;
@@ -103,12 +102,11 @@
 +		}
 +	}
 +
-+	ieee80211_bss_info_change_notify(sdata, changed);
+ 	ieee80211_link_info_change_notify(sdata, link, changed);
  	return 0;
  }
- 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index c5620f3..95676d9 100644
+index e0ee534..ff8afa5 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] = {
@@ -119,7 +117,7 @@
  };
  
  static const struct nla_policy
-@@ -5605,6 +5606,8 @@ static int nl80211_parse_fils_discovery(struct cfg80211_registered_device *rdev,
+@@ -5692,6 +5693,8 @@ static int nl80211_parse_fils_discovery(struct cfg80211_registered_device *rdev,
  	fd->tmpl = nla_data(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
  	fd->min_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN]);
  	fd->max_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX]);
@@ -128,7 +126,7 @@
  
  	return 0;
  }
-@@ -6092,7 +6095,8 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
+@@ -6224,7 +6227,8 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
  	unsigned int link_id = nl80211_link_id(info->attrs);
  	struct net_device *dev = info->user_ptr[1];
  	struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -138,15 +136,15 @@
  	int err;
  
  	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
-@@ -6105,16 +6109,35 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
+@@ -6237,17 +6241,36 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
  	if (!wdev->links[link_id].ap.beacon_interval)
  		return -EINVAL;
  
--	err = nl80211_parse_beacon(rdev, info->attrs, &params);
+-	err = nl80211_parse_beacon(rdev, info->attrs, &params, info->extack);
 +	memset(&ap_params, 0, sizeof(ap_params));
 +	params = &ap_params.beacon;
 +
-+	err = nl80211_parse_beacon(rdev, info->attrs, params);
++	err = nl80211_parse_beacon(rdev, info->attrs, params, info->extack);
  	if (err)
  		goto out;
  
@@ -173,10 +171,12 @@
  
  out:
 -	kfree(params.mbssid_ies);
+-	kfree(params.rnr_ies);
 +	kfree(params->mbssid_ies);
++	kfree(params->rnr_ies);
  	return err;
  }
  
 -- 
-2.39.2
+2.25.1
 
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-0006-cfg80211-mtk-implement-DFS-status-show-cac-and-nop-s.patch
index 4072a92..b2408ad 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-0006-cfg80211-mtk-implement-DFS-status-show-cac-and-nop-s.patch
@@ -1,8 +1,8 @@
-From dc8caecd0c7f5dfd542ba08f98605a7d6849e110 Mon Sep 17 00:00:00 2001
+From cbb9327b27651e375f72783e9c2453a2474f3ad3 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] cfg80211: mtk: implement DFS status show, cac and nop skip
- command via debugfs
+Subject: [PATCH 06/21] cfg80211: mtk: implement DFS status show, cac and nop
+ skip command via debugfs
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -16,23 +16,23 @@
  7 files changed, 360 insertions(+), 7 deletions(-)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 450de58..ddd63e7 100644
+index 7ba5fe9..cd0ec8a 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -4647,6 +4647,7 @@ struct cfg80211_ops {
- 				    struct link_station_parameters *params);
- 	int	(*del_link_station)(struct wiphy *wiphy, struct net_device *dev,
+@@ -4768,6 +4768,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);
 +	void	(*skip_cac)(struct wireless_dev *wdev);
  };
  
  /*
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 97f7905..36a2c8d 100644
+index a78ee52..8033b2f 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -4962,6 +4962,25 @@ ieee80211_del_link_station(struct wiphy *wiphy, struct net_device *dev,
- 	return ret;
+@@ -5049,6 +5049,25 @@ static int ieee80211_set_hw_timestamp(struct wiphy *wiphy,
+ 	return local->ops->set_hw_timestamp(&local->hw, &sdata->vif, hwts);
  }
  
 +static void
@@ -57,14 +57,14 @@
  const struct cfg80211_ops mac80211_config_ops = {
  	.add_virtual_intf = ieee80211_add_iface,
  	.del_virtual_intf = ieee80211_del_iface,
-@@ -5072,4 +5091,5 @@ const struct cfg80211_ops mac80211_config_ops = {
- 	.add_link_station = ieee80211_add_link_station,
+@@ -5161,4 +5180,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,
 +	.skip_cac = ieee80211_skip_cac,
  };
 diff --git a/net/wireless/core.h b/net/wireless/core.h
-index 382455c..c9d7712 100644
+index 70fc2e6..ea1b6ff 100644
 --- a/net/wireless/core.h
 +++ b/net/wireless/core.h
 @@ -86,6 +86,9 @@ struct cfg80211_registered_device {
@@ -410,10 +410,10 @@
 +	DEBUGFS_ADD(dfs_available_reset, 0600);
  }
 diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
-index 5a63dba..57b9bde 100644
+index 8b87bc9..e3cbfc0 100644
 --- a/net/wireless/mlme.c
 +++ b/net/wireless/mlme.c
-@@ -1030,13 +1030,16 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
+@@ -1054,13 +1054,16 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
  		queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
  		cfg80211_sched_dfs_chan_update(rdev);
  		wdev = rdev->background_radar_wdev;
@@ -430,7 +430,7 @@
  		break;
  	default:
  		return;
-@@ -1056,6 +1059,7 @@ cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
+@@ -1080,6 +1083,7 @@ cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
  					chandef, event);
  	wiphy_unlock(&rdev->wiphy);
  }
@@ -438,7 +438,7 @@
  
  void cfg80211_background_cac_done_wk(struct work_struct *work)
  {
-@@ -1117,8 +1121,10 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
+@@ -1141,8 +1145,10 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
  	if (!cac_time_ms)
  		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
  
@@ -450,13 +450,14 @@
  	__cfg80211_background_cac_event(rdev, wdev, chandef,
  					NL80211_RADAR_CAC_STARTED);
 diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
-index ca29892..ce83152 100644
+index 72c1282..5a4854c 100644
 --- a/net/wireless/rdev-ops.h
 +++ b/net/wireless/rdev-ops.h
-@@ -1494,4 +1494,18 @@ rdev_del_link_station(struct cfg80211_registered_device *rdev,
+@@ -1524,4 +1524,18 @@ rdev_set_hw_timestamp(struct cfg80211_registered_device *rdev,
+ 
  	return ret;
  }
- 
++
 +static inline int
 +rdev_skip_cac(struct cfg80211_registered_device *rdev,
 +	      struct wireless_dev *wdev)
@@ -470,14 +471,13 @@
 +
 +	return 0;
 +}
-+
  #endif /* __CFG80211_RDEV_OPS */
 diff --git a/net/wireless/trace.h b/net/wireless/trace.h
-index 4a7d0ae..4d44c55 100644
+index fc955a9..01dcfd3 100644
 --- a/net/wireless/trace.h
 +++ b/net/wireless/trace.h
-@@ -3909,6 +3909,18 @@ TRACE_EVENT(rdev_del_link_station,
- 		  __entry->link_id)
+@@ -3981,6 +3981,18 @@ TRACE_EVENT(cfg80211_links_removed,
+ 		  __entry->link_mask)
  );
  
 +TRACE_EVENT(rdev_skip_cac,
@@ -496,5 +496,5 @@
  
  #undef TRACE_INCLUDE_PATH
 -- 
-2.18.0
+2.39.2
 
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-0007-mac80211-mtk-Set-TWT-Information-Frame-Disabled-bit-.patch
index 0b33292..5276b39 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-0007-mac80211-mtk-Set-TWT-Information-Frame-Disabled-bit-.patch
@@ -1,7 +1,7 @@
-From f6619b6ecec6122b107fa3c3c9bb0e2a4ceaba87 Mon Sep 17 00:00:00 2001
+From c1fac970b782b1d6786f3ec59abc995d84374ceb 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/14] mac80211: mtk: Set TWT Information Frame Disabled bit
+Subject: [PATCH 07/21] mac80211: mtk: Set TWT Information Frame Disabled bit
  as 1.
 
 This modification means that current implementation do not support twt information frame.
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-0008-mac80211-mtk-check-the-control-channel-before-downgr.patch
index 685e0b7..6c614fe 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-0008-mac80211-mtk-check-the-control-channel-before-downgr.patch
@@ -1,7 +1,7 @@
-From 74dec28f086c6d919d936fb159bfb3fada5f4ca7 Mon Sep 17 00:00:00 2001
+From cc5889f25d7d72cf4ecbaefbe885ad654d50e730 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/14] mac80211: mtk: check the control channel before
+Subject: [PATCH 08/21] mac80211: mtk: check the control channel before
  downgrading the bandwidth
 
 ---
@@ -9,11 +9,11 @@
  1 file changed, 23 insertions(+)
 
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index d63434b..72d153f 100644
+index f93eb38..86f762d 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
-@@ -4657,6 +4657,26 @@ ieee80211_verify_sta_he_mcs_support(struct ieee80211_sub_if_data *sdata,
- 	return false;
+@@ -4791,6 +4791,26 @@ ieee80211_verify_sta_eht_mcs_support(struct ieee80211_sub_if_data *sdata,
+ 	return true;
  }
  
 +static bool ieee80211_check_same_ctrl_channel(struct ieee80211_sub_if_data *sdata,
@@ -39,7 +39,7 @@
  static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
  				  struct ieee80211_link_data *link,
  				  struct cfg80211_bss *cbss,
-@@ -4883,6 +4903,9 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
+@@ -5033,6 +5053,9 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
  	    chandef.width == NL80211_CHAN_WIDTH_10)
  		goto out;
  
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-0009-mac80211-mtk-fix-tx-amsdu-aggregation.patch
index fd2295f..a505811 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-0009-mac80211-mtk-fix-tx-amsdu-aggregation.patch
@@ -1,7 +1,7 @@
-From e12f4ecc226a21580958bcbb2f418ae979e49a36 Mon Sep 17 00:00:00 2001
+From 3a7bbbffc4870e413856f3f3d7e54066117d13ed 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/14] mac80211: mtk: fix tx amsdu aggregation
+Subject: [PATCH 09/21] mac80211: mtk: fix tx amsdu aggregation
 
 ---
  include/net/mac80211.h | 7 +++++++
@@ -9,10 +9,10 @@
  2 files changed, 11 insertions(+), 2 deletions(-)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 09fad2b..bd257ce 100644
+index 96e4ec9..eb229aa 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -2905,6 +2905,13 @@ static inline void _ieee80211_hw_set(struct ieee80211_hw *hw,
+@@ -2921,6 +2921,13 @@ static inline void _ieee80211_hw_set(struct ieee80211_hw *hw,
  }
  #define ieee80211_hw_set(hw, flg)	_ieee80211_hw_set(hw, IEEE80211_HW_##flg)
  
@@ -27,7 +27,7 @@
   * struct ieee80211_scan_request - hw scan request
   *
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 6597607..752ad09 100644
+index b6b7726..80cd642 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
 @@ -66,7 +66,8 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
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-0010-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-id.patch
index a160e14..d121c4f 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-0010-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-id.patch
@@ -1,7 +1,7 @@
-From ea115965135f78dc8993f1a73a0600fb5b83cdf7 Mon Sep 17 00:00:00 2001
+From 66fbfef0e7ae77359c9609aeec93a31463af59b4 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/14] mac80211: mtk: add fill receive path ops to get wed idx
+Subject: [PATCH 10/21] mac80211: mtk: add fill receive path ops to get wed idx
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
@@ -12,10 +12,10 @@
  4 files changed, 50 insertions(+)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index bd257ce..9208a8d 100644
+index eb229aa..2c282e6 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -4226,6 +4226,8 @@ struct ieee80211_prep_tx_info {
+@@ -4255,6 +4255,8 @@ struct ieee80211_prep_tx_info {
   *	disable background CAC/radar detection.
   * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to
   *	resolve a path for hardware flow offloading
@@ -24,7 +24,7 @@
   * @change_vif_links: Change the valid links on an interface, note that while
   *	removing the old link information is still valid (link_conf pointer),
   *	but may immediately disappear after the function returns. The old or
-@@ -4591,6 +4593,9 @@ struct ieee80211_ops {
+@@ -4631,6 +4633,9 @@ struct ieee80211_ops {
  				     struct ieee80211_sta *sta,
  				     struct net_device_path_ctx *ctx,
  				     struct net_device_path *path);
@@ -35,10 +35,10 @@
  				struct ieee80211_vif *vif,
  				u16 old_links, u16 new_links,
 diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
-index 37f428e..b076658 100644
+index 650d8d1..d187206 100644
 --- a/net/mac80211/driver-ops.h
 +++ b/net/mac80211/driver-ops.h
-@@ -1485,6 +1485,19 @@ static inline int drv_net_fill_forward_path(struct ieee80211_local *local,
+@@ -1519,6 +1519,19 @@ static inline int drv_net_fill_forward_path(struct ieee80211_local *local,
  	return ret;
  }
  
@@ -59,10 +59,10 @@
  				   struct ieee80211_sub_if_data *sdata,
  				   struct net_device *dev,
 diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index a18f80d..b82065c 100644
+index be586bc..b8dfd32 100644
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
-@@ -936,6 +936,28 @@ out:
+@@ -930,6 +930,28 @@ out:
  	return ret;
  }
  
@@ -91,7 +91,7 @@
  static const struct net_device_ops ieee80211_dataif_8023_ops = {
  	.ndo_open		= ieee80211_open,
  	.ndo_stop		= ieee80211_stop,
-@@ -945,6 +967,7 @@ static const struct net_device_ops ieee80211_dataif_8023_ops = {
+@@ -939,6 +961,7 @@ static const struct net_device_ops ieee80211_dataif_8023_ops = {
  	.ndo_set_mac_address	= ieee80211_change_mac,
  	.ndo_get_stats64	= ieee80211_get_stats64,
  	.ndo_fill_forward_path	= ieee80211_netdev_fill_forward_path,
@@ -100,10 +100,10 @@
  };
  
 diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index 5a6c091..f6a2561 100644
+index 8a6917c..3650dcd 100644
 --- a/net/mac80211/util.c
 +++ b/net/mac80211/util.c
-@@ -888,6 +888,15 @@ struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
+@@ -868,6 +868,15 @@ struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
  }
  EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev);
  
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-0011-mac80211-mtk-fix-build-error-on-Linux-Kernel-5.4.patch
index 17a5248..a75e19c 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-0011-mac80211-mtk-fix-build-error-on-Linux-Kernel-5.4.patch
@@ -1,17 +1,17 @@
-From ecf81145d85cc3d991d360d283b83a0e91ecf1da Mon Sep 17 00:00:00 2001
+From d0528e1e6fffdb620314bb7934cdab4971e02e77 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/14] mac80211: mtk: fix build error on Linux Kernel 5.4
+Subject: [PATCH 11/21] mac80211: mtk: fix build error on Linux Kernel 5.4
 
 ---
- include/linux/ieee80211.h          | 8 +++-----
- net/mac80211/rc80211_minstrel_ht.c | 2 ++
- net/mac80211/wpa.c                 | 4 ++--
- net/wireless/nl80211.c             | 4 ++++
- 4 files changed, 11 insertions(+), 7 deletions(-)
+ include/linux/ieee80211.h          |  8 +++-----
+ net/mac80211/rc80211_minstrel_ht.c |  2 ++
+ net/mac80211/wpa.c                 |  4 ++--
+ net/wireless/nl80211.c             | 12 +++++-------
+ 4 files changed, 12 insertions(+), 14 deletions(-)
 
 diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
-index d15816f..00d381e 100644
+index 4b99809..7aaae32 100644
 --- a/include/linux/ieee80211.h
 +++ b/include/linux/ieee80211.h
 @@ -310,11 +310,9 @@ static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2)
@@ -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 33001ec..277fec9 100644
+index e916130..c09147f 100644
 --- a/net/mac80211/rc80211_minstrel_ht.c
 +++ b/net/mac80211/rc80211_minstrel_ht.c
 @@ -10,7 +10,9 @@
@@ -66,10 +66,32 @@
  
  
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 95676d9..6f1d60a 100644
+index ff8afa5..0ed3f51 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -16457,9 +16457,11 @@ static const struct genl_ops nl80211_ops[] = {
+@@ -461,11 +461,6 @@ nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
+ 	[NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
+ };
+ 
+-static struct netlink_range_validation nl80211_punct_bitmap_range = {
+-	.min = 0,
+-	.max = 0xffff,
+-};
+-
+ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
+ 	[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
+@@ -805,8 +800,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+ 	[NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
+ 	[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
+ 	[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
+-	[NL80211_ATTR_PUNCT_BITMAP] =
+-		NLA_POLICY_FULL_RANGE(NLA_U32, &nl80211_punct_bitmap_range),
++	[NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff),
+ 
+ 	[NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 },
+ 	[NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
+@@ -16687,9 +16681,11 @@ static const struct genl_ops nl80211_ops[] = {
  		/* can be retrieved by unprivileged users */
  		.internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
  	},
@@ -81,7 +103,7 @@
  	{
  		.cmd = NL80211_CMD_SET_WIPHY,
  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
-@@ -17296,8 +17298,10 @@ static struct genl_family nl80211_fam __genl_ro_after_init = {
+@@ -17534,8 +17530,10 @@ static struct genl_family nl80211_fam __genl_ro_after_init = {
  	.module = THIS_MODULE,
  	.ops = nl80211_ops,
  	.n_ops = ARRAY_SIZE(nl80211_ops),
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-0012-mac80211-mtk-track-obss-color-bitmap.patch
index 607670c..31811d3 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-0012-mac80211-mtk-track-obss-color-bitmap.patch
@@ -1,7 +1,7 @@
-From a7b0e17e0dafe6cfe58f88465006cd0c9e7c3217 Mon Sep 17 00:00:00 2001
+From 529ea5156b39398b24801eabcb3f1531ca53d3ca 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/14] mac80211: mtk: track obss color bitmap
+Subject: [PATCH 12/21] mac80211: mtk: track obss color bitmap
 
 Track OBSS BSS color when receive their beacon.
 
@@ -9,17 +9,16 @@
 echo 1 > /sys/kernel/debug/tracing/events/mac80211/bss_color_bitmap/enable
 echo 1 > /sys/kernel/debug/tracing/events/mac80211/bss_color_collision/enable
 ---
- include/net/mac80211.h |  5 +++--
- net/mac80211/cfg.c     |  4 ++--
- net/mac80211/rx.c      |  9 +++++++--
+ include/net/mac80211.h |  1 +
+ net/mac80211/rx.c      |  6 +++++-
  net/mac80211/trace.h   | 21 +++++++++++++++++++++
- 4 files changed, 33 insertions(+), 6 deletions(-)
+ 3 files changed, 27 insertions(+), 1 deletion(-)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 9208a8d..299425a 100644
+index 2c282e6..b90e828 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -741,6 +741,7 @@ struct ieee80211_bss_conf {
+@@ -744,6 +744,7 @@ struct ieee80211_bss_conf {
  	} he_oper;
  	struct ieee80211_he_obss_pd he_obss_pd;
  	struct cfg80211_he_bss_color he_bss_color;
@@ -27,72 +26,30 @@
  	struct ieee80211_fils_discovery fils_discovery;
  	u32 unsol_bcast_probe_resp_interval;
  	struct cfg80211_bitrate_mask beacon_tx_rate;
-@@ -7269,7 +7270,7 @@ ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
- 					  struct ieee80211_vif *vif);
- 
- /**
-- * ieeee80211_obss_color_collision_notify - notify userland about a BSS color
-+ * ieee80211_obss_color_collision_notify - notify userland about a BSS color
-  * collision.
-  *
-  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-@@ -7278,7 +7279,7 @@ ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
-  * @gfp: allocation flags
-  */
- void
--ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
-+ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
- 				       u64 color_bitmap, gfp_t gfp);
- 
- /**
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 36a2c8d..0ecc026 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -4750,7 +4750,7 @@ void ieee80211_color_change_finish(struct ieee80211_vif *vif)
- EXPORT_SYMBOL_GPL(ieee80211_color_change_finish);
- 
- void
--ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
-+ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
- 				       u64 color_bitmap, gfp_t gfp)
- {
- 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-@@ -4770,7 +4770,7 @@ ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
- 				     &link->color_collision_detect_work,
- 				     msecs_to_jiffies(500));
- }
--EXPORT_SYMBOL_GPL(ieeee80211_obss_color_collision_notify);
-+EXPORT_SYMBOL_GPL(ieee80211_obss_color_collision_notify);
- 
- static int
- ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 54dcaf6..0048c22 100644
+index 56abe67..cf41b93 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3338,9 +3338,14 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
+@@ -3349,9 +3349,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);
 +
 +		bss_conf->used_color_bitmap |= BIT_ULL(color);
 +
-+		trace_bss_color_bitmap(color, bss_conf->used_color_bitmap);
-+
++		// trace_bss_color_bitmap(color, bss_conf->used_color_bitmap);
  		if (color == bss_conf->he_bss_color.color)
--			ieeee80211_obss_color_collision_notify(&rx->sdata->vif,
--							       BIT_ULL(color),
-+			ieee80211_obss_color_collision_notify(&rx->sdata->vif,
-+							       bss_conf->used_color_bitmap,
- 							       GFP_ATOMIC);
+ 			ieee80211_obss_color_collision_notify(&rx->sdata->vif,
+-							      BIT_ULL(color),
++							      bss_conf->used_color_bitmap,
+ 							      GFP_ATOMIC);
  	}
  }
 diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
-index de5d69f..cad6597 100644
+index b8c53b4..814aed6 100644
 --- a/net/mac80211/trace.h
 +++ b/net/mac80211/trace.h
-@@ -3058,6 +3058,27 @@ TRACE_EVENT(stop_queue,
+@@ -3060,6 +3060,27 @@ TRACE_EVENT(stop_queue,
  	)
  );
  
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-0013-mac80211-mtk-ageout-color-bitmap.patch
index 34e1f5c..4531d85 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-0013-mac80211-mtk-ageout-color-bitmap.patch
@@ -1,7 +1,7 @@
-From dd1fc5e8ea8df5f6a5e0b87957872053d13b3278 Mon Sep 17 00:00:00 2001
+From 31b5d2289d106c9d0f55ea501182080ca1d52a72 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] mac80211: mtk: ageout color bitmap
+Subject: [PATCH 13/21] mac80211: mtk: 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.
@@ -11,14 +11,14 @@
  net/mac80211/ieee80211_i.h |  5 +++++
  net/mac80211/iface.c       |  5 +++++
  net/mac80211/link.c        |  2 ++
- net/mac80211/rx.c          |  3 ++-
- 6 files changed, 45 insertions(+), 1 deletion(-)
+ net/mac80211/rx.c          |  1 +
+ 6 files changed, 44 insertions(+)
 
 diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-index 299425a..b4f156e 100644
+index b90e828..6ff6d3a 100644
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -742,6 +742,7 @@ struct ieee80211_bss_conf {
+@@ -745,6 +745,7 @@ struct ieee80211_bss_conf {
  	struct ieee80211_he_obss_pd he_obss_pd;
  	struct cfg80211_he_bss_color he_bss_color;
  	u64 used_color_bitmap;
@@ -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 0ecc026..3c83024 100644
+index 8033b2f..177409d 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -4817,6 +4817,36 @@ out:
+@@ -4881,6 +4881,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 04128d5..bf2c51e 100644
+index 7ca2482..1fa9641 100644
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -989,6 +989,7 @@ struct ieee80211_link_data {
+@@ -996,6 +996,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 */
-@@ -1932,9 +1933,13 @@ void ieee80211_csa_finalize_work(struct work_struct *work);
+@@ -1993,9 +1994,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);
  
@@ -94,7 +94,7 @@
  /* interface handling */
  #define MAC80211_SUPPORTED_FEATURES_TX	(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
 diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index b82065c..6a300ab 100644
+index b8dfd32..e5b5e74 100644
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
 @@ -541,6 +541,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
@@ -105,7 +105,7 @@
  
  	if (sdata->wdev.cac_started) {
  		chandef = sdata->vif.bss_conf.chandef;
-@@ -1470,6 +1471,10 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
+@@ -1474,6 +1475,10 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
  
  	set_bit(SDATA_STATE_RUNNING, &sdata->state);
  
@@ -117,10 +117,10 @@
   err_del_interface:
  	drv_remove_interface(local, sdata);
 diff --git a/net/mac80211/link.c b/net/mac80211/link.c
-index a1b3031..7d4cdfb 100644
+index 6148208..2f64b69 100644
 --- a/net/mac80211/link.c
 +++ b/net/mac80211/link.c
-@@ -45,6 +45,8 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
+@@ -47,6 +47,8 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
  	INIT_LIST_HEAD(&link->reserved_chanctx_list);
  	INIT_DELAYED_WORK(&link->dfs_cac_timer_work,
  			  ieee80211_dfs_cac_timer_work);
@@ -130,20 +130,17 @@
  	if (!deflink) {
  		switch (sdata->vif.type) {
 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 0048c22..6b0fb01 100644
+index cf41b93..e245f31 100644
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -3340,8 +3340,9 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
+@@ -3351,6 +3351,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);
 +		bss_conf->color_last_seen[color] = jiffies;
  
--		trace_bss_color_bitmap(color, bss_conf->used_color_bitmap);
-+		/* trace_bss_color_bitmap(color, bss_conf->used_color_bitmap); */
- 
+ 		// trace_bss_color_bitmap(color, bss_conf->used_color_bitmap);
  		if (color == bss_conf->he_bss_color.color)
- 			ieee80211_obss_color_collision_notify(&rx->sdata->vif,
 -- 
 2.39.2
 
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
index 205d30d..8d2b34d 100644
--- 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
@@ -1,7 +1,7 @@
-From 869bb0c749acc325ea6ecbf7513a90159d426602 Mon Sep 17 00:00:00 2001
+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/14] mac80211: mtk: update max_bssid_indicator based on real
+Subject: [PATCH 14/21] mac80211: mtk: update max_bssid_indicator based on real
  BSS numbers
 
 ---
@@ -9,12 +9,12 @@
  1 file changed, 1 insertion(+), 2 deletions(-)
 
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 3c83024..d5ffa64 100644
+index 177409d..9724258 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1152,8 +1152,7 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
- 		pos += struct_size(new->mbssid_ies, elem, mbssid->cnt);
- 		ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies, mbssid);
+@@ -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));
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mac80211-support-configurable-addba-resp-time.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-support-configurable-addba-resp-time.patch
similarity index 80%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mac80211-support-configurable-addba-resp-time.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-support-configurable-addba-resp-time.patch
index 759d36b..de32d4e 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mac80211-support-configurable-addba-resp-time.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-support-configurable-addba-resp-time.patch
@@ -1,14 +1,14 @@
-From 0236a4a01f3f3ed932ab326de0deef6911519dab Mon Sep 17 00:00:00 2001
+From 41a81ced950b4f97331f964b8ad67b773b5dcd7a 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] support configurable addba resp time.
+Subject: [PATCH 15/21] support configurable addba resp time.
 
 ---
  net/mac80211/agg-tx.c | 8 +++++++-
  1 file changed, 7 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 6992c1f..ad0c0d6 100644
+index 80cd642..7f66e69 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
 @@ -16,10 +16,16 @@
@@ -28,8 +28,8 @@
  /**
   * DOC: TX A-MPDU aggregation
   *
-@@ -460,7 +466,7 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
- 	u16 buf_size;
+@@ -466,7 +472,7 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
+ 	lockdep_assert_held(&sta->ampdu_mlme.mtx);
  
  	/* activate the timer for the recipient's addBA response */
 -	mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
@@ -38,5 +38,5 @@
  	       sta->sta.addr, tid);
  
 -- 
-2.18.0
+2.39.2
 
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-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch
index f14111c..945a5bd 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-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch
@@ -1,7 +1,8 @@
-From e545285e24de95d0d620bb7e9c97abba39e363b9 Mon Sep 17 00:00:00 2001
+From e2aa2e712fbebfbbb2338debd632d83157d72e92 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] mac80211: mtk: add sta-assisted DFS state update mechanism
+Subject: [PATCH 16/21] mac80211: mtk: add sta-assisted DFS state update
+ mechanism
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,10 +13,10 @@
  4 files changed, 92 insertions(+)
 
 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index 84564bd..06d1567 100644
+index cd0ec8a..2c51c3e 100644
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -8180,6 +8180,20 @@ void cfg80211_cac_event(struct net_device *netdev,
+@@ -8430,6 +8430,20 @@ void cfg80211_cac_event(struct net_device *netdev,
  			const struct cfg80211_chan_def *chandef,
  			enum nl80211_radar_event event, gfp_t gfp);
  
@@ -37,10 +38,10 @@
   * cfg80211_background_cac_abort - Channel Availability Check offchan abort event
   * @wiphy: the wiphy
 diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
-index bd26a06..e453d64 100644
+index 72ef4d9..60c6f79 100644
 --- a/include/uapi/linux/nl80211.h
 +++ b/include/uapi/linux/nl80211.h
-@@ -6565,6 +6565,10 @@ enum nl80211_smps_mode {
+@@ -6671,6 +6671,10 @@ enum nl80211_smps_mode {
   *	applicable for ETSI dfs domain where pre-CAC is valid for ever.
   * @NL80211_RADAR_CAC_STARTED: Channel Availability Check has been started,
   *	should be generated by HW if NL80211_EXT_FEATURE_DFS_OFFLOAD is enabled.
@@ -51,7 +52,7 @@
   */
  enum nl80211_radar_event {
  	NL80211_RADAR_DETECTED,
-@@ -6573,6 +6577,8 @@ enum nl80211_radar_event {
+@@ -6679,6 +6683,8 @@ enum nl80211_radar_event {
  	NL80211_RADAR_NOP_FINISHED,
  	NL80211_RADAR_PRE_CAC_EXPIRED,
  	NL80211_RADAR_CAC_STARTED,
@@ -61,10 +62,10 @@
  
  /**
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 72d153f..5a3dd31 100644
+index 86f762d..df39a8b 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
-@@ -1987,6 +1987,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
+@@ -1981,6 +1981,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
  					  IEEE80211_QUEUE_STOP_REASON_CSA);
  	mutex_unlock(&local->mtx);
  
@@ -73,13 +74,13 @@
 +				      &link->csa_chandef,
 +				      sdata->vif.cfg.assoc);
 +
- 	cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef, 0,
- 					  csa_ie.count, csa_ie.mode, 0);
- 
-@@ -3072,6 +3077,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
+ 	cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef,
+ 					  link->link_id, csa_ie.count,
+ 					  csa_ie.mode, 0);
+@@ -3066,6 +3071,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
  	       sizeof(sdata->vif.bss_conf.tx_pwr_env));
  
- 	ieee80211_vif_set_links(sdata, 0);
+ 	ieee80211_vif_set_links(sdata, 0, 0);
 +
 +	cfg80211_sta_update_dfs_state(&sdata->wdev,
 +				      &sdata->vif.bss_conf.chandef,
@@ -87,7 +88,7 @@
  }
  
  static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
-@@ -5276,6 +5285,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+@@ -5445,6 +5454,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
  		event.u.mlme.status = MLME_SUCCESS;
  		drv_event_callback(sdata->local, sdata, &event);
  		sdata_info(sdata, "associated\n");
@@ -98,7 +99,7 @@
  		info.success = 1;
  	}
 diff --git a/net/wireless/chan.c b/net/wireless/chan.c
-index fef0ba5..13276bc 100644
+index caa5acc..a7e597d 100644
 --- a/net/wireless/chan.c
 +++ b/net/wireless/chan.c
 @@ -14,6 +14,7 @@
@@ -109,7 +110,7 @@
  
  static bool cfg80211_valid_60g_freq(u32 freq)
  {
-@@ -1436,6 +1437,65 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
+@@ -1437,6 +1438,65 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
  }
  EXPORT_SYMBOL(cfg80211_any_usable_channels);
  
@@ -176,5 +177,5 @@
  				       unsigned int link_id)
  {
 -- 
-2.18.0
+2.39.2
 
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-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch
index cdc6290..92686c5 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-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch
@@ -1,17 +1,17 @@
-From 4c78e6469da8de9c4584d029231938063545b031 Mon Sep 17 00:00:00 2001
+From 532a2d6aacdd960d8f9f046f5862cae740b160b5 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] nl80211: mtk: Mark DFS channel as available for CSA.
+Subject: [PATCH 17/21] nl80211: mtk: 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 af43c22..53f32c6 100644
+index 0ed3f51..d8e4d0f 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -10079,6 +10079,11 @@ skip_beacons:
+@@ -10250,6 +10250,11 @@ skip_beacons:
  	if (err)
  		goto free;
  
@@ -24,5 +24,5 @@
  					   wdev->iftype)) {
  		err = -EINVAL;
 -- 
-2.18.0
+2.39.2
 
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-0018-cfg80211-mtk-fix-early-return-in-cfg80211_stop_backg.patch
index d57273b..810054d 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-0018-cfg80211-mtk-fix-early-return-in-cfg80211_stop_backg.patch
@@ -1,7 +1,7 @@
-From 435bf8765d44b694b86a400fb128fcf6d72b8aa6 Mon Sep 17 00:00:00 2001
+From ca445932b19fb346ea7cb33a5d23d94f979a2603 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/19] cfg80211: mtk: fix early return in
+Subject: [PATCH 18/21] cfg80211: mtk: fix early return in
  cfg80211_stop_background_radar_detection
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
-index 57b9bde..c2cf8aa 100644
+index e3cbfc0..d345c72 100644
 --- a/net/wireless/mlme.c
 +++ b/net/wireless/mlme.c
-@@ -1145,9 +1145,9 @@ void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
+@@ -1169,9 +1169,9 @@ void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
  		return;
  
  	rdev_set_radar_background(rdev, NULL);
@@ -25,5 +25,5 @@
 +	rdev->background_radar_wdev = NULL; /* Release offchain ownership */
  }
 -- 
-2.18.0
+2.39.2
 
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-0019-cfg80211-mtk-add-background-radar-stop-when-backgrou.patch
index 66d4d10..a07ea82 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-0019-cfg80211-mtk-add-background-radar-stop-when-backgrou.patch
@@ -1,7 +1,7 @@
-From 818c8f1d1a9ff9e5423ed0927b052692c282fdf4 Mon Sep 17 00:00:00 2001
+From a97cd11f1654844ed431aa359eca83fa844883c0 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/19] cfg80211: mtk: add background radar stop when
+Subject: [PATCH 19/21] cfg80211: mtk: add background radar stop when
  background channel is overlapped with operating channel
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index 53f32c6..ab61f8f 100644
+index d8e4d0f..4692480 100644
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -9852,6 +9852,10 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+@@ -10021,6 +10021,10 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
  		wdev->cac_started = true;
  		wdev->cac_start_time = jiffies;
  		wdev->cac_time_ms = cac_time_ms;
@@ -25,5 +25,5 @@
  unlock:
  	wiphy_unlock(wiphy);
 -- 
-2.18.0
+2.39.2
 
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-0020-mac80211-mtk-avoid-kernel-warning-of-check_flush_dep.patch
index cc72cf9..3ac2f2c 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-0020-mac80211-mtk-avoid-kernel-warning-of-check_flush_dep.patch
@@ -1,7 +1,7 @@
-From 6e6ceea486d4bd12a2d4118905d8fc0ba5eec6f6 Mon Sep 17 00:00:00 2001
+From f386c3a87f050489992ca66b8b17e970dc4a1ec1 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 1/7] mac80211: mtk: avoid kernel warning of
+Subject: [PATCH 20/21] mac80211: mtk: 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 06d111d..8965fff 100644
+index 0188e6a..ba133fa 100644
 --- a/net/mac80211/main.c
 +++ b/net/mac80211/main.c
-@@ -1276,7 +1276,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+@@ -1291,7 +1291,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.18.0
+2.39.2
 
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-0021-mac80211-mtk-avoid-calling-switch_vif_chanctx-when-u.patch
index d9fcacf..11bc559 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-0021-mac80211-mtk-avoid-calling-switch_vif_chanctx-when-u.patch
@@ -1,7 +1,7 @@
-From d5104c3407f3f1d476d072a8242ba40cc96ae566 Mon Sep 17 00:00:00 2001
+From 244189a8c4412ac16301678a7683f4eb2545d657 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] mac80211: mtk: avoid calling switch_vif_chanctx when
+Subject: [PATCH 21/21] mac80211: mtk: avoid calling switch_vif_chanctx when
  use_chanctx is false
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 8 insertions(+), 6 deletions(-)
 
 diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
-index dbc34fb..f9d1a8a 100644
+index 6895275..96f1ad0 100644
 --- a/net/mac80211/chan.c
 +++ b/net/mac80211/chan.c
-@@ -1280,13 +1280,15 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
+@@ -1304,13 +1304,15 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
  	list_del(&link->reserved_chanctx_list);
  	link->reserved_chanctx = NULL;
  
@@ -36,5 +36,5 @@
  
  	list_move(&link->assigned_chanctx_list, &new_ctx->assigned_links);
 -- 
-2.18.0
+2.39.2
 
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-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch
new file mode 100644
index 0000000..e32ba2f
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch
@@ -0,0 +1,201 @@
+From 979c688e54a73cfedb8757881a95c4f6c795023a 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
+
+These utilities include converting op_class to nl80211 channel width and
+center frequency.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ include/net/cfg80211.h |  25 ++++++++
+ net/wireless/util.c    | 130 ++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 154 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index cfaa3d6..bea7d25 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,
+ bool ieee80211_operating_class_to_band(u8 operating_class,
+ 				       enum nl80211_band *band);
+ 
++/**
++ * ieee80211_operating_class_to_center_freq - convert operating class to
++ * center frequency
++ *
++ * @operating_class: the operating class to convert
++ * @chan: the ieee80211_channel to convert
++ * @center_freq1: cneter frequency 1 pointer to fill
++ * @center_freq2: cneter frequency 2 pointer to fill
++ *
++ * Returns %true if the conversion was successful, %false otherwise.
++ */
++bool ieee80211_operating_class_to_center_freq(u8 operating_class,
++					      struct ieee80211_channel *chan,
++					      u32 *center_freq1,
++					      u32 *center_freq2);
++
++/**
++ * ieee80211_operating_class_to_chan_width - convert operating class to
++ * nl80211 channel width
++ *
++ * @operating_class: the operating class to convert
++ */
++enum nl80211_chan_width
++ieee80211_operating_class_to_chan_width(u8 operating_class);
++
+ /**
+  * ieee80211_chandef_to_operating_class - convert chandef to operation class
+  *
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 1783ab9..13cb986 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -1981,7 +1981,7 @@ bool ieee80211_operating_class_to_band(u8 operating_class,
+ 	case 128 ... 130:
+ 		*band = NL80211_BAND_5GHZ;
+ 		return true;
+-	case 131 ... 135:
++	case 131 ... 137:
+ 		*band = NL80211_BAND_6GHZ;
+ 		return true;
+ 	case 81:
+@@ -1999,6 +1999,134 @@ bool ieee80211_operating_class_to_band(u8 operating_class,
+ }
+ EXPORT_SYMBOL(ieee80211_operating_class_to_band);
+ 
++bool ieee80211_operating_class_to_center_freq(u8 operating_class,
++					      struct ieee80211_channel *chan,
++					      u32 *center_freq1,
++					      u32 *center_freq2)
++{
++	u32 control_freq, offset;
++	enum nl80211_band band;
++
++	control_freq = chan->center_freq;
++	if (!ieee80211_operating_class_to_band(operating_class, &band))
++		return false;
++
++	if (band != chan->band)
++		return false;
++
++	if (control_freq >= 5955)
++		offset = control_freq - 5955;
++	else if (control_freq >= 5745)
++		offset = control_freq - 5745;
++	else if (control_freq >= 5180)
++		offset = control_freq - 5180;
++	offset /= 20;
++
++	*center_freq2 = 0;
++	switch (operating_class) {
++	case 81:  /* 2 GHz band; 20 MHz; channels 1..13 */
++	case 82:  /* 2 GHz band; 20 MHz; channel 14 */
++	case 115: /* 5 GHz band; 20 MHz; channels 36,40,44,48 */
++	case 118: /* 5 GHz band; 20 MHz; channels 52,56,60,64 */
++	case 121: /* 5 GHz band; 20 MHz; channels 100..144 */
++	case 124: /* 5 GHz band; 20 MHz; channels 149,153,157,161 */
++	case 125: /* 5 GHz band; 20 MHz; channels 149..177 */
++	case 131: /* 6 GHz band; 20 MHz; channels 1..233*/
++	case 136: /* 6 GHz band; 20 MHz; channel 2 */
++		*center_freq1 = control_freq;
++		return true;
++	case 83:  /* 2 GHz band; 40 MHz; channels 1..9 */
++	case 116: /* 5 GHz band; 40 MHz; channels 36,44 */
++	case 119: /* 5 GHz band; 40 MHz; channels 52,60 */
++	case 122: /* 5 GHz band; 40 MHz; channels 100,108,116,124,132,140 */
++	case 126: /* 5 GHz band; 40 MHz; channels 149,157,165,173 */
++		*center_freq1 = control_freq + 10;
++		return true;
++	case 84:  /* 2 GHz band; 40 MHz; channels 5..13 */
++	case 117: /* 5 GHz band; 40 MHz; channels 40,48 */
++	case 120: /* 5 GHz band; 40 MHz; channels 56,64 */
++	case 123: /* 5 GHz band; 40 MHz; channels 104,112,120,128,136,144 */
++	case 127: /* 5 GHz band; 40 MHz; channels 153,161,169,177 */
++		*center_freq1 = control_freq - 10;
++		return true;
++	case 132: /* 6 GHz band; 40 MHz; channels 1,5,..,229*/
++		*center_freq1 = control_freq + 10 - (offset & 1) * 20;
++		return true;
++	case 128: /* 5 GHz band; 80 MHz; channels 36..64,100..144,149..177 */
++		*center_freq1 = control_freq + 30 - (offset & 3) * 20;
++		return true;
++	case 130: /* 5 GHz band; 80+80 MHz; channels 36..64,100..144,149..177 */
++		/* TODO How to know the center_freq2 of 80+80 MHz?*/
++		*center_freq1 = 0;
++		return false;
++	case 133: /* 6 GHz band; 80 MHz; channels 1,5,..,229 */
++		*center_freq1 = control_freq + 30 - (offset & 3) * 20;
++		return true;
++	case 129: /* 5 GHz band; 160 MHz; channels 36..64,100..144,149..177 */
++		*center_freq1 = control_freq + 70 - (offset & 7) * 20;
++		return true;
++	case 134: /* 6 GHz band; 160 MHz; channels 1,5,..,229 */
++		*center_freq1 = control_freq + 70 - (offset & 7) * 20;
++		return true;
++	case 135: /* 6 GHz band; 80+80 MHz; channels 1,5,..,229 */
++		/* TODO How to know the center_freq2 of 80+80 MHz?*/
++		*center_freq1 = 0;
++		return false;
++	case 137: /* 6 GHz band; 320 MHz; channels 1,5,..,229 */
++		/* TODO it's 320-1 or 320-2 channelization? */
++		/* Currently convert to 320-1 */
++		*center_freq1 = control_freq + 150 - (offset & 15) * 20;
++		return true;
++	default:
++		return false;
++	}
++}
++EXPORT_SYMBOL(ieee80211_operating_class_to_center_freq);
++
++enum nl80211_chan_width
++ieee80211_operating_class_to_chan_width(u8 operating_class)
++{
++	switch (operating_class) {
++	case 81:  /* 2 GHz band; 20 MHz; channels 1..13 */
++	case 82:  /* 2 GHz band; 20 MHz; channel 14 */
++	case 115: /* 5 GHz band; 20 MHz; channels 36,40,44,48 */
++	case 118: /* 5 GHz band; 20 MHz; channels 52,56,60,64 */
++	case 121: /* 5 GHz band; 20 MHz; channels 100..144 */
++	case 124: /* 5 GHz band; 20 MHz; channels 149,153,157,161 */
++	case 125: /* 5 GHz band; 20 MHz; channels 149..177 */
++	case 131: /* 6 GHz band; 20 MHz; channels 1..233*/
++	case 136: /* 6 GHz band; 20 MHz; channel 2 */
++		return NL80211_CHAN_WIDTH_20;
++	case 83:  /* 2 GHz band; 40 MHz; channels 1..9 */
++	case 84:  /* 2 GHz band; 40 MHz; channels 5..13 */
++	case 116: /* 5 GHz band; 40 MHz; channels 36,44 */
++	case 117: /* 5 GHz band; 40 MHz; channels 40,48 */
++	case 119: /* 5 GHz band; 40 MHz; channels 52,60 */
++	case 120: /* 5 GHz band; 40 MHz; channels 56,64 */
++	case 122: /* 5 GHz band; 40 MHz; channels 100,108,116,124,132,140 */
++	case 123: /* 5 GHz band; 40 MHz; channels 104,112,120,128,136,144 */
++	case 126: /* 5 GHz band; 40 MHz; channels 149,157,165,173 */
++	case 127: /* 5 GHz band; 40 MHz; channels 153,161,169,177 */
++	case 132: /* 6 GHz band; 40 MHz; channels 1,5,..,229*/
++		return NL80211_CHAN_WIDTH_40;
++	case 128: /* 5 GHz band; 80 MHz; channels 36..64,100..144,149..177 */
++	case 133: /* 6 GHz band; 80 MHz; channels 1,5,..,229 */
++		return NL80211_CHAN_WIDTH_80;
++	case 130: /* 5 GHz band; 80+80 MHz; channels 36..64,100..144,149..177 */
++	case 135: /* 6 GHz band; 80+80 MHz; channels 1,5,..,229 */
++		return NL80211_CHAN_WIDTH_80P80;
++	case 129: /* 5 GHz band; 160 MHz; channels 36..64,100..144,149..177 */
++	case 134: /* 6 GHz band; 160 MHz; channels 1,5,..,229 */
++		return NL80211_CHAN_WIDTH_160;
++	case 137: /* 6 GHz band; 320 MHz; channels 1,5,..,229 */
++		return NL80211_CHAN_WIDTH_320;
++	default:
++		WARN_ON(1);
++		return NL80211_CHAN_WIDTH_20_NOHT;
++	}
++}
++EXPORT_SYMBOL(ieee80211_operating_class_to_chan_width);
++
+ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
+ 					  u8 *op_class)
+ {
+-- 
+2.25.1
+
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-0023-mac80211-mtk-change-STA-CSA-parsing-flows.patch
new file mode 100644
index 0000000..54b59e1
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0023-mac80211-mtk-change-STA-CSA-parsing-flows.patch
@@ -0,0 +1,598 @@
+From e7247da28b7d7e90abd9ced10438df1cbe59af7e 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
+
+This patch changes the flows when STA parses csa IE:
+
+1. If Extended CSA IE is presented, this patch uses the subfield op_class
+   to build the VHT and HE operation in 5 GHz and 6 GHz, respectively.
+2. If Extended CSA IE is NOT presented but the Wide Bandwidth Channel
+   Switch IE is presented, the new channel width is at least 40 MHz.
+   Therefore this patch first prepares a 40 MHz chandef, then build the
+   VHT and HE operation in 5 GHz and 6 GHz, respectively.
+   Note that in a 6 GHz BSS, the subfield of Wide Bandwidth Channel Switch
+   IE might be the VHT, deprecated VHT or HE operation, so this patch
+   checks the combination of new channel width, ccfs0 and ccfs1 to build
+   the correct HE operation.
+3. From the HE/VHT operation created in step 1 or 2, this patch then
+   creates the chandef and assigns it to csa_ie.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ net/mac80211/spectmgmt.c | 508 ++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 454 insertions(+), 54 deletions(-)
+
+diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
+index 871cdac..dee7a60 100644
+--- a/net/mac80211/spectmgmt.c
++++ b/net/mac80211/spectmgmt.c
+@@ -19,6 +19,332 @@
+ #include "sta_info.h"
+ #include "wme.h"
+ 
++static inline void
++op_class_to_6ghz_he_eht_oper(u8 op_class, struct ieee80211_channel *chan,
++			     struct ieee80211_he_operation *he_oper,
++			     struct ieee80211_eht_operation *eht_oper)
++{
++	u8 new_chan_width;
++	u32 he_oper_params, center_freq1 = 0, center_freq2 = 0;
++	struct ieee80211_he_6ghz_oper *he_6ghz_oper;
++	struct ieee80211_eht_operation_info *eht_oper_info;
++
++	new_chan_width = ieee80211_operating_class_to_chan_width(op_class);
++	if (!ieee80211_operating_class_to_center_freq(op_class, chan,
++						      &center_freq1,
++						      &center_freq2)) {
++		new_chan_width = NL80211_CHAN_WIDTH_20;
++		center_freq1 = chan->center_freq;
++	}
++
++	he_oper_params =
++		u32_encode_bits(1, IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
++	he_oper->he_oper_params = cpu_to_le32(he_oper_params);
++
++	he_6ghz_oper = (struct ieee80211_he_6ghz_oper *)he_oper->optional;
++	he_6ghz_oper->primary =
++		ieee80211_frequency_to_channel(chan->center_freq);
++	he_6ghz_oper->ccfs0 = ieee80211_frequency_to_channel(center_freq1);
++	he_6ghz_oper->ccfs1 = center_freq2 ?
++		ieee80211_frequency_to_channel(center_freq2) : 0;
++
++	switch (new_chan_width) {
++	case NL80211_CHAN_WIDTH_320:
++		/* Cannot derive center frequency for 320 MHZ from op_class
++		 * since it might be 320-1 or 320-2
++		 */
++		WARN_ON(1);
++		break;
++	case NL80211_CHAN_WIDTH_160:
++		he_6ghz_oper->ccfs1 = he_6ghz_oper->ccfs0;
++		he_6ghz_oper->ccfs0 += chan->center_freq < center_freq1 ? -8 : 8;
++		fallthrough;
++	case NL80211_CHAN_WIDTH_80P80:
++		he_6ghz_oper->control =
++			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
++		break;
++	case NL80211_CHAN_WIDTH_80:
++		he_6ghz_oper->control =
++			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ;
++		break;
++	case NL80211_CHAN_WIDTH_40:
++		he_6ghz_oper->control =
++			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ;
++		break;
++	default:
++		he_6ghz_oper->control =
++			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ;
++		break;
++	}
++
++	eht_oper->params = IEEE80211_EHT_OPER_INFO_PRESENT;
++
++	eht_oper_info =
++		(struct ieee80211_eht_operation_info *)eht_oper->optional;
++	eht_oper_info->control = he_6ghz_oper->control;
++	eht_oper_info->ccfs0 = he_6ghz_oper->ccfs0;
++	eht_oper_info->ccfs1 = he_6ghz_oper->ccfs1;
++}
++
++static inline void
++wbcs_ie_to_6ghz_he_eht_oper(const struct ieee80211_wide_bw_chansw_ie *wbcs_ie,
++			    u8 new_chan_no,
++			    struct ieee80211_he_operation *he_oper,
++			    struct ieee80211_eht_operation *eht_oper)
++{
++	u32 he_oper_params;
++	struct ieee80211_he_6ghz_oper *he_6ghz_oper;
++	struct ieee80211_eht_operation_info *eht_oper_info;
++	bool fallback_20mhz;
++	u8 ccfs_diff;
++
++	he_oper_params =
++		u32_encode_bits(1, IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
++	he_oper->he_oper_params = cpu_to_le32(he_oper_params);
++
++	he_6ghz_oper = (struct ieee80211_he_6ghz_oper *)he_oper->optional;
++	he_6ghz_oper->primary = new_chan_no;
++
++	/* The Wide Bandwidth Channel Switch IE in a 6 GHz BSS migth be
++	 * deprecated VHT operation, VHT operation (IEEE 802.11-2020 9.4.2.160)
++	 * or HE operation (IEEE P80211be D3.2 9.4.2.159).
++	 * Check the combination of width, ccfs0 and ccfs1 to build the correct
++	 * HE/EHT operation.
++	 */
++	he_6ghz_oper->ccfs0 = wbcs_ie->new_center_freq_seg0;
++	he_6ghz_oper->ccfs1 = wbcs_ie->new_center_freq_seg1;
++	switch (wbcs_ie->new_channel_width) {
++	case 0:
++		/* Must be [deprecated] VHT operation with 40 MHz bandwidth */
++		he_6ghz_oper->control =
++			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ;
++		break;
++	case 1:
++		if (he_6ghz_oper->ccfs1) {
++			/* VHT operation with 160/80P80 MHz bandwidth */
++			he_6ghz_oper->control =
++				IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
++		} else if ((he_6ghz_oper->ccfs0 - 7) % 16 == 0) {
++			/* [deprecated] VHT operation with 80 MHz bandwidth */
++			he_6ghz_oper->control =
++				IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ;
++		} else {
++			/* HE operation with 40 MHz bandwidth */
++			he_6ghz_oper->control =
++				IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ;
++		}
++		break;
++	case 2:
++		if ((he_6ghz_oper->ccfs0 - 15) % 32 == 0) {
++			/* deprecated VHT operation with 160 MHz bandwidth */
++			he_6ghz_oper->control =
++				IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
++			he_6ghz_oper->ccfs1 = he_6ghz_oper->ccfs0;
++			he_6ghz_oper->ccfs0 +=
++				new_chan_no < he_6ghz_oper->ccfs0 ? -8 : 8;
++		} else {
++			/* HE operation with 80 MHz bandwidth */
++			he_6ghz_oper->control =
++				IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ;
++		}
++		break;
++	case 3:
++		/* Can be
++		 * 1. deprecated VHT operation with 80P80 MHz bandwidth
++		 * 2. HE operation with 160/80P80 MHz bandwidth
++		 */
++		he_6ghz_oper->control =
++			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
++		break;
++	case 4:
++		/* 320 MHz bandwidth
++		 * TODO channel switch to 320 MHz bandwidth should be indiated
++		 * by Bandwidth Indication IE (IEEE P80211be D3.2 9.4.2.159)
++		 */
++		he_6ghz_oper->control = IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ;
++		break;
++	default:
++		/* Ignore invalid width */
++		break;
++	}
++
++	/* Validate the relationship between new channel width and center frequency
++	 * segments, and fallback to 20 MHz if the relationship is wrong.
++	 */
++	fallback_20mhz = false;
++	switch (he_6ghz_oper->control) {
++	case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ:
++		if ((he_6ghz_oper->ccfs0 - 3) % 8 != 0)
++			fallback_20mhz = true;
++		break;
++	case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ:
++		if ((he_6ghz_oper->ccfs0 - 7) % 16 != 0)
++			fallback_20mhz = true;
++		break;
++	case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ:
++		ccfs_diff = abs(he_6ghz_oper->ccfs1 - he_6ghz_oper->ccfs0);
++		if ((ccfs_diff == 8 && (he_6ghz_oper->ccfs1 - 15) % 32 != 0) ||
++		    (ccfs_diff > 16 && ((he_6ghz_oper->ccfs0 - 7) % 16 != 0 ||
++		    (he_6ghz_oper->ccfs1 - 7) % 16 != 0)))
++			fallback_20mhz = true;
++		break;
++	case IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ:
++		if ((he_6ghz_oper->ccfs1 - 31) % 32 != 0)
++			fallback_20mhz = true;
++		break;
++	}
++
++	if (fallback_20mhz) {
++		he_6ghz_oper->control =
++			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ;
++		he_6ghz_oper->ccfs0 = he_6ghz_oper->primary;
++		he_6ghz_oper->ccfs1 = 0;
++	}
++
++	eht_oper->params = IEEE80211_EHT_OPER_INFO_PRESENT;
++	eht_oper_info =
++		(struct ieee80211_eht_operation_info *)eht_oper->optional;
++	eht_oper_info->control = he_6ghz_oper->control;
++	eht_oper_info->ccfs0 = he_6ghz_oper->ccfs0;
++	eht_oper_info->ccfs1 = he_6ghz_oper->ccfs1;
++}
++
++static inline void
++op_class_to_ht_vht_oper(u8 op_class, struct ieee80211_channel *chan,
++			struct ieee80211_ht_operation *ht_oper,
++			struct ieee80211_vht_operation *vht_oper)
++{
++	u8 new_chan_width;
++	u32 center_freq1 = 0, center_freq2 = 0;
++
++	new_chan_width = ieee80211_operating_class_to_chan_width(op_class);
++	if (!ieee80211_operating_class_to_center_freq(op_class, chan,
++						      &center_freq1,
++						      &center_freq2)) {
++		new_chan_width = NL80211_CHAN_WIDTH_20;
++		center_freq1 = chan->center_freq;
++	}
++
++	vht_oper->center_freq_seg0_idx =
++		ieee80211_frequency_to_channel(center_freq1);
++	vht_oper->center_freq_seg1_idx = center_freq2 ?
++		ieee80211_frequency_to_channel(center_freq2) : 0;
++
++	ht_oper->ht_param = (chan->center_freq / 20) & 1 ?
++				IEEE80211_HT_PARAM_CHA_SEC_ABOVE :
++				IEEE80211_HT_PARAM_CHA_SEC_BELOW;
++
++	switch (new_chan_width) {
++	case NL80211_CHAN_WIDTH_320:
++		WARN_ON(1);
++		break;
++	case NL80211_CHAN_WIDTH_160:
++		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
++		vht_oper->center_freq_seg1_idx = vht_oper->center_freq_seg0_idx;
++		vht_oper->center_freq_seg0_idx +=
++			chan->center_freq < center_freq1 ? -8 : 8;
++		break;
++	case NL80211_CHAN_WIDTH_80P80:
++		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
++		break;
++	case NL80211_CHAN_WIDTH_80:
++		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
++		break;
++	default:
++		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
++		if (chan->center_freq != center_freq1)
++			ht_oper->ht_param = chan->center_freq > center_freq1 ?
++				IEEE80211_HT_PARAM_CHA_SEC_BELOW :
++				IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
++		else
++			ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
++	}
++
++	ht_oper->operation_mode =
++		cpu_to_le16(vht_oper->center_freq_seg1_idx <<
++				IEEE80211_HT_OP_MODE_CCFS2_SHIFT);
++}
++
++static inline void
++wbcs_ie_to_ht_vht_oper(struct ieee80211_channel *chan,
++		       const struct ieee80211_wide_bw_chansw_ie *wbcs_ie,
++		       struct ieee80211_ht_operation *ht_oper,
++		       struct ieee80211_vht_operation *vht_oper)
++{
++	u8 new_chan_width, new_ccfs0, new_ccfs1;
++	bool fallback_20mhz;
++
++	new_chan_width = wbcs_ie->new_channel_width;
++	new_ccfs0 = wbcs_ie->new_center_freq_seg0;
++	new_ccfs1 = wbcs_ie->new_center_freq_seg1;
++
++	/* Validate the relationship between new channel width and center frequency
++	 * segments, and fallback to 20 MHz if the relationship is wrong.
++	 */
++	fallback_20mhz = false;
++	switch (new_chan_width) {
++	case IEEE80211_VHT_CHANWIDTH_USE_HT:
++		/* If the wide bandwidth channel switch IE is presented,
++		 * the new channel width is at least 40 MHz.
++		 */
++		if (!new_ccfs1) {
++			new_ccfs0 -= (new_ccfs0 >= 149) ? 151 : 38;
++			if (new_ccfs0 % 8 != 0)
++				fallback_20mhz = true;
++		} else {
++			fallback_20mhz = true;
++		}
++		break;
++	case IEEE80211_VHT_CHANWIDTH_80MHZ:
++		if (!new_ccfs1) {
++			new_ccfs0 -= (new_ccfs0 >= 149) ? 155 : 42;
++			if (new_ccfs0 % 16 != 0)
++				fallback_20mhz = true;
++			break;
++		} else if (abs(new_ccfs1 - new_ccfs0) == 8) {
++			new_ccfs0 = new_ccfs1;
++			new_ccfs1 = 0;
++		}
++		fallthrough;
++	case IEEE80211_VHT_CHANWIDTH_160MHZ:
++		if (!new_ccfs1) {
++			if (new_ccfs0 != 50 && new_ccfs0 != 114 && new_ccfs0 != 163)
++				fallback_20mhz = true;
++			break;
++		}
++		fallthrough;
++	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
++		new_ccfs0 -= (new_ccfs0 >= 149) ? 155 : 42;
++		new_ccfs1 -= (new_ccfs1 >= 149) ? 155 : 42;
++		if (new_ccfs0 % 16 != 0 || new_ccfs1 % 16 != 0)
++			fallback_20mhz = true;
++		break;
++	default:
++		fallback_20mhz = true;
++	}
++
++	if (fallback_20mhz) {
++		ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
++
++		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
++		vht_oper->center_freq_seg0_idx =
++			ieee80211_frequency_to_channel(chan->center_freq);
++		vht_oper->center_freq_seg1_idx = 0;
++
++	} else {
++		ht_oper->ht_param = (chan->center_freq / 20) & 1 ?
++					IEEE80211_HT_PARAM_CHA_SEC_ABOVE :
++					IEEE80211_HT_PARAM_CHA_SEC_BELOW;
++
++		vht_oper->chan_width = new_chan_width;
++		vht_oper->center_freq_seg0_idx = wbcs_ie->new_center_freq_seg0;
++		vht_oper->center_freq_seg1_idx = wbcs_ie->new_center_freq_seg1;
++	}
++
++	ht_oper->operation_mode = cpu_to_le16(vht_oper->center_freq_seg1_idx <<
++					      IEEE80211_HT_OP_MODE_CCFS2_SHIFT);
++}
++
+ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
+ 				 struct ieee802_11_elems *elems,
+ 				 enum nl80211_band current_band,
+@@ -26,19 +352,27 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
+ 				 ieee80211_conn_flags_t conn_flags, u8 *bssid,
+ 				 struct ieee80211_csa_ie *csa_ie)
+ {
++	struct ieee80211_supported_band *sband;
+ 	enum nl80211_band new_band = current_band;
+-	int new_freq;
+-	u8 new_chan_no;
++	int new_freq, size;
++	u8 new_chan_no = 0, new_op_class = 0;
+ 	struct ieee80211_channel *new_chan;
+-	struct cfg80211_chan_def new_vht_chandef = {};
++	struct cfg80211_chan_def new_chandef = {};
+ 	const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
+ 	const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
++	const struct ieee80211_ext_chansw_ie *ext_chansw_ie;
++	struct ieee80211_ht_operation *ht_oper;
++	struct ieee80211_vht_operation *vht_oper;
++	struct ieee80211_he_operation *he_oper;
++	struct ieee80211_eht_operation *eht_oper;
++	struct ieee80211_sta_ht_cap sta_ht_cap;
+ 	int secondary_channel_offset = -1;
+ 
+ 	memset(csa_ie, 0, sizeof(*csa_ie));
+ 
+ 	sec_chan_offs = elems->sec_chan_offs;
+ 	wide_bw_chansw_ie = elems->wide_bw_chansw_ie;
++	ext_chansw_ie = elems->ext_chansw_ie;
+ 
+ 	if (conn_flags & (IEEE80211_CONN_DISABLE_HT |
+ 			  IEEE80211_CONN_DISABLE_40MHZ)) {
+@@ -46,29 +380,30 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
+ 		wide_bw_chansw_ie = NULL;
+ 	}
+ 
+-	if (conn_flags & IEEE80211_CONN_DISABLE_VHT)
+-		wide_bw_chansw_ie = NULL;
+-
+-	if (elems->ext_chansw_ie) {
+-		if (!ieee80211_operating_class_to_band(
+-				elems->ext_chansw_ie->new_operating_class,
+-				&new_band)) {
+-			sdata_info(sdata,
+-				   "cannot understand ECSA IE operating class, %d, ignoring\n",
+-				   elems->ext_chansw_ie->new_operating_class);
++	if (ext_chansw_ie) {
++		new_op_class = ext_chansw_ie->new_operating_class;
++		if (!ieee80211_operating_class_to_band(new_op_class, &new_band)) {
++			new_op_class = 0;
++			sdata_info(sdata, "cannot understand ECSA IE "
++					  "operating class, %d, ignoring\n",
++				   ext_chansw_ie->new_operating_class);
++		} else {
++			new_chan_no = ext_chansw_ie->new_ch_num;
++			csa_ie->count = ext_chansw_ie->count;
++			csa_ie->mode = ext_chansw_ie->mode;
+ 		}
+-		new_chan_no = elems->ext_chansw_ie->new_ch_num;
+-		csa_ie->count = elems->ext_chansw_ie->count;
+-		csa_ie->mode = elems->ext_chansw_ie->mode;
+-	} else if (elems->ch_switch_ie) {
++	}
++
++	if (!new_op_class && elems->ch_switch_ie) {
+ 		new_chan_no = elems->ch_switch_ie->new_ch_num;
+ 		csa_ie->count = elems->ch_switch_ie->count;
+ 		csa_ie->mode = elems->ch_switch_ie->mode;
+-	} else {
+-		/* nothing here we understand */
+-		return 1;
+ 	}
+ 
++	/* nothing here we understand */
++	if (!new_chan_no)
++		return 1;
++
+ 	/* Mesh Channel Switch Parameters Element */
+ 	if (elems->mesh_chansw_params_ie) {
+ 		csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl;
+@@ -132,54 +467,119 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
+ 		break;
+ 	}
+ 
+-	if (wide_bw_chansw_ie) {
+-		u8 new_seg1 = wide_bw_chansw_ie->new_center_freq_seg1;
+-		struct ieee80211_vht_operation vht_oper = {
+-			.chan_width =
+-				wide_bw_chansw_ie->new_channel_width,
+-			.center_freq_seg0_idx =
+-				wide_bw_chansw_ie->new_center_freq_seg0,
+-			.center_freq_seg1_idx = new_seg1,
+-			/* .basic_mcs_set doesn't matter */
+-		};
+-		struct ieee80211_ht_operation ht_oper = {
+-			.operation_mode =
+-				cpu_to_le16(new_seg1 <<
+-					    IEEE80211_HT_OP_MODE_CCFS2_SHIFT),
+-		};
+-
+-		/* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT,
+-		 * to the previously parsed chandef
+-		 */
+-		new_vht_chandef = csa_ie->chandef;
++	if (new_band == NL80211_BAND_6GHZ) {
++		size = sizeof(struct ieee80211_he_operation) +
++		       sizeof(struct ieee80211_he_6ghz_oper);
++		he_oper = kzalloc(size, GFP_KERNEL);
++		if (!he_oper)
++			return -ENOMEM;
++
++		size = sizeof(struct ieee80211_eht_operation) +
++		       sizeof(struct ieee80211_eht_operation_info);
++		eht_oper = kzalloc(size, GFP_KERNEL);
++		if (!eht_oper) {
++			kfree(he_oper);
++			return -ENOMEM;
++		}
++
++		if (new_op_class && new_op_class != 135 && new_op_class != 137) {
++			/* There is no way to tell the ccfs1 for op_class 135
++			 * (80P80 MHz) and 137 (320 MHz).
++			 */
++			op_class_to_6ghz_he_eht_oper(new_op_class, new_chan,
++						     he_oper, eht_oper);
++		} else if (wide_bw_chansw_ie) {
++			wbcs_ie_to_6ghz_he_eht_oper(wide_bw_chansw_ie,
++						    new_chan_no, he_oper,
++						    eht_oper);
++		}
++
++		new_chandef = csa_ie->chandef;
+ 
+ 		/* ignore if parsing fails */
+-		if (!ieee80211_chandef_vht_oper(&sdata->local->hw,
+-						vht_cap_info,
+-						&vht_oper, &ht_oper,
+-						&new_vht_chandef))
+-			new_vht_chandef.chan = NULL;
++		if (!ieee80211_chandef_he_6ghz_oper(sdata, he_oper, eht_oper,
++						    &new_chandef))
++			new_chandef.chan = NULL;
++
++		kfree(he_oper);
++		kfree(eht_oper);
++	} else {
++		sband = sdata->local->hw.wiphy->bands[new_band];
++		memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
++		ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
++
++		if (!sta_ht_cap.ht_supported ||
++		    !(sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
++			goto out;
++
++		ht_oper = kzalloc(sizeof(*ht_oper), GFP_KERNEL);
++		if (!ht_oper)
++			return -ENOMEM;
++
++		vht_oper = kzalloc(sizeof(*vht_oper), GFP_KERNEL);
++		if (!vht_oper) {
++			kfree(ht_oper);
++			return -ENOMEM;
++		}
++
++		if (new_op_class && new_op_class != 130) {
++			/* There is no way to tell the ccfs1 for op_class 130
++			 * (80P80 MHz).
++			 */
++			op_class_to_ht_vht_oper(new_op_class, new_chan, ht_oper,
++						vht_oper);
++		} else if (wide_bw_chansw_ie && new_band == NL80211_BAND_5GHZ &&
++			   sband->vht_cap.vht_supported) {
++			/* It is assumed that there is no WBCS IE in the beacon
++			 * from a 2 GHz BSS during a channel switch.
++			 */
++			wbcs_ie_to_ht_vht_oper(new_chan, wide_bw_chansw_ie,
++					       ht_oper, vht_oper);
++		} else {
++			kfree(ht_oper);
++			kfree(vht_oper);
++			goto out;
++		}
++
++		new_chandef = csa_ie->chandef;
++
++		ieee80211_chandef_ht_oper(ht_oper, &new_chandef);
++
++		/* ignore if parsing fails */
++		if (sband->vht_cap.vht_supported &&
++		    !ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info,
++						vht_oper, ht_oper, &new_chandef))
++			new_chandef.chan = NULL;
++
++		kfree(ht_oper);
++		kfree(vht_oper);
++	}
++
++	if (new_chandef.chan) {
++		if (conn_flags & IEEE80211_CONN_DISABLE_320MHZ &&
++		    new_chandef.width == NL80211_CHAN_WIDTH_320)
++			ieee80211_chandef_downgrade(&new_chandef);
+ 
+ 		if (conn_flags & IEEE80211_CONN_DISABLE_80P80MHZ &&
+-		    new_vht_chandef.width == NL80211_CHAN_WIDTH_80P80)
+-			ieee80211_chandef_downgrade(&new_vht_chandef);
++		    new_chandef.width == NL80211_CHAN_WIDTH_80P80)
++			ieee80211_chandef_downgrade(&new_chandef);
++
+ 		if (conn_flags & IEEE80211_CONN_DISABLE_160MHZ &&
+-		    new_vht_chandef.width == NL80211_CHAN_WIDTH_160)
+-			ieee80211_chandef_downgrade(&new_vht_chandef);
+-	}
++		    new_chandef.width == NL80211_CHAN_WIDTH_160)
++			ieee80211_chandef_downgrade(&new_chandef);
+ 
+-	/* if VHT data is there validate & use it */
+-	if (new_vht_chandef.chan) {
+-		if (!cfg80211_chandef_compatible(&new_vht_chandef,
++		if (!cfg80211_chandef_compatible(&new_chandef,
+ 						 &csa_ie->chandef)) {
+ 			sdata_info(sdata,
+ 				   "BSS %pM: CSA has inconsistent channel data, disconnecting\n",
+ 				   bssid);
+ 			return -EINVAL;
+ 		}
+-		csa_ie->chandef = new_vht_chandef;
++
++		csa_ie->chandef = new_chandef;
+ 	}
+ 
++out:
+ 	if (elems->max_channel_switch_time)
+ 		csa_ie->max_switch_time =
+ 			(elems->max_channel_switch_time[0] << 0) |
+-- 
+2.25.1
+
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-1000-mac80211-mtk-add-EHT-BA1024-support.patch
index fe7b1af..41d3d2f 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-1000-mac80211-mtk-add-EHT-BA1024-support.patch
@@ -1,7 +1,7 @@
-From 5a82834ed7eb4cbf0f4f5abc8665eeef023b67ff Mon Sep 17 00:00:00 2001
+From 1a54516b2d934f80a80c6e1bb0fe824ceb63cd3b 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/1003] mac80211: mtk: add EHT BA1024 support
+Subject: [PATCH 1000/1006] mac80211: mtk: add EHT BA1024 support
 
 ---
  include/linux/ieee80211.h |  2 ++
@@ -9,10 +9,10 @@
  2 files changed, 45 insertions(+), 2 deletions(-)
 
 diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
-index 00d381e..0781b76 100644
+index 7aaae32..3308e85 100644
 --- a/include/linux/ieee80211.h
 +++ b/include/linux/ieee80211.h
-@@ -1256,6 +1256,8 @@ struct ieee80211_mgmt {
+@@ -1267,6 +1267,8 @@ struct ieee80211_mgmt {
  					__le16 status;
  					__le16 capab;
  					__le16 timeout;
@@ -22,10 +22,10 @@
  				struct{
  					u8 action_code;
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 752ad09..7f0e72a 100644
+index 7f66e69..b8b8e22 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
-@@ -66,10 +66,17 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
+@@ -72,10 +72,17 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
  	struct ieee80211_local *local = sdata->local;
  	struct sk_buff *skb;
  	struct ieee80211_mgmt *mgmt;
@@ -44,7 +44,7 @@
  
  	if (!skb)
  		return;
-@@ -108,6 +115,15 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
+@@ -114,6 +121,15 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
  	mgmt->u.action.u.addba_req.start_seq_num =
  					cpu_to_le16(start_seq_num << 4);
  
@@ -60,7 +60,7 @@
  	ieee80211_tx_skb_tid(sdata, skb, tid, -1);
  }
  
-@@ -469,8 +485,11 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
+@@ -481,8 +497,11 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
  	sta->ampdu_mlme.addba_req_num[tid]++;
  	spin_unlock_bh(&sta->lock);
  
@@ -73,7 +73,7 @@
  	} else {
  		/*
  		 * We really should use what the driver told us it will
-@@ -980,13 +999,35 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
+@@ -998,13 +1017,35 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
  {
  	struct tid_ampdu_tx *tid_tx;
  	struct ieee80211_txq *txq;
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-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
index f20cb61..d94b942 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-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
@@ -1,7 +1,7 @@
-From 857debd24af093da4e85f148767fd16fb9eaf975 Mon Sep 17 00:00:00 2001
+From 732eee694af50c9854755e4bcecf3a37f762a932 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/1003] mac80211: mtk: add rate duration for EHT rate.
+Subject: [PATCH 1001/1006] mac80211: mtk: add rate duration for EHT rate.
 
 ---
  net/mac80211/airtime.c | 349 ++++++++++++++++++++++++++++++++++++++++-
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-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch
index 099071c..a8ecdb7 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-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch
@@ -1,7 +1,7 @@
-From a9b8e0e62b19fbd7c1dd865330ceb5a943e5cbb2 Mon Sep 17 00:00:00 2001
+From 962ea174654c240aacc4e83b2000846c796cf1fc 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/1003] mac80211: mtk: add send bar action when recieve
+Subject: [PATCH 1002/1006] mac80211: mtk: add send bar action when recieve
  addba rsp
 
 Signed-off-by: ye he <ye.he@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 7f0e72a..3ce2226 100644
+index b8b8e22..285433a 100644
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
-@@ -1080,7 +1080,8 @@ next:
+@@ -1098,7 +1098,8 @@ next:
  
  		tid_tx->buf_size = buf_size;
  		tid_tx->amsdu = amsdu;
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-1003-mac80211-mtk-inrease-beacon-loss-count.patch
index 1def860..559b91d 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-1003-mac80211-mtk-inrease-beacon-loss-count.patch
@@ -1,7 +1,7 @@
-From 8175f5cdf45728cdfcf34893696f994c6f1e6cc1 Mon Sep 17 00:00:00 2001
+From 6e12a9af43178a46e573e8ee92520ec502562bb5 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/1003] mac80211: mtk: inrease beacon loss count
+Subject: [PATCH 1003/1006] mac80211: mtk: inrease beacon loss count
 
 as per eagle code beacone loss time out is
 4 seconds.
@@ -16,7 +16,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
-index 72d153f..458609c 100644
+index df39a8b..ccc72da 100644
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
 @@ -61,7 +61,7 @@ MODULE_PARM_DESC(max_probe_tries,
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-1004-cfg80211-mtk-add-support-for-updating-background-cha.patch
new file mode 100644
index 0000000..b52511a
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-cfg80211-mtk-add-support-for-updating-background-cha.patch
@@ -0,0 +1,88 @@
+From f0e42c5a5ea3491be2d7c61c798dffe126eabd2b 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
+ channel
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h       | 14 ++++++++++++++
+ include/uapi/linux/nl80211.h |  6 ++++++
+ net/wireless/mlme.c          | 12 ++++++++++++
+ 3 files changed, 32 insertions(+)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 2c51c3e..46c477a 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,
+ 				   const struct cfg80211_chan_def *csa_chandef,
+ 				   bool associated);
+ 
++/**
++ * cfg80211_background_radar_update_channel - notify background chandef has been updated
++ * @wiphy: the wiphy
++ * @chandef: the updated chandef
++ * @expand: whether or not the operating channel should expand its width
++ * after offchan CAC
++ *
++ * Update the background chandef based on driver's decision, and notify the userspace
++ * that the current channel of background chain should be updated.
++ */
++void cfg80211_background_radar_update_channel(struct wiphy *wiphy,
++					      const struct cfg80211_chan_def *chandef,
++					      bool expand);
++
+ /**
+  * cfg80211_background_cac_abort - Channel Availability Check offchan abort event
+  * @wiphy: the wiphy
+diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
+index 60c6f79..6e96ad9 100644
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -6671,6 +6671,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
+@@ -6683,6 +6687,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,
+ };
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index d345c72..5510d77 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -1158,6 +1158,18 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
+ 	return 0;
+ }
+ 
++void cfg80211_background_radar_update_channel(struct wiphy *wiphy,
++					      const struct cfg80211_chan_def *chandef,
++					      bool expand)
++{
++	enum nl80211_radar_event event;
++
++	event = expand ? NL80211_RADAR_BACKGROUND_CHAN_EXPAND :
++			 NL80211_RADAR_BACKGROUND_CHAN_UPDATE;
++	nl80211_radar_notify(wiphy_to_rdev(wiphy), chandef, event, NULL, GFP_ATOMIC);
++}
++EXPORT_SYMBOL(cfg80211_background_radar_update_channel);
++
+ void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
+ {
+ 	struct wiphy *wiphy = wdev->wiphy;
+-- 
+2.39.2
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-mac80211-mtk-add-disabling-cca-when-stopping-AP.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-mac80211-mtk-add-disabling-cca-when-stopping-AP.patch
deleted file mode 100644
index c8fc398..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-mac80211-mtk-add-disabling-cca-when-stopping-AP.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 79837bcb22a80a4c95cbba77b23f16352d4e791d Mon Sep 17 00:00:00 2001
-From: Michael Lee <michael-cy.lee@mediatek.com>
-Date: Mon, 24 Apr 2023 09:59:24 +0800
-Subject: [PATCH] mac80211: mtk: add disabling cca when stopping AP.
-
----
- net/mac80211/cfg.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 343ce2b..611c29e 100644
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1540,6 +1540,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
- 	/* abort any running channel switch */
- 	mutex_lock(&local->mtx);
- 	link_conf->csa_active = false;
-+	link_conf->color_change_active = false;
- 	if (link->csa_block_tx) {
- 		ieee80211_wake_vif_queues(local, sdata,
- 					  IEEE80211_QUEUE_STOP_REASON_CSA);
--- 
-2.25.1
-
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-1005-mac80211-mtk-Allow-STA-interface-to-set-TX-queue-par.patch
new file mode 100644
index 0000000..83fb948
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1005-mac80211-mtk-Allow-STA-interface-to-set-TX-queue-par.patch
@@ -0,0 +1,26 @@
+From 345695bc97c9a69aa9717e2fceb2e42701a63486 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
+ parameters
+
+Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
+---
+ net/wireless/nl80211.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 4692480..e098263 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)
+ 		}
+ 
+ 		if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
++		    netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ 		    netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
+ 			result = -EINVAL;
+ 			goto out;
+-- 
+2.39.2
+
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-1006-mac80211-mtk-export-ieee80211_tpt_led_trig_tx-rx-for.patch
new file mode 100644
index 0000000..825a8dc
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1006-mac80211-mtk-export-ieee80211_tpt_led_trig_tx-rx-for.patch
@@ -0,0 +1,150 @@
+From 8fb30028bd630b37840d023029aa6aa4791f7697 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
+
+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
+blink for that reason.
+
+The ieee80211_tpt_led_trig_tx/rx functions are exported for the driver
+so that we can report the tx and rx bytes from the driver when
+the H/W path is being used.
+
+Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
+---
+ include/net/mac80211.h | 17 +++++++++++++++++
+ net/mac80211/led.c     | 16 ++++++++++++++++
+ net/mac80211/led.h     | 17 -----------------
+ net/mac80211/rx.c      |  2 +-
+ net/mac80211/tx.c      |  4 ++--
+ 5 files changed, 36 insertions(+), 20 deletions(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 6ff6d3a..345c323 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -4744,6 +4744,8 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw,
+ 				   unsigned int flags,
+ 				   const struct ieee80211_tpt_blink *blink_table,
+ 				   unsigned int blink_table_len);
++void __ieee80211_tpt_led_trig_tx(struct ieee80211_hw *hw, int bytes);
++void __ieee80211_tpt_led_trig_rx(struct ieee80211_hw *hw, int bytes);
+ #endif
+ /**
+  * ieee80211_get_tx_led_name - get name of TX LED
+@@ -4854,6 +4856,21 @@ ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags,
+ #endif
+ }
+ 
++static inline void
++ieee80211_tpt_led_trig_tx(struct ieee80211_hw *hw, int bytes)
++{
++#ifdef CPTCFG_MAC80211_LEDS
++	__ieee80211_tpt_led_trig_tx(hw, bytes);
++#endif
++}
++
++static inline void
++ieee80211_tpt_led_trig_rx(struct ieee80211_hw *hw, int bytes)
++{
++#ifdef CPTCFG_MAC80211_LEDS
++	__ieee80211_tpt_led_trig_rx(hw, bytes);
++#endif
++}
+ /**
+  * ieee80211_unregister_hw - Unregister a hardware device
+  *
+diff --git a/net/mac80211/led.c b/net/mac80211/led.c
+index b992430..3109501 100644
+--- a/net/mac80211/led.c
++++ b/net/mac80211/led.c
+@@ -364,6 +364,22 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw,
+ }
+ EXPORT_SYMBOL(__ieee80211_create_tpt_led_trigger);
+ 
++void __ieee80211_tpt_led_trig_tx(struct ieee80211_hw *hw, int bytes)
++{
++	struct ieee80211_local *local = hw_to_local(hw);
++	if (atomic_read(&local->tpt_led_active))
++		local->tpt_led_trigger->tx_bytes += bytes;
++}
++EXPORT_SYMBOL(__ieee80211_tpt_led_trig_tx);
++
++void __ieee80211_tpt_led_trig_rx(struct ieee80211_hw *hw, int bytes)
++{
++	struct ieee80211_local *local = hw_to_local(hw);
++	if (atomic_read(&local->tpt_led_active))
++		local->tpt_led_trigger->rx_bytes += bytes;
++}
++EXPORT_SYMBOL(__ieee80211_tpt_led_trig_rx);
++
+ static void ieee80211_start_tpt_led_trig(struct ieee80211_local *local)
+ {
+ 	struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
+diff --git a/net/mac80211/led.h b/net/mac80211/led.h
+index 59f5a83..f381790 100644
+--- a/net/mac80211/led.h
++++ b/net/mac80211/led.h
+@@ -65,22 +65,5 @@ static inline void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
+ 					      unsigned int types_off)
+ {
+ }
+-#endif
+ 
+-static inline void
+-ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, int bytes)
+-{
+-#ifdef CPTCFG_MAC80211_LEDS
+-	if (atomic_read(&local->tpt_led_active))
+-		local->tpt_led_trigger->tx_bytes += bytes;
+ #endif
+-}
+-
+-static inline void
+-ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, int bytes)
+-{
+-#ifdef CPTCFG_MAC80211_LEDS
+-	if (atomic_read(&local->tpt_led_active))
+-		local->tpt_led_trigger->rx_bytes += bytes;
+-#endif
+-}
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index e245f31..a44381b 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,
+ 	if (skb) {
+ 		if ((status->flag & RX_FLAG_8023) ||
+ 			ieee80211_is_data_present(hdr->frame_control))
+-			ieee80211_tpt_led_trig_rx(local, skb->len);
++			ieee80211_tpt_led_trig_rx(&local->hw, skb->len);
+ 
+ 		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
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -4320,7 +4320,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
+ 	len = 0;
+  out:
+ 	if (len)
+-		ieee80211_tpt_led_trig_tx(local, len);
++		ieee80211_tpt_led_trig_tx(&local->hw, len);
+ 	rcu_read_unlock();
+ }
+ 
+@@ -4646,7 +4646,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;
+ 
+-	ieee80211_tpt_led_trig_tx(local, len);
++	ieee80211_tpt_led_trig_tx(&local->hw, len);
+ 
+ 	ieee80211_tx_8023(sdata, skb, sta, false);
+ 
+-- 
+2.39.2
+
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-1007-mac80211-mtk-add-packet-count-input-for-dev_sw_netst.patch
new file mode 100644
index 0000000..9a4f9ce
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1007-mac80211-mtk-add-packet-count-input-for-dev_sw_netst.patch
@@ -0,0 +1,136 @@
+From 26a73e67325cd28ff295afacfb875c14ea8e1988 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
+ dev_sw_netstat_rx_add
+
+---
+ backport-include/linux/netdevice.h                   | 12 ++++++++----
+ drivers/net/usb/qmi_wwan.c                           |  2 +-
+ .../net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c |  2 +-
+ .../net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c |  2 +-
+ net/mac80211/rx.c                                    |  8 ++++----
+ 5 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/backport-include/linux/netdevice.h b/backport-include/linux/netdevice.h
+index 1d2ac66..04d76d7 100644
+--- a/backport-include/linux/netdevice.h
++++ b/backport-include/linux/netdevice.h
+@@ -112,13 +112,15 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s,
+ #define netif_rx_any_context LINUX_BACKPORT(netif_rx_any_context)
+ int netif_rx_any_context(struct sk_buff *skb);
+ 
+-static inline void dev_sw_netstats_rx_add(struct net_device *dev, unsigned int len)
++static inline void dev_sw_netstats_rx_add(struct net_device *dev,
++					  unsigned int packets,
++					  unsigned int len)
+ {
+ 	struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
+ 
+ 	u64_stats_update_begin(&tstats->syncp);
+ 	tstats->rx_bytes += len;
+-	tstats->rx_packets++;
++	tstats->rx_packets += packets;
+ 	u64_stats_update_end(&tstats->syncp);
+ }
+ 
+@@ -140,13 +142,15 @@ static inline void dev_sw_netstats_tx_add(struct net_device *dev,
+ 
+ #if LINUX_VERSION_IS_LESS(5,10,0)
+ #define dev_sw_netstats_rx_add LINUX_BACKPORT(dev_sw_netstats_rx_add)
+-static inline void dev_sw_netstats_rx_add(struct net_device *dev, unsigned int len)
++static inline void dev_sw_netstats_rx_add(struct net_device *dev,
++					  unsigned int packets,
++					  unsigned int len)
+ {
+ 	struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
+ 
+ 	u64_stats_update_begin(&tstats->syncp);
+ 	tstats->rx_bytes += len;
+-	tstats->rx_packets++;
++	tstats->rx_packets += packets;
+ 	u64_stats_update_end(&tstats->syncp);
+ }
+ #endif /* < 5.10 */
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index adbcfdf..f93359a 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -210,7 +210,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+ 			net->stats.rx_errors++;
+ 			return 0;
+ 		} else {
+-			dev_sw_netstats_rx_add(net, pkt_len);
++			dev_sw_netstats_rx_add(net, 1, pkt_len);
+ 		}
+ 
+ skip:
+diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
+index 8c23a77..8f201ea 100644
+--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
+@@ -756,7 +756,7 @@ static int qtnf_pcie_pearl_rx_poll(struct napi_struct *napi, int budget)
+ 			skb_put(skb, psize);
+ 			ndev = qtnf_classify_skb(bus, skb);
+ 			if (likely(ndev)) {
+-				dev_sw_netstats_rx_add(ndev, skb->len);
++				dev_sw_netstats_rx_add(ndev, 1, skb->len);
+ 				skb->protocol = eth_type_trans(skb, ndev);
+ 				napi_gro_receive(napi, skb);
+ 			} else {
+diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
+index d833625..0a7bb97 100644
+--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
+@@ -662,7 +662,7 @@ static int qtnf_topaz_rx_poll(struct napi_struct *napi, int budget)
+ 			skb_put(skb, psize);
+ 			ndev = qtnf_classify_skb(bus, skb);
+ 			if (likely(ndev)) {
+-				dev_sw_netstats_rx_add(ndev, skb->len);
++				dev_sw_netstats_rx_add(ndev, 1, skb->len);
+ 				skb->protocol = eth_type_trans(skb, ndev);
+ 				netif_receive_skb(skb);
+ 			} else {
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index fb3d2e4..347867c 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -853,7 +853,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
+ 
+ 			if (skb) {
+ 				skb->dev = sdata->dev;
+-				dev_sw_netstats_rx_add(skb->dev, skb->len);
++				dev_sw_netstats_rx_add(skb->dev, 1, skb->len);
+ 				netif_receive_skb(skb);
+ 			}
+ 		}
+@@ -2632,7 +2632,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
+ 	skb = rx->skb;
+ 	xmit_skb = NULL;
+ 
+-	dev_sw_netstats_rx_add(dev, skb->len);
++	dev_sw_netstats_rx_add(dev, 1, skb->len);
+ 
+ 	if (rx->sta) {
+ 		/* The seqno index has the same property as needed
+@@ -4050,7 +4050,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
+ 		}
+ 
+ 		prev_dev = sdata->dev;
+-		dev_sw_netstats_rx_add(sdata->dev, skb->len);
++		dev_sw_netstats_rx_add(sdata->dev, 1, skb->len);
+ 	}
+ 
+ 	if (prev_dev) {
+@@ -4762,7 +4762,7 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
+ 
+ 	skb->dev = fast_rx->dev;
+ 
+-	dev_sw_netstats_rx_add(fast_rx->dev, skb->len);
++	dev_sw_netstats_rx_add(fast_rx->dev, 1, skb->len);
+ 
+ 	/* The seqno index has the same property as needed
+ 	 * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
+-- 
+2.18.0
+
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-1008-mac80211-mtk-add-per-bss-flag-to-support-vendors-cou.patch
new file mode 100644
index 0000000..4cb182c
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1008-mac80211-mtk-add-per-bss-flag-to-support-vendors-cou.patch
@@ -0,0 +1,91 @@
+From 7ef885cff2d628c84b83eb4b697106b781495fa5 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
+ counter
+
+---
+ include/uapi/linux/nl80211.h |  1 +
+ net/mac80211/rx.c            |  8 ++++++--
+ net/mac80211/tx.c            | 13 ++++++++++---
+ 3 files changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
+index 6e96ad9..b1555bb 100644
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -6471,6 +6471,7 @@ enum nl80211_ext_feature_index {
+ 	NL80211_EXT_FEATURE_PUNCT,
+ 	NL80211_EXT_FEATURE_SECURE_NAN,
+ 	NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA,
++	NL80211_EXT_FEATURE_STAS_COUNT,
+ 
+ 	/* add new features before the definition below */
+ 	NUM_NL80211_EXT_FEATURES,
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 347867c..07dddcd 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2632,7 +2632,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
+ 	skb = rx->skb;
+ 	xmit_skb = NULL;
+ 
+-	dev_sw_netstats_rx_add(dev, 1, skb->len);
++	if (!wiphy_ext_feature_isset(sdata->local->hw.wiphy,
++	    NL80211_EXT_FEATURE_STAS_COUNT) || !rx->sta)
++		dev_sw_netstats_rx_add(dev, 1, skb->len);
+ 
+ 	if (rx->sta) {
+ 		/* The seqno index has the same property as needed
+@@ -4762,7 +4764,9 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
+ 
+ 	skb->dev = fast_rx->dev;
+ 
+-	dev_sw_netstats_rx_add(fast_rx->dev, 1, skb->len);
++	if (!wiphy_ext_feature_isset(sta->local->hw.wiphy,
++	    NL80211_EXT_FEATURE_STAS_COUNT))
++		dev_sw_netstats_rx_add(fast_rx->dev, 1, skb->len);
+ 
+ 	/* The seqno index has the same property as needed
+ 	 * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 0ed18d5..c6eec00 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3540,7 +3540,9 @@ ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
+ 	if (key)
+ 		info->control.hw_key = &key->conf;
+ 
+-	dev_sw_netstats_tx_add(skb->dev, 1, skb->len);
++	if (!wiphy_ext_feature_isset(sta->local->hw.wiphy,
++	    NL80211_EXT_FEATURE_STAS_COUNT))
++		dev_sw_netstats_tx_add(skb->dev, 1, skb->len);
+ 
+ 	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
+ 		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
+@@ -4311,7 +4313,9 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
+ 			goto out;
+ 		}
+ 
+-		dev_sw_netstats_tx_add(dev, 1, skb->len);
++		if (!wiphy_ext_feature_isset(sdata->local->hw.wiphy,
++		    NL80211_EXT_FEATURE_STAS_COUNT) || !sta)
++			dev_sw_netstats_tx_add(dev, 1, skb->len);
+ 
+ 		ieee80211_xmit(sdata, sta, skb);
+ 	}
+@@ -4643,7 +4647,10 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
+ 		info->ack_frame_id = ieee80211_store_ack_skb(local, skb,
+ 							     &info->flags, NULL);
+ 
+-	dev_sw_netstats_tx_add(dev, skbs, len);
++	if (!wiphy_ext_feature_isset(sta->local->hw.wiphy,
++	    NL80211_EXT_FEATURE_STAS_COUNT))
++		dev_sw_netstats_tx_add(dev, skbs, len);
++
+ 	sta->deflink.tx_stats.packets[queue] += skbs;
+ 	sta->deflink.tx_stats.bytes[queue] += len;
+ 
+-- 
+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 758523e..ccc29ce 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
@@ -2,54 +2,21 @@
 SRC_URI_append = " \
     file://110-mac80211_keep_keys_on_stop_ap.patch \
     file://120-cfg80211_allow_perm_addr_change.patch \
+    file://130-disable_auto_vif.patch \
     file://210-ap_scan.patch \
     file://301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch \
     file://302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch \
     file://303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch \
     file://304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch \
     file://305-mac80211-increase-quantum-for-airtime-scheduler.patch \
-    file://306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch \
-    file://306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch \
-    file://306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch \
-    file://306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch \
-    file://310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch \
-    file://311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch \
-    file://312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch \
-    file://313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch \
-    file://314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch \
-    file://315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch \
-    file://316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch \
-    file://318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch \
-    file://319-wifi-mac80211-mesh-fast-xmit-support.patch \
-    file://320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch \
-    file://321-mac80211-fix-mesh-forwarding.patch \
-    file://322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch \
-    file://323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch \
-    file://324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch \
-    file://325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch \
-    file://326-wifi-mac80211-add-mesh-fast-rx-support.patch \
-    file://327-wifi-mac80211-add-support-for-letting-drivers-regist.patch \
-    file://329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch \
-    file://330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch \
-    file://331-wifi-mac80211-flush-queues-on-STA-removal.patch \
-    file://332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch \
-    file://333-wifi-mac80211-add-flush_sta-method.patch \
-    file://334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch \
-    file://335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch \
-    file://336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch \
-    file://337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch \
-    file://338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch \
-    file://339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch \
+    file://310-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch \
+    file://311-mac80211-fix-mesh-id-corruption-on-32-bit-systems.patch \
+    file://312-wifi-cfg80211-annotate-iftype_data-pointer-with-spar.patch \
+    file://313-wifi-cfg80211-export-DFS-CAC-time-and-usable-state-h.patch \
+    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-0002-mac80211-support-minimal-EHT-rate-reporting-on-RX.patch \
-    file://bp-0003-cfg80211-Update-Transition-Disable-policy-during-por.patch \
-    file://bp-0004-wifi-mac80211-mlme-handle-EHT-channel-puncturing.patch \
-    file://bp-0005-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch \
-    file://bp-0006-wifi-nl80211-validate-and-configure-puncturing-bitma.patch \
-    file://bp-0007-wifi-cfg80211-include-puncturing-bitmap-in-channel-s.patch \
-    file://bp-0008-wifi-mac80211-configure-puncturing-bitmap.patch \
-    file://bp-0009-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch \
+    file://bp-0001-Revert-mac80211-use-the-new-drop-reasons-infrastruct.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 \
@@ -64,16 +31,22 @@
     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-mac80211-support-configurable-addba-resp-time.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-mac80211-mtk-add-disabling-cca-when-stopping-AP.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 \
     "
diff --git a/recipes-wifi/linux-mac80211/linux-mac80211_6.%.bb b/recipes-wifi/linux-mac80211/linux-mac80211_6.%.bb
index 9010d00..d601c7d 100644
--- a/recipes-wifi/linux-mac80211/linux-mac80211_6.%.bb
+++ b/recipes-wifi/linux-mac80211/linux-mac80211_6.%.bb
@@ -6,14 +6,14 @@
 
 inherit module
 
-PV = "6.1.24"
+PV = "6.5"
 
 SRC_URI = " \
     http://mirror2.openwrt.org/sources/backports-${PV}.tar.xz \
     file://config \
     file://0001-rdkb-fix_build_issue-mac80211-without_depmod.patch;apply=no \
     "
-SRC_URI[sha256sum] = "5d39aca7e34c33cb9b3e366117b2e86841b7bdd37933679d6b1e61be6b150648"
+SRC_URI[sha256sum] = "908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7"
 
 DEPENDS += "virtual/kernel"
 DEPENDS += "bison-native coreutils-native flex-native"
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-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
new file mode 100644
index 0000000..bef1050
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
@@ -0,0 +1,44 @@
+From 455955959ceaabf80454570c2dfaa3128d524791 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"
+
+This reverts commit 325a0c4931990d553487024c4f76c776492bdcc2.
+---
+ mt7996/mac.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index c43839a..1a1e218 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,
+ 		return id;
+ 
+ 	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+-	mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
+-			      pid, qid, 0);
++	memset(txwi_ptr, 0, MT_TXD_SIZE);
++	/* Transmit non qos data by 802.11 header and need to fill txd by host*/
++	if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
++		mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
++				      pid, qid, 0);
+ 
+ 	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,
+ 	}
+ 	txp->fw.nbuf = nbuf;
+ 
+-	txp->fw.flags =
+-		cpu_to_le16(MT_CT_INFO_FROM_HOST | MT_CT_INFO_APPLY_TXD);
++	txp->fw.flags = cpu_to_le16(MT_CT_INFO_FROM_HOST);
++
++	if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
++		txp->fw.flags |= cpu_to_le16(MT_CT_INFO_APPLY_TXD);
+ 
+ 	if (!key)
+ 		txp->fw.flags |= cpu_to_le16(MT_CT_INFO_NONE_CIPHER_FRAME);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch
deleted file mode 100644
index 91d65d7..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 15d734c77b25451efdf3bb1bcd5e687bc429a852 Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Fri, 10 Feb 2023 17:39:23 +0800
-Subject: [PATCH 01/11] wifi: mt76: mt7996: add eht rx rate support
-
-Add support to report eht rx rate.
-
-Change-Id: Iee067d891bd634a918c942c2ba90ae72cd40c538
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mac80211.c   | 11 ++++++++---
- mt76.h       | 18 ++++++++++++++----
- mt7996/mac.c |  9 +++++----
- 3 files changed, 27 insertions(+), 11 deletions(-)
-
-diff --git a/mac80211.c b/mac80211.c
-index 2c4a5290..467afef9 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -1067,9 +1067,14 @@ 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;
--	status->he_ru = mstat.he_ru;
--	status->he_gi = mstat.he_gi;
--	status->he_dcm = mstat.he_dcm;
-+	if (status->encoding == RX_ENC_EHT) {
-+		status->eht.ru = mstat.eht.ru;
-+		status->eht.gi = mstat.eht.gi;
-+	} else {
-+		status->he_ru = mstat.he_ru;
-+		status->he_gi = mstat.he_gi;
-+		status->he_dcm = mstat.he_dcm;
-+	}
- 	status->rate_idx = mstat.rate_idx;
- 	status->nss = mstat.nss;
- 	status->band = mstat.band;
-diff --git a/mt76.h b/mt76.h
-index 8b4635e9..6b07b8fa 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -621,12 +621,22 @@ struct mt76_rx_status {
- 	u16 freq;
- 	u32 flag;
- 	u8 enc_flags;
--	u8 encoding:2, bw:3, he_ru:3;
--	u8 he_gi:2, he_dcm:1;
-+	u8 encoding:3, bw:4;
-+	union {
-+		struct {
-+			u8 he_ru:3;
-+			u8 he_gi:2;
-+			u8 he_dcm:1;
-+		};
-+		struct {
-+			u8 ru:4;
-+			u8 gi:2;
-+		} eht;
-+	};
-+
- 	u8 amsdu:1, first_amsdu:1, last_amsdu:1;
- 	u8 rate_idx;
--	u8 nss;
--	u8 band;
-+	u8 nss:5, band:3;
- 	s8 signal;
- 	u8 chains;
- 	s8 chain_signal[IEEE80211_MAX_CHAINS];
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 0d51090d..23cbfdde 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -580,11 +580,12 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
- 	case MT_PHY_TYPE_EHT_SU:
- 	case MT_PHY_TYPE_EHT_TRIG:
- 	case MT_PHY_TYPE_EHT_MU:
--		/* TODO: currently report rx rate with HE rate */
- 		status->nss = nss;
--		status->encoding = RX_ENC_HE;
--		bw = min_t(int, bw, IEEE80211_STA_RX_BW_160);
--		i = min_t(int, i & 0xf, 11);
-+		status->encoding = RX_ENC_EHT;
-+		i &= GENMASK(3, 0);
-+
-+		if (gi <= NL80211_RATE_INFO_EHT_GI_3_2)
-+			status->eht.gi = gi;
- 		break;
- 	default:
- 		return -EINVAL;
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-move-radio-ctrl-commands-to-proper-.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-move-radio-ctrl-commands-to-proper-.patch
deleted file mode 100644
index 8ab501f..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-move-radio-ctrl-commands-to-proper-.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 83d30a89d61ee914b23d77256e993e9521de5cbc Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Wed, 15 Feb 2023 18:38:04 +0800
-Subject: [PATCH 02/11] wifi: mt76: mt7996: move radio ctrl commands to proper
- functions
-
-Move radio enable/disable commands into functions for configuring
-per-phy radio.
-
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/main.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/mt7996/main.c b/mt7996/main.c
-index f306e9c5..e7c97d2f 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -43,6 +43,10 @@ int mt7996_run(struct ieee80211_hw *hw)
- 	if (ret)
- 		goto out;
- 
-+	ret = mt7996_mcu_set_radio_en(phy, true);
-+	if (ret)
-+		goto out;
-+
- 	ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_RX_PATH);
- 	if (ret)
- 		goto out;
-@@ -82,6 +86,8 @@ static void mt7996_stop(struct ieee80211_hw *hw)
- 
- 	mutex_lock(&dev->mt76.mutex);
- 
-+	mt7996_mcu_set_radio_en(phy, false);
-+
- 	clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
- 
- 	mutex_unlock(&dev->mt76.mutex);
-@@ -190,10 +196,6 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
- 	if (ret)
- 		goto out;
- 
--	ret = mt7996_mcu_set_radio_en(phy, true);
--	if (ret)
--		goto out;
--
- 	dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);
- 	phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
- 
-@@ -253,7 +255,6 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
- 		phy->monitor_vif = NULL;
- 
- 	mt7996_mcu_add_dev_info(phy, vif, false);
--	mt7996_mcu_set_radio_en(phy, false);
- 
- 	rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
- 
--- 
-2.39.2
-
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
new file mode 100644
index 0000000..25dfc5d
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-wed-sync-to-wed-upstream.patch
@@ -0,0 +1,2740 @@
+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/0003-wifi-mt76-connac-add-support-for-dsp-firmware-downlo.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-connac-add-support-for-dsp-firmware-downlo.patch
deleted file mode 100644
index 4342d73..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-connac-add-support-for-dsp-firmware-downlo.patch
+++ /dev/null
@@ -1,198 +0,0 @@
-From 20c8d7bfeb91be51129e7e98213db441a62d6d95 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Wed, 31 May 2023 18:31:41 +0800
-Subject: [PATCH 03/11] wifi: mt76: connac: add support for dsp firmware
- download
-
-Add FW_START_WORKING_PDA_DSP for the indication of starting DSP
-firmware download, which is for phy-related control.
-The firmware is transparent to the driver, but it's necessary for the
-firmware download process.
-
-Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: I35666504cfe7bf213c8f8f0c0223b3089372f2ab
----
-v2:
-  - merge two commits
-  - move main load ram code to a regular function
-v3:
-  - remove all macros to directly call __mt7996_load_ram()
-  - add back missing code which records fw_version to wiphy
----
- mt76_connac_mcu.h |  1 +
- mt7996/mcu.c      | 67 +++++++++++++++++++++++------------------------
- mt7996/mt7996.h   |  7 +++++
- mt7996/pci.c      |  1 +
- 4 files changed, 42 insertions(+), 34 deletions(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 91d98eff..d2a3d56b 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -22,6 +22,7 @@
- 
- #define FW_START_OVERRIDE		BIT(0)
- #define FW_START_WORKING_PDA_CR4	BIT(2)
-+#define FW_START_WORKING_PDA_DSP	BIT(3)
- 
- #define PATCH_SEC_NOT_SUPPORT		GENMASK(31, 0)
- #define PATCH_SEC_TYPE_MASK		GENMASK(15, 0)
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 88e2f9d0..545cc987 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2155,7 +2155,7 @@ out:
- static int
- mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
- 			     const struct mt7996_fw_trailer *hdr,
--			     const u8 *data, bool is_wa)
-+			     const u8 *data, enum mt7996_ram_type type)
- {
- 	int i, offset = 0;
- 	u32 override = 0, option = 0;
-@@ -2167,8 +2167,10 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
- 
- 		region = (const struct mt7996_fw_region *)((const u8 *)hdr -
- 			 (hdr->n_region - i) * sizeof(*region));
-+		/* DSP and WA use same mode */
- 		mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,
--						   region->feature_set, is_wa);
-+						   region->feature_set,
-+						   type != MT7996_RAM_TYPE_WM);
- 		len = le32_to_cpu(region->len);
- 		addr = le32_to_cpu(region->addr);
- 
-@@ -2195,19 +2197,22 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
- 	if (override)
- 		option |= FW_START_OVERRIDE;
- 
--	if (is_wa)
-+	if (type == MT7996_RAM_TYPE_WA)
- 		option |= FW_START_WORKING_PDA_CR4;
-+	else if (type == MT7996_RAM_TYPE_DSP)
-+		option |= FW_START_WORKING_PDA_DSP;
- 
- 	return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
- }
- 
--static int mt7996_load_ram(struct mt7996_dev *dev)
-+static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
-+			     const char *fw_file, enum mt7996_ram_type ram_type)
- {
- 	const struct mt7996_fw_trailer *hdr;
- 	const struct firmware *fw;
- 	int ret;
- 
--	ret = request_firmware(&fw, MT7996_FIRMWARE_WM, dev->mt76.dev);
-+	ret = request_firmware(&fw, fw_file, dev->mt76.dev);
- 	if (ret)
- 		return ret;
- 
-@@ -2217,37 +2222,13 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
- 		goto out;
- 	}
- 
--	hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
--
--	dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
--		 hdr->fw_ver, hdr->build_date);
-+	hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
-+	dev_info(dev->mt76.dev, "%s Firmware Version: %.10s, Build Time: %.15s\n",
-+		 fw_type, hdr->fw_ver, hdr->build_date);
- 
--	ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, false);
-+	ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, ram_type);
- 	if (ret) {
--		dev_err(dev->mt76.dev, "Failed to start WM firmware\n");
--		goto out;
--	}
--
--	release_firmware(fw);
--
--	ret = request_firmware(&fw, MT7996_FIRMWARE_WA, dev->mt76.dev);
--	if (ret)
--		return ret;
--
--	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
--		dev_err(dev->mt76.dev, "Invalid firmware\n");
--		ret = -EINVAL;
--		goto out;
--	}
--
--	hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
--
--	dev_info(dev->mt76.dev, "WA Firmware Version: %.10s, Build Time: %.15s\n",
--		 hdr->fw_ver, hdr->build_date);
--
--	ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, true);
--	if (ret) {
--		dev_err(dev->mt76.dev, "Failed to start WA firmware\n");
-+		dev_err(dev->mt76.dev, "Failed to start %s firmware\n", fw_type);
- 		goto out;
- 	}
- 
-@@ -2261,6 +2242,24 @@ out:
- 	return ret;
- }
- 
-+static int mt7996_load_ram(struct mt7996_dev *dev)
-+{
-+	int ret;
-+
-+	ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
-+				MT7996_RAM_TYPE_WM);
-+	if (ret)
-+		return ret;
-+
-+	ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP,
-+				MT7996_RAM_TYPE_DSP);
-+	if (ret)
-+		return ret;
-+
-+	return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA,
-+				 MT7996_RAM_TYPE_WA);
-+}
-+
- static int
- mt7996_firmware_state(struct mt7996_dev *dev, bool wa)
- {
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 4d7dcb95..7dfdc738 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -29,6 +29,7 @@
- 
- #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_ROM_PATCH		"mediatek/mt7996/mt7996_rom_patch.bin"
- 
- #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
-@@ -52,6 +53,12 @@ struct mt7996_sta;
- struct mt7996_dfs_pulse;
- struct mt7996_dfs_pattern;
- 
-+enum mt7996_ram_type {
-+	MT7996_RAM_TYPE_WM,
-+	MT7996_RAM_TYPE_WA,
-+	MT7996_RAM_TYPE_DSP,
-+};
-+
- enum mt7996_txq_id {
- 	MT7996_TXQ_FWDL = 16,
- 	MT7996_TXQ_MCU_WM,
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index 64aee3fb..c5301050 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -219,4 +219,5 @@ MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table);
- MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table);
- MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
- MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
-+MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
- MODULE_FIRMWARE(MT7996_ROM_PATCH);
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0030-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
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0030-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
index 798eb69..c657c5b 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0030-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
@@ -1,7 +1,7 @@
-From 7390e5db3745febd580026e723b2ca806e308008 Mon Sep 17 00:00:00 2001
+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 30/39] wifi: mt76: mt7996: add support for auxiliary path
+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.
@@ -17,10 +17,10 @@
  4 files changed, 35 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index f5e9546..9840c77 100644
+index 544b6c6..9db7e53 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -171,36 +171,49 @@ static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
+@@ -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)
  {
@@ -75,10 +75,10 @@
  	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 0f8f0cd..9ea3667 100644
+index 0c74977..412d6e2 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
-@@ -34,6 +34,9 @@ enum mt7996_eeprom_field {
+@@ -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)
@@ -89,10 +89,10 @@
  #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 7b8f883..a2c1e43 100644
+index 3ff70c6..328bea9 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -3198,7 +3198,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
+@@ -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),
@@ -102,19 +102,19 @@
  		.channel_band = ch_band[chandef->chan->band],
  	};
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index f7d6580..8e5b3c3 100644
+index c541eaa..ef84173 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -248,6 +248,8 @@ struct mt7996_phy {
- 	struct mib_stats mib;
- 	struct mt76_channel_state state_ts;
+@@ -206,6 +206,8 @@ struct mt7996_phy {
  
-+	bool has_aux_rx;
+ 	struct mt76_mib_stats mib;
+ 	struct mt76_channel_state state_ts;
 +
- #ifdef CONFIG_NL80211_TESTMODE
- 	struct {
- 		u32 *reg_backup;
-@@ -551,6 +553,18 @@ static inline void mt7996_irq_disable(struct mt7996_dev *dev, u32 mask)
++	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);
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0032-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
similarity index 71%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0032-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
index ba0e378..bb8761d 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0032-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
@@ -1,7 +1,7 @@
-From fd7730026ccef8b0d5a52ac07ddb21af48def17d Mon Sep 17 00:00:00 2001
+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 32/39] wifi: mt76: mt7996: add eht mode tx stats
+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
 
@@ -11,19 +11,19 @@
  1 file changed, 3 insertions(+), 2 deletions(-)
 
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 0422018..ca4d615 100644
+index 4d40ec7..9bd9535 100644
 --- a/mt7996/debugfs.c
 +++ b/mt7996/debugfs.c
-@@ -481,7 +481,7 @@ static void
- mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
+@@ -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"
  	};
- 	struct mib_stats *mib = &phy->mib;
  
-@@ -495,8 +495,9 @@ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
+ 	/* 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: ");
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch
deleted file mode 100644
index a4e17a9..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 3c7a5592ea211f5ddb2f6bbd6ba8720c74faf459 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Thu, 2 Mar 2023 15:44:52 +0800
-Subject: [PATCH 04/11] wifi: mt76: mt7996: fix bss wlan_idx when sending
- bss_info command
-
-The bmc_tx_wlan_idx should be the wlan_idx of the current bss rather
-than peer AP's wlan_idx, otherwise there will appear some frame
-decryption problems on station mode.
-
-Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
-Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/mcu.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 545cc987..6706d38c 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -712,6 +712,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- 	struct cfg80211_chan_def *chandef = &phy->chandef;
- 	struct mt76_connac_bss_basic_tlv *bss;
- 	u32 type = CONNECTION_INFRA_AP;
-+	u16 sta_wlan_idx = wlan_idx;
- 	struct tlv *tlv;
- 	int idx;
- 
-@@ -731,7 +732,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- 				struct mt76_wcid *wcid;
- 
- 				wcid = (struct mt76_wcid *)sta->drv_priv;
--				wlan_idx = wcid->idx;
-+				sta_wlan_idx = wcid->idx;
- 			}
- 			rcu_read_unlock();
- 		}
-@@ -751,7 +752,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- 	bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
- 	bss->dtim_period = vif->bss_conf.dtim_period;
- 	bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx);
--	bss->sta_idx = cpu_to_le16(wlan_idx);
-+	bss->sta_idx = cpu_to_le16(sta_wlan_idx);
- 	bss->conn_type = cpu_to_le32(type);
- 	bss->omac_idx = mvif->omac_idx;
- 	bss->band_idx = mvif->band_idx;
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0017-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
similarity index 86%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-add-thermal-protection-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-add-thermal-protection-support.patch
index bcc5d51..9d85c7c 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0017-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
@@ -1,7 +1,7 @@
-From 1fa1645ef7621981c7e87d27b9a7816f3485d3db Mon Sep 17 00:00:00 2001
+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 17/39] wifi: mt76: mt7996: add thermal protection support
+Subject: [PATCH 05/98] wifi: mt76: mt7996: add thermal protection support
 
 This commit includes the following changes:
 1. implement MTK thermal protection driver API
@@ -10,27 +10,27 @@
 Change-Id: I8fecc28f5b17ee50ae4644d1dd17d188dd694731
 ---
  mt76_connac_mcu.h |   1 +
- mt7996/init.c     | 103 ++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/init.c     | 103 +++++++++++++++++++++++++++++++++++++++++++++
  mt7996/main.c     |   8 ++++
- mt7996/mcu.c      | 106 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.c      | 105 ++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/mcu.h      |  44 +++++++++++++++++++
  mt7996/mt7996.h   |  15 +++++++
- 6 files changed, 277 insertions(+)
+ 6 files changed, 276 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 6249de5..30c9a5d 100644
+index 6064973..99077f1 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1010,6 +1010,7 @@ enum {
- 	MCU_UNI_EVENT_FW_LOG_2_HOST = 0x04,
- 	MCU_UNI_EVENT_IE_COUNTDOWN = 0x09,
+@@ -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,
  };
  
- #define MCU_UNI_CMD_EVENT			BIT(1)
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 8247153..c072b09 100644
+index d335b58..610d80e 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
 @@ -42,6 +42,98 @@ static const struct ieee80211_iface_combination if_comb[] = {
@@ -132,7 +132,7 @@
  static void mt7996_led_set_config(struct led_classdev *led_cdev,
  				  u8 delay_on, u8 delay_off)
  {
-@@ -391,6 +483,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+@@ -419,6 +511,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
  	if (ret)
  		goto error;
  
@@ -143,7 +143,7 @@
  	ret = mt7996_init_debugfs(phy);
  	if (ret)
  		goto error;
-@@ -411,6 +507,8 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
+@@ -446,6 +542,8 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
  	if (!phy)
  		return;
  
@@ -152,7 +152,7 @@
  	mphy = phy->dev->mt76.phys[band];
  	mt76_unregister_phy(mphy);
  	ieee80211_free_hw(mphy->hw);
-@@ -882,6 +980,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1027,6 +1125,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -163,7 +163,7 @@
  	ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
  
  	ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
-@@ -905,6 +1007,7 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
+@@ -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);
@@ -172,7 +172,7 @@
  	mt76_unregister_device(&dev->mt76);
  	mt7996_mcu_exit(dev);
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 02a33b8..9c80839 100644
+index ae4f0ce..280120b 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -51,6 +51,14 @@ int mt7996_run(struct ieee80211_hw *hw)
@@ -183,7 +183,7 @@
 +	if (ret)
 +		goto out;
 +
-+	ret = mt7996_mcu_set_thermal_protect(phy);
++	ret = mt7996_mcu_set_thermal_protect(phy, true);
 +	if (ret)
 +		goto out;
 +
@@ -191,10 +191,10 @@
  
  	ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index c50dcce..c308d86 100644
+index 328bea9..5310f9b 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -447,6 +447,34 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -449,6 +449,34 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
  	}
  }
  
@@ -229,7 +229,7 @@
  static void
  mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb)
  {
-@@ -491,6 +519,9 @@ mt7996_mcu_uni_rx_unsolicited_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;
@@ -239,7 +239,7 @@
  	default:
  		break;
  	}
-@@ -3217,6 +3248,81 @@ out:
+@@ -3450,6 +3481,80 @@ out:
  	return 0;
  }
  
@@ -277,7 +277,7 @@
 +	return 0;
 +}
 +
-+int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy)
++int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable)
 +{
 +#define SUSTAIN_PERIOD		10
 +	struct {
@@ -302,13 +302,12 @@
 +
 +	ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
 +				&req, sizeof(req) - sizeof(req.enable), false);
-+	if (ret)
++	if (ret || !enable)
 +		return ret;
 +
 +	/* set high-temperature trigger threshold */
 +	req.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_ENABLE);
-+	/* add a safety margin ~10 */
-+	req.enable.restore_temp = cpu_to_le32(phy->throttle_temp[0] - 10);
++	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);
 +
@@ -322,7 +321,7 @@
  {
  	struct {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 078f828..f235175 100644
+index e4b3122..f1528df 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
 @@ -30,6 +30,28 @@ struct mt7996_mcu_uni_event {
@@ -377,7 +376,7 @@
  enum mt7996_chan_mib_offs {
  	UNI_MIB_OBSS_AIRTIME = 26,
  	UNI_MIB_NON_WIFI_TIME = 27,
-@@ -659,6 +697,12 @@ enum{
+@@ -656,6 +694,12 @@ enum{
  	UNI_CMD_SR_SET_SIGA = 0xd0,
  };
  
@@ -391,10 +390,10 @@
  	UNI_CMD_ACCESS_REG_BASIC = 0x0,
  	UNI_CMD_ACCESS_RF_REG_BASIC,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 651f53a..071031b 100644
+index ef84173..e1972e9 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -49,6 +49,13 @@
+@@ -50,6 +50,13 @@
  #define MT7996_BASIC_RATES_TBL		11
  #define MT7996_BEACON_RATES_TBL		25
  
@@ -405,10 +404,10 @@
 +#define MT7996_CRIT_TEMP		110
 +#define MT7996_MAX_TEMP			120
 +
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -217,6 +224,11 @@ struct mt7996_phy {
+ #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;
  
@@ -420,13 +419,13 @@
  	u32 rxfilter;
  	u64 omac_mask;
  
-@@ -466,6 +478,9 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
+@@ -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);
++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,
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch
deleted file mode 100644
index d4968dd..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 56d84272851f6c77cf68186bc8906de0558d2e5b Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Fri, 17 Mar 2023 11:08:04 +0800
-Subject: [PATCH 05/11] wifi: mt76: mt7996: init he and eht cap for AP_VLAN
-
-Init he and eht capabilities for AP_VLAN type. Without this patch, the
-BA response from AP_VLAN will not include the ADDBA extension tag.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/init.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/mt7996/init.c b/mt7996/init.c
-index f1b48cdd..004575a0 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -808,6 +808,7 @@ __mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy,
- 		switch (i) {
- 		case NL80211_IFTYPE_STATION:
- 		case NL80211_IFTYPE_AP:
-+		case NL80211_IFTYPE_AP_VLAN:
- #ifdef CONFIG_MAC80211_MESH
- 		case NL80211_IFTYPE_MESH_POINT:
- #endif
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0018-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
similarity index 83%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
index effc63b..a4338f3 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0018-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
@@ -1,15 +1,15 @@
-From db282c765c1d9cd2a5eec6a095069fd4bcf627b4 Mon Sep 17 00:00:00 2001
+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 18/39] wifi: mt76: mt7996: add thermal sensor device support
+Subject: [PATCH 06/98] wifi: mt76: mt7996: add thermal sensor device support
 
 ---
- mt7996/init.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/init.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/mcu.c  | 41 ++++++++++++++++++++++++
- 2 files changed, 128 insertions(+)
+ 2 files changed, 129 insertions(+)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index c072b09..0319e7f 100644
+index 610d80e..de4a5f7 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
 @@ -4,6 +4,8 @@
@@ -21,7 +21,7 @@
  #include <linux/thermal.h>
  #include "mt7996.h"
  #include "mac.h"
-@@ -42,6 +44,81 @@ static const struct ieee80211_iface_combination if_comb[] = {
+@@ -42,6 +44,82 @@ static const struct ieee80211_iface_combination if_comb[] = {
  	}
  };
  
@@ -66,12 +66,13 @@
 +	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]) ||
++	     val > phy->throttle_temp[MT7996_MAX_TEMP_IDX] - 10) ||
 +	    (i - 1 == MT7996_MAX_TEMP_IDX &&
-+	     val < phy->throttle_temp[MT7996_CRIT_TEMP_IDX])) {
++	     val - 10 < phy->throttle_temp[MT7996_CRIT_TEMP_IDX])) {
 +		dev_err(phy->dev->mt76.dev,
-+			"temp1_max shall be greater than temp1_crit.");
++			"temp1_max shall be 10 degrees higher than temp1_crit.");
 +		mutex_unlock(&phy->dev->mt76.mutex);
 +		return -EINVAL;
 +	}
@@ -79,7 +80,7 @@
 +	phy->throttle_temp[i - 1] = val;
 +	mutex_unlock(&phy->dev->mt76.mutex);
 +
-+	ret = mt7996_mcu_set_thermal_protect(phy);
++	ret = mt7996_mcu_set_thermal_protect(phy, true);
 +	if (ret)
 +		return ret;
 +
@@ -103,7 +104,7 @@
  static int
  mt7996_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
  				      unsigned long *state)
-@@ -113,6 +190,7 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
+@@ -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;
@@ -111,7 +112,7 @@
  	const char *name;
  
  	name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7996_%s",
-@@ -131,6 +209,15 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
+@@ -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;
  
@@ -128,10 +129,10 @@
  }
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index c308d86..349c20e 100644
+index 5310f9b..8320c8c 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -3248,6 +3248,47 @@ out:
+@@ -3481,6 +3481,47 @@ out:
  	return 0;
  }
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-enable-VHT-extended-NSS-BW-feature.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-enable-VHT-extended-NSS-BW-feature.patch
deleted file mode 100644
index 348a04a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-enable-VHT-extended-NSS-BW-feature.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 1e7bbf8c04d60eb6cd234990f94da73bccd73118 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Mon, 27 Mar 2023 14:30:25 +0800
-Subject: [PATCH 06/11] wifi: mt76: mt7996: enable VHT extended NSS BW feature
-
-Set SUPPORTS_VHT_EXT_NSS_BW to let the max BW capability correctly be
-parsed by different devices.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/init.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 004575a0..8247153d 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -217,6 +217,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
- 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
- 		phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
- 			IEEE80211_HT_MPDU_DENSITY_1;
-+
-+		ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
- 	}
- 
- 	mt76_set_stream_caps(phy->mt76, true);
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-connac-add-support-to-set-ifs-time-by-mcu-.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-connac-add-support-to-set-ifs-time-by-mcu-.patch
deleted file mode 100644
index 8021427..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-connac-add-support-to-set-ifs-time-by-mcu-.patch
+++ /dev/null
@@ -1,261 +0,0 @@
-From edca876e34fc2696e8f855c2d05036fa79a05f8f Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Thu, 1 Jun 2023 12:01:10 +0800
-Subject: [PATCH 07/11] wifi: mt76: connac: add support to set ifs time by mcu
- command
-
-There's a race between driver and fw on some tx/rx control registers
-when setting ifs, which will cause accidental hw queue pause problems.
-Avoid this by setting ifs time with bss_info mcu command.
-
-Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: Ib6477462a35df84a89f113a4db0e6aef5154c6a8
----
-v2:
-  - merge two commits
-  - change bool a_band to use is_2ghz
----
- mt76_connac_mcu.h |  1 +
- mt7996/mac.c      | 27 ++-------------------------
- mt7996/main.c     |  5 ++---
- mt7996/mcu.c      | 46 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      | 17 +++++++++++++++++
- mt7996/mt7996.h   |  3 ++-
- 6 files changed, 70 insertions(+), 29 deletions(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index d2a3d56b..b91262ee 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1288,6 +1288,7 @@ enum {
- 	UNI_BSS_INFO_UAPSD = 19,
- 	UNI_BSS_INFO_PS = 21,
- 	UNI_BSS_INFO_BCNFT = 22,
-+	UNI_BSS_INFO_IFS_TIME = 23,
- 	UNI_BSS_INFO_OFFLOAD = 25,
- 	UNI_BSS_INFO_MLD = 26,
- };
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 23cbfdde..2da61d2e 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1612,20 +1612,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy)
- 	mt7996_mcu_get_chan_mib_info(phy, true);
- }
- 
--void mt7996_mac_set_timing(struct mt7996_phy *phy)
-+void mt7996_mac_set_coverage_class(struct mt7996_phy *phy)
- {
- 	s16 coverage_class = phy->coverage_class;
- 	struct mt7996_dev *dev = phy->dev;
- 	struct mt7996_phy *phy2 = mt7996_phy2(dev);
- 	struct mt7996_phy *phy3 = mt7996_phy3(dev);
--	u32 val, reg_offset;
-+	u32 reg_offset;
- 	u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) |
- 		  FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
- 	u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
- 		   FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
- 	u8 band_idx = phy->mt76->band_idx;
- 	int offset;
--	bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
- 
- 	if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
- 		return;
-@@ -1638,34 +1637,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy)
- 		coverage_class = max_t(s16, coverage_class,
- 				       phy3->coverage_class);
- 
--	mt76_set(dev, MT_ARB_SCR(band_idx),
--		 MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
--	udelay(1);
--
- 	offset = 3 * coverage_class;
- 	reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |
- 		     FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);
- 
- 	mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset);
- 	mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset);
--	mt76_wr(dev, MT_TMAC_ICR0(band_idx),
--		FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
--		FIELD_PREP(MT_IFS_RIFS, 2) |
--		FIELD_PREP(MT_IFS_SIFS, 10) |
--		FIELD_PREP(MT_IFS_SLOT, phy->slottime));
--
--	if (!a_band)
--		mt76_wr(dev, MT_TMAC_ICR1(band_idx),
--			FIELD_PREP(MT_IFS_EIFS_CCK, 314));
--
--	if (phy->slottime < 20 || a_band)
--		val = MT7996_CFEND_RATE_DEFAULT;
--	else
--		val = MT7996_CFEND_RATE_11B;
--
--	mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val);
--	mt76_clear(dev, MT_ARB_SCR(band_idx),
--		   MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
- }
- 
- void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band)
-diff --git a/mt7996/main.c b/mt7996/main.c
-index e7c97d2f..786c3fbc 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -287,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy)
- 	if (ret)
- 		goto out;
- 
--	mt7996_mac_set_timing(phy);
- 	ret = mt7996_dfs_init_radar_detector(phy);
- 	mt7996_mac_cca_stats_reset(phy);
- 
-@@ -564,7 +563,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
- 
- 		if (slottime != phy->slottime) {
- 			phy->slottime = slottime;
--			mt7996_mac_set_timing(phy);
-+			mt7996_mcu_set_timing(phy, vif);
- 		}
- 	}
- 
-@@ -904,7 +903,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
- 
- 	mutex_lock(&dev->mt76.mutex);
- 	phy->coverage_class = max_t(s16, coverage_class, 0);
--	mt7996_mac_set_timing(phy);
-+	mt7996_mac_set_coverage_class(phy);
- 	mutex_unlock(&dev->mt76.mutex);
- }
- 
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 6706d38c..0ede9769 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -701,6 +701,34 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif,
- 				 sizeof(req), true);
- }
- 
-+static void
-+mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
-+{
-+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+	struct mt7996_phy *phy = mvif->phy;
-+	struct bss_ifs_time_tlv *ifs_time;
-+	struct tlv *tlv;
-+	bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ;
-+
-+	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time));
-+
-+	ifs_time = (struct bss_ifs_time_tlv *)tlv;
-+	ifs_time->slot_valid = true;
-+	ifs_time->sifs_valid = true;
-+	ifs_time->rifs_valid = true;
-+	ifs_time->eifs_valid = true;
-+
-+	ifs_time->slot_time = cpu_to_le16(phy->slottime);
-+	ifs_time->sifs_time = cpu_to_le16(10);
-+	ifs_time->rifs_time = cpu_to_le16(2);
-+	ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84);
-+
-+	if (is_2ghz) {
-+		ifs_time->eifs_cck_valid = true;
-+		ifs_time->eifs_cck_time = cpu_to_le16(314);
-+	}
-+}
-+
- static int
- mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- 			 struct ieee80211_vif *vif,
-@@ -826,6 +854,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
- 		mt7996_mcu_bss_bmc_tlv(skb, vif, phy);
- 		mt7996_mcu_bss_ra_tlv(skb, vif, phy);
- 		mt7996_mcu_bss_txcmd_tlv(skb, true);
-+		mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
- 
- 		if (vif->bss_conf.he_support)
- 			mt7996_mcu_bss_he_tlv(skb, vif, phy);
-@@ -838,6 +867,23 @@ out:
- 				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
- }
- 
-+int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
-+{
-+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+	struct mt7996_dev *dev = phy->dev;
-+	struct sk_buff *skb;
-+
-+	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
-+					 MT7996_BSS_UPDATE_MAX_SIZE);
-+	if (IS_ERR(skb))
-+		return PTR_ERR(skb);
-+
-+	mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
-+
-+	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-+				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
-+}
-+
- static int
- mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
- 		  struct ieee80211_ampdu_params *params,
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index d7075a4d..078f8285 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -317,6 +317,22 @@ struct bss_sec_tlv {
- 	u8 __rsv2[1];
- } __packed;
- 
-+struct bss_ifs_time_tlv {
-+	__le16 tag;
-+	__le16 len;
-+	u8 slot_valid;
-+	u8 sifs_valid;
-+	u8 rifs_valid;
-+	u8 eifs_valid;
-+	__le16 slot_time;
-+	__le16 sifs_time;
-+	__le16 rifs_time;
-+	__le16 eifs_time;
-+	u8 eifs_cck_valid;
-+	u8 rsv;
-+	__le16 eifs_cck_time;
-+} __packed;
-+
- struct bss_power_save {
- 	__le16 tag;
- 	__le16 len;
-@@ -552,6 +568,7 @@ enum {
- 					 sizeof(struct bss_txcmd_tlv) +		\
- 					 sizeof(struct bss_power_save) +	\
- 					 sizeof(struct bss_sec_tlv) +		\
-+					 sizeof(struct bss_ifs_time_tlv) +	\
- 					 sizeof(struct bss_mld_tlv))
- 
- #define MT7996_STA_UPDATE_MAX_SIZE	(sizeof(struct sta_req_hdr) +		\
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 7dfdc738..42892f06 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -463,6 +463,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index,
- 			    const struct mt7996_dfs_pattern *pattern);
- 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_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
- 		       u8 rx_sel, u8 val);
-@@ -526,7 +527,7 @@ 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,
- 			   enum mt76_txq_id qid, u32 changed);
--void mt7996_mac_set_timing(struct mt7996_phy *phy);
-+void mt7996_mac_set_coverage_class(struct mt7996_phy *phy);
- int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- 		       struct ieee80211_sta *sta);
- void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0035-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
similarity index 67%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0035-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
index 6864e26..873029f 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0035-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
@@ -1,7 +1,7 @@
-From 18ed969cf7bfdaa059ed946f5bacd62a2ebf9ffe Mon Sep 17 00:00:00 2001
+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 35/39] wifi: mt76: mt7996: make band capability init flexible
+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.
@@ -9,20 +9,20 @@
 Change-Id: Ifcb49504f02f5cc6a23c626e30b4f0e1360fe157
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 ---
- mt7996/dma.c    |  8 ++++----
+ mt7996/dma.c    | 14 +++++++-------
  mt7996/init.c   | 29 ++++++++++++++++++-----------
  mt7996/mcu.c    | 13 +++++--------
  mt7996/mt7996.h | 11 +++++++++++
  mt7996/regs.h   |  3 +++
- 5 files changed, 41 insertions(+), 23 deletions(-)
+ 5 files changed, 44 insertions(+), 26 deletions(-)
 
 diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 6a21e3e..f01cea5 100644
+index 2221d22..3d04470 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -159,13 +159,13 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
- 
- 	irq_mask |= (MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU);
+@@ -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))
@@ -36,23 +36,50 @@
 +	if (mt7996_band_valid(dev, MT_BAND2))
  		irq_mask |= MT_INT_BAND2_RX_DONE;
  
- done:
-@@ -334,7 +334,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 	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],
- 				       MT_RXQ_ID(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 0562439..0825e0b 100644
+index de4a5f7..2e6efc5 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -529,11 +529,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	u32 mac_ofs, hif1_ofs = 0;
+@@ -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;
@@ -63,7 +90,7 @@
  		return 0;
  
  	if (phy)
-@@ -648,8 +644,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -782,8 +778,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  
  	INIT_WORK(&dev->init_work, mt7996_init_work);
  
@@ -76,7 +103,7 @@
  
  	ret = mt7996_dma_init(dev);
  	if (ret)
-@@ -1089,8 +1087,6 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1217,8 +1215,6 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -85,7 +112,7 @@
  	ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
  	if (ret)
  		return ret;
-@@ -1099,13 +1095,24 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1227,13 +1223,24 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -113,7 +140,7 @@
  
  void mt7996_unregister_device(struct mt7996_dev *dev)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index c647979..9fb800a 100644
+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)
@@ -144,10 +171,10 @@
  	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 f59dce7..488f59c 100644
+index e1972e9..137d5a2 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -431,6 +431,17 @@ mt7996_phy3(struct mt7996_dev *dev)
+@@ -381,6 +381,17 @@ mt7996_phy3(struct mt7996_dev *dev)
  	return __mt7996_phy(dev, MT_BAND2);
  }
  
@@ -166,10 +193,10 @@
  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 c054586..3a5914c 100644
+index 854390d..a4d5ad8 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -546,6 +546,9 @@ enum base_rev {
+@@ -602,6 +602,9 @@ enum base_rev {
  #define MT_TOP_MISC				MT_TOP(0xf0)
  #define MT_TOP_MISC_FW_STATE			GENMASK(2, 0)
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0037-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
similarity index 82%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0037-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
index 5dc8109..a5b808a 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0037-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
@@ -1,7 +1,7 @@
-From de92f88f5c00cf1069df00bb89f50281b0b2d05e Mon Sep 17 00:00:00 2001
+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 37/39] wifi: mt76: mt7996: add beacon duplicate tx mode
+Subject: [PATCH 08/98] wifi: mt76: mt7996: add beacon duplicate tx mode
  support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,22 +16,22 @@
  7 files changed, 69 insertions(+), 25 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index bfec420..4bb9508 100644
+index 99077f1..90c08d2 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1224,6 +1224,7 @@ enum {
+@@ -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_TESTMODE_CTRL = 0x46,
  	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 1072874..9eba689 100644
+index 2e6efc5..17a4abd 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -351,6 +351,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+@@ -354,6 +354,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
  		IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
  
  	phy->slottime = 9;
@@ -39,7 +39,7 @@
  
  	hw->sta_data_size = sizeof(struct mt7996_sta);
  	hw->vif_data_size = sizeof(struct mt7996_vif);
-@@ -459,11 +460,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
+@@ -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;
@@ -55,10 +55,10 @@
  }
  
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 724af82..05269e7 100644
+index 4be5410..6688186 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -252,17 +252,6 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
+@@ -248,17 +248,6 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
  		mt76_clear(dev, addr, BIT(5));
  }
  
@@ -73,15 +73,15 @@
 -	mt76_wr(dev, MT_WTBL_ITCR, ctrl);
 -}
 -
- static void
- mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
- 				 struct ieee80211_radiotap_he *he,
+ /* 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 20b89a7..2ed66e6 100644
+index 280120b..41f0fa1 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -544,24 +544,25 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+@@ -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;
@@ -101,7 +101,7 @@
 +			mt7996_mcu_set_fixed_rate_table(phy, idx, rate, beacon);
  
 -		/* must odd index */
--		idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->mt76.idx % 20);
+-		idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->idx % 20);
 -		mt7996_mac_set_fixed_rate_table(dev, idx, rate);
  		return idx;
  	}
@@ -114,7 +114,7 @@
  
  	return mvif->basic_rates_idx;
  }
-@@ -965,7 +966,6 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+@@ -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);
  
@@ -123,10 +123,10 @@
  
  	return 0;
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index a5c473a..b34c6b7 100644
+index 84f362b..dbb3ceb 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -4056,6 +4056,36 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+@@ -4055,6 +4055,36 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
  				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
  }
  
@@ -164,10 +164,10 @@
  {
  	struct {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index eb63441..e32767e 100644
+index f1528df..c20a947 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -771,4 +771,24 @@ enum {
+@@ -738,4 +738,24 @@ enum {
  #define MT7996_SEC_KEY_IDX		GENMASK(2, 1)
  #define MT7996_SEC_IV			BIT(3)
  
@@ -193,10 +193,10 @@
 +
  #endif
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index f78f1fd..286fc1e 100644
+index 137d5a2..21ad51d 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -48,7 +48,7 @@
+@@ -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 */
@@ -205,7 +205,7 @@
  #define MT7996_BEACON_RATES_TBL		25
  
  #define MT7996_THERMAL_THROTTLE_MAX	100
-@@ -256,6 +256,8 @@ struct mt7996_phy {
+@@ -213,6 +213,8 @@ struct mt7996_phy {
  
  	u8 rdd_state;
  
@@ -214,7 +214,7 @@
  	u32 rx_ampdu_ts;
  	u32 ampdu_ref;
  
-@@ -539,6 +541,8 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+@@ -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);
@@ -223,7 +223,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);
-@@ -606,8 +610,6 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
+@@ -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);
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch
deleted file mode 100644
index 24d2bfd..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 9cf96fa56a20d30f7e46e96d9c48c3568fbf11af Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Tue, 7 Mar 2023 17:05:01 +0800
-Subject: [PATCH 08/11] wifi: mt76: mt7996: use correct phy for background
- radar event
-
-If driver directly uses the band_idx reported from the radar event to
-access mt76_phy array, it will get the wrong phy for background radar.
-Fix this by adjusting the statement.
-
-Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/mcu.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 0ede9769..20519bff 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -339,7 +339,11 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
- 	if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
- 		return;
- 
--	mphy = dev->mt76.phys[r->band_idx];
-+	if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2)
-+		mphy = dev->rdd2_phy->mt76;
-+	else
-+		mphy = dev->mt76.phys[r->band_idx];
-+
- 	if (!mphy)
- 		return;
- 
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-WA-event-ring-size.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-WA-event-ring-size.patch
deleted file mode 100644
index 6ffa018..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-WA-event-ring-size.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From f9ac23ac488c0dafceab97c8d39a22904cf78f77 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Thu, 23 Mar 2023 15:16:14 +0800
-Subject: [PATCH 09/11] wifi: mt76: mt7996: fix WA event ring size
-
-Fix rx ring size of WA event to get rid of event loss and queue overflow
-problems.
-
-Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/dma.c    | 2 +-
- mt7996/mt7996.h | 1 +
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 53414346..fbedaacf 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -293,7 +293,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 	/* event from WA */
- 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
- 			       MT_RXQ_ID(MT_RXQ_MCU_WA),
--			       MT7996_RX_MCU_RING_SIZE,
-+			       MT7996_RX_MCU_RING_SIZE_WA,
- 			       MT_RX_BUF_SIZE,
- 			       MT_RXQ_RING_BASE(MT_RXQ_MCU_WA));
- 	if (ret)
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 42892f06..a3bd85d3 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -26,6 +26,7 @@
- 
- #define MT7996_RX_RING_SIZE		1536
- #define MT7996_RX_MCU_RING_SIZE		512
-+#define MT7996_RX_MCU_RING_SIZE_WA	1024
- 
- #define MT7996_FIRMWARE_WA		"mediatek/mt7996/mt7996_wa.bin"
- #define MT7996_FIRMWARE_WM		"mediatek/mt7996/mt7996_wm.bin"
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0039-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
similarity index 76%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0039-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
index c2fed58..b151c94 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0039-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
@@ -1,7 +1,7 @@
-From affb48f4b09fca1e4df1e2291c78ee01b877e40f Mon Sep 17 00:00:00 2001
+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 39/39] wifi: mt76: mt7996: fix bss rate tlv to sync firmware
+Subject: [PATCH 09/98] wifi: mt76: mt7996: fix bss rate tlv to sync firmware
  change
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index e32767e..549007f 100644
+index c20a947..78ecd75 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
 @@ -259,7 +259,7 @@ struct bss_rate_tlv {
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-add-muru-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-add-muru-support.patch
deleted file mode 100644
index c0f61b7..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-add-muru-support.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 8a284ffc268754a8e941888ce6f1b506f3c7564c Mon Sep 17 00:00:00 2001
-From: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
-Date: Mon, 28 Nov 2022 14:36:09 +0800
-Subject: [PATCH 10/11] wifi: mt76: mt7996: add muru support
-
-Add sta_rec_muru() fw command to support MU-MIMO and OFDMA features.
-
-Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt76_connac_mcu.h |  3 ++-
- mt7996/mcu.c      | 56 ++++++++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 57 insertions(+), 2 deletions(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index b91262ee..6249de57 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -519,7 +519,8 @@ struct sta_rec_muru {
- 		u8 uo_ra;
- 		u8 he_2x996_tone;
- 		u8 rx_t_frame_11ac;
--		u8 rsv[3];
-+		u8 rx_ctrl_frame_to_mbss;
-+		u8 rsv[2];
- 	} ofdma_ul;
- 
- 	struct {
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 20519bff..611f6450 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -1101,6 +1101,59 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
- 	}
- }
- 
-+static void
-+mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
-+			struct ieee80211_vif *vif, struct ieee80211_sta *sta)
-+{
-+	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
-+	struct sta_rec_muru *muru;
-+	struct tlv *tlv;
-+
-+	if (vif->type != NL80211_IFTYPE_STATION &&
-+	    vif->type != NL80211_IFTYPE_AP)
-+		return;
-+
-+	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));
-+
-+	muru = (struct sta_rec_muru *)tlv;
-+	muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer ||
-+			       vif->bss_conf.he_mu_beamformer ||
-+			       vif->bss_conf.vht_mu_beamformer ||
-+			       vif->bss_conf.vht_mu_beamformee;
-+	muru->cfg.ofdma_dl_en = true;
-+
-+	if (sta->deflink.vht_cap.vht_supported)
-+		muru->mimo_dl.vht_mu_bfee =
-+			!!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
-+
-+	if (!sta->deflink.he_cap.has_he)
-+		return;
-+
-+	muru->mimo_dl.partial_bw_dl_mimo =
-+		HE_PHY(CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO, elem->phy_cap_info[6]);
-+
-+	muru->mimo_ul.full_ul_mimo =
-+		HE_PHY(CAP2_UL_MU_FULL_MU_MIMO, elem->phy_cap_info[2]);
-+	muru->mimo_ul.partial_ul_mimo =
-+		HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]);
-+
-+	muru->ofdma_dl.punc_pream_rx =
-+		HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
-+	muru->ofdma_dl.he_20m_in_40m_2g =
-+		HE_PHY(CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G, elem->phy_cap_info[8]);
-+	muru->ofdma_dl.he_20m_in_160m =
-+		HE_PHY(CAP8_20MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);
-+	muru->ofdma_dl.he_80m_in_160m =
-+		HE_PHY(CAP8_80MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);
-+
-+	muru->ofdma_ul.t_frame_dur =
-+		HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
-+	muru->ofdma_ul.mu_cascading =
-+		HE_MAC(CAP2_MU_CASCADING, elem->mac_cap_info[2]);
-+	muru->ofdma_ul.uo_ra =
-+		HE_MAC(CAP3_OFDMA_RA, elem->mac_cap_info[3]);
-+}
-+
- static inline bool
- mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,
- 			struct ieee80211_sta *sta, bool bfee)
-@@ -1778,7 +1831,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- 		mt7996_mcu_sta_he_6g_tlv(skb, sta);
- 		/* starec eht */
- 		mt7996_mcu_sta_eht_tlv(skb, sta);
--		/* TODO: starec muru */
-+		/* starec muru */
-+		mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta);
- 		/* starec bfee */
- 		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
- 		/* starec hdr trans */
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0041-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
similarity index 76%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0041-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
index f6e14b7..ca966b6 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0041-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
@@ -1,7 +1,7 @@
-From 78bc83a6a4dc69f135c6a32756e8acb96c64b1bf Mon Sep 17 00:00:00 2001
+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] wifi: mt76: mt7996: adjust wfdma setting to enhance
+Subject: [PATCH 10/98] wifi: mt76: mt7996: adjust wfdma setting to enhance
  throughput
 
 1. Set band 1 traffic to pcie1.
@@ -10,15 +10,15 @@
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
 ---
- mt7996/dma.c  | 57 ++++++++++++++++++++++++++++++++++++++-------------
- mt7996/regs.h |  9 ++++++++
- 2 files changed, 52 insertions(+), 14 deletions(-)
+ 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 f01cea5e..bb390517 100644
+index 3d04470..1ed91da 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -56,22 +56,34 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
+@@ -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);
  }
  
@@ -62,11 +62,33 @@
 +	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));
-+#undef PREFETCH
  
- 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
- }
-@@ -223,6 +235,12 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ 	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);
  
@@ -79,7 +101,7 @@
  	if (dev->hif2) {
  		/* GLO_CFG_EXT0 */
  		mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
-@@ -234,7 +252,18 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+@@ -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,
@@ -100,10 +122,10 @@
  
  	if (dev->hif2) {
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 3a5914c4..5917ba1a 100644
+index a4d5ad8..f7c99cd 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -333,6 +333,11 @@ enum base_rev {
+@@ -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)
  
@@ -115,7 +137,7 @@
  #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)
-@@ -355,10 +360,14 @@ enum base_rev {
+@@ -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)
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
new file mode 100644
index 0000000..d32dea5
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch
@@ -0,0 +1,46 @@
+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/0011-wifi-mt76-mt7996-increase-tx-token-size.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-increase-tx-token-size.patch
deleted file mode 100644
index aa039ce..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-increase-tx-token-size.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0cc8d7827510e36978175d84d63cced5f842ff61 Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Mon, 17 Apr 2023 09:49:53 +0800
-Subject: [PATCH 11/11] wifi: mt76: mt7996: increase tx token size
-
-Align tx token size to proprietary driver, which can improve peak
-throughput under MU performance tests.
-
-Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7996/mt7996.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index a3bd85d3..651f53aa 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -36,7 +36,7 @@
- #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
- #define MT7996_EEPROM_SIZE		7680
- #define MT7996_EEPROM_BLOCK_SIZE	16
--#define MT7996_TOKEN_SIZE		8192
-+#define MT7996_TOKEN_SIZE		16384
- 
- #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
- #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
--- 
-2.39.2
-
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
new file mode 100644
index 0000000..3a49f34
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0012-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch
@@ -0,0 +1,72 @@
+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-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
new file mode 100644
index 0000000..5f85886
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0013-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch
@@ -0,0 +1,154 @@
+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-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
new file mode 100644
index 0000000..1a93d0b
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
@@ -0,0 +1,170 @@
+From 6a8359a808df29b708b2fd2aa84c0a369be7a7d5 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
+ 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
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -86,7 +86,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);
+ 
+-	dev->reg_l1_backup = dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);
+ 	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)
+ 	u32 offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET, addr);
+ 	u32 base = FIELD_GET(MT_HIF_REMAP_L2_BASE, addr);
+ 
+-	dev->reg_l2_backup = dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2);
+ 	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)
+ 	return MT_HIF_REMAP_BASE_L2 + offset;
+ }
+ 
+-static void mt7996_reg_remap_restore(struct mt7996_dev *dev)
+-{
+-	/* remap to ori status */
+-	if (unlikely(dev->reg_l1_backup)) {
+-		dev->bus_ops->wr(&dev->mt76, MT_HIF_REMAP_L1, dev->reg_l1_backup);
+-		dev->reg_l1_backup = 0;
+-	}
+-
+-	if (dev->reg_l2_backup) {
+-		dev->bus_ops->wr(&dev->mt76, MT_HIF_REMAP_L2, dev->reg_l2_backup);
+-		dev->reg_l2_backup = 0;
+-	}
+-}
+-
+ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
+ {
+ 	int i;
+ 
+-	mt7996_reg_remap_restore(dev);
+-
+ 	if (addr < 0x100000)
+ 		return addr;
+ 
+@@ -147,6 +129,11 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
+ 		return dev->reg.map[i].mapped + ofs;
+ 	}
+ 
++	return 0;
++}
++
++static u32 __mt7996_reg_remap_addr(struct mt7996_dev *dev, u32 addr)
++{
+ 	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,
+ {
+ 	u32 addr = __mt7996_reg_addr(dev, offset);
+ 
+-	memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len);
++	unsigned long flags;
++
++	if (addr) {
++		memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len);
++		return;
++	}
++
++	spin_lock_irqsave(&dev->reg_lock, flags);
++	memcpy_fromio(buf, dev->mt76.mmio.regs +
++			   __mt7996_reg_remap_addr(dev, offset), len);
++	spin_unlock_irqrestore(&dev->reg_lock, flags);
+ }
+ 
+ static u32 mt7996_rr(struct mt76_dev *mdev, u32 offset)
+ {
+ 	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
++	u32 addr = __mt7996_reg_addr(dev, offset), val;
++	unsigned long flags;
++
++	if (addr)
++		return dev->bus_ops->rr(mdev, addr);
+ 
+-	return dev->bus_ops->rr(mdev, __mt7996_reg_addr(dev, offset));
++	spin_lock_irqsave(&dev->reg_lock, flags);
++	val = dev->bus_ops->rr(mdev, __mt7996_reg_remap_addr(dev, offset));
++	spin_unlock_irqrestore(&dev->reg_lock, flags);
++
++	return val;
+ }
+ 
+ static void mt7996_wr(struct mt76_dev *mdev, u32 offset, u32 val)
+ {
+ 	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
++	u32 addr = __mt7996_reg_addr(dev, offset);
++	unsigned long flags;
+ 
+-	dev->bus_ops->wr(mdev, __mt7996_reg_addr(dev, offset), val);
++	if (addr) {
++		dev->bus_ops->wr(mdev, addr, val);
++		return;
++	}
++
++	spin_lock_irqsave(&dev->reg_lock, flags);
++	dev->bus_ops->wr(mdev, __mt7996_reg_remap_addr(dev, offset), val);
++	spin_unlock_irqrestore(&dev->reg_lock, flags);
+ }
+ 
+ static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+ {
+ 	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
++	u32 addr = __mt7996_reg_addr(dev, offset);
++	unsigned long flags;
++
++	if (addr)
++		return dev->bus_ops->rmw(mdev, addr, mask, val);
++
++	spin_lock_irqsave(&dev->reg_lock, flags);
++	val = dev->bus_ops->rmw(mdev, __mt7996_reg_remap_addr(dev, offset), mask, val);
++	spin_unlock_irqrestore(&dev->reg_lock, flags);
+ 
+-	return dev->bus_ops->rmw(mdev, __mt7996_reg_addr(dev, offset), mask, val);
++	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,
+ 
+ 	dev = container_of(mdev, struct mt7996_dev, mt76);
+ 	mt76_mmio_init(&dev->mt76, mem_base);
++	spin_lock_init(&dev->reg_lock);
+ 
+ 	switch (device_id) {
+ 	case 0x7990:
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index c8e7a33..c0ceef0 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -309,8 +309,7 @@ struct mt7996_dev {
+ 		u8 n_agrt;
+ 	} twt;
+ 
+-	u32 reg_l1_backup;
+-	u32 reg_l2_backup;
++	spinlock_t reg_lock;
+ 
+ 	u8 wtbl_size_group;
+ };
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-set-wcid-in-txp.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-set-wcid-in-txp.patch
deleted file mode 100644
index 8103127..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-set-wcid-in-txp.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 5e2177e77b9609185f748708332aa6a6fdf4d1f9 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Mon, 6 Mar 2023 15:52:26 +0800
-Subject: [PATCH 14/39] wifi: mt76: mt7996: set wcid in txp
-
-Set correct wcid in txp for SDO to get wtbl.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Change-Id: Ie715a659ff52f2d85332158f273d0ee4fe9f4051
----
- mt7996/mac.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 2da61d2..bddb84f 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1166,10 +1166,12 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- 	}
- 
- 	txp->fw.token = cpu_to_le16(id);
--	if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags))
--		txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx);
--	else
-+	if ((is_8023 && is_multicast_ether_addr(tx_info->skb->data)) ||
-+	    (!is_8023 && is_multicast_ether_addr(hdr->addr1)))
- 		txp->fw.rept_wds_wcid = cpu_to_le16(0xfff);
-+	else
-+		txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx);
-+
- 	tx_info->skb = DMA_DUMMY_DATA;
- 
- 	/* pass partial skb header to fw */
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
similarity index 77%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
index e6a4f75..381c929 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
@@ -1,7 +1,7 @@
-From eec83d4410d7c669d9a05bba1a69a742a6ccd490 Mon Sep 17 00:00:00 2001
+From 09a1b2d9ad49d3bea1bdd8d4f7326af6a65a3dbb 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 16/39] wifi: mt76: connac: set correct muar_idx for connac3
+Subject: [PATCH 15/98] 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
@@ -15,10 +15,10 @@
  2 files changed, 8 insertions(+)
 
 diff --git a/mt76_connac.h b/mt76_connac.h
-index 77ca8f0..02acac6 100644
+index e5ebde1..c6726ab 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
-@@ -240,6 +240,11 @@ static inline bool is_connac_v1(struct mt76_dev *dev)
+@@ -245,6 +245,11 @@ static inline bool is_connac_v1(struct mt76_dev *dev)
  	return is_mt7615(dev) || is_mt7663(dev) || is_mt7622(dev);
  }
  
@@ -31,10 +31,10 @@
  {
  	switch (mt76_chip(dev)) {
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 46f69aa..5fab677 100644
+index bcd6c20..68de525 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -281,6 +281,9 @@ __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
+@@ -282,6 +282,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/0015-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch
deleted file mode 100644
index ea01cf0..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 5580f05c864aadfad4092fc97a937869dc08eca8 Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Thu, 16 Feb 2023 00:39:01 +0800
-Subject: [PATCH 15/39] wifi: mt76: mt7996: reduce repeated bss_info and
- sta_rec commands
-
-Refine the flow of setting bss_info and sta_rec commands to prevent from
-sending duplicated commands, especially for station mode.
-
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: Iffd2c81f9ec98284793e75f4b7d39e9618977024
----
- mt7996/main.c | 21 ++++++---------------
- 1 file changed, 6 insertions(+), 15 deletions(-)
-
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 786c3fb..02a33b8 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -248,8 +248,8 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
- 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
- 	int idx = msta->wcid.idx;
- 
--	mt7996_mcu_add_bss_info(phy, vif, false);
- 	mt7996_mcu_add_sta(dev, vif, NULL, false);
-+	mt7996_mcu_add_bss_info(phy, vif, false);
- 
- 	if (vif == phy->monitor_vif)
- 		phy->monitor_vif = NULL;
-@@ -544,17 +544,13 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
- 	/* station mode uses BSSID to map the wlan entry to a peer,
- 	 * and then peer references bss_info_rfch to set bandwidth cap.
- 	 */
--	if (changed & BSS_CHANGED_BSSID &&
--	    vif->type == NL80211_IFTYPE_STATION) {
--		bool join = !is_zero_ether_addr(info->bssid);
--
--		mt7996_mcu_add_bss_info(phy, vif, join);
--		mt7996_mcu_add_sta(dev, vif, NULL, join);
-+	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)) {
-+		mt7996_mcu_add_bss_info(phy, vif, true);
-+		mt7996_mcu_add_sta(dev, vif, NULL, true);
- 	}
- 
--	if (changed & BSS_CHANGED_ASSOC)
--		mt7996_mcu_add_bss_info(phy, vif, vif->cfg.assoc);
--
- 	if (changed & BSS_CHANGED_ERP_CTS_PROT)
- 		mt7996_mac_enable_rtscts(dev, vif, info->use_cts_prot);
- 
-@@ -575,11 +571,6 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
- 		mvif->basic_rates_idx =
- 			mt7996_get_rates_table(hw, vif, false, false);
- 
--	if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
--		mt7996_mcu_add_bss_info(phy, vif, true);
--		mt7996_mcu_add_sta(dev, vif, NULL, true);
--	}
--
- 	/* ensure that enable txcmd_mode after bss_info */
- 	if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
- 		mt7996_mcu_set_tx(dev, vif);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0034-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0034-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
index 3d4d1c0..a850a6c 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0034-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
@@ -1,7 +1,7 @@
-From cf66e6fc90e7a12209bd0a3d9b687b37f7324718 Mon Sep 17 00:00:00 2001
+From 4d055393b680ce616cb96f75cca154016cfb9a68 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] wifi: mt76: mt7996: add firmware WA's coredump.
+Subject: [PATCH 16/98] wifi: mt76: mt7996: add firmware WA's coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 Change-Id: I51f115b4ae15bc0f871f93652570d72511dbf880
@@ -15,7 +15,7 @@
  6 files changed, 182 insertions(+), 83 deletions(-)
 
 diff --git a/mt7996/coredump.c b/mt7996/coredump.c
-index ccab0d7b..60b88085 100644
+index ccab0d7..60b8808 100644
 --- a/mt7996/coredump.c
 +++ b/mt7996/coredump.c
 @@ -7,11 +7,11 @@
@@ -336,7 +336,7 @@
  }
  
 diff --git a/mt7996/coredump.h b/mt7996/coredump.h
-index af2ba219..01ed3731 100644
+index af2ba21..01ed373 100644
 --- a/mt7996/coredump.h
 +++ b/mt7996/coredump.h
 @@ -6,10 +6,13 @@
@@ -429,10 +429,10 @@
  	return NULL;
  }
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 986031f5..724af82a 100644
+index ccb7b22..066955e 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -2082,28 +2082,25 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -1962,28 +1962,25 @@ void mt7996_mac_reset_work(struct work_struct *work)
  }
  
  /* firmware coredump */
@@ -465,7 +465,7 @@
  	if (!mem_region || !crash_data->memdump_buf_len) {
  		mutex_unlock(&dev->dump_mutex);
  		goto skip_memdump;
-@@ -2113,6 +2110,9 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -1993,6 +1990,9 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	buf_len = crash_data->memdump_buf_len;
  
  	/* dumping memory content... */
@@ -475,7 +475,7 @@
  	memset(buf, 0, buf_len);
  	for (i = 0; i < num; i++) {
  		if (mem_region->len > buf_len) {
-@@ -2129,6 +2129,7 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2009,6 +2009,7 @@ void mt7996_mac_dump_work(struct work_struct *work)
  		mt7996_memcpy_fromio(dev, buf, mem_region->start,
  				     mem_region->len);
  
@@ -483,7 +483,7 @@
  		hdr->start = mem_region->start;
  		hdr->len = mem_region->len;
  
-@@ -2145,8 +2146,20 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2025,8 +2026,20 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	mutex_unlock(&dev->dump_mutex);
  
  skip_memdump:
@@ -507,7 +507,7 @@
  }
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 38292da3..14f7a43f 100644
+index ee1915c..2c611e7 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -2458,6 +2458,8 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
@@ -530,27 +530,27 @@
  		 fw_type, hdr->fw_ver, hdr->build_date);
  
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 561c1cdc..f59dce77 100644
+index c0ceef0..0bb20a9 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -58,6 +58,8 @@
+@@ -57,6 +57,8 @@
  #define MT7996_CRIT_TEMP		110
  #define MT7996_MAX_TEMP			120
  
 +#define MT7996_BUILD_TIME_LEN		24
 +
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -68,6 +70,7 @@ enum mt7996_ram_type {
- 	MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
+ #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 {
+ 	MT7996_RAM_TYPE_WM,
  	MT7996_RAM_TYPE_WA,
  	MT7996_RAM_TYPE_DSP,
 +	__MT7996_RAM_TYPE_MAX,
  };
  
  enum mt7996_txq_id {
-@@ -306,9 +309,11 @@ struct mt7996_dev {
+@@ -265,9 +268,11 @@ struct mt7996_dev {
  	struct mutex dump_mutex;
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
@@ -562,12 +562,12 @@
 +	char ram_build_date[__MT7996_RAM_TYPE_MAX][MT7996_BUILD_TIME_LEN];
  
  	struct list_head sta_rc_list;
- 	struct list_head sta_poll_list;
+ 	struct list_head twt_list;
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 86da1bf8..c054586d 100644
+index f7c99cd..bd0eb51 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -482,7 +482,8 @@ enum base_rev {
+@@ -548,7 +548,8 @@ enum base_rev {
  
  /* FW MODE SYNC */
  #define MT_FW_ASSERT_CNT			0x02208274
@@ -577,7 +577,7 @@
  
  #define MT_SWDEF_BASE				0x00401400
  
-@@ -580,11 +581,15 @@ enum base_rev {
+@@ -656,11 +657,15 @@ enum base_rev {
  #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR		BIT(29)
  
  /* CONN MCU EXCP CON */
@@ -594,5 +594,5 @@
  
  #endif
 -- 
-2.39.2
+2.18.0
 
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
new file mode 100644
index 0000000..54d32c3
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch
@@ -0,0 +1,107 @@
+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/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
new file mode 100644
index 0000000..5110644
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch
@@ -0,0 +1,249 @@
+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-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
new file mode 100644
index 0000000..6505422
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch
@@ -0,0 +1,182 @@
+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/0019-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch
deleted file mode 100644
index 1fef46a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 2fe477b8db9ab494a975a565a28e35fff76505d1 Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Thu, 16 Mar 2023 16:09:51 +0800
-Subject: [PATCH 19/39] wifi: mt76: mt7996: fix beamform mcu cmd configuration
-
-bf_num means how many band can support beamform, so the value shall be 3.
-bf_bitmap represents which band can support beamform.
----
- mt7996/mcu.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 349c20e..62e4869 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -3444,8 +3444,8 @@ int mt7996_mcu_set_txbf(struct mt7996_dev *dev, u8 action)
- 
- 		tlv = mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req_mod_en));
- 		req_mod_en = (struct bf_mod_en_ctrl *)tlv;
--		req_mod_en->bf_num = 2;
--		req_mod_en->bf_bitmap = GENMASK(0, 0);
-+		req_mod_en->bf_num = 3;
-+		req_mod_en->bf_bitmap = GENMASK(2, 0);
- 		break;
- 	}
- 	default:
--- 
-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
new file mode 100644
index 0000000..5cee6a0
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch
@@ -0,0 +1,233 @@
+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/0020-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch
deleted file mode 100644
index 14855c7..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-From bfb2498bbef4bcfd44658fad8acf82730c56ede6 Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Tue, 20 Dec 2022 09:47:31 +0800
-Subject: [PATCH] wifi: mt76: mt7996: support more options in
- .set_bitrate_mask()
-
-With this patch, driver can support runtime configuration for single
-rate, (HE)GI and HE_Ltf through .set_bitrate_mask(). Please noted that
-currently we do not support to fix any single parameter for EHT mode.
-
-Co-developed-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
-Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
-Co-developed-by: Howard Hsu <howard-yh.hsu@mediatek.com>
-Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
----
- mt7996/mcu.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 135 insertions(+), 2 deletions(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 62e4869..b7f378a 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -1656,6 +1656,134 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
- 				     MCU_WM_UNI_CMD(RA), true);
- }
- 
-+static int
-+mt7996_mcu_set_part_fixed_rate_ctrl(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;
-+	struct sta_phy *phy = data;
-+	struct sta_rec_ra_fixed *ra;
-+	struct sk_buff *skb;
-+	struct tlv *tlv;
-+
-+	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
-+					      &msta->wcid,
-+					      MT7996_STA_UPDATE_MAX_SIZE);
-+
-+	if (IS_ERR(skb))
-+		return PTR_ERR(skb);
-+
-+	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
-+	ra = (struct sta_rec_ra_fixed*)tlv;
-+
-+	switch (field) {
-+	case RATE_PARAM_AUTO:
-+		break;
-+	case RATE_PARAM_FIXED:
-+	case RATE_PARAM_FIXED_MCS:
-+	case RATE_PARAM_FIXED_GI:
-+	case RATE_PARAM_FIXED_HE_LTF:
-+		if (phy)
-+			ra->phy = *phy;
-+		break;
-+	default:
-+		break;
-+	}
-+	ra->field = cpu_to_le32(field);
-+
-+	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-+				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
-+}
-+
-+
-+static int
-+mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-+			       struct ieee80211_sta *sta)
-+{
-+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+	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 = {};
-+	int ret, nrates = 0;
-+
-+#define __sta_phy_bitrate_mask_check(_mcs, _gi, _ht, _he)			\
-+	do {									\
-+		u8 i, gi = mask->control[band]._gi;				\
-+		gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI;		\
-+		phy.sgi = gi;							\
-+		phy.he_ltf = mask->control[band].he_ltf;			\
-+		for (i = 0; i < ARRAY_SIZE(mask->control[band]._mcs); i++) {	\
-+			if (!mask->control[band]._mcs[i])			\
-+				continue;					\
-+			nrates += hweight16(mask->control[band]._mcs[i]);	\
-+			phy.mcs = ffs(mask->control[band]._mcs[i]) - 1;		\
-+			if (_ht)						\
-+				phy.mcs += 8 * i;				\
-+		}								\
-+	} while (0)
-+
-+	if (sta->deflink.he_cap.has_he) {
-+		__sta_phy_bitrate_mask_check(he_mcs, he_gi, 0, 1);
-+	} else if (sta->deflink.vht_cap.vht_supported) {
-+		__sta_phy_bitrate_mask_check(vht_mcs, gi, 0, 0);
-+	} else if (sta->deflink.ht_cap.ht_supported) {
-+		__sta_phy_bitrate_mask_check(ht_mcs, gi, 1, 0);
-+	} else {
-+		nrates = hweight32(mask->control[band].legacy);
-+		phy.mcs = ffs(mask->control[band].legacy) - 1;
-+	}
-+#undef __sta_phy_bitrate_mask_check
-+
-+	/* fall back to auto rate control */
-+	if (mask->control[band].gi == NL80211_TXRATE_DEFAULT_GI &&
-+	    mask->control[band].he_gi == GENMASK(7, 0) &&
-+	    mask->control[band].he_ltf == GENMASK(7, 0) &&
-+	    nrates != 1)
-+		return 0;
-+
-+	/* fixed single rate */
-+	if (nrates == 1) {
-+		ret = mt7996_mcu_set_part_fixed_rate_ctrl(dev, vif, sta, &phy,
-+							  RATE_PARAM_FIXED_MCS);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	/* fixed GI */
-+	if (mask->control[band].gi != NL80211_TXRATE_DEFAULT_GI ||
-+	    mask->control[band].he_gi != GENMASK(7, 0)) {
-+		struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
-+		u32 addr;
-+
-+		/* firmware updates only TXCMD but doesn't take WTBL into
-+		 * account, so driver should update here to reflect the
-+		 * actual txrate hardware sends out.
-+		 */
-+		addr = mt7996_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7);
-+		if (sta->deflink.he_cap.has_he)
-+			mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi);
-+		else
-+			mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi);
-+
-+		ret = mt7996_mcu_set_part_fixed_rate_ctrl(dev, vif, sta, &phy,
-+							  RATE_PARAM_FIXED_GI);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	/* fixed HE_LTF */
-+	if (mask->control[band].he_ltf != GENMASK(7, 0)) {
-+		ret = mt7996_mcu_set_part_fixed_rate_ctrl(dev, vif, sta, &phy,
-+							  RATE_PARAM_FIXED_HE_LTF);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	return 0;
-+}
-+
- static void
- mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
- 			     struct ieee80211_vif *vif, struct ieee80211_sta *sta)
-@@ -1765,6 +1893,7 @@ int mt7996_mcu_add_rate_ctrl(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 sk_buff *skb;
-+	int ret;
- 
- 	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
- 					      &msta->wcid,
-@@ -1784,8 +1913,12 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- 	 */
- 	mt7996_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta);
- 
--	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
--				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
-+	ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
-+				    MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
-+	if (ret)
-+		return ret;
-+
-+	return mt7996_mcu_add_rate_ctrl_fixed(dev, vif, sta);
- }
- 
- static int
--- 
-2.39.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
new file mode 100644
index 0000000..a5a8417
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch
@@ -0,0 +1,119 @@
+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/0021-wifi-mt76-mt7996-update-wmm-queue-mapping.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-update-wmm-queue-mapping.patch
deleted file mode 100644
index 6b1d684..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-update-wmm-queue-mapping.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 88577bcf928a15c2e8e78b7684ccb75dfc693eac Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Mon, 20 Mar 2023 19:09:59 +0800
-Subject: [PATCH 21/39] wifi: mt76: mt7996: update wmm queue mapping
-
-The mac80211 use mac80211 queue (MQ) and the firmware
-use access class index (ACI) so convert the MQ to ACI
-in mt7996_conf_tx.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt7996/main.c | 11 +++++++++--
- mt7996/mcu.c  |  2 +-
- 2 files changed, 10 insertions(+), 3 deletions(-)
-
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 9c80839..8e38ebc 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -198,7 +198,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
- 	mvif->mt76.omac_idx = idx;
- 	mvif->phy = phy;
- 	mvif->mt76.band_idx = band_idx;
--	mvif->mt76.wmm_idx = band_idx;
-+	mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
- 
- 	ret = mt7996_mcu_add_dev_info(phy, vif, true);
- 	if (ret)
-@@ -422,9 +422,16 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 	       const struct ieee80211_tx_queue_params *params)
- {
- 	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+	const u8 MQ_to_ACI[IEEE80211_NUM_ACS] = {
-+		[IEEE80211_AC_VO] = 3,
-+		[IEEE80211_AC_VI] = 2,
-+		[IEEE80211_AC_BE] = 0,
-+		[IEEE80211_AC_BK] = 1,
-+	};
- 
- 	/* no need to update right away, we'll get BSS_CHANGED_QOS */
--	queue = mt76_connac_lmac_mapping(queue);
-+	/* convert mac80211 queue to ACI */
-+	queue = MQ_to_ACI[queue];
- 	mvif->queue_params[queue] = *params;
- 
- 	return 0;
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index b27b88c..4359ede 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2835,7 +2835,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif)
- 
- 		e = (struct edca *)tlv;
- 		e->set = WMM_PARAM_SET;
--		e->queue = ac + mvif->mt76.wmm_idx * MT7996_MAX_WMM_SETS;
-+		e->queue = ac;
- 		e->aifs = q->aifs;
- 		e->txop = cpu_to_le16(q->txop);
- 
--- 
-2.18.0
-
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/0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
new file mode 100644
index 0000000..575b7db
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
@@ -0,0 +1,55 @@
+From 1b0bafc1cfb554b6150eb2ea3e1a5100ef1b0a24 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
+
+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>
+---
+ mt76_connac_mcu.c | 9 ++++++++-
+ mt7996/main.c     | 3 +++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index 68de525..bb570f2 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,
+ 
+ 	if (!sta) {
+ 		basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
+-		eth_broadcast_addr(basic->peer_addr);
++
++		if (vif->type == NL80211_IFTYPE_STATION &&
++		    !is_zero_ether_addr(vif->bss_conf.bssid)) {
++			memcpy(basic->peer_addr, vif->bss_conf.bssid, ETH_ALEN);
++			basic->aid = cpu_to_le16(vif->cfg.aid);
++		} else {
++			eth_broadcast_addr(basic->peer_addr);
++		}
+ 		return;
+ 	}
+ 
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 832b861..0e51fe0 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -582,6 +582,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)) {
++		/* reset bmc wtbl once BSSID changed */
++		if (changed & BSS_CHANGED_BSSID)
++			mt7996_mcu_add_sta(dev, vif, NULL, false);
+ 		mt7996_mcu_add_bss_info(phy, vif, true);
+ 		mt7996_mcu_add_sta(dev, vif, NULL, true);
+ 	}
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-mt7996-enable-IDS-debug-log.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-mt7996-enable-IDS-debug-log.patch
deleted file mode 100644
index 659edd4..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-mt7996-enable-IDS-debug-log.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 7e3ab3b90fc75ff41a503f4632a669c8cba2ae90 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Tue, 21 Mar 2023 15:04:45 +0800
-Subject: [PATCH 22/39] wifi: mt76: mt7996: enable IDS debug log
-
----
- mt7996/debugfs.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 513ab4b..0422018 100644
---- a/mt7996/debugfs.c
-+++ b/mt7996/debugfs.c
-@@ -290,6 +290,12 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
- 		DEBUG_SPL,
- 		DEBUG_RPT_RX,
- 		DEBUG_RPT_RA = 68,
-+		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;
- 	bool tx, rx, en;
- 	int ret;
-@@ -309,8 +315,8 @@ 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;
- 
- 		if (debug == DEBUG_RPT_RX)
--- 
-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/0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
new file mode 100644
index 0000000..1494376
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
@@ -0,0 +1,51 @@
+From cb01c8f9cef451d5e478d8498902d52a92ca4b55 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
+
+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
+--- 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,
+ 	else
+ 		hdr_trans->from_ds = true;
+ 
+-	wcid = (struct mt76_wcid *)sta->drv_priv;
+-	if (!wcid)
++	if (!sta)
+ 		return;
+ 
++	wcid = (struct mt76_wcid *)sta->drv_priv;
+ 	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,
+ 	if (!enable)
+ 		goto out;
+ 
++	/* starec hdr trans */
++	mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta);
++
+ 	/* 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,
+ 		mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta);
+ 		/* starec bfee */
+ 		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
+-		/* starec hdr trans */
+-		mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta);
+ 	}
+ 
+ 	ret = mt7996_mcu_add_group(dev, vif, sta);
+-- 
+2.18.0
+
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
new file mode 100644
index 0000000..d3c12af
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-mt7996-add-kite-pci-support.patch
@@ -0,0 +1,81 @@
+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
new file mode 100644
index 0000000..7ce6401
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0025-wifi-mt76-mt7996-add-kite-wtbl-size-support.patch
@@ -0,0 +1,56 @@
+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
new file mode 100644
index 0000000..d494783
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-accommodate-MT7992-with-different-c.patch
@@ -0,0 +1,28 @@
+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/0026-wifi-mt76-mt7996-add-led-feature-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-add-led-feature-support.patch
deleted file mode 100644
index 06e273a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-add-led-feature-support.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 030159528eff349db01b6b47b6fff8112b4282a4 Mon Sep 17 00:00:00 2001
-From: mtk25577 <jen-hao.cheng@mediatek.com>
-Date: Tue, 28 Mar 2023 18:23:00 +0800
-Subject: [PATCH 26/39] wifi: mt76: mt7996: add led feature support
-
-Signed-off-by: mtk25577 <jen-hao.cheng@mediatek.com>
----
- mt7996/Makefile |  1 +
- mt7996/init.c   | 33 +++++++++++++++++++++------------
- mt7996/regs.h   |  1 +
- 3 files changed, 23 insertions(+), 12 deletions(-)
-
-diff --git a/mt7996/Makefile b/mt7996/Makefile
-index bed9efd..7c2514a 100644
---- a/mt7996/Makefile
-+++ b/mt7996/Makefile
-@@ -1,4 +1,5 @@
- # SPDX-License-Identifier: ISC
-+EXTRA_CFLAGS += -DCONFIG_MT76_LEDS
- 
- obj-$(CONFIG_MT7996E) += mt7996e.o
- 
-diff --git a/mt7996/init.c b/mt7996/init.c
-index fecd0d3..192af3f 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -232,23 +232,31 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev,
- 	dev = container_of(mphy->dev, struct mt7996_dev, mt76);
- 
- 	/* select TX blink mode, 2: only data frames */
--	mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2);
-+	mt76_rmw_field(dev, MT_TMAC_TCR0(mphy->band_idx), MT_TMAC_TCR0_TX_BLINK, 2);
- 
- 	/* enable LED */
--	mt76_wr(dev, MT_LED_EN(0), 1);
-+	mt76_wr(dev, MT_LED_EN(mphy->band_idx), 1);
- 
- 	/* set LED Tx blink on/off time */
- 	val = FIELD_PREP(MT_LED_TX_BLINK_ON_MASK, delay_on) |
- 	      FIELD_PREP(MT_LED_TX_BLINK_OFF_MASK, delay_off);
--	mt76_wr(dev, MT_LED_TX_BLINK(0), val);
-+	mt76_wr(dev, MT_LED_TX_BLINK(mphy->band_idx), val);
-+
-+	/* turn LED off */
-+	if (delay_off == 0xff && delay_on == 0x0)
-+		val = MT_LED_CTRL_POLARITY | MT_LED_CTRL_KICK;
-+	else {
-+		/* control LED */
-+		val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
-+		if (mphy->band_idx == MT_BAND1)
-+			val |= MT_LED_CTRL_BLINK_BAND_SEL;
-+	}
- 
--	/* control LED */
--	val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
- 	if (mphy->leds.al)
- 		val |= MT_LED_CTRL_POLARITY;
- 
--	mt76_wr(dev, MT_LED_CTRL(0), val);
--	mt76_clear(dev, MT_LED_CTRL(0), MT_LED_CTRL_KICK);
-+	mt76_wr(dev, MT_LED_CTRL(mphy->band_idx), val);
-+	mt76_clear(dev, MT_LED_CTRL(mphy->band_idx), MT_LED_CTRL_KICK);
- }
- 
- static int mt7996_led_set_blink(struct led_classdev *led_cdev,
-@@ -400,6 +408,12 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
- 		ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
- 	}
- 
-+	/* init led callbacks */
-+	if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-+		phy->mt76->leds.cdev.brightness_set = mt7996_led_set_brightness;
-+		phy->mt76->leds.cdev.blink_set = mt7996_led_set_blink;
-+	}
-+
- 	mt76_set_stream_caps(phy->mt76, true);
- 	mt7996_set_stream_vht_txbf_caps(phy);
- 	mt7996_set_stream_he_eht_caps(phy);
-@@ -1063,11 +1077,6 @@ int mt7996_register_device(struct mt7996_dev *dev)
- #ifdef CONFIG_NL80211_TESTMODE
- 	dev->mt76.test_ops = &mt7996_testmode_ops;
- #endif
--	/* init led callbacks */
--	if (IS_ENABLED(CONFIG_MT76_LEDS)) {
--		dev->mphy.leds.cdev.brightness_set = mt7996_led_set_brightness;
--		dev->mphy.leds.cdev.blink_set = mt7996_led_set_blink;
--	}
- 
- 	ret = mt76_register_device(&dev->mt76, true, mt76_rates,
- 				   ARRAY_SIZE(mt76_rates));
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index d1d3d15..86da1bf 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -509,6 +509,7 @@ enum base_rev {
- 
- #define MT_LED_CTRL(_n)				MT_LED_PHYS(0x00 + ((_n) * 4))
- #define MT_LED_CTRL_KICK			BIT(7)
-+#define MT_LED_CTRL_BLINK_BAND_SEL		BIT(4)
- #define MT_LED_CTRL_BLINK_MODE			BIT(2)
- #define MT_LED_CTRL_POLARITY			BIT(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
new file mode 100644
index 0000000..3f5cfe7
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-add-AFE-pll-enable-before-driver-ow.patch
@@ -0,0 +1,47 @@
+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/0027-wifi-mt76-mt7996-fix-twt-mcu-command.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-fix-twt-mcu-command.patch
deleted file mode 100644
index 2e938b7..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-fix-twt-mcu-command.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From e503dbe84bc2b46907a792e11c196018b274647a Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Tue, 28 Mar 2023 20:20:57 +0800
-Subject: [PATCH 27/39] wifi: mt76: mt7996: fix twt mcu command
-
-Update unified command for twt.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt7915/mcu.h | 1 -
- mt7996/mcu.c | 7 +++++--
- 2 files changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index b9ea297..e7a5395 100644
---- a/mt7915/mcu.h
-+++ b/mt7915/mcu.h
-@@ -264,7 +264,6 @@ enum {
- 	MCU_TWT_AGRT_MODIFY,
- 	MCU_TWT_AGRT_DELETE,
- 	MCU_TWT_AGRT_TEARDOWN,
--	MCU_TWT_AGRT_GET_TSF,
- };
- 
- enum {
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index a6d8235..6bcb33e 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -3823,7 +3823,9 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
- 			       int cmd)
- {
- 	struct {
--		u8 _rsv[4];
-+		/* fixed field */
-+		u8 bss;
-+		u8 _rsv[3];
- 
- 		__le16 tag;
- 		__le16 len;
-@@ -3841,7 +3843,7 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
- 		u8 exponent;
- 		u8 is_ap;
- 		u8 agrt_params;
--		u8 __rsv2[135];
-+		u8 __rsv2[23];
- 	} __packed req = {
- 		.tag = cpu_to_le16(UNI_CMD_TWT_ARGT_UPDATE),
- 		.len = cpu_to_le16(sizeof(req) - 4),
-@@ -3851,6 +3853,7 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
- 		.flowid = flow->id,
- 		.peer_id = cpu_to_le16(flow->wcid),
- 		.duration = flow->duration,
-+		.bss = mvif->mt76.idx,
- 		.bss_idx = mvif->mt76.idx,
- 		.start_tsf = cpu_to_le64(flow->tsf),
- 		.mantissa = flow->mantissa,
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-11v-mbss-support-for-mt76.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-11v-mbss-support-for-mt76.patch
deleted file mode 100644
index bf724c8..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-11v-mbss-support-for-mt76.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From 0449694e4e963d0b48354ae2c52016c34899fba6 Mon Sep 17 00:00:00 2001
-From: mtk20656 <chank.chen@mediatek.com>
-Date: Wed, 8 Mar 2023 14:18:29 +0800
-Subject: [PATCH 28/39] wifi: mt76: mt7996: add 11v mbss support for mt76
-
-Signed-off-by: mtk20656 <chank.chen@mediatek.com>
----
- mt76_connac_mcu.h | 10 ++++++
- mt7996/init.c     |  2 ++
- mt7996/mcu.c      | 79 ++++++++++++++++++++++++++++++++++++++++++++++-
- 3 files changed, 90 insertions(+), 1 deletion(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 724a48a..97f874b 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1281,6 +1281,7 @@ enum {
- 	UNI_BSS_INFO_RLM = 2,
- 	UNI_BSS_INFO_BSS_COLOR = 4,
- 	UNI_BSS_INFO_HE_BASIC = 5,
-+	UNI_BSS_INFO_11V_MBSSID = 6,
- 	UNI_BSS_INFO_BCN_CONTENT = 7,
- 	UNI_BSS_INFO_BCN_CSA = 8,
- 	UNI_BSS_INFO_BCN_BCC = 9,
-@@ -1551,6 +1552,15 @@ struct bss_info_uni_he {
- 	u8 rsv[2];
- } __packed;
- 
-+struct bss_info_uni_mbssid {
-+	__le16 tag;
-+	__le16 len;
-+	u8 max_indicator;
-+	u8 mbss_idx;
-+	u8 tx_bss_omac_idx;
-+	u8 rsv[1];
-+} __packed;
-+
- struct mt76_connac_gtk_rekey_tlv {
- 	__le16 tag;
- 	__le16 len;
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 192af3f..0562439 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -359,6 +359,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
- 	wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
- 	wiphy->reg_notifier = mt7996_regd_notifier;
- 	wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
-+	wiphy->mbssid_max_interfaces = 16;
- 
- 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BSS_COLOR);
- 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
-@@ -381,6 +382,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
- 	ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
- 	ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
- 	ieee80211_hw_set(hw, WANT_MONITOR_VIF);
-+	ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
- 
- 	hw->max_tx_fragments = 4;
- 
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 6bcb33e..a369a08 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -631,6 +631,24 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
- 	he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
- }
- 
-+static void
-+mt7996_mcu_bss_mbssid_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
-+		      struct mt7996_phy *phy)
-+{
-+	struct bss_info_uni_mbssid *mbssid;
-+	struct tlv *tlv;
-+
-+	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_11V_MBSSID, sizeof(*mbssid));
-+
-+	mbssid = (struct bss_info_uni_mbssid *)tlv;
-+
-+	mbssid->max_indicator = vif->bss_conf.bssid_indicator;
-+	mbssid->mbss_idx = vif->bss_conf.bssid_index;
-+	mbssid->tx_bss_omac_idx = 0;
-+
-+	return;
-+}
-+
- static void
- mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
- 		       struct mt7996_phy *phy)
-@@ -895,6 +913,9 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
- 		if (vif->bss_conf.he_support)
- 			mt7996_mcu_bss_he_tlv(skb, vif, phy);
- 
-+		if (vif->bss_conf.bssid_indicator)
-+			mt7996_mcu_bss_mbssid_tlv(skb, vif, phy);
-+
- 		/* this tag is necessary no matter if the vif is MLD */
- 		mt7996_mcu_bss_mld_tlv(skb, vif);
- 	}
-@@ -2162,6 +2183,59 @@ mt7996_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb,
- 	info->cnt = skb->data[offs->cntdwn_counter_offs[0]];
- }
- 
-+static void
-+mt7996_mcu_beacon_mbss(struct sk_buff *rskb, struct sk_buff *skb,
-+			struct ieee80211_vif *vif, struct bss_bcn_content_tlv *bcn,
-+			struct ieee80211_mutable_offsets *offs)
-+{
-+	struct bss_bcn_mbss_tlv *mbss;
-+	const struct element *elem;
-+	struct tlv *tlv;
-+
-+	if (!vif->bss_conf.bssid_indicator)
-+		return;
-+
-+	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_MBSSID, sizeof(*mbss));
-+
-+	mbss = (struct bss_bcn_mbss_tlv *)tlv;
-+	mbss->offset[0] = cpu_to_le16(offs->tim_offset);
-+	mbss->bitmap = cpu_to_le32(1);
-+
-+	for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID,
-+			&skb->data[offs->mbssid_off],
-+			skb->len - offs->mbssid_off) {
-+		const struct element *sub_elem;
-+
-+		if (elem->datalen < 2)
-+			continue;
-+
-+		for_each_element(sub_elem, elem->data + 1, elem->datalen - 1) {
-+			const struct ieee80211_bssid_index *idx;
-+			const u8 *idx_ie;
-+
-+			if (sub_elem->id || sub_elem->datalen < 4)
-+				 continue; /* not a valid BSS profile */
-+
-+			/* Find WLAN_EID_MULTI_BSSID_IDX
-+			 * in the merged nontransmitted profile
-+			 */
-+			idx_ie = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
-+						sub_elem->data,
-+						sub_elem->datalen);
-+			if (!idx_ie || idx_ie[1] < sizeof(*idx))
-+				 continue;
-+
-+			idx = (void *)(idx_ie + 2);
-+			if (!idx->bssid_index || idx->bssid_index > 31)
-+				continue;
-+
-+			mbss->offset[idx->bssid_index] =
-+				cpu_to_le16(idx_ie - skb->data);
-+			mbss->bitmap |= cpu_to_le32(BIT(idx->bssid_index));
-+		}
-+	}
-+}
-+
- static void
- mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- 		       struct sk_buff *rskb, struct sk_buff *skb,
-@@ -2202,6 +2276,9 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
- 	struct tlv *tlv;
- 	struct bss_bcn_content_tlv *bcn;
- 
-+	if (vif->bss_conf.nontransmitted)
-+		return 0;
-+
- 	rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
- 					  MT7996_BEACON_UPDATE_SIZE);
- 	if (IS_ERR(rskb))
-@@ -2229,7 +2306,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
- 	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
- 
- 	mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
--	/* TODO: subtag - 11v MBSSID */
-+	mt7996_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs);
- 	mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs);
- 	dev_kfree_skb(skb);
- out:
--- 
-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
new file mode 100644
index 0000000..9d0f02b
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-kite-eagle-CR-offset-revision.patch
@@ -0,0 +1,232 @@
+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/0029-wifi-mt76-mt7996-Update-beacon-size-limitation-for-1.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-Update-beacon-size-limitation-for-1.patch
deleted file mode 100644
index 67e5c6c..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-Update-beacon-size-limitation-for-1.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-From 8b591f425b1bb71ebde4a1eb9c926f0c9017fe28 Mon Sep 17 00:00:00 2001
-From: MeiChia Chiu <meichia.chiu@mediatek.com>
-Date: Mon, 27 Mar 2023 09:47:44 +0800
-Subject: [PATCH 29/39] wifi: mt76: mt7996: Update beacon size limitation for
- 11v
-
-The TLV size limitation for these two has been expanded to
-accommodate 11v MBSSID IE.
-
-Co-developed-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Co-developed-by: Money Wang <Money.Wang@mediatek.com>
-Signed-off-by: Money Wang <Money.Wang@mediatek.com>
-Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
----
- mt7996/main.c |  4 ++--
- mt7996/mcu.c  | 39 +++++++++++++++++++++++----------------
- mt7996/mcu.h  | 11 ++++-------
- 3 files changed, 29 insertions(+), 25 deletions(-)
-
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 6c38993..520f250 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -618,8 +618,8 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
- 		mt7996_mcu_add_beacon(hw, vif, info->enable_beacon);
- 	}
- 
--	if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP ||
--	    changed & BSS_CHANGED_FILS_DISCOVERY)
-+	if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
-+		       BSS_CHANGED_FILS_DISCOVERY))
- 		mt7996_mcu_beacon_inband_discov(dev, vif, changed);
- 
- 	mutex_unlock(&dev->mt76.mutex);
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index a369a08..7b8f883 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2257,7 +2257,7 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- 			bcn->bcc_ie_pos = cpu_to_le16(offset - 3);
- 	}
- 
--	buf = (u8 *)bcn + sizeof(*bcn) - MAX_BEACON_SIZE;
-+	buf = (u8 *)bcn + sizeof(*bcn);
- 	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0,
- 			      BSS_CHANGED_BEACON);
- 
-@@ -2275,28 +2275,21 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
- 	struct sk_buff *skb, *rskb;
- 	struct tlv *tlv;
- 	struct bss_bcn_content_tlv *bcn;
-+	int len;
- 
- 	if (vif->bss_conf.nontransmitted)
- 		return 0;
- 
- 	rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
--					  MT7996_BEACON_UPDATE_SIZE);
-+					  MT7996_MAX_BSS_OFFLOAD_SIZE);
- 	if (IS_ERR(rskb))
- 		return PTR_ERR(rskb);
- 
--	tlv = mt7996_mcu_add_uni_tlv(rskb,
--				     UNI_BSS_INFO_BCN_CONTENT, sizeof(*bcn));
--	bcn = (struct bss_bcn_content_tlv *)tlv;
--	bcn->enable = en;
--
--	if (!en)
--		goto out;
--
- 	skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
- 	if (!skb)
- 		return -EINVAL;
- 
--	if (skb->len > MAX_BEACON_SIZE - MT_TXD_SIZE) {
-+	if (skb->len > MT7996_MAX_BEACON_SIZE) {
- 		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
- 		dev_kfree_skb(skb);
- 		return -EINVAL;
-@@ -2305,11 +2298,19 @@ 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;
-+	tlv = mt7996_mcu_add_uni_tlv(rskb,
-+				     UNI_BSS_INFO_BCN_CONTENT, len);
-+	bcn = (struct bss_bcn_content_tlv *)tlv;
-+	bcn->enable = en;
-+	if (!en)
-+		goto out;
-+
- 	mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
- 	mt7996_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs);
- 	mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs);
--	dev_kfree_skb(skb);
- out:
-+	dev_kfree_skb(skb);
- 	return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
- 				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
- }
-@@ -2330,9 +2331,13 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
- 	struct sk_buff *rskb, *skb = NULL;
- 	struct tlv *tlv;
- 	u8 *buf, interval;
-+	int len;
-+
-+	if (vif->bss_conf.nontransmitted)
-+		return 0;
- 
- 	rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
--					  MT7996_INBAND_FRAME_SIZE);
-+					  MT7996_MAX_BSS_OFFLOAD_SIZE);
- 	if (IS_ERR(rskb))
- 		return PTR_ERR(rskb);
- 
-@@ -2349,7 +2354,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
- 	if (!skb)
- 		return -EINVAL;
- 
--	if (skb->len > MAX_INBAND_FRAME_SIZE - MT_TXD_SIZE) {
-+	if (skb->len > MT7996_MAX_BEACON_SIZE) {
- 		dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
- 		dev_kfree_skb(skb);
- 		return -EINVAL;
-@@ -2360,7 +2365,9 @@ 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);
- 
--	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, sizeof(*discov));
-+	len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
-+
-+	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, len);
- 
- 	discov = (struct bss_inband_discovery_tlv *)tlv;
- 	discov->tx_mode = OFFLOAD_TX_MODE_SU;
-@@ -2371,7 +2378,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
- 	discov->enable = true;
- 	discov->wcid = cpu_to_le16(MT7996_WTBL_RESERVED);
- 
--	buf = (u8 *)tlv + sizeof(*discov) - MAX_INBAND_FRAME_SIZE;
-+	buf = (u8 *)tlv + sizeof(*discov);
- 
- 	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, changed);
- 
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 4ba06d9..eed7371 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -308,8 +308,6 @@ struct bss_inband_discovery_tlv {
- 	u8 enable;
- 	__le16 wcid;
- 	__le16 prob_rsp_len;
--#define MAX_INBAND_FRAME_SIZE 512
--	u8 pkt[MAX_INBAND_FRAME_SIZE];
- } __packed;
- 
- struct bss_bcn_content_tlv {
-@@ -321,8 +319,6 @@ struct bss_bcn_content_tlv {
- 	u8 enable;
- 	u8 type;
- 	__le16 pkt_len;
--#define MAX_BEACON_SIZE 512
--	u8 pkt[MAX_BEACON_SIZE];
- } __packed;
- 
- struct bss_bcn_cntdwn_tlv {
-@@ -629,13 +625,14 @@ enum {
- 					 sizeof(struct sta_rec_hdr_trans) +	\
- 					 sizeof(struct tlv))
- 
-+#define MT7996_MAX_BEACON_SIZE		1342
- #define MT7996_BEACON_UPDATE_SIZE	(sizeof(struct bss_req_hdr) +		\
- 					 sizeof(struct bss_bcn_content_tlv) +	\
-+					 MT_TXD_SIZE +				\
- 					 sizeof(struct bss_bcn_cntdwn_tlv) +	\
- 					 sizeof(struct bss_bcn_mbss_tlv))
--
--#define MT7996_INBAND_FRAME_SIZE	(sizeof(struct bss_req_hdr) +		\
--					 sizeof(struct bss_inband_discovery_tlv))
-+#define MT7996_MAX_BSS_OFFLOAD_SIZE	(MT7996_MAX_BEACON_SIZE +		\
-+					 MT7996_BEACON_UPDATE_SIZE)
- 
- enum {
- 	UNI_BAND_CONFIG_RADIO_ENABLE,
--- 
-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/0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch
new file mode 100644
index 0000000..7b88df9
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch
@@ -0,0 +1,97 @@
+From ee2e6d4d137cadf56c1c102d73761f76fd97a6ea 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
+
+Add support configure preamble puncture feature through mcu commands.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt76_connac_mcu.h |  1 +
+ mt7996/mcu.c      | 30 ++++++++++++++++++++++++++++++
+ mt7996/mcu.h      |  4 ++++
+ mt7996/mt7996.h   |  2 ++
+ 4 files changed, 37 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 8562ca4..6fac67b 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1241,6 +1241,7 @@ enum {
+ 	MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
+ 	MCU_UNI_CMD_THERMAL = 0x35,
+ 	MCU_UNI_CMD_VOW = 0x37,
++	MCU_UNI_CMD_PP = 0x38,
+ 	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
+ 	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
+--- 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);
+ }
++
++int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, bool auto_mode,
++			 u8 force_bitmap_ctrl, u16 bitmap)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++		bool mgmt_mode;
++		u8 band_idx;
++		u8 force_bitmap_ctrl;
++		bool auto_mode;
++		__le16 bitmap;
++		u8 _rsv2[2];
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_CMD_PP_EN_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++
++		.mgmt_mode = !auto_mode,
++		.band_idx = phy->mt76->band_idx,
++		.force_bitmap_ctrl = force_bitmap_ctrl,
++		.auto_mode = auto_mode,
++		.bitmap = cpu_to_le16(bitmap),
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(PP),
++				 &req, sizeof(req), false);
++}
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 376931e..296acbd 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -845,6 +845,10 @@ enum {
+ 	MT7996_SEC_MODE_MAX,
+ };
+ 
++enum {
++	UNI_CMD_PP_EN_CTRL,
++};
++
+ #define MT7996_PATCH_SEC		GENMASK(31, 24)
+ #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
+--- 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,
+ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+ 				     struct ieee80211_vif *vif,
+ 				     struct ieee80211_sta *sta);
++int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, bool auto_mode, u8 force_bitmap,
++			 u16 bitmap);
+ #ifdef CONFIG_MAC80211_DEBUGFS
+ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			    struct ieee80211_sta *sta, struct dentry *dir);
+-- 
+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
new file mode 100644
index 0000000..0789ad2
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0030-wifi-mt76-mt7996-fix-all-sta-info-struct-alignment.patch
@@ -0,0 +1,26 @@
+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-fix-memory-leak.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-fix-memory-leak.patch
deleted file mode 100644
index 0669836..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-fix-memory-leak.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 80a4f15fa3077ef5a340a4af5b12fda8d958c337 Mon Sep 17 00:00:00 2001
-From: Bo Jiao <Bo.Jiao@mediatek.com>
-Date: Tue, 18 Apr 2023 19:49:45 +0800
-Subject: [PATCH 31/39] wifi: mt76: mt7996: fix memory leak.
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
----
- mt7996/mcu.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index a2c1e43..f98a48d 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2286,11 +2286,14 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
- 		return PTR_ERR(rskb);
- 
- 	skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
--	if (!skb)
-+	if (!skb) {
-+		dev_kfree_skb(rskb);
- 		return -EINVAL;
-+	}
- 
- 	if (skb->len > MT7996_MAX_BEACON_SIZE) {
- 		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
-+		dev_kfree_skb(rskb);
- 		dev_kfree_skb(skb);
- 		return -EINVAL;
- 	}
-@@ -2351,11 +2354,14 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
- 		skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
- 	}
- 
--	if (!skb)
-+	if (!skb) {
-+		dev_kfree_skb(rskb);
- 		return -EINVAL;
-+	}
- 
- 	if (skb->len > MT7996_MAX_BEACON_SIZE) {
- 		dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
-+		dev_kfree_skb(rskb);
- 		dev_kfree_skb(skb);
- 		return -EINVAL;
- 	}
--- 
-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
new file mode 100644
index 0000000..8e716a0
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-refine-ampdu-factor.patch
@@ -0,0 +1,111 @@
+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/0033-wifi-mt76-mt7996-disable-wfdma-tx-rx-during-SER.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0033-wifi-mt76-mt7996-disable-wfdma-tx-rx-during-SER.patch
deleted file mode 100644
index a88d36a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0033-wifi-mt76-mt7996-disable-wfdma-tx-rx-during-SER.patch
+++ /dev/null
@@ -1,219 +0,0 @@
-From d246d8300bcbf7dea19919d61df9d7553e21bd1b Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Wed, 26 Apr 2023 15:37:23 +0800
-Subject: [PATCH 33/39] wifi: mt76: mt7996: disable wfdma tx/rx during SER
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
----
- dma.c           |  6 ++++
- mt7996/dma.c    | 79 ++++++++++++++++++++++++++++++-------------------
- mt7996/mac.c    | 13 ++++++--
- mt7996/mt7996.h |  1 +
- 4 files changed, 65 insertions(+), 34 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 465190e..f2b1b2a 100644
---- a/dma.c
-+++ b/dma.c
-@@ -466,6 +466,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
- 	struct mt76_queue_buf buf = {};
- 	dma_addr_t addr;
- 
-+	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
-+		goto error;
-+
- 	if (q->queued + 1 >= q->ndesc - 1)
- 		goto error;
- 
-@@ -507,6 +510,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
- 	dma_addr_t addr;
- 	u8 *txwi;
- 
-+	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
-+		goto free_skb;
-+
- 	t = mt76_get_txwi(dev);
- 	if (!t)
- 		goto free_skb;
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index fbedaac..6a21e3e 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -128,11 +128,55 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
- 	}
- }
- 
--static int mt7996_dma_enable(struct mt7996_dev *dev)
-+void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
- {
- 	u32 hif1_ofs = 0;
- 	u32 irq_mask;
- 
-+	if (dev->hif2)
-+		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+	/* enable wpdma 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 (dev->hif2)
-+			mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
-+				 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);
-+	}
-+
-+	/* 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);
-+
-+	if (!dev->mphy.band_idx)
-+		irq_mask |= MT_INT_BAND0_RX_DONE;
-+
-+	if (dev->dbdc_support)
-+		irq_mask |= MT_INT_BAND1_RX_DONE;
-+
-+	if (dev->tbtc_support)
-+		irq_mask |= MT_INT_BAND2_RX_DONE;
-+
-+done:
-+	mt7996_irq_enable(dev, irq_mask);
-+	mt7996_irq_disable(dev, 0);
-+}
-+
-+static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
-+{
-+	u32 hif1_ofs = 0;
-+
- 	if (dev->hif2)
- 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
- 
-@@ -170,13 +214,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
- 	mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
- 		  MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
- 
--	/* set WFDMA Tx/Rx */
--	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);
--
- 	/* GLO_CFG_EXT0 */
- 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0,
- 		 WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
-@@ -187,12 +224,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
- 		 WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
- 
- 	if (dev->hif2) {
--		mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
--			 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);
--
- 		/* GLO_CFG_EXT0 */
- 		mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
- 			 WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
-@@ -216,21 +247,7 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
- 		/* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
- 	}
- 
--	/* enable interrupts for TX/RX rings */
--	irq_mask = MT_INT_RX_DONE_MCU |
--		   MT_INT_TX_DONE_MCU |
--		   MT_INT_MCU_CMD;
--
--	if (!dev->mphy.band_idx)
--		irq_mask |= MT_INT_BAND0_RX_DONE;
--
--	if (dev->dbdc_support)
--		irq_mask |= MT_INT_BAND1_RX_DONE;
--
--	if (dev->tbtc_support)
--		irq_mask |= MT_INT_BAND2_RX_DONE;
--
--	mt7996_irq_enable(dev, irq_mask);
-+	__mt7996_dma_enable(dev, reset);
- 
- 	return 0;
- }
-@@ -347,7 +364,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 			  mt7996_poll_tx);
- 	napi_enable(&dev->mt76.tx_napi);
- 
--	mt7996_dma_enable(dev);
-+	mt7996_dma_enable(dev, false);
- 
- 	return 0;
- }
-@@ -413,7 +430,7 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
- 	mt76_for_each_q_rx(&dev->mt76, i)
- 		mt76_queue_rx_reset(dev, i);
- 
--	mt7996_dma_enable(dev);
-+	mt7996_dma_enable(dev, !force);
- }
- 
- void mt7996_dma_cleanup(struct mt7996_dev *dev)
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index bddb84f..986031f 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -2028,6 +2028,12 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 		mt7996_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
- 	}
- 
-+	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
-+	mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
-+
-+	/* enable dma tx/rx and interrupt */
-+	__mt7996_dma_enable(dev, false);
-+
- 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
- 	clear_bit(MT76_RESET, &dev->mphy.state);
- 	if (phy2)
-@@ -2044,9 +2050,6 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 
- 	tasklet_schedule(&dev->mt76.irq_tasklet);
- 
--	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
--	mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
--
- 	mt76_worker_enable(&dev->mt76.tx_worker);
- 
- 	local_bh_disable();
-@@ -2149,6 +2152,10 @@ skip_coredump:
- 
- 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;
- 
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 8e5b3c3..561c1cd 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -448,6 +448,7 @@ 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_enable(struct mt7996_dev *dev, bool reset);
- void mt7996_init_txpower(struct mt7996_dev *dev,
- 			 struct ieee80211_supported_band *sband);
- int mt7996_txbf_init(struct mt7996_dev *dev);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch
deleted file mode 100644
index 10bbe3a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 39893cc863213984a9ab0ae279dbfe433a6fe90e Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Tue, 23 May 2023 21:18:59 +0800
-Subject: [PATCH 38/39] wifi: mt76: mt7996: fix DFS CAC tx emission issue after
- 2nd interface up
-
-FW's channel state is set during the first wifi interface setup. If the switch reason for
-setting the tx/rx path during second-time wifi interface setup is CH_SWITCH_NORMAL,
-then the FW would perform runtime dpd channel calibration during DFS CAC, which leads to
-tx emission. Therefore, in order to bypass tx calibration during DFS CAC, set the switch reason
-to CH_SWITCH_DFS whenever chandef is set to DFS channel.
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/mcu.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index b34c6b7..be5c908 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -3211,12 +3211,12 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
- 		.channel_band = ch_band[chandef->chan->band],
- 	};
- 
--	if (tag == UNI_CHANNEL_RX_PATH ||
--	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
-+	if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
- 		req.switch_reason = CH_SWITCH_NORMAL;
- 	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
- 		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
--	else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
-+	else if (cfg80211_chandef_valid(chandef) &&
-+		 !cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
- 					  NL80211_IFTYPE_AP))
- 		req.switch_reason = CH_SWITCH_DFS;
- 	else
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch
deleted file mode 100644
index b5a49a5..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From da1c93b8c6480cfcd605cd8c19111a6df8c9f8b4 Mon Sep 17 00:00:00 2001
-From: Howard Hsu <howard-yh.hsu@mediatek.com>
-Date: Fri, 2 Jun 2023 15:12:34 +0800
-Subject: [PATCH] wifi: mt76: mt7996: fix beamformee ss subfield in EHT PHY
- caps IE
-
-According to P802.11be_D2.1 Table 9-401I, the minimum value of Beamformee SS shall
-be 3. Fix it to ensure that the value of Beamformee SS subfield is at least 3.
-
-Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
----
- mt7996/init.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 9eba689a..96c4bb01 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -936,16 +936,17 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band,
- 		IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |
- 		IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
- 
-+	val = max_t(u8, sts - 1, 3);
- 	eht_cap_elem->phy_cap_info[0] |=
--		u8_encode_bits(u8_get_bits(sts - 1, BIT(0)),
-+		u8_encode_bits(u8_get_bits(val, BIT(0)),
- 			       IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK);
- 
- 	eht_cap_elem->phy_cap_info[1] =
--		u8_encode_bits(u8_get_bits(sts - 1, GENMASK(2, 1)),
-+		u8_encode_bits(u8_get_bits(val, GENMASK(2, 1)),
- 			       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK) |
--		u8_encode_bits(sts - 1,
-+		u8_encode_bits(val,
- 			       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK) |
--		u8_encode_bits(sts - 1,
-+		u8_encode_bits(val,
- 			       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK);
- 
- 	eht_cap_elem->phy_cap_info[2] =
--- 
-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-wifi-mt76-mt7996-for-build-pass.patch
index cb5d3bb..48ca34e 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-wifi-mt76-mt7996-for-build-pass.patch
@@ -1,7 +1,7 @@
-From 83bb8ec37f85161b08f4eb2abf6a9a0530cfc189 Mon Sep 17 00:00:00 2001
+From fd11038a011cf006ee347a48d880c38a2ad20c75 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 0999/1015] wifi: mt76: mt7996: for build pass
+Subject: [PATCH 32/98] wifi: mt76: mt7996: for build pass
 
 Change-Id: Ieb44c33ee6e6a2e6058c1ef528404c1a1cbcfdaf
 ---
@@ -18,7 +18,7 @@
  10 files changed, 19 insertions(+), 4 deletions(-)
 
 diff --git a/debugfs.c b/debugfs.c
-index 79064a4d..e10d4cbc 100644
+index c4649ba..ac5207e 100644
 --- a/debugfs.c
 +++ b/debugfs.c
 @@ -33,8 +33,11 @@ mt76_napi_threaded_set(void *data, u64 val)
@@ -34,10 +34,10 @@
  	return 0;
  }
 diff --git a/dma.c b/dma.c
-index f2b1b2ac..e1e9062b 100644
+index dd20271..bb995e2 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -859,7 +859,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -943,7 +943,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 +47,10 @@
  			goto free_frag;
  
 diff --git a/eeprom.c b/eeprom.c
-index 263e5089..aa889258 100644
+index 2558788..a07ca84 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -108,9 +108,15 @@ void
+@@ -161,9 +161,15 @@ void
  mt76_eeprom_override(struct mt76_phy *phy)
  {
  	struct mt76_dev *dev = phy->dev;
@@ -68,7 +68,7 @@
  	if (!is_valid_ether_addr(phy->macaddr)) {
  		eth_random_addr(phy->macaddr);
 diff --git a/mcu.c b/mcu.c
-index a8cafa39..fa4b0544 100644
+index a8cafa3..fa4b054 100644
 --- a/mcu.c
 +++ b/mcu.c
 @@ -4,6 +4,7 @@
@@ -80,7 +80,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 8d745c97..86061e95 100644
+index 955974a..db337aa 100644
 --- a/mt7615/mcu.c
 +++ b/mt7615/mcu.c
 @@ -10,6 +10,7 @@
@@ -92,7 +92,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 5fab6772..c24dac10 100644
+index bb570f2..236cfea 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -4,6 +4,7 @@
@@ -104,7 +104,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 aa706ff6..e8c1e572 100644
+index b6fba1a..dee01e0 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -6,6 +6,7 @@
@@ -116,10 +116,10 @@
  #define fw_name(_dev, name, ...)	({			\
  	char *_fw;						\
 diff --git a/mt7996/dma.c b/mt7996/dma.c
-index f01cea5e..b8f253d0 100644
+index 1ed91da..23f6f16 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -360,8 +360,8 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -602,8 +602,8 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  	if (ret < 0)
  		return ret;
  
@@ -131,10 +131,10 @@
  
  	mt7996_dma_enable(dev, false);
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 9840c77d..b81ed64c 100644
+index ca0e9d0..7ae92e1 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -121,6 +121,7 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
+@@ -98,6 +98,7 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -143,7 +143,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 871d32a4..58893348 100644
+index 8b81644..fdc4fb4 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -5,6 +5,7 @@
@@ -155,5 +155,5 @@
  #include "mcu.h"
  #include "mac.h"
 -- 
-2.39.2
+2.18.0
 
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-wifi-mt76-mt7996-add-debug-tool.patch
index fcc450e..d29a90b 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-wifi-mt76-mt7996-add-debug-tool.patch
@@ -1,45 +1,46 @@
-From 16ea1c12d369ea1f315edcc7a8525efc6d78403a Mon Sep 17 00:00:00 2001
+From 393f2e0f06e9a6ead8ffd64c904b6e24ff6c92f1 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] wifi: mt76: mt7996: add debug tool
+Subject: [PATCH 33/98] wifi: mt76: mt7996: add debug tool
 
 Change-Id: Ie10390b01f17db893dbfbf3221bf63a4bd1fe38f
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
- mt7996/Makefile      |    3 +
+ mt7996/Makefile      |    4 +
  mt7996/coredump.c    |   10 +-
  mt7996/coredump.h    |    7 +
- mt7996/debugfs.c     |   24 +-
- mt7996/mt7996.h      |   14 +
- mt7996/mtk_debug.h   | 2165 ++++++++++++++++++++++++++++++++++++++
- mt7996/mtk_debugfs.c | 2353 ++++++++++++++++++++++++++++++++++++++++++
+ mt7996/debugfs.c     |   34 +-
+ mt7996/mt7996.h      |   10 +
+ mt7996/mtk_debug.h   | 2147 ++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_debugfs.c | 2379 ++++++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.c     |   18 +
  mt7996/mtk_mcu.h     |   16 +
  tools/fwlog.c        |   25 +-
- 10 files changed, 4617 insertions(+), 18 deletions(-)
+ 10 files changed, 4630 insertions(+), 20 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/mt7996/Makefile b/mt7996/Makefile
-index 7c2514a6..df131869 100644
+index 07c8b55..a056b40 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
-@@ -1,5 +1,6 @@
+@@ -1,4 +1,6 @@
  # SPDX-License-Identifier: ISC
- EXTRA_CFLAGS += -DCONFIG_MT76_LEDS
++EXTRA_CFLAGS += -DCONFIG_MT76_LEDS
 +EXTRA_CFLAGS += -DCONFIG_MTK_DEBUG
  
  obj-$(CONFIG_MT7996E) += mt7996e.o
  
-@@ -9,3 +10,5 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
- mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
+@@ -6,3 +8,5 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
+ 	     debugfs.o mmio.o
  
- mt7996e-$(CONFIG_NL80211_TESTMODE) += testmode.o
+ mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
 +
 +mt7996e-y += mtk_debugfs.o mtk_mcu.o
 diff --git a/mt7996/coredump.c b/mt7996/coredump.c
-index 60b88085..a7f91b56 100644
+index 60b8808..a7f91b5 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
@@ -88,7 +89,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 01ed3731..93cd84a0 100644
+index 01ed373..93cd84a 100644
 --- a/mt7996/coredump.h
 +++ b/mt7996/coredump.h
 @@ -75,6 +75,7 @@ struct mt7996_mem_region {
@@ -113,10 +114,21 @@
  mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type)
  {
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index ca4d615d..93581fef 100644
+index 9bd9535..92aa164 100644
 --- a/mt7996/debugfs.c
 +++ b/mt7996/debugfs.c
-@@ -301,6 +301,9 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
+@@ -290,11 +290,20 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
+ 		DEBUG_SPL,
+ 		DEBUG_RPT_RX,
+ 		DEBUG_RPT_RA = 68,
++		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;
+ 	bool tx, rx, en;
  	int ret;
  
  	dev->fw_debug_wm = val ? MCU_FW_LOG_TO_HOST : 0;
@@ -126,7 +138,18 @@
  
  	if (dev->fw_debug_bin)
  		val = MCU_FW_LOG_RELAY;
-@@ -407,11 +410,12 @@ mt7996_fw_debug_bin_set(void *data, u64 val)
+@@ -309,8 +318,8 @@ 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;
+ 
+ 		if (debug == DEBUG_RPT_RX)
+@@ -401,11 +410,12 @@ mt7996_fw_debug_bin_set(void *data, u64 val)
  	};
  	struct mt7996_dev *dev = data;
  
@@ -142,7 +165,7 @@
  
  	dev->fw_debug_bin = val;
  
-@@ -825,6 +829,11 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
+@@ -819,6 +829,11 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
  	if (phy == &dev->phy)
  		dev->debugfs_dir = dir;
  
@@ -154,7 +177,7 @@
  	return 0;
  }
  
-@@ -837,6 +846,12 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
+@@ -831,6 +846,12 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
  	void *dest;
  
  	spin_lock_irqsave(&lock, flags);
@@ -167,7 +190,7 @@
  	dest = relay_reserve(dev->relay_fwlog, hdrlen + len + 4);
  	if (dest) {
  		*(u32 *)dest = hdrlen + len;
-@@ -869,9 +884,6 @@ void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int
+@@ -863,9 +884,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),
  	};
  
@@ -178,11 +201,11 @@
  	hdr.timestamp = cpu_to_le32(mt76_rr(dev, MT_LPON_FRCR(0)));
  	hdr.len = *(__le16 *)data;
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 286fc1eb..6c76ec20 100644
+index c4d74a0..8801956 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -363,6 +363,16 @@ struct mt7996_dev {
- 	u32 reg_l2_backup;
+@@ -317,6 +317,16 @@ struct mt7996_dev {
+ 	spinlock_t reg_lock;
  
  	u8 wtbl_size_group;
 +
@@ -198,21 +221,12 @@
  };
  
  enum {
-@@ -659,4 +669,8 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			    struct ieee80211_sta *sta, struct dentry *dir);
- #endif
- 
-+#ifdef CONFIG_MTK_DEBUG
-+int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
-+#endif
-+
- #endif
 diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
 new file mode 100644
-index 00000000..eb40f9cb
+index 0000000..368f0bc
 --- /dev/null
 +++ b/mt7996/mtk_debug.h
-@@ -0,0 +1,2165 @@
+@@ -0,0 +1,2147 @@
 +#ifndef __MTK_DEBUG_H
 +#define __MTK_DEBUG_H
 +
@@ -289,23 +303,23 @@
 +#define BN0_WF_AGG_TOP_TWTEDTB_ADDR                            (BN0_WF_AGG_TOP_BASE + 0xe4) // 20E4
 +#define BN0_WF_AGG_TOP_TWTEETB_ADDR                            (BN0_WF_AGG_TOP_BASE + 0xe8) // 20E8
 +#define BN0_WF_AGG_TOP_TWTEFTB_ADDR                            (BN0_WF_AGG_TOP_BASE + 0xec) // 20EC
-+#define BN0_WF_AGG_TOP_AALCR2_ADDR                             (BN0_WF_AGG_TOP_BASE + 0xf0) // 20F0
-+#define BN0_WF_AGG_TOP_AALCR3_ADDR                             (BN0_WF_AGG_TOP_BASE + 0xf4) // 20F4
-+#define BN0_WF_AGG_TOP_AALCR4_ADDR                             (BN0_WF_AGG_TOP_BASE + 0xf8) // 20F8
-+#define BN0_WF_AGG_TOP_AALCR5_ADDR                             (BN0_WF_AGG_TOP_BASE + 0xfc) // 20FC
-+#define BN0_WF_AGG_TOP_AALCR6_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x100) // 2100
-+#define BN0_WF_AGG_TOP_AALCR7_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x104) // 2104
 +#define BN0_WF_AGG_TOP_ATCR0_ADDR                              (BN0_WF_AGG_TOP_BASE + 0x108) // 2108
 +#define BN0_WF_AGG_TOP_ATCR1_ADDR                              (BN0_WF_AGG_TOP_BASE + 0x10c) // 210C
 +#define BN0_WF_AGG_TOP_TCCR_ADDR                               (BN0_WF_AGG_TOP_BASE + 0x110) // 2110
 +#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_CSDCR0_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x120) // 2120
-+#define BN0_WF_AGG_TOP_CSDCR1_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x124) // 2124
-+#define BN0_WF_AGG_TOP_CSDCR2_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x128) // 2128
-+#define BN0_WF_AGG_TOP_CSDCR3_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x12c) // 212C
-+#define BN0_WF_AGG_TOP_CSDCR4_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x130) // 2130
++#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_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
++#define BN0_WF_AGG_TOP_CSDCR3_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x15c) // 215C
++#define BN0_WF_AGG_TOP_CSDCR4_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x160) // 2160
 +#define BN0_WF_AGG_TOP_DYNSCR_ADDR                             (BN0_WF_AGG_TOP_BASE + 0x178) // 2178
 +#define BN0_WF_AGG_TOP_DYNSSCR_ADDR                            (BN0_WF_AGG_TOP_BASE + 0x198) // 2198
 +#define BN0_WF_AGG_TOP_TCDCNT0_ADDR                            (BN0_WF_AGG_TOP_BASE + 0x2c8) // 22C8
@@ -912,22 +926,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 + 0x9B4) // D9B4
-+#define BN0_WF_MIB_TOP_TRDR1_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9B8) // D9B8
-+#define BN0_WF_MIB_TOP_TRDR2_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9BC) // D9BC
-+#define BN0_WF_MIB_TOP_TRDR3_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9C0) // D9C0
-+#define BN0_WF_MIB_TOP_TRDR4_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9C4) // D9C4
-+#define BN0_WF_MIB_TOP_TRDR5_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9C8) // D9C8
-+#define BN0_WF_MIB_TOP_TRDR6_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9CC) // D9CC
-+#define BN0_WF_MIB_TOP_TRDR7_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9D0) // D9D0
-+#define BN0_WF_MIB_TOP_TRDR8_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9D4) // D9D4
-+#define BN0_WF_MIB_TOP_TRDR9_ADDR                              (BN0_WF_MIB_TOP_BASE + 0x9D8) // D9D8
-+#define BN0_WF_MIB_TOP_TRDR10_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x9DC) // D9DC
-+#define BN0_WF_MIB_TOP_TRDR11_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x9E0) // D9E0
-+#define BN0_WF_MIB_TOP_TRDR12_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x9E4) // D9E4
-+#define BN0_WF_MIB_TOP_TRDR13_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x9E8) // D9E8
-+#define BN0_WF_MIB_TOP_TRDR14_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x9EC) // D9EC
-+#define BN0_WF_MIB_TOP_TRDR15_ADDR                             (BN0_WF_MIB_TOP_BASE + 0x9F0) // D9F0
++#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_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]
@@ -1178,6 +1192,10 @@
 +#define WF_UWTBL_AMSDU_CFG_ADDR                                     32
 +#define WF_UWTBL_AMSDU_CFG_MASK                                     0x00000fff // 11- 0
 +#define WF_UWTBL_AMSDU_CFG_SHIFT                                    0
++#define WF_UWTBL_SEC_ADDR_MODE_DW                                   8
++#define WF_UWTBL_SEC_ADDR_MODE_ADDR                                 32
++#define WF_UWTBL_SEC_ADDR_MODE_MASK                                 0x00300000 // 21-20
++#define WF_UWTBL_SEC_ADDR_MODE_SHIFT                                20
 +#define WF_UWTBL_WMM_Q_DW                                           8
 +#define WF_UWTBL_WMM_Q_ADDR                                         32
 +#define WF_UWTBL_WMM_Q_MASK                                         0x06000000 // 26-25
@@ -1405,6 +1423,11 @@
 +#define WF_LWTBL_ULPF_MASK \
 +	0x02000000 // 25-25
 +#define WF_LWTBL_ULPF_SHIFT                                         25
++#define WF_LWTBL_BYPASS_TXSMM_DW                                    3
++#define WF_LWTBL_BYPASS_TXSMM_ADDR                                  12
++#define WF_LWTBL_BYPASS_TXSMM_MASK \
++	0x04000000 // 26-26
++#define WF_LWTBL_BYPASS_TXSMM_SHIFT                                 26
 +#define WF_LWTBL_TBF_HT_DW                                          3
 +#define WF_LWTBL_TBF_HT_ADDR                                        12
 +#define WF_LWTBL_TBF_HT_MASK \
@@ -1431,46 +1454,46 @@
 +	0x80000000 // 31-31
 +#define WF_LWTBL_IGN_FBK_SHIFT                                      31
 +// DW4
-+#define WF_LWTBL_ANT_ID0_DW                                         4
-+#define WF_LWTBL_ANT_ID0_ADDR                                       16
-+#define WF_LWTBL_ANT_ID0_MASK \
++#define WF_LWTBL_NEGOTIATED_WINSIZE0_DW                             4
++#define WF_LWTBL_NEGOTIATED_WINSIZE0_ADDR                           16
++#define WF_LWTBL_NEGOTIATED_WINSIZE0_MASK \
 +	0x00000007 // 2- 0
-+#define WF_LWTBL_ANT_ID0_SHIFT                                      0
-+#define WF_LWTBL_ANT_ID1_DW                                         4
-+#define WF_LWTBL_ANT_ID1_ADDR                                       16
-+#define WF_LWTBL_ANT_ID1_MASK \
++#define WF_LWTBL_NEGOTIATED_WINSIZE0_SHIFT                          0
++#define WF_LWTBL_NEGOTIATED_WINSIZE1_DW                             4
++#define WF_LWTBL_NEGOTIATED_WINSIZE1_ADDR                           16
++#define WF_LWTBL_NEGOTIATED_WINSIZE1_MASK \
 +	0x00000038 // 5- 3
-+#define WF_LWTBL_ANT_ID1_SHIFT                                      3
-+#define WF_LWTBL_ANT_ID2_DW                                         4
-+#define WF_LWTBL_ANT_ID2_ADDR                                       16
-+#define WF_LWTBL_ANT_ID2_MASK \
++#define WF_LWTBL_NEGOTIATED_WINSIZE1_SHIFT                          3
++#define WF_LWTBL_NEGOTIATED_WINSIZE2_DW                             4
++#define WF_LWTBL_NEGOTIATED_WINSIZE2_ADDR                           16
++#define WF_LWTBL_NEGOTIATED_WINSIZE2_MASK \
 +	0x000001c0 // 8- 6
-+#define WF_LWTBL_ANT_ID2_SHIFT                                      6
-+#define WF_LWTBL_ANT_ID3_DW                                         4
-+#define WF_LWTBL_ANT_ID3_ADDR                                       16
-+#define WF_LWTBL_ANT_ID3_MASK \
++#define WF_LWTBL_NEGOTIATED_WINSIZE2_SHIFT                          6
++#define WF_LWTBL_NEGOTIATED_WINSIZE3_DW                             4
++#define WF_LWTBL_NEGOTIATED_WINSIZE3_ADDR                           16
++#define WF_LWTBL_NEGOTIATED_WINSIZE3_MASK \
 +	0x00000e00 // 11- 9
-+#define WF_LWTBL_ANT_ID3_SHIFT                                      9
-+#define WF_LWTBL_ANT_ID4_DW                                         4
-+#define WF_LWTBL_ANT_ID4_ADDR                                       16
-+#define WF_LWTBL_ANT_ID4_MASK \
++#define WF_LWTBL_NEGOTIATED_WINSIZE3_SHIFT                          9
++#define WF_LWTBL_NEGOTIATED_WINSIZE4_DW                             4
++#define WF_LWTBL_NEGOTIATED_WINSIZE4_ADDR                           16
++#define WF_LWTBL_NEGOTIATED_WINSIZE4_MASK \
 +	0x00007000 // 14-12
-+#define WF_LWTBL_ANT_ID4_SHIFT                                      12
-+#define WF_LWTBL_ANT_ID5_DW                                         4
-+#define WF_LWTBL_ANT_ID5_ADDR                                       16
-+#define WF_LWTBL_ANT_ID5_MASK \
++#define WF_LWTBL_NEGOTIATED_WINSIZE4_SHIFT                          12
++#define WF_LWTBL_NEGOTIATED_WINSIZE5_DW                             4
++#define WF_LWTBL_NEGOTIATED_WINSIZE5_ADDR                           16
++#define WF_LWTBL_NEGOTIATED_WINSIZE5_MASK \
 +	0x00038000 // 17-15
-+#define WF_LWTBL_ANT_ID5_SHIFT                                      15
-+#define WF_LWTBL_ANT_ID6_DW                                         4
-+#define WF_LWTBL_ANT_ID6_ADDR                                       16
-+#define WF_LWTBL_ANT_ID6_MASK \
++#define WF_LWTBL_NEGOTIATED_WINSIZE5_SHIFT                          15
++#define WF_LWTBL_NEGOTIATED_WINSIZE6_DW                             4
++#define WF_LWTBL_NEGOTIATED_WINSIZE6_ADDR                           16
++#define WF_LWTBL_NEGOTIATED_WINSIZE6_MASK \
 +	0x001c0000 // 20-18
-+#define WF_LWTBL_ANT_ID6_SHIFT                                      18
-+#define WF_LWTBL_ANT_ID7_DW                                         4
-+#define WF_LWTBL_ANT_ID7_ADDR                                       16
-+#define WF_LWTBL_ANT_ID7_MASK \
++#define WF_LWTBL_NEGOTIATED_WINSIZE6_SHIFT                          18
++#define WF_LWTBL_NEGOTIATED_WINSIZE7_DW                             4
++#define WF_LWTBL_NEGOTIATED_WINSIZE7_ADDR                           16
++#define WF_LWTBL_NEGOTIATED_WINSIZE7_MASK \
 +	0x00e00000 // 23-21
-+#define WF_LWTBL_ANT_ID7_SHIFT                                      21
++#define WF_LWTBL_NEGOTIATED_WINSIZE7_SHIFT                          21
 +#define WF_LWTBL_PE_DW                                              4
 +#define WF_LWTBL_PE_ADDR                                            16
 +#define WF_LWTBL_PE_MASK \
@@ -1501,6 +1524,11 @@
 +#define WF_LWTBL_LDPC_EHT_MASK \
 +	0x40000000 // 30-30
 +#define WF_LWTBL_LDPC_EHT_SHIFT                                     30
++#define WF_LWTBL_BA_MODE_DW                                         4
++#define WF_LWTBL_BA_MODE_ADDR                                       16
++#define WF_LWTBL_BA_MODE_MASK \
++	0x80000000 // 31-31
++#define WF_LWTBL_BA_MODE_SHIFT                                      31
 +// DW5
 +#define WF_LWTBL_AF_DW                                              5
 +#define WF_LWTBL_AF_ADDR                                            20
@@ -2087,46 +2115,15 @@
 +	0xffff0000 // 31-16
 +#define WF_LWTBL_LINK_MGF_SHIFT                                     16
 +// DW31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE0_DW                             31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE0_ADDR                           124
-+#define WF_LWTBL_NEGOTIATED_WINSIZE0_MASK \
-+	0x00000007 // 2- 0
-+#define WF_LWTBL_NEGOTIATED_WINSIZE0_SHIFT                          0
-+#define WF_LWTBL_NEGOTIATED_WINSIZE1_DW                             31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE1_ADDR                           124
-+#define WF_LWTBL_NEGOTIATED_WINSIZE1_MASK \
-+	0x00000038 // 5- 3
-+#define WF_LWTBL_NEGOTIATED_WINSIZE1_SHIFT                          3
-+#define WF_LWTBL_NEGOTIATED_WINSIZE2_DW                             31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE2_ADDR                           124
-+#define WF_LWTBL_NEGOTIATED_WINSIZE2_MASK \
-+	0x000001c0 // 8- 6
-+#define WF_LWTBL_NEGOTIATED_WINSIZE2_SHIFT                          6
-+#define WF_LWTBL_NEGOTIATED_WINSIZE3_DW                             31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE3_ADDR                           124
-+#define WF_LWTBL_NEGOTIATED_WINSIZE3_MASK \
-+	0x00000e00 // 11- 9
-+#define WF_LWTBL_NEGOTIATED_WINSIZE3_SHIFT                          9
-+#define WF_LWTBL_NEGOTIATED_WINSIZE4_DW                             31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE4_ADDR                           124
-+#define WF_LWTBL_NEGOTIATED_WINSIZE4_MASK \
-+	0x00007000 // 14-12
-+#define WF_LWTBL_NEGOTIATED_WINSIZE4_SHIFT                          12
-+#define WF_LWTBL_NEGOTIATED_WINSIZE5_DW                             31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE5_ADDR                           124
-+#define WF_LWTBL_NEGOTIATED_WINSIZE5_MASK \
-+	0x00038000 // 17-15
-+#define WF_LWTBL_NEGOTIATED_WINSIZE5_SHIFT                          15
-+#define WF_LWTBL_NEGOTIATED_WINSIZE6_DW                             31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE6_ADDR                           124
-+#define WF_LWTBL_NEGOTIATED_WINSIZE6_MASK \
-+	0x001c0000 // 20-18
-+#define WF_LWTBL_NEGOTIATED_WINSIZE6_SHIFT                          18
-+#define WF_LWTBL_NEGOTIATED_WINSIZE7_DW                             31
-+#define WF_LWTBL_NEGOTIATED_WINSIZE7_ADDR                           124
-+#define WF_LWTBL_NEGOTIATED_WINSIZE7_MASK \
-+	0x00e00000 // 23-21
-+#define WF_LWTBL_NEGOTIATED_WINSIZE7_SHIFT                          21
++#define WF_LWTBL_BFTX_TB_DW                                         31
++#define WF_LWTBL_BFTX_TB_ADDR                                       124
++#define WF_LWTBL_BFTX_TB_MASK \
++	0x00800000 // 23-23
++#define WF_LWTBL_DROP_DW                                            31
++#define WF_LWTBL_DROP_ADDR                                          124
++#define WF_LWTBL_DROP_MASK \
++	0x01000000 // 24-24
++#define WF_LWTBL_DROP_SHIFT                                         24
 +#define WF_LWTBL_CASCAD_DW                                          31
 +#define WF_LWTBL_CASCAD_ADDR                                        124
 +#define WF_LWTBL_CASCAD_MASK \
@@ -2142,42 +2139,37 @@
 +#define WF_LWTBL_MPDU_SIZE_MASK \
 +	0x18000000 // 28-27
 +#define WF_LWTBL_MPDU_SIZE_SHIFT                                    27
-+#define WF_LWTBL_BA_MODE_DW                                         31
-+#define WF_LWTBL_BA_MODE_ADDR                                       124
-+#define WF_LWTBL_BA_MODE_MASK \
-+	0xe0000000 // 31-29
-+#define WF_LWTBL_BA_MODE_SHIFT                                      29
++#define WF_LWTBL_RXD_DUP_MODE_DW                                    31
++#define WF_LWTBL_RXD_DUP_MODE_ADDR                                  124
++#define WF_LWTBL_RXD_DUP_MODE_MASK \
++	0x60000000 // 30-29
++#define WF_LWTBL_RXD_DUP_MODE_SHIFT                                 29
++#define WF_LWTBL_ACK_EN_DW                                          31
++#define WF_LWTBL_ACK_EN_ADDR                                        128
++#define WF_LWTBL_ACK_EN_MASK \
++	0x80000000 // 31-31
++#define WF_LWTBL_ACK_EN_SHIFT                                       31
 +// DW32
 +#define WF_LWTBL_OM_INFO_DW                                         32
 +#define WF_LWTBL_OM_INFO_ADDR                                       128
 +#define WF_LWTBL_OM_INFO_MASK \
 +	0x00000fff // 11- 0
 +#define WF_LWTBL_OM_INFO_SHIFT                                      0
++#define WF_LWTBL_OM_INFO_EHT_DW                                     32
++#define WF_LWTBL_OM_INFO_EHT_ADDR                                   128
++#define WF_LWTBL_OM_INFO_EHT_MASK \
++	0x0000f000 // 15-12
++#define WF_LWTBL_OM_INFO_EHT_SHIFT                                  12
 +#define WF_LWTBL_RXD_DUP_FOR_OM_CHG_DW                              32
 +#define WF_LWTBL_RXD_DUP_FOR_OM_CHG_ADDR                            128
 +#define WF_LWTBL_RXD_DUP_FOR_OM_CHG_MASK \
-+	0x00001000 // 12-12
-+#define WF_LWTBL_RXD_DUP_FOR_OM_CHG_SHIFT                           12
++	0x00010000 // 16-16
++#define WF_LWTBL_RXD_DUP_FOR_OM_CHG_SHIFT                           16
 +#define WF_LWTBL_RXD_DUP_WHITE_LIST_DW                              32
 +#define WF_LWTBL_RXD_DUP_WHITE_LIST_ADDR                            128
 +#define WF_LWTBL_RXD_DUP_WHITE_LIST_MASK \
-+	0x01ffe000 // 24-13
-+#define WF_LWTBL_RXD_DUP_WHITE_LIST_SHIFT                           13
-+#define WF_LWTBL_RXD_DUP_MODE_DW                                    32
-+#define WF_LWTBL_RXD_DUP_MODE_ADDR                                  128
-+#define WF_LWTBL_RXD_DUP_MODE_MASK \
-+	0x06000000 // 26-25
-+#define WF_LWTBL_RXD_DUP_MODE_SHIFT                                 25
-+#define WF_LWTBL_DROP_DW                                            32
-+#define WF_LWTBL_DROP_ADDR                                          128
-+#define WF_LWTBL_DROP_MASK \
-+	0x40000000 // 30-30
-+#define WF_LWTBL_DROP_SHIFT                                         30
-+#define WF_LWTBL_ACK_EN_DW                                          32
-+#define WF_LWTBL_ACK_EN_ADDR                                        128
-+#define WF_LWTBL_ACK_EN_MASK \
-+	0x80000000 // 31-31
-+#define WF_LWTBL_ACK_EN_SHIFT                                       31
++	0x1ffe0000 // 28-17
++#define WF_LWTBL_RXD_DUP_WHITE_LIST_SHIFT                           17
 +// DW33
 +#define WF_LWTBL_USER_RSSI_DW                                       33
 +#define WF_LWTBL_USER_RSSI_ADDR                                     132
@@ -2288,6 +2280,10 @@
 +#define WTBL_AMSDU_EN_MASK              BIT(11)
 +#define WTBL_AMSDU_EN_OFFSET            11
 +
++/* UWTBL DW 8 */
++#define WTBL_SEC_ADDR_MODE_MASK		BITS(20, 21)
++#define WTBL_SEC_ADDR_MODE_OFFSET	20
++
 +/* LWTBL Rate field */
 +#define WTBL_RATE_TX_RATE_MASK          BITS(0, 5)
 +#define WTBL_RATE_TX_RATE_OFFSET        0
@@ -2380,10 +2376,10 @@
 +#endif
 diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
 new file mode 100644
-index 00000000..f04c300f
+index 0000000..5aa5c94
 --- /dev/null
 +++ b/mt7996/mtk_debugfs.c
-@@ -0,0 +1,2353 @@
+@@ -0,0 +1,2379 @@
 +// SPDX-License-Identifier: ISC
 +/*
 + * Copyright (C) 2023 MediaTek Inc.
@@ -2406,7 +2402,7 @@
 +	struct mt7996_dev *dev = dev_get_drvdata(s->private);
 +	u64 total_burst, total_ampdu, ampdu_cnt[16];
 +	u32 value, idx, row_idx, col_idx, start_range, agg_rang_sel[16], burst_cnt[16], band_offset = 0;
-+	u8 readFW = 0, partial_str[16] = {}, full_str[64] = {};
++	u8 partial_str[16] = {}, full_str[64] = {};
 +
 +	switch (band_idx) {
 +	case 0:
@@ -2465,50 +2461,46 @@
 +
 +	seq_printf(s, "===AMPDU Related Counters===\n");
 +
-+	if (readFW) {
-+		/* BELLWETHER TODO: Wait MIB counter API implement complete */
-+	} else {
-+		value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC0_ADDR + band_offset);
-+		agg_rang_sel[0] = (value & BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_0_MASK) >> BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_0_SHFT;
-+		agg_rang_sel[1] = (value & BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_1_MASK) >> BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_1_SHFT;
-+		value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC1_ADDR + band_offset);
-+		agg_rang_sel[2] = (value & BN0_WF_MIB_TOP_TRARC1_AGG_RANG_SEL_2_MASK) >> BN0_WF_MIB_TOP_TRARC1_AGG_RANG_SEL_2_SHFT;
-+		agg_rang_sel[3] = (value & BN0_WF_MIB_TOP_TRARC1_AGG_RANG_SEL_3_MASK) >> BN0_WF_MIB_TOP_TRARC1_AGG_RANG_SEL_3_SHFT;
-+		value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC2_ADDR + band_offset);
-+		agg_rang_sel[4] = (value & BN0_WF_MIB_TOP_TRARC2_AGG_RANG_SEL_4_MASK) >> BN0_WF_MIB_TOP_TRARC2_AGG_RANG_SEL_4_SHFT;
-+		agg_rang_sel[5] = (value & BN0_WF_MIB_TOP_TRARC2_AGG_RANG_SEL_5_MASK) >> BN0_WF_MIB_TOP_TRARC2_AGG_RANG_SEL_5_SHFT;
-+		value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC3_ADDR + band_offset);
-+		agg_rang_sel[6] = (value & BN0_WF_MIB_TOP_TRARC3_AGG_RANG_SEL_6_MASK) >> BN0_WF_MIB_TOP_TRARC3_AGG_RANG_SEL_6_SHFT;
-+		agg_rang_sel[7] = (value & BN0_WF_MIB_TOP_TRARC3_AGG_RANG_SEL_7_MASK) >> BN0_WF_MIB_TOP_TRARC3_AGG_RANG_SEL_7_SHFT;
-+		value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC4_ADDR + band_offset);
-+		agg_rang_sel[8] = (value & BN0_WF_MIB_TOP_TRARC4_AGG_RANG_SEL_8_MASK) >> BN0_WF_MIB_TOP_TRARC4_AGG_RANG_SEL_8_SHFT;
-+		agg_rang_sel[9] = (value & BN0_WF_MIB_TOP_TRARC4_AGG_RANG_SEL_9_MASK) >> BN0_WF_MIB_TOP_TRARC4_AGG_RANG_SEL_9_SHFT;
-+		value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC5_ADDR + band_offset);
-+		agg_rang_sel[10] = (value & BN0_WF_MIB_TOP_TRARC5_AGG_RANG_SEL_10_MASK) >> BN0_WF_MIB_TOP_TRARC5_AGG_RANG_SEL_10_SHFT;
-+		agg_rang_sel[11] = (value & BN0_WF_MIB_TOP_TRARC5_AGG_RANG_SEL_11_MASK) >> BN0_WF_MIB_TOP_TRARC5_AGG_RANG_SEL_11_SHFT;
-+		value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC6_ADDR + band_offset);
-+		agg_rang_sel[12] = (value & BN0_WF_MIB_TOP_TRARC6_AGG_RANG_SEL_12_MASK) >> BN0_WF_MIB_TOP_TRARC6_AGG_RANG_SEL_12_SHFT;
-+		agg_rang_sel[13] = (value & BN0_WF_MIB_TOP_TRARC6_AGG_RANG_SEL_13_MASK) >> BN0_WF_MIB_TOP_TRARC6_AGG_RANG_SEL_13_SHFT;
-+		value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC7_ADDR + band_offset);
-+		agg_rang_sel[14] = (value & BN0_WF_MIB_TOP_TRARC7_AGG_RANG_SEL_14_MASK) >> BN0_WF_MIB_TOP_TRARC7_AGG_RANG_SEL_14_SHFT;
++	value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC0_ADDR + band_offset);
++	agg_rang_sel[0] = (value & BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_0_MASK) >> BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_0_SHFT;
++	agg_rang_sel[1] = (value & BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_1_MASK) >> BN0_WF_MIB_TOP_TRARC0_AGG_RANG_SEL_1_SHFT;
++	value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC1_ADDR + band_offset);
++	agg_rang_sel[2] = (value & BN0_WF_MIB_TOP_TRARC1_AGG_RANG_SEL_2_MASK) >> BN0_WF_MIB_TOP_TRARC1_AGG_RANG_SEL_2_SHFT;
++	agg_rang_sel[3] = (value & BN0_WF_MIB_TOP_TRARC1_AGG_RANG_SEL_3_MASK) >> BN0_WF_MIB_TOP_TRARC1_AGG_RANG_SEL_3_SHFT;
++	value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC2_ADDR + band_offset);
++	agg_rang_sel[4] = (value & BN0_WF_MIB_TOP_TRARC2_AGG_RANG_SEL_4_MASK) >> BN0_WF_MIB_TOP_TRARC2_AGG_RANG_SEL_4_SHFT;
++	agg_rang_sel[5] = (value & BN0_WF_MIB_TOP_TRARC2_AGG_RANG_SEL_5_MASK) >> BN0_WF_MIB_TOP_TRARC2_AGG_RANG_SEL_5_SHFT;
++	value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC3_ADDR + band_offset);
++	agg_rang_sel[6] = (value & BN0_WF_MIB_TOP_TRARC3_AGG_RANG_SEL_6_MASK) >> BN0_WF_MIB_TOP_TRARC3_AGG_RANG_SEL_6_SHFT;
++	agg_rang_sel[7] = (value & BN0_WF_MIB_TOP_TRARC3_AGG_RANG_SEL_7_MASK) >> BN0_WF_MIB_TOP_TRARC3_AGG_RANG_SEL_7_SHFT;
++	value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC4_ADDR + band_offset);
++	agg_rang_sel[8] = (value & BN0_WF_MIB_TOP_TRARC4_AGG_RANG_SEL_8_MASK) >> BN0_WF_MIB_TOP_TRARC4_AGG_RANG_SEL_8_SHFT;
++	agg_rang_sel[9] = (value & BN0_WF_MIB_TOP_TRARC4_AGG_RANG_SEL_9_MASK) >> BN0_WF_MIB_TOP_TRARC4_AGG_RANG_SEL_9_SHFT;
++	value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC5_ADDR + band_offset);
++	agg_rang_sel[10] = (value & BN0_WF_MIB_TOP_TRARC5_AGG_RANG_SEL_10_MASK) >> BN0_WF_MIB_TOP_TRARC5_AGG_RANG_SEL_10_SHFT;
++	agg_rang_sel[11] = (value & BN0_WF_MIB_TOP_TRARC5_AGG_RANG_SEL_11_MASK) >> BN0_WF_MIB_TOP_TRARC5_AGG_RANG_SEL_11_SHFT;
++	value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC6_ADDR + band_offset);
++	agg_rang_sel[12] = (value & BN0_WF_MIB_TOP_TRARC6_AGG_RANG_SEL_12_MASK) >> BN0_WF_MIB_TOP_TRARC6_AGG_RANG_SEL_12_SHFT;
++	agg_rang_sel[13] = (value & BN0_WF_MIB_TOP_TRARC6_AGG_RANG_SEL_13_MASK) >> BN0_WF_MIB_TOP_TRARC6_AGG_RANG_SEL_13_SHFT;
++	value = mt76_rr(dev, BN0_WF_MIB_TOP_TRARC7_ADDR + band_offset);
++	agg_rang_sel[14] = (value & BN0_WF_MIB_TOP_TRARC7_AGG_RANG_SEL_14_MASK) >> BN0_WF_MIB_TOP_TRARC7_AGG_RANG_SEL_14_SHFT;
 +
-+		burst_cnt[0] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR0_ADDR + band_offset);
-+		burst_cnt[1] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR1_ADDR + band_offset);
-+		burst_cnt[2] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR2_ADDR + band_offset);
-+		burst_cnt[3] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR3_ADDR + band_offset);
-+		burst_cnt[4] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR4_ADDR + band_offset);
-+		burst_cnt[5] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR5_ADDR + band_offset);
-+		burst_cnt[6] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR6_ADDR + band_offset);
-+		burst_cnt[7] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR7_ADDR + band_offset);
-+		burst_cnt[8] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR8_ADDR + band_offset);
-+		burst_cnt[9] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR9_ADDR + band_offset);
-+		burst_cnt[10] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR10_ADDR + band_offset);
-+		burst_cnt[11] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR11_ADDR + band_offset);
-+		burst_cnt[12] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR12_ADDR + band_offset);
-+		burst_cnt[13] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR13_ADDR + band_offset);
-+		burst_cnt[14] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR14_ADDR + band_offset);
-+		burst_cnt[15] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR15_ADDR + band_offset);
-+	}
++	burst_cnt[0] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR0_ADDR + band_offset);
++	burst_cnt[1] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR1_ADDR + band_offset);
++	burst_cnt[2] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR2_ADDR + band_offset);
++	burst_cnt[3] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR3_ADDR + band_offset);
++	burst_cnt[4] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR4_ADDR + band_offset);
++	burst_cnt[5] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR5_ADDR + band_offset);
++	burst_cnt[6] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR6_ADDR + band_offset);
++	burst_cnt[7] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR7_ADDR + band_offset);
++	burst_cnt[8] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR8_ADDR + band_offset);
++	burst_cnt[9] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR9_ADDR + band_offset);
++	burst_cnt[10] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR10_ADDR + band_offset);
++	burst_cnt[11] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR11_ADDR + band_offset);
++	burst_cnt[12] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR12_ADDR + band_offset);
++	burst_cnt[13] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR13_ADDR + band_offset);
++	burst_cnt[14] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR14_ADDR + band_offset);
++	burst_cnt[15] = mt76_rr(dev, BN0_WF_MIB_TOP_TRDR15_ADDR + band_offset);
 +
 +	start_range = 1;
 +	total_burst = 0;
@@ -3455,7 +3447,8 @@
 +	{"PFMU_IDX",	    WF_LWTBL_PFMU_IDX_MASK,		WF_LWTBL_PFMU_IDX_SHIFT,	false},
 +	{"ULPF_IDX",	    WF_LWTBL_ULPF_IDX_MASK,		WF_LWTBL_ULPF_IDX_SHIFT,	false},
 +	{"RIBF",	    WF_LWTBL_RIBF_MASK,			NO_SHIFT_DEFINE,		false},
-+	{"ULPF",	    WF_LWTBL_ULPF_MASK,			NO_SHIFT_DEFINE,		true},
++	{"ULPF",	    WF_LWTBL_ULPF_MASK,			NO_SHIFT_DEFINE,		false},
++	{"BYPASS_TXSMM",    WF_LWTBL_BYPASS_TXSMM_MASK,         NO_SHIFT_DEFINE,		true},
 +	{"TBF_HT",          WF_LWTBL_TBF_HT_MASK,		NO_SHIFT_DEFINE,		false},
 +	{"TBF_VHT",         WF_LWTBL_TBF_VHT_MASK,		NO_SHIFT_DEFINE,		false},
 +	{"TBF_HE",          WF_LWTBL_TBF_HE_MASK,		NO_SHIFT_DEFINE,		false},
@@ -3489,20 +3482,21 @@
 +}
 +
 +static const struct berse_wtbl_parse WTBL_LMAC_DW4[] = {
-+	{"ANT_ID_STS0",     WF_LWTBL_ANT_ID0_MASK,      WF_LWTBL_ANT_ID0_SHIFT,	false},
-+	{"STS1",            WF_LWTBL_ANT_ID1_MASK,      WF_LWTBL_ANT_ID1_SHIFT,	false},
-+	{"STS2",            WF_LWTBL_ANT_ID2_MASK,      WF_LWTBL_ANT_ID2_SHIFT,	false},
-+	{"STS3",            WF_LWTBL_ANT_ID3_MASK,      WF_LWTBL_ANT_ID3_SHIFT,	true},
-+	{"ANT_ID_STS4",     WF_LWTBL_ANT_ID4_MASK,      WF_LWTBL_ANT_ID4_SHIFT,	false},
-+	{"STS5",            WF_LWTBL_ANT_ID5_MASK,      WF_LWTBL_ANT_ID5_SHIFT,	false},
-+	{"STS6",            WF_LWTBL_ANT_ID6_MASK,      WF_LWTBL_ANT_ID6_SHIFT,	false},
-+	{"STS7",            WF_LWTBL_ANT_ID7_MASK,      WF_LWTBL_ANT_ID7_SHIFT,	true},
++	{"NEGOTIATED_WINSIZE0",	WF_LWTBL_NEGOTIATED_WINSIZE0_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE0_SHIFT,    false},
++	{"WINSIZE1",	WF_LWTBL_NEGOTIATED_WINSIZE1_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE1_SHIFT,    false},
++	{"WINSIZE2",	WF_LWTBL_NEGOTIATED_WINSIZE2_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE2_SHIFT,    false},
++	{"WINSIZE3",	WF_LWTBL_NEGOTIATED_WINSIZE3_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE3_SHIFT,    true},
++	{"WINSIZE4",	WF_LWTBL_NEGOTIATED_WINSIZE4_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE4_SHIFT,    false},
++	{"WINSIZE5",	WF_LWTBL_NEGOTIATED_WINSIZE5_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE5_SHIFT,    false},
++	{"WINSIZE6",	WF_LWTBL_NEGOTIATED_WINSIZE6_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE6_SHIFT,    false},
++	{"WINSIZE7",	WF_LWTBL_NEGOTIATED_WINSIZE7_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE7_SHIFT,    true},
 +	{"PE",              WF_LWTBL_PE_MASK,           WF_LWTBL_PE_SHIFT,	false},
 +	{"DIS_RHTR",        WF_LWTBL_DIS_RHTR_MASK,     NO_SHIFT_DEFINE,	false},
 +	{"LDPC_HT",         WF_LWTBL_LDPC_HT_MASK,      NO_SHIFT_DEFINE,	false},
 +	{"LDPC_VHT",        WF_LWTBL_LDPC_VHT_MASK,     NO_SHIFT_DEFINE,	false},
 +	{"LDPC_HE",         WF_LWTBL_LDPC_HE_MASK,      NO_SHIFT_DEFINE,	false},
 +	{"LDPC_EHT",	    WF_LWTBL_LDPC_EHT_MASK,	NO_SHIFT_DEFINE,	true},
++	{"BA_MODE",	    WF_LWTBL_BA_MODE_MASK,	NO_SHIFT_DEFINE,	true},
 +	{NULL,}
 +};
 +
@@ -3888,6 +3882,12 @@
 +	{NULL,}
 +};
 +
++static const struct berse_wtbl_parse WTBL_LMAC_DW14[] = {
++	{"RATE1_TX_CNT",      WF_LWTBL_RATE1_TX_CNT_MASK,     WF_LWTBL_RATE1_TX_CNT_SHIFT,   false},
++	{"RATE1_FAIL_CNT",    WF_LWTBL_RATE1_FAIL_CNT_MASK,   WF_LWTBL_RATE1_FAIL_CNT_SHIFT, true},
++	{NULL,}
++};
++
 +static void parse_fmac_lwtbl_dw14(struct seq_file *s, u8 *lwtbl)
 +{
 +	u32 *addr, *muar_addr = 0;
@@ -3906,7 +3906,27 @@
 +		dw_value = *addr;
 +
 +		while (WTBL_LMAC_DW14_BMC[i].name) {
-+			parse_rate(s, i+6, (dw_value & WTBL_LMAC_DW14_BMC[i].mask) >> WTBL_LMAC_DW14_BMC[i].shift);
++			if (WTBL_LMAC_DW14_BMC[i].shift == NO_SHIFT_DEFINE)
++				seq_printf(s, "\t%s:%d\n", WTBL_LMAC_DW14_BMC[i].name,
++					(dw_value & WTBL_LMAC_DW14_BMC[i].mask) ? 1 : 0);
++			else
++				seq_printf(s, "\t%s:%u\n", WTBL_LMAC_DW14_BMC[i].name,
++					(dw_value & WTBL_LMAC_DW14_BMC[i].mask) >> WTBL_LMAC_DW14_BMC[i].shift);
++			i++;
++		}
++	} else {
++		seq_printf(s, "\t\n");
++		seq_printf(s, "LWTBL DW 14\n");
++		addr = (u32 *)&(lwtbl[WF_LWTBL_CIPHER_SUIT_IGTK_DW*4]);
++		dw_value = *addr;
++
++		while (WTBL_LMAC_DW14[i].name) {
++			if (WTBL_LMAC_DW14[i].shift == NO_SHIFT_DEFINE)
++				seq_printf(s, "\t%s:%d\n", WTBL_LMAC_DW14[i].name,
++					(dw_value & WTBL_LMAC_DW14[i].mask) ? 1 : 0);
++			else
++				seq_printf(s, "\t%s:%u\n", WTBL_LMAC_DW14[i].name,
++					(dw_value & WTBL_LMAC_DW14[i].mask) >> WTBL_LMAC_DW14[i].shift);
 +			i++;
 +		}
 +	}
@@ -3916,7 +3936,7 @@
 +	{"RELATED_IDX0",	WF_LWTBL_RELATED_IDX0_MASK,		WF_LWTBL_RELATED_IDX0_SHIFT,	false},
 +	{"RELATED_BAND0",	WF_LWTBL_RELATED_BAND0_MASK,		WF_LWTBL_RELATED_BAND0_SHIFT,	false},
 +	{"PRI_MLD_BAND",    WF_LWTBL_PRIMARY_MLD_BAND_MASK,		WF_LWTBL_PRIMARY_MLD_BAND_SHIFT,	true},
-+	{"RELATED_IDX0",	WF_LWTBL_RELATED_IDX1_MASK,		WF_LWTBL_RELATED_IDX1_SHIFT,	false},
++	{"RELATED_IDX1",	WF_LWTBL_RELATED_IDX1_MASK,		WF_LWTBL_RELATED_IDX1_SHIFT,	false},
 +	{"RELATED_BAND1",   WF_LWTBL_RELATED_BAND1_MASK,		WF_LWTBL_RELATED_BAND1_SHIFT,	false},
 +	{"SEC_MLD_BAND",	WF_LWTBL_SECONDARY_MLD_BAND_MASK,	WF_LWTBL_SECONDARY_MLD_BAND_SHIFT,	true},
 +	{NULL,}
@@ -4022,18 +4042,13 @@
 +}
 +
 +static const struct berse_wtbl_parse WTBL_LMAC_DW31[] = {
-+	{"NEGO_WINSIZE0",	WF_LWTBL_NEGOTIATED_WINSIZE0_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE0_SHIFT,    false},
-+	{"WINSIZE1",	WF_LWTBL_NEGOTIATED_WINSIZE1_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE1_SHIFT,    false},
-+	{"WINSIZE2",	WF_LWTBL_NEGOTIATED_WINSIZE2_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE2_SHIFT,    false},
-+	{"WINSIZE3",	WF_LWTBL_NEGOTIATED_WINSIZE3_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE3_SHIFT,    true},
-+	{"WINSIZE4",	WF_LWTBL_NEGOTIATED_WINSIZE4_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE4_SHIFT,    false},
-+	{"WINSIZE5",	WF_LWTBL_NEGOTIATED_WINSIZE5_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE5_SHIFT,    false},
-+	{"WINSIZE6",	WF_LWTBL_NEGOTIATED_WINSIZE6_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE6_SHIFT,    false},
-+	{"WINSIZE7",	WF_LWTBL_NEGOTIATED_WINSIZE7_MASK,	WF_LWTBL_NEGOTIATED_WINSIZE7_SHIFT,    true},
++	{"BFTX_TB",          WF_LWTBL_BFTX_TB_MASK,                 NO_SHIFT_DEFINE,    false},
++	{"DROP",          WF_LWTBL_DROP_MASK,                 NO_SHIFT_DEFINE,    false},
 +	{"CASCAD",	        WF_LWTBL_CASCAD_MASK,			NO_SHIFT_DEFINE,    false},
 +	{"ALL_ACK",	        WF_LWTBL_ALL_ACK_MASK,			NO_SHIFT_DEFINE,    false},
 +	{"MPDU_SIZE",	WF_LWTBL_MPDU_SIZE_MASK,		WF_LWTBL_MPDU_SIZE_SHIFT,  false},
-+	{"BA_MODE",		WF_LWTBL_BA_MODE_MASK,			WF_LWTBL_BA_MODE_SHIFT,  true},
++	{"RXD_DUP_MODE",	WF_LWTBL_RXD_DUP_MODE_MASK,			WF_LWTBL_RXD_DUP_MODE_SHIFT,  true},
++	{"ACK_EN",		WF_LWTBL_ACK_EN_MASK,			NO_SHIFT_DEFINE,		true},
 +	{NULL,}
 +};
 +
@@ -4063,11 +4078,9 @@
 +
 +static const struct berse_wtbl_parse WTBL_LMAC_DW32[] = {
 +	{"OM_INFO",			WF_LWTBL_OM_INFO_MASK,			WF_LWTBL_OM_INFO_SHIFT,		false},
-+	{"OM_RXD_DUP_MODE",		WF_LWTBL_RXD_DUP_FOR_OM_CHG_MASK,	NO_SHIFT_DEFINE,		false},
++	{"OM_INFO_EHT",         WF_LWTBL_OM_INFO_EHT_MASK,         WF_LWTBL_OM_INFO_EHT_SHIFT,  false},
++	{"RXD_DUP_FOR_OM_CHG",		WF_LWTBL_RXD_DUP_FOR_OM_CHG_MASK,	NO_SHIFT_DEFINE,		false},
 +	{"RXD_DUP_WHITE_LIST",	WF_LWTBL_RXD_DUP_WHITE_LIST_MASK,	WF_LWTBL_RXD_DUP_WHITE_LIST_SHIFT,	false},
-+	{"RXD_DUP_MODE",		WF_LWTBL_RXD_DUP_MODE_MASK,		WF_LWTBL_RXD_DUP_MODE_SHIFT,	false},
-+	{"DROP",			WF_LWTBL_DROP_MASK,			NO_SHIFT_DEFINE,		false},
-+	{"ACK_EN",			WF_LWTBL_ACK_EN_MASK,			NO_SHIFT_DEFINE,		true},
 +	{NULL,}
 +};
 +
@@ -4212,7 +4225,7 @@
 +	{"RELATED_IDX0",	WF_UWTBL_RELATED_IDX0_MASK,		WF_UWTBL_RELATED_IDX0_SHIFT,	false},
 +	{"RELATED_BAND0",	WF_UWTBL_RELATED_BAND0_MASK,		WF_UWTBL_RELATED_BAND0_SHIFT,	false},
 +	{"PRI_MLD_BAND",    WF_UWTBL_PRIMARY_MLD_BAND_MASK,		WF_UWTBL_PRIMARY_MLD_BAND_SHIFT,	true},
-+	{"RELATED_IDX0",	WF_UWTBL_RELATED_IDX1_MASK,		WF_UWTBL_RELATED_IDX1_SHIFT,	false},
++	{"RELATED_IDX1",	WF_UWTBL_RELATED_IDX1_MASK,		WF_UWTBL_RELATED_IDX1_SHIFT,	false},
 +	{"RELATED_BAND1",   WF_UWTBL_RELATED_BAND1_MASK,		WF_UWTBL_RELATED_BAND1_SHIFT,	false},
 +	{"SEC_MLD_BAND",	WF_UWTBL_SECONDARY_MLD_BAND_MASK,	WF_UWTBL_SECONDARY_MLD_BAND_SHIFT,	true},
 +	{NULL,}
@@ -4287,6 +4300,7 @@
 +static const struct berse_wtbl_parse WTBL_UMAC_DW3[] = {
 +	{"PN4",     WTBL_PN4_MASK,      WTBL_PN4_OFFSET,	false},
 +	{"PN5",     WTBL_PN5_MASK,      WTBL_PN5_OFFSET,	true},
++	{"COM_SN",     WF_UWTBL_COM_SN_MASK,     WF_UWTBL_COM_SN_SHIFT,	true},
 +	{NULL,}
 +};
 +
@@ -4299,8 +4313,8 @@
 +};
 +
 +static const struct berse_wtbl_parse WTBL_UMAC_DW5_BIPN[] = {
-+	{"BIPN4",	WTBL_BIPN0_MASK,	WTBL_BIPN0_OFFSET,	false},
-+	{"BIPN5",	WTBL_BIPN1_MASK,	WTBL_BIPN1_OFFSET,	true},
++	{"BIPN4",	WTBL_BIPN4_MASK,	WTBL_BIPN4_OFFSET,	false},
++	{"BIPN5",	WTBL_BIPN5_MASK,	WTBL_BIPN5_OFFSET,	true},
 +	{NULL,}
 +};
 +
@@ -4515,6 +4529,8 @@
 +
 +	/* UMAC WTBL DW 6 for BIGTK */
 +	if (is_wtbl_bigtk_exist(lwtbl) == true) {
++		addr = (u32 *)&(uwtbl[WF_UWTBL_KEY_LOC2_DW*4]);
++		dw_value = *addr;
 +		keyloc2 = (dw_value & WF_UWTBL_KEY_LOC2_MASK) >>
 +			WF_UWTBL_KEY_LOC2_SHIFT;
 +		seq_printf(s, "\t%s:%u\n", "Key Loc 2", keyloc2);
@@ -4558,6 +4574,12 @@
 +		i++;
 +	}
 +
++	/* UMAC WTBL DW 8 - SEC_ADDR_MODE */
++	addr = (u32 *)&(uwtbl[WF_UWTBL_SEC_ADDR_MODE_DW*4]);
++	dw_value = *addr;
++	seq_printf(s, "\t%s:%lu\n", "SEC_ADDR_MODE",
++		(dw_value & WTBL_SEC_ADDR_MODE_MASK) >> WTBL_SEC_ADDR_MODE_OFFSET);
++
 +	/* UMAC WTBL DW 8 - AMSDU_CFG */
 +	seq_printf(s, "\t%s:%d\n", "HW AMSDU Enable",
 +				(dw_value & WTBL_AMSDU_EN_MASK) ? 1 : 0);
@@ -4739,7 +4761,7 @@
 +#endif
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
 new file mode 100644
-index 00000000..e8870166
+index 0000000..e887016
 --- /dev/null
 +++ b/mt7996/mtk_mcu.c
 @@ -0,0 +1,18 @@
@@ -4763,7 +4785,7 @@
 +#endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
 new file mode 100644
-index 00000000..e741aa27
+index 0000000..e741aa2
 --- /dev/null
 +++ b/mt7996/mtk_mcu.h
 @@ -0,0 +1,16 @@
@@ -4784,7 +4806,7 @@
 +
 +#endif
 diff --git a/tools/fwlog.c b/tools/fwlog.c
-index e5d4a105..3c6a61d7 100644
+index e5d4a10..3c6a61d 100644
 --- a/tools/fwlog.c
 +++ b/tools/fwlog.c
 @@ -26,7 +26,7 @@ static const char *debugfs_path(const char *phyname, const char *file)
@@ -4868,5 +4890,5 @@
  	return ret;
  }
 -- 
-2.39.2
+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/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch
new file mode 100644
index 0000000..ff8d7a8
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch
@@ -0,0 +1,61 @@
+From cb64d3c0b0dd79b8255caef614b13fe17f1b5b07 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
+
+Add check for hostapd config he_ldpc.
+This capabilities is checked in mcu_beacon_check_caps in 7915.
+
+Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
+Change-Id: I6d6f59df8897e3c00f2e0a1e3c6e5701e31c5e4b
+---
+ mt7996/mcu.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index fdc4fb4..7d0c511 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -1096,7 +1096,8 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
+ }
+ 
+ static void
+-mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
++mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
++		      struct ieee80211_sta *sta)
+ {
+ 	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)
+ 		he->he_phy_cap[i] = elem->phy_cap_info[i];
+ 	}
+ 
++	if (vif->type == NL80211_IFTYPE_AP)
++		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,
+ 	 * update sta_rec_he here.
+ 	 */
+ 	if (changed)
+-		mt7996_mcu_sta_he_tlv(skb, sta);
++		mt7996_mcu_sta_he_tlv(skb, vif, sta);
+ 
+ 	/* 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,
+ 		/* starec amsdu */
+ 		mt7996_mcu_sta_amsdu_tlv(dev, skb, vif, sta);
+ 		/* starec he */
+-		mt7996_mcu_sta_he_tlv(skb, sta);
++		mt7996_mcu_sta_he_tlv(skb, vif, sta);
+ 		/* starec he 6g*/
+ 		mt7996_mcu_sta_he_6g_tlv(skb, sta);
+ 		/* starec eht */
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
similarity index 86%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
index 686576d..56f85a8 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
@@ -1,7 +1,7 @@
-From 33211d380fbf3b0892e560db99ac8dbc5c4e8cd5 Mon Sep 17 00:00:00 2001
+From e622295e18a1af30c999928701787d8c562621c3 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 23/39] wifi: mt76: testmode: add atenl support in mt7996
+Subject: [PATCH 35/98] wifi: mt76: testmode: add atenl support in mt7996
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -10,10 +10,10 @@
  2 files changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/testmode.c b/testmode.c
-index 0accc71..0d2bae9 100644
+index 4644dac..5c93aa6 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -612,7 +612,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -613,7 +613,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  
  	if (dev->test_mtd.name &&
  	    (nla_put_string(msg, MT76_TM_ATTR_MTD_PART, dev->test_mtd.name) ||
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-testmode-add-basic-testmode-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-testmode-add-basic-testmode-support.patch
similarity index 83%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-testmode-add-basic-testmode-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-testmode-add-basic-testmode-support.patch
index 6facdc3..5b78a59 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-testmode-add-basic-testmode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-testmode-add-basic-testmode-support.patch
@@ -1,36 +1,37 @@
-From 826ab7312fa42110844329a333df76dec614e48f Mon Sep 17 00:00:00 2001
+From ce58ffb18be834e2f62a30a71c9d6f5805517a9e 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] wifi: mt76: testmode: add basic testmode support
+Subject: [PATCH 36/98] wifi: mt76: testmode: add basic testmode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
  eeprom.c          |   6 +-
  mac80211.c        |   3 +-
- mt76.h            |  33 +++
+ mt76.h            |  35 +++
  mt76_connac_mcu.h |   2 +
- mt7996/Makefile   |   2 +
+ mt7996/Makefile   |   1 +
  mt7996/eeprom.c   |  35 ++-
  mt7996/eeprom.h   |   1 +
- mt7996/init.c     |   7 +
+ mt7996/init.c     |   8 +
+ mt7996/mac.c      |   3 +-
  mt7996/main.c     |  16 ++
  mt7996/mcu.c      |  42 ++-
  mt7996/mcu.h      |  27 ++
- mt7996/mt7996.h   |  22 ++
- mt7996/testmode.c | 658 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/testmode.h | 295 +++++++++++++++++++++
- testmode.c        |  73 +++--
- testmode.h        |  60 +++++
- tools/fields.c    |  92 +++++++
- 17 files changed, 1344 insertions(+), 30 deletions(-)
+ mt7996/mt7996.h   |  23 ++
+ mt7996/testmode.c | 674 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/testmode.h | 297 ++++++++++++++++++++
+ testmode.c        |  78 ++++--
+ testmode.h        |  64 +++++
+ tools/fields.c    | 102 ++++++-
+ 18 files changed, 1383 insertions(+), 34 deletions(-)
  create mode 100644 mt7996/testmode.c
  create mode 100644 mt7996/testmode.h
 
 diff --git a/eeprom.c b/eeprom.c
-index ea54b7a..263e508 100644
+index a07ca84..437d8ca 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -89,8 +89,10 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
+@@ -94,8 +94,10 @@ static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offs
  	}
  
  #ifdef CONFIG_NL80211_TESTMODE
@@ -44,10 +45,10 @@
  
  out_put_node:
 diff --git a/mac80211.c b/mac80211.c
-index 467afef..d1cdaee 100644
+index cd102dd..f10ca90 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -826,7 +826,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
+@@ -835,7 +835,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
  	}
  
  #ifdef CONFIG_NL80211_TESTMODE
@@ -58,10 +59,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 6b07b8f..31d5dc3 100644
+index 7f93210..feb861c 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -652,8 +652,12 @@ struct mt76_testmode_ops {
+@@ -692,14 +692,20 @@ 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);
@@ -74,7 +75,15 @@
  struct mt76_testmode_data {
  	enum mt76_testmode_state state;
  
-@@ -669,6 +673,7 @@ struct mt76_testmode_data {
+ 	u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)];
+ 	struct sk_buff *tx_skb;
+ 
++	u8 sku_en;
++
+ 	u32 tx_count;
+ 	u16 tx_mpdu_len;
+ 
+@@ -709,6 +715,7 @@ struct mt76_testmode_data {
  	u8 tx_rate_sgi;
  	u8 tx_rate_ldpc;
  	u8 tx_rate_stbc;
@@ -82,7 +91,7 @@
  	u8 tx_ltf;
  
  	u8 tx_antenna_mask;
-@@ -678,6 +683,9 @@ struct mt76_testmode_data {
+@@ -718,6 +725,9 @@ struct mt76_testmode_data {
  	u32 tx_time;
  	u32 tx_ipg;
  
@@ -92,7 +101,7 @@
  	u32 freq_offset;
  
  	u8 tx_power[4];
-@@ -692,7 +700,16 @@ struct mt76_testmode_data {
+@@ -732,7 +742,16 @@ struct mt76_testmode_data {
  	struct {
  		u64 packets[__MT_RXQ_MAX];
  		u64 fcs_error[__MT_RXQ_MAX];
@@ -109,7 +118,7 @@
  };
  
  struct mt76_vif {
-@@ -1258,6 +1275,22 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
+@@ -1418,6 +1437,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);
  
@@ -133,10 +142,10 @@
  {
  #ifdef CONFIG_NL80211_TESTMODE
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 30c9a5d..724a48a 100644
+index ca2e573..4d054bd 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1218,10 +1218,12 @@ enum {
+@@ -1239,12 +1239,14 @@ enum {
  	MCU_UNI_CMD_EFUSE_CTRL = 0x2d,
  	MCU_UNI_CMD_RA = 0x2f,
  	MCU_UNI_CMD_MURU = 0x31,
@@ -145,22 +154,25 @@
  	MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
  	MCU_UNI_CMD_THERMAL = 0x35,
  	MCU_UNI_CMD_VOW = 0x37,
+ 	MCU_UNI_CMD_PP = 0x38,
+ 	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
 +	MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
  	MCU_UNI_CMD_RRO = 0x57,
  	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
- 	MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
+ 	MCU_UNI_CMD_PER_STA_INFO = 0x6d,
 diff --git a/mt7996/Makefile b/mt7996/Makefile
-index 07c8b55..bed9efd 100644
+index a056b40..7bb17f4 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
-@@ -6,3 +6,5 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
+@@ -8,5 +8,6 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
  	     debugfs.o mmio.o
  
  mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
-+
 +mt7996e-$(CONFIG_NL80211_TESTMODE) += testmode.o
+ 
+ mt7996e-y += mtk_debugfs.o mtk_mcu.o
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 544b6c6..f5e9546 100644
+index 7ae92e1..7fd318c 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -6,6 +6,11 @@
@@ -230,7 +242,7 @@
  		if (ret < 0)
  			return ret;
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 0c74977..0f8f0cd 100644
+index 412d6e2..9ea3667 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -14,6 +14,7 @@ enum mt7996_eeprom_field {
@@ -242,10 +254,10 @@
  	MT_EE_RATE_DELTA_2G =	0x1400,
  	MT_EE_RATE_DELTA_5G =	0x147d,
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 0319e7f..fecd0d3 100644
+index 273d1e7..6d39c3c 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -641,6 +641,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -800,6 +800,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  
  	set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
  
@@ -256,18 +268,33 @@
  	ret = mt7996_mcu_init(dev);
  	if (ret)
  		return ret;
-@@ -1056,6 +1060,9 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1217,6 +1221,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
  
- 	mt7996_init_wiphy(hw);
+ 	mt7996_init_wiphy(hw, &dev->mt76.mmio.wed);
  
 +#ifdef CONFIG_NL80211_TESTMODE
 +	dev->mt76.test_ops = &mt7996_testmode_ops;
 +#endif
- 	/* init led callbacks */
- 	if (IS_ENABLED(CONFIG_MT76_LEDS)) {
- 		dev->mphy.leds.cdev.brightness_set = mt7996_led_set_brightness;
++
+ 	ret = mt76_register_device(&dev->mt76, true, mt76_rates,
+ 				   ARRAY_SIZE(mt76_rates));
+ 	if (ret)
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 32c52fc..637f0f6 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,
+ 				     *info);
+ 	}
+ 
+-	if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
++	if (rxv && mode >= MT_PHY_TYPE_HE_SU && mode < MT_PHY_TYPE_EHT_SU &&
++	    !(status->flag & RX_FLAG_8023))
+ 		mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode);
+ 
+ 	if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr)
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 8e38ebc..6c38993 100644
+index 0e51fe0..226235c 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -23,6 +23,18 @@ static bool mt7996_dev_running(struct mt7996_dev *dev)
@@ -298,7 +325,7 @@
  	mt7996_mac_enable_nf(dev, phy->mt76->band_idx);
  
  	ret = mt7996_mcu_set_rts_thresh(phy, 0x92b);
-@@ -1389,6 +1403,8 @@ const struct ieee80211_ops mt7996_ops = {
+@@ -1478,6 +1492,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,
@@ -308,10 +335,10 @@
  	.sta_add_debugfs = mt7996_sta_add_debugfs,
  #endif
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 665457a..0d2053c 100644
+index 7d0c511..141b838 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2515,8 +2515,12 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
+@@ -2681,8 +2681,12 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
  {
  	int ret;
  
@@ -326,9 +353,9 @@
  	if (ret)
  		return ret;
  
-@@ -4066,3 +4070,37 @@ 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);
+@@ -4308,3 +4312,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);
  }
 +
 +int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data)
@@ -365,10 +392,10 @@
 +				 &req, sizeof(req), false);
 +}
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index f235175..4ba06d9 100644
+index ca16336..16ffc3d 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -703,6 +703,33 @@ enum {
+@@ -814,6 +814,33 @@ enum {
  	UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG,
  };
  
@@ -403,10 +430,10 @@
  	UNI_CMD_ACCESS_REG_BASIC = 0x0,
  	UNI_CMD_ACCESS_RF_REG_BASIC,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 071031b..f7d6580 100644
+index 8801956..3964035 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -31,9 +31,11 @@
+@@ -32,9 +32,11 @@
  #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"
@@ -418,18 +445,18 @@
  #define MT7996_EEPROM_SIZE		7680
  #define MT7996_EEPROM_BLOCK_SIZE	16
  #define MT7996_TOKEN_SIZE		16384
-@@ -63,6 +65,7 @@ struct mt7996_dfs_pattern;
+@@ -83,6 +85,7 @@ struct mt7996_dfs_pattern;
  
  enum mt7996_ram_type {
  	MT7996_RAM_TYPE_WM,
 +	MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
  	MT7996_RAM_TYPE_WA,
  	MT7996_RAM_TYPE_DSP,
- };
-@@ -244,6 +247,20 @@ struct mt7996_phy {
- 
- 	struct mib_stats mib;
+ 	__MT7996_RAM_TYPE_MAX,
+@@ -225,6 +228,21 @@ struct mt7996_phy {
  	struct mt76_channel_state state_ts;
+ 
+ 	bool has_aux_rx;
 +
 +#ifdef CONFIG_NL80211_TESTMODE
 +	struct {
@@ -437,6 +464,7 @@
 +
 +		s32 last_freq_offset;
 +		u8 last_rcpi[4];
++		s8 last_rssi[4];
 +		s8 last_ib_rssi[4];
 +		s8 last_wb_rssi[4];
 +		u8 last_snr;
@@ -447,16 +475,16 @@
  };
  
  struct mt7996_dev {
-@@ -303,6 +320,8 @@ struct mt7996_dev {
- 	bool flash_mode:1;
- 	bool has_eht:1;
+@@ -300,6 +318,8 @@ struct mt7996_dev {
+ 		} session;
+ 	} wed_rro;
  
 +	bool testmode_enable;
 +
  	bool ibf;
  	u8 fw_debug_wm;
  	u8 fw_debug_wa;
-@@ -408,6 +427,7 @@ mt7996_phy3(struct mt7996_dev *dev)
+@@ -414,6 +434,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;
@@ -464,7 +492,7 @@
  
  struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
  				     void __iomem *mem_base, u32 device_id);
-@@ -417,6 +437,7 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
+@@ -423,6 +444,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);
@@ -472,20 +500,20 @@
  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);
-@@ -494,6 +515,7 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
- int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
+@@ -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);
  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);
  
  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..43eca4e
+index 0000000..fb041c3
 --- /dev/null
 +++ b/mt7996/testmode.c
-@@ -0,0 +1,658 @@
+@@ -0,0 +1,674 @@
 +// SPDX-License-Identifier: ISC
 +/*
 + * Copyright (C) 2022 MediaTek Inc.
@@ -499,6 +527,7 @@
 +enum {
 +	TM_CHANGED_TXPOWER,
 +	TM_CHANGED_FREQ_OFFSET,
++	TM_CHANGED_SKU_EN,
 +	TM_CHANGED_TX_LENGTH,
 +	TM_CHANGED_TX_TIME,
 +	TM_CHANGED_CFG,
@@ -510,6 +539,7 @@
 +static const u8 tm_change_map[] = {
 +	[TM_CHANGED_TXPOWER] = MT76_TM_ATTR_TX_POWER,
 +	[TM_CHANGED_FREQ_OFFSET] = MT76_TM_ATTR_FREQ_OFFSET,
++	[TM_CHANGED_SKU_EN] = MT76_TM_ATTR_SKU_EN,
 +	[TM_CHANGED_TX_LENGTH] = MT76_TM_ATTR_TX_LENGTH,
 +	[TM_CHANGED_TX_TIME] = MT76_TM_ATTR_TX_TIME,
 +	[TM_CHANGED_CFG] = MT76_TM_ATTR_CFG,
@@ -681,7 +711,6 @@
 +static void
 +mt7996_tm_init(struct mt7996_phy *phy, bool en)
 +{
-+#define POWER_CTRL(type)	UNI_TXPOWER_##type##_CTRL
 +	struct mt7996_dev *dev = phy->dev;
 +	u8 rf_test_mode = en ? RF_OPER_RF_TEST : RF_OPER_NORMAL;
 +
@@ -690,8 +719,6 @@
 +
 +	mt7996_mcu_set_tx_power_ctrl(phy, POWER_CTRL(ATE_MODE), en);
 +	mt7996_mcu_set_tx_power_ctrl(phy, POWER_CTRL(SKU_POWER_LIMIT), !en);
-+	mt7996_mcu_set_tx_power_ctrl(phy, POWER_CTRL(PERCENTAGE_DROP), 100);
-+	mt7996_mcu_set_tx_power_ctrl(phy, POWER_CTRL(PERCENTAGE), !en);
 +	mt7996_mcu_set_tx_power_ctrl(phy, POWER_CTRL(BACKOFF_POWER_LIMIT), !en);
 +
 +	mt7996_tm_rf_switch_mode(dev, rf_test_mode);
@@ -896,6 +923,12 @@
 +		mt7996_tm_set(dev, SET_ID(FREQ_OFFSET), en ? td->freq_offset : 0);
 +	if (changed & BIT(TM_CHANGED_TXPOWER))
 +		mt7996_tm_set(dev, SET_ID(POWER), td->tx_power[0]);
++	if (changed & BIT(TM_CHANGED_SKU_EN)) {
++		mt7996_tm_update_channel(phy);
++		mt7996_mcu_set_tx_power_ctrl(phy, POWER_CTRL(SKU_POWER_LIMIT), td->sku_en);
++		mt7996_mcu_set_tx_power_ctrl(phy, POWER_CTRL(BACKOFF_POWER_LIMIT), td->sku_en);
++		mt7996_mcu_set_txpower_sku(phy);
++	}
 +	if (changed & BIT(TM_CHANGED_TX_LENGTH)) {
 +		mt7996_tm_set(dev, SET_ID(TX_LEN), td->tx_mpdu_len);
 +		mt7996_tm_set(dev, SET_ID(TX_TIME), 0);
@@ -1028,6 +1061,7 @@
 +	phy->test.last_snr = le32_to_cpu(rx_stats_all->user_info[0].snr);
 +	for (i = 0; i < ARRAY_SIZE(phy->test.last_rcpi); i++) {
 +		phy->test.last_rcpi[i] = le16_to_cpu(rx_stats_all->rxv_info[i].rcpi);
++		phy->test.last_rssi[i] = le16_to_cpu(rx_stats_all->rxv_info[i].rssi);
 +		phy->test.last_ib_rssi[i] = rx_stats_all->fagc[i].ib_rssi;
 +		phy->test.last_wb_rssi[i] = rx_stats_all->fagc[i].wb_rssi;
 +	}
@@ -1109,6 +1143,16 @@
 +
 +	nla_nest_end(msg, rssi);
 +
++	rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RSSI);
++	if (!rssi)
++		return -ENOMEM;
++
++	for (i = 0; i < ARRAY_SIZE(phy->test.last_rssi); i++)
++		if (nla_put_s8(msg, i, phy->test.last_rssi[i]))
++			return -ENOMEM;
++
++	nla_nest_end(msg, rssi);
++
 +	rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_IB_RSSI);
 +	if (!rssi)
 +		return -ENOMEM;
@@ -1146,10 +1190,10 @@
 +};
 diff --git a/mt7996/testmode.h b/mt7996/testmode.h
 new file mode 100644
-index 0000000..f00e51f
+index 0000000..e4d55a6
 --- /dev/null
 +++ b/mt7996/testmode.h
-@@ -0,0 +1,295 @@
+@@ -0,0 +1,297 @@
 +/* SPDX-License-Identifier: ISC */
 +/* Copyright (C) 2020 MediaTek Inc. */
 +
@@ -1307,6 +1351,8 @@
 +	RF_TEST_ID_SET_AID_OFFSET = 204,
 +};
 +
++#define POWER_CTRL(type)	UNI_TXPOWER_##type##_CTRL
++
 +struct mt7996_tm_rx_stat_user_ctrl {
 +	__le16 tag;
 +	__le16 len;
@@ -1446,10 +1492,10 @@
 +
 +#endif
 diff --git a/testmode.c b/testmode.c
-index 0d2bae9..fc68c2a 100644
+index 5c93aa6..bbe8230 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -2,6 +2,7 @@
+@@ -2,11 +2,13 @@
  /* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
  
  #include <linux/random.h>
@@ -1457,7 +1503,13 @@
  #include "mt76.h"
  
  const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
-@@ -81,6 +82,11 @@ mt76_testmode_max_mpdu_len(struct mt76_phy *phy, u8 tx_rate_mode)
+ 	[MT76_TM_ATTR_RESET] = { .type = NLA_FLAG },
+ 	[MT76_TM_ATTR_STATE] = { .type = NLA_U8 },
++	[MT76_TM_ATTR_SKU_EN] = { .type = NLA_U8 },
+ 	[MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 },
+ 	[MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 },
+ 	[MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 },
+@@ -82,6 +84,11 @@ mt76_testmode_max_mpdu_len(struct mt76_phy *phy, u8 tx_rate_mode)
  		    IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991)
  			return IEEE80211_MAX_MPDU_LEN_VHT_7991;
  		return IEEE80211_MAX_MPDU_LEN_VHT_11454;
@@ -1469,7 +1521,7 @@
  	case MT76_TM_TX_MODE_CCK:
  	case MT76_TM_TX_MODE_OFDM:
  	default:
-@@ -182,6 +188,9 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
+@@ -183,6 +190,9 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
  	u8 max_nss = hweight8(phy->antenna_mask);
  	int ret;
  
@@ -1479,7 +1531,7 @@
  	ret = mt76_testmode_alloc_skb(phy, td->tx_mpdu_len);
  	if (ret)
  		return ret;
-@@ -274,7 +283,9 @@ mt76_testmode_tx_start(struct mt76_phy *phy)
+@@ -275,7 +285,9 @@ mt76_testmode_tx_start(struct mt76_phy *phy)
  	td->tx_queued = 0;
  	td->tx_done = 0;
  	td->tx_pending = td->tx_count;
@@ -1490,7 +1542,7 @@
  }
  
  static void
-@@ -283,6 +294,11 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
+@@ -284,6 +296,11 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
  	struct mt76_testmode_data *td = &phy->test;
  	struct mt76_dev *dev = phy->dev;
  
@@ -1502,7 +1554,7 @@
  	mt76_worker_disable(&dev->tx_worker);
  
  	td->tx_pending = 0;
-@@ -295,22 +311,11 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
+@@ -296,22 +313,11 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
  	mt76_testmode_free_skb(phy);
  }
  
@@ -1526,7 +1578,7 @@
  
  	if (td->tx_mpdu_len > 0)
  		return;
-@@ -318,11 +323,18 @@ mt76_testmode_init_defaults(struct mt76_phy *phy)
+@@ -319,11 +325,18 @@ mt76_testmode_init_defaults(struct mt76_phy *phy)
  	td->tx_mpdu_len = 1024;
  	td->tx_count = 1;
  	td->tx_rate_mode = MT76_TM_TX_MODE_OFDM;
@@ -1535,20 +1587,20 @@
 +	/* 0xffff for OFDMA no puncture */
 +	td->tx_preamble_puncture = ~(td->tx_preamble_puncture & 0);
 +	td->tx_ipg = 50;
-+
-+	/* rx stat user config */
-+	td->aid = 1;
  
 -	memcpy(td->addr[0], phy->macaddr, ETH_ALEN);
 -	memcpy(td->addr[1], phy->macaddr, ETH_ALEN);
 -	memcpy(td->addr[2], phy->macaddr, ETH_ALEN);
++	/* rx stat user config */
++	td->aid = 1;
++
 +	memcpy(td->addr[0], addr, ETH_ALEN);
 +	memcpy(td->addr[1], addr, ETH_ALEN);
 +	memcpy(td->addr[2], addr, ETH_ALEN);
  }
  
  static int
-@@ -352,7 +364,7 @@ __mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state)
+@@ -353,7 +366,7 @@ __mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state)
  	if (state == MT76_TM_STATE_TX_FRAMES)
  		mt76_testmode_tx_start(phy);
  	else if (state == MT76_TM_STATE_RX_FRAMES) {
@@ -1557,7 +1609,17 @@
  	}
  
  	phy->test.state = state;
-@@ -453,7 +465,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -434,6 +447,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 
+ 	mt76_testmode_init_defaults(phy);
+ 
++	if (tb[MT76_TM_ATTR_SKU_EN])
++		td->sku_en = nla_get_u8(tb[MT76_TM_ATTR_SKU_EN]);
++
+ 	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,
  	    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],
@@ -1567,7 +1629,7 @@
  		goto out;
  
  	if (tb[MT76_TM_ATTR_TX_LENGTH]) {
-@@ -493,7 +506,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -494,7 +511,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  			    idx >= ARRAY_SIZE(td->tx_power))
  				goto out;
  
@@ -1578,7 +1640,7 @@
  		}
  	}
  
-@@ -511,6 +526,22 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -512,6 +531,22 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		}
  	}
  
@@ -1601,7 +1663,7 @@
  	if (dev->test_ops->set_params) {
  		err = dev->test_ops->set_params(phy, tb, state);
  		if (err)
-@@ -560,6 +591,9 @@ mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg)
+@@ -561,6 +596,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,
@@ -1611,19 +1673,28 @@
  			      MT76_TM_STATS_ATTR_PAD))
  		return -EMSGSIZE;
  
-@@ -624,6 +658,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -625,6 +663,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) ||
++	    nla_put_u8(msg, MT76_TM_ATTR_SKU_EN, td->sku_en) ||
 +	    nla_put_u8(msg, MT76_TM_ATTR_AID, td->aid) ||
  	    (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) &&
 diff --git a/testmode.h b/testmode.h
-index a40cd74..8d0b970 100644
+index a40cd74..141bb86 100644
 --- a/testmode.h
 +++ b/testmode.h
-@@ -39,6 +39,11 @@
+@@ -19,6 +19,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)
+  *
++ * @MT76_TM_ATTR_SKU_EN: config txpower sku is enabled or disabled in testmode (u8)
+  * @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 @@
   *
   * @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr)
   *
@@ -1635,7 +1706,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 +53,29 @@
+@@ -48,6 +54,29 @@
   * @MT76_TM_ATTR_DRV_DATA: driver specific netlink attrs (nested)
   *
   * @MT76_TM_ATTR_MAC_ADDRS: array of nested MAC addresses (nested)
@@ -1665,7 +1736,15 @@
   */
  enum mt76_testmode_attr {
  	MT76_TM_ATTR_UNSPEC,
-@@ -76,6 +104,8 @@ enum mt76_testmode_attr {
+@@ -59,6 +88,7 @@ enum mt76_testmode_attr {
+ 	MT76_TM_ATTR_MTD_OFFSET,
+ 	MT76_TM_ATTR_BAND_IDX,
+ 
++	MT76_TM_ATTR_SKU_EN,
+ 	MT76_TM_ATTR_TX_COUNT,
+ 	MT76_TM_ATTR_TX_LENGTH,
+ 	MT76_TM_ATTR_TX_RATE_MODE,
+@@ -76,6 +106,8 @@ enum mt76_testmode_attr {
  	MT76_TM_ATTR_FREQ_OFFSET,
  
  	MT76_TM_ATTR_STATS,
@@ -1674,7 +1753,7 @@
  
  	MT76_TM_ATTR_TX_SPE_IDX,
  
-@@ -86,6 +116,27 @@ enum mt76_testmode_attr {
+@@ -86,6 +118,27 @@ enum mt76_testmode_attr {
  	MT76_TM_ATTR_DRV_DATA,
  
  	MT76_TM_ATTR_MAC_ADDRS,
@@ -1702,7 +1781,7 @@
  
  	/* keep last */
  	NUM_MT76_TM_ATTRS,
-@@ -103,6 +154,8 @@ enum mt76_testmode_attr {
+@@ -103,6 +156,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
@@ -1711,7 +1790,7 @@
   */
  enum mt76_testmode_stats_attr {
  	MT76_TM_STATS_ATTR_UNSPEC,
-@@ -115,6 +168,7 @@ enum mt76_testmode_stats_attr {
+@@ -115,6 +170,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,
@@ -1719,7 +1798,23 @@
  
  	/* keep last */
  	NUM_MT76_TM_STATS_ATTRS,
-@@ -179,6 +233,9 @@ enum mt76_testmode_state {
+@@ -127,6 +183,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)
++ * @MT76_TM_RX_ATTR_RSSI: received signal strength indicator (array, s8)
+  * @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 {
+ 
+ 	MT76_TM_RX_ATTR_FREQ_OFFSET,
+ 	MT76_TM_RX_ATTR_RCPI,
++	MT76_TM_RX_ATTR_RSSI,
+ 	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 {
   * @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
@@ -1729,7 +1824,7 @@
   */
  enum mt76_testmode_tx_mode {
  	MT76_TM_TX_MODE_CCK,
-@@ -189,6 +246,9 @@ enum mt76_testmode_tx_mode {
+@@ -189,6 +250,9 @@ enum mt76_testmode_tx_mode {
  	MT76_TM_TX_MODE_HE_EXT_SU,
  	MT76_TM_TX_MODE_HE_TB,
  	MT76_TM_TX_MODE_HE_MU,
@@ -1740,7 +1835,7 @@
  	/* keep last */
  	NUM_MT76_TM_TX_MODES,
 diff --git a/tools/fields.c b/tools/fields.c
-index e3f6908..e5cf7c5 100644
+index e3f6908..055f90f 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -10,6 +10,7 @@ static const char * const testmode_state[] = {
@@ -1761,6 +1856,30 @@
  };
  
  static void print_enum(const struct tm_field *field, struct nlattr *attr)
+@@ -65,7 +69,7 @@ static bool parse_u8(const struct tm_field *field, int idx,
+ 
+ static void print_u8(const struct tm_field *field, struct nlattr *attr)
+ {
+-	printf("%d", nla_get_u8(attr));
++	printf("%u", nla_get_u8(attr));
+ }
+ 
+ static void print_s8(const struct tm_field *field, struct nlattr *attr)
+@@ -86,12 +90,12 @@ static void print_s32(const struct tm_field *field, struct nlattr *attr)
+ 
+ static void print_u32(const struct tm_field *field, struct nlattr *attr)
+ {
+-	printf("%d", nla_get_u32(attr));
++	printf("%u", nla_get_u32(attr));
+ }
+ 
+ static void print_u64(const struct tm_field *field, struct nlattr *attr)
+ {
+-	printf("%lld", (unsigned long long)nla_get_u64(attr));
++	printf("%llu", (unsigned long long)nla_get_u64(attr));
+ }
+ 
+ static bool parse_flag(const struct tm_field *field, int idx,
 @@ -201,6 +205,62 @@ static void print_extra_stats(const struct tm_field *field, struct nlattr **tb)
  	printf("%srx_per=%.02f%%\n", prefix, 100 * failed / total);
  }
@@ -1824,7 +1943,7 @@
  
  #define FIELD_GENERIC(_field, _name, ...)	\
  	[FIELD_NAME(_field)] = {			\
-@@ -250,6 +310,13 @@ static void print_extra_stats(const struct tm_field *field, struct nlattr **tb)
+@@ -250,10 +310,18 @@ static void print_extra_stats(const struct tm_field *field, struct nlattr **tb)
  		 ##__VA_ARGS__				\
  	)
  
@@ -1838,7 +1957,20 @@
  #define FIELD_NAME(_field) MT76_TM_RX_ATTR_##_field
  static const struct tm_field rx_fields[NUM_MT76_TM_RX_ATTRS] = {
  	FIELD_RO(s32, FREQ_OFFSET, "freq_offset"),
-@@ -274,6 +341,7 @@ static const struct tm_field stats_fields[NUM_MT76_TM_STATS_ATTRS] = {
+ 	FIELD_ARRAY_RO(u8, RCPI, "rcpi"),
++	FIELD_ARRAY_RO(s8, RSSI, "rssi"),
+ 	FIELD_ARRAY_RO(s8, IB_RSSI, "ib_rssi"),
+ 	FIELD_ARRAY_RO(s8, WB_RSSI, "wb_rssi"),
+ 	FIELD_RO(s8, SNR, "snr"),
+@@ -261,6 +329,7 @@ static const struct tm_field rx_fields[NUM_MT76_TM_RX_ATTRS] = {
+ static struct nla_policy rx_policy[NUM_MT76_TM_RX_ATTRS] = {
+ 	[MT76_TM_RX_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
+ 	[MT76_TM_RX_ATTR_RCPI] = { .type = NLA_NESTED },
++	[MT76_TM_RX_ATTR_RSSI] = { .type = NLA_NESTED },
+ 	[MT76_TM_RX_ATTR_IB_RSSI] = { .type = NLA_NESTED },
+ 	[MT76_TM_RX_ATTR_WB_RSSI] = { .type = NLA_NESTED },
+ 	[MT76_TM_RX_ATTR_SNR] = { .type = NLA_U8 },
+@@ -274,6 +343,7 @@ static const struct tm_field stats_fields[NUM_MT76_TM_STATS_ATTRS] = {
  	FIELD_RO(u32, TX_DONE, "tx_done"),
  	FIELD_RO(u64, RX_PACKETS, "rx_packets"),
  	FIELD_RO(u64, RX_FCS_ERROR, "rx_fcs_error"),
@@ -1846,7 +1978,7 @@
  	FIELD_NESTED_RO(LAST_RX, rx, "last_"),
  };
  static struct nla_policy stats_policy[NUM_MT76_TM_STATS_ATTRS] = {
-@@ -282,6 +350,7 @@ static struct nla_policy stats_policy[NUM_MT76_TM_STATS_ATTRS] = {
+@@ -282,6 +352,7 @@ static struct nla_policy stats_policy[NUM_MT76_TM_STATS_ATTRS] = {
  	[MT76_TM_STATS_ATTR_TX_DONE] = { .type = NLA_U32 },
  	[MT76_TM_STATS_ATTR_RX_PACKETS] = { .type = NLA_U64 },
  	[MT76_TM_STATS_ATTR_RX_FCS_ERROR] = { .type = NLA_U64 },
@@ -1854,7 +1986,15 @@
  };
  #undef FIELD_NAME
  
-@@ -300,12 +369,20 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+@@ -291,6 +362,7 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+ 	FIELD_ENUM(STATE, "state", testmode_state),
+ 	FIELD_RO(string, MTD_PART, "mtd_part"),
+ 	FIELD_RO(u32, MTD_OFFSET, "mtd_offset"),
++	FIELD(u8, SKU_EN, "sku_en"),
+ 	FIELD(u32, TX_COUNT, "tx_count"),
+ 	FIELD(u32, TX_LENGTH, "tx_length"),
+ 	FIELD_ENUM(TX_RATE_MODE, "tx_rate_mode", testmode_tx_mode),
+@@ -300,12 +372,20 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
  	FIELD(u8, TX_RATE_LDPC, "tx_rate_ldpc"),
  	FIELD(u8, TX_RATE_STBC, "tx_rate_stbc"),
  	FIELD(u8, TX_LTF, "tx_ltf"),
@@ -1875,7 +2015,15 @@
  };
  #undef FIELD_NAME
  
-@@ -322,10 +399,25 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
+@@ -313,6 +393,7 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
+ 	[MT76_TM_ATTR_STATE] = { .type = NLA_U8 },
+ 	[MT76_TM_ATTR_MTD_PART] = { .type = NLA_STRING },
+ 	[MT76_TM_ATTR_MTD_OFFSET] = { .type = NLA_U32 },
++	[MT76_TM_ATTR_SKU_EN] = { .type = NLA_U8 },
+ 	[MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 },
+ 	[MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 },
+ 	[MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 },
+@@ -322,10 +403,25 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
  	[MT76_TM_ATTR_TX_RATE_LDPC] = { .type = NLA_U8 },
  	[MT76_TM_ATTR_TX_RATE_STBC] = { .type = NLA_U8 },
  	[MT76_TM_ATTR_TX_LTF] = { .type = NLA_U8 },
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/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch
new file mode 100644
index 0000000..dbef00c
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch
@@ -0,0 +1,111 @@
+From 10df4848e7a7116529e1f596e06d0d03891f502e 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
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c |  2 ++
+ mt7996/init.c   |  4 ++++
+ mt7996/mt7996.h | 28 ++++++++++++++++++++++++++--
+ 3 files changed, 32 insertions(+), 2 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 7fd318c..3276740 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
+ 		return MT7996_EEPROM_DEFAULT;
+ }
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 6d39c3c..fed74d0 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);
+ 
++	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) &&
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 3964035..efdcff7 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -36,6 +36,7 @@
+ #define MT7996_ROM_PATCH		"mediatek/mt7996/mt7996_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 MT7996_EEPROM_SIZE		7680
+ #define MT7996_EEPROM_BLOCK_SIZE	16
+@@ -83,6 +84,11 @@ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+ struct mt7996_dfs_pattern;
+ 
++enum mt7996_sku_type {
++	MT7996_SKU_404,
++	MT7996_SKU_444,
++};
++
+ enum mt7996_ram_type {
+ 	MT7996_RAM_TYPE_WM,
+ 	MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
+@@ -264,6 +270,8 @@ struct mt7996_dev {
+ 	struct cfg80211_chan_def rdd2_chandef;
+ 	struct mt7996_phy *rdd2_phy;
+ 
++	u8 chip_sku;
++
+ 	u16 chainmask;
+ 	u8 chainshift[__MT_MAX_BAND];
+ 	u32 hif_idx;
+@@ -417,6 +425,23 @@ 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)
+ {
+@@ -424,8 +449,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
+ 		return band <= MT_BAND1;
+ 
+ 	/* tri-band support */
+-	if (band <= MT_BAND2 &&
+-	    mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1)
++	if (band <= MT_BAND2 && dev->chip_sku)
+ 		return true;
+ 
+ 	return band == MT_BAND0 || band == MT_BAND2;
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-add-U-NII-4-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-add-U-NII-4-support.patch
deleted file mode 100644
index 8eaf2d5..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-add-U-NII-4-support.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 09b50cf201ede70688619366c31aa2ddd57d5cb2 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Fri, 31 Mar 2023 11:26:27 +0800
-Subject: [PATCH 1005/1015] wifi: mt76: mt7996: add U-NII-4 support
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mac80211.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/mac80211.c b/mac80211.c
-index d1cdaee8..501325e9 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -76,6 +76,7 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
- 	CHAN5G(165, 5825),
- 	CHAN5G(169, 5845),
- 	CHAN5G(173, 5865),
-+	CHAN5G(177, 5885),
- };
- 
- static const struct ieee80211_channel mt76_channels_6ghz[] = {
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0036-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
similarity index 85%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0036-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
index c0ce85d..78ae8ad 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0036-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
@@ -1,7 +1,7 @@
-From 18f990de206c3301d3ae72cfeef40dfb3b361fb0 Mon Sep 17 00:00:00 2001
+From b02a81b168e9c42350c1f6a9b7e38c60c76cc692 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 36/39] wifi: mt76: mt7996: enable SCS feature for mt7996
+Subject: [PATCH 38/98] wifi: mt76: mt7996: enable SCS feature for mt7996
  driver
 
 Enable Smart Carrier Sense algorithn by default to improve performance
@@ -14,35 +14,35 @@
  mt7996/main.c     |   7 +++
  mt7996/mcu.c      | 123 ++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/mcu.h      |   6 +++
- mt7996/mt7996.h   |  16 ++++++
- 6 files changed, 154 insertions(+)
+ mt7996/mt7996.h   |  15 ++++++
+ 6 files changed, 153 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 97f874b..bfec420 100644
+index 4d054bd..fae76c9 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1213,6 +1213,7 @@ enum {
- 	MCU_UNI_CMD_GET_MIB_INFO = 0x22,
+@@ -1232,6 +1232,7 @@ enum {
+ 	MCU_UNI_CMD_GET_STAT_INFO = 0x23,
  	MCU_UNI_CMD_SNIFFER = 0x24,
  	MCU_UNI_CMD_SR = 0x25,
 +	MCU_UNI_CMD_SCS = 0x26,
  	MCU_UNI_CMD_ROC = 0x27,
+ 	MCU_UNI_CMD_SET_DBDC_PARMS = 0x28,
  	MCU_UNI_CMD_TXPOWER = 0x2b,
- 	MCU_UNI_CMD_EFUSE_CTRL = 0x2d,
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 0825e0b..1072874 100644
+index fed74d0..f393e04 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -1058,6 +1058,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1211,6 +1211,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);
 +	INIT_DELAYED_WORK(&dev->scs_work, mt7996_mcu_scs_sta_poll);
  	INIT_LIST_HEAD(&dev->sta_rc_list);
- 	INIT_LIST_HEAD(&dev->sta_poll_list);
  	INIT_LIST_HEAD(&dev->twt_list);
+ 
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 520f250..20b89a7 100644
+index 226235c..6fa4a65 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -73,11 +73,17 @@ int mt7996_run(struct ieee80211_hw *hw)
@@ -72,10 +72,10 @@
  	mutex_lock(&dev->mt76.mutex);
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 9fb800a..a5c473a 100644
+index 141b838..6cedc39 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -4190,3 +4190,126 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+@@ -4346,3 +4346,126 @@ 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);
  }
@@ -203,11 +203,11 @@
 +				 &req, sizeof(req), false);
 +}
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index eed7371..eb63441 100644
+index 16ffc3d..ff9cc9c 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -757,6 +757,12 @@ enum {
- 	MT7996_SEC_MODE_MAX,
+@@ -875,6 +875,12 @@ enum {
+ 	UNI_CMD_PP_EN_CTRL,
  };
  
 +enum {
@@ -220,14 +220,13 @@
  #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 488f59c..f78f1fd 100644
+index efdcff7..eb48dbd 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -222,6 +222,17 @@ struct mt7996_hif {
+@@ -193,6 +193,16 @@ struct mt7996_hif {
  	int irq;
  };
  
-+
 +struct mt7996_scs_ctrl {
 +	u8 scs_enable;
 +	s8 sta_min_rssi;
@@ -238,10 +237,10 @@
 +	SCS_ENABLE,
 +};
 +
- struct mt7996_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7996_dev *dev;
-@@ -253,6 +264,8 @@ struct mt7996_phy {
+ struct mt7996_wed_rro_addr {
+ 	u32 head_low;
+ 	u32 head_high : 4;
+@@ -235,6 +245,8 @@ struct mt7996_phy {
  
  	bool has_aux_rx;
  
@@ -250,7 +249,7 @@
  #ifdef CONFIG_NL80211_TESTMODE
  	struct {
  		u32 *reg_backup;
-@@ -295,6 +308,7 @@ struct mt7996_dev {
+@@ -280,6 +292,7 @@ struct mt7996_dev {
  	struct work_struct rc_work;
  	struct work_struct dump_work;
  	struct work_struct reset_work;
@@ -258,9 +257,9 @@
  	wait_queue_head_t reset_wait;
  	struct {
  		u32 state;
-@@ -535,6 +549,8 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
- void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+@@ -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);
 +int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
 +void mt7996_mcu_scs_sta_poll(struct work_struct *work);
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-txpower-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-mt7996-add-txpower-support.patch
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-txpower-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-mt7996-add-txpower-support.patch
index 75fa826..0a0d376 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-txpower-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-mt7996-add-txpower-support.patch
@@ -1,7 +1,7 @@
-From b729a28ee5895d921e8df1a371e114dee7724595 Mon Sep 17 00:00:00 2001
+From 1c1dd57bde8919fdf04ef914b781eb6183582562 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 1001/1015] wifi: mt76: mt7996: add txpower support
+Subject: [PATCH 39/98] wifi: mt76: mt7996: add txpower support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Change-Id: Ic3e7b17f3664fa7f774137572f885359fa2ec93b
@@ -13,14 +13,14 @@
  mt7996/mtk_debugfs.c | 229 +++++++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.c     |  23 +++++
  mt7996/mtk_mcu.h     |  78 +++++++++++++++
- mt7996/regs.h        |  17 +++-
- 8 files changed, 423 insertions(+), 5 deletions(-)
+ mt7996/regs.h        |  29 +++---
+ 8 files changed, 429 insertions(+), 11 deletions(-)
 
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index b81ed64c..be0a34ae 100644
+index 3276740..e4c4b86 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -293,3 +293,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
+@@ -296,3 +296,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
  
  	return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
  }
@@ -59,7 +59,7 @@
 +	[SKU_EHT3x996_484] = 16,
 +};
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 9ea3667f..343e65e1 100644
+index 9ea3667..343e65e 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -75,4 +75,46 @@ mt7996_get_channel_group_6g(int channel)
@@ -110,10 +110,10 @@
 +
  #endif
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 549007f9..5d52b0b7 100644
+index ff9cc9c..71dc165 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -712,6 +712,7 @@ struct tx_power_ctrl {
+@@ -826,6 +826,7 @@ struct tx_power_ctrl {
  		bool ate_mode_enable;
  		bool percentage_ctrl_enable;
  		bool bf_backoff_enable;
@@ -121,7 +121,7 @@
  		u8 power_drop_level;
  	};
  	u8 band_idx;
-@@ -725,6 +726,7 @@ enum {
+@@ -839,6 +840,7 @@ enum {
  	UNI_TXPOWER_BACKOFF_POWER_LIMIT_CTRL = 3,
  	UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4,
  	UNI_TXPOWER_ATE_MODE_CTRL = 6,
@@ -130,31 +130,31 @@
  
  enum {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 6c76ec20..085307ab 100644
+index eb48dbd..23d1614 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -60,6 +60,8 @@
+@@ -63,6 +63,8 @@
  
  #define MT7996_BUILD_TIME_LEN		24
  
 +#define MT7996_SKU_RATE_NUM		417
 +
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -563,6 +565,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
- void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #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);
 +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 f04c300f..2aee3ab0 100644
+index 5aa5c94..57fcbab 100644
 --- a/mt7996/mtk_debugfs.c
 +++ b/mt7996/mtk_debugfs.c
-@@ -2299,6 +2299,232 @@ static int mt7996_sta_info(struct seq_file *s, void *data)
+@@ -2325,6 +2325,232 @@ static int mt7996_sta_info(struct seq_file *s, void *data)
  	return 0;
  }
  
@@ -387,7 +387,7 @@
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
  {
  	struct mt7996_dev *dev = phy->dev;
-@@ -2341,6 +2567,9 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+@@ -2367,6 +2593,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,7 +398,7 @@
  	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 e8870166..f772243b 100644
+index e887016..f772243 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
 @@ -12,7 +12,30 @@
@@ -433,7 +433,7 @@
  
  #endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
-index e741aa27..1fa449ea 100644
+index e741aa2..beb1aba 100644
 --- a/mt7996/mtk_mcu.h
 +++ b/mt7996/mtk_mcu.h
 @@ -10,6 +10,84 @@
@@ -454,22 +454,22 @@
 +
 +	/* power percentage info */
 +	bool percentage_ctrl_enable;
-+	u8 power_drop_level;
++	s8 power_drop_level;
 +
 +	/* frond-end loss TX info */
-+	u8 front_end_loss_tx[4];
++	s8 front_end_loss_tx[4];
 +
 +	/* frond-end loss RX info */
-+	u8 front_end_loss_rx[4];
++	s8 front_end_loss_rx[4];
 +
 +	/* thermal info */
 +	bool thermal_compensate_enable;
-+	u8 thermal_compensate_value;
++	s8 thermal_compensate_value;
 +	u8 rsv2;
 +
 +	/* TX power max/min limit info */
-+	u8 max_power_bound;
-+	u8 min_power_bound;
++	s8 max_power_bound;
++	s8 min_power_bound;
 +
 +	/* power limit info */
 +	bool sku_enable;
@@ -477,8 +477,8 @@
 +
 +	/* MU TX power info */
 +	bool mu_tx_power_manual_enable;
-+	u8 mu_tx_power_auto;
-+	u8 mu_tx_power_manual;
++	s8 mu_tx_power_auto;
++	s8 mu_tx_power_manual;
 +	u8 rsv3;
 +};
 +
@@ -522,12 +522,12 @@
  #endif
  
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 3a5914c4..6ef905a9 100644
+index de5df91..565022a 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -562,15 +562,22 @@ enum base_rev {
- 
- #define MT_PCIE1_MAC_INT_ENABLE			MT_PCIE1_MAC(0x188)
+@@ -672,24 +672,31 @@ enum offs_rev {
+ 						 ((_wf) << 16) + (ofs))
+ #define MT_WF_PHYRX_CSD_IRPI(_band, _wf)	MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
  
 -/* PHYRX CTRL */
 -#define MT_WF_PHYRX_BAND_BASE			0x83080000
@@ -537,6 +537,19 @@
 +#define MT_WF_PHY_BAND(_band, ofs)		(MT_WF_PHY_BAND_BASE + \
  						 ((_band) << 20) + (ofs))
  
+-#define MT_WF_PHYRX_BAND_GID_TAB_VLD0(_band)	MT_WF_PHYRX_BAND(_band, 0x1054)
+-#define MT_WF_PHYRX_BAND_GID_TAB_VLD1(_band)	MT_WF_PHYRX_BAND(_band, 0x1058)
+-#define MT_WF_PHYRX_BAND_GID_TAB_POS0(_band)	MT_WF_PHYRX_BAND(_band, 0x105c)
+-#define MT_WF_PHYRX_BAND_GID_TAB_POS1(_band)	MT_WF_PHYRX_BAND(_band, 0x1060)
+-#define MT_WF_PHYRX_BAND_GID_TAB_POS2(_band)	MT_WF_PHYRX_BAND(_band, 0x1064)
+-#define MT_WF_PHYRX_BAND_GID_TAB_POS3(_band)	MT_WF_PHYRX_BAND(_band, 0x1068)
++#define MT_WF_PHYRX_BAND_GID_TAB_VLD0(_band)	MT_WF_PHY_BAND(_band, 0x1054)
++#define MT_WF_PHYRX_BAND_GID_TAB_VLD1(_band)	MT_WF_PHY_BAND(_band, 0x1058)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS0(_band)	MT_WF_PHY_BAND(_band, 0x105c)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS1(_band)	MT_WF_PHY_BAND(_band, 0x1060)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS2(_band)	MT_WF_PHY_BAND(_band, 0x1064)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS3(_band)	MT_WF_PHY_BAND(_band, 0x1068)
+ 
 -#define MT_WF_PHYRX_BAND_RX_CTRL1(_band)	MT_WF_PHYRX_BAND(_band, 0x2004)
 +/* PHYRX CTRL */
 +#define MT_WF_PHYRX_BAND_RX_CTRL1(_band)	MT_WF_PHY_BAND(_band, 0x2004)
@@ -549,12 +562,6 @@
 +#define MT_WF_PHY_TPC_POWER_RMAC		GENMASK(23, 16)
 +#define MT_WF_PHY_TPC_POWER_TSSI		GENMASK(31, 24)
 +
- /* PHYRX CSD */
- #define MT_WF_PHYRX_CSD_BASE			0x83000000
- #define MT_WF_PHYRX_CSD(_band, _wf, ofs)	(MT_WF_PHYRX_CSD_BASE + \
-@@ -579,7 +586,7 @@ enum base_rev {
- #define MT_WF_PHYRX_CSD_IRPI(_band, _wf)	MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
- 
  /* PHYRX CSD BAND */
 -#define MT_WF_PHYRX_CSD_BAND_RXTD12(_band)		MT_WF_PHYRX_BAND(_band, 0x8230)
 +#define MT_WF_PHYRX_CSD_BAND_RXTD12(_band)		MT_WF_PHY_BAND(_band, 0x8230)
@@ -562,5 +569,5 @@
  #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR		BIT(29)
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-mt7996-add-mu-vendor-command-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
similarity index 85%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
index fe75034..38754fa 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
@@ -1,23 +1,23 @@
-From 55619fa44187b6ed841f94c2bedbc4779457e3f9 Mon Sep 17 00:00:00 2001
+From 6c7addb48070af33da842ede744264149f2a9110 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 1002/1015] wifi: mt76: mt7996: add mu vendor command support
+Subject: [PATCH 40/98] wifi: mt76: mt7996: add mu vendor command support
 
 Change-Id: I4599bd97917651aaea51d7ff186ffff73a07e4ce
 ---
  mt7996/Makefile |  3 +-
  mt7996/init.c   |  8 +++++
- mt7996/mcu.c    | 37 +++++++++++++++++++---
+ mt7996/mcu.c    | 37 ++++++++++++++++++---
  mt7996/mcu.h    | 12 +++++++
- mt7996/mt7996.h |  7 +++++
- mt7996/vendor.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mt7996.h |  6 ++++
+ mt7996/vendor.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/vendor.h | 22 +++++++++++++
  7 files changed, 167 insertions(+), 6 deletions(-)
  create mode 100644 mt7996/vendor.c
  create mode 100644 mt7996/vendor.h
 
 diff --git a/mt7996/Makefile b/mt7996/Makefile
-index df131869..8dbbc34c 100644
+index 7bb17f4..6643c7a 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
 @@ -1,11 +1,12 @@
@@ -33,12 +33,12 @@
 +	     debugfs.o mmio.o vendor.o
  
  mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
- 
+ mt7996e-$(CONFIG_NL80211_TESTMODE) += testmode.o
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 96c4bb01..1d4359f0 100644
+index f393e04..1f4e84d 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -579,6 +579,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+@@ -597,6 +597,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
  	if (ret)
  		goto error;
  
@@ -49,7 +49,7 @@
  	ret = mt76_register_phy(mphy, true, mt76_rates,
  				ARRAY_SIZE(mt76_rates));
  	if (ret)
-@@ -1082,6 +1086,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1230,6 +1234,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	dev->mt76.test_ops = &mt7996_testmode_ops;
  #endif
  
@@ -61,10 +61,10 @@
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 58893348..91f3103a 100644
+index 6cedc39..a008c08 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1158,6 +1158,8 @@ static void
+@@ -1266,6 +1266,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 +73,7 @@
  	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
  	struct sta_rec_muru *muru;
  	struct tlv *tlv;
-@@ -1169,11 +1171,14 @@ mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+@@ -1277,11 +1279,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 +93,7 @@
  
  	if (sta->deflink.vht_cap.vht_supported)
  		muru->mimo_dl.vht_mu_bfee =
-@@ -4353,3 +4358,25 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
+@@ -4469,3 +4474,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 +120,10 @@
 +}
 +#endif
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 5d52b0b7..baffbcd7 100644
+index 71dc165..c5c0a44 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -568,8 +568,20 @@ enum {
+@@ -683,8 +683,20 @@ enum {
  	RATE_PARAM_FIXED_MCS,
  	RATE_PARAM_FIXED_GI = 11,
  	RATE_PARAM_AUTO = 20,
@@ -145,21 +145,20 @@
  	BF_SOUNDING_ON = 1,
  	BF_HW_EN_UPDATE = 17,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 085307ab..b9f3dd8e 100644
+index 23d1614..013122f 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -263,6 +263,8 @@ struct mt7996_phy {
- 	u32 rx_ampdu_ts;
- 	u32 ampdu_ref;
+@@ -249,6 +249,7 @@ struct mt7996_phy {
  
-+	u8 muru_onoff;
-+
- 	struct mib_stats mib;
- 	struct mt76_channel_state state_ts;
+ 	struct mt7996_scs_ctrl scs_ctrl;
  
-@@ -672,6 +674,11 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			    struct ieee80211_sta *sta, struct dentry *dir);
- #endif
++	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,
+ 			 bool hif2, int *irq);
+ 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);
@@ -171,10 +170,10 @@
  #endif
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
 new file mode 100644
-index 00000000..08ecc2b3
+index 0000000..b5ecbdf
 --- /dev/null
 +++ b/mt7996/vendor.c
-@@ -0,0 +1,84 @@
+@@ -0,0 +1,85 @@
 +// SPDX-License-Identifier: ISC
 +/*
 + * Copyright (C) 2020, MediaTek Inc. All rights reserved.
@@ -185,6 +184,7 @@
 +#include "mt7996.h"
 +#include "mcu.h"
 +#include "vendor.h"
++#include "mtk_mcu.h"
 +
 +static const struct nla_policy
 +mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
@@ -261,7 +261,7 @@
 +}
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
 new file mode 100644
-index 00000000..8ac3ba8e
+index 0000000..8ac3ba8
 --- /dev/null
 +++ b/mt7996/vendor.h
 @@ -0,0 +1,22 @@
@@ -288,5 +288,5 @@
 +
 +#endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-mt7996-Add-air-monitor-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch
similarity index 93%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-mt7996-Add-air-monitor-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch
index d83c3f9..45f1585 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-mt7996-Add-air-monitor-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch
@@ -1,7 +1,7 @@
-From 2637da59e92d101889cf3680e57f0594c6b349ec Mon Sep 17 00:00:00 2001
+From 98127145e2f401f65029185adab6dfcb0e90dbd9 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 1003/1015] wifi: mt76: mt7996: Add air monitor support
+Subject: [PATCH 41/98] 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 4bb9508a..e62f17ad 100644
+index fae76c9..bbf600b 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1206,6 +1206,7 @@ enum {
+@@ -1222,6 +1222,7 @@ enum {
  	MCU_UNI_CMD_REG_ACCESS = 0x0d,
  	MCU_UNI_CMD_CHIP_CONFIG = 0x0e,
  	MCU_UNI_CMD_POWER_CTRL = 0x0f,
@@ -25,10 +25,10 @@
  	MCU_UNI_CMD_SER = 0x13,
  	MCU_UNI_CMD_TWT = 0x14,
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 05269e7f..3dc5cdae 100644
+index 637f0f6..ee17d59 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -865,6 +865,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -679,6 +679,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
  			if (ieee80211_has_a4(fc) && is_mesh && status->amsdu)
  				*qos &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
  		}
@@ -38,12 +38,12 @@
 +#endif
  	} else {
  		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 2ed66e6c..e5627c96 100644
+index 6fa4a65..804c0c1 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -672,6 +672,10 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -696,6 +696,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,10 +55,10 @@
  	if (ret)
  		return ret;
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index b9f3dd8e..dc44edc1 100644
+index 013122f..3c535be 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -235,6 +235,34 @@ enum {
+@@ -205,6 +205,34 @@ enum {
  	SCS_ENABLE,
  };
  
@@ -90,10 +90,10 @@
 +};
 +#endif
 +
- struct mt7996_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7996_dev *dev;
-@@ -285,6 +313,10 @@ struct mt7996_phy {
+ struct mt7996_wed_rro_addr {
+ 	u32 head_low;
+ 	u32 head_high : 4;
+@@ -264,6 +292,10 @@ struct mt7996_phy {
  		u8 spe_idx;
  	} test;
  #endif
@@ -104,7 +104,7 @@
  };
  
  struct mt7996_dev {
-@@ -677,6 +709,9 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -687,6 +719,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,10 +115,10 @@
  
  #ifdef CONFIG_MTK_DEBUG
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index 08ecc2b3..8a021324 100644
+index b5ecbdf..f3b089d 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
-@@ -15,6 +15,32 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
+@@ -16,6 +16,32 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
  	[MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 },
  };
  
@@ -151,7 +151,7 @@
  static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
  				 struct wireless_dev *wdev,
  				 const void *data,
-@@ -62,6 +88,328 @@ mt7996_vendor_mu_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -63,6 +89,328 @@ mt7996_vendor_mu_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
  	return len;
  }
  
@@ -480,7 +480,7 @@
  static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
  	{
  		.info = {
-@@ -75,10 +423,24 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+@@ -76,10 +424,24 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
  		.policy = mu_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX,
  	},
@@ -506,7 +506,7 @@
 +	spin_lock_init(&phy->amnt_lock);
  }
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index 8ac3ba8e..2078cafa 100644
+index 8ac3ba8..2078caf 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -4,6 +4,7 @@
@@ -561,5 +561,5 @@
 +
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-Beacon-protection-feature-added.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
deleted file mode 100644
index 7ddc56f..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
+++ /dev/null
@@ -1,220 +0,0 @@
-From b99c942620576c63baffd687090febea5ab2973d Mon Sep 17 00:00:00 2001
-From: mtk23510 <rudra.shahi@mediatek.com>
-Date: Wed, 26 Apr 2023 20:08:10 +0800
-Subject: [PATCH 1009/1015] wifi: mt76: mt7996: Beacon protection feature added
-
-Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
-Change-Id: I0149a65f71d844fc395c2827a54f9360492d181e
----
- mt76_connac_mcu.h | 16 +++++++++
- mt7996/main.c     |  4 +++
- mt7996/mcu.c      | 86 +++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      | 11 ++++++
- mt7996/mt7996.h   |  2 ++
- 5 files changed, 119 insertions(+)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 42246fb9..a53fa138 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -415,6 +415,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;
-@@ -767,6 +775,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)
- 
-@@ -796,6 +805,7 @@ enum {
- 	STA_REC_HE_6G = 0x17,
- 	STA_REC_HE_V2 = 0x19,
- 	STA_REC_EHT = 0x22,
-+	STA_REC_PN_INFO = 0x26,
- 	STA_REC_HDRT = 0x28,
- 	STA_REC_HDR_TRANS = 0x2B,
- 	STA_REC_MAX_NUM
-@@ -1077,6 +1087,11 @@ 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,
- };
- 
- enum {
-@@ -1295,6 +1310,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,
-diff --git a/mt7996/main.c b/mt7996/main.c
-index d40d3047..d3d10fab 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -400,6 +400,10 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- 	}
- 
- 	mt76_wcid_key_setup(&dev->mt76, wcid, key);
-+
-+	if (key->keyidx == 6 || key->keyidx == 7)
-+		mt7996_mcu_bcn_prot_enable(dev, vif, key);
-+
- 	err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip,
- 				 key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
- 				 &msta->wcid, cmd);
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 6add77da..53d2fc73 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2133,6 +2133,92 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
- 	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)
-+{
-+#define WPA_BIGTK_MAX_LEN 32
-+	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 = 1;
-+	memcpy(bcn_prot->key, key->key, WPA_BIGTK_MAX_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 baffbcd7..f32ac153 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -262,6 +262,17 @@ struct bss_rate_tlv {
- 	u8 __rsv2[9];
- } __packed;
- 
-+struct mt7996_mcu_bcn_prot_tlv {
-+	__le16 tag;
-+	__le16 len;
-+	u8 pn[6];
-+	u8 enable;
-+	u8 cipher_id;
-+	u8 key[32];
-+	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 c16bc8b4..94b62211 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -710,6 +710,8 @@ 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.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
similarity index 64%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
index 50db576..672885d 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
@@ -1,8 +1,8 @@
-From 75b684d04d569b5e83780d2296bed12d3785836c Mon Sep 17 00:00:00 2001
+From 786bd792b2a62dee5e4aca8aa09ed01be1731ec4 Mon Sep 17 00:00:00 2001
 From: mtk23510 <rudra.shahi@mediatek.com>
 Date: Fri, 24 Mar 2023 19:18:53 +0800
-Subject: [PATCH 1004/1015] wifi: mt76: mt7996: add driver support for wpa3 ocv
- and bp mt76
+Subject: [PATCH 42/98] wifi: mt76: mt7996: add driver support for wpa3 ocv and
+ bp mt76
 
 Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
 ---
@@ -10,12 +10,12 @@
  1 file changed, 2 insertions(+)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 1d4359f0..40d610ae 100644
+index 1f4e84d..5940e41 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -373,6 +373,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
- 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
+@@ -377,6 +377,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);
  
 +	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION);
 +	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION);
@@ -23,5 +23,5 @@
  	    !of_property_read_bool(mdev->dev->of_node,
  				   "mediatek,disable-radar-background"))
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
index e185c11..1185d02 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
@@ -1,7 +1,7 @@
-From 47c64d6cac5ed78fab15cd4173ae8935605a3fca Mon Sep 17 00:00:00 2001
+From db3b9fa4bc9c70231b7237dee2f7bcf35c6135f2 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 1006/1015] wifi: mt76: testmode: add testmode pre-calibration
+Subject: [PATCH 43/98] wifi: mt76: testmode: add testmode pre-calibration
  support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -22,7 +22,7 @@
  12 files changed, 632 insertions(+), 23 deletions(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index 501325e9..6430e6ee 100644
+index f10ca90..9c582cb 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -7,27 +7,6 @@
@@ -54,7 +54,7 @@
  	CHAN2G(1, 2412),
  	CHAN2G(2, 2417),
 diff --git a/mt76.h b/mt76.h
-index 31d5dc37..3341720c 100644
+index feb861c..fc69d3e 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -18,6 +18,27 @@
@@ -85,7 +85,7 @@
  #define MT_MCU_RING_SIZE	32
  #define MT_RX_BUF_SIZE		2048
  #define MT_SKB_HEAD_LEN		256
-@@ -654,6 +675,7 @@ struct mt76_testmode_ops {
+@@ -694,6 +715,7 @@ struct mt76_testmode_ops {
  	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);
@@ -94,20 +94,22 @@
  
  #define MT_TM_FW_RX_COUNT	BIT(0)
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index e62f17ad..262abf88 100644
+index bbf600b..d65ecf0 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1011,6 +1011,8 @@ enum {
- 	MCU_UNI_EVENT_IE_COUNTDOWN = 0x09,
+@@ -1023,8 +1023,10 @@ enum {
  	MCU_UNI_EVENT_RDD_REPORT = 0x11,
- 	MCU_UNI_EVENT_THERMAL = 0x35,
+ 	MCU_UNI_EVENT_ROC = 0x27,
+ 	MCU_UNI_EVENT_TX_DONE = 0x2d,
 +	MCU_UNI_EVENT_BF = 0x33,
+ 	MCU_UNI_EVENT_THERMAL = 0x35,
+ 	MCU_UNI_EVENT_NIC_CAPAB = 0x43,
 +	MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
+ 	MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
+ 	MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
  };
- 
- #define MCU_UNI_CMD_EVENT			BIT(1)
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index be0a34ae..60e98463 100644
+index e4c4b86..b88fd64 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -12,6 +12,42 @@ static bool testmode_enable;
@@ -153,7 +155,7 @@
  static int mt7996_check_eeprom(struct mt7996_dev *dev)
  {
  	u8 *eeprom = dev->mt76.eeprom.data;
-@@ -34,6 +70,36 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
+@@ -36,6 +72,36 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
  		return MT7996_EEPROM_DEFAULT;
  }
  
@@ -191,7 +193,7 @@
  mt7996_eeprom_load_default(struct mt7996_dev *dev)
  {
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 343e65e1..7ff290f4 100644
+index 343e65e..7ff290f 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -14,6 +14,7 @@ enum mt7996_eeprom_field {
@@ -256,12 +258,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 91f3103a..1fb7bae1 100644
+index a008c08..d6f4e22 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -523,6 +523,11 @@ 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);
+@@ -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);
  		break;
 +#ifdef CONFIG_NL80211_TESTMODE
 +	case MCU_UNI_EVENT_TESTMODE_CTRL:
@@ -272,10 +274,10 @@
  		break;
  	}
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index dc44edc1..9ab86eaf 100644
+index 3c535be..684c254 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -390,6 +390,9 @@ struct mt7996_dev {
+@@ -385,6 +385,9 @@ struct mt7996_dev {
  	struct dentry *debugfs_dir;
  	struct rchan *relay_fwlog;
  
@@ -285,7 +287,7 @@
  	struct {
  		u8 table_mask;
  		u8 n_agrt;
-@@ -522,6 +525,7 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
+@@ -521,6 +524,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);
@@ -293,7 +295,7 @@
  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);
-@@ -602,6 +606,9 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+@@ -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);
@@ -304,7 +306,7 @@
  static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
  {
 diff --git a/mt7996/testmode.c b/mt7996/testmode.c
-index 43eca4ef..7d36902e 100644
+index fb041c3..8ceea00 100644
 --- a/mt7996/testmode.c
 +++ b/mt7996/testmode.c
 @@ -7,6 +7,8 @@
@@ -316,7 +318,7 @@
  
  enum {
  	TM_CHANGED_TXPOWER,
-@@ -397,6 +399,436 @@ mt7996_tm_set_tx_cont(struct mt7996_phy *phy, bool en)
+@@ -396,6 +398,436 @@ mt7996_tm_set_tx_cont(struct mt7996_phy *phy, bool en)
  	}
  }
  
@@ -753,7 +755,7 @@
  static void
  mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
  {
-@@ -447,6 +879,10 @@ mt7996_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -452,6 +884,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));
@@ -764,14 +766,14 @@
  
  	if ((state == MT76_TM_STATE_IDLE &&
  	     prev_state == MT76_TM_STATE_OFF) ||
-@@ -655,4 +1091,5 @@ const struct mt76_testmode_ops mt7996_testmode_ops = {
+@@ -671,4 +1107,5 @@ const struct mt76_testmode_ops mt7996_testmode_ops = {
  	.dump_stats = mt7996_tm_dump_stats,
  	.reset_rx_stats = mt7996_tm_reset_trx_stats,
  	.tx_stop = mt7996_tm_tx_stop,
 +	.dump_precal = mt7996_tm_dump_precal,
  };
 diff --git a/mt7996/testmode.h b/mt7996/testmode.h
-index f00e51f4..778c9bc6 100644
+index e4d55a6..17c1456 100644
 --- a/mt7996/testmode.h
 +++ b/mt7996/testmode.h
 @@ -34,6 +34,12 @@ enum bw_mapping_method {
@@ -833,10 +835,10 @@
  	RF_OPER_NORMAL,
  	RF_OPER_RF_TEST,
 diff --git a/testmode.c b/testmode.c
-index fc68c2af..74bb26fa 100644
+index bbe8230..e66b54a 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -626,6 +626,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -631,6 +631,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  
  	mutex_lock(&dev->mutex);
  
@@ -856,10 +858,10 @@
  		err = -EINVAL;
  
 diff --git a/testmode.h b/testmode.h
-index 8d0b9702..0c3b1393 100644
+index 141bb86..db8ff53 100644
 --- a/testmode.h
 +++ b/testmode.h
-@@ -215,6 +215,14 @@ enum mt76_testmode_state {
+@@ -219,6 +219,14 @@ enum mt76_testmode_state {
  	MT76_TM_STATE_TX_FRAMES,
  	MT76_TM_STATE_RX_FRAMES,
  	MT76_TM_STATE_TX_CONT,
@@ -875,7 +877,7 @@
  
  	/* keep last */
 diff --git a/tools/fields.c b/tools/fields.c
-index e5cf7c53..b22b3fc8 100644
+index 055f90f..b012276 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -11,6 +11,14 @@ static const char * const testmode_state[] = {
@@ -894,5 +896,5 @@
  
  static const char * const testmode_tx_mode[] = {
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1007-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
similarity index 86%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-binfile-mode-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-binfile-mode-support.patch
index 549344f..6d1a987 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1007-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
@@ -1,7 +1,7 @@
-From 2cf8a9517919b39318eb1e878ca69418a499126a Mon Sep 17 00:00:00 2001
+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 1007/1015] wifi: mt76: mt7996: add binfile mode support
+Subject: [PATCH 44/98] wifi: mt76: mt7996: add binfile mode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -14,10 +14,10 @@
  6 files changed, 112 insertions(+), 3 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index aa889258..412740f0 100644
+index 437d8ca..89bb913 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -104,6 +104,26 @@ out_put_node:
+@@ -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);
  
@@ -45,10 +45,10 @@
  mt76_eeprom_override(struct mt76_phy *phy)
  {
 diff --git a/mt76.h b/mt76.h
-index 3341720c..7d6e3241 100644
+index fc69d3e..0bf0177 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -894,6 +894,8 @@ struct mt76_dev {
+@@ -945,6 +945,8 @@ struct mt76_dev {
  		struct mt76_usb usb;
  		struct mt76_sdio sdio;
  	};
@@ -56,8 +56,8 @@
 +	const char *bin_file_name;
  };
  
- struct mt76_power_limits {
-@@ -1030,6 +1032,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
+ /* 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);
@@ -66,7 +66,7 @@
  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 60e98463..85d9e057 100644
+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)
@@ -82,7 +82,7 @@
  	/* reserve for future variants */
  	if (dev->testmode_enable)
  		return MT7996_EEPROM_DEFAULT_TM;
-@@ -112,7 +115,10 @@ mt7996_eeprom_load_default(struct mt7996_dev *dev)
+@@ -114,7 +117,10 @@ mt7996_eeprom_load_default(struct mt7996_dev *dev)
  		return ret;
  
  	if (!fw || !fw->data) {
@@ -94,7 +94,7 @@
  		ret = -EINVAL;
  		goto out;
  	}
-@@ -126,18 +132,45 @@ out:
+@@ -128,18 +134,45 @@ out:
  	return ret;
  }
  
@@ -141,7 +141,7 @@
  		eeprom = dev->mt76.eeprom.data;
  		/* testmode enable priority: eeprom field > module parameter */
  		dev->testmode_enable = !mt7996_check_eeprom(dev) ? eeprom[MT_EE_TESTMODE_EN] :
-@@ -171,6 +204,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
+@@ -173,6 +206,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
  			if (ret < 0)
  				return ret;
  		}
@@ -149,7 +149,7 @@
  	}
  
  	return mt7996_check_eeprom(dev);
-@@ -306,6 +340,8 @@ int mt7996_eeprom_init(struct mt7996_dev *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");
@@ -159,7 +159,7 @@
  		if (ret)
  			return ret;
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 7ff290f4..20dd8771 100644
+index 7ff290f..20dd877 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -99,6 +99,13 @@ enum mt7996_eeprom_band {
@@ -177,11 +177,11 @@
  mt7996_get_channel_group_5g(int channel)
  {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 9ab86eaf..6ef6bad9 100644
+index 684c254..cda557e 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -380,6 +380,8 @@ struct mt7996_dev {
- 	bool has_eht:1;
+@@ -375,6 +375,8 @@ struct mt7996_dev {
+ 	} wed_rro;
  
  	bool testmode_enable;
 +	bool bin_file_mode;
@@ -189,7 +189,7 @@
  
  	bool ibf;
  	u8 fw_debug_wm;
-@@ -519,6 +521,7 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
+@@ -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);
@@ -198,10 +198,10 @@
  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 2aee3ab0..2ab2a8a8 100644
+index 57fcbab..82b2785 100644
 --- a/mt7996/mtk_debugfs.c
 +++ b/mt7996/mtk_debugfs.c
-@@ -2525,6 +2525,44 @@ static const struct file_operations mt7996_txpower_sku_fops = {
+@@ -2551,6 +2551,44 @@ static const struct file_operations mt7996_txpower_sku_fops = {
  	.llseek = default_llseek,
  };
  
@@ -246,7 +246,7 @@
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
  {
  	struct mt7996_dev *dev = phy->dev;
-@@ -2570,6 +2608,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+@@ -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);
@@ -256,5 +256,5 @@
  	debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
  				    mt7996_wtbl_read);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
similarity index 90%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
index 6b18fb0..3aac8a9 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
@@ -1,7 +1,7 @@
-From f3ff5d5029a0a589e797dd2536070d3a3e4e30a6 Mon Sep 17 00:00:00 2001
+From 114d3abef99827bcc848e6aef393be79a7c34e71 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 1008/1015] wifi: mt76: mt7996: add normal mode pre-calibration
+Subject: [PATCH 45/98] wifi: mt76: mt7996: add normal mode pre-calibration
  support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,22 +16,22 @@
  7 files changed, 206 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 262abf88..42246fb9 100644
+index d65ecf0..762ac29 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1229,6 +1229,7 @@ enum {
- 	MCU_UNI_CMD_VOW = 0x37,
+@@ -1251,6 +1251,7 @@ enum {
+ 	MCU_UNI_CMD_PP = 0x38,
  	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
  	MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
 +	MCU_UNI_CMD_PRECAL_RESULT = 0x47,
  	MCU_UNI_CMD_RRO = 0x57,
  	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
- 	MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
+ 	MCU_UNI_CMD_PER_STA_INFO = 0x6d,
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 85d9e057..bee4a4b5 100644
+index ca91c69..56605de 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -330,6 +330,25 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
+@@ -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);
  }
  
@@ -57,7 +57,7 @@
  int mt7996_eeprom_init(struct mt7996_dev *dev)
  {
  	int ret;
-@@ -347,6 +366,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+@@ -350,6 +369,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
  			return ret;
  	}
  
@@ -69,7 +69,7 @@
  	if (ret < 0)
  		return ret;
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 20dd8771..0f3f31d8 100644
+index 20dd877..0f3f31d 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -25,6 +25,8 @@ enum mt7996_eeprom_field {
@@ -82,10 +82,10 @@
  
  #define MT_EE_WIFI_CONF0_TX_PATH		GENMASK(2, 0)
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 40d610ae..31695090 100644
+index 5940e41..bf3479e 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -675,6 +675,12 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -826,6 +826,12 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  	if (ret < 0)
  		return ret;
  
@@ -99,7 +99,7 @@
  	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA);
  	if (idx)
 diff --git a/mt7996/main.c b/mt7996/main.c
-index e5627c96..d40d3047 100644
+index 804c0c1..7d1bd42 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -312,6 +312,12 @@ int mt7996_set_channel(struct mt7996_phy *phy)
@@ -116,10 +116,10 @@
  	if (ret)
  		goto out;
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 1fb7bae1..6add77da 100644
+index d6f4e22..695d5f0 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -3386,6 +3386,172 @@ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
+@@ -3456,6 +3456,172 @@ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
  	return 0;
  }
  
@@ -293,11 +293,11 @@
  {
  #define NIC_CAP	3
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 6ef6bad9..c16bc8b4 100644
+index cda557e..80a10bf 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -607,6 +607,8 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
- void mt7996_mcu_exit(struct mt7996_dev *dev);
+@@ -611,6 +611,8 @@ 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);
  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);
@@ -306,5 +306,5 @@
  void mt7996_mcu_scs_sta_poll(struct work_struct *work);
  #ifdef CONFIG_NL80211_TESTMODE
 -- 
-2.39.2
+2.18.0
 
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
new file mode 100644
index 0000000..9a38681
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
@@ -0,0 +1,343 @@
+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/1013-wifi-mt76-mt7996-get-tx_retries-and-tx_fails-from-tx.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-get-tx_retries-and-tx_fails-from-tx.patch
deleted file mode 100644
index c01b398..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-get-tx_retries-and-tx_fails-from-tx.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 3a58791cef81709963d654d520fab9f1b7987e7b Mon Sep 17 00:00:00 2001
-From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
-Date: Thu, 11 May 2023 09:14:28 +0800
-Subject: [PATCH 1013/1015] wifi: mt76: mt7996: get tx_retries and tx_fails
- from txfree
-
-Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
----
- mt7996/mac.c  | 20 +++++++++++++++-----
- mt7996/mac.h  |  6 ++++--
- mt7996/main.c |  6 ++++++
- 3 files changed, 25 insertions(+), 7 deletions(-)
-
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 3dc5cdae..bee4a8ae 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1240,6 +1240,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;
-@@ -1258,7 +1259,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);
-@@ -1274,10 +1275,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)
-@@ -1289,10 +1289,20 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
- 				list_add_tail(&msta->poll_list, &dev->sta_poll_list);
- 			spin_unlock_bh(&dev->sta_poll_lock);
- 			continue;
--		}
-+		} else if (info & MT_TXFREE_INFO_HEADER) {
-+			if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid) {
-+				u32 tx_retries = 0, tx_failed = 0;
-+
-+				tx_retries =
-+					FIELD_GET(MT_TXFREE_INFO_TX_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/mac.h b/mt7996/mac.h
-index bc4e6c55..74ad1e81 100644
---- a/mt7996/mac.h
-+++ b/mt7996/mac.h
-@@ -256,11 +256,13 @@ 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_TX_COUNT		GENMASK(27, 24)
-+#define MT_TXFREE_INFO_STAT		GENMASK(29, 28)
-+#define MT_TXFREE_INFO_MLD_ID		GENMASK(23, 12)
- #define MT_TXFREE_INFO_MSDU_ID		GENMASK(14, 0)
- 
- #define MT_TXS0_BW			GENMASK(31, 29)
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 71c346cb..f0bdec6b 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -1024,6 +1024,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.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
similarity index 93%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
index 999d9ba..16439d4 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
@@ -1,8 +1,8 @@
-From 639385416a573ae5ce631a0323c5541dea3e406c Mon Sep 17 00:00:00 2001
+From 9bbc79e25d5fe7c14ec520413f4fb0625af9c630 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 1010/1015] wifi: mt76: testmode: add testmode ZWDFS
- verification support
+Subject: [PATCH 47/98] 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 7d6e3241..5b442691 100644
+index 0bf0177..0096c7f 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -732,6 +732,14 @@ struct mt76_testmode_data {
+@@ -774,6 +774,14 @@ struct mt76_testmode_data {
  	} cfg;
  
  	u8 aid;
@@ -34,22 +34,22 @@
  
  struct mt76_vif {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 94b62211..abdbb1ef 100644
+index 9f99d13..7269076 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -295,6 +295,7 @@ struct mt7996_phy {
+@@ -272,6 +272,7 @@ struct mt7996_phy {
  
- 	struct mib_stats mib;
+ 	struct mt76_mib_stats mib;
  	struct mt76_channel_state state_ts;
 +	struct delayed_work ipi_work;
  
  	bool has_aux_rx;
  
 diff --git a/mt7996/testmode.c b/mt7996/testmode.c
-index 7d36902e..ba3cd802 100644
+index 8ceea00..c52bf41 100644
 --- a/mt7996/testmode.c
 +++ b/mt7996/testmode.c
-@@ -16,6 +16,12 @@ enum {
+@@ -17,6 +17,12 @@ enum {
  	TM_CHANGED_TX_LENGTH,
  	TM_CHANGED_TX_TIME,
  	TM_CHANGED_CFG,
@@ -62,7 +62,7 @@
  
  	/* must be last */
  	NUM_TM_CHANGED
-@@ -27,20 +33,31 @@ static const u8 tm_change_map[] = {
+@@ -29,20 +35,31 @@ static const u8 tm_change_map[] = {
  	[TM_CHANGED_TX_LENGTH] = MT76_TM_ATTR_TX_LENGTH,
  	[TM_CHANGED_TX_TIME] = MT76_TM_ATTR_TX_TIME,
  	[TM_CHANGED_CFG] = MT76_TM_ATTR_CFG,
@@ -105,7 +105,7 @@
  	};
  
  	if (width >= ARRAY_SIZE(width_to_bw))
-@@ -217,6 +234,9 @@ mt7996_tm_init(struct mt7996_phy *phy, bool en)
+@@ -216,6 +233,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
-@@ -829,6 +849,204 @@ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -828,6 +848,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)
  {
-@@ -853,6 +1071,14 @@ mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
+@@ -858,6 +1076,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 778c9bc6..09f81d39 100644
+index 17c1456..57fde8c 100644
 --- a/mt7996/testmode.h
 +++ b/mt7996/testmode.h
 @@ -27,9 +27,15 @@ enum {
@@ -355,7 +355,7 @@
  
  	NUM_BW_MAP,
  };
-@@ -308,4 +314,42 @@ struct mt7996_tm_rx_event {
+@@ -310,4 +316,42 @@ struct mt7996_tm_rx_event {
  	};
  } __packed;
  
@@ -399,10 +399,10 @@
 +
  #endif
 diff --git a/testmode.c b/testmode.c
-index 74bb26fa..22d6afd4 100644
+index e66b54a..bce3a9c 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -25,6 +25,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+@@ -27,6 +27,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 },
@@ -416,7 +416,7 @@
  };
  EXPORT_SYMBOL_GPL(mt76_tm_policy);
  
-@@ -451,6 +458,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -456,6 +463,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,
-@@ -466,7 +476,14 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -471,7 +481,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,9 +442,9 @@
  		goto out;
  
  	if (tb[MT76_TM_ATTR_TX_LENGTH]) {
-@@ -671,6 +688,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
- 	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_LDPC, td->tx_rate_ldpc) ||
+@@ -677,6 +694,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) ||
 +	    nla_put_u8(msg, MT76_TM_ATTR_OFF_CH_SCAN_CH, td->offchan_ch) ||
 +	    nla_put_u8(msg, MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH, td->offchan_center_ch) ||
@@ -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 b22b3fc8..55854a6f 100644
+index b012276..77696ce 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -35,6 +35,15 @@ static const char * const testmode_tx_mode[] = {
@@ -472,7 +472,7 @@
  static void print_enum(const struct tm_field *field, struct nlattr *attr)
  {
  	unsigned int i = nla_get_u8(attr);
-@@ -387,6 +396,12 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+@@ -390,6 +399,12 @@ 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"),
@@ -486,5 +486,5 @@
  	FIELD_NESTED_RO(STATS, stats, "",
  			.print_extra = print_extra_stats),
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-single-sku.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-single-sku.patch
similarity index 76%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-single-sku.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-single-sku.patch
index 0fcae6a..14514e2 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-single-sku.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-single-sku.patch
@@ -1,27 +1,27 @@
-From 0d9ff0aa7afe37146c6015e416d9b944b4bb16f5 Mon Sep 17 00:00:00 2001
+From d07d8b3b246b974d7ae4ad9bdfc676438cb45fec Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
-Date: Tue, 18 Apr 2023 15:56:22 +0800
-Subject: [PATCH 1011/1015] wifi: mt76: mt7996: add single sku
+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          | 38 ++++++++++++++++++--
- mt76.h            | 10 ++++++
+ eeprom.c          | 50 +++++++++++++++++++++++---
+ mt76.h            |  9 +++++
  mt76_connac_mcu.c |  2 +-
  mt7996/init.c     |  2 ++
- mt7996/main.c     | 15 ++++++++
+ mt7996/main.c     | 16 +++++++++
  mt7996/mcu.c      | 92 +++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/mcu.h      | 12 +++++++
  mt7996/mt7996.h   |  2 ++
- 8 files changed, 169 insertions(+), 4 deletions(-)
+ 8 files changed, 179 insertions(+), 6 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index 412740f0..3abefb5a 100644
+index 89bb913..bd662dd 100644
 --- a/eeprom.c
 +++ b/eeprom.c
-@@ -301,6 +301,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
+@@ -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,
@@ -29,15 +29,19 @@
  			      s8 target_power)
  {
  	struct mt76_dev *dev = phy->dev;
-@@ -308,16 +309,17 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+@@ -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 = 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;
@@ -49,7 +53,7 @@
  
  	if (!IS_ENABLED(CONFIG_OF))
  		return target_power;
-@@ -365,11 +367,41 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+@@ -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);
  
@@ -59,85 +63,91 @@
  				     ARRAY_SIZE(dest->ru), val, len,
  				     target_power, txs_delta, &max_power);
  
-+	val = mt76_get_of_array(np, "rates-eht-ru", &len, ARRAY_SIZE(dest->eht_ru[0]) + 1);
-+	mt76_apply_multi_array_limit(dest->eht_ru[0], ARRAY_SIZE(dest->eht_ru[0]),
-+				     ARRAY_SIZE(dest->eht_ru), val, len,
+-	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, txs_delta, &max_power);
++			       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, txs_delta, &max_power);
++			       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, txs_delta, &max_power);
++			       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, txs_delta, &max_power);
++				     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, txs_delta, &max_power);
++				     target_power_combine, txs_delta, &max_power_backoff);
++
++	if (max_power_backoff == target_power_combine)
++		return max_power;
 +
- 	return max_power;
++	return max_power_backoff;
  }
  EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
+ 
 diff --git a/mt76.h b/mt76.h
-index 5b442691..8abb6f41 100644
+index 0096c7f..d59a1f5 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -911,6 +911,15 @@ struct mt76_power_limits {
- 	s8 ofdm[8];
- 	s8 mcs[4][10];
- 	s8 ru[7][12];
-+	s8 eht_ru[16][16];
-+};
-+
+@@ -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 {
-@@ -1493,6 +1502,7 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
+ 	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_rx(struct mt76_queue *q)
+ 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 c24dac10..ca7b6a6f 100644
+index 236cfea..214a526 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -2235,7 +2235,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
+@@ -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,
+ 			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 31695090..a6caf4f1 100644
+index bf3479e..ad93927 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -294,6 +294,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+@@ -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;
@@ -145,7 +155,7 @@
  
  	for (i = 0; i < sband->n_channels; i++) {
  		struct ieee80211_channel *chan = &sband->channels[i];
-@@ -302,6 +303,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+@@ -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,
@@ -154,7 +164,7 @@
  		target_power += nss_delta;
  		target_power = DIV_ROUND_UP(target_power, 2);
 diff --git a/mt7996/main.c b/mt7996/main.c
-index d3d10fab..71c346cb 100644
+index 0ea006c..9e3e4ed 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -77,6 +77,15 @@ int mt7996_run(struct ieee80211_hw *hw)
@@ -173,7 +183,7 @@
  	set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
  
  	ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
-@@ -427,6 +436,12 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
+@@ -429,6 +438,12 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
  		ieee80211_wake_queues(hw);
  	}
  
@@ -186,11 +196,19 @@
  	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 53d2fc73..aefbdca6 100644
+index 1a1c732..c87cb1a 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -4616,6 +4616,98 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
+@@ -4708,6 +4708,98 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
  				 &req, sizeof(req), false);
  }
  
@@ -249,7 +267,7 @@
 +	skb_put_data(skb, &la.ru[0], sizeof(la.ru));
 +
 +	/* eht */
-+	skb_put_data(skb, &la.eht_ru[0], sizeof(la.eht_ru));
++	skb_put_data(skb, &la.eht[0], sizeof(la.eht));
 +
 +	/* padding */
 +	skb_put_zero(skb, MT7996_SKU_PATH_NUM - MT7996_SKU_RATE_NUM);
@@ -290,10 +308,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 f32ac153..1d2b7c58 100644
+index 7808c35..6fc5ab3 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -657,6 +657,18 @@ enum {
+@@ -777,6 +777,18 @@ enum {
  #define MT7996_MAX_BSS_OFFLOAD_SIZE	(MT7996_MAX_BEACON_SIZE +		\
  					 MT7996_BEACON_UPDATE_SIZE)
  
@@ -313,18 +331,18 @@
  	UNI_BAND_CONFIG_RADIO_ENABLE,
  	UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index abdbb1ef..d15bd950 100644
+index 7269076..34c8fe6 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -61,6 +61,7 @@
+@@ -64,6 +64,7 @@
  #define MT7996_BUILD_TIME_LEN		24
  
  #define MT7996_SKU_RATE_NUM		417
 +#define MT7996_SKU_PATH_NUM		494
  
- struct mt7996_vif;
- struct mt7996_sta;
-@@ -610,6 +611,7 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+ #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);
@@ -333,5 +351,5 @@
  void mt7996_mcu_scs_sta_poll(struct work_struct *work);
  #ifdef CONFIG_NL80211_TESTMODE
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
index c5ea448..37717c3 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
@@ -1,7 +1,7 @@
-From a048ff567915954ca9cc68ef94c9a7786542b5d9 Mon Sep 17 00:00:00 2001
+From 8d1ba9d8e0f80eedcdf14d29dbca9c3cbd8589dc 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 1012/1015] wifi: mt76: mt7996: add vendor cmd to get available
+Subject: [PATCH 49/98] wifi: mt76: mt7996: add vendor cmd to get available
  color bitmap
 
 Add a vendor cmd to notify user space available color bitmap.
@@ -14,10 +14,10 @@
  2 files changed, 47 insertions(+)
 
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index 8a021324..73f613aa 100644
+index f3b089d..3910157 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
-@@ -34,6 +34,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
+@@ -35,6 +35,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
  	[MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
  };
  
@@ -29,7 +29,7 @@
  struct mt7996_amnt_data {
  	u8 idx;
  	u8 addr[ETH_ALEN];
-@@ -409,6 +414,26 @@ mt7966_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -410,6 +415,26 @@ mt7966_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
  	return len + 1;
  }
  
@@ -56,7 +56,7 @@
  
  static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
  	{
-@@ -435,6 +460,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+@@ -436,6 +461,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
  		.policy = amnt_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_AMNT_CTRL_MAX,
  	},
@@ -75,7 +75,7 @@
  
  void mt7996_vendor_register(struct mt7996_phy *phy)
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index 2078cafa..eec9e74a 100644
+index 2078caf..eec9e74 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -6,6 +6,7 @@
@@ -103,5 +103,5 @@
  
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
similarity index 88%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
index 1b22e9a..da8c4bd 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
@@ -1,7 +1,7 @@
-From 97144fb0d20ba67ec6c3a022ed5a39bc95ed40e9 Mon Sep 17 00:00:00 2001
+From 7556e60ec860e301a053dad4b16b7e88ccd9baa7 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 1014/1015] wifi: mt76: mt7996: add debugfs for fw coredump.
+Subject: [PATCH 50/98] wifi: mt76: mt7996: add debugfs for fw coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  4 files changed, 56 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 8a513f46..49c815a5 100644
+index 92aa164..2c11837 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 +64,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 bee4a8ae..993b43ce 100644
+index ee17d59..37cc94e 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -2157,15 +2157,36 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2021,15 +2021,36 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	struct mt7996_dev *dev;
  
  	dev = container_of(work, struct mt7996_dev, dump_work);
@@ -106,8 +106,8 @@
 +
  void mt7996_reset(struct mt7996_dev *dev)
  {
- 	dev_info(dev->mt76.dev, "%s SER recovery state: 0x%08x\n",
-@@ -2187,6 +2208,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)
  
  		mt7996_irq_disable(dev, MT_INT_MCU_CMD);
  		queue_work(dev->mt76.wq, &dev->dump_work);
@@ -116,10 +116,10 @@
  	}
  
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 1d2b7c58..a0cbf922 100644
+index 6fc5ab3..989a2ff 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -780,7 +780,11 @@ enum {
+@@ -900,7 +900,11 @@ enum {
  	UNI_CMD_SER_SET_RECOVER_L3_BF,
  	UNI_CMD_SER_SET_RECOVER_L4_MDP,
  	UNI_CMD_SER_SET_RECOVER_FULL,
@@ -132,10 +132,10 @@
  	UNI_CMD_SER_ENABLE = 1,
  	UNI_CMD_SER_SET,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index d15bd950..e371964b 100644
+index 34c8fe6..9b110cf 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -76,6 +76,14 @@ enum mt7996_ram_type {
+@@ -100,6 +100,14 @@ enum mt7996_ram_type {
  	__MT7996_RAM_TYPE_MAX,
  };
  
@@ -150,7 +150,7 @@
  enum mt7996_txq_id {
  	MT7996_TXQ_FWDL = 16,
  	MT7996_TXQ_MCU_WM,
-@@ -361,6 +369,7 @@ struct mt7996_dev {
+@@ -342,6 +350,7 @@ struct mt7996_dev {
  
  	/* protects coredump data */
  	struct mutex dump_mutex;
@@ -158,7 +158,7 @@
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
  		struct mt7996_crash_data *crash_data[__MT7996_RAM_TYPE_MAX];
-@@ -540,6 +549,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+@@ -541,6 +550,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
  			 struct ieee80211_supported_band *sband);
  int mt7996_txbf_init(struct mt7996_dev *dev);
  void mt7996_reset(struct mt7996_dev *dev);
@@ -167,5 +167,5 @@
  int mt7996_mcu_init(struct mt7996_dev *dev);
  int mt7996_mcu_init_firmware(struct mt7996_dev *dev);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
similarity index 80%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
index 33432ff..dc0b0c3 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
@@ -1,8 +1,8 @@
-From 0d4c8fc47472e0acb7f823f483bc8b83c8a9f235 Mon Sep 17 00:00:00 2001
+From a928c6df5edd9920b4293de6d1216461952aec27 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 1015/1015] wifi: mt76: mt7996: add support for runtime set
- in-band discovery
+Subject: [PATCH 51/98] 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 aefbdca6..59f22f6d 100644
+index c87cb1a..722c435 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2438,8 +2438,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+@@ -2484,8 +2484,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 &&
-@@ -2475,7 +2474,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+@@ -2521,7 +2520,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);
@@ -40,5 +40,5 @@
  
  	buf = (u8 *)tlv + sizeof(*discov);
 -- 
-2.39.2
+2.18.0
 
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/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch
new file mode 100644
index 0000000..06fc5e8
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch
@@ -0,0 +1,392 @@
+From 140f810c788ffccc605fa979635c9be2db4b9748 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
+
+---
+ mt7996/main.c    |   3 ++
+ mt7996/mcu.h     |   2 +
+ mt7996/mt7996.h  |  11 ++++
+ mt7996/mtk_mcu.c |  86 ++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.h |  15 ++++++
+ mt7996/vendor.c  | 132 +++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h  |  33 ++++++++++++
+ 7 files changed, 282 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
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -791,6 +791,8 @@ mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
+ 
+ enum {
+ 	UNI_BAND_CONFIG_RADIO_ENABLE,
++	UNI_BAND_CONFIG_EDCCA_ENABLE = 0x05,
++	UNI_BAND_CONFIG_EDCCA_THRESHOLD = 0x06,
+ 	UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
+ };
+ 
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 9b110cf..8fd29d7 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -750,6 +750,17 @@ int mt7996_vendor_amnt_sta_remove(struct mt7996_phy *phy,
+ 				  struct ieee80211_sta *sta);
+ #endif
+ 
++int mt7996_mcu_edcca_enable(struct mt7996_phy *phy, bool enable);
++int mt7996_mcu_edcca_threshold_ctrl(struct mt7996_phy *phy, u8 *value, bool set);
++
++enum edcca_bw_id {
++	EDCCA_BW_20 = 0,
++	EDCCA_BW_40,
++	EDCCA_BW_80,
++	EDCCA_BW_160,
++	EDCCA_MAX_BW_NUM,
++};
++
+ #ifdef CONFIG_MTK_DEBUG
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
+ #endif
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index f772243..048c534 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;
+ }
+ 
++int mt7996_mcu_edcca_enable(struct mt7996_phy *phy, bool enable)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
++	enum nl80211_band band = chandef->chan->band;
++	struct {
++		u8 band_idx;
++		u8 _rsv[3];
++
++		__le16 tag;
++		__le16 len;
++		u8 enable;
++		u8 std;
++		u8 _rsv2[2];
++	} __packed req = {
++		.band_idx = phy->mt76->band_idx,
++		.tag = cpu_to_le16(UNI_BAND_CONFIG_EDCCA_ENABLE),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.enable = enable,
++		.std = EDCCA_DEFAULT,
++	};
++
++	switch (dev->mt76.region) {
++	case NL80211_DFS_JP:
++		req.std = EDCCA_JAPAN;
++		break;
++	case NL80211_DFS_FCC:
++		if (band == NL80211_BAND_6GHZ)
++			req.std = EDCCA_FCC;
++		break;
++	case NL80211_DFS_ETSI:
++		if (band == NL80211_BAND_6GHZ)
++			req.std = EDCCA_ETSI;
++		break;
++	default:
++		break;
++	}
++
++	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
++				 &req, sizeof(req), true);
++}
++
++int mt7996_mcu_edcca_threshold_ctrl(struct mt7996_phy *phy, u8 *value, bool set)
++{
++	struct {
++		u8 band_idx;
++		u8 _rsv[3];
++
++		__le16 tag;
++		__le16 len;
++		u8 threshold[4];
++		bool init;
++	} __packed *res, req = {
++		.band_idx = phy->mt76->band_idx,
++		.tag = cpu_to_le16(UNI_BAND_CONFIG_EDCCA_THRESHOLD),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.init = false,
++	};
++	struct sk_buff *skb;
++	int ret;
++	int i;
++
++	for (i = 0; i < EDCCA_MAX_BW_NUM; i++)
++		req.threshold[i] = value[i];
++
++	if (set)
++		return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
++					 &req, sizeof(req), true);
++
++	ret = mt76_mcu_send_and_get_msg(&phy->dev->mt76,
++					MCU_WM_UNI_CMD_QUERY(BAND_CONFIG),
++					&req, sizeof(req), true, &skb);
++
++	if (ret)
++		return ret;
++
++	res = (void *)skb->data;
++
++	for (i = 0; i < EDCCA_MAX_BW_NUM; i++)
++		value[i] = res->threshold[i];
++
++	dev_kfree_skb(skb);
++
++	return 0;
++}
++
+ #endif
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index beb1aba..9c0db87 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -89,6 +89,21 @@ enum txpower_event {
+ 	UNI_TXPOWER_PHY_RATE_INFO = 5,
+ };
+ 
++enum {
++	EDCCA_CTRL_SET_EN = 0,
++	EDCCA_CTRL_SET_THRES,
++	EDCCA_CTRL_GET_EN,
++	EDCCA_CTRL_GET_THRES,
++	EDCCA_CTRL_NUM,
++};
++
++enum {
++	EDCCA_DEFAULT = 0,
++	EDCCA_FCC = 1,
++	EDCCA_ETSI = 2,
++	EDCCA_JAPAN = 3
++};
++
+ #endif
+ 
+ #endif
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 3910157..9f333d0 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -40,6 +40,26 @@ bss_color_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL] = {
+ 	[MTK_VENDOR_ATTR_AVAL_BSS_COLOR_BMP] = { .type = NLA_U64 },
+ };
+ 
++static const 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_S8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC160_VAL] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++edcca_dump_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP] = {
++	[MTK_VENDOR_ATTR_EDCCA_DUMP_MODE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_DUMP_PRI20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_DUMP_SEC40_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_DUMP_SEC80_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_DUMP_SEC160_VAL] = { .type = NLA_U8 },
++};
++
+ struct mt7996_amnt_data {
+ 	u8 idx;
+ 	u8 addr[ETH_ALEN];
+@@ -436,6 +456,106 @@ mt7996_vendor_bss_color_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev
+ 	return len;
+ }
+ 
++static int mt7996_vendor_edcca_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 nlattr *tb[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL];
++	int err;
++	u8 edcca_mode;
++	u8 edcca_value[EDCCA_MAX_BW_NUM];
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_EDCCA_CTRL_MAX, data, data_len,
++			edcca_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	if (!tb[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE])
++		return -EINVAL;
++
++	edcca_mode = nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE]);
++	if (edcca_mode == EDCCA_CTRL_SET_EN) {
++		if (!tb[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL])
++			return -EINVAL;
++
++		edcca_value[0] =
++			nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL]);
++
++		err = mt7996_mcu_edcca_enable(phy, !!edcca_value[0]);
++		if (err)
++			return err;
++	} else if (edcca_mode == EDCCA_CTRL_SET_THRES) {
++		if (!tb[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] ||
++		    !tb[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] ||
++		    !tb[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] ||
++		    !tb[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC160_VAL]) {
++			return -EINVAL;
++		}
++		edcca_value[EDCCA_BW_20] =
++			nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL]);
++		edcca_value[EDCCA_BW_40] =
++			nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL]);
++		edcca_value[EDCCA_BW_80] =
++			nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL]);
++		edcca_value[EDCCA_BW_160] =
++			nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC160_VAL]);
++
++		err = mt7996_mcu_edcca_threshold_ctrl(phy, edcca_value, true);
++
++		if (err)
++			return err;
++	} else {
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++
++static int
++mt7996_vendor_edcca_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);
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL];
++	int err;
++	u8 edcca_mode;
++	u8 value[EDCCA_MAX_BW_NUM];
++
++	if (*storage == 1)
++		return -ENOENT;
++	*storage = 1;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_EDCCA_CTRL_MAX, data, data_len,
++			edcca_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	if (!tb[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE])
++		return -EINVAL;
++
++	edcca_mode = nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE]);
++
++	if (edcca_mode != EDCCA_CTRL_GET_THRES)
++		return -EINVAL;
++
++	err = mt7996_mcu_edcca_threshold_ctrl(phy, value, false);
++
++	if (err)
++		return err;
++
++	if (nla_put_u8(skb, MTK_VENDOR_ATTR_EDCCA_DUMP_PRI20_VAL, value[EDCCA_BW_20]) ||
++	    nla_put_u8(skb, MTK_VENDOR_ATTR_EDCCA_DUMP_SEC40_VAL, value[EDCCA_BW_40]) ||
++	    nla_put_u8(skb, MTK_VENDOR_ATTR_EDCCA_DUMP_SEC80_VAL, value[EDCCA_BW_80]) ||
++	    nla_put_u8(skb, MTK_VENDOR_ATTR_EDCCA_DUMP_SEC160_VAL, value[EDCCA_BW_160]))
++		return -ENOMEM;
++
++	return EDCCA_MAX_BW_NUM;
++}
++
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 	{
+ 		.info = {
+@@ -472,6 +592,18 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 		.policy = bss_color_ctrl_policy,
+ 		.maxattr = MTK_VENDOR_ATTR_BSS_COLOR_CTRL_MAX,
+ 	},
++	{
++		.info = {
++			.vendor_id = MTK_NL80211_VENDOR_ID,
++			.subcmd = MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++			 WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_edcca_ctrl,
++		.dumpit = mt7996_vendor_edcca_ctrl_dump,
++		.policy = edcca_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_EDCCA_CTRL_MAX,
++	},
+ };
+ 
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index eec9e74..4465bc9 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -6,9 +6,42 @@
+ 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_BSS_COLOR_CTRL = 0xca,
+ };
+ 
++enum mtk_vendor_attr_edcca_ctrl {
++	MTK_VENDOR_ATTR_EDCCA_THRESHOLD_INVALID = 0,
++
++	MTK_VENDOR_ATTR_EDCCA_CTRL_MODE,
++	MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL,
++	MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL,
++	MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL,
++	MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL,
++	MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE,
++	MTK_VENDOR_ATTR_EDCCA_CTRL_SEC160_VAL,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL,
++	MTK_VENDOR_ATTR_EDCCA_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL - 1
++};
++
++enum mtk_vendor_attr_edcca_dump {
++	MTK_VENDOR_ATTR_EDCCA_DUMP_UNSPEC = 0,
++
++	MTK_VENDOR_ATTR_EDCCA_DUMP_MODE,
++	MTK_VENDOR_ATTR_EDCCA_DUMP_PRI20_VAL,
++	MTK_VENDOR_ATTR_EDCCA_DUMP_SEC40_VAL,
++	MTK_VENDOR_ATTR_EDCCA_DUMP_SEC80_VAL,
++	MTK_VENDOR_ATTR_EDCCA_DUMP_SEC160_VAL,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP,
++	MTK_VENDOR_ATTR_EDCCA_DUMP_MAX =
++		NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP - 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/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
new file mode 100644
index 0000000..f7596bb
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch
@@ -0,0 +1,30 @@
+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/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch
new file mode 100644
index 0000000..142193f
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch
@@ -0,0 +1,393 @@
+From 86906513b2597a79c26b72a6a9dc0ecf8b0ce1ed 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
+
+This commit adds the following debug commands in debugfs:
+1. sr_enable: enable/disable spatial reuse feature. Default is on.
+2. sr_enhanced_enable: enable/disable enhanced spatial reuse feature.
+Default is on. This feature is mtk proprietary feature.
+3. sr_stats: Check the Spatial reuse tx statistics.
+4. sr_scene_cond: Check the result of mtk scene detection algorithm. Mtk
+scene detection algorithm in firmware may decide whether current
+environment can SR Tx or not.
+
+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/mt7996.h      |   6 +++
+ mt7996/mtk_debugfs.c |  82 ++++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.c     | 111 +++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.h     |  56 ++++++++++++++++++++++
+ 7 files changed, 267 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 42eb64c..e904ebc 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1031,6 +1031,7 @@ enum {
+ 	MCU_UNI_EVENT_BSS_BEACON_LOSS = 0x0c,
+ 	MCU_UNI_EVENT_SCAN_DONE = 0x0e,
+ 	MCU_UNI_EVENT_RDD_REPORT = 0x11,
++	MCU_UNI_EVENT_SR = 0x25,
+ 	MCU_UNI_EVENT_ROC = 0x27,
+ 	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
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -6,6 +6,9 @@
+ #include "mt7996.h"
+ #include "mcu.h"
+ #include "mac.h"
++#ifdef CONFIG_MTK_DEBUG
++#include "mtk_mcu.h"
++#endif
+ 
+ static bool mt7996_dev_running(struct mt7996_dev *dev)
+ {
+@@ -78,6 +81,9 @@ int mt7996_run(struct ieee80211_hw *hw)
+ 		goto out;
+ 
+ #ifdef CONFIG_MTK_DEBUG
++	phy->sr_enable = true;
++	phy->enhanced_sr_enable = true;
++
+ 	ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
+ 					   !dev->dbg.sku_disable);
+ #else
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 722c435..2dbec1e 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);
+ 		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;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 8fd29d7..1fac783 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -306,6 +306,10 @@ struct mt7996_phy {
+ 	spinlock_t amnt_lock;
+ 	struct mt7996_air_monitor_ctrl amnt_ctrl;
+ #endif
++#ifdef CONFIG_MTK_DEBUG
++	bool sr_enable:1;
++	bool enhanced_sr_enable:1;
++#endif
+ };
+ 
+ struct mt7996_dev {
+@@ -763,6 +767,8 @@ enum edcca_bw_id {
+ 
+ #ifdef CONFIG_MTK_DEBUG
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
++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
+--- 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)
+ 	return 0;
+ }
+ 
++static int
++mt7996_sr_enable_get(void *data, u64 *val)
++{
++	struct mt7996_phy *phy = data;
++
++	*val = phy->sr_enable;
++
++	return 0;
++}
++
++static int
++mt7996_sr_enable_set(void *data, u64 val)
++{
++	struct mt7996_phy *phy = data;
++	int ret;
++
++	if (!!val == phy->sr_enable)
++		return 0;
++
++	ret = mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_CFG_SR_ENABLE, val, true);
++	if (ret)
++		return ret;
++
++	return mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_CFG_SR_ENABLE, 0, false);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enable, mt7996_sr_enable_get,
++			 mt7996_sr_enable_set, "%lld\n");
++static int
++mt7996_sr_enhanced_enable_get(void *data, u64 *val)
++{
++	struct mt7996_phy *phy = data;
++
++	*val = phy->enhanced_sr_enable;
++
++	return 0;
++}
++
++static int
++mt7996_sr_enhanced_enable_set(void *data, u64 val)
++{
++	struct mt7996_phy *phy = data;
++	int ret;
++
++	if (!!val == phy->enhanced_sr_enable)
++		return 0;
++
++	ret = mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_ENHANCE_SR_ENABLE, val, true);
++	if (ret)
++		return ret;
++
++	return mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_ENHANCE_SR_ENABLE, 0, false);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enhanced_enable, mt7996_sr_enhanced_enable_get,
++			 mt7996_sr_enhanced_enable_set, "%lld\n");
++
++static int
++mt7996_sr_stats_show(struct seq_file *file, void *data)
++{
++	struct mt7996_phy *phy = file->private;
++
++	mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_IND, 0, false);
++
++	return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(mt7996_sr_stats);
++
++static int
++mt7996_sr_scene_cond_show(struct seq_file *file, void *data)
++{
++	struct mt7996_phy *phy = file->private;
++
++	mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_SW_SD, 0, false);
++
++	return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(mt7996_sr_scene_cond);
++
+ 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)
+ 
+ 	debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
+ 
++	debugfs_create_file("sr_enable", 0600, dir, phy, &fops_sr_enable);
++	debugfs_create_file("sr_enhanced_enable", 0600, dir, phy, &fops_sr_enhanced_enable);
++	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);
++
+ 	return 0;
+ }
+ 
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index 048c534..3256de7 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)
+ 	return 0;
+ }
+ 
++int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set)
++{
++	struct {
++		u8 band_idx;
++		u8 _rsv[3];
++
++		__le16 tag;
++		__le16 len;
++
++		__le32 val;
++
++	} __packed req = {
++		.band_idx = phy->mt76->band_idx,
++
++		.tag = cpu_to_le16(action),
++		.len = cpu_to_le16(sizeof(req) - 4),
++
++		.val = cpu_to_le32((u32) val),
++	};
++
++	if (set)
++		return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SR), &req,
++					 sizeof(req), false);
++	else
++		return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD_QUERY(SR), &req,
++					 sizeof(req), false);
++}
++
++void mt7996_mcu_rx_sr_swsd(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++#define SR_SCENE_DETECTION_TIMER_PERIOD_MS 500
++	struct mt7996_mcu_sr_swsd_event *event;
++	static const char * const rules[] = {"1 - NO CONNECTED", "2 - NO CONGESTION",
++					     "3 - NO INTERFERENCE", "4 - SR ON"};
++	u8 idx;
++
++	event = (struct mt7996_mcu_sr_swsd_event *)skb->data;
++	idx = event->basic.band_idx;
++
++	dev_info(dev->mt76.dev, "Band index = %u\n", le16_to_cpu(event->basic.band_idx));
++	dev_info(dev->mt76.dev, "Hit Rule = %s\n", rules[event->tlv[idx].rule]);
++	dev_info(dev->mt76.dev, "Timer Period = %d(us)\n"
++		 "Congestion Ratio  = %d.%1d%%\n",
++		 SR_SCENE_DETECTION_TIMER_PERIOD_MS * 1000,
++		 le32_to_cpu(event->tlv[idx].total_airtime_ratio) / 10,
++		 le32_to_cpu(event->tlv[idx].total_airtime_ratio) % 10);
++	dev_info(dev->mt76.dev,
++		 "Total Airtime = %d(us)\n"
++		 "ChBusy = %d\n"
++		 "SrTx = %d\n"
++		 "OBSS = %d\n"
++		 "MyTx = %d\n"
++		 "MyRx = %d\n"
++		 "Interference Ratio = %d.%1d%%\n",
++		 le32_to_cpu(event->tlv[idx].total_airtime),
++		 le32_to_cpu(event->tlv[idx].channel_busy_time),
++		 le32_to_cpu(event->tlv[idx].sr_tx_airtime),
++		 le32_to_cpu(event->tlv[idx].obss_airtime),
++		 le32_to_cpu(event->tlv[idx].my_tx_airtime),
++		 le32_to_cpu(event->tlv[idx].my_rx_airtime),
++		 le32_to_cpu(event->tlv[idx].obss_airtime_ratio) / 10,
++		 le32_to_cpu(event->tlv[idx].obss_airtime_ratio) % 10);
++}
++
++void mt7996_mcu_rx_sr_hw_indicator(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++	struct mt7996_mcu_sr_hw_ind_event *event;
++
++	event = (struct mt7996_mcu_sr_hw_ind_event *)skb->data;
++
++	dev_info(dev->mt76.dev, "Inter PPDU Count = %u\n",
++		 le16_to_cpu(event->inter_bss_ppdu_cnt));
++	dev_info(dev->mt76.dev, "SR Valid Count = %u\n",
++		 le16_to_cpu(event->non_srg_valid_cnt));
++	dev_info(dev->mt76.dev, "SR Tx Count = %u\n",
++		 le32_to_cpu(event->sr_ampdu_mpdu_cnt));
++	dev_info(dev->mt76.dev, "SR Tx Acked Count = %u\n",
++		 le32_to_cpu(event->sr_ampdu_mpdu_acked_cnt));
++}
++
++void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++	struct mt76_phy *mphy = &dev->mt76.phy;
++	struct mt7996_phy *phy;
++	struct mt7996_mcu_sr_common_event *event;
++
++	event = (struct mt7996_mcu_sr_common_event *)skb->data;
++	mphy = dev->mt76.phys[event->basic.band_idx];
++	if (!mphy)
++		return;
++
++	phy = (struct mt7996_phy *)mphy->priv;
++
++	switch (le16_to_cpu(event->basic.tag)) {
++	case UNI_EVENT_SR_CFG_SR_ENABLE:
++		phy->sr_enable = le32_to_cpu(event->value) ? true : false;
++		break;
++	case UNI_EVENT_SR_HW_ESR_ENABLE:
++		phy->enhanced_sr_enable = le32_to_cpu(event->value) ? true : false;
++		break;
++	case UNI_EVENT_SR_SW_SD:
++		mt7996_mcu_rx_sr_swsd(dev, skb);
++		break;
++	case UNI_EVENT_SR_HW_IND:
++		mt7996_mcu_rx_sr_hw_indicator(dev, skb);
++		break;
++	default:
++		dev_info(dev->mt76.dev, "Unknown SR event tag %d\n",
++			 le16_to_cpu(event->basic.tag));
++	}
++}
+ #endif
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index 9c0db87..a5bdb88 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -104,6 +104,62 @@ enum {
+ 	EDCCA_JAPAN = 3
+ };
+ 
++enum {
++	UNI_EVENT_SR_CFG_SR_ENABLE = 0x1,
++	UNI_EVENT_SR_SW_SD = 0x83,
++	UNI_EVENT_SR_HW_IND = 0xC9,
++	UNI_EVENT_SR_HW_ESR_ENABLE = 0xD8,
++};
++enum {
++	UNI_CMD_SR_CFG_SR_ENABLE = 0x1,
++	UNI_CMD_SR_SW_SD = 0x84,
++	UNI_CMD_SR_HW_IND = 0xCB,
++	UNI_CMD_SR_HW_ENHANCE_SR_ENABLE = 0xDA,
++};
++
++struct mt7996_mcu_sr_basic_event {
++	struct mt7996_mcu_rxd rxd;
++
++	u8 band_idx;
++	u8 _rsv[3];
++
++	__le16 tag;
++	__le16 len;
++};
++
++struct sr_sd_tlv {
++	u8 _rsv[16];
++	__le32 sr_tx_airtime;
++	__le32 obss_airtime;
++	__le32 my_tx_airtime;
++	__le32 my_rx_airtime;
++	__le32 channel_busy_time;
++	__le32 total_airtime;
++	__le32 total_airtime_ratio;
++	__le32 obss_airtime_ratio;
++	u8 rule;
++	u8 _rsv2[59];
++} __packed;
++
++struct mt7996_mcu_sr_swsd_event {
++	struct mt7996_mcu_sr_basic_event basic;
++	struct sr_sd_tlv tlv[3];
++} __packed;
++
++struct mt7996_mcu_sr_common_event {
++	struct mt7996_mcu_sr_basic_event basic;
++	__le32 value;
++};
++
++struct mt7996_mcu_sr_hw_ind_event {
++	struct mt7996_mcu_sr_basic_event basic;
++	__le16 non_srg_valid_cnt;
++	u8 _rsv[4];
++	__le16 inter_bss_ppdu_cnt;
++	u8 _rsv2[4];
++	__le32 sr_ampdu_mpdu_cnt;
++	__le32 sr_ampdu_mpdu_acked_cnt;
++};
+ #endif
+ 
+ #endif
+-- 
+2.18.0
+
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/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
new file mode 100644
index 0000000..ac60aa8
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
@@ -0,0 +1,25 @@
+From d7337c25e774ed96fc8f6d1390321bfc2dcac545 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
+
+---
+ mt7996/mac.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 37cc94e..b24f237 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)
+ 		return;
+ 
+ 	tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+-	if (tid >= 6) /* skip VO queue */
+-		return;
+ 
+ 	if (is_8023)
+ 		fc = IEEE80211_FTYPE_DATA |
+-- 
+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/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch
new file mode 100644
index 0000000..9fbc586
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch
@@ -0,0 +1,144 @@
+From b69722554a27e8c13612f62c9b9cf8651a30bd8f 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
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/main.c   | 58 ++++++++++++++++++++++++++++++++++++++++++++++---
+ mt7996/mcu.c    |  6 +++--
+ mt7996/mt7996.h |  1 +
+ 3 files changed, 60 insertions(+), 5 deletions(-)
+
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 35f8fee..d27275a 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1413,6 +1413,54 @@ mt7996_twt_teardown_request(struct ieee80211_hw *hw,
+ 	mutex_unlock(&dev->mt76.mutex);
+ }
+ 
++static void
++mt7996_background_radar_handle_7975_ifem(struct ieee80211_hw *hw,
++					 struct cfg80211_chan_def *user_chandef,
++					 struct cfg80211_chan_def *fw_chandef)
++{
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct mt7996_dev *dev = phy->dev;
++	struct cfg80211_chan_def *c = user_chandef;
++	bool is_ifem_adie, expand = false;
++	u32 origin_control;
++
++	if (is_mt7996(&dev->mt76))
++		is_ifem_adie = !!(mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) % 2);
++	else
++		is_ifem_adie = (mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB_7992) == 1);
++
++	if (!user_chandef || !is_ifem_adie)
++		goto out;
++
++	if (user_chandef->width == NL80211_CHAN_WIDTH_160) {
++		origin_control = user_chandef->chan->center_freq;
++		if (dev->bg_nxt_freq)
++			goto out;
++
++		if (user_chandef->chan->flags & IEEE80211_CHAN_RADAR)
++			dev->bg_nxt_freq = origin_control;
++		else
++			c = fw_chandef;
++
++		c->chan = ieee80211_get_channel(hw->wiphy, origin_control + 80);
++	} else {
++		if (!dev->bg_nxt_freq)
++			goto out;
++
++		c->chan = ieee80211_get_channel(hw->wiphy, dev->bg_nxt_freq);
++		dev->bg_nxt_freq = 0;
++		expand = true;
++	}
++	c->width = NL80211_CHAN_WIDTH_80;
++	c->center_freq1 = c->chan->center_freq + 30;
++
++	if (c == user_chandef)
++		cfg80211_background_radar_update_channel(hw->wiphy, c, expand);
++	return;
++out:
++	dev->bg_nxt_freq = 0;
++}
++
+ 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,
+ 	struct mt7996_dev *dev = phy->dev;
+ 	int ret = -EINVAL;
+ 	bool running;
++	struct cfg80211_chan_def ifem_chandef = {};
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 
+@@ -1433,13 +1482,14 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
+ 		goto out;
+ 	}
+ 
++	mt7996_background_radar_handle_7975_ifem(hw, chandef, &ifem_chandef);
++
+ 	/* rdd2 already configured on a radar channel */
+ 	running = dev->rdd2_phy &&
+ 		  cfg80211_chandef_valid(&dev->rdd2_chandef) &&
+ 		  !!(dev->rdd2_chandef.chan->flags & IEEE80211_CHAN_RADAR);
+ 
+-	if (!chandef || running ||
+-	    !(chandef->chan->flags & IEEE80211_CHAN_RADAR)) {
++	if (!chandef || running) {
+ 		ret = mt7996_mcu_rdd_background_enable(phy, NULL);
+ 		if (ret)
+ 			goto out;
+@@ -1448,7 +1498,9 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
+ 			goto update_phy;
+ 	}
+ 
+-	ret = mt7996_mcu_rdd_background_enable(phy, chandef);
++	ret = mt7996_mcu_rdd_background_enable(phy,
++					       ifem_chandef.chan ?
++					       &ifem_chandef : chandef);
+ 	if (ret)
+ 		goto out;
+ 
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 2dbec1e..a4f3ed9 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)
+ 	if (!mphy)
+ 		return;
+ 
+-	if (r->band_idx == MT_RX_SEL2)
++	if (r->band_idx == MT_RX_SEL2) {
++		dev->bg_nxt_freq = 0;
+ 		cfg80211_background_radar_event(mphy->hw->wiphy,
+ 						&dev->rdd2_chandef,
+ 						GFP_ATOMIC);
+-	else
++	} else {
+ 		ieee80211_radar_detected(mphy->hw);
++	}
+ 	dev->hw_pattern++;
+ }
+ 
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 1fac783..413fbf7 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -392,6 +392,7 @@ struct mt7996_dev {
+ 	bool testmode_enable;
+ 	bool bin_file_mode;
+ 	u8 eeprom_mode;
++	u32 bg_nxt_freq;
+ 
+ 	bool ibf;
+ 	u8 fw_debug_wm;
+-- 
+2.18.0
+
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/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch
new file mode 100644
index 0000000..63afb2c
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch
@@ -0,0 +1,46 @@
+From fd96728a963faf55b7daba46a78aa25ab0c5f147 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
+
+---
+ 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
+--- 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)
+ 		u8 ac;
+ 		u16 wlan_idx;
+ 		struct mt76_wcid *wcid;
++		struct mt76_phy *mphy;
++		u32 tx_bytes, rx_bytes;
+ 
+ 		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)
+ 			if (!wcid)
+ 				break;
+ 
++			mphy = mt76_dev_phy(&dev->mt76, wcid->phy_idx);
+ 			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]);
++				tx_bytes = le32_to_cpu(res->adm_stat[i].tx_bytes[ac]);
++				rx_bytes = le32_to_cpu(res->adm_stat[i].rx_bytes[ac]);
++
++				wcid->stats.tx_bytes += tx_bytes;
++				wcid->stats.rx_bytes += rx_bytes;
++
++				ieee80211_tpt_led_trig_tx(mphy->hw, tx_bytes);
++				ieee80211_tpt_led_trig_rx(mphy->hw, rx_bytes);
+ 			}
+ 			break;
+ 		case UNI_ALL_STA_TXRX_MSDU_COUNT:
+-- 
+2.18.0
+
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/1025-wifi-mt76-mt7996-support-dup-wtbl.patch
new file mode 100644
index 0000000..12cdca3
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1025-wifi-mt76-mt7996-support-dup-wtbl.patch
@@ -0,0 +1,72 @@
+From a0baa183c16552ec874141c62ce3c6346d24c684 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
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Change-Id: I14ba41ace8341c23c1cfb6e9c4fbb2d5e93a5714
+---
+ mt7996/init.c    |  1 +
+ mt7996/mt7996.h  |  1 +
+ mt7996/mtk_mcu.c | 23 +++++++++++++++++++++++
+ 3 files changed, 25 insertions(+)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index ad93927..4503482 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);
+ 	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
+--- 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);
+ 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);
+ #endif
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index 3256de7..149694c 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)
+ 			 le16_to_cpu(event->basic.tag));
+ 	}
+ }
++
++int mt7996_mcu_set_dup_wtbl(struct mt7996_dev *dev)
++{
++#define CHIP_CONFIG_DUP_WTBL	4
++#define DUP_WTBL_NUM	80
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++		__le16 base;
++		__le16 num;
++		u8 _rsv2[4];
++	} __packed req = {
++		.tag = cpu_to_le16(CHIP_CONFIG_DUP_WTBL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.base = cpu_to_le16(MT7996_WTBL_STA - DUP_WTBL_NUM + 1),
++		.num = cpu_to_le16(DUP_WTBL_NUM),
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(CHIP_CONFIG), &req,
++				 sizeof(req), true);
++}
+ #endif
+-- 
+2.18.0
+
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/1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
new file mode 100644
index 0000000..354e553
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
@@ -0,0 +1,143 @@
+From b5d139f32d6f4f6476b82d59af7a96a1f57858a9 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
+
+Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
+---
+ mt7996/vendor.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h | 23 +++++++++++++++++
+ 2 files changed, 88 insertions(+)
+
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 9f333d0..dae3260 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
++ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
++	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
++};
++
+ struct mt7996_amnt_data {
+ 	u8 idx;
+ 	u8 addr[ETH_ALEN];
+@@ -556,6 +561,54 @@ mt7996_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+ 	return EDCCA_MAX_BW_NUM;
+ }
+ 
++static int mt7996_vendor_ibf_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_IBF_CTRL];
++	int err;
++	u8 val;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_IBF_CTRL_MAX, data, data_len,
++			ibf_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	if (tb[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE]) {
++		val = nla_get_u8(tb[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE]);
++
++		dev->ibf = !!val;
++
++		err = mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);
++		if (err)
++			return err;
++	}
++	return 0;
++}
++
++static int
++mt7996_vendor_ibf_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);
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct mt7996_dev *dev = phy->dev;
++
++	if (*storage == 1)
++		return -ENOENT;
++	*storage = 1;
++
++	if (nla_put_u8(skb, MTK_VENDOR_ATTR_IBF_DUMP_ENABLE, dev->ibf))
++		return -ENOMEM;
++
++	return 1;
++}
++
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 	{
+ 		.info = {
+@@ -604,6 +657,18 @@ 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_IBF_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++			WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_ibf_ctrl,
++		.dumpit = mt7996_vendor_ibf_ctrl_dump,
++		.policy = ibf_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_IBF_CTRL_MAX,
++	},
+ };
+ 
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 4465bc9..49f46f2 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_IBF_CTRL = 0xc9,
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ };
+ 
+@@ -102,4 +103,26 @@ enum mtk_vendor_attr_bss_color_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_BSS_COLOR_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
++};
++
+ #endif
+-- 
+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
new file mode 100644
index 0000000..a555c23
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1027-wifi-mt76-mt7996-add-kite-fwdl-support.patch
@@ -0,0 +1,120 @@
+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-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
new file mode 100644
index 0000000..3556945
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1028-wifi-mt76-mt7996-add-kite-eeprom-load-support.patch
@@ -0,0 +1,146 @@
+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-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
new file mode 100644
index 0000000..8b8119a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1029-wifi-mt76-mt7996-add-kite-fw-default-bin-for-differe.patch
@@ -0,0 +1,128 @@
+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-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
new file mode 100644
index 0000000..3af30bf
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1030-wifi-mt76-mt7996-add-wtbl_info-support-for-kite.patch
@@ -0,0 +1,198 @@
+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/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
similarity index 65%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
index 58605d3..d2800ea 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
@@ -1,51 +1,50 @@
-From 15b04fc966aa8f30492726132a6b81466b187581 Mon Sep 17 00:00:00 2001
+From cc82fae54b1efd7de07034bea7a883b9fb362799 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 2001/2008] wifi: mt76: revert page_poll for kernel 5.4
+Subject: [PATCH 64/98] wifi: mt76: revert page_poll for kernel 5.4
 
 This reverts commit e8c10835cf062c577ddf426913788c39d30b4bd7.
 
 Change-Id: I4e5764fc545087f691fb4c2f43e7a9cefd1e1657
 ---
- dma.c         | 78 +++++++++++++++++++++++++++++----------------------
- mac80211.c    | 57 -------------------------------------
+ dma.c         | 75 +++++++++++++++++++++++++++------------------------
+ mac80211.c    | 57 ---------------------------------------
+ mmio.c        | 56 ++++++++++++++++++++++++--------------
  mt76.h        | 22 +--------------
- mt7915/main.c | 26 +++++++----------
- mt7915/mmio.c | 55 ++++++++++++++++++++++--------------
- mt7921/main.c | 31 +++-----------------
- usb.c         | 43 ++++++++++++++--------------
- 7 files changed, 115 insertions(+), 197 deletions(-)
+ mt7915/main.c | 26 +++++++-----------
+ usb.c         | 43 ++++++++++++++---------------
+ 6 files changed, 109 insertions(+), 170 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 35db73b9..7153be47 100644
+index bb995e2..06b76ea 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -173,7 +173,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
+@@ -178,7 +178,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
  	local_bh_disable();
- 	while ((r = __mt76_get_rxwi(dev)) != NULL) {
- 		if (r->ptr)
--			mt76_put_page_pool_buf(r->ptr, false);
-+			skb_free_frag(r->ptr);
- 		kfree(r);
+ 	while ((t = __mt76_get_rxwi(dev)) != NULL) {
+ 		if (t->ptr)
+-			mt76_put_page_pool_buf(t->ptr, false);
++			skb_free_frag(t->ptr);
+ 		kfree(t);
  	}
  	local_bh_enable();
-@@ -409,9 +409,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 		if (!r)
+@@ -445,9 +445,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		if (!t)
  			return NULL;
  
--		dma_sync_single_for_cpu(dev->dma_dev, r->dma_addr,
+-		dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
 -				SKB_WITH_OVERHEAD(q->buf_size),
 -				page_pool_get_dma_dir(q->page_pool));
-+		dma_unmap_single(dev->dma_dev, r->dma_addr,
++		dma_unmap_single(dev->dma_dev, t->dma_addr,
 +				 SKB_WITH_OVERHEAD(q->buf_size),
 +				 DMA_FROM_DEVICE);
  
- 		buf = r->ptr;
- 		r->dma_addr = 0;
-@@ -430,9 +430,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		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,
+ 		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));
@@ -54,8 +53,8 @@
 +				 DMA_FROM_DEVICE);
  	}
  
- 	return buf;
-@@ -592,11 +592,11 @@ free_skb:
+ done:
+@@ -626,11 +626,11 @@ free_skb:
  }
  
  static int
@@ -70,15 +69,17 @@
  
  	if (!q->ndesc)
  		return 0;
-@@ -604,25 +604,26 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
- 	spin_lock_bh(&q->lock);
+@@ -639,28 +639,29 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
  
  	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);
 +		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
@@ -95,8 +96,9 @@
 +		}
  
 -		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) {
@@ -107,16 +109,25 @@
  			break;
  		}
  		frames++;
-@@ -666,7 +667,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -704,7 +705,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);
-@@ -714,10 +715,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)
+@@ -733,7 +734,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:
+@@ -789,10 +790,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  	if (!q->entry)
  		return -ENOMEM;
  
@@ -127,7 +138,7 @@
  	ret = mt76_dma_wed_setup(dev, q, false);
  	if (ret)
  		return ret;
-@@ -731,6 +728,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -811,6 +808,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)
  {
@@ -135,26 +146,21 @@
  	void *buf;
  	bool more;
  
-@@ -744,7 +742,10 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
- 		if (!buf)
+@@ -825,7 +823,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  			break;
  
--		mt76_put_page_pool_buf(buf, false);
-+		if (q->flags & MT_QFLAG_RRO)
-+			continue;
-+
-+		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) {
-@@ -753,6 +754,18 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -834,6 +832,16 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  	}
  
  	spin_unlock_bh(&q->lock);
 +
-+	if (((q->flags & MT_QFLAG_WED) &&
-+	     FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) ||
-+	    (q->flags & MT_QFLAG_RRO))
++	if (mt76_queue_is_wed_rx(q))
 +		return;
 +
 +	if (!q->rx_page.va)
@@ -166,16 +172,16 @@
  }
  
  static void
-@@ -773,7 +786,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+@@ -857,7 +865,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) {
+ 	if (!mt76_queue_is_wed_tx_free(q)) {
  		mt76_dma_sync_idx(dev, q);
 -		mt76_dma_rx_fill(dev, q, false);
 +		mt76_dma_rx_fill(dev, q);
  	}
  }
  
-@@ -791,7 +804,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
+@@ -875,7 +883,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 {
@@ -184,7 +190,7 @@
  	}
  
  	if (more)
-@@ -864,7 +877,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -948,7 +956,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  			goto free_frag;
  
  		skb_reserve(skb, q->buf_offset);
@@ -192,7 +198,7 @@
  
  		*(u32 *)skb->cb = info;
  
-@@ -880,10 +892,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -964,10 +971,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		continue;
  
  free_frag:
@@ -205,7 +211,7 @@
  	return done;
  }
  
-@@ -928,7 +940,7 @@ mt76_dma_init(struct mt76_dev *dev,
+@@ -1012,7 +1019,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);
@@ -214,7 +220,7 @@
  		napi_enable(&dev->napi[i]);
  	}
  
-@@ -982,8 +994,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+@@ -1067,8 +1074,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
  
  		netif_napi_del(&dev->napi[i]);
  		mt76_dma_rx_cleanup(dev, q);
@@ -224,7 +230,7 @@
  
  	if (mtk_wed_device_active(&dev->mmio.wed))
 diff --git a/mac80211.c b/mac80211.c
-index 5a203d31..f7578308 100644
+index 9c582cb..3715c73 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -4,7 +4,6 @@
@@ -235,7 +241,7 @@
  #include "mt76.h"
  
  static const struct ieee80211_channel mt76_channels_2ghz[] = {
-@@ -542,47 +541,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
+@@ -546,47 +545,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
  }
  EXPORT_SYMBOL_GPL(mt76_unregister_phy);
  
@@ -283,7 +289,7 @@
  struct mt76_dev *
  mt76_alloc_device(struct device *pdev, unsigned int size,
  		  const struct ieee80211_ops *ops,
-@@ -1728,21 +1686,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
+@@ -1786,21 +1744,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  }
  EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
  
@@ -305,11 +311,111 @@
  enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy)
  {
  	struct ieee80211_hw *hw = phy->hw;
+diff --git a/mmio.c b/mmio.c
+index c346249..5fb8392 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,33 +118,45 @@ 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)
+-			goto unmap;
++		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);
++		phy_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))) {
++			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);
+ 		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;
+ 		}
+ 
+@@ -150,8 +168,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 72c3eb8f..a0c20d36 100644
+index d59a1f5..3af97e5 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -224,7 +224,7 @@ struct mt76_queue {
+@@ -245,7 +245,7 @@ struct mt76_queue {
  
  	dma_addr_t desc_dma;
  	struct sk_buff *rx_head;
@@ -318,7 +424,7 @@
  };
  
  struct mt76_mcu_ops {
-@@ -1410,7 +1410,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
+@@ -1566,7 +1566,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);
  }
  
@@ -326,10 +432,10 @@
  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);
-@@ -1523,25 +1522,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
- struct mt76_rxwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
+@@ -1707,25 +1706,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_rxwi_cache *r, dma_addr_t phys);
+ 			  struct mt76_txwi_cache *r, dma_addr_t phys);
 -int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q);
 -static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
 -{
@@ -353,21 +459,21 @@
  static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
  {
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 8ce7b1c5..fbff908f 100644
+index ba34c8e..4c80473 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1289,22 +1289,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
+@@ -1397,22 +1397,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
  			   struct ieee80211_vif *vif,
  			   u32 sset, u8 *data)
  {
 -	if (sset != ETH_SS_STATS)
 -		return;
 -
--	memcpy(data, *mt7915_gstrings_stats, sizeof(mt7915_gstrings_stats));
+-	memcpy(data, mt7915_gstrings_stats, sizeof(mt7915_gstrings_stats));
 -	data += sizeof(mt7915_gstrings_stats);
 -	page_pool_ethtool_stats_get_strings(data);
 +	if (sset == ETH_SS_STATS)
-+		memcpy(data, *mt7915_gstrings_stats,
++		memcpy(data, mt7915_gstrings_stats,
 +		       sizeof(mt7915_gstrings_stats));
  }
  
@@ -385,16 +491,16 @@
  }
  
  static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
-@@ -1332,7 +1329,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1440,7 +1437,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+ 		.idx = mvif->mt76.idx,
  	};
- 	struct mib_stats *mib = &phy->mib;
  	/* See mt7915_ampdu_stat_read_phy, etc */
 -	int i, ei = 0, stats_size;
 +	int i, ei = 0;
  
  	mutex_lock(&dev->mt76.mutex);
  
-@@ -1413,12 +1410,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1552,12 +1549,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
  		return;
  
  	ei += wi.worker_stat_count;
@@ -410,178 +516,8 @@
  }
  
  static void
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 46256842..8ff2c70c 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -596,9 +596,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_rxwi_cache *r;
- 
-@@ -606,7 +610,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- 		if (!r || !r->ptr)
- 			continue;
- 
--		mt76_put_page_pool_buf(r->ptr, false);
-+		dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
-+				 wed->wlan.rx_size, DMA_FROM_DEVICE);
-+		__free_pages(virt_to_page(r->ptr), get_order(length));
- 		r->ptr = NULL;
- 
- 		mt76_put_rxwi(&dev->mt76, r);
-@@ -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_rxwi_cache *r = 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, r);
- 			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, r);
-+			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, r, 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, r);
- 			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/mt7921/main.c b/mt7921/main.c
-index 3b6adb29..47eb38e4 100644
---- a/mt7921/main.c
-+++ b/mt7921/main.c
-@@ -1083,34 +1083,17 @@ static void
- mt7921_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 		      u32 sset, u8 *data)
- {
--	struct mt7921_dev *dev = mt7921_hw_dev(hw);
--
- 	if (sset != ETH_SS_STATS)
- 		return;
- 
- 	memcpy(data, *mt7921_gstrings_stats, sizeof(mt7921_gstrings_stats));
--
--	if (mt76_is_sdio(&dev->mt76))
--		return;
--
--	data += sizeof(mt7921_gstrings_stats);
--	page_pool_ethtool_stats_get_strings(data);
- }
- 
- static int
- mt7921_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			 int sset)
- {
--	struct mt7921_dev *dev = mt7921_hw_dev(hw);
--
--	if (sset != ETH_SS_STATS)
--		return 0;
--
--	if (mt76_is_sdio(&dev->mt76))
--		return ARRAY_SIZE(mt7921_gstrings_stats);
--
--	return ARRAY_SIZE(mt7921_gstrings_stats) +
--	       page_pool_ethtool_stats_get_count();
-+	return sset == ETH_SS_STATS ? ARRAY_SIZE(mt7921_gstrings_stats) : 0;
- }
- 
- static void
-@@ -1130,7 +1113,6 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			 struct ethtool_stats *stats, u64 *data)
- {
- 	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
--	int stats_size = ARRAY_SIZE(mt7921_gstrings_stats);
- 	struct mt7921_phy *phy = mt7921_hw_phy(hw);
- 	struct mt7921_dev *dev = phy->dev;
- 	struct mib_stats *mib = &phy->mib;
-@@ -1186,14 +1168,9 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 		return;
- 
- 	ei += wi.worker_stat_count;
--
--	if (!mt76_is_sdio(&dev->mt76)) {
--		mt76_ethtool_page_pool_stats(&dev->mt76, &data[ei], &ei);
--		stats_size += page_pool_ethtool_stats_get_count();
--	}
--
--	if (ei != stats_size)
--		dev_err(dev->mt76.dev, "ei: %d  SSTATS_LEN: %d", ei, stats_size);
-+	if (ei != ARRAY_SIZE(mt7921_gstrings_stats))
-+		dev_err(dev->mt76.dev, "ei: %d  SSTATS_LEN: %zu",
-+			ei, ARRAY_SIZE(mt7921_gstrings_stats));
- }
- 
- static u64
 diff --git a/usb.c b/usb.c
-index 5e5c7bf5..3e281715 100644
+index 5e5c7bf..3e28171 100644
 --- a/usb.c
 +++ b/usb.c
 @@ -319,27 +319,29 @@ mt76u_set_endpoints(struct usb_interface *intf,
@@ -715,5 +651,5 @@
  
  static void mt76u_free_rx(struct mt76_dev *dev)
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-rework-wed-rx-flow.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-rework-wed-rx-flow.patch
deleted file mode 100644
index 050c6f2..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-rework-wed-rx-flow.patch
+++ /dev/null
@@ -1,443 +0,0 @@
-From 06c6ad7b99c07aedc5403506c91cbb8e11cf95df 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 2000/2008] wifi: mt76: rework wed rx flow
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Change-Id: Icd787345c811cb5ad30d9c7c1c5f9e5298bd3be6
----
- dma.c           | 89 +++++++++++++++++++++++++------------------------
- mac80211.c      |  2 +-
- mt76.h          | 23 ++++++++-----
- mt7915/dma.c    |  2 --
- mt7915/mmio.c   | 27 +++++++++++----
- mt7915/mt7915.h |  1 +
- tx.c            | 16 ++++-----
- 7 files changed, 90 insertions(+), 70 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index e1e9062b..35db73b9 100644
---- a/dma.c
-+++ b/dma.c
-@@ -59,17 +59,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
- 	return t;
- }
- 
--static struct mt76_txwi_cache *
-+static struct mt76_rxwi_cache *
- mt76_alloc_rxwi(struct mt76_dev *dev)
- {
--	struct mt76_txwi_cache *t;
-+	struct mt76_rxwi_cache *r;
- 
--	t = kzalloc(L1_CACHE_ALIGN(sizeof(*t)), GFP_ATOMIC);
--	if (!t)
-+	r = kzalloc(L1_CACHE_ALIGN(sizeof(*r)), GFP_ATOMIC);
-+	if (!r)
- 		return NULL;
- 
--	t->ptr = NULL;
--	return t;
-+	r->ptr = NULL;
-+	return r;
- }
- 
- static struct mt76_txwi_cache *
-@@ -88,20 +88,20 @@ __mt76_get_txwi(struct mt76_dev *dev)
- 	return t;
- }
- 
--static struct mt76_txwi_cache *
-+static struct mt76_rxwi_cache *
- __mt76_get_rxwi(struct mt76_dev *dev)
- {
--	struct mt76_txwi_cache *t = NULL;
-+	struct mt76_rxwi_cache *r = NULL;
- 
--	spin_lock(&dev->wed_lock);
-+	spin_lock(&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,
- 				     list);
--		list_del(&t->list);
-+		list_del(&r->list);
- 	}
--	spin_unlock(&dev->wed_lock);
-+	spin_unlock(&dev->lock);
- 
--	return t;
-+	return r;
- }
- 
- static struct mt76_txwi_cache *
-@@ -115,13 +115,13 @@ mt76_get_txwi(struct mt76_dev *dev)
- 	return mt76_alloc_txwi(dev);
- }
- 
--struct mt76_txwi_cache *
-+struct mt76_rxwi_cache *
- mt76_get_rxwi(struct mt76_dev *dev)
- {
--	struct mt76_txwi_cache *t = __mt76_get_rxwi(dev);
-+	struct mt76_rxwi_cache *r = __mt76_get_rxwi(dev);
- 
--	if (t)
--		return t;
-+	if (r)
-+		return r;
- 
- 	return mt76_alloc_rxwi(dev);
- }
-@@ -140,14 +140,14 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
- EXPORT_SYMBOL_GPL(mt76_put_txwi);
- 
- void
--mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
-+mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r)
- {
--	if (!t)
-+	if (!r)
- 		return;
- 
--	spin_lock(&dev->wed_lock);
--	list_add(&t->list, &dev->rxwi_cache);
--	spin_unlock(&dev->wed_lock);
-+	spin_lock(&dev->lock);
-+	list_add(&r->list, &dev->rxwi_cache);
-+	spin_unlock(&dev->lock);
- }
- EXPORT_SYMBOL_GPL(mt76_put_rxwi);
- 
-@@ -168,13 +168,13 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
- void
- mt76_free_pending_rxwi(struct mt76_dev *dev)
- {
--	struct mt76_txwi_cache *t;
-+	struct mt76_rxwi_cache *r;
- 
- 	local_bh_disable();
--	while ((t = __mt76_get_rxwi(dev)) != NULL) {
--		if (t->ptr)
--			mt76_put_page_pool_buf(t->ptr, false);
--		kfree(t);
-+	while ((r = __mt76_get_rxwi(dev)) != NULL) {
-+		if (r->ptr)
-+			mt76_put_page_pool_buf(r->ptr, false);
-+		kfree(r);
- 	}
- 	local_bh_enable();
- }
-@@ -212,7 +212,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- {
- 	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;
- 	int idx = q->head;
- 	int rx_token;
-@@ -220,13 +220,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);
- 
- 	if (mt76_queue_is_wed_rx(q)) {
--		txwi = mt76_get_rxwi(dev);
--		if (!txwi)
-+		rxwi = mt76_get_rxwi(dev);
-+		if (!rxwi)
- 			return -ENOMEM;
- 
--		rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr);
-+		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
- 		if (rx_token < 0) {
--			mt76_put_rxwi(dev, txwi);
-+			mt76_put_rxwi(dev, rxwi);
- 			return -ENOMEM;
- 		}
- 
-@@ -241,7 +241,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 
- 	entry->dma_addr[0] = buf->addr;
- 	entry->dma_len[0] = buf->len;
--	entry->txwi = txwi;
-+	entry->rxwi = rxwi;
- 	entry->buf = data;
- 	entry->wcid = 0xffff;
- 	entry->skip_buf1 = true;
-@@ -404,20 +404,20 @@ 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);
- 
--		if (!t)
-+		if (!r)
- 			return NULL;
- 
--		dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
-+		dma_sync_single_for_cpu(dev->dma_dev, r->dma_addr,
- 				SKB_WITH_OVERHEAD(q->buf_size),
- 				page_pool_get_dma_dir(q->page_pool));
- 
--		buf = t->ptr;
--		t->dma_addr = 0;
--		t->ptr = NULL;
-+		buf = r->ptr;
-+		r->dma_addr = 0;
-+		r->ptr = NULL;
- 
--		mt76_put_rxwi(dev, t);
-+		mt76_put_rxwi(dev, r);
- 
- 		if (drop) {
- 			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
-@@ -977,16 +977,19 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
- 	mt76_for_each_q_rx(dev, i) {
- 		struct mt76_queue *q = &dev->q_rx[i];
- 
-+		if (mt76_queue_is_wed_rx(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);
-+
-+	mt76_free_pending_txwi(dev);
-+	mt76_free_pending_rxwi(dev);
- }
- EXPORT_SYMBOL_GPL(mt76_dma_cleanup);
-diff --git a/mac80211.c b/mac80211.c
-index 6430e6ee..5a203d31 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -613,7 +613,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);
--	spin_lock_init(&dev->wed_lock);
- 	mutex_init(&dev->mutex);
- 	init_waitqueue_head(&dev->tx_wait);
- 
-@@ -644,6 +643,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;
-+	dev->rx_token_size = dev->drv->rx_token_size;
- 
- 	for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
- 		skb_queue_head_init(&dev->rx_skb[i]);
-diff --git a/mt76.h b/mt76.h
-index 8abb6f41..72c3eb8f 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -180,6 +180,7 @@ struct mt76_queue_entry {
- 	};
- 	union {
- 		struct mt76_txwi_cache *txwi;
-+		struct mt76_rxwi_cache *rxwi;
- 		struct urb *urb;
- 		int buf_sz;
- 	};
-@@ -371,10 +372,14 @@ struct mt76_txwi_cache {
- 	struct list_head list;
- 	dma_addr_t dma_addr;
- 
--	union {
--		struct sk_buff *skb;
--		void *ptr;
--	};
-+	struct sk_buff *skb;
-+};
-+
-+struct mt76_rxwi_cache {
-+	struct list_head list;
-+	dma_addr_t dma_addr;
-+
-+	void *ptr;
- };
- 
- struct mt76_rx_tid {
-@@ -460,6 +465,7 @@ struct mt76_driver_ops {
- 	u16 txwi_size;
- 	u16 token_size;
- 	u8 mcs_rates;
-+	u16 rx_token_size;
- 
- 	void (*update_survey)(struct mt76_phy *phy);
- 
-@@ -810,7 +816,6 @@ struct mt76_dev {
- 
- 	struct ieee80211_hw *hw;
- 
--	spinlock_t wed_lock;
- 	spinlock_t lock;
- 	spinlock_t cc_lock;
- 
-@@ -1360,8 +1365,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);
--void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
--struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
-+void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r);
-+struct mt76_rxwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
- 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);
-@@ -1515,9 +1520,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);
--struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
-+struct mt76_rxwi_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);
-+			  struct mt76_rxwi_cache *r, dma_addr_t phys);
- int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q);
- static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
- {
-diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 86a93ded..848e9843 100644
---- a/mt7915/dma.c
-+++ b/mt7915/dma.c
-@@ -493,7 +493,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 =
- 				MT_WED_Q_RX(MT7915_RXQ_BAND0);
--			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
- 		}
- 
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
-@@ -530,7 +529,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 =
- 				MT_WED_Q_RX(MT7915_RXQ_BAND1);
--			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
- 		}
- 
- 		/* rx data queue for band1 */
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 984b5f60..46256842 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -600,16 +600,28 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- 
- 	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;
-+		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;
- 
--		mt76_put_page_pool_buf(t->ptr, false);
--		t->ptr = NULL;
-+		mt76_put_page_pool_buf(r->ptr, false);
-+		r->ptr = NULL;
- 
--		mt76_put_rxwi(&dev->mt76, t);
-+		mt76_put_rxwi(&dev->mt76, r);
-+	}
-+
-+	mt76_for_each_q_rx(dev, i) {
-+		struct mt76_queue *q = &dev->q_rx[i];
-+
-+		if (!mt76_queue_is_wed_rx(q))
-+			continue;
-+
-+		netif_napi_del(&dev->napi[i]);
-+		mt76_dma_rx_cleanup(dev, q);
-+
-+		page_pool_destroy(q->page_pool);
- 	}
- 
- 	mt76_free_pending_rxwi(&dev->mt76);
-@@ -812,7 +824,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;
- 
--	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;
-@@ -1018,6 +1030,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
- 				SURVEY_INFO_TIME_RX |
- 				SURVEY_INFO_TIME_BSS_RX,
- 		.token_size = MT7915_TOKEN_SIZE,
-+		.rx_token_size = MT7915_RX_TOKEN_SIZE;
- 		.tx_prepare_skb = mt7915_tx_prepare_skb,
- 		.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 103cd0d7..8ee62f63 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -62,6 +62,7 @@
- #define MT7915_EEPROM_BLOCK_SIZE	16
- #define MT7915_HW_TOKEN_SIZE		4096
- #define MT7915_TOKEN_SIZE		8192
-+#define MT7915_RX_TOKEN_SIZE		4096
- 
- #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 72b3ec71..6cb71f34 100644
---- a/tx.c
-+++ b/tx.c
-@@ -761,16 +761,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,
--			  struct mt76_txwi_cache *t, dma_addr_t phys)
-+			  struct mt76_rxwi_cache *r, dma_addr_t phys)
- {
- 	int token;
- 
- 	spin_lock_bh(&dev->rx_token_lock);
--	token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size,
-+	token = idr_alloc(&dev->rx_token, r, 0, dev->rx_token_size,
- 			  GFP_ATOMIC);
- 	if (token >= 0) {
--		t->ptr = ptr;
--		t->dma_addr = phys;
-+		r->ptr = ptr;
-+		r->dma_addr = phys;
- 	}
- 	spin_unlock_bh(&dev->rx_token_lock);
- 
-@@ -807,15 +807,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
- }
- EXPORT_SYMBOL_GPL(mt76_token_release);
- 
--struct mt76_txwi_cache *
-+struct mt76_rxwi_cache *
- mt76_rx_token_release(struct mt76_dev *dev, int token)
- {
--	struct mt76_txwi_cache *t;
-+	struct mt76_rxwi_cache *r;
- 
- 	spin_lock_bh(&dev->rx_token_lock);
--	t = idr_remove(&dev->rx_token, token);
-+	r = idr_remove(&dev->rx_token, token);
- 	spin_unlock_bh(&dev->rx_token_lock);
- 
--	return t;
-+	return r;
- }
- EXPORT_SYMBOL_GPL(mt76_rx_token_release);
--- 
-2.39.2
-
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-wifi-mt76-rework-wed-rx-flow.patch
new file mode 100644
index 0000000..a0854af
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-rework-wed-rx-flow.patch
@@ -0,0 +1,539 @@
+From 78b8b86fce85c8ff6fad935bd9bd8b2df0e151ab 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
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+Change-Id: Icd787345c811cb5ad30d9c7c1c5f9e5298bd3be6
+---
+ dma.c           | 125 +++++++++++++++++++++++++++++++-----------------
+ mac80211.c      |   2 +-
+ mmio.c          |  58 ++++++++++++++--------
+ mt76.h          |  23 +++++----
+ mt7915/mmio.c   |   3 +-
+ mt7915/mt7915.h |   1 +
+ tx.c            |  16 +++----
+ 7 files changed, 143 insertions(+), 85 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 06b76ea..f48ec57 100644
+--- a/dma.c
++++ b/dma.c
+@@ -64,17 +64,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
+ 	return t;
+ }
+ 
+-static struct mt76_txwi_cache *
++static struct mt76_rxwi_cache *
+ mt76_alloc_rxwi(struct mt76_dev *dev)
+ {
+-	struct mt76_txwi_cache *t;
++	struct mt76_rxwi_cache *r;
+ 
+-	t = kzalloc(L1_CACHE_ALIGN(sizeof(*t)), GFP_ATOMIC);
+-	if (!t)
++	r = kzalloc(L1_CACHE_ALIGN(sizeof(*r)), GFP_ATOMIC);
++	if (!r)
+ 		return NULL;
+ 
+-	t->ptr = NULL;
+-	return t;
++	r->ptr = NULL;
++	return r;
+ }
+ 
+ static struct mt76_txwi_cache *
+@@ -93,20 +93,20 @@ __mt76_get_txwi(struct mt76_dev *dev)
+ 	return t;
+ }
+ 
+-static struct mt76_txwi_cache *
++static struct mt76_rxwi_cache *
+ __mt76_get_rxwi(struct mt76_dev *dev)
+ {
+-	struct mt76_txwi_cache *t = NULL;
++	struct mt76_rxwi_cache *r = NULL;
+ 
+-	spin_lock(&dev->wed_lock);
++	spin_lock(&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,
+ 				     list);
+-		list_del(&t->list);
++		list_del(&r->list);
+ 	}
+-	spin_unlock(&dev->wed_lock);
++	spin_unlock(&dev->lock);
+ 
+-	return t;
++	return r;
+ }
+ 
+ static struct mt76_txwi_cache *
+@@ -120,13 +120,13 @@ mt76_get_txwi(struct mt76_dev *dev)
+ 	return mt76_alloc_txwi(dev);
+ }
+ 
+-struct mt76_txwi_cache *
++struct mt76_rxwi_cache *
+ mt76_get_rxwi(struct mt76_dev *dev)
+ {
+-	struct mt76_txwi_cache *t = __mt76_get_rxwi(dev);
++	struct mt76_rxwi_cache *r = __mt76_get_rxwi(dev);
+ 
+-	if (t)
+-		return t;
++	if (r)
++		return r;
+ 
+ 	return mt76_alloc_rxwi(dev);
+ }
+@@ -145,14 +145,14 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+ EXPORT_SYMBOL_GPL(mt76_put_txwi);
+ 
+ void
+-mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
++mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r)
+ {
+-	if (!t)
++	if (!r)
+ 		return;
+ 
+-	spin_lock(&dev->wed_lock);
+-	list_add(&t->list, &dev->rxwi_cache);
+-	spin_unlock(&dev->wed_lock);
++	spin_lock(&dev->lock);
++	list_add(&r->list, &dev->rxwi_cache);
++	spin_unlock(&dev->lock);
+ }
+ EXPORT_SYMBOL_GPL(mt76_put_rxwi);
+ 
+@@ -173,13 +173,13 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
+ void
+ mt76_free_pending_rxwi(struct mt76_dev *dev)
+ {
+-	struct mt76_txwi_cache *t;
++	struct mt76_rxwi_cache *r;
+ 
+ 	local_bh_disable();
+-	while ((t = __mt76_get_rxwi(dev)) != NULL) {
+-		if (t->ptr)
+-			skb_free_frag(t->ptr);
+-		kfree(t);
++	while ((r = __mt76_get_rxwi(dev)) != NULL) {
++		if (r->ptr)
++			skb_free_frag(r->ptr);
++		kfree(r);
+ 	}
+ 	local_bh_enable();
+ }
+@@ -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,
+-		    struct mt76_queue_buf *buf, void *data)
++		    struct mt76_queue_buf *buf, void *data,
++		    struct mt76_rxwi_cache *rxwi)
+ {
+ 	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);
+ 
+ 	if (mt76_queue_is_wed_rx(q)) {
+-		txwi = mt76_get_rxwi(dev);
+-		if (!txwi)
+-			return -ENOMEM;
++		if (!rxwi) {
++			rxwi = mt76_get_rxwi(dev);
++			if (!rxwi)
++				return -ENOMEM;
++		}
+ 
+-		rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr);
++		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
+ 		if (rx_token < 0) {
+-			mt76_put_rxwi(dev, txwi);
++			mt76_put_rxwi(dev, rxwi);
+ 			return -ENOMEM;
+ 		}
+ 
+@@ -270,7 +272,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;
++	entry->rxwi = rxwi;
+ 	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)
+ 
+ static void *
+ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+-		 int *len, u32 *info, bool *more, bool *drop)
++		 int *len, u32 *info, bool *more, bool *drop, bool flush)
+ {
+ 	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,
+ 	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);
+ 
+-		if (!t)
++		if (!r)
+ 			return NULL;
+ 
+-		dma_unmap_single(dev->dma_dev, t->dma_addr,
++		dma_unmap_single(dev->dma_dev, r->dma_addr,
+ 				 SKB_WITH_OVERHEAD(q->buf_size),
+ 				 DMA_FROM_DEVICE);
+ 
+-		buf = t->ptr;
+-		t->dma_addr = 0;
+-		t->ptr = NULL;
++		if (flush) {
++			buf = r->ptr;
++			r->dma_addr = 0;
++			r->ptr = NULL;
++
++			mt76_put_rxwi(dev, r);
++		} else {
++			struct mt76_queue_buf qbuf;
++
++			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++			if (!buf)
++				return NULL;
++
++			memcpy(buf, r->ptr, SKB_WITH_OVERHEAD(q->buf_size));
++
++			r->dma_addr = dma_map_single(dev->dma_dev, r->ptr,
++						     SKB_WITH_OVERHEAD(q->buf_size),
++						     DMA_FROM_DEVICE);
++			if (unlikely(dma_mapping_error(dev->dma_dev, r->dma_addr))) {
++				skb_free_frag(r->ptr);
++				mt76_put_rxwi(dev, r);
++				return NULL;
++			}
++
++			qbuf.addr = r->dma_addr;
++			qbuf.len = SKB_WITH_OVERHEAD(q->buf_size);
++			qbuf.skip_unmap = false;
++
++			if (mt76_dma_add_rx_buf(dev, q, &qbuf, r->ptr, r) < 0) {
++				dma_unmap_single(dev->dma_dev, r->dma_addr,
++						 SKB_WITH_OVERHEAD(q->buf_size),
++						 DMA_FROM_DEVICE);
++				skb_free_frag(r->ptr);
++				mt76_put_rxwi(dev, r);
++				return NULL;
++			}
++		}
+ 
+-		mt76_put_rxwi(dev, t);
+ 		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,
+ 	q->tail = (q->tail + 1) % q->ndesc;
+ 	q->queued--;
+ 
+-	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop);
++	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush);
+ }
+ 
+ static int
+@@ -658,7 +693,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) {
++		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf, NULL) < 0) {
+ 			dma_unmap_single(dev->dma_dev, addr, len,
+ 					 DMA_FROM_DEVICE);
+ 			skb_free_frag(buf);
+diff --git a/mac80211.c b/mac80211.c
+index 3715c73..4552bc2 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -575,7 +575,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);
+-	spin_lock_init(&dev->wed_lock);
+ 	mutex_init(&dev->mutex);
+ 	init_waitqueue_head(&dev->tx_wait);
+ 
+@@ -608,6 +607,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;
++	dev->rx_token_size = dev->drv->rx_token_size;
+ 
+ 	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
+--- a/mmio.c
++++ b/mmio.c
+@@ -89,28 +89,45 @@ 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;
++	struct page *page;
+ 	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;
++		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;
++		skb_free_frag(r->ptr);
++		r->ptr = NULL;
+ 
+-		mt76_put_rxwi(dev, t);
++		mt76_put_rxwi(dev, r);
+ 	}
+ 
+ 	mt76_free_pending_rxwi(dev);
++
++	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)
++				continue;
++
++			page = virt_to_page(q->rx_page.va);
++			__page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
++			memset(&q->rx_page, 0, sizeof(q->rx_page));
++		}
++	}
++
++	if (!wed->rx_buf_ring.rx_page.va)
++		return;
++
++	page = virt_to_page(wed->rx_buf_ring.rx_page.va);
++	__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);
+ 
+@@ -125,18 +142,17 @@ 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);
++		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length, GFP_ATOMIC);
++		if (!ptr) {
++			mt76_put_rxwi(dev, r);
+  			goto unmap;
+ 		}
+ 
+@@ -146,17 +162,17 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 
+ 		if (unlikely(dma_mapping_error(dev->dev, phy_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);
+ 		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);
++			skb_free_frag(ptr);
++			mt76_put_rxwi(dev, r);
+ 			goto unmap;
+ 		}
+ 
+diff --git a/mt76.h b/mt76.h
+index 3af97e5..b960f3d 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -200,6 +200,7 @@ struct mt76_queue_entry {
+ 	};
+ 	union {
+ 		struct mt76_txwi_cache *txwi;
++		struct mt76_rxwi_cache *rxwi;
+ 		struct urb *urb;
+ 		int buf_sz;
+ 	};
+@@ -410,10 +411,14 @@ struct mt76_txwi_cache {
+ 	struct list_head list;
+ 	dma_addr_t dma_addr;
+ 
+-	union {
+-		struct sk_buff *skb;
+-		void *ptr;
+-	};
++	struct sk_buff *skb;
++};
++
++struct mt76_rxwi_cache {
++	struct list_head list;
++	dma_addr_t dma_addr;
++
++	void *ptr;
+ };
+ 
+ struct mt76_rx_tid {
+@@ -499,6 +504,7 @@ struct mt76_driver_ops {
+ 	u16 txwi_size;
+ 	u16 token_size;
+ 	u8 mcs_rates;
++	u16 rx_token_size;
+ 
+ 	void (*update_survey)(struct mt76_phy *phy);
+ 
+@@ -858,7 +864,6 @@ struct mt76_dev {
+ 
+ 	struct ieee80211_hw *hw;
+ 
+-	spinlock_t wed_lock;
+ 	spinlock_t lock;
+ 	spinlock_t cc_lock;
+ 
+@@ -1521,8 +1526,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);
+-void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
+-struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
++void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r);
++struct mt76_rxwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
+ 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 *
+ 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);
+-struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
++struct mt76_rxwi_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);
++			  struct mt76_rxwi_cache *r, dma_addr_t phys);
+ 
+ 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
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -687,7 +687,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;
+ 
+-	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,
+ 				SURVEY_INFO_TIME_RX |
+ 				SURVEY_INFO_TIME_BSS_RX,
+ 		.token_size = MT7915_TOKEN_SIZE,
++		.rx_token_size = MT7915_RX_TOKEN_SIZE;
+ 		.tx_prepare_skb = mt7915_tx_prepare_skb,
+ 		.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
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -62,6 +62,7 @@
+ #define MT7915_EEPROM_BLOCK_SIZE	16
+ #define MT7915_HW_TOKEN_SIZE		4096
+ #define MT7915_TOKEN_SIZE		8192
++#define MT7915_RX_TOKEN_SIZE		4096
+ 
+ #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
+--- a/tx.c
++++ b/tx.c
+@@ -843,16 +843,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,
+-			  struct mt76_txwi_cache *t, dma_addr_t phys)
++			  struct mt76_rxwi_cache *r, dma_addr_t phys)
+ {
+ 	int token;
+ 
+ 	spin_lock_bh(&dev->rx_token_lock);
+-	token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size,
++	token = idr_alloc(&dev->rx_token, r, 0, dev->rx_token_size,
+ 			  GFP_ATOMIC);
+ 	if (token >= 0) {
+-		t->ptr = ptr;
+-		t->dma_addr = phys;
++		r->ptr = ptr;
++		r->dma_addr = phys;
+ 	}
+ 	spin_unlock_bh(&dev->rx_token_lock);
+ 
+@@ -889,15 +889,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
+ }
+ EXPORT_SYMBOL_GPL(mt76_token_release);
+ 
+-struct mt76_txwi_cache *
++struct mt76_rxwi_cache *
+ mt76_rx_token_release(struct mt76_dev *dev, int token)
+ {
+-	struct mt76_txwi_cache *t;
++	struct mt76_rxwi_cache *r;
+ 
+ 	spin_lock_bh(&dev->rx_token_lock);
+-	t = idr_remove(&dev->rx_token, token);
++	r = idr_remove(&dev->rx_token, token);
+ 	spin_unlock_bh(&dev->rx_token_lock);
+ 
+-	return t;
++	return r;
+ }
+ EXPORT_SYMBOL_GPL(mt76_rx_token_release);
+-- 
+2.18.0
+
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-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
index 21f5e83..3dc3543 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-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
@@ -1,8 +1,8 @@
-From 2ced3e3d33ef919332226f09a214ef2b04555a6d Mon Sep 17 00:00:00 2001
+From 1c0cb4fc09293006efdf8d1a9e92715a5705c29e 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 2002/2008] wifi: mt76: wed: change wed token init size to
- adapt wed3.0
+Subject: [PATCH 66/98] 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 6cb71f34..618c99a1 100644
+index 74bf0de..3857c2a 100644
 --- a/tx.c
 +++ b/tx.c
-@@ -737,12 +737,16 @@ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
+@@ -819,12 +819,16 @@ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
  
  int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
  {
@@ -34,5 +34,5 @@
  
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2006-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
similarity index 82%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2006-wifi-mt76-add-random-early-drop-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-add-random-early-drop-support.patch
index 7902639..e21fa8b 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2006-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
@@ -1,19 +1,19 @@
-From fba98d69dcbbbcbd4cbf61e997637ecead9e55a3 Mon Sep 17 00:00:00 2001
+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 2006/2008] wifi: mt76: add random early drop support
+Subject: [PATCH 67/98] wifi: mt76: add random early drop support
 
 ---
- mt7996/mcu.c    | 77 +++++++++++++++++++++++++++++++++++++++++++++++--
+ mt7996/mcu.c    | 81 +++++++++++++++++++++++++++++++++++++++++++++++--
  mt7996/mcu.h    |  4 ++-
  mt7996/mt7996.h |  1 +
- 3 files changed, 79 insertions(+), 3 deletions(-)
+ 3 files changed, 83 insertions(+), 3 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 1891c0d7..0c01e90b 100644
+index b8d26ec..6589610 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2933,8 +2933,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev)
+@@ -3012,8 +3012,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -24,7 +24,7 @@
  }
  
  int mt7996_mcu_init(struct mt7996_dev *dev)
-@@ -2966,6 +2966,79 @@ out:
+@@ -3045,6 +3045,83 @@ out:
  	skb_queue_purge(&dev->mt76.mcu.res_q);
  }
  
@@ -64,6 +64,10 @@
 +		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);
 +}
@@ -105,10 +109,10 @@
  {
  	struct {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index a0cbf922..ec074bc6 100644
+index bb876f3..666216a 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -239,8 +239,9 @@ enum {
+@@ -287,8 +287,9 @@ enum {
  enum {
  	MCU_WA_PARAM_PDMA_RX = 0x04,
  	MCU_WA_PARAM_CPU_UTIL = 0x0b,
@@ -119,7 +123,7 @@
  };
  
  enum mcu_mmps_mode {
-@@ -695,6 +696,7 @@ enum {
+@@ -817,6 +818,7 @@ enum {
  	UNI_VOW_DRR_CTRL,
  	UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
  	UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
@@ -128,10 +132,10 @@
  
  enum {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 836c7db7..b239c44c 100644
+index 6775360..bba1364 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -671,6 +671,7 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
+@@ -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);
@@ -140,5 +144,5 @@
  int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
  int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch
deleted file mode 100644
index feb77a6..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch
+++ /dev/null
@@ -1,995 +0,0 @@
-From d9167faacb2a8466e2d19993f29b2c0770c5164e Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Wed, 26 Apr 2023 16:44:57 +0800
-Subject: [PATCH 2003/2008] wifi: mt76: mt7996: wed: add wed3.0 tx support
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- dma.c           |  17 ++-
- mt76.h          |   7 ++
- mt7996/dma.c    | 128 ++++++++++++++++++---
- mt7996/init.c   |  21 +++-
- mt7996/mac.c    |  29 ++++-
- mt7996/main.c   |  46 ++++++++
- mt7996/mmio.c   | 295 +++++++++++++++++++++++++++++++++++++++++++++---
- mt7996/mt7996.h |   8 +-
- mt7996/pci.c    |  72 +++++++++---
- mt7996/regs.h   |   5 +
- 10 files changed, 567 insertions(+), 61 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 7153be47..930ec768 100644
---- a/dma.c
-+++ b/dma.c
-@@ -13,6 +13,11 @@
- 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
- 	u32 _val;							\
- 	if ((_q)->flags & MT_QFLAG_WED)					\
-+		if((_q)->flags & MT_QFLAG_WED_EXT)			\
-+		_val = mtk_wed_device_reg_read(&(_dev)->mmio.wed_ext,	\
-+					       ((_q)->wed_regs +	\
-+					        _offset));		\
-+		else							\
- 		_val = mtk_wed_device_reg_read(&(_dev)->mmio.wed,	\
- 					       ((_q)->wed_regs +	\
- 					        _offset));		\
-@@ -24,6 +29,11 @@
- #define Q_WRITE(_dev, _q, _field, _val)	do {				\
- 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
- 	if ((_q)->flags & MT_QFLAG_WED)					\
-+		if((_q)->flags & MT_QFLAG_WED_EXT)			\
-+		mtk_wed_device_reg_write(&(_dev)->mmio.wed_ext,		\
-+					 ((_q)->wed_regs + _offset),	\
-+					 _val);				\
-+		else							\
- 		mtk_wed_device_reg_write(&(_dev)->mmio.wed,		\
- 					 ((_q)->wed_regs + _offset),	\
- 					 _val);				\
-@@ -654,6 +664,9 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
- 	if (!(q->flags & MT_QFLAG_WED))
- 		return 0;
- 
-+	if ((q->flags & MT_QFLAG_WED_EXT))
-+		wed = &dev->mmio.wed_ext;
-+
- 	type = FIELD_GET(MT_QFLAG_WED_TYPE, q->flags);
- 	ring = FIELD_GET(MT_QFLAG_WED_RING, q->flags);
- 
-@@ -719,7 +732,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- 	if (ret)
- 		return ret;
- 
--	if (q->flags != MT_WED_Q_TXFREE)
-+	if (!mt76_queue_is_txfree(q))
- 		mt76_dma_queue_reset(dev, q);
- 
- 	return 0;
-@@ -999,6 +1012,8 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
- 	if (mtk_wed_device_active(&dev->mmio.wed))
- 		mtk_wed_device_detach(&dev->mmio.wed);
- 
-+	if (mtk_wed_device_active(&dev->mmio.wed_ext))
-+		mtk_wed_device_detach(&dev->mmio.wed_ext);
- 	mt76_free_pending_txwi(dev);
- 	mt76_free_pending_rxwi(dev);
- }
-diff --git a/mt76.h b/mt76.h
-index a0c20d36..ee0dbdd7 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -51,6 +51,7 @@
- #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_EXT	BIT(11)
- 
- #define __MT_WED_Q(_type, _n)	(MT_QFLAG_WED | \
- 				 FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
-@@ -623,6 +624,7 @@ struct mt76_mmio {
- 	u32 irqmask;
- 
- 	struct mtk_wed_device wed;
-+	struct mtk_wed_device wed_ext;
- 	struct completion wed_reset;
- 	struct completion wed_reset_complete;
- };
-@@ -1514,6 +1516,11 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
- 	return (q->flags & MT_QFLAG_WED) &&
- 	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
- }
-+static inline bool mt76_queue_is_txfree(struct mt76_queue *q)
-+{
-+	return (q->flags & MT_QFLAG_WED) &&
-+	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
-+}
- 
- struct mt76_txwi_cache *
- mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index b8f253d0..673b08bb 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -7,6 +7,25 @@
- #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);
-+		flags = MT_WED_Q_TX(idx);
-+		if (phy->mt76->band_idx == MT_BAND2)
-+			flags = MT_QFLAG_WED_EXT | MT_WED_Q_TX(0) ;
-+	}
-+
-+	return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc,
-+					  ring_base, flags);
-+}
-+
- static int mt7996_poll_tx(struct napi_struct *napi, int budget)
- {
- 	struct mt7996_dev *dev;
-@@ -128,7 +147,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
- 	}
- }
- 
--void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
-+void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
- {
- 	u32 hif1_ofs = 0;
- 	u32 irq_mask;
-@@ -153,11 +172,9 @@ void __mt7996_dma_enable(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 (mt7996_band_valid(dev, MT_BAND0))
- 		irq_mask |= MT_INT_BAND0_RX_DONE;
-@@ -168,7 +185,18 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
- 	if (mt7996_band_valid(dev, MT_BAND2))
- 		irq_mask |= MT_INT_BAND2_RX_DONE;
- 
--done:
-+	if (mtk_wed_device_active(&dev->mt76.mmio.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(&dev->mt76.mmio.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,19 +269,24 @@ static int 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);
--
--		/* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->rro_support)
-+			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_enable(dev, reset);
-+	__mt7996_dma_enable(dev, reset, true);
- 
- 	return 0;
- }
- 
- int mt7996_dma_init(struct mt7996_dev *dev)
- {
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct mtk_wed_device *wed_ext = &dev->mt76.mmio.wed_ext;
-+	u32 rx_base;
- 	u32 hif1_ofs = 0;
- 	int ret;
- 
-@@ -267,10 +300,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;
- 
-@@ -326,6 +360,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->rro_support)
-+		dev->mt76.q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
-+
- 	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,
-@@ -336,17 +373,24 @@ 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))
-+			rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2);
-+
- 		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_ext) && !dev->rro_support)
-+			dev->mt76.q_rx[MT_RXQ_BAND2_WA].flags = MT_WED_Q_TXFREE |
-+								MT_QFLAG_WED_EXT;
- 		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,
-@@ -356,6 +400,56 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 			return ret;
- 	}
- 
-+
-+	if (dev->rro_support) {
-+		/* rx rro data queue for band0 */
-+		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags = MT_RRO_Q_DATA(0);
-+		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_QFLAG_MAGIC;
-+		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 */
-+		if (mtk_wed_device_active(wed))
-+			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
-+		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 */
-+			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags = MT_RRO_Q_DATA(1);
-+			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags |= MT_QFLAG_MAGIC;
-+			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_ext))
-+				dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].flags = MT_WED_Q_TXFREE |
-+									    MT_QFLAG_WED_EXT;
-+			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 a6caf4f1..6cfbc50d 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -534,6 +534,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 (!mt7996_band_valid(dev, band) || band == MT_BAND0)
- 		return 0;
-@@ -541,8 +542,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_ext;
-+	}
- 
- 	mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7996_ops, band);
- 	if (!mphy)
-@@ -576,10 +579,11 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 
- 	/* 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);
-+	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;
- 
-@@ -1119,6 +1123,13 @@ int mt7996_register_device(struct mt7996_dev *dev)
- 
- 	ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
- 
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext)) {
-+		mt76_wr(dev, MT_INT1_MASK_CSR,
-+			dev->mt76.mmio.irqmask|MT_INT_TX_DONE_BAND2);
-+		mtk_wed_device_start(&dev->mt76.mmio.wed_ext,
-+				     dev->mt76.mmio.irqmask |MT_INT_TX_DONE_BAND2);
-+	}
-+
- 	dev->recovery.hw_init_done = true;
- 
- 	ret = mt7996_init_debugfs(&dev->phy);
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 993b43ce..fc2d9269 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1175,6 +1175,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)
- {
-@@ -1561,6 +1584,10 @@ 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_ext) &&
-+		    q == MT_RXQ_TXFREE_BAND2)
-+		    return;
-+
- 		mt7996_mac_tx_free(dev, skb->data, skb->len);
- 		napi_consume_skb(skb, 1);
- 		break;
-@@ -2035,7 +2062,7 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 	mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
- 
- 	/* enable dma tx/rx and interrupt */
--	__mt7996_dma_enable(dev, false);
-+	__mt7996_dma_enable(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 f0bdec6b..50fa6523 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -1405,6 +1405,49 @@ 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_ext;
-+
-+	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;
-+
-+	/* pao info */
-+	if (mtk_wed_device_support_pao(wed)) {
-+		path->mtk_wdma.amsdu_en = 1;
-+		path->mtk_wdma.is_sp = 0;
-+		path->mtk_wdma.is_fixedrate = 0;
-+	}
-+	ctx->dev = NULL;
-+
-+	return 0;
-+}
-+
-+#endif
-+
- const struct ieee80211_ops mt7996_ops = {
- 	.tx = mt7996_tx,
- 	.start = mt7996_start,
-@@ -1451,4 +1494,7 @@ 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,
-+#endif
- };
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 3a591a7b..b9e47e73 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -10,6 +10,11 @@
- #include "mt7996.h"
- #include "mac.h"
- #include "../trace.h"
-+#include "../dma.h"
-+
-+
-+static bool wed_enable = true;
-+module_param(wed_enable, bool, 0644);
- 
- static const struct __base mt7996_reg_base[] = {
- 	[WF_AGG_BASE]		= { { 0x820e2000, 0x820f2000, 0x830e2000 } },
-@@ -191,6 +196,228 @@ 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);
- }
- 
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+static void mt7996_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
-+{
-+	struct mt7996_dev *dev;
-+	struct page *page;
-+	int i;
-+
-+	dev = container_of(wed, struct mt7996_dev, mt76.mmio.wed);
-+	for (i = 0; i < dev->mt76.rx_token_size; i++) {
-+		struct mt76_rxwi_cache *r;
-+
-+		r = mt76_rx_token_release(&dev->mt76, i);
-+		if (!r || !r->ptr)
-+			continue;
-+
-+		dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
-+				 wed->wlan.rx_size, DMA_FROM_DEVICE);
-+		skb_free_frag(r->ptr);
-+		r->ptr = NULL;
-+
-+		mt76_put_rxwi(&dev->mt76, r);
-+	}
-+
-+	mt76_free_pending_rxwi(&dev->mt76);
-+
-+	mt76_for_each_q_rx(&dev->mt76, i) {
-+		struct mt76_queue *q = &dev->mt76.q_rx[i];
-+
-+		if (mt76_queue_is_wed_rx(q)) {
-+			if (!q->rx_page.va)
-+				continue;
-+
-+			page = virt_to_page(q->rx_page.va);
-+			__page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
-+			memset(&q->rx_page, 0, sizeof(q->rx_page));
-+		}
-+	}
-+
-+	if (!wed->rx_buf_ring.rx_page.va)
-+		return;
-+
-+	page = virt_to_page(wed->rx_buf_ring.rx_page.va);
-+	__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));
-+
-+}
-+
-+static u32 mt7996_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
-+{
-+	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
-+	struct mt7996_dev *dev;
-+	u32 length;
-+	int i;
-+
-+	dev = container_of(wed, struct mt7996_dev, mt76.mmio.wed);
-+	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
-+				sizeof(struct skb_shared_info));
-+
-+	for (i = 0; i < size; i++) {
-+		struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
-+		dma_addr_t phy_addr;
-+		int token;
-+		void *ptr;
-+
-+		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
-+				      GFP_KERNEL);
-+		if (!ptr) {
-+			mt76_put_rxwi(&dev->mt76, r);
-+			goto unmap;
-+		}
-+
-+		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);
-+			goto unmap;
-+		}
-+
-+		desc->buf0 = cpu_to_le32(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);
-+			skb_free_frag(ptr);
-+			mt76_put_rxwi(&dev->mt76, r);
-+			goto unmap;
-+		}
-+
-+		desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
-+						      token));
-+		desc++;
-+	}
-+
-+	return 0;
-+
-+unmap:
-+	mt7996_mmio_wed_release_rx_buf(wed);
-+	return -ENOMEM;
-+}
-+#endif
-+
-+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->rro_support = true;
-+
-+	hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+	if (hif2)
-+		wed = &dev->mt76.mmio.wed_ext;
-+
-+	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->rro_support) {
-+			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.chip_id = 0x7991;
-+		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
-+	} else {
-+		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.rx_nbuf = 65536;
-+		wed->wlan.rx_npkt = 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.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
-+		wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
-+		if (dev->rro_support) {
-+			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;
-+		}
-+	}
-+
-+	wed->wlan.nbuf = 16384;
-+
-+	wed->wlan.token_start = 0;
-+
-+	wed->wlan.max_amsdu_nums = 8;
-+	wed->wlan.max_amsdu_len = 1536;
-+
-+	wed->wlan.init_buf = mt7996_wed_init_buf;
-+	wed->wlan.offload_enable = NULL;
-+	wed->wlan.offload_disable = NULL;
-+	wed->wlan.init_rx_buf = mt7996_mmio_wed_init_rx_buf;
-+	wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
-+	wed->wlan.update_wo_rx_stats = NULL;
-+
-+	dev->mt76.rx_token_size += wed->wlan.rx_npkt;
-+
-+	if (mtk_wed_device_attach(wed))
-+		return 0;
-+
-+	*irq = wed->irq;
-+	dev->mt76.dma_dev = wed->dev;
-+
-+	dev->mt76.token_size = 1024;
-+
-+	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 +468,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_ext)) {
-+				mtk_wed_device_irq_set_mask(&mdev->mmio.wed_ext,
-+							    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 +496,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_ext = &dev->mt76.mmio.wed_ext;
- 	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_ext)) {
-+		mtk_wed_device_irq_set_mask(wed_ext, 0);
-+		intr1 = mtk_wed_device_irq_get(wed_ext,
-+					       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);
-@@ -307,10 +557,19 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
- irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
- {
- 	struct mt7996_dev *dev = dev_instance;
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 
--	mt76_wr(dev, MT_INT_MASK_CSR, 0);
--	if (dev->hif2)
--		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
-+	if (mtk_wed_device_active(wed))
-+		mtk_wed_device_irq_set_mask(wed, 0);
-+	else
-+		mt76_wr(dev, MT_INT_MASK_CSR, 0);
-+
-+	if (dev->hif2) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext))
-+			mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed_ext, 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 e371964b..43f20da4 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -544,7 +544,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_enable(struct mt7996_dev *dev, bool 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_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset);
- void mt7996_init_txpower(struct mt7996_dev *dev,
- 			 struct ieee80211_supported_band *sband);
- int mt7996_txbf_init(struct mt7996_dev *dev);
-@@ -732,7 +734,9 @@ 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_VENDOR
- void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
- void mt7996_vendor_register(struct mt7996_phy *phy);
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index c5301050..869f32ac 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_ext)) {
-+			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_ext))
-+		devm_free_irq(mdev->dev, dev->mt76.mmio.wed_ext.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_ext))
-+			mtk_wed_device_detach(&dev->mt76.mmio.wed_ext);
-+		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 6ef905a9..04658639 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -323,6 +323,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 +368,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)
-@@ -412,6 +416,7 @@ 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(q)				(dev->q_int_mask[__RXQ(q)])
- #define MT_INT_TX_MCU(q)			(dev->q_int_mask[(q)])
--- 
-2.39.2
-
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
new file mode 100644
index 0000000..d9fe625
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
@@ -0,0 +1,425 @@
+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/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
deleted file mode 100644
index 9a003d7..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
+++ /dev/null
@@ -1,1471 +0,0 @@
-From 017ed7925cbdfb41d3d85fed54a97cff9fcf2f78 Mon Sep 17 00:00:00 2001
-From: Bo Jiao <Bo.Jiao@mediatek.com>
-Date: Mon, 6 Feb 2023 13:50:56 +0800
-Subject: [PATCH] wifi: mt76: mt7996: wed: add wed3.0 rx support
-
-add hardware rro support, This is the preliminary patch for WED3.0 support.
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Change-Id: I7e113b1392bcf085ec02c8a44ffbb7cf7c3fa027
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- dma.c           | 205 +++++++++++++++++++++++++++++++++++++-----------
- dma.h           |  12 +++
- mac80211.c      |   1 +
- mt76.h          |  63 +++++++++++++--
- mt7996/dma.c    | 163 ++++++++++++++++++++++++++++++++------
- mt7996/init.c   | 124 ++++++++++++++++++++++++++++-
- mt7996/mac.c    |  42 ++++++++--
- mt7996/mcu.c    |   8 +-
- mt7996/mmio.c   |  36 +++++++--
- mt7996/mt7996.h |  58 ++++++++++++++
- mt7996/regs.h   |  63 ++++++++++++++-
- 11 files changed, 683 insertions(+), 92 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 930ec768..e5b4d898 100644
---- a/dma.c
-+++ b/dma.c
-@@ -193,46 +193,68 @@ EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
- static void
- mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
- {
-+	int ndesc = q->ndesc;
-+
-+	if (q->flags & MT_QFLAG_MAGIC)
-+		ndesc |= MT_DMA_MAGIC_EN;
-+
- 	Q_WRITE(dev, q, desc_base, q->desc_dma);
--	Q_WRITE(dev, q, ring_size, q->ndesc);
-+	Q_WRITE(dev, q, ring_size, ndesc);
- 	q->head = Q_READ(dev, 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 skip)
- {
- 	int i;
- 
- 	if (!q || !q->ndesc)
- 		return;
- 
-+	if (!q->desc)
-+		goto done;
-+
- 	/* clear descriptors */
- 	for (i = 0; i < q->ndesc; i++)
- 		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
- 
-+	if (skip)
-+		goto sync;
-+
-+done:
- 	Q_WRITE(dev, q, cpu_idx, 0);
- 	Q_WRITE(dev, q, dma_idx, 0);
-+sync:
- 	mt76_dma_sync_idx(dev, q);
- }
- 
- static int
- mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
--		    struct mt76_queue_buf *buf, void *data)
-+		    struct mt76_queue_buf *buf, void *data,
-+		    struct mt76_rxwi_cache *rxwi)
- {
--	struct mt76_desc *desc = &q->desc[q->head];
-+	struct mt76_desc *desc;
- 	struct mt76_queue_entry *entry = &q->entry[q->head];
--	struct mt76_rxwi_cache *rxwi = NULL;
- 	u32 buf1 = 0, ctrl;
- 	int idx = q->head;
- 	int rx_token;
-+	void *e_buf = data;
-+
-+	if (mt76_queue_is_rro_ind(q)) {
-+		e_buf = &q->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)) {
--		rxwi = mt76_get_rxwi(dev);
--		if (!rxwi)
--			return -ENOMEM;
-+		if (!rxwi) {
-+			rxwi = mt76_get_rxwi(dev);
-+			if (!rxwi)
-+				return -ENOMEM;
-+		}
- 
- 		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
- 		if (rx_token < 0) {
-@@ -249,10 +271,11 @@ 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->rxwi = rxwi;
--	entry->buf = data;
-+	entry->buf = e_buf;
- 	entry->wcid = 0xffff;
- 	entry->skip_buf1 = true;
- 	q->head = (q->head + 1) % q->ndesc;
-@@ -396,14 +419,18 @@ 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,
--		 int *len, u32 *info, bool *more, bool *drop)
-+		 int *len, u32 *info, bool *more, bool *drop, bool flush)
- {
- 	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_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);
- 	}
-@@ -411,6 +438,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);
-@@ -423,28 +456,54 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 				 SKB_WITH_OVERHEAD(q->buf_size),
- 				 DMA_FROM_DEVICE);
- 
--		buf = r->ptr;
--		r->dma_addr = 0;
--		r->ptr = NULL;
--
--		mt76_put_rxwi(dev, r);
--
--		if (drop) {
--			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
--
--			*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A |
--					   MT_DMA_CTL_DROP));
-+		if (flush) {
-+			buf = r->ptr;
-+			r->dma_addr = 0;
-+			r->ptr = NULL;
-+
-+			mt76_put_rxwi(dev, r);
-+		} else {
-+			struct mt76_queue_buf qbuf;
-+
-+			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
-+			if (!buf)
-+				return NULL;
-+
-+			memcpy(buf, r->ptr, SKB_WITH_OVERHEAD(q->buf_size));
-+
-+			r->dma_addr = dma_map_single(dev->dma_dev, r->ptr,
-+						     SKB_WITH_OVERHEAD(q->buf_size),
-+						     DMA_FROM_DEVICE);
-+			if (unlikely(dma_mapping_error(dev->dma_dev, r->dma_addr))) {
-+				skb_free_frag(r->ptr);
-+				mt76_put_rxwi(dev, r);
-+				return NULL;
-+			}
-+
-+			qbuf.addr = r->dma_addr;
-+			qbuf.len = SKB_WITH_OVERHEAD(q->buf_size);
-+			qbuf.skip_unmap = false;
-+
-+			if (mt76_dma_add_rx_buf(dev, q, &qbuf, r->ptr, r) < 0) {
-+				dma_unmap_single(dev->dma_dev, r->dma_addr,
-+						 SKB_WITH_OVERHEAD(q->buf_size),
-+						 DMA_FROM_DEVICE);
-+				skb_free_frag(r->ptr);
-+				mt76_put_rxwi(dev, r);
-+				return NULL;
-+			}
-+		}
- 
-+		if (drop)
- 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
--		}
- 	} else {
--		buf = e->buf;
--		e->buf = NULL;
- 		dma_unmap_single(dev->dma_dev, e->dma_addr[0],
- 				 SKB_WITH_OVERHEAD(q->buf_size),
- 				 DMA_FROM_DEVICE);
- 	}
- 
-+done:
-+	e->buf = NULL;
- 	return buf;
- }
- 
-@@ -458,15 +517,22 @@ 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_rro_ind(q)) {
-+		goto done;
-+	} else if (q->flags & MT_QFLAG_RRO) {
- 		return NULL;
-+	} else {
-+		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;
-+	}
- 
-+done:
- 	q->tail = (q->tail + 1) % q->ndesc;
- 	q->queued--;
- 
--	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop);
-+	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush);
- }
- 
- static int
-@@ -615,7 +681,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 
- 	while (q->queued < q->ndesc - 1) {
- 		struct mt76_queue_buf qbuf;
--		void *buf;
-+		void *buf = NULL;
-+
-+		if (mt76_queue_is_rro_ind(q))
-+			goto done;
- 
- 		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
- 		if (!buf)
-@@ -627,10 +696,11 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 			break;
- 		}
- 
-+done:
- 		qbuf.addr = addr + offset;
- 		qbuf.len = len - offset;
- 		qbuf.skip_unmap = false;
--		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
-+		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf, NULL) < 0) {
- 			dma_unmap_single(dev->dma_dev, addr, len,
- 					 DMA_FROM_DEVICE);
- 			skb_free_frag(buf);
-@@ -639,7 +709,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);
-@@ -652,7 +722,7 @@ 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;
-+	u16 flags;
- 
- 	if (!q || !q->ndesc)
- 		return -EINVAL;
-@@ -679,7 +749,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, false);
- 		mt76_dma_rx_fill(dev, q);
- 		q->flags = flags;
- 
-@@ -688,9 +758,31 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
- 			q->wed_regs = wed->txfree_ring.reg_base;
- 		break;
- 	case MT76_WED_Q_RX:
--		ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
--		if (!ret)
--			q->wed_regs = wed->rx_ring[ring].reg_base;
-+		if (q->flags & MT_QFLAG_RRO) {
-+			q->flags &= ~0x1f;
-+
-+			ring = FIELD_GET(MT_QFLAG_RRO_RING, q->flags);
-+			type = FIELD_GET(MT_QFLAG_RRO_TYPE, q->flags);
-+			if (type == MT76_RRO_Q_DATA) {
-+				mt76_dma_queue_reset(dev, q, true);
-+				ret = mtk_wed_device_rro_rx_ring_setup(wed, ring, q->regs);
-+			} else if (type == MT76_RRO_Q_MSDU_PG) {
-+				mt76_dma_queue_reset(dev, q, true);
-+				ret = mtk_wed_device_msdu_pg_rx_ring_setup(wed, ring, q->regs);
-+			} else if (type == MT76_RRO_Q_IND) {
-+				mt76_dma_queue_reset(dev, q, false);
-+				mt76_dma_rx_fill(dev, q);
-+				ret = mtk_wed_device_ind_rx_ring_setup(wed, q->regs);
-+			}
-+			if (type != MT76_RRO_Q_IND) {
-+				q->head = q->ndesc - 1;
-+				q->queued = q->ndesc - 1;
-+			}
-+		} else {
-+			ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, 0);
-+			if (!ret)
-+				q->wed_regs = wed->rx_ring[ring].reg_base;
-+		}
- 		break;
- 	default:
- 		ret = -EINVAL;
-@@ -719,10 +811,25 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- 	q->hw_idx = idx;
- 
- 	size = q->ndesc * sizeof(struct mt76_desc);
-+	if (mt76_queue_is_rro_ind(q))
-+		size = q->ndesc * sizeof(struct mt76_rro_desc);
-+
- 	q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
- 	if (!q->desc)
- 		return -ENOMEM;
- 
-+	if (mt76_queue_is_rro_ind(q)) {
-+		struct mt76_rro_ind *cmd;
-+		int i;
-+
-+		q->rro_desc = (struct mt76_rro_desc *)(q->desc);
-+		q->desc = NULL;
-+		for (i = 0; i < q->ndesc; i++) {
-+			cmd = (struct mt76_rro_ind *) &q->rro_desc[i];
-+			cmd->magic_cnt = MT_DMA_IND_CMD_MAGIC_CNT - 1;
-+		}
-+	}
-+
- 	size = q->ndesc * sizeof(*q->entry);
- 	q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
- 	if (!q->entry)
-@@ -732,8 +839,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- 	if (ret)
- 		return ret;
- 
--	if (!mt76_queue_is_txfree(q))
--		mt76_dma_queue_reset(dev, q);
-+	if (!mtk_wed_device_active(&dev->mmio.wed) ||
-+	    (!mt76_queue_is_wed_txfree(q) &&
-+	     !(mtk_wed_get_rx_capa(&dev->mmio.wed) &&
-+	       q->flags & MT_QFLAG_RRO)))
-+		mt76_dma_queue_reset(dev, q, false);
- 
- 	return 0;
- }
-@@ -768,8 +878,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
- 
- 	spin_unlock_bh(&q->lock);
- 
--	if (((q->flags & MT_QFLAG_WED) &&
--	     FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) ||
-+	if (mt76_queue_is_wed_rx(q) ||
- 	    (q->flags & MT_QFLAG_RRO))
- 		return;
- 
-@@ -790,9 +899,13 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
- 	if (!q->ndesc)
- 		return;
- 
-+	if (!q->desc)
-+		goto done;
-+
- 	for (i = 0; i < q->ndesc; i++)
- 		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
- 
-+done:
- 	mt76_dma_rx_cleanup(dev, q);
- 
- 	/* reset WED rx queues */
-@@ -839,8 +952,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
- 	bool check_ddone = false;
- 	bool more;
- 
--	if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
--	    q->flags == MT_WED_Q_TXFREE) {
-+	if ((IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
-+	     q->flags == MT_WED_Q_TXFREE)) {
- 		dma_idx = Q_READ(dev, q, dma_idx);
- 		check_ddone = true;
- 	}
-@@ -1002,7 +1115,8 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
- 	mt76_for_each_q_rx(dev, i) {
- 		struct mt76_queue *q = &dev->q_rx[i];
- 
--		if (mt76_queue_is_wed_rx(q))
-+		if (mtk_wed_device_active(&dev->mmio.wed) &&
-+		    (q->flags & MT_QFLAG_RRO))
- 			continue;
- 
- 		netif_napi_del(&dev->napi[i]);
-@@ -1014,6 +1128,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
- 
- 	if (mtk_wed_device_active(&dev->mmio.wed_ext))
- 		mtk_wed_device_detach(&dev->mmio.wed_ext);
-+
- 	mt76_free_pending_txwi(dev);
- 	mt76_free_pending_rxwi(dev);
- }
-diff --git a/dma.h b/dma.h
-index 1b090d78..48037092 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_MAGIC_EN		BIT(13)
-+
-+#define MT_DMA_IND_CMD_MAGIC_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_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 f7578308..3a5755f9 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -727,6 +727,7 @@ static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
- 			return;
- 		}
- 	}
-+
- 	__skb_queue_tail(&dev->rx_skb[q], skb);
- }
- 
-diff --git a/mt76.h b/mt76.h
-index ee0dbdd7..e4351338 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -48,6 +48,18 @@
- 
- #define MT76_TOKEN_FREE_THR	64
- 
-+#define MT_QFLAG_RRO_RING	GENMASK(6, 5)
-+#define MT_QFLAG_RRO_TYPE	GENMASK(8, 7)
-+#define MT_QFLAG_RRO		BIT(9)
-+#define MT_QFLAG_MAGIC		BIT(10)
-+
-+#define __MT_RRO_Q(_type, _n)	(MT_QFLAG_RRO | \
-+				 FIELD_PREP(MT_QFLAG_RRO_TYPE, _type) | \
-+				 FIELD_PREP(MT_QFLAG_RRO_RING, _n))
-+#define MT_RRO_Q_DATA(_n)	__MT_RRO_Q(MT76_RRO_Q_DATA, _n)
-+#define MT_RRO_Q_MSDU_PG(_n)	__MT_RRO_Q(MT76_RRO_Q_MSDU_PG, _n)
-+#define MT_RRO_Q_IND		__MT_RRO_Q(MT76_RRO_Q_IND, 0)
-+
- #define MT_QFLAG_WED_RING	GENMASK(1, 0)
- #define MT_QFLAG_WED_TYPE	GENMASK(3, 2)
- #define MT_QFLAG_WED		BIT(4)
-@@ -82,6 +94,12 @@ enum mt76_wed_type {
- 	MT76_WED_Q_RX,
- };
- 
-+enum mt76_RRO_type {
-+	MT76_RRO_Q_DATA,
-+	MT76_RRO_Q_MSDU_PG,
-+	MT76_RRO_Q_IND,
-+};
-+
- struct mt76_bus_ops {
- 	u32 (*rr)(struct mt76_dev *dev, u32 offset);
- 	void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
-@@ -128,6 +146,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
- };
- 
-@@ -206,6 +234,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;
-@@ -219,8 +248,8 @@ struct mt76_queue {
- 
- 	u8 buf_offset;
- 	u8 hw_idx;
--	u8 flags;
--
-+	u8 magic_cnt;
-+	u32 flags;
- 	u32 wed_regs;
- 
- 	dma_addr_t desc_dma;
-@@ -274,7 +303,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 skip);
- };
- 
- enum mt76_phy_type {
-@@ -369,6 +398,17 @@ struct mt76_txq {
- 	bool aggr;
- };
- 
-+struct mt76_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;
-@@ -1516,12 +1556,19 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
- 	return (q->flags & MT_QFLAG_WED) &&
- 	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
- }
--static inline bool mt76_queue_is_txfree(struct mt76_queue *q)
-+
-+static inline bool mt76_queue_is_wed_txfree(struct mt76_queue *q)
- {
- 	return (q->flags & MT_QFLAG_WED) &&
- 	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
- }
- 
-+static inline bool mt76_queue_is_rro_ind(struct mt76_queue *q)
-+{
-+	return (q->flags & MT_QFLAG_RRO) &&
-+	       FIELD_GET(MT_QFLAG_RRO_TYPE, q->flags) == MT76_RRO_Q_IND;
-+}
-+
- 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);
-@@ -1540,10 +1587,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/mt7996/dma.c b/mt7996/dma.c
-index 428f3d08..45ccc7b5 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -64,6 +64,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->rro_support) {
-+		/* 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);
-@@ -102,6 +125,22 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
- 	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->rro_support) {
-+		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));
-+		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,
-+			PREFETCH(0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND2) + ofs,
-+			PREFETCH(0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND0) + ofs,
-+			PREFETCH(0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
-+			PREFETCH(0x4));
-+	}
- #undef PREFETCH
- 
- 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
-@@ -161,6 +200,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
- 
- void __mt7996_dma_enable(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;
- 
-@@ -169,11 +209,16 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
- 
- 	/* enable wpdma 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,
-@@ -185,8 +230,8 @@ void __mt7996_dma_enable(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;
-+		   MT_INT_RX_DONE_MCU |
-+		   MT_INT_TX_DONE_MCU;
- 
- 	if (mt7996_band_valid(dev, MT_BAND0))
- 		irq_mask |= MT_INT_BAND0_RX_DONE;
-@@ -197,14 +242,14 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
- 	if (mt7996_band_valid(dev, MT_BAND2))
- 		irq_mask |= MT_INT_BAND2_RX_DONE;
- 
--	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
-+	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(&dev->mt76.mmio.wed, wed_irq_mask);
-+		mtk_wed_device_start(wed, wed_irq_mask);
- 	}
- 
- 	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
-@@ -298,7 +343,8 @@ static int 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
- 		 */
--		if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->rro_support)
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    dev->rro_support)
- 			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
- 				 MT_WFDMA0_RX_INT_SEL_RING6);
- 		else
-@@ -311,6 +357,78 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
- 	return 0;
- }
- 
-+int mt7996_dma_rro_init(struct mt7996_dev *dev)
-+{
-+	int ret;
-+	u32 hif1_ofs = 0;
-+	u32 wed_irq_mask;
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+
-+	if (dev->hif2)
-+		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+	/* ind cmd */
-+	dev->mt76.q_rx[MT_RXQ_RRO_IND].flags = MT_RRO_Q_IND | MT_WED_Q_RX(0);
-+	dev->mt76.q_rx[MT_RXQ_RRO_IND].flags |= MT_WED_Q_RX(0);
-+	ret = mt76_queue_alloc(dev, &dev->mt76.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;
-+
-+	/* rx msdu page queue for band0 */
-+	dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags = MT_RRO_Q_MSDU_PG(0);
-+	dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags |= MT_QFLAG_MAGIC;
-+	dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags |= MT_WED_Q_RX(0);
-+	ret = mt76_queue_alloc(dev, &dev->mt76.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 (mt7996_band_valid(dev, MT_BAND1)) {
-+		/* rx msdu page queue for band1 */
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags = MT_RRO_Q_MSDU_PG(1);
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags |= MT_QFLAG_MAGIC;
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags |= MT_WED_Q_RX(1);
-+		ret = mt76_queue_alloc(dev, &dev->mt76.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 (mt7996_band_valid(dev, MT_BAND2)) {
-+		/* rx msdu page queue for band2 */
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags = MT_RRO_Q_MSDU_PG(2);
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags |= MT_QFLAG_MAGIC;
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags |= MT_WED_Q_RX(0);
-+		ret = mt76_queue_alloc(dev, &dev->mt76.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;
-+	}
-+
-+	wed_irq_mask = dev->mt76.mmio.irqmask |
-+		       MT_INT_RRO_RX_DONE |
-+		       MT_INT_TX_DONE_BAND2;
-+
-+	mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
-+
-+	mtk_wed_device_start_hwrro(wed, wed_irq_mask, false);
-+	mt7996_irq_enable(dev, wed_irq_mask);
-+
-+	return 0;
-+}
-+
- int mt7996_dma_init(struct mt7996_dev *dev)
- {
- 	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-@@ -380,6 +498,9 @@ 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);
-+
- 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
- 			       MT_RXQ_ID(MT_RXQ_MAIN),
- 			       MT7996_RX_RING_SIZE,
-@@ -403,9 +524,6 @@ 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))
--			rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2);
--
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
- 				       MT_RXQ_ID(MT_RXQ_BAND2),
- 				       MT7996_RX_RING_SIZE,
-@@ -429,11 +547,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 			return ret;
- 	}
- 
--
--	if (dev->rro_support) {
-+	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed) &&
-+	    dev->rro_support) {
- 		/* rx rro data queue for band0 */
- 		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags = MT_RRO_Q_DATA(0);
- 		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_QFLAG_MAGIC;
-+		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_WED_Q_RX(0);
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
- 				       MT_RXQ_ID(MT_RXQ_RRO_BAND0),
- 				       MT7996_RX_RING_SIZE,
-@@ -443,8 +562,7 @@ 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->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
-+		dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
- 		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,
-@@ -457,6 +575,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 			/* rx rro data queue for band2 */
- 			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags = MT_RRO_Q_DATA(1);
- 			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags |= MT_QFLAG_MAGIC;
-+			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags |= MT_WED_Q_RX(1);
- 			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
- 					       MT_RXQ_ID(MT_RXQ_RRO_BAND2),
- 					       MT7996_RX_RING_SIZE,
-@@ -534,18 +653,18 @@ void mt7996_dma_reset(struct mt7996_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], false);
- 		if (phy2)
--			mt76_queue_reset(dev, phy2->q_tx[i]);
-+			mt76_queue_reset(dev, phy2->q_tx[i], false);
- 		if (phy3)
--			mt76_queue_reset(dev, phy3->q_tx[i]);
-+			mt76_queue_reset(dev, phy3->q_tx[i], false);
- 	}
- 
- 	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], false);
- 
- 	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], false);
- 	}
- 
- 	mt76_tx_status_check(&dev->mt76, true);
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 6cfbc50d..d70dcf9f 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -496,8 +496,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->rro_support) {
-+		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,
-@@ -650,6 +655,114 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
- 	msleep(20);
- }
- 
-+static int mt7996_rro_init(struct mt7996_dev *dev)
-+{
-+	struct mt7996_rro_addr *ptr;
-+	struct mt7996_rro_cfg *rro = &dev->rro;
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	u32 size, val = 0, reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;
-+	int i, j;
-+	void *buf;
-+
-+	for (i = 0; i < MT7996_RRO_BA_BITMAP_CR_CNT; i++) {
-+		buf = dmam_alloc_coherent(dev->mt76.dma_dev,
-+					  MT7996_BA_BITMAP_SZ_PER_CR,
-+					  &rro->ba_bitmap_cache_pa[i],
-+					  GFP_KERNEL);
-+		if (!buf)
-+			return -ENOMEM;
-+
-+		rro->ba_bitmap_cache_va[i] = buf;
-+	}
-+
-+	rro->win_sz = MT7996_RRO_WIN_SIZE_MAX;
-+	for (i = 0; i < MT7996_RRO_ADDR_ELEM_CR_CNT; i++) {
-+		size = MT7996_RRO_SESSION_PER_CR *
-+		       rro->win_sz * sizeof(struct mt7996_rro_addr);
-+
-+		buf = dmam_alloc_coherent(dev->mt76.dma_dev, size,
-+					  &rro->addr_elem_alloc_pa[i],
-+					  GFP_KERNEL);
-+		if (!buf)
-+			return -ENOMEM;
-+		rro->addr_elem_alloc_va[i] = buf;
-+
-+		memset(rro->addr_elem_alloc_va[i], 0, size);
-+
-+		ptr = rro->addr_elem_alloc_va[i];
-+		for (j = 0; j < MT7996_RRO_SESSION_PER_CR * rro->win_sz; j++, ptr++)
-+			ptr->signature = 0xff;
-+
-+		wed->wlan.ind_cmd.addr_elem_phys[i] = rro->addr_elem_alloc_pa[i];
-+	}
-+
-+	rro->particular_se_id = MT7996_RRO_SESSION_MAX;
-+	size = rro->win_sz * sizeof(struct mt7996_rro_addr);
-+	buf = dmam_alloc_coherent(dev->mt76.dma_dev, size,
-+				  &rro->particular_session_pa,
-+				  GFP_KERNEL);
-+	if (!buf)
-+		return -ENOMEM;
-+
-+	rro->particular_session_va = buf;
-+	ptr = rro->particular_session_va;
-+	for (j = 0; j < rro->win_sz; j++, ptr++)
-+		ptr->signature = 0xff;
-+
-+	INIT_LIST_HEAD(&rro->pg_addr_cache);
-+	for (i = 0; i < MT7996_RRO_MSDU_PG_HASH_SIZE; i++)
-+		INIT_LIST_HEAD(&rro->pg_hash_head[i]);
-+
-+	/* 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,
-+		rro->ba_bitmap_cache_pa[0]);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
-+		rro->ba_bitmap_cache_pa[1]);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
-+
-+	/* setup Address element address */
-+	for (i = 0; i < MT7996_RRO_ADDR_ELEM_CR_CNT; i++) {
-+		mt76_wr(dev, reg, rro->addr_elem_alloc_pa[i] >> 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(rro->win_sz) - 6;
-+	wed->wlan.ind_cmd.particular_sid = rro->particular_se_id;
-+	wed->wlan.ind_cmd.particular_se_phys = rro->particular_session_pa;
-+	wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_CR_CNT;
-+	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,
-+		rro->particular_session_pa);
-+
-+	val = FIELD_PREP(MT_RRO_PARTICULAR_SID,
-+			 MT7996_RRO_SESSION_MAX);
-+	val |= MT_RRO_PARTICULAR_CONFG_EN;
-+	mt76_wr(dev, MT_RRO_PARTICULAR_CFG1, val);
-+
-+	/* 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);
-+}
-+
- static int mt7996_init_hardware(struct mt7996_dev *dev)
- {
- 	int ret, idx;
-@@ -677,6 +790,13 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+	    dev->rro_support) {
-+		ret = mt7996_rro_init(dev);
-+		if (ret)
-+			return ret;
-+	}
-+
- 	ret = mt7996_eeprom_init(dev);
- 	if (ret < 0)
- 		return ret;
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index fc2d9269..4fbbc077 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -614,8 +614,37 @@ 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;
-@@ -640,7 +669,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);
-@@ -667,8 +699,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->sta_poll_lock);
- 		if (list_empty(&msta->poll_list))
-@@ -871,12 +901,14 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- #endif
- 	} 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))
- 		mt7996_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 &&
-@@ -1604,7 +1636,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;
- 		}
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 59f22f6d..1891c0d7 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -949,7 +949,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,
- 		  struct ieee80211_ampdu_params *params,
--		  bool enable, bool tx)
-+		  bool enable, bool tx, bool rro_enable)
- {
- 	struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
- 	struct sta_rec_ba_uni *ba;
-@@ -970,6 +970,8 @@ 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;
-+	if (rro_enable && !tx && enable)
-+		ba->ba_rdd_rro = true;
- 
- 	return mt76_mcu_skb_send_msg(dev, skb,
- 				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
-@@ -987,7 +989,7 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
- 		msta->wcid.amsdu = false;
- 
- 	return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
--				 enable, true);
-+				 enable, true, dev->rro_support);
- }
- 
- int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
-@@ -998,7 +1000,7 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
- 	struct mt7996_vif *mvif = msta->vif;
- 
- 	return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
--				 enable, false);
-+				 enable, false, dev->rro_support);
- }
- 
- static void
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index b9e47e73..9960dca7 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -346,9 +346,15 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 			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.chip_id = 0x7991;
- 		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
- 	} else {
-+		wed->wlan.hwrro = dev->rro_support; /* 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) +
-@@ -360,13 +366,33 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 				     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 = 24576;
-+		if (dev->hif2)
-+			wed->wlan.rx_npkt += 8192;
-+
- 		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->rro_support) {
-@@ -378,6 +404,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 			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 += wed->wlan.rx_npkt;
- 	}
- 
- 	wed->wlan.nbuf = 16384;
-@@ -394,8 +422,6 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 	wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
- 	wed->wlan.update_wo_rx_stats = NULL;
- 
--	dev->mt76.rx_token_size += wed->wlan.rx_npkt;
--
- 	if (mtk_wed_device_attach(wed))
- 		return 0;
- 
-@@ -557,10 +583,9 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
- irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
- {
- 	struct mt7996_dev *dev = dev_instance;
--	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 
--	if (mtk_wed_device_active(wed))
--		mtk_wed_device_irq_set_mask(wed, 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);
- 
-@@ -592,6 +617,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
- 				SURVEY_INFO_TIME_RX |
- 				SURVEY_INFO_TIME_BSS_RX,
- 		.token_size = MT7996_TOKEN_SIZE,
-+		.rx_token_size = MT7996_RX_TOKEN_SIZE,
- 		.tx_prepare_skb = mt7996_tx_prepare_skb,
- 		.tx_complete_skb = mt76_connac_tx_complete_skb,
- 		.rx_skb = mt7996_queue_rx_skb,
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 43f20da4..836c7db7 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -39,6 +39,7 @@
- #define MT7996_EEPROM_SIZE		7680
- #define MT7996_EEPROM_BLOCK_SIZE	16
- #define MT7996_TOKEN_SIZE		16384
-+#define MT7996_RX_TOKEN_SIZE		16384
- 
- #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
- #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
-@@ -63,6 +64,24 @@
- #define MT7996_SKU_RATE_NUM		417
- #define MT7996_SKU_PATH_NUM		494
- 
-+#define MT7996_RRO_MSDU_PG_HASH_SIZE	127
-+#define MT7996_RRO_SESSION_MAX		1024
-+#define MT7996_RRO_WIN_SIZE_MAX		1024
-+#define MT7996_RRO_ADDR_ELEM_CR_CNT	128
-+#define MT7996_RRO_BA_BITMAP_CR_CNT	2
-+#define MT7996_RRO_SESSION_PER_CR	(MT7996_RRO_SESSION_MAX /	\
-+					 MT7996_RRO_ADDR_ELEM_CR_CNT)
-+#define MT7996_BA_BITMAP_SZ_PER_SESSION	128
-+#define MT7996_BA_BITMAP_SZ_PER_CR	((MT7996_RRO_SESSION_MAX *		\
-+					 MT7996_BA_BITMAP_SZ_PER_SESSION) /	\
-+					 MT7996_RRO_BA_BITMAP_CR_CNT)
-+#define MT7996_SKB_TRUESIZE(x)		((x) +	\
-+					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
-+#define MT7996_RX_BUF_SIZE		MT7996_SKB_TRUESIZE(1800)
-+#define MT7996_RX_MSDU_PAGE_SIZE	MT7996_SKB_TRUESIZE(128)
-+
-+#define MT7996_WED_RX_TOKEN_SIZE	32768
-+
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -102,6 +121,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 {
-@@ -272,6 +301,31 @@ struct mt7996_air_monitor_ctrl {
- };
- #endif
- 
-+struct mt7996_rro_addr {
-+	u32 head_pkt_l;
-+	u32 head_pkt_h	: 4;
-+	u32 seg_cnt	: 11;
-+	u32 out_of_range: 1;
-+	u32 rsv		: 8;
-+	u32 signature	: 8;
-+};
-+
-+struct mt7996_rro_cfg {
-+	u32 ind_signature;
-+	void *ba_bitmap_cache_va[MT7996_RRO_BA_BITMAP_CR_CNT];
-+	void *addr_elem_alloc_va[MT7996_RRO_ADDR_ELEM_CR_CNT];
-+	void *particular_session_va;
-+	u32 particular_se_id;
-+	dma_addr_t ba_bitmap_cache_pa[MT7996_RRO_BA_BITMAP_CR_CNT];
-+	dma_addr_t addr_elem_alloc_pa[MT7996_RRO_ADDR_ELEM_CR_CNT];
-+	dma_addr_t particular_session_pa;
-+	u16 win_sz;
-+
-+	spinlock_t lock;
-+	struct list_head pg_addr_cache;
-+	struct list_head pg_hash_head[MT7996_RRO_MSDU_PG_HASH_SIZE];
-+};
-+
- struct mt7996_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7996_dev *dev;
-@@ -390,6 +444,9 @@ struct mt7996_dev {
- 	bool flash_mode:1;
- 	bool has_eht:1;
- 
-+	bool rro_support:1;
-+	struct mt7996_rro_cfg rro;
-+
- 	bool testmode_enable;
- 	bool bin_file_mode;
- 	u8 eeprom_mode;
-@@ -709,6 +766,7 @@ 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);
-+int mt7996_dma_rro_init(struct mt7996_dev *dev);
- 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 5ed7bcca..47fa965f 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -39,6 +39,40 @@ 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)
-@@ -400,6 +434,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)
-@@ -427,6 +462,15 @@ enum base_rev {
- #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)])
- 
-@@ -434,20 +478,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/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch
deleted file mode 100644
index 7fdee4c..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From e5136e5f940adf55f1e7604960dba89e24a187bb Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Thu, 13 Apr 2023 14:12:16 +0800
-Subject: [PATCH 2005/2008] wifi: mt76: mt7996: wed: add mt7996_net_setup_tc to
- support wifi2wifi offload
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- mt7996/main.c | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
-
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 50fa6523..cebac4ab 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -1446,6 +1446,24 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
- 	return 0;
- }
- 
-+static int mt7996_net_setup_tc(struct ieee80211_hw *hw,
-+			       struct ieee80211_vif *vif,
-+			       struct net_device *ndev,
-+			       enum tc_setup_type type,
-+			       void *type_data)
-+
-+{
-+	struct mt7996_dev *dev = mt7996_hw_dev(hw);
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+
-+	if (!mtk_wed_device_active(wed))
-+		return -ENODEV;
-+
-+	mtk_wed_device_setup_tc(wed, ndev, type, type_data);
-+
-+	return 0;
-+}
-+
- #endif
- 
- const struct ieee80211_ops mt7996_ops = {
-@@ -1496,5 +1514,6 @@ const struct ieee80211_ops mt7996_ops = {
- 	.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 = mt7996_net_setup_tc,
- #endif
- };
--- 
-2.39.2
-
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
new file mode 100644
index 0000000..306c6e6
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G-ICS.patch
@@ -0,0 +1,93 @@
+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-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
new file mode 100644
index 0000000..7511279
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2006-wifi-mt76-mt7996-add-rro-elem-free-when-rmmod-wifi-m.patch
@@ -0,0 +1,65 @@
+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-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
similarity index 61%
rename from recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-add-SER-support-for-wed3.0.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-add-SER-support-for-wed3.0.patch
index 3d25c27..2ba1f4e 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2008-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
@@ -1,60 +1,36 @@
-From 5df084a32eac68dd66a3b833cf5f718118850b08 Mon Sep 17 00:00:00 2001
+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 2008/2008] wifi: mt76: add SER support for wed3.0
+Subject: [PATCH 71/98] wifi: mt76: add SER support for wed3.0
 
 Change-Id: I2711b9dc336fca9a1ae32a8fbf27810a7e27b1e3
 ---
- dma.c         |  7 +++++--
- mt7996/dma.c  | 48 +++++++++++++++++++++++++++++++++++++++++++++---
- mt7996/mac.c  | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
- mt7996/mmio.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 145 insertions(+), 6 deletions(-)
+ 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 e5b4d898..e31f6390 100644
+index f48ec57..141a97b 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -778,8 +778,9 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
- 				q->head = q->ndesc - 1;
- 				q->queued = q->ndesc - 1;
- 			}
-+			q->flags = flags;
- 		} else {
--			ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, 0);
-+			ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
- 			if (!ret)
- 				q->wed_regs = wed->rx_ring[ring].reg_base;
- 		}
-@@ -910,7 +911,9 @@ done:
+@@ -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 (q->flags != MT_WED_Q_TXFREE) {
-+	if (q->flags != MT_WED_Q_TXFREE &&
-+	    !((q->flags & MT_QFLAG_RRO) &&
+-	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 c5c7f160..471ae81c 100644
+index 2397fe5..b2c7ae6 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -524,6 +524,12 @@ 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)) {
-+			rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2);
-+			if (mtk_wed_get_rx_capa(wed))
-+				dev->mt76.q_rx[MT_RXQ_BAND2].flags = MT_WED_Q_RX(1);
-+		}
-+
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
- 				       MT_RXQ_ID(MT_RXQ_BAND2),
- 				       MT7996_RX_RING_SIZE,
-@@ -611,11 +617,35 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -615,11 +615,35 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  	return 0;
  }
  
@@ -75,7 +51,7 @@
 +static void
 +mt7996_dma_reset_tx_queue(struct mt7996_dev *dev, struct mt76_queue *q)
 +{
-+	mt76_queue_reset(dev, q, false);
++	mt76_queue_reset(dev, q);
 +	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
 +		mt76_dma_wed_setup(&dev->mt76, q, true);
 +}
@@ -86,16 +62,16 @@
  	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_ext = &dev->mt76.mmio.wed_ext;
++	struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
  	int i;
  
  	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
-@@ -649,21 +679,33 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+@@ -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_ext))
-+		mtk_wed_device_dma_reset(wed_ext);
++	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);
@@ -105,61 +81,61 @@
  
  	/* reset hw queues */
  	for (i = 0; i < __MT_TXQ_MAX; i++) {
--		mt76_queue_reset(dev, dev->mphy.q_tx[i], false);
+-		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], false);
+-			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], false);
+-			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], false);
+ 		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
  
  	mt76_for_each_q_rx(&dev->mt76, i) {
 +		if (mtk_wed_device_active(wed) &&
-+		    ((dev->mt76.q_rx[i].flags & MT_QFLAG_RRO) ||
-+		    dev->mt76.q_rx[i].flags == MT_WED_Q_TXFREE))
++		    (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], false);
+ 		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
  	}
  
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 3a89013c..d1082e89 100644
+index 60ca23b..22cff71 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -2002,6 +2002,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
+@@ -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) &&
-+		    (mdev->q_rx[i].flags & MT_QFLAG_RRO))
++		    mt76_queue_is_wed_rro(&mdev->q_rx[i]))
 +			continue;
 +
  		if (mdev->q_rx[i].ndesc)
  			napi_disable(&dev->mt76.napi[i]);
  	}
-@@ -2015,6 +2019,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
+@@ -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) &&
-+		    (mdev->q_rx[i].flags & MT_QFLAG_RRO))
++		    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]);
-@@ -2189,6 +2197,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -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_ext))
-+		mtk_wed_device_stop(&dev->mt76.mmio.wed_ext);
++	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);
@@ -167,14 +143,14 @@
  	ieee80211_stop_queues(mt76_hw(dev));
  	if (phy2)
  		ieee80211_stop_queues(phy2->mt76->hw);
-@@ -2212,8 +2227,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -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) &&
-+		    (dev->mt76.q_rx[i].flags & MT_QFLAG_RRO))
++		    mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]))
 +			continue;
 +
  		napi_disable(&dev->mt76.napi[i]);
@@ -182,9 +158,9 @@
  	napi_disable(&dev->mt76.tx_napi);
  
  	mutex_lock(&dev->mt76.mutex);
-@@ -2236,6 +2256,29 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 	/* enable dma tx/rx and interrupt */
- 	__mt7996_dma_enable(dev, false, false);
+@@ -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)) {
@@ -202,29 +178,27 @@
 +		mt7996_irq_disable(dev, 0);
 +	}
 +
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext)) {
-+		mt76_wr(dev, MT_INT1_MASK_CSR,
-+			dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2);
-+		mtk_wed_device_start(&dev->mt76.mmio.wed_ext,
-+			dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2);
++	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)
-@@ -2245,6 +2288,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -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) &&
-+		    ((dev->mt76.q_rx[i].flags & MT_QFLAG_RRO)))
++		    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 9960dca7..fe34bb7d 100644
+index 2e395d1..631d905 100644
 --- a/mt7996/mmio.c
 +++ b/mt7996/mmio.c
 @@ -6,9 +6,11 @@
@@ -239,11 +213,11 @@
  #include "../trace.h"
  #include "../dma.h"
  
-@@ -297,6 +299,43 @@ unmap:
- 	mt7996_mmio_wed_release_rx_buf(wed);
- 	return -ENOMEM;
+@@ -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);
@@ -280,13 +254,15 @@
 +	complete(&dev->mmio.wed_reset_complete);
 +}
 +
- #endif
- 
++#endif
++
  int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
-@@ -421,6 +460,14 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 	wed->wlan.init_rx_buf = mt7996_mmio_wed_init_rx_buf;
- 	wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
- 	wed->wlan.update_wo_rx_stats = NULL;
+ 			 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;
@@ -294,10 +270,9 @@
 +		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.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
deleted file mode 100644
index 5897422..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
+++ /dev/null
@@ -1,473 +0,0 @@
-From cc7283ecc1da9d4f62803062466fb5420d2ea766 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 2007/2008] 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      | 140 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/main.c     |   7 +++
- mt7996/mcu.c      |  64 +++++++++++++++++++++
- mt7996/mcu.h      |  34 +++++++++++
- mt7996/mt7996.h   |  32 +++++++++++
- mt7996/regs.h     |   5 ++
- 9 files changed, 287 insertions(+)
-
-diff --git a/mt76.h b/mt76.h
-index e4351338..7ebcf432 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -436,6 +436,7 @@ struct mt76_rx_tid {
- 	u16 nframes;
- 
- 	u8 num;
-+	u8 partial_id;
- 
- 	u8 started:1, stopped:1, timer_pending:1;
- 
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index a53fa138..d74fd2dd 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1023,6 +1023,7 @@ enum {
- 	MCU_UNI_EVENT_THERMAL = 0x35,
- 	MCU_UNI_EVENT_BF = 0x33,
- 	MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
-+	MCU_UNI_EVENT_RRO = 0x57,
- };
- 
- #define MCU_UNI_CMD_EVENT			BIT(1)
-diff --git a/mt7996/init.c b/mt7996/init.c
-index d70dcf9f..93262297 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -759,6 +759,9 @@ static int mt7996_rro_init(struct mt7996_dev *dev)
- 	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
- 		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
- 
-+	INIT_DELAYED_WORK(&dev->rro.rro_del_work, mt7996_rro_delete_sessions);
-+	INIT_LIST_HEAD(&dev->rro.rro_poll_list);
-+
- 	/* rro ind cmd queue init */
- 	return mt7996_dma_rro_init(dev);
- }
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 4fbbc077..3a89013c 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1647,6 +1647,139 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 	}
- }
- 
-+static struct mt7996_rro_addr *
-+mt7996_rro_get_addr_elem(struct mt7996_dev *dev, u16 seid, u16 sn)
-+{
-+	struct mt7996_rro_cfg *rro = &dev->rro;
-+	u32 idx;
-+	void *addr;
-+
-+	if (seid == rro->particular_se_id) {
-+		addr = rro->particular_session_va;
-+		idx = sn % rro->win_sz;
-+	} else {
-+		addr = rro->addr_elem_alloc_va[seid / MT7996_RRO_SESSION_PER_CR];
-+		idx = (seid % MT7996_RRO_SESSION_PER_CR) * rro->win_sz
-+			+ (sn % rro->win_sz);
-+	}
-+	return addr + idx * sizeof(struct mt7996_rro_addr);
-+}
-+
-+static bool mt7996_rro_reset_sessions(struct mt7996_dev *dev,
-+				  u16 wcid, u8 partial_id)
-+{
-+	u32 sid = ((wcid & 0x7F) << 3) + partial_id;
-+	u32 value[2];
-+	struct mt7996_rro_ba_session *s;
-+	struct  mt7996_rro_addr *elem;
-+	int i;
-+
-+	mt76_wr(dev, MT_RRO_DBG_RD_CTRL, MT_RRO_DBG_RD_EXEC |
-+		sid >> 1 | 0x200);
-+
-+	if (sid & 0x1) {
-+		value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(2));
-+		value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(2));
-+	} else {
-+		value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(0));
-+		value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(1));
-+	}
-+
-+	s = (struct mt7996_rro_ba_session *)&value[0];
-+	if (!s->cn && s->ack_sn == s->last_in_sn) {
-+		for (i = 0; i < MT7996_RRO_WIN_SIZE_MAX; i++) {
-+			elem = mt7996_rro_get_addr_elem(dev, sid, i);
-+			elem->signature = 0xff;
-+		}
-+		return true;
-+	}
-+
-+	return false;
-+}
-+
-+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,
-+					       rro.rro_del_work.work);
-+	elem_nums = dev->rro.elem_nums;
-+
-+	spin_lock_bh(&dev->rro.rro_stbl_lock);
-+	list_splice_init(&dev->rro.rro_poll_list, &rro_poll_list);
-+	spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+
-+	do {
-+		spin_lock_bh(&dev->rro.rro_stbl_lock);
-+		if (list_empty(&rro_poll_list)) {
-+			spin_unlock_bh(&dev->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->rro.rro_stbl_lock);
-+			break;
-+		}
-+		list_del_init(&e->poll_list);
-+		spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+
-+		if (mt7996_rro_reset_sessions(dev, e->wlan_idx,
-+					      e->partial_id)) {
-+			mt7996_mcu_reset_rro_sessions(dev, e->wlan_idx,
-+						      e->tid, e->partial_id);
-+			kfree(e);
-+			dev->rro.elem_nums--;
-+		} else {
-+			spin_lock_bh(&dev->rro.rro_stbl_lock);
-+			list_add_tail(&e->poll_list, &dev->rro.rro_poll_list);
-+			spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+		}
-+		elem_nums--;
-+	} while (elem_nums);
-+
-+	if (list_empty(&rro_poll_list))
-+		ieee80211_queue_delayed_work(mt76_hw(dev),
-+					     &dev->rro.rro_del_work,
-+					     MT7996_WATCHDOG_TIME);
-+}
-+
-+int mt7996_rro_add_delete_elem(struct mt7996_dev *dev,
-+			       struct mt7996_sta *msta, u8 tidno)
-+{
-+	struct mt76_rx_tid *tid = NULL;
-+	struct mt76_wcid *wcid = &msta->wcid;
-+	struct mt7996_rro_ba_session_elem *e;
-+	u16 idx = msta->wcid.idx;
-+
-+	tid = rcu_dereference(wcid->aggr[tidno]);
-+	if (!tid)
-+		return 0;
-+
-+	e = kzalloc(sizeof(*e), GFP_ATOMIC);
-+	if (!e)
-+		return -ENOMEM;
-+
-+	e->wlan_idx = idx;
-+	e->tid = tidno;
-+	e->partial_id = tid->partial_id;
-+
-+	spin_lock_bh(&dev->rro.rro_stbl_lock);
-+	list_add_tail(&e->poll_list, &dev->rro.rro_poll_list);
-+	spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+	dev->rro.elem_nums++;
-+
-+	ieee80211_queue_delayed_work(mt76_hw(dev),
-+				     &dev->rro.rro_del_work,
-+				     MT7996_WATCHDOG_TIME);
-+	return 0;
-+}
-+
- void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy)
- {
- 	struct mt7996_dev *dev = phy->dev;
-@@ -1971,6 +2104,9 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
- 	if (phy3)
- 		ieee80211_stop_queues(phy3->mt76->hw);
- 
-+	if (dev->rro_support)
-+		cancel_delayed_work_sync(&dev->rro.rro_del_work);
-+
- 	cancel_delayed_work_sync(&dev->mphy.mac_work);
- 	if (phy2)
- 		cancel_delayed_work_sync(&phy2->mt76->mac_work);
-@@ -2062,6 +2198,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->rro_support)
-+		cancel_delayed_work_sync(&dev->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/main.c b/mt7996/main.c
-index cebac4ab..4cb72220 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -119,6 +119,9 @@ static void mt7996_stop(struct ieee80211_hw *hw)
- 	struct mt7996_dev *dev = mt7996_hw_dev(hw);
- 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
- 
-+	if (dev->rro_support)
-+		cancel_delayed_work_sync(&dev->rro.rro_del_work);
-+
- 	cancel_delayed_work_sync(&phy->mt76->mac_work);
- 	cancel_delayed_work_sync(&dev->scs_work);
- 
-@@ -797,6 +800,10 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 		ret = mt7996_mcu_add_rx_ba(dev, params, true);
- 		break;
- 	case IEEE80211_AMPDU_RX_STOP:
-+		if (dev->rro_support)  {
-+			ret = mt7996_rro_add_delete_elem(dev, msta,
-+							 params->tid);
-+		}
- 		mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
- 		ret = mt7996_mcu_add_rx_ba(dev, params, false);
- 		break;
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 0c01e90b..094f3656 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -476,6 +476,41 @@ mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
- 	phy->throttle_state = n->duty_percent;
- }
- 
-+static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
-+{
-+	struct mt7996_mcu_rro_event *event;
-+
-+	if (!dev->rro_support)
-+		return;
-+
-+	event = (struct mt7996_mcu_rro_event*)skb->data;
-+
-+	switch (event->tag) {
-+	case UNI_RRO_BA_SESSION_STATUS: {
-+		struct mt7996_mcu_rro_ba *rro = (struct mt7996_mcu_rro_ba *)skb->data;
-+		u16 idx = 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->partial_id = rro->partial_id;
-+
-+		break;
-+	}
-+	default:
-+		dev_info(dev->mt76.dev, "%s: unknown rro event tag %d\n",
-+			 __func__, event->tag);
-+		break;
-+	}
-+
-+}
-+
- static void
- mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb)
- {
-@@ -528,6 +563,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;
- 	}
-@@ -4533,6 +4571,32 @@ 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 wcid, u8 tid, u8 pid)
-+{
-+	struct {
-+		/* fixed field */
-+		u8 __rsv[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+		u16 wcid;
-+		u8 tid;
-+		u8 partial_id;
-+		u8 pad[4];
-+	} __packed req = {
-+		.tag = cpu_to_le16(UNI_RRO_DEL_BA_SESSION),
-+		.len = cpu_to_le16(sizeof(req) - 4),
-+		.wcid = wcid,
-+		.tid = tid,
-+		.partial_id = pid,
-+	};
-+
-+	return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(RRO),
-+				 &req, sizeof(req), true);
-+}
-+
-+
- int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data)
- {
- 	struct mt7996_dev *dev = phy->dev;
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index ec074bc6..10e3799f 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -191,6 +191,38 @@ 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 {
-+	struct mt7996_mcu_rro_event event;
-+
-+	u16 wlan_id;
-+	u8 tid;
-+	u8 partial_id;
-+	__le32 status;
-+}__packed;
-+
-+enum  {
-+	UNI_RRO_BA_SESSION_STATUS = 0,
-+	UNI_RRO_BA_SESSION_TBL	= 1,
-+	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,
-@@ -718,6 +750,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 b239c44c..88d42c3a 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -310,6 +310,28 @@ struct mt7996_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 wlan_idx;
-+	u8 tid;
-+	u8 partial_id;
-+};
-+
- struct mt7996_rro_cfg {
- 	u32 ind_signature;
- 	void *ba_bitmap_cache_va[MT7996_RRO_BA_BITMAP_CR_CNT];
-@@ -324,6 +346,11 @@ struct mt7996_rro_cfg {
- 	spinlock_t lock;
- 	struct list_head pg_addr_cache;
- 	struct list_head pg_hash_head[MT7996_RRO_MSDU_PG_HASH_SIZE];
-+
-+	struct delayed_work rro_del_work;
-+	spinlock_t rro_stbl_lock;
-+	struct list_head rro_poll_list;
-+	u16 elem_nums;
- };
- 
- struct mt7996_phy {
-@@ -670,6 +697,8 @@ 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 wcid, u8 tid, u8 pid);
- 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);
-@@ -768,6 +797,9 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- 			  struct mt76_tx_info *tx_info);
- void mt7996_tx_token_put(struct mt7996_dev *dev);
- int mt7996_dma_rro_init(struct mt7996_dev *dev);
-+void  mt7996_rro_delete_sessions(struct work_struct *work);
-+int mt7996_rro_add_delete_elem(struct mt7996_dev *dev,
-+			       struct mt7996_sta *msta, u8 tid);
- 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 6624685e..f97c87c9 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -72,6 +72,11 @@ enum base_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)
--- 
-2.39.2
-
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/2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
new file mode 100644
index 0000000..2688d54
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
@@ -0,0 +1,66 @@
+From 50c902b8856af271bc5514d623ad09f7c3f2d880 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
+
+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.
+Add len == 0 check to drop garbage frames
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ dma.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 141a97b..3983ebb 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,
+ 	}
+ 
+ 	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;
++
++		if (*more) {
++			spin_lock_bh(&dev->rx_token_lock);
++
++			idr_for_each_entry(&dev->rx_token, r, id) {
++				if (r->dma_addr == le32_to_cpu(desc->buf0)) {
++					find = 1;
++					token = id;
++
++					/* Write correct id back to DMA*/
++					u32p_replace_bits(&buf1, id,
++							  MT_DMA_CTL_TOKEN);
++					WRITE_ONCE(desc->buf1, cpu_to_le32(buf1));
++					break;
++				}
++			}
+ 
++			spin_unlock_bh(&dev->rx_token_lock);
++			if (!find)
++				return NULL;
++		}
++
++		r = mt76_rx_token_release(dev, token);
+ 		if (!r)
+ 			return NULL;
+ 
+@@ -965,7 +988,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+ 		if (!data)
+ 			break;
+ 
+-		if (drop)
++		if (drop || (len == 0))
+ 			goto free_frag;
+ 
+ 		if (q->rx_head)
+-- 
+2.18.0
+
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
new file mode 100644
index 0000000..675e4eb
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2009-wifi-mt76-drop-packet-based-on-ind_reason.patch
@@ -0,0 +1,77 @@
+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-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
new file mode 100644
index 0000000..6fe2cea
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2010-wifi-mt76-mt7996-add-rro-timeout-setting.patch
@@ -0,0 +1,94 @@
+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/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
new file mode 100644
index 0000000..fec02ea
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2011-wifi-mt76-mt7996-add-dma-mask-limitation.patch
@@ -0,0 +1,84 @@
+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-wifi-mt76-mt7996-add-per-bss-statistic-info.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
new file mode 100644
index 0000000..3295f14
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
@@ -0,0 +1,122 @@
+From d97655d3fe3ddf2bbd508de52e207bc91d0115e2 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
+
+Whenever WED is enabled, unicast traffic might run through HW path.
+As a result, we need to count them using WM event.
+Broadcast and multicast traffic on the other hand, will be counted in mac80211
+as they always go through SW path and thus mac80211 can always see and count them.
+
+|         | Tx                             | Rx                        |
+|---------|--------------------------------|---------------------------|
+| Unicast | mt76                           | mt76                      |
+|         | __mt7996_stat_to_netdev()      | __mt7996_stat_to_netdev() |
+|---------|--------------------------------|---------------------------|
+| BMCast  | mac80211                       | mac80211                  |
+|         | __ieee80211_subif_start_xmit() | ieee80211_deliver_skb()   |
+---
+ mt7996/init.c |  1 +
+ mt7996/main.c |  1 +
+ mt7996/mcu.c  | 40 +++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 37 insertions(+), 5 deletions(-)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 51649dd..20e14e7 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)
+ 	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);
++	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STAS_COUNT);
+ 
+ 	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
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -251,6 +251,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
+ 	mvif->sta.wcid.phy_idx = band_idx;
+ 	mvif->sta.wcid.hw_key_idx = -1;
+ 	mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;
++	mvif->sta.vif = mvif;
+ 	mt76_wcid_init(&mvif->sta.wcid);
+ 
+ 	mt7996_mac_wtbl_update(dev, idx,
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index bebd020..b2cb627 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)
+ 
+ }
+ 
++static inline void __mt7996_stat_to_netdev(struct mt76_phy *mphy,
++					   struct mt76_wcid *wcid,
++					   u32 tx_bytes, u32 rx_bytes,
++					   u32 tx_packets, u32 rx_packets)
++{
++	struct mt7996_sta *msta;
++	struct ieee80211_vif *vif;
++	struct wireless_dev *wdev;
++
++	if (wiphy_ext_feature_isset(mphy->hw->wiphy,
++				    NL80211_EXT_FEATURE_STAS_COUNT)) {
++		msta = container_of(wcid, struct mt7996_sta, wcid);
++		vif = container_of((void *)msta->vif, struct ieee80211_vif,
++				   drv_priv);
++		wdev = ieee80211_vif_to_wdev(vif);
++
++		dev_sw_netstats_tx_add(wdev->netdev, tx_packets, tx_bytes);
++		dev_sw_netstats_rx_add(wdev->netdev, rx_packets, rx_bytes);
++	}
++}
++
+ 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)
+ 		u16 wlan_idx;
+ 		struct mt76_wcid *wcid;
+ 		struct mt76_phy *mphy;
+-		u32 tx_bytes, rx_bytes;
++		u32 tx_bytes, rx_bytes, tx_packets, rx_packets;
+ 
+ 		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)
+ 				wcid->stats.tx_bytes += tx_bytes;
+ 				wcid->stats.rx_bytes += rx_bytes;
+ 
++				__mt7996_stat_to_netdev(mphy, wcid,
++							tx_bytes, rx_bytes, 0, 0);
++
+ 				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)
+ 			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);
++			mphy = mt76_dev_phy(&dev->mt76, wcid->phy_idx);
++
++			tx_packets = le32_to_cpu(res->msdu_cnt[i].tx_msdu_cnt);
++			rx_packets = le32_to_cpu(res->msdu_cnt[i].rx_msdu_cnt);
++
++			wcid->stats.tx_packets += tx_packets;
++			wcid->stats.rx_packets += rx_packets;
++
++			__mt7996_stat_to_netdev(mphy, wcid, 0, 0,
++						tx_packets, rx_packets);
+ 			break;
+ 		default:
+ 			break;
+-- 
+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
new file mode 100644
index 0000000..8dd2d61
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2013-wifi-mt76-mt7996-support-TX-RX-for-Kite-without-WED-.patch
@@ -0,0 +1,234 @@
+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-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch
new file mode 100644
index 0000000..a581775
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch
@@ -0,0 +1,528 @@
+From dda3205c68ab3b38945f0066be5fc95ba067f3af 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
+
+---
+ mt7996/init.c   |  43 ++++++++
+ mt7996/mcu.c    | 263 +++++++++++++++++++++++++++++++++++++++++++-----
+ mt7996/mcu.h    |   1 +
+ mt7996/mt7996.h |  94 +++++++++++++++++
+ 4 files changed, 376 insertions(+), 25 deletions(-)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index d539af0..d1db1d7 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -553,6 +553,37 @@ int mt7996_txbf_init(struct mt7996_dev *dev)
+ 	return mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);
+ }
+ 
++static int mt7996_vow_init(struct mt7996_phy *phy)
++{
++	struct mt7996_vow_ctrl *vow = &phy->dev->vow;
++	int ret;
++
++	vow->atf_enable = true;
++	vow->watf_enable = false;
++	vow->max_deficit = 64;
++	vow->sch_type = VOW_SCH_TYPE_FOLLOW_POLICY;
++	vow->sch_policy = VOW_SCH_POLICY_SRR;
++
++	vow->drr_quantum[0] = VOW_DRR_QUANTUM_L0;
++	vow->drr_quantum[1] = VOW_DRR_QUANTUM_L1;
++	vow->drr_quantum[2] = VOW_DRR_QUANTUM_L2;
++	vow->drr_quantum[3] = VOW_DRR_QUANTUM_L3;
++	vow->drr_quantum[4] = VOW_DRR_QUANTUM_L4;
++	vow->drr_quantum[5] = VOW_DRR_QUANTUM_L5;
++	vow->drr_quantum[6] = VOW_DRR_QUANTUM_L6;
++	vow->drr_quantum[7] = VOW_DRR_QUANTUM_L7;
++
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, NULL, VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND);
++	if (ret)
++		return ret;
++
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, NULL, VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL);
++	if (ret)
++		return ret;
++
++	return mt7996_mcu_set_vow_feature_ctrl(phy);
++}
++
+ 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,
+ 	if (ret)
+ 		goto error;
+ 
++	if (mt7996_vow_should_enable(dev)) {
++		ret = mt7996_vow_init(phy);
++		if (ret)
++			goto error;
++	}
++
+ 	ret = mt7996_init_debugfs(phy);
+ 	if (ret)
+ 		goto error;
+@@ -1315,6 +1352,12 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ 
+ 	dev->recovery.hw_init_done = true;
+ 
++	if (mt7996_vow_should_enable(dev)) {
++		ret = mt7996_vow_init(&dev->phy);
++		if (ret)
++			goto error;
++	}
++
+ 	ret = mt7996_init_debugfs(&dev->phy);
+ 	if (ret)
+ 		goto error;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index b2cb627..1915a22 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,
+ }
+ 
+ static int
+-mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+-		     struct ieee80211_sta *sta)
++mt7996_mcu_sta_init_vow(struct mt7996_phy *phy, struct mt7996_sta *msta)
+ {
+-#define MT_STA_BSS_GROUP		1
+-	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+-	struct mt7996_sta *msta;
+-	struct {
+-		u8 __rsv1[4];
++	struct mt7996_vow_sta_ctrl *vow = &msta->vow;
++	u8 omac_idx = msta->vif->mt76.omac_idx;
++	int ret;
+ 
+-		__le16 tag;
+-		__le16 len;
+-		__le16 wlan_idx;
+-		u8 __rsv2[2];
+-		__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(MT_STA_BSS_GROUP),
+-		.val = cpu_to_le32(mvif->mt76.idx % 16),
+-	};
++	/* Assignment of STA BSS group index aligns FW.
++	 * Each band has its own BSS group bitmap space.
++	 * 0: BSS 0
++	 * 4..18: BSS 0x11..0x1f
++	 */
++	vow->bss_grp_idx = (omac_idx <= HW_BSSID_MAX)
++	                   ? omac_idx
++	                   : HW_BSSID_MAX + omac_idx - EXT_BSSID_START;
++	vow->paused = false;
++	vow->drr_quantum[IEEE80211_AC_VO] = VOW_DRR_QUANTUM_IDX0;
++	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;
++
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_BSS_GROUP);
++	if (ret)
++		return ret;
+ 
+-	msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta;
+-	req.wlan_idx = cpu_to_le16(msta->wcid.idx);
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_PAUSE);
++	if (ret)
++		return ret;
+ 
+-	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
+-				 sizeof(req), true);
++	return mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_ALL);
+ }
+ 
+ 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,
+ 		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
+ 	}
+ 
+-	ret = mt7996_mcu_add_group(dev, vif, sta);
++	ret = mt7996_mcu_sta_init_vow(mvif->phy, msta);
+ 	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);
+ }
+ 
++int mt7996_mcu_set_vow_drr_ctrl(struct mt7996_phy *phy, struct mt7996_sta *msta,
++	                        enum vow_drr_ctrl_id id)
++{
++	struct mt7996_vow_sta_ctrl *vow = msta ? &msta->vow : NULL;
++	u32 val = 0;
++	struct {
++		u8 __rsv1[4];
++
++		__le16 tag;
++		__le16 len;
++		__le16 wlan_idx;
++		u8 band_idx;
++		u8 wmm_idx;
++		__le32 ctrl_id;
++
++		union {
++			__le32 val;
++			u8 drr_quantum[VOW_DRR_QUANTUM_NUM];
++		};
++
++		u8 __rsv2[3];
++		u8 omac_idx;
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_VOW_DRR_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.wlan_idx = cpu_to_le16(msta ? msta->wcid.idx : 0),
++		.band_idx = phy->mt76->band_idx,
++		.wmm_idx = msta ? msta->vif->mt76.wmm_idx : 0,
++		.ctrl_id = cpu_to_le32(id),
++		.omac_idx = msta ? msta->vif->mt76.omac_idx : 0
++	};
++
++	switch (id) {
++	case VOW_DRR_CTRL_STA_ALL:
++		val |= FIELD_PREP(MT7996_DRR_STA_BSS_GRP_MASK, vow->bss_grp_idx);
++		val |= FIELD_PREP(MT7996_DRR_STA_AC0_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_BK]);
++		val |= FIELD_PREP(MT7996_DRR_STA_AC1_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_BE]);
++		val |= FIELD_PREP(MT7996_DRR_STA_AC2_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_VI]);
++		val |= FIELD_PREP(MT7996_DRR_STA_AC3_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_VO]);
++		req.val = cpu_to_le32(val);
++		break;
++	case VOW_DRR_CTRL_STA_BSS_GROUP:
++		req.val = cpu_to_le32(vow->bss_grp_idx);
++		break;
++	case VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND:
++		req.val = cpu_to_le32(phy->dev->vow.max_deficit);
++		break;
++	case VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL:
++		memcpy(req.drr_quantum, phy->dev->vow.drr_quantum, VOW_DRR_QUANTUM_NUM);
++		break;
++	case VOW_DRR_CTRL_STA_PAUSE:
++		req.val = cpu_to_le32(vow->paused);
++		break;
++	default:
++		dev_err(phy->dev->mt76.dev, "Unknown VoW DRR Control ID: %u\n", id);
++		return -EINVAL;
++	}
++
++	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(VOW),
++	                         &req, sizeof(req), true);
++}
++
++int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy)
++{
++	struct mt7996_vow_ctrl *vow = &phy->dev->vow;
++	struct {
++		u8 __rsv1[4];
++
++		__le16 tag;
++		__le16 len;
++
++		/* DW0 */
++		__le16 apply_bwc_enable_per_grp;
++		__le16 apply_bwc_refill_period		: 1;
++		__le16 __rsv2				: 3;
++		__le16 apply_band1_search_rule		: 1;
++		__le16 apply_band0_search_rule		: 1;
++		__le16 __rsv3				: 3;
++		__le16 apply_watf_enable		: 1;
++		__le16 __rsv4				: 2;
++		__le16 apply_grp_no_change_in_txop	: 1;
++		__le16 apply_atf_enable			: 1;
++		__le16 apply_bwc_token_refill_enable	: 1;
++		__le16 apply_bwc_enable			: 1;
++
++		/* DW1 */
++		__le16 apply_bwc_check_time_token_per_grp;
++		__le16 __rsv5;
++
++		/* DW2 */
++		__le16 apply_bwc_check_len_token_per_grp;
++		__le16 __rsv6;
++
++		/* DW3 */
++		u8 band_idx;
++		u8 __rsv7[3];
++
++		/* DW4 */
++		__le32 __rsv8;
++
++		/* DW5 */
++		__le16 bwc_enable_per_grp;
++		__le16 bwc_refill_period	: 3;
++		__le16 __rsv9			: 1;
++		__le16 band1_search_rule	: 1;
++		__le16 band0_search_rule	: 1;
++		__le16 __rsv10			: 3;
++		__le16 watf_enable		: 1;
++		__le16 __rsv11			: 2;
++		__le16 grp_no_change_in_txop	: 1;
++		__le16 atf_enable		: 1;
++		__le16 bwc_token_refill_enable	: 1;
++		__le16 bwc_enable		: 1;
++
++		/* DW6 */
++		__le16 bwc_check_time_token_per_grp;
++		__le16 __rsv12;
++
++		/* DW7 */
++		__le16 bwc_check_len_token_per_grp;
++		__le16 __rsv13;
++
++		/* DW8 */
++		__le32 apply_atf_rts_sta_lock		: 1;
++		__le32 atf_rts_sta_lock			: 1;
++		__le32 apply_atf_keep_quantum		: 1;
++		__le32 atf_keep_quantum			: 1;
++		__le32 apply_tx_cnt_mode_ctrl		: 1;
++		__le32 tx_cnt_mode_ctrl			: 4;
++		__le32 apply_tx_measure_mode_enable	: 1;
++		__le32 tx_measure_mode_enable		: 1;
++		__le32 apply_backoff_ctrl		: 1;
++		__le32 backoff_bound_enable		: 1;
++		__le32 backoff_bound			: 5;
++		__le32 apply_atf_rts_fail_charge	: 1;
++		__le32 atf_rts_fail_charge		: 1;
++		__le32 apply_zero_eifs			: 1;
++		__le32 zero_eifs			: 1;
++		__le32 apply_rx_rifs_enable		: 1;
++		__le32 rx_rifs_enable			: 1;
++		__le32 apply_vow_ctrl			: 1;
++		__le32 vow_ctrl_val			: 1;
++		__le32 vow_ctrl_bit			: 5;
++		__le32 __rsv14				: 1;
++
++		/* DW9 */
++		__le32 apply_spl_sta_num	: 1;
++		__le32 spl_sta_num		: 3;
++		__le32 dbg_lvl			: 2;
++		__le32 apply_atf_sch_ctrl	: 1;
++		__le32 atf_sch_type		: 2;
++		__le32 atf_sch_policy		: 2;
++		__le32 __rsv15			: 21;
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_VOW_FEATURE_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		/* DW0 */
++		.apply_bwc_enable_per_grp = cpu_to_le16(0xffff),
++		.apply_bwc_refill_period = true,
++		.apply_band1_search_rule = true,
++		.apply_band0_search_rule = true,
++		.apply_watf_enable = true,
++		.apply_grp_no_change_in_txop = true,
++		.apply_atf_enable = true,
++		.apply_bwc_token_refill_enable = true,
++		.apply_bwc_enable = true,
++		/* DW1 */
++		.apply_bwc_check_time_token_per_grp = cpu_to_le16(0xffff),
++		/* DW2 */
++		.apply_bwc_check_len_token_per_grp = cpu_to_le16(0xffff),
++		/* DW3 */
++		.band_idx = phy->mt76->band_idx,
++		/* DW5 */
++		.bwc_enable_per_grp = cpu_to_le16(0xffff),
++		.bwc_refill_period = VOW_REFILL_PERIOD_32US,
++		.band1_search_rule = VOW_SEARCH_WMM_FIRST,
++		.band0_search_rule = VOW_SEARCH_WMM_FIRST,
++		.watf_enable = vow->watf_enable,
++		.grp_no_change_in_txop = true,
++		.atf_enable = vow->atf_enable,
++		.bwc_token_refill_enable = true,
++		.bwc_enable = false,
++		/* DW6 */
++		.bwc_check_time_token_per_grp = cpu_to_le16(0x0),
++		/* DW7 */
++		.bwc_check_len_token_per_grp = cpu_to_le16(0x0),
++		/* DW8 */
++		.apply_atf_rts_sta_lock = false,
++		.apply_atf_keep_quantum = true,
++		.atf_keep_quantum = true,
++		.apply_tx_cnt_mode_ctrl = false,
++		.apply_tx_measure_mode_enable = false,
++		.apply_backoff_ctrl = false,
++		.apply_atf_rts_fail_charge = false,
++		.apply_zero_eifs = false,
++		.apply_rx_rifs_enable = false,
++		.apply_vow_ctrl = true,
++		.vow_ctrl_val = true,
++		/* Reset DRR table when SER occurs. */
++		.vow_ctrl_bit = 26,
++		/* DW9 */
++		.apply_spl_sta_num = false,
++		.dbg_lvl = 0,
++		.apply_atf_sch_ctrl = true,
++		.atf_sch_type = vow->sch_type,
++		.atf_sch_policy = vow->sch_policy
++	};
++
++	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(VOW),
++	                         &req, sizeof(req), 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 0aa68f7..fb81645 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -860,6 +860,7 @@ enum {
+ 
+ enum {
+ 	UNI_VOW_DRR_CTRL,
++	UNI_VOW_FEATURE_CTRL,
+ 	UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
+ 	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
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -107,6 +107,12 @@
+ #define MT7996_RX_MSDU_PAGE_SIZE	(128 + \
+ 					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+ 
++#define MT7996_DRR_STA_BSS_GRP_MASK	GENMASK(5, 0)
++#define MT7996_DRR_STA_AC0_QNTM_MASK	GENMASK(10, 8)
++#define MT7996_DRR_STA_AC1_QNTM_MASK	GENMASK(14, 12)
++#define MT7996_DRR_STA_AC2_QNTM_MASK	GENMASK(18, 16)
++#define MT7996_DRR_STA_AC3_QNTM_MASK	GENMASK(22, 20)
++
+ struct mt7996_vif;
+ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+@@ -187,6 +193,79 @@ struct mt7996_twt_flow {
+ 
+ DECLARE_EWMA(avg_signal, 10, 8)
+ 
++enum {
++	VOW_SEARCH_AC_FIRST,
++	VOW_SEARCH_WMM_FIRST
++};
++
++enum {
++	VOW_REFILL_PERIOD_1US,
++	VOW_REFILL_PERIOD_2US,
++	VOW_REFILL_PERIOD_4US,
++	VOW_REFILL_PERIOD_8US,
++	VOW_REFILL_PERIOD_16US,
++	VOW_REFILL_PERIOD_32US,
++	VOW_REFILL_PERIOD_64US,
++	VOW_REFILL_PERIOD_128US
++};
++
++/* Default DRR airtime quantum of each level */
++enum {
++	VOW_DRR_QUANTUM_L0 = 6,
++	VOW_DRR_QUANTUM_L1 = 12,
++	VOW_DRR_QUANTUM_L2 = 16,
++	VOW_DRR_QUANTUM_L3 = 20,
++	VOW_DRR_QUANTUM_L4 = 24,
++	VOW_DRR_QUANTUM_L5 = 28,
++	VOW_DRR_QUANTUM_L6 = 32,
++	VOW_DRR_QUANTUM_L7 = 36
++};
++
++enum {
++	VOW_DRR_QUANTUM_IDX0,
++	VOW_DRR_QUANTUM_IDX1,
++	VOW_DRR_QUANTUM_IDX2,
++	VOW_DRR_QUANTUM_IDX3,
++	VOW_DRR_QUANTUM_IDX4,
++	VOW_DRR_QUANTUM_IDX5,
++	VOW_DRR_QUANTUM_IDX6,
++	VOW_DRR_QUANTUM_IDX7,
++	VOW_DRR_QUANTUM_NUM
++};
++
++enum {
++	VOW_SCH_TYPE_FOLLOW_POLICY,
++	VOW_SCH_TYPE_FOLLOW_HW
++};
++
++enum {
++	VOW_SCH_POLICY_SRR, /* Shared Round-Robin */
++	VOW_SCH_POLICY_WRR /* Weighted Round-Robin */
++};
++
++enum vow_drr_ctrl_id {
++	VOW_DRR_CTRL_STA_ALL,
++	VOW_DRR_CTRL_STA_BSS_GROUP,
++	VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND = 0x10,
++	VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL = 0x28,
++	VOW_DRR_CTRL_STA_PAUSE = 0x30
++};
++
++struct mt7996_vow_ctrl {
++	bool atf_enable;
++	bool watf_enable;
++	u8 drr_quantum[VOW_DRR_QUANTUM_NUM];
++	u8 max_deficit;
++	u8 sch_type;
++	u8 sch_policy;
++};
++
++struct mt7996_vow_sta_ctrl {
++	bool paused;
++	u8 bss_grp_idx;
++	u8 drr_quantum[IEEE80211_NUM_ACS];
++};
++
+ struct mt7996_sta {
+ 	struct mt76_wcid wcid; /* must be first */
+ 
+@@ -206,6 +285,8 @@ struct mt7996_sta {
+ 		u8 flowid_mask;
+ 		struct mt7996_twt_flow flow[MT7996_MAX_STA_TWT_AGRT];
+ 	} twt;
++
++	struct mt7996_vow_sta_ctrl vow;
+ };
+ 
+ struct mt7996_vif {
+@@ -470,6 +551,7 @@ struct mt7996_dev {
+ 
+ 	u8 wtbl_size_group;
+ 
++	struct mt7996_vow_ctrl vow;
+ #ifdef CONFIG_MTK_DEBUG
+ 	u16 wlan_idx;
+ 	struct {
+@@ -697,6 +779,10 @@ 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
+ 
++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)
+ {
+ 	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)
+ 	return tx_chainmask | (BIT(fls(tx_chainmask)) * phy->has_aux_rx);
+ }
+ 
++static inline bool
++mt7996_vow_should_enable(struct mt7996_dev *dev)
++{
++	return !wiphy_ext_feature_isset(mt76_hw(dev)->wiphy,
++	                                NL80211_EXT_FEATURE_AIRTIME_FAIRNESS) ||
++	       mtk_wed_device_active(&dev->mt76.mmio.wed);
++}
++
+ 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/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
new file mode 100644
index 0000000..a6ffa60
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2999-wifi-mt76-mt7996-support-backaward-compatiable.patch
@@ -0,0 +1,146 @@
+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 dda4d93..f1b8285 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
@@ -1,67 +1,82 @@
 #patch patches (come from openwrt/lede/target/linux/mediatek)
 SRC_URI_append = " \
-    file://0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch \
-    file://0002-wifi-mt76-mt7996-move-radio-ctrl-commands-to-proper-.patch \
-    file://0003-wifi-mt76-connac-add-support-for-dsp-firmware-downlo.patch \
-    file://0004-wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch \
-    file://0005-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch \
-    file://0006-wifi-mt76-mt7996-enable-VHT-extended-NSS-BW-feature.patch \
-    file://0007-wifi-mt76-connac-add-support-to-set-ifs-time-by-mcu-.patch \
-    file://0008-wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch \
-    file://0009-wifi-mt76-mt7996-fix-WA-event-ring-size.patch \
-    file://0010-wifi-mt76-mt7996-add-muru-support.patch \
-    file://0011-wifi-mt76-mt7996-increase-tx-token-size.patch \
-    file://0014-wifi-mt76-mt7996-set-wcid-in-txp.patch \
-    file://0015-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch \
-    file://0016-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch \
-    file://0017-wifi-mt76-mt7996-add-thermal-protection-support.patch \
-    file://0018-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch \
-    file://0019-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch \
-    file://0020-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch \
-    file://0021-wifi-mt76-mt7996-update-wmm-queue-mapping.patch \
-    file://0022-wifi-mt76-mt7996-enable-IDS-debug-log.patch \
-    file://0023-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch \
-    file://0024-wifi-mt76-testmode-add-basic-testmode-support.patch \
-    file://0026-wifi-mt76-mt7996-add-led-feature-support.patch \
-    file://0027-wifi-mt76-mt7996-fix-twt-mcu-command.patch \
-    file://0028-wifi-mt76-mt7996-add-11v-mbss-support-for-mt76.patch \
-    file://0029-wifi-mt76-mt7996-Update-beacon-size-limitation-for-1.patch \
-    file://0030-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch \
-    file://0031-wifi-mt76-mt7996-fix-memory-leak.patch \
-    file://0032-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch \
-    file://0033-wifi-mt76-mt7996-disable-wfdma-tx-rx-during-SER.patch \
-    file://0034-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch \
-    file://0035-wifi-mt76-mt7996-make-band-capability-init-flexible.patch \
-    file://0036-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch \
-    file://0037-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch \
-    file://0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch \
-    file://0039-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch \
-    file://0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch \
-    file://0041-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch \
+    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-txpower-support.patch \
-    file://1002-wifi-mt76-mt7996-add-mu-vendor-command-support.patch \
-    file://1003-wifi-mt76-mt7996-Add-air-monitor-support.patch \
-    file://1004-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch \
-    file://1005-wifi-mt76-mt7996-add-U-NII-4-support.patch \
-    file://1006-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch \
-    file://1007-wifi-mt76-mt7996-add-binfile-mode-support.patch \
-    file://1008-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch \
-    file://1009-wifi-mt76-mt7996-Beacon-protection-feature-added.patch \
-    file://1010-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch \
-    file://1011-wifi-mt76-mt7996-add-single-sku.patch \
-    file://1012-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch \
-    file://1013-wifi-mt76-mt7996-get-tx_retries-and-tx_fails-from-tx.patch \
-    file://1014-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch \
-    file://1015-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch \
-    file://2000-wifi-mt76-rework-wed-rx-flow.patch \
-    file://2001-wifi-mt76-revert-page_poll-for-kernel-5.4.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-mt7996-wed-add-wed3.0-tx-support.patch \
-    file://2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch \
-    file://2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch \
-    file://2006-wifi-mt76-add-random-early-drop-support.patch \
-    file://2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch \
-    file://2008-wifi-mt76-add-SER-support-for-wed3.0.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 \
     "
diff --git a/recipes-wifi/linux-mt76/files/patches/0009-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
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches/0009-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
rename to recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
index b752c0e..39ad5d0 100644
--- a/recipes-wifi/linux-mt76/files/patches/0009-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 809ef0860a8e3f3fe223cd2842d882e203124639 Mon Sep 17 00:00:00 2001
+From 5b47f914de6c0fb2d4a8494bb4c05a6f7d729135 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 09/15] wifi: mt76: fix incorrect HE TX GI report
+Subject: [PATCH 1/7] wifi: mt76: fix incorrect HE TX GI report
 
 Change GI reporting source from static capability to rate-tuning module.
 
@@ -17,7 +17,7 @@
  7 files changed, 282 insertions(+), 22 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 034ab90c..1ca23c90 100644
+index a238216..0609b4a 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -254,12 +254,16 @@ struct mt76_queue_ops {
@@ -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 004f41bf..2eec451f 100644
+index 9312c35..c1f234e 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -663,6 +663,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
+@@ -660,6 +660,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);
-@@ -1195,6 +1197,8 @@ int mt7915_register_device(struct mt7915_dev *dev)
+@@ -1192,6 +1194,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 b8b0c0fd..789f86a1 100644
+index 2222fb9..99a770e 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -173,15 +173,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
@@ -188,10 +188,10 @@
  
  	mt76_tx_status_check(mphy->dev, false);
 diff --git a/mt7915/main.c b/mt7915/main.c
-index de994ea7..33813259 100644
+index a3fd54c..449c2ee 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -739,6 +739,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -751,6 +751,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  
  	INIT_LIST_HEAD(&msta->rc_list);
  	INIT_LIST_HEAD(&msta->wcid.poll_list);
@@ -199,7 +199,7 @@
  	msta->vif = mvif;
  	msta->wcid.sta = 1;
  	msta->wcid.idx = idx;
-@@ -763,6 +764,7 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -775,6 +776,7 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  {
  	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
  	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
@@ -207,7 +207,7 @@
  	int i;
  
  	mt7915_mcu_add_sta(dev, vif, sta, false);
-@@ -779,6 +781,11 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -791,6 +793,11 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (!list_empty(&msta->rc_list))
  		list_del_init(&msta->rc_list);
  	spin_unlock_bh(&mdev->sta_poll_lock);
@@ -220,10 +220,10 @@
  
  static void mt7915_tx(struct ieee80211_hw *hw,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 5c4a275c..0660843c 100644
+index b6fba1a..9996c08 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3721,6 +3721,167 @@ out:
+@@ -3723,6 +3723,167 @@ out:
  	return ret;
  }
  
@@ -392,7 +392,7 @@
  				struct cfg80211_he_bss_color *he_bss_color)
  {
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 1592b5d6..aebacc7d 100644
+index 1592b5d..aebacc7 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 21984e97..3510dbcc 100644
+index d317c52..900ba09 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;
-@@ -493,6 +498,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
+@@ -495,6 +500,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);
@@ -497,5 +497,5 @@
  			   struct ieee80211_sta *sta, struct rate_info *rate);
  int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-update-beacon-size-limitation.patch b/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-update-beacon-size-limitation.patch
deleted file mode 100644
index b426ae9..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-update-beacon-size-limitation.patch
+++ /dev/null
@@ -1,214 +0,0 @@
-From 5205d81a06d556463a50b163bc6ceb6a6fb2bdeb Mon Sep 17 00:00:00 2001
-From: MeiChia Chiu <meichia.chiu@mediatek.com>
-Date: Thu, 23 Mar 2023 08:49:48 +0800
-Subject: [PATCH 01/15] wifi: mt76: mt7915: update beacon size limitation
-
-To accommodate 11v MBSSID IE and support maximum 16 MBSSIDs, expand the
-beacon size limitation for beacon and inband discovery commands.
-
-Co-developed-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Co-developed-by: Money Wang <Money.Wang@mediatek.com>
-Signed-off-by: Money Wang <Money.Wang@mediatek.com>
-Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/main.c   |  8 +++++---
- mt7915/mcu.c    | 49 +++++++++++++++++++++++++++++--------------------
- mt7915/mcu.h    | 18 ++++++++----------
- mt7915/mt7915.h |  2 ++
- 4 files changed, 44 insertions(+), 33 deletions(-)
-
-diff --git a/mt7915/main.c b/mt7915/main.c
-index 9b79e915..de994ea7 100644
---- a/mt7915/main.c
-+++ b/mt7915/main.c
-@@ -646,11 +646,13 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
- 		mt7915_update_bss_color(hw, vif, &info->he_bss_color);
- 
- 	if (changed & (BSS_CHANGED_BEACON |
--		       BSS_CHANGED_BEACON_ENABLED |
--		       BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
--		       BSS_CHANGED_FILS_DISCOVERY))
-+		       BSS_CHANGED_BEACON_ENABLED))
- 		mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);
- 
-+	if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
-+		       BSS_CHANGED_FILS_DISCOVERY))
-+		mt7915_mcu_add_inband_discov(dev, vif, changed);
-+
- 	if (set_bss_info == 0)
- 		mt7915_mcu_add_bss_info(phy, vif, false);
- 	if (set_sta == 0)
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 8224f8be..6d000841 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -1882,10 +1882,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
- 	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
- }
- 
--static void
--mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
--				struct sk_buff *rskb, struct bss_info_bcn *bcn,
--				u32 changed)
-+int
-+mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
-+			     u32 changed)
- {
- #define OFFLOAD_TX_MODE_SU	BIT(0)
- #define OFFLOAD_TX_MODE_MU	BIT(1)
-@@ -1895,14 +1894,27 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
- 	struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
- 	enum nl80211_band band = chandef->chan->band;
- 	struct mt76_wcid *wcid = &dev->mt76.global_wcid;
-+	struct bss_info_bcn *bcn;
- 	struct bss_info_inband_discovery *discov;
- 	struct ieee80211_tx_info *info;
--	struct sk_buff *skb = NULL;
--	struct tlv *tlv;
-+	struct sk_buff *rskb, *skb = NULL;
-+	struct tlv *tlv, *sub_tlv;
- 	bool ext_phy = phy != &dev->phy;
- 	u8 *buf, interval;
- 	int len;
- 
-+	if (vif->bss_conf.nontransmitted)
-+		return 0;
-+
-+	rskb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, NULL,
-+					       MT7915_MAX_BSS_OFFLOAD_SIZE);
-+	if (IS_ERR(rskb))
-+		return PTR_ERR(rskb);
-+
-+	tlv = mt76_connac_mcu_add_tlv(rskb, BSS_INFO_OFFLOAD, sizeof(*bcn));
-+	bcn = (struct bss_info_bcn *)tlv;
-+	bcn->enable = true;
-+
- 	if (changed & BSS_CHANGED_FILS_DISCOVERY &&
- 	    vif->bss_conf.fils_discovery.max_interval) {
- 		interval = vif->bss_conf.fils_discovery.max_interval;
-@@ -1914,26 +1926,25 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
- 	}
- 
- 	if (!skb)
--		return;
-+		return -EINVAL;
- 
- 	info = IEEE80211_SKB_CB(skb);
- 	info->control.vif = vif;
- 	info->band = band;
--
- 	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, ext_phy);
- 
- 	len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
- 	len = (len & 0x3) ? ((len | 0x3) + 1) : len;
- 
--	if (len > (MT7915_MAX_BSS_OFFLOAD_SIZE - rskb->len)) {
-+	if (skb->len > MT7915_MAX_BEACON_SIZE) {
- 		dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
- 		dev_kfree_skb(skb);
--		return;
-+		return -EINVAL;
- 	}
- 
--	tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_DISCOV,
--					   len, &bcn->sub_ntlv, &bcn->len);
--	discov = (struct bss_info_inband_discovery *)tlv;
-+	sub_tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_DISCOV,
-+					       len, &bcn->sub_ntlv, &bcn->len);
-+	discov = (struct bss_info_inband_discovery *)sub_tlv;
- 	discov->tx_mode = OFFLOAD_TX_MODE_SU;
- 	/* 0: UNSOL PROBE RESP, 1: FILS DISCOV */
- 	discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
-@@ -1941,13 +1952,16 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
- 	discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
- 	discov->enable = true;
- 
--	buf = (u8 *)tlv + sizeof(*discov);
-+	buf = (u8 *)sub_tlv + sizeof(*discov);
- 
- 	mt7915_mac_write_txwi(&dev->mt76, (__le32 *)buf, skb, wcid, 0, NULL,
- 			      0, changed);
- 	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
- 
- 	dev_kfree_skb(skb);
-+
-+	return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
-+				     MCU_EXT_CMD(BSS_INFO_UPDATE), true);
- }
- 
- int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-@@ -1983,7 +1997,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 	if (!skb)
- 		return -EINVAL;
- 
--	if (skb->len > MT7915_MAX_BEACON_SIZE - MT_TXD_SIZE) {
-+	if (skb->len > MT7915_MAX_BEACON_SIZE) {
- 		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
- 		dev_kfree_skb(skb);
- 		return -EINVAL;
-@@ -1997,11 +2011,6 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 	mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
- 	dev_kfree_skb(skb);
- 
--	if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP ||
--	    changed & BSS_CHANGED_FILS_DISCOVERY)
--		mt7915_mcu_beacon_inband_discov(dev, vif, rskb,
--						bcn, changed);
--
- out:
- 	return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
- 				     MCU_EXT_CMD(BSS_INFO_UPDATE), true);
-diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index b9ea297f..1592b5d6 100644
---- a/mt7915/mcu.h
-+++ b/mt7915/mcu.h
-@@ -495,10 +495,14 @@ enum {
- 	SER_RECOVER
- };
- 
--#define MT7915_MAX_BEACON_SIZE		512
--#define MT7915_MAX_INBAND_FRAME_SIZE	256
--#define MT7915_MAX_BSS_OFFLOAD_SIZE	(MT7915_MAX_BEACON_SIZE +	  \
--					 MT7915_MAX_INBAND_FRAME_SIZE +	  \
-+#define MT7915_MAX_BEACON_SIZE		1308
-+#define MT7915_BEACON_UPDATE_SIZE	(sizeof(struct sta_req_hdr) +	\
-+					 sizeof(struct bss_info_bcn) +	\
-+					 sizeof(struct bss_info_bcn_cntdwn) +	\
-+					 sizeof(struct bss_info_bcn_mbss) +	\
-+					 MT_TXD_SIZE +	\
-+					 sizeof(struct bss_info_bcn_cont))
-+#define MT7915_MAX_BSS_OFFLOAD_SIZE	(MT7915_MAX_BEACON_SIZE +	\
- 					 MT7915_BEACON_UPDATE_SIZE)
- 
- #define MT7915_BSS_UPDATE_MAX_SIZE	(sizeof(struct sta_req_hdr) +	\
-@@ -511,12 +515,6 @@ enum {
- 					 sizeof(struct bss_info_bmc_rate) +\
- 					 sizeof(struct bss_info_ext_bss))
- 
--#define MT7915_BEACON_UPDATE_SIZE	(sizeof(struct sta_req_hdr) +	\
--					 sizeof(struct bss_info_bcn_cntdwn) + \
--					 sizeof(struct bss_info_bcn_mbss) + \
--					 sizeof(struct bss_info_bcn_cont) + \
--					 sizeof(struct bss_info_inband_discovery))
--
- static inline s8
- mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
- {
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 0456e56f..21984e97 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -447,6 +447,8 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev,
- 			 bool add);
- int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
- 				struct cfg80211_he_bss_color *he_bss_color);
-+int mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
-+				 u32 changed);
- int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			  int enable, u32 changed);
- int mt7915_mcu_add_obss_spr(struct mt7915_phy *phy, struct ieee80211_vif *vif,
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0010-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
similarity index 96%
rename from recipes-wifi/linux-mt76/files/patches/0010-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
rename to recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
index 70ca901..f269b5c 100644
--- a/recipes-wifi/linux-mt76/files/patches/0010-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,8 +1,7 @@
-From 5f92b4ac9dd583b733b95455d8d3bf88b14a95b5 Mon Sep 17 00:00:00 2001
+From 395824a77010ab860cb20141105dc61a4feacbc9 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 10/15] wifi: mt76: mt7915: add pc stack dump for WM's
- coredump.
+Subject: [PATCH 2/7] wifi: mt76: mt7915: add pc stack dump for WM's coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -16,7 +15,7 @@
  7 files changed, 207 insertions(+), 71 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 1ca23c90..a4cf9b62 100644
+index 0609b4a..0d864fe 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -27,6 +27,8 @@
@@ -41,7 +40,7 @@
  enum mt76_wed_type {
  	MT76_WED_Q_TX,
  	MT76_WED_Q_TXFREE,
-@@ -782,6 +790,9 @@ struct mt76_dev {
+@@ -798,6 +806,9 @@ struct mt76_dev {
  	struct device *dma_dev;
  
  	struct mt76_mcu mcu;
@@ -52,10 +51,10 @@
  	struct net_device napi_dev;
  	struct net_device tx_napi_dev;
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 0f0a519f..cd6ce3c0 100644
+index bcd6c20..3aef23a 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -3020,6 +3020,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
+@@ -3049,6 +3049,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
  		goto out;
  	}
  
@@ -65,7 +64,7 @@
  	snprintf(dev->hw->wiphy->fw_version,
  		 sizeof(dev->hw->wiphy->fw_version),
  		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
-@@ -3049,6 +3052,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
+@@ -3078,6 +3081,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
  		goto out;
  	}
  
@@ -75,7 +74,7 @@
  	snprintf(dev->hw->wiphy->fw_version,
  		 sizeof(dev->hw->wiphy->fw_version),
  		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
-@@ -3119,6 +3125,9 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
+@@ -3148,6 +3154,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);
  
@@ -86,7 +85,7 @@
  		struct mt76_connac2_patch_sec *sec;
  		u32 len, addr, mode;
 diff --git a/mt7915/coredump.c b/mt7915/coredump.c
-index 5daf2258..298c1cad 100644
+index 5daf225..298c1ca 100644
 --- a/mt7915/coredump.c
 +++ b/mt7915/coredump.c
 @@ -7,7 +7,7 @@
@@ -414,7 +413,7 @@
  }
  
 diff --git a/mt7915/coredump.h b/mt7915/coredump.h
-index 709f8e9c..809ccbdf 100644
+index 709f8e9..809ccbd 100644
 --- a/mt7915/coredump.h
 +++ b/mt7915/coredump.h
 @@ -4,6 +4,7 @@
@@ -514,7 +513,7 @@
  	return NULL;
  }
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 789f86a1..67e7b264 100644
+index 99a770e..d81fae9 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -1595,28 +1595,31 @@ void mt7915_mac_reset_work(struct work_struct *work)
@@ -595,7 +594,7 @@
  }
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 3510dbcc..eb66fcda 100644
+index 900ba09..2c5d929 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -286,7 +286,7 @@ struct mt7915_dev {
@@ -608,10 +607,10 @@
  #endif
  
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 588cd87e..d01b9ea9 100644
+index 89ac8e6..7515b23 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
-@@ -1218,4 +1218,24 @@ enum offs_rev {
+@@ -1219,4 +1219,24 @@ enum offs_rev {
  #define MT_MCU_WM_CIRQ_EINT_MASK_CLR_ADDR	MT_MCU_WM_CIRQ(0x108)
  #define MT_MCU_WM_CIRQ_EINT_SOFT_ADDR		MT_MCU_WM_CIRQ(0x118)
  
@@ -637,5 +636,5 @@
 +
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-check-sta-rx-control-frame-to-multi.patch b/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-check-sta-rx-control-frame-to-multi.patch
deleted file mode 100644
index 0d2b350..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-check-sta-rx-control-frame-to-multi.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From a8a4d23f21cf56ca5d23a2ba15981b1f6459f19b Mon Sep 17 00:00:00 2001
-From: Allen Ye <allen.ye@mediatek.com>
-Date: Wed, 30 Aug 2023 18:34:47 +0800
-Subject: [PATCH 02/15] wifi: mt76: mt7915: check sta rx control frame to
- multibss capability
-
-Add CAP3_RX_CTRL_FRAME_TO_MULTIBSS check when setting sta_muru_tlv,
-which is used to get stations's capability of receving control frames
-when running OFDMA with MBSSIDs.
-
-Signed-off-by: Allen Ye <allen.ye@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/mcu.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 6d000841..35cd4fb0 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -906,6 +906,8 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
- 		HE_MAC(CAP2_MU_CASCADING, elem->mac_cap_info[2]);
- 	muru->ofdma_ul.uo_ra =
- 		HE_MAC(CAP3_OFDMA_RA, elem->mac_cap_info[3]);
-+	muru->ofdma_ul.rx_ctrl_frame_to_mbss =
-+		HE_MAC(CAP3_RX_CTRL_FRAME_TO_MULTIBSS, elem->mac_cap_info[3]);
- }
- 
- static void
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-fix-potential-memory-leak-of-beacon.patch b/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-fix-potential-memory-leak-of-beacon.patch
deleted file mode 100644
index fd0a117..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-fix-potential-memory-leak-of-beacon.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From b63b83d4a4af7c51cd4cac1616863829b9308fd4 Mon Sep 17 00:00:00 2001
-From: Bo Jiao <Bo.Jiao@mediatek.com>
-Date: Wed, 30 Aug 2023 18:44:01 +0800
-Subject: [PATCH 03/15] wifi: mt76: mt7915: fix potential memory leak of beacon
- commands
-
-Fix potential memory leak when setting beacon and inband discovery
-commands.
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/mcu.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 35cd4fb0..74fafedb 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -1927,8 +1927,10 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
- 		skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
- 	}
- 
--	if (!skb)
-+	if (!skb) {
-+		dev_kfree_skb(rskb);
- 		return -EINVAL;
-+	}
- 
- 	info = IEEE80211_SKB_CB(skb);
- 	info->control.vif = vif;
-@@ -1940,6 +1942,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
- 
- 	if (skb->len > MT7915_MAX_BEACON_SIZE) {
- 		dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
-+		dev_kfree_skb(rskb);
- 		dev_kfree_skb(skb);
- 		return -EINVAL;
- 	}
-@@ -1996,11 +1999,14 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 		goto out;
- 
- 	skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
--	if (!skb)
-+	if (!skb) {
-+		dev_kfree_skb(rskb);
- 		return -EINVAL;
-+	}
- 
- 	if (skb->len > MT7915_MAX_BEACON_SIZE) {
- 		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
-+		dev_kfree_skb(rskb);
- 		dev_kfree_skb(skb);
- 		return -EINVAL;
- 	}
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0011-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
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches/0011-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch
rename to recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch
index 1e17d22..9e2ce35 100644
--- a/recipes-wifi/linux-mt76/files/patches/0011-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 b7d4a039b0f828dfc7758a364c72c389cc500093 Mon Sep 17 00:00:00 2001
+From b5829fc76a9451651a8710a6c8b8f74b93d0a1cf 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 11/15] wifi: mt76: mt7915: move temperature margin check to
+Subject: [PATCH 3/7] 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 2eec451f..bcd37172 100644
+index c1f234e..294876a 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
 @@ -83,12 +83,13 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev,
@@ -38,10 +38,10 @@
  		return -EINVAL;
  	}
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 0660843c..ae488039 100644
+index 9996c08..9a79119 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3154,8 +3154,7 @@ int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy)
+@@ -3156,8 +3156,7 @@ int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy)
  
  	/* set high-temperature trigger threshold */
  	req.ctrl.ctrl_id = THERMAL_PROTECT_ENABLE;
@@ -52,5 +52,5 @@
  	req.sustain_time = cpu_to_le16(10);
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/0012-wifi-mt76-mt7915-fix-txpower-issues.patch b/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch
similarity index 91%
rename from recipes-wifi/linux-mt76/files/patches/0012-wifi-mt76-mt7915-fix-txpower-issues.patch
rename to recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch
index d0665af..31fcb9e 100644
--- a/recipes-wifi/linux-mt76/files/patches/0012-wifi-mt76-mt7915-fix-txpower-issues.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch
@@ -1,7 +1,7 @@
-From 285ce41898a1c7c49e89681a31cd7daa1d8b6ad3 Mon Sep 17 00:00:00 2001
+From 6cb2b319acc161e61dd875536bb2c8ee86efcad8 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 12/15] wifi: mt76: mt7915: fix txpower issues
+Subject: [PATCH 4/7] wifi: mt76: mt7915: fix txpower issues
 
 ---
  eeprom.c         |  4 ++--
@@ -13,7 +13,7 @@
  6 files changed, 32 insertions(+), 27 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index 2558788f..750e031d 100644
+index 2558788..750e031 100644
 --- a/eeprom.c
 +++ b/eeprom.c
 @@ -338,7 +338,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
@@ -35,10 +35,10 @@
  	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 85407387..0a081613 100644
+index 12fcb2b..aaaf6a9 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -1486,7 +1486,7 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1538,7 +1538,7 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		     int *dbm)
  {
  	struct mt76_phy *phy = hw->priv;
@@ -48,7 +48,7 @@
  
  	*dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index 6c3696c8..93e549c3 100644
+index 6c3696c..93e549c 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -950,9 +950,9 @@ mt7915_xmit_queues_show(struct seq_file *file, void *data)
@@ -132,10 +132,10 @@
  	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 bcd37172..15b719fa 100644
+index 294876a..d8fd8d6 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -281,7 +281,7 @@ static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
+@@ -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)
  {
@@ -145,10 +145,10 @@
  	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 33813259..a90ac456 100644
+index 449c2ee..96336b6 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1063,6 +1063,7 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+@@ -1075,6 +1075,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);
@@ -157,7 +157,7 @@
  	mutex_unlock(&dev->mt76.mutex);
  
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index aebacc7d..8f365461 100644
+index aebacc7..8f36546 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -574,7 +574,7 @@ static inline s8
@@ -170,5 +170,5 @@
  	txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * 2);
  	txpower -= mt76_tx_power_nss_delta(n_chains);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-get-rid-of-false-alamrs-of-tx-emiss.patch b/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-get-rid-of-false-alamrs-of-tx-emiss.patch
deleted file mode 100644
index 80f8e1d..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-get-rid-of-false-alamrs-of-tx-emiss.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From c521ab8836a3e1a4e4f71896e364802c3cf2d6e7 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Wed, 17 May 2023 17:34:55 +0800
-Subject: [PATCH 04/15] wifi: mt76: mt7915: get rid of false alamrs of tx
- emission issues
-
-When mt7915_mcu_set_chan_info() is set with CH_SWITCH_NORMAL reason,
-even if the action is UNI_CHANNEL_RX_PATH, it'll still generate some
-unexpected tones, which might confuse DFS CAC tests that there are some
-tone leakages. To get rid of these kinds of false alarms, always bypass
-DPD calibration when IEEE80211_CONF_IDLE is set.
-
-Reviewed-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/mcu.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 74fafedb..9ee65fa5 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -2742,10 +2742,10 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
- 	if (mt76_connac_spe_idx(phy->mt76->antenna_mask))
- 		req.tx_path_num = fls(phy->mt76->antenna_mask);
- 
--	if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
--	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
-+	if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
- 		req.switch_reason = CH_SWITCH_NORMAL;
--	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
-+	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL ||
-+		 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
- 		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
- 	else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
- 					  NL80211_IFTYPE_AP))
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-fix-per-band-IEEE80211_CONF_MONITOR.patch b/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-fix-per-band-IEEE80211_CONF_MONITOR.patch
deleted file mode 100644
index e5bab73..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-fix-per-band-IEEE80211_CONF_MONITOR.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 5119f4b1da53dfd34e73803a35adf80831db176e Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Wed, 30 Aug 2023 18:51:08 +0800
-Subject: [PATCH 05/15] wifi: mt76: mt7915: fix per-band IEEE80211_CONF_MONITOR
- flag comparison
-
-Use the correct ieee80211_conf on each band for IEEE80211_CONF_MONITOR
-comparison.
-
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/mcu.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 9ee65fa5..eae62b9c 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -2742,7 +2742,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
- 	if (mt76_connac_spe_idx(phy->mt76->antenna_mask))
- 		req.tx_path_num = fls(phy->mt76->antenna_mask);
- 
--	if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
-+	if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)
- 		req.switch_reason = CH_SWITCH_NORMAL;
- 	else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL ||
- 		 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0013-wifi-mt76-mt7915-rework-init-txpower.patch b/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-init-txpower.patch
similarity index 84%
rename from recipes-wifi/linux-mt76/files/patches/0013-wifi-mt76-mt7915-rework-init-txpower.patch
rename to recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-init-txpower.patch
index 75c90b7..e6ddc58 100644
--- a/recipes-wifi/linux-mt76/files/patches/0013-wifi-mt76-mt7915-rework-init-txpower.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-rework-init-txpower.patch
@@ -1,7 +1,7 @@
-From 738d720905afdf9abcb85cb6d6e8cd48a69cb82f Mon Sep 17 00:00:00 2001
+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 13/15] wifi: mt76: mt7915: rework init txpower
+Subject: [PATCH 5/7] wifi: mt76: mt7915: rework init txpower
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 ---
@@ -11,10 +11,10 @@
  3 files changed, 23 insertions(+), 14 deletions(-)
 
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 15b719fa..5ac1f995 100644
+index d8fd8d6..0d2587c 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -278,10 +278,11 @@ static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
+@@ -275,10 +275,11 @@ static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
  		mt7915_led_set_config(led_cdev, 0xff, 0);
  }
  
@@ -29,7 +29,7 @@
  	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;
-@@ -299,7 +300,7 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
+@@ -296,7 +297,7 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
  		}
  
  		target_power += pwr_delta;
@@ -38,7 +38,7 @@
  							  &limits,
  							  target_power);
  		target_power += nss_delta;
-@@ -310,6 +311,19 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
+@@ -307,6 +308,19 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
  	}
  }
  
@@ -58,7 +58,7 @@
  static void
  mt7915_regd_notifier(struct wiphy *wiphy,
  		     struct regulatory_request *request)
-@@ -325,9 +339,7 @@ mt7915_regd_notifier(struct wiphy *wiphy,
+@@ -322,9 +336,7 @@ mt7915_regd_notifier(struct wiphy *wiphy,
  	if (dev->mt76.region == NL80211_DFS_UNSET)
  		mt7915_mcu_rdd_background_enable(phy, NULL);
  
@@ -69,7 +69,7 @@
  
  	mphy->dfs_state = MT_DFS_STATE_UNKNOWN;
  	mt7915_dfs_init_radar_detector(phy);
-@@ -448,6 +460,7 @@ mt7915_init_wiphy(struct mt7915_phy *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);
@@ -77,7 +77,7 @@
  
  	wiphy->available_antennas_rx = phy->mt76->antenna_mask;
  	wiphy->available_antennas_tx = phy->mt76->antenna_mask;
-@@ -711,9 +724,6 @@ static void mt7915_init_work(struct work_struct *work)
+@@ -708,9 +721,6 @@ static void mt7915_init_work(struct work_struct *work)
  
  	mt7915_mcu_set_eeprom(dev);
  	mt7915_mac_init(dev);
@@ -88,7 +88,7 @@
  }
  
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 67e7b264..d9d5aad4 100644
+index d81fae9..a9bdb65 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -1395,8 +1395,8 @@ mt7915_mac_restart(struct mt7915_dev *dev)
@@ -103,10 +103,10 @@
  
  	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index eb66fcda..f0809291 100644
+index 2c5d929..4293385 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -428,8 +428,7 @@ void mt7915_dma_cleanup(struct mt7915_dev *dev);
+@@ -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);
@@ -117,5 +117,5 @@
  int mt7915_run(struct ieee80211_hw *hw);
  int mt7915_mcu_init(struct mt7915_dev *dev);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-check-vif-type-before-reporting-cca.patch b/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-check-vif-type-before-reporting-cca.patch
deleted file mode 100644
index 22f8981..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-check-vif-type-before-reporting-cca.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 18d25338da14f4b7de5aabd86ebb066b45d7e916 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Mon, 28 Aug 2023 10:59:23 +0800
-Subject: [PATCH 06/15] wifi: mt76: mt7915: check vif type before reporting cca
- and csa
-
-Don't report cca and csa finish to upper layer on station type vif to
-prevent warnings caused by setting beacon.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/mcu.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index eae62b9c..cdd1f847 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -225,7 +225,7 @@ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3)
- static void
- mt7915_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
- {
--	if (vif->bss_conf.csa_active)
-+	if (vif->bss_conf.csa_active && vif->type != NL80211_IFTYPE_STATION)
- 		ieee80211_csa_finish(vif);
- }
- 
-@@ -326,7 +326,7 @@ mt7915_mcu_rx_log_message(struct mt7915_dev *dev, struct sk_buff *skb)
- static void
- mt7915_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
- {
--	if (!vif->bss_conf.color_change_active)
-+	if (!vif->bss_conf.color_change_active || vif->type == NL80211_IFTYPE_STATION)
- 		return;
- 
- 	ieee80211_color_change_finish(vif);
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0014-wifi-mt76-mt7915-rework-mmio-access-flow.patch b/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-rework-mmio-access-flow.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches/0014-wifi-mt76-mt7915-rework-mmio-access-flow.patch
rename to recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-rework-mmio-access-flow.patch
index 9ee551a..0521fec 100644
--- a/recipes-wifi/linux-mt76/files/patches/0014-wifi-mt76-mt7915-rework-mmio-access-flow.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-rework-mmio-access-flow.patch
@@ -1,7 +1,7 @@
-From bee24c603808a54783adea0afbb0332eb9726f5f Mon Sep 17 00:00:00 2001
+From 441383b3fc8140bdff89d50861fd753b56154cba 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 14/15] wifi: mt76: mt7915: rework mmio access flow
+Subject: [PATCH 6/7] 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 fc7ace63..55096616 100644
+index fc7ace6..5509661 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -490,6 +490,11 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)
@@ -106,7 +106,7 @@
  	switch (device_id) {
  	case 0x7915:
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index f0809291..24d8da28 100644
+index 4293385..35458ec 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -292,6 +292,7 @@ struct mt7915_dev {
@@ -118,5 +118,5 @@
  	u32 hw_pattern;
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/0015-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch b/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
similarity index 76%
rename from recipes-wifi/linux-mt76/files/patches/0015-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
rename to recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
index c5e2934..93f2945 100644
--- a/recipes-wifi/linux-mt76/files/patches/0015-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch
@@ -1,7 +1,7 @@
-From 96656c8856b6e386608b67b15ef4ab10f60af666 Mon Sep 17 00:00:00 2001
+From 42bd7d9fbb234b9765983a0fc30926a0df2d1c51 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] wifi: mt76: disable HW AMSDU when using fixed rate
+Subject: [PATCH 7/7] 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 ee5177fd..1ece8754 100644
+index 93402d2..e26fcf8 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -557,7 +557,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+@@ -543,7 +543,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);
-@@ -592,6 +592,8 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+@@ -578,6 +578,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/0007-wifi-mt76-mt7915-update-mpdu-density-capability.patch b/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-update-mpdu-density-capability.patch
deleted file mode 100644
index b87db29..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-update-mpdu-density-capability.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From cb7c72bdaee4dedeea85377f120e12efb070e835 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Wed, 24 May 2023 10:17:38 +0800
-Subject: [PATCH 07/15] wifi: mt76: mt7915: update mpdu density capability
-
-Set mpdu density to 2 usec for non-mt7915 Wi-Fi 6 generation chipsets
-to align to the hardware capability which improves the throughput.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/init.c | 16 ++++++++++++----
- 1 file changed, 12 insertions(+), 4 deletions(-)
-
-diff --git a/mt7915/init.c b/mt7915/init.c
-index 688e6bc6..004f41bf 100644
---- a/mt7915/init.c
-+++ b/mt7915/init.c
-@@ -398,8 +398,12 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
- 		phy->mt76->sband_2g.sband.ht_cap.cap |=
- 			IEEE80211_HT_CAP_LDPC_CODING |
- 			IEEE80211_HT_CAP_MAX_AMSDU;
--		phy->mt76->sband_2g.sband.ht_cap.ampdu_density =
--			IEEE80211_HT_MPDU_DENSITY_4;
-+		if (is_mt7915(&dev->mt76))
-+			phy->mt76->sband_2g.sband.ht_cap.ampdu_density =
-+				IEEE80211_HT_MPDU_DENSITY_4;
-+		else
-+			phy->mt76->sband_2g.sband.ht_cap.ampdu_density =
-+				IEEE80211_HT_MPDU_DENSITY_2;
- 	}
- 
- 	if (phy->mt76->cap.has_5ghz) {
-@@ -409,10 +413,11 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
- 		phy->mt76->sband_5g.sband.ht_cap.cap |=
- 			IEEE80211_HT_CAP_LDPC_CODING |
- 			IEEE80211_HT_CAP_MAX_AMSDU;
--		phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
--			IEEE80211_HT_MPDU_DENSITY_4;
- 
- 		if (is_mt7915(&dev->mt76)) {
-+			phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
-+				IEEE80211_HT_MPDU_DENSITY_4;
-+
- 			vht_cap->cap |=
- 				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
- 				IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
-@@ -422,6 +427,9 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
- 					IEEE80211_VHT_CAP_SHORT_GI_160 |
- 					FIELD_PREP(IEEE80211_VHT_CAP_EXT_NSS_BW_MASK, 1);
- 		} else {
-+			phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
-+				IEEE80211_HT_MPDU_DENSITY_2;
-+
- 			vht_cap->cap |=
- 				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
- 				IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
--- 
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-fix-beamforming-availability-check.patch b/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-fix-beamforming-availability-check.patch
deleted file mode 100644
index d3d52fd..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-fix-beamforming-availability-check.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 47a2c8faf86bd3b3f3e7e0495015eebee53de0e9 Mon Sep 17 00:00:00 2001
-From: MeiChia Chiu <meichia.chiu@mediatek.com>
-Date: Wed, 12 Apr 2023 15:53:42 +0800
-Subject: [PATCH 08/15] wifi: mt76: mt7915: fix beamforming availability check
-
-Without this patch, when ap sets the tx stream number to 2,
-ap won't send any beamforming packet.
-
-Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- mt7915/mcu.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index cdd1f847..5c4a275c 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -1017,13 +1017,13 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
- 			struct ieee80211_sta *sta, bool bfee)
- {
- 	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
--	int tx_ant = hweight8(phy->mt76->chainmask) - 1;
-+	int sts = hweight16(phy->mt76->chainmask);
- 
- 	if (vif->type != NL80211_IFTYPE_STATION &&
- 	    vif->type != NL80211_IFTYPE_AP)
- 		return false;
- 
--	if (!bfee && tx_ant < 2)
-+	if (!bfee && sts < 2)
- 		return false;
- 
- 	if (sta->deflink.he_cap.has_he) {
--- 
-2.39.2
-
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 c874e7a..8ccddd2 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,7 +1,7 @@
-From 96d8883e50abdbe6261de3a0aac64e5e7edbb248 Mon Sep 17 00:00:00 2001
+From ed118d36cb5185ef0bc31725c973998edfc6969f 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/1034] wifi: mt76: mt7915: build pass for Linux Kernel 5.4
+Subject: [PATCH 0999/1040] wifi: mt76: mt7915: build pass for Linux Kernel 5.4
  fixes
 
 ---
@@ -15,14 +15,14 @@
  mt76_connac.h     |  2 --
  mt76_connac_mcu.c | 47 +-----------------------------
  mt76_connac_mcu.h |  4 ---
- mt7915/main.c     | 26 +++++++----------
+ mt7915/main.c     | 25 +++++++---------
  mt7915/mcu.c      |  1 +
  mt7915/mmio.c     | 55 +++++++++++++++++++++--------------
  usb.c             | 43 +++++++++++++--------------
- 14 files changed, 118 insertions(+), 225 deletions(-)
+ 14 files changed, 118 insertions(+), 224 deletions(-)
 
 diff --git a/debugfs.c b/debugfs.c
-index 79064a4d..4a8e1864 100644
+index c4649ba..1c8328d 100644
 --- a/debugfs.c
 +++ b/debugfs.c
 @@ -33,8 +33,10 @@ mt76_napi_threaded_set(void *data, u64 val)
@@ -37,10 +37,10 @@
  	return 0;
  }
 diff --git a/dma.c b/dma.c
-index 05d9ab3c..c9d2671d 100644
+index 643e18e..24b44e7 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -173,7 +173,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
+@@ -178,7 +178,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
  	local_bh_disable();
  	while ((t = __mt76_get_rxwi(dev)) != NULL) {
  		if (t->ptr)
@@ -49,7 +49,7 @@
  		kfree(t);
  	}
  	local_bh_enable();
-@@ -409,9 +409,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -411,9 +411,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  		if (!t)
  			return NULL;
  
@@ -62,7 +62,7 @@
  
  		buf = t->ptr;
  		t->dma_addr = 0;
-@@ -430,9 +430,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -432,9 +432,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  	} else {
  		buf = e->buf;
  		e->buf = NULL;
@@ -75,7 +75,7 @@
  	}
  
  	return buf;
-@@ -592,11 +592,11 @@ free_skb:
+@@ -594,11 +594,11 @@ free_skb:
  }
  
  static int
@@ -90,7 +90,7 @@
  
  	if (!q->ndesc)
  		return 0;
-@@ -604,25 +604,26 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -606,25 +606,26 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
  	spin_lock_bh(&q->lock);
  
  	while (q->queued < q->ndesc - 1) {
@@ -128,7 +128,7 @@
  			break;
  		}
  		frames++;
-@@ -666,7 +667,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -668,7 +669,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);
@@ -137,7 +137,7 @@
  		q->flags = flags;
  
  		ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
-@@ -714,10 +715,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -716,10 +717,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  	if (!q->entry)
  		return -ENOMEM;
  
@@ -148,7 +148,7 @@
  	ret = mt76_dma_wed_setup(dev, q, false);
  	if (ret)
  		return ret;
-@@ -731,6 +728,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -733,6 +730,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,7 +156,7 @@
  	void *buf;
  	bool more;
  
-@@ -744,7 +742,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -746,7 +744,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  		if (!buf)
  			break;
  
@@ -165,7 +165,7 @@
  	} while (1);
  
  	if (q->rx_head) {
-@@ -753,6 +751,13 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -755,6 +753,13 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  	}
  
  	spin_unlock_bh(&q->lock);
@@ -179,7 +179,7 @@
  }
  
  static void
-@@ -773,7 +778,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+@@ -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);
@@ -188,7 +188,7 @@
  	}
  }
  
-@@ -791,7 +796,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
+@@ -793,7 +798,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 {
@@ -197,7 +197,7 @@
  	}
  
  	if (more)
-@@ -859,12 +864,11 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -861,12 +866,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,7 +211,7 @@
  
  		*(u32 *)skb->cb = info;
  
-@@ -880,10 +884,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -882,10 +886,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		continue;
  
  free_frag:
@@ -224,7 +224,7 @@
  	return done;
  }
  
-@@ -928,7 +932,7 @@ mt76_dma_init(struct mt76_dev *dev,
+@@ -930,7 +934,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 +233,7 @@
  		napi_enable(&dev->napi[i]);
  	}
  
-@@ -979,8 +983,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+@@ -981,8 +985,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
  
  		netif_napi_del(&dev->napi[i]);
  		mt76_dma_rx_cleanup(dev, q);
@@ -243,7 +243,7 @@
  
  	mt76_free_pending_txwi(dev);
 diff --git a/eeprom.c b/eeprom.c
-index 750e031d..ff8dc939 100644
+index 750e031..ff8dc93 100644
 --- a/eeprom.c
 +++ b/eeprom.c
 @@ -161,9 +161,15 @@ void
@@ -264,7 +264,7 @@
  	if (!is_valid_ether_addr(phy->macaddr)) {
  		eth_random_addr(phy->macaddr);
 diff --git a/mac80211.c b/mac80211.c
-index 0a081613..638405df 100644
+index aaaf6a9..647f74c 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -4,7 +4,6 @@
@@ -275,7 +275,7 @@
  #include "mt76.h"
  
  #define CHAN2G(_idx, _freq) {			\
-@@ -563,47 +562,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
+@@ -567,47 +566,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
  }
  EXPORT_SYMBOL_GPL(mt76_unregister_phy);
  
@@ -323,7 +323,7 @@
  struct mt76_dev *
  mt76_alloc_device(struct device *pdev, unsigned int size,
  		  const struct ieee80211_ops *ops,
-@@ -1748,21 +1706,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
+@@ -1805,21 +1763,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  }
  EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
  
@@ -346,7 +346,7 @@
  {
  	struct ieee80211_hw *hw = phy->hw;
 diff --git a/mcu.c b/mcu.c
-index a8cafa39..fa4b0544 100644
+index a8cafa3..fa4b054 100644
 --- a/mcu.c
 +++ b/mcu.c
 @@ -4,6 +4,7 @@
@@ -358,7 +358,7 @@
  struct sk_buff *
  __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data,
 diff --git a/mt76.h b/mt76.h
-index a4cf9b62..35bf19fb 100644
+index 0d864fe..97ced84 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -210,7 +210,7 @@ struct mt76_queue {
@@ -370,7 +370,7 @@
  };
  
  struct mt76_mcu_ops {
-@@ -1439,7 +1439,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
+@@ -1457,7 +1457,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 +378,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);
-@@ -1551,25 +1550,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
+@@ -1569,25 +1568,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 +405,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 8d745c97..86061e95 100644
+index 955974a..db337aa 100644
 --- a/mt7615/mcu.c
 +++ b/mt7615/mcu.c
 @@ -10,6 +10,7 @@
@@ -417,7 +417,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 22878f08..4560ab79 100644
+index 1f29d8c..6f5cf18 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
 @@ -56,7 +56,6 @@ enum {
@@ -428,7 +428,7 @@
  
  	CMD_HE_MCS_BW80 = 0,
  	CMD_HE_MCS_BW160,
-@@ -264,7 +263,6 @@ static inline u8 mt76_connac_chan_bw(struct cfg80211_chan_def *chandef)
+@@ -270,7 +269,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 +437,7 @@
  
  	if (chandef->width >= ARRAY_SIZE(width_to_bw))
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index cd6ce3c0..a558c68c 100644
+index 3aef23a..f06a81d 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -4,6 +4,7 @@
@@ -448,7 +448,7 @@
  
  int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
  {
-@@ -1332,40 +1333,6 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1346,40 +1347,6 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
  }
  EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode);
  
@@ -489,7 +489,7 @@
  const struct ieee80211_sta_he_cap *
  mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
  {
-@@ -1378,18 +1345,6 @@ 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)
  }
  EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap);
  
@@ -509,10 +509,10 @@
  #define DEFAULT_HE_DURATION_RTS_THRES	1023
  static void
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index fe729bbf..bd0bf4bb 100644
+index 6064973..ddf901a 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1887,12 +1887,8 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val);
+@@ -1928,12 +1928,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,22 +526,22 @@
  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 e18cc93b..48970349 100644
+index 96336b6..95ad05d 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1393,22 +1393,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
+@@ -1405,22 +1405,20 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
  			   struct ieee80211_vif *vif,
  			   u32 sset, u8 *data)
  {
 -	if (sset != ETH_SS_STATS)
 -		return;
--
--	memcpy(data, *mt7915_gstrings_stats, sizeof(mt7915_gstrings_stats));
--	data += sizeof(mt7915_gstrings_stats);
--	page_pool_ethtool_stats_get_strings(data);
 +	if (sset == ETH_SS_STATS)
 +		memcpy(data, *mt7915_gstrings_stats,
 +		       sizeof(mt7915_gstrings_stats));
+ 
+-	memcpy(data, mt7915_gstrings_stats, sizeof(mt7915_gstrings_stats));
+-	data += sizeof(mt7915_gstrings_stats);
+-	page_pool_ethtool_stats_get_strings(data);
  }
  
  static
@@ -558,7 +558,7 @@
  }
  
  static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
-@@ -1436,7 +1433,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1448,7 +1446,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
  		.idx = mvif->mt76.idx,
  	};
  	/* See mt7915_ampdu_stat_read_phy, etc */
@@ -567,7 +567,7 @@
  
  	mutex_lock(&dev->mt76.mutex);
  
-@@ -1548,12 +1545,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1560,12 +1558,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
  		return;
  
  	ei += wi.worker_stat_count;
@@ -584,7 +584,7 @@
  
  static void
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index a34b75dc..50b49e54 100644
+index 9a79119..e9d7f20 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -6,6 +6,7 @@
@@ -596,10 +596,10 @@
  #define fw_name(_dev, name, ...)	({			\
  	char *_fw;						\
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index fc7ace63..8d92e76d 100644
+index 5509661..10f4e66 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -570,9 +570,13 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+@@ -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;
@@ -613,7 +613,7 @@
  	for (i = 0; i < dev->mt76.rx_token_size; i++) {
  		struct mt76_txwi_cache *t;
  
-@@ -580,7 +584,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -618,7 +622,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  		if (!t || !t->ptr)
  			continue;
  
@@ -624,7 +624,7 @@
  		t->ptr = NULL;
  
  		mt76_put_rxwi(&dev->mt76, t);
-@@ -592,38 +598,47 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -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;
@@ -690,7 +690,7 @@
  			goto unmap;
  		}
  
-@@ -635,8 +650,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -673,8 +688,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  	return 0;
  
  unmap:
@@ -700,7 +700,7 @@
  	return -ENOMEM;
  }
 diff --git a/usb.c b/usb.c
-index 5e5c7bf5..3e281715 100644
+index 5e5c7bf..3e28171 100644
 --- a/usb.c
 +++ b/usb.c
 @@ -319,27 +319,29 @@ mt76u_set_endpoints(struct usb_interface *intf,
@@ -834,5 +834,5 @@
  
  static void mt76u_free_rx(struct mt76_dev *dev)
 -- 
-2.39.2
+2.18.0
 
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 0e55e52..096309d 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 11e837febd8092b39d13b74c76d9134496c6e9d4 Mon Sep 17 00:00:00 2001
+From f2346c4a30dd7be798f2a9d8575f8edce64ff8eb 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
@@ -22,10 +22,10 @@
  create mode 100644 mt7915/mtk_mcu.c
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index bd0bf4bb..ab3b58e1 100644
+index ddf901ae..8b3b7c0b 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1151,6 +1151,7 @@ enum {
+@@ -1162,6 +1162,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,
-@@ -1174,6 +1175,11 @@ enum {
+@@ -1185,6 +1186,11 @@ enum {
  	MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
  	MCU_EXT_CMD_RXDCOC_CAL = 0x59,
  	MCU_EXT_CMD_GET_MIB_INFO = 0x5a,
@@ -231,7 +231,7 @@
  
  	if (dev->relay_fwlog)
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index d9d5aad4..d22a4079 100644
+index a9bdb653..2650b875 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 4e5c138f..b6dc9513 100644
+index 95ad05dd..b19aa635 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -73,7 +73,11 @@ int mt7915_run(struct ieee80211_hw *hw)
@@ -285,16 +285,16 @@
  	if (ret)
  		goto out;
  
-@@ -253,6 +257,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
- 	mvif->sta.wcid.phy_idx = ext_phy;
+@@ -254,6 +258,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
  	mvif->sta.wcid.hw_key_idx = -1;
  	mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;
+ 	mt76_wcid_init(&mvif->sta.wcid);
 +	mvif->sta.vif = mvif;
- 	mt76_packet_id_init(&mvif->sta.wcid);
  
  	mt7915_mac_wtbl_update(dev, idx,
+ 			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 03f84343..6b19af74 100644
+index e9d7f20b..47e178fd 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,
@@ -309,7 +309,7 @@
  	return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0);
  }
  
-@@ -2288,7 +2293,10 @@ static int mt7915_red_set_watermark(struct mt7915_dev *dev)
+@@ -2297,7 +2302,10 @@ static int mt7915_red_set_watermark(struct mt7915_dev *dev)
  				 sizeof(req), false);
  }
  
@@ -321,7 +321,7 @@
  {
  #define RED_DISABLE		0
  #define RED_BY_WA_ENABLE	2
-@@ -3352,6 +3360,8 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
+@@ -3360,6 +3368,8 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
  		.sku_enable = enable,
  	};
  
@@ -330,7 +330,7 @@
  	return mt76_mcu_send_msg(&dev->mt76,
  				 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
  				 sizeof(req), true);
-@@ -4006,6 +4016,23 @@ out:
+@@ -4014,6 +4024,23 @@ out:
  	return ret;
  }
  
@@ -354,7 +354,7 @@
  int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
  {
  	struct {
-@@ -4034,3 +4061,22 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
+@@ -4042,3 +4069,22 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
  
  	return 0;
  }
@@ -393,7 +393,7 @@
  };
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 24d8da28..f9e6917c 100644
+index 35458ec9..887c4a56 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -9,6 +9,7 @@
@@ -404,7 +404,7 @@
  #define MT7915_MAX_INTERFACES		19
  #define MT7915_WTBL_SIZE		288
  #define MT7916_WTBL_SIZE		544
-@@ -320,6 +321,28 @@ struct mt7915_dev {
+@@ -322,6 +323,28 @@ struct mt7915_dev {
  	struct reset_control *rstc;
  	void __iomem *dcm;
  	void __iomem *sku;
@@ -433,7 +433,7 @@
  };
  
  enum {
-@@ -599,4 +622,24 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -601,4 +624,24 @@ 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);
  
@@ -1884,7 +1884,7 @@
 +#endif
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
 new file mode 100644
-index 00000000..275acc61
+index 00000000..772adbb3
 --- /dev/null
 +++ b/mt7915/mtk_debugfs.c
 @@ -0,0 +1,3622 @@
@@ -4814,7 +4814,7 @@
 +{
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
 +	struct mt76_dev *mdev = NULL;
-+	seq_printf(s, "Version: 2.2.13.0\n");
++	seq_printf(s, "Version: 2.2.14.0\n");
 +
 +	if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
 +		return 0;
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 1e40fba..900672a 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,7 +1,7 @@
-From 3f62c2657a17715114869a4fa27bc32818bd2ad7 Mon Sep 17 00:00:00 2001
+From e6ccf89484d41dbd38992cf60150ef0db4bbafb2 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/1034] wifi: mt76: mt7915: csi: implement csi support
+Subject: [PATCH 1001/1040] wifi: mt76: mt7915: csi: implement csi support
 
 ---
  mt76_connac_mcu.h |   2 +
@@ -17,10 +17,10 @@
  create mode 100644 mt7915/vendor.h
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index ab3b58e1..f6738bc6 100644
+index 8b3b7c0..8a377dd 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1003,6 +1003,7 @@ enum {
+@@ -1007,6 +1007,7 @@ enum {
  	MCU_EXT_EVENT_WA_TX_STAT = 0x74,
  	MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
  	MCU_EXT_EVENT_MURU_CTRL = 0x9f,
@@ -28,7 +28,7 @@
  };
  
  /* unified event table */
-@@ -1196,6 +1197,7 @@ enum {
+@@ -1207,6 +1208,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,
@@ -37,7 +37,7 @@
  
  enum {
 diff --git a/mt7915/Makefile b/mt7915/Makefile
-index fd711416..65129b4f 100644
+index fd71141..65129b4 100644
 --- a/mt7915/Makefile
 +++ b/mt7915/Makefile
 @@ -1,10 +1,10 @@
@@ -54,10 +54,10 @@
  mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
  mt7915e-$(CONFIG_MT798X_WMAC) += soc.o
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 5ac1f995..0ea2af17 100644
+index 0d2587c..607d881 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -699,6 +699,12 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
+@@ -696,6 +696,12 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
  	/* init wiphy according to mphy and phy */
  	mt7915_init_wiphy(phy);
  
@@ -70,7 +70,7 @@
  	ret = mt76_register_phy(mphy, true, mt76_rates,
  				ARRAY_SIZE(mt76_rates));
  	if (ret)
-@@ -1176,6 +1182,25 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+@@ -1173,6 +1179,25 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
  	}
  }
  
@@ -96,7 +96,7 @@
  static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
  {
  	struct mt7915_phy *phy = mt7915_ext_phy(dev);
-@@ -1184,6 +1209,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
+@@ -1181,6 +1206,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);
-@@ -1196,6 +1225,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
+@@ -1193,6 +1222,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);
  }
-@@ -1236,6 +1269,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
+@@ -1233,6 +1266,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
  	dev->mt76.test_ops = &mt7915_testmode_ops;
  #endif
  
@@ -132,7 +132,7 @@
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 897e0dd9..8994ea6a 100644
+index 47e178f..729a41d 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -40,6 +40,10 @@ static bool sr_scene_detect = true;
@@ -146,7 +146,7 @@
  static u8
  mt7915_mcu_get_sta_nss(u16 mcs_map)
  {
-@@ -377,6 +381,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -379,6 +383,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	case MCU_EXT_EVENT_FW_LOG_2_HOST:
  		mt7915_mcu_rx_log_message(dev, skb);
  		break;
@@ -158,7 +158,7 @@
  	case MCU_EXT_EVENT_BCC_NOTIFY:
  		mt7915_mcu_rx_bcc_notify(dev, skb);
  		break;
-@@ -4015,6 +4024,108 @@ out:
+@@ -4024,6 +4033,108 @@ out:
  	return ret;
  }
  
@@ -268,7 +268,7 @@
  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 dd3b5062..67eac5c9 100644
+index dd3b506..67eac5c 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -589,4 +589,81 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
@@ -354,7 +354,7 @@
 +
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 00476647..23119d0d 100644
+index 887c4a5..6a96996 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -243,6 +243,20 @@ struct mt7915_phy {
@@ -378,7 +378,7 @@
  };
  
  struct mt7915_dev {
-@@ -621,6 +635,12 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -624,6 +638,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);
  
@@ -393,7 +393,7 @@
  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 00000000..98fd9c2d
+index 0000000..98fd9c2
 --- /dev/null
 +++ b/mt7915/vendor.c
 @@ -0,0 +1,452 @@
@@ -851,7 +851,7 @@
 +}
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
 new file mode 100644
-index 00000000..9d3db2a7
+index 0000000..9d3db2a
 --- /dev/null
 +++ b/mt7915/vendor.h
 @@ -0,0 +1,60 @@
@@ -916,5 +916,5 @@
 +
 +#endif
 -- 
-2.39.2
+2.18.0
 
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 2e58f8b..cd80105 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,7 +1,7 @@
-From c13fe2649dddd5f918ab7d93a13e839c11e258a1 Mon Sep 17 00:00:00 2001
+From 9887703630f6949fffbbca476a121a38afc2d558 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/1034] wifi: mt76: mt7915: air monitor support
+Subject: [PATCH 1002/1040] wifi: mt76: mt7915: air monitor support
 
 ---
  mt76_connac_mcu.h |   2 +
@@ -13,10 +13,10 @@
  6 files changed, 442 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index f6738bc6..c24fa8e8 100644
+index 8a377dd..c1d9191 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1197,6 +1197,8 @@ enum {
+@@ -1208,6 +1208,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 d22a4079..0e74c0d4 100644
+index 2650b87..f171e97 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 df506b01..7896c824 100644
+index b4dfe4b..d667b44 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -760,6 +760,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -772,6 +772,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (ret)
  		return ret;
  
@@ -55,7 +55,7 @@
  }
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 23119d0d..c733035b 100644
+index 6a96996..6192e81 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -195,6 +195,35 @@ struct mt7915_hif {
@@ -103,7 +103,7 @@
  #endif
  };
  
-@@ -639,6 +670,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -642,6 +673,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);
@@ -114,7 +114,7 @@
  
  #ifdef MTK_DEBUG
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 98fd9c2d..43f96903 100644
+index 98fd9c2..43f9690 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -430,6 +430,355 @@ out:
@@ -493,7 +493,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 9d3db2a7..976817f3 100644
+index 9d3db2a..976817f 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -4,6 +4,7 @@
@@ -547,5 +547,5 @@
 +
  #endif
 -- 
-2.39.2
+2.18.0
 
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 3473003..831ac6c 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,7 +1,7 @@
-From a5abc630e8bf65e4ca21bc1cf1b74db7df6cd6d1 Mon Sep 17 00:00:00 2001
+From 74fffd688572bd2f2f9633f0acb0da2dba249aa7 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/1034] wifi: mt76: mt7915: add support for muru_onoff via
+Subject: [PATCH 1003/1040] wifi: mt76: mt7915: add support for muru_onoff via
 
 ---
  mt7915/mcu.c         | 10 ++++++++--
@@ -11,10 +11,10 @@
  4 files changed, 49 insertions(+), 2 deletions(-)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 8994ea6..fdb6bc5 100644
+index 729a41d..66ec469 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -873,6 +873,7 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -875,6 +875,7 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  {
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
  	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
@@ -22,7 +22,7 @@
  	struct sta_rec_muru *muru;
  	struct tlv *tlv;
  
-@@ -884,13 +885,18 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -886,13 +887,18 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  
  	muru = (struct sta_rec_muru *)tlv;
  
@@ -59,7 +59,7 @@
 +
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index c733035..bd5543b 100644
+index 6192e81..e45e2fb 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -252,6 +252,8 @@ struct mt7915_phy {
@@ -72,10 +72,10 @@
  	struct mt76_channel_state state_ts;
  
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index e6796bc..e1758ed 100644
+index 275acc6..b7c54cc 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
-@@ -2558,6 +2558,38 @@ static int mt7915_token_txd_read(struct seq_file *s, void *data)
+@@ -2556,6 +2556,38 @@ static int mt7915_token_txd_read(struct seq_file *s, void *data)
  	return 0;
  }
  
@@ -114,7 +114,7 @@
  static int mt7915_amsduinfo_read(struct seq_file *s, void *data)
  {
  	struct mt7915_dev *dev = dev_get_drvdata(s->private);
-@@ -3554,6 +3586,7 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+@@ -3552,6 +3584,7 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  
  	mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);
  
@@ -123,5 +123,5 @@
  			    &fops_fw_debug_module);
  	debugfs_create_file("fw_debug_level", 0600, dir, dev,
 -- 
-2.39.0
+2.18.0
 
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 52d665b..b8198c4 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 8f6f793835431b195cde1379b19640c550de2caa Mon Sep 17 00:00:00 2001
+From d35da7aef3ecc8b64605277374e676dcf3bffd94 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 1004/1034] wifi: mt76: mt7915: certification patches
+Subject: [PATCH 1004/1040] wifi: mt76: mt7915: certification patches
 
 ---
  mt76_connac_mcu.h    |   1 +
@@ -16,10 +16,10 @@
  9 files changed, 954 insertions(+), 5 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index c24fa8e8..7b96feb2 100644
+index c1d9191..9b065f3 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1199,6 +1199,7 @@ enum {
+@@ -1210,6 +1210,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 0e74c0d4..20b9b99f 100644
+index f171e97..8d1eeef 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -8,6 +8,7 @@
@@ -76,10 +76,10 @@
  			       IEEE80211_RC_NSS_CHANGED |
  			       IEEE80211_RC_BW_CHANGED))
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 7896c824..9b54ba1c 100644
+index d667b44..ce5dcb3 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -735,6 +735,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -747,6 +747,9 @@ 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;
@@ -89,7 +89,7 @@
  	int ret, idx;
  
  	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
-@@ -763,7 +766,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -775,7 +778,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  #ifdef CONFIG_MTK_VENDOR
  	mt7915_vendor_amnt_sta_remove(mvif->phy, sta);
  #endif
@@ -107,10 +107,10 @@
  
  void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index fdb6bc5f..929f9bbe 100644
+index 66ec469..92fa560 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4130,6 +4130,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -4139,6 +4139,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
  
  	return 0;
  }
@@ -584,7 +584,7 @@
  
  #ifdef MTK_DEBUG
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 84c52d9b..7b7c2d1d 100644
+index 84c52d9..7b7c2d1 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -471,10 +471,14 @@ enum {
@@ -818,10 +818,10 @@
  
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index bd5543b5..bf0f7dee 100644
+index e45e2fb..ab3c8f7 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -669,6 +669,19 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -672,6 +672,19 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  			 bool pci, int *irq);
  
  #ifdef CONFIG_MTK_VENDOR
@@ -842,10 +842,10 @@
  int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
  			u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index e1758edb..9bb6dd05 100644
+index b7c54cc..96655db 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
-@@ -2564,7 +2564,8 @@ static int mt7915_muru_onoff_get(void *data, u64 *val)
+@@ -2562,7 +2562,8 @@ static int mt7915_muru_onoff_get(void *data, u64 *val)
  
  	*val = phy->muru_onoff;
  
@@ -855,7 +855,7 @@
  		    !!(phy->muru_onoff & MUMIMO_UL),
  		    !!(phy->muru_onoff & MUMIMO_DL),
  		    !!(phy->muru_onoff & OFDMA_UL),
-@@ -2577,8 +2578,8 @@ static int mt7915_muru_onoff_set(void *data, u64 val)
+@@ -2575,8 +2576,8 @@ static int mt7915_muru_onoff_set(void *data, u64 val)
  {
  	struct mt7915_phy *phy = data;
  
@@ -867,7 +867,7 @@
  	}
  
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 43f96903..5a1cce13 100644
+index 43f9690..5a1cce1 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -22,6 +22,29 @@ csi_ctrl_policy[NUM_MTK_VENDOR_ATTRS_CSI_CTRL] = {
@@ -1079,7 +1079,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 976817f3..1b08321c 100644
+index 976817f..1b08321 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -6,6 +6,48 @@
@@ -1132,5 +1132,5 @@
  
  enum mtk_vendor_attr_csi_ctrl {
 -- 
-2.39.2
+2.18.0
 
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 a8cae10..92ce23e 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,7 +1,7 @@
-From 7d26aa2de5124be98341720a87ffae9e5b4453d6 Mon Sep 17 00:00:00 2001
+From e1fb54da7217b4c2c88666cf1b782669632a795c 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/1034] wifi: mt76: mt7915: add support for runtime set
+Subject: [PATCH 1005/1040] wifi: mt76: mt7915: add support for runtime set
  in-band discovery
 
 Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+), 3 deletions(-)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 929f9bbe..d5420cb5 100644
+index 92fa560..f2ab2e3 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -1937,8 +1937,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1940,8 +1940,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	bcn = (struct bss_info_bcn *)tlv;
  	bcn->enable = true;
  
@@ -23,7 +23,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 &&
-@@ -1972,7 +1971,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1978,7 +1977,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
  	discov->tx_interval = interval;
  	discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
@@ -33,5 +33,5 @@
  	buf = (u8 *)sub_tlv + sizeof(*discov);
  
 -- 
-2.39.2
+2.18.0
 
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 9c926db..5b0bacc 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,7 +1,7 @@
-From f606394c86514dd140cb4ab0d7065c3c1ff584f5 Mon Sep 17 00:00:00 2001
+From 1a9f08c9d8dfb8c2f1c06f8bd52d6e08c0df7e8d 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/1034] wifi: mt76: mt7915: add mt76 vendor muru onoff
+Subject: [PATCH 1006/1040] wifi: mt76: mt7915: add mt76 vendor muru onoff
  command
 
 ---
@@ -12,10 +12,10 @@
  4 files changed, 63 insertions(+)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index d5420cb5..1f5f938e 100644
+index f2ab2e3..7b3c70e 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4149,6 +4149,13 @@ void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+@@ -4158,6 +4158,13 @@ void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
  		if (val == 0)
  			phy->muru_onoff = MUMIMO_DL_CERT | MUMIMO_DL;
  		break;
@@ -30,7 +30,7 @@
  }
  
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 7b7c2d1d..b6e21369 100644
+index 7b7c2d1..b6e2136 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -478,6 +478,7 @@ enum {
@@ -42,7 +42,7 @@
  };
  
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 5a1cce13..df1cac3f 100644
+index 5a1cce1..df1cac3 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -34,6 +34,11 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -110,7 +110,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 1b08321c..2be5fc89 100644
+index 1b08321..2be5fc8 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -8,6 +8,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -140,5 +140,5 @@
  	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
  
 -- 
-2.39.2
+2.18.0
 
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 5c2ffb7..a08e7de 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 27cd55caaf8ce2e8bb5c9bd82160ee4d32e95a3d Mon Sep 17 00:00:00 2001
+From 86b11ceef3db1601919f54f5cc73b3e301094223 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/1034] wifi: mt76: mt7915: drop undefined action frame
+Subject: [PATCH 1007/1040] 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 20b9b99f..7ae34b77 100644
+index 8d1eeef..f1c78ec 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,
@@ -32,5 +32,5 @@
  	if (id < 0)
  		return id;
 -- 
-2.39.2
+2.18.0
 
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 0f4ed45..1ad2d4a 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,7 +1,7 @@
-From a7090a0aa6c95315fc9356708c2db0222b494a7d Mon Sep 17 00:00:00 2001
+From db7a7f8f00bf19913b153a377a7808900bafeb20 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/1034] wifi: mt76: testmode: rework testmode init
+Subject: [PATCH 1008/1040] wifi: mt76: testmode: rework testmode init
  registers
 
 ---
@@ -18,10 +18,10 @@
  10 files changed, 164 insertions(+), 35 deletions(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index 638405df..eac90b3e 100644
+index 647f74c..430ed1c 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -787,7 +787,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
+@@ -793,7 +793,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
  	}
  
  #ifdef CONFIG_NL80211_TESTMODE
@@ -32,10 +32,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 35bf19fb..c2ad06a2 100644
+index 97ced84..d66f4d0 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -659,6 +659,8 @@ struct mt76_testmode_ops {
+@@ -672,6 +672,8 @@ struct mt76_testmode_ops {
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
  };
  
@@ -44,7 +44,7 @@
  struct mt76_testmode_data {
  	enum mt76_testmode_state state;
  
-@@ -690,6 +692,8 @@ struct mt76_testmode_data {
+@@ -703,6 +705,8 @@ struct mt76_testmode_data {
  
  	u8 addr[3][ETH_ALEN];
  
@@ -53,7 +53,7 @@
  	u32 tx_pending;
  	u32 tx_queued;
  	u16 tx_queued_limit;
-@@ -697,6 +701,7 @@ struct mt76_testmode_data {
+@@ -710,6 +714,7 @@ struct mt76_testmode_data {
  	struct {
  		u64 packets[__MT_RXQ_MAX];
  		u64 fcs_error[__MT_RXQ_MAX];
@@ -62,10 +62,10 @@
  };
  
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 7b96feb2..92e0b912 100644
+index 9b065f3..cb68141 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1193,6 +1193,7 @@ enum {
+@@ -1204,6 +1204,7 @@ enum {
  	MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
  	MCU_EXT_CMD_SET_RDD_TH = 0x9d,
  	MCU_EXT_CMD_MURU_CTRL = 0x9f,
@@ -74,7 +74,7 @@
  	MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
  	MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index b6e21369..c15b4b74 100644
+index b6e2136..c15b4b7 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -9,6 +9,7 @@
@@ -86,7 +86,7 @@
  	MCU_ATE_CLEAN_TXQUEUE = 0x1c,
  };
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 8d92e76d..b23679ac 100644
+index 10f4e66..10c2c7d 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -120,6 +120,7 @@ static const u32 mt7986_reg[] = {
@@ -106,7 +106,7 @@
  	[TMAC_ODTR]		= 0x0cc,
  	[TMAC_ATCR]		= 0x00c,
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index d01b9ea9..038596c3 100644
+index 7515b23..2a9e50b 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
 @@ -48,6 +48,7 @@ enum reg_rev {
@@ -117,7 +117,7 @@
  	TMAC_CDTR,
  	TMAC_ODTR,
  	TMAC_ATCR,
-@@ -201,6 +202,12 @@ enum offs_rev {
+@@ -202,6 +203,12 @@ enum offs_rev {
  #define MT_TRB_RXPSR0_RX_WTBL_PTR	GENMASK(25, 16)
  #define MT_TRB_RXPSR0_RX_RMAC_PTR	GENMASK(9, 0)
  
@@ -130,7 +130,7 @@
  /* TMAC: band 0(0x820e4000), band 1(0x820f4000) */
  #define MT_WF_TMAC_BASE(_band)		((_band) ? 0x820f4000 : 0x820e4000)
  #define MT_WF_TMAC(_band, ofs)		(MT_WF_TMAC_BASE(_band) + (ofs))
-@@ -209,6 +216,9 @@ enum offs_rev {
+@@ -210,6 +217,9 @@ enum offs_rev {
  #define MT_TMAC_TCR0_TX_BLINK		GENMASK(7, 6)
  #define MT_TMAC_TCR0_TBTT_STOP_CTRL	BIT(25)
  
@@ -140,7 +140,7 @@
  #define MT_TMAC_CDTR(_band)		MT_WF_TMAC(_band, __OFFS(TMAC_CDTR))
   #define MT_TMAC_ODTR(_band)		MT_WF_TMAC(_band, __OFFS(TMAC_ODTR))
  #define MT_TIMEOUT_VAL_PLCP		GENMASK(15, 0)
-@@ -488,8 +498,10 @@ enum offs_rev {
+@@ -489,8 +499,10 @@ enum offs_rev {
  #define MT_AGG_PCR0_VHT_PROT		BIT(13)
  #define MT_AGG_PCR0_PTA_WIN_DIS		BIT(15)
  
@@ -154,7 +154,7 @@
  #define MT_AGG_ACR0(_band)		MT_WF_AGG(_band, __OFFS(AGG_ACR0))
  #define MT_AGG_ACR_CFEND_RATE		GENMASK(13, 0)
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 0d76ae31..46939191 100644
+index 0d76ae3..4693919 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -30,7 +30,7 @@ struct reg_band {
@@ -379,7 +379,7 @@
  
  const struct mt76_testmode_ops mt7915_testmode_ops = {
 diff --git a/mt7915/testmode.h b/mt7915/testmode.h
-index 5573ac30..a1c54c89 100644
+index 5573ac3..a1c54c8 100644
 --- a/mt7915/testmode.h
 +++ b/mt7915/testmode.h
 @@ -33,6 +33,12 @@ struct mt7915_tm_clean_txq {
@@ -430,7 +430,7 @@
 +
  #endif
 diff --git a/testmode.c b/testmode.c
-index 4644dace..1b37392c 100644
+index 4644dac..1b37392 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -448,8 +448,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -454,7 +454,7 @@
  		return -EMSGSIZE;
  
 diff --git a/testmode.h b/testmode.h
-index 5e2792d8..89613266 100644
+index 5e2792d..8961326 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -101,6 +101,8 @@ enum mt76_testmode_attr {
@@ -475,5 +475,5 @@
  	/* keep last */
  	NUM_MT76_TM_STATS_ATTRS,
 -- 
-2.39.2
+2.18.0
 
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 73fd048..ca61e6e 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,4 +1,4 @@
-From 8f1bea09505a143e4922d4230bf7ad1181c53893 Mon Sep 17 00:00:00 2001
+From 555abaed13e0426eb3295c7f7b02de57320a63e6 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] wifi: mt76: testmode: additional supports
@@ -8,31 +8,31 @@
 ---
  dma.c             |    3 +-
  mac80211.c        |   12 +
- mt76.h            |  108 +++-
+ mt76.h            |  110 +++-
  mt76_connac_mcu.c |    4 +
  mt76_connac_mcu.h |    2 +
  mt7915/eeprom.c   |    2 +-
  mt7915/init.c     |    2 +-
- mt7915/mac.c      |   39 +-
+ mt7915/mac.c      |   40 +-
  mt7915/main.c     |    2 +-
  mt7915/mcu.c      |   22 +-
  mt7915/mcu.h      |   29 +-
  mt7915/mmio.c     |    2 +
- mt7915/mt7915.h   |   16 +-
+ mt7915/mt7915.h   |   17 +-
  mt7915/regs.h     |    3 +
- mt7915/testmode.c | 1222 ++++++++++++++++++++++++++++++++++++++++++---
- mt7915/testmode.h |  278 +++++++++++
- testmode.c        |  282 +++++++++--
- testmode.h        |   75 +++
- tools/fields.c    |   84 +++-
+ mt7915/testmode.c | 1238 ++++++++++++++++++++++++++++++++++++++++++---
+ mt7915/testmode.h |  278 ++++++++++
+ testmode.c        |  287 +++++++++--
+ testmode.h        |   79 +++
+ tools/fields.c    |   90 +++-
  tx.c              |    3 +-
- 20 files changed, 2024 insertions(+), 166 deletions(-)
+ 20 files changed, 2058 insertions(+), 167 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index c9d2671d..fc92e391 100644
+index 24b44e7..8049830 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -574,8 +574,7 @@ free:
+@@ -576,8 +576,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 eac90b3e..ed1d659b 100644
+index 430ed1c..fccf26d 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 c2ad06a2..a5908de4 100644
+index d66f4d0..597488d 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -657,6 +657,21 @@ struct mt76_testmode_ops {
+@@ -670,6 +670,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,11 +98,13 @@
  };
  
  #define MT_TM_FW_RX_COUNT	BIT(0)
-@@ -665,16 +680,11 @@ struct mt76_testmode_data {
+@@ -678,16 +693,13 @@ struct mt76_testmode_data {
  	enum mt76_testmode_state state;
  
  	u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)];
 -	struct sk_buff *tx_skb;
++
++	u8 sku_en;
  
  	u32 tx_count;
 -	u16 tx_mpdu_len;
@@ -115,7 +117,7 @@
  	u8 tx_rate_stbc;
  	u8 tx_ltf;
  
-@@ -690,10 +700,37 @@ struct mt76_testmode_data {
+@@ -703,10 +715,37 @@ struct mt76_testmode_data {
  	u8 tx_power[4];
  	u8 tx_power_control;
  
@@ -154,7 +156,7 @@
  	u32 tx_pending;
  	u32 tx_queued;
  	u16 tx_queued_limit;
-@@ -1258,6 +1295,59 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
+@@ -1276,6 +1315,59 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
  #endif
  }
  
@@ -214,7 +216,7 @@
  static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
  					struct sk_buff *skb,
  					struct ieee80211_hw **hw)
-@@ -1268,7 +1358,8 @@ static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
+@@ -1286,7 +1378,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];
  
@@ -224,7 +226,7 @@
  			*hw = dev->phys[i]->hw;
  			return true;
  		}
-@@ -1370,7 +1461,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1388,7 +1481,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);
@@ -235,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 80a5cbc0..18812aff 100644
+index f06a81d..60e159c 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -402,6 +402,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -396,6 +396,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:
@@ -246,7 +248,7 @@
  		if (vif->p2p && !is_mt7921(dev))
  			conn_type = CONNECTION_P2P_GC;
  		else
-@@ -583,6 +584,9 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
+@@ -577,6 +578,9 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
  	rx->rca2 = 1;
  	rx->rv = 1;
  
@@ -257,10 +259,10 @@
  		return;
  
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 92e0b912..e3980c37 100644
+index cb68141..7a7dbf4 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -998,6 +998,7 @@ enum {
+@@ -1002,6 +1002,7 @@ enum {
  	MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
  	MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
  	MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
@@ -268,7 +270,7 @@
  	MCU_EXT_EVENT_RDD_REPORT = 0x3a,
  	MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
  	MCU_EXT_EVENT_WA_TX_STAT = 0x74,
-@@ -1200,6 +1201,7 @@ enum {
+@@ -1211,6 +1212,7 @@ enum {
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
  	/* for vendor csi and air monitor */
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
@@ -277,7 +279,7 @@
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
  };
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index 76be7308..f5ab3319 100644
+index 76be730..f5ab331 100644
 --- a/mt7915/eeprom.c
 +++ b/mt7915/eeprom.c
 @@ -131,7 +131,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
@@ -290,10 +292,10 @@
  				return ret;
  		}
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 0ea2af17..c54c1f33 100644
+index 607d881..d908a58 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -728,7 +728,7 @@ static void mt7915_init_work(struct work_struct *work)
+@@ -725,7 +725,7 @@ static void mt7915_init_work(struct work_struct *work)
  	struct mt7915_dev *dev = container_of(work, struct mt7915_dev,
  				 init_work);
  
@@ -303,10 +305,18 @@
  	mt7915_txbf_init(dev);
  }
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 7ae34b77..6c9401dd 100644
+index f1c78ec..06a5fb1 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -604,16 +604,38 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+@@ -579,6 +579,7 @@ mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
+ 			wb_rssi = le32_to_cpu(rxv[9]);
+ 
+ 		phy->test.last_rcpi[i] = rcpi & 0xff;
++		phy->test.last_rssi[i] = to_rssi(GENMASK(7, 0), rcpi);
+ 		phy->test.last_ib_rssi[i] = ib_rssi & 0xff;
+ 		phy->test.last_wb_rssi[i] = wb_rssi & 0xff;
+ 	}
+@@ -604,16 +605,38 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
  {
  #ifdef CONFIG_NL80211_TESTMODE
  	struct mt76_testmode_data *td = &phy->mt76->test;
@@ -348,7 +358,7 @@
  
  	switch (td->tx_rate_mode) {
  	case MT76_TM_TX_MODE_HT:
-@@ -644,7 +666,7 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+@@ -644,7 +667,7 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
  			rate_idx += 4;
  
  		r = &phy->mt76->hw->wiphy->bands[band]->bitrates[rate_idx];
@@ -357,7 +367,7 @@
  
  		mode = val >> 8;
  		rate_idx = val & 0xff;
-@@ -703,13 +725,14 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+@@ -703,13 +726,14 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
  	if (mode >= MT_PHY_TYPE_HE_SU)
  		val |= FIELD_PREP(MT_TXD6_HELTF, td->tx_ltf);
  
@@ -375,7 +385,7 @@
  #endif
  }
  
-@@ -1415,7 +1438,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
+@@ -1415,7 +1439,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
  		goto out;
  
  	/* set the necessary init items */
@@ -385,7 +395,7 @@
  		goto out;
  
 diff --git a/mt7915/main.c b/mt7915/main.c
-index bb7075ed..60639fe0 100644
+index ce5dcb3..3b18c95 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -238,7 +238,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
@@ -398,10 +408,10 @@
  		mvif->mt76.wmm_idx += 2;
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 8a77d7ff..18eaf687 100644
+index 7b3c70e..0d1e09c 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -389,6 +389,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -391,6 +391,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	case MCU_EXT_EVENT_BCC_NOTIFY:
  		mt7915_mcu_rx_bcc_notify(dev, skb);
  		break;
@@ -413,7 +423,7 @@
  	default:
  		break;
  	}
-@@ -420,6 +425,7 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -422,6 +427,7 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	     rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
  	     rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
  	     rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
@@ -421,7 +431,7 @@
  	     !rxd->seq) &&
  	     !(rxd->eid == MCU_CMD_EXT_CID &&
  	       rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
-@@ -2763,7 +2769,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
+@@ -2764,7 +2770,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
  	}
  #endif
  
@@ -479,7 +489,7 @@
  
  	return 0;
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index c15b4b74..99827354 100644
+index c15b4b7..9982735 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -8,10 +8,15 @@
@@ -537,7 +547,7 @@
  
  enum {
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 10c2c7d8..87a5c5c4 100644
+index 10c2c7d..87a5c5c 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -134,6 +134,7 @@ static const u32 mt7915_offs[] = {
@@ -557,10 +567,16 @@
  	[AGG_PCR0]		= 0x040,
  	[AGG_ACR0]		= 0x054,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index f1c9a9bc..d0a8a99e 100644
+index ab3c8f7..b91af94 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -272,6 +272,9 @@ struct mt7915_phy {
+@@ -267,11 +267,15 @@ struct mt7915_phy {
+ 
+ 		s32 last_freq_offset;
+ 		u8 last_rcpi[4];
++		s8 last_rssi[4];
+ 		s8 last_ib_rssi[4];
+ 		s8 last_wb_rssi[4];
  		u8 last_snr;
  
  		u8 spe_idx;
@@ -570,7 +586,7 @@
  	} test;
  #endif
  
-@@ -369,6 +372,14 @@ struct mt7915_dev {
+@@ -371,6 +375,14 @@ struct mt7915_dev {
  	void __iomem *dcm;
  	void __iomem *sku;
  
@@ -585,7 +601,7 @@
  #ifdef MTK_DEBUG
  	u16 wlan_idx;
  	struct {
-@@ -540,8 +551,8 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
+@@ -542,8 +554,8 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
  				   struct ieee80211_vif *vif,
  				   struct ieee80211_sta *sta,
  				   void *data, u32 field);
@@ -596,7 +612,7 @@
  int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num);
  int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
  		       bool hdr_trans);
-@@ -580,6 +591,7 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
+@@ -582,6 +594,7 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
  int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
  void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
  void mt7915_mcu_exit(struct mt7915_dev *dev);
@@ -605,7 +621,7 @@
  static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
  {
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 038596c3..428f4820 100644
+index 2a9e50b..6783797 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
 @@ -62,6 +62,7 @@ enum offs_rev {
@@ -616,7 +632,7 @@
  	AGG_AWSCR0,
  	AGG_PCR0,
  	AGG_ACR0,
-@@ -485,6 +486,8 @@ enum offs_rev {
+@@ -486,6 +487,8 @@ enum offs_rev {
  #define MT_WF_AGG_BASE(_band)		((_band) ? 0x820f2000 : 0x820e2000)
  #define MT_WF_AGG(_band, ofs)		(MT_WF_AGG_BASE(_band) + (ofs))
  
@@ -626,30 +642,32 @@
  							  (_n) * 4))
  #define MT_AGG_PCR0(_band, _n)		MT_WF_AGG(_band, (__OFFS(AGG_PCR0) +	\
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 46939191..e5d0ef9b 100644
+index 4693919..8367204 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
-@@ -9,6 +9,9 @@
+@@ -9,6 +9,10 @@
  enum {
  	TM_CHANGED_TXPOWER,
  	TM_CHANGED_FREQ_OFFSET,
++	TM_CHANGED_SKU_EN,
 +	TM_CHANGED_AID,
 +	TM_CHANGED_CFG,
 +	TM_CHANGED_TXBF_ACT,
  
  	/* must be last */
  	NUM_TM_CHANGED
-@@ -17,6 +20,9 @@ enum {
+@@ -17,6 +21,10 @@ enum {
  static const u8 tm_change_map[] = {
  	[TM_CHANGED_TXPOWER] = MT76_TM_ATTR_TX_POWER,
  	[TM_CHANGED_FREQ_OFFSET] = MT76_TM_ATTR_FREQ_OFFSET,
++	[TM_CHANGED_SKU_EN] = MT76_TM_ATTR_SKU_EN,
 +	[TM_CHANGED_AID] = MT76_TM_ATTR_AID,
 +	[TM_CHANGED_CFG] = MT76_TM_ATTR_CFG,
 +	[TM_CHANGED_TXBF_ACT] = MT76_TM_ATTR_TXBF_ACT,
  };
  
  struct reg_band {
-@@ -33,6 +39,57 @@ struct reg_band {
+@@ -33,6 +41,57 @@ struct reg_band {
  #define TM_REG_MAX_ID	20
  static struct reg_band reg_backup_list[TM_REG_MAX_ID];
  
@@ -707,7 +725,7 @@
  
  static int
  mt7915_tm_set_tx_power(struct mt7915_phy *phy)
-@@ -119,18 +176,28 @@ mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en)
+@@ -119,18 +178,28 @@ mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en)
  }
  
  static int
@@ -740,7 +758,7 @@
  }
  
  static int
-@@ -141,7 +208,7 @@ mt7915_tm_set_phy_count(struct mt7915_phy *phy, u8 control)
+@@ -141,7 +210,7 @@ mt7915_tm_set_phy_count(struct mt7915_phy *phy, u8 control)
  		.testmode_en = 1,
  		.param_idx = MCU_ATE_SET_PHY_COUNT,
  		.param.cfg.enable = control,
@@ -749,7 +767,7 @@
  	};
  
  	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
-@@ -182,12 +249,739 @@ mt7915_tm_set_tam_arb(struct mt7915_phy *phy, bool enable, bool mu)
+@@ -182,12 +251,739 @@ mt7915_tm_set_tam_arb(struct mt7915_phy *phy, bool enable, bool mu)
  	return mt7915_mcu_set_muru_ctrl(dev, MURU_SET_ARB_OP_MODE, op_mode);
  }
  
@@ -1491,7 +1509,7 @@
  	struct edca *e = &req.edca[0];
  
  	e->queue = qid + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS;
-@@ -263,7 +1057,8 @@ done:
+@@ -263,7 +1059,8 @@ done:
  
  	return mt7915_tm_set_wmm_qid(phy,
  				     mt76_connac_lmac_mapping(IEEE80211_AC_BE),
@@ -1501,7 +1519,7 @@
  }
  
  static int
-@@ -339,7 +1134,7 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
+@@ -339,7 +1136,7 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
  	bitrate = cfg80211_calculate_bitrate(&rate);
  	tx_len = bitrate * tx_time / 10 / 8;
  
@@ -1510,7 +1528,7 @@
  	if (ret)
  		return ret;
  
-@@ -458,64 +1253,227 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
+@@ -458,64 +1255,227 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
  
  	phy->mt76->test.flag |= MT_TM_FW_RX_COUNT;
  
@@ -1769,7 +1787,7 @@
  
  	mt7915_tm_set_trx(phy, TM_MAC_TX, en);
  }
-@@ -544,10 +1502,6 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
+@@ -544,10 +1504,6 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
  		return ret;
  
  	rs_band = (struct mt7915_tm_rx_stat_band *)skb->data;
@@ -1780,7 +1798,7 @@
  
  	if (!clear) {
  		enum mt76_rxq_id q = req.band ? MT_RXQ_BAND1 : MT_RXQ_MAIN;
-@@ -562,13 +1516,61 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
+@@ -562,13 +1518,61 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
  	return 0;
  }
  
@@ -1843,7 +1861,7 @@
  
  		/* read-clear */
  		mt7915_tm_get_rx_stats(phy, true);
-@@ -576,9 +1578,12 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
+@@ -576,9 +1580,12 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
  		/* clear fw count */
  		mt7915_tm_set_phy_count(phy, 0);
  		mt7915_tm_set_phy_count(phy, 1);
@@ -1858,7 +1876,7 @@
  }
  
  static int
-@@ -617,34 +1622,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
+@@ -617,34 +1624,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
  	tx_cont->tx_ant = td->tx_antenna_mask;
  	tx_cont->band = band;
  
@@ -1894,10 +1912,14 @@
  
  	if (!en) {
  		req.op.rf.param.func_data = cpu_to_le32(band);
-@@ -728,6 +1706,12 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
+@@ -728,6 +1708,16 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
  		mt7915_tm_set_freq_offset(phy, en, en ? td->freq_offset : 0);
  	if (changed & BIT(TM_CHANGED_TXPOWER))
  		mt7915_tm_set_tx_power(phy);
++	if (changed & BIT(TM_CHANGED_SKU_EN)) {
++		mt7915_mcu_set_sku_en(phy, td->sku_en);
++		mt7915_mcu_set_txpower_sku(phy);
++	}
 +	if (changed & BIT(TM_CHANGED_AID))
 +		mt7915_tm_set_entry(phy);
 +	if (changed & BIT(TM_CHANGED_CFG))
@@ -1907,7 +1929,7 @@
  }
  
  static int
-@@ -737,6 +1721,11 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -737,6 +1727,11 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
  	struct mt7915_phy *phy = mphy->priv;
  	enum mt76_testmode_state prev_state = td->state;
  
@@ -1919,7 +1941,7 @@
  	mphy->test.state = state;
  
  	if (prev_state == MT76_TM_STATE_TX_FRAMES ||
-@@ -757,7 +1746,7 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -757,7 +1752,7 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
  	    (state == MT76_TM_STATE_OFF &&
  	     prev_state == MT76_TM_STATE_IDLE)) {
  		u32 changed = 0;
@@ -1928,7 +1950,7 @@
  
  		for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
  			u16 cur = tm_change_map[i];
-@@ -766,6 +1755,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -766,6 +1761,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
  				changed |= BIT(i);
  		}
  
@@ -1939,7 +1961,7 @@
  		mt7915_tm_update_params(phy, changed);
  	}
  
-@@ -778,10 +1771,8 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
+@@ -778,10 +1777,8 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
  {
  	struct mt76_testmode_data *td = &mphy->test;
  	struct mt7915_phy *phy = mphy->priv;
@@ -1952,7 +1974,7 @@
  
  	BUILD_BUG_ON(NUM_TM_CHANGED >= 32);
  
-@@ -789,9 +1780,9 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
+@@ -789,9 +1786,9 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
  	    td->state == MT76_TM_STATE_OFF)
  		return 0;
  
@@ -1965,7 +1987,7 @@
  
  	for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
  		if (tb[tm_change_map[i]])
-@@ -807,6 +1798,7 @@ static int
+@@ -807,6 +1804,7 @@ static int
  mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
  {
  	struct mt7915_phy *phy = mphy->priv;
@@ -1973,7 +1995,24 @@
  	void *rx, *rssi;
  	int i;
  
-@@ -852,11 +1844,75 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
+@@ -827,6 +1825,16 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
+ 
+ 	nla_nest_end(msg, rssi);
+ 
++	rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RSSI);
++	if (!rssi)
++		return -ENOMEM;
++
++	for (i = 0; i < ARRAY_SIZE(phy->test.last_rssi); i++)
++		if (nla_put_s8(msg, i, phy->test.last_rssi[i]))
++			return -ENOMEM;
++
++	nla_nest_end(msg, rssi);
++
+ 	rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_IB_RSSI);
+ 	if (!rssi)
+ 		return -ENOMEM;
+@@ -852,11 +1860,75 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
  
  	nla_nest_end(msg, rx);
  
@@ -2050,7 +2089,7 @@
 +	.set_eeprom = mt7915_tm_set_eeprom,
  };
 diff --git a/mt7915/testmode.h b/mt7915/testmode.h
-index a1c54c89..eb0e0432 100644
+index a1c54c8..eb0e043 100644
 --- a/mt7915/testmode.h
 +++ b/mt7915/testmode.h
 @@ -4,6 +4,8 @@
@@ -2365,10 +2404,18 @@
 +
  #endif
 diff --git a/testmode.c b/testmode.c
-index 1b37392c..d2cef5b9 100644
+index 1b37392..b39fef4 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -28,28 +28,16 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+@@ -8,6 +8,7 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+ 	[MT76_TM_ATTR_RESET] = { .type = NLA_FLAG },
+ 	[MT76_TM_ATTR_STATE] = { .type = NLA_U8 },
+ 	[MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 },
++	[MT76_TM_ATTR_SKU_EN] = { .type = NLA_U8 },
+ 	[MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 },
+ 	[MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 },
+ 	[MT76_TM_ATTR_TX_RATE_NSS] = { .type = NLA_U8 },
+@@ -28,28 +29,16 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
  };
  EXPORT_SYMBOL_GPL(mt76_tm_policy);
  
@@ -2403,7 +2450,7 @@
  	       q->queued < q->ndesc / 2) {
  		int ret;
  
-@@ -58,13 +46,68 @@ void mt76_testmode_tx_pending(struct mt76_phy *phy)
+@@ -58,13 +47,68 @@ void mt76_testmode_tx_pending(struct mt76_phy *phy)
  		if (ret < 0)
  			break;
  
@@ -2473,7 +2520,7 @@
  }
  
  static u32
-@@ -90,15 +133,31 @@ mt76_testmode_max_mpdu_len(struct mt76_phy *phy, u8 tx_rate_mode)
+@@ -90,15 +134,31 @@ mt76_testmode_max_mpdu_len(struct mt76_phy *phy, u8 tx_rate_mode)
  }
  
  static void
@@ -2509,7 +2556,7 @@
  {
  #define MT_TXP_MAX_LEN	4095
  	u16 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
-@@ -119,7 +178,8 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+@@ -119,7 +179,8 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
  	nfrags = len / MT_TXP_MAX_LEN;
  	head_len = nfrags ? MT_TXP_MAX_LEN : len;
  
@@ -2519,7 +2566,7 @@
  		fc |= IEEE80211_STYPE_QOS_DATA;
  
  	head = alloc_skb(head_len, GFP_KERNEL);
-@@ -128,9 +188,9 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+@@ -128,9 +189,9 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
  
  	hdr = __skb_put_zero(head, sizeof(*hdr));
  	hdr->frame_control = cpu_to_le16(fc);
@@ -2532,7 +2579,7 @@
  	skb_set_queue_mapping(head, IEEE80211_AC_BE);
  	get_random_bytes(__skb_put(head, head_len - sizeof(*hdr)),
  			 head_len - sizeof(*hdr));
-@@ -154,7 +214,7 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+@@ -154,7 +215,7 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
  
  		frag = alloc_skb(frag_len, GFP_KERNEL);
  		if (!frag) {
@@ -2541,7 +2588,7 @@
  			dev_kfree_skb(head);
  			return -ENOMEM;
  		}
-@@ -167,15 +227,14 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+@@ -167,15 +228,14 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
  		frag_tail = &(*frag_tail)->next;
  	}
  
@@ -2561,7 +2608,7 @@
  {
  	struct mt76_testmode_data *td = &phy->test;
  	struct ieee80211_tx_info *info;
-@@ -183,7 +242,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
+@@ -183,7 +243,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
  	u8 max_nss = hweight8(phy->antenna_mask);
  	int ret;
  
@@ -2570,7 +2617,7 @@
  	if (ret)
  		return ret;
  
-@@ -193,7 +252,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
+@@ -193,7 +253,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
  	if (td->tx_antenna_mask)
  		max_nss = min_t(u8, max_nss, hweight8(td->tx_antenna_mask));
  
@@ -2579,7 +2626,7 @@
  	rate = &info->control.rates[0];
  	rate->count = 1;
  	rate->idx = td->tx_rate_idx;
-@@ -265,6 +324,25 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
+@@ -265,6 +325,25 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
  out:
  	return 0;
  }
@@ -2605,7 +2652,7 @@
  
  static void
  mt76_testmode_tx_start(struct mt76_phy *phy)
-@@ -275,6 +353,14 @@ mt76_testmode_tx_start(struct mt76_phy *phy)
+@@ -275,6 +354,14 @@ mt76_testmode_tx_start(struct mt76_phy *phy)
  	td->tx_queued = 0;
  	td->tx_done = 0;
  	td->tx_pending = td->tx_count;
@@ -2620,7 +2667,7 @@
  	mt76_worker_schedule(&dev->tx_worker);
  }
  
-@@ -293,7 +379,7 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
+@@ -293,7 +380,7 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
  	wait_event_timeout(dev->tx_wait, td->tx_done == td->tx_queued,
  			   MT76_TM_TIMEOUT * HZ);
  
@@ -2629,7 +2676,7 @@
  }
  
  static inline void
-@@ -324,6 +410,8 @@ mt76_testmode_init_defaults(struct mt76_phy *phy)
+@@ -324,6 +411,8 @@ mt76_testmode_init_defaults(struct mt76_phy *phy)
  	memcpy(td->addr[0], phy->macaddr, ETH_ALEN);
  	memcpy(td->addr[1], phy->macaddr, ETH_ALEN);
  	memcpy(td->addr[2], phy->macaddr, ETH_ALEN);
@@ -2638,7 +2685,7 @@
  }
  
  static int
-@@ -333,8 +421,12 @@ __mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state)
+@@ -333,8 +422,12 @@ __mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state)
  	struct mt76_dev *dev = phy->dev;
  	int err;
  
@@ -2652,7 +2699,7 @@
  
  	if (state == MT76_TM_STATE_TX_FRAMES) {
  		err = mt76_testmode_tx_init(phy);
-@@ -404,6 +496,44 @@ mt76_tm_get_u8(struct nlattr *attr, u8 *dest, u8 min, u8 max)
+@@ -404,6 +497,44 @@ mt76_tm_get_u8(struct nlattr *attr, u8 *dest, u8 min, u8 max)
  	return 0;
  }
  
@@ -2697,7 +2744,7 @@
  int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		      void *data, int len)
  {
-@@ -427,6 +557,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -427,6 +558,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  
  	mutex_lock(&dev->mutex);
  
@@ -2709,7 +2756,17 @@
  	if (tb[MT76_TM_ATTR_RESET]) {
  		mt76_testmode_set_state(phy, MT76_TM_STATE_OFF);
  		memset(td, 0, sizeof(*td));
-@@ -453,7 +588,10 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -434,6 +570,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 
+ 	mt76_testmode_init_defaults(phy);
+ 
++	if (tb[MT76_TM_ATTR_SKU_EN])
++		td->sku_en = nla_get_u8(tb[MT76_TM_ATTR_SKU_EN]);
++
+ 	if (tb[MT76_TM_ATTR_TX_COUNT])
+ 		td->tx_count = nla_get_u32(tb[MT76_TM_ATTR_TX_COUNT]);
+ 
+@@ -453,7 +592,10 @@ 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],
@@ -2721,7 +2778,7 @@
  		goto out;
  
  	if (tb[MT76_TM_ATTR_TX_LENGTH]) {
-@@ -485,8 +623,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -485,8 +627,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  
  	if (tb[MT76_TM_ATTR_TX_POWER]) {
  		struct nlattr *cur;
@@ -2731,7 +2788,7 @@
  
  		nla_for_each_nested(cur, tb[MT76_TM_ATTR_TX_POWER], rem) {
  			if (nla_len(cur) != 1 ||
-@@ -506,11 +643,45 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -506,11 +647,45 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  			if (nla_len(cur) != ETH_ALEN || idx >= 3)
  				goto out;
  
@@ -2778,7 +2835,7 @@
  	if (dev->test_ops->set_params) {
  		err = dev->test_ops->set_params(phy, tb, state);
  		if (err)
-@@ -575,6 +746,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -575,6 +750,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  	struct mt76_phy *phy = hw->priv;
  	struct mt76_dev *dev = phy->dev;
  	struct mt76_testmode_data *td = &phy->test;
@@ -2786,7 +2843,7 @@
  	struct nlattr *tb[NUM_MT76_TM_ATTRS] = {};
  	int err = 0;
  	void *a;
-@@ -607,6 +779,19 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -607,6 +783,19 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  		goto out;
  	}
  
@@ -2806,11 +2863,12 @@
  	mt76_testmode_init_defaults(phy);
  
  	err = -EMSGSIZE;
-@@ -619,12 +804,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -619,12 +808,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  		goto out;
  
  	if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
 -	    nla_put_u32(msg, MT76_TM_ATTR_TX_LENGTH, td->tx_mpdu_len) ||
++	    nla_put_u8(msg, MT76_TM_ATTR_SKU_EN, td->sku_en) ||
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_MODE, td->tx_rate_mode) ||
 -	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_NSS, td->tx_rate_nss) ||
 -	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_IDX, td->tx_rate_idx) ||
@@ -2819,7 +2877,7 @@
  	    nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) ||
  	    (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_LTF) &&
  	     nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
-@@ -641,7 +822,16 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -641,7 +827,16 @@ 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) &&
@@ -2838,7 +2896,7 @@
  
  	if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER)) {
 diff --git a/testmode.h b/testmode.h
-index 89613266..8c55fa0f 100644
+index 8961326..7a68625 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -6,6 +6,8 @@
@@ -2850,7 +2908,15 @@
  
  /**
   * enum mt76_testmode_attr - testmode attributes inside NL80211_ATTR_TESTDATA
-@@ -47,6 +49,15 @@
+@@ -18,6 +20,7 @@
+  * @MT76_TM_ATTR_MTD_PART: mtd partition used for eeprom data (string)
+  * @MT76_TM_ATTR_MTD_OFFSET: offset of eeprom data within the partition (u32)
+  *
++ * @MT76_TM_ATTR_SKU_EN: config txpower sku is enabled or disabled in testmode (u8)
+  * @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)
+@@ -47,6 +50,15 @@
   * @MT76_TM_ATTR_DRV_DATA: driver specific netlink attrs (nested)
   *
   * @MT76_TM_ATTR_MAC_ADDRS: array of nested MAC addresses (nested)
@@ -2866,7 +2932,15 @@
   */
  enum mt76_testmode_attr {
  	MT76_TM_ATTR_UNSPEC,
-@@ -84,6 +95,17 @@ enum mt76_testmode_attr {
+@@ -57,6 +69,7 @@ enum mt76_testmode_attr {
+ 	MT76_TM_ATTR_MTD_PART,
+ 	MT76_TM_ATTR_MTD_OFFSET,
+ 
++	MT76_TM_ATTR_SKU_EN,
+ 	MT76_TM_ATTR_TX_COUNT,
+ 	MT76_TM_ATTR_TX_LENGTH,
+ 	MT76_TM_ATTR_TX_RATE_MODE,
+@@ -84,6 +97,17 @@ enum mt76_testmode_attr {
  	MT76_TM_ATTR_DRV_DATA,
  
  	MT76_TM_ATTR_MAC_ADDRS,
@@ -2884,7 +2958,23 @@
  
  	/* keep last */
  	NUM_MT76_TM_ATTRS,
-@@ -198,4 +220,57 @@ enum mt76_testmode_tx_mode {
+@@ -128,6 +152,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)
++ * @MT76_TM_RX_ATTR_RSSI: received signal strength indicator (array, s8)
+  * @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)
+@@ -137,6 +162,7 @@ enum mt76_testmode_rx_attr {
+ 
+ 	MT76_TM_RX_ATTR_FREQ_OFFSET,
+ 	MT76_TM_RX_ATTR_RCPI,
++	MT76_TM_RX_ATTR_RSSI,
+ 	MT76_TM_RX_ATTR_IB_RSSI,
+ 	MT76_TM_RX_ATTR_WB_RSSI,
+ 	MT76_TM_RX_ATTR_SNR,
+@@ -198,4 +224,57 @@ enum mt76_testmode_tx_mode {
  
  extern const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS];
  
@@ -2943,7 +3033,7 @@
 +
  #endif
 diff --git a/tools/fields.c b/tools/fields.c
-index e3f69089..7e564a3b 100644
+index e3f6908..406ba77 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -10,6 +10,7 @@ static const char * const testmode_state[] = {
@@ -2954,6 +3044,15 @@
  };
  
  static const char * const testmode_tx_mode[] = {
+@@ -65,7 +66,7 @@ static bool parse_u8(const struct tm_field *field, int idx,
+ 
+ static void print_u8(const struct tm_field *field, struct nlattr *attr)
+ {
+-	printf("%d", nla_get_u8(attr));
++	printf("%u", nla_get_u8(attr));
+ }
+ 
+ static void print_s8(const struct tm_field *field, struct nlattr *attr)
 @@ -86,12 +87,12 @@ static void print_s32(const struct tm_field *field, struct nlattr *attr)
  
  static void print_u32(const struct tm_field *field, struct nlattr *attr)
@@ -3033,7 +3132,7 @@
  
  #define FIELD_GENERIC(_field, _name, ...)	\
  	[FIELD_NAME(_field)] = {			\
-@@ -250,6 +308,13 @@ static void print_extra_stats(const struct tm_field *field, struct nlattr **tb)
+@@ -250,10 +308,18 @@ static void print_extra_stats(const struct tm_field *field, struct nlattr **tb)
  		 ##__VA_ARGS__				\
  	)
  
@@ -3047,7 +3146,28 @@
  #define FIELD_NAME(_field) MT76_TM_RX_ATTR_##_field
  static const struct tm_field rx_fields[NUM_MT76_TM_RX_ATTRS] = {
  	FIELD_RO(s32, FREQ_OFFSET, "freq_offset"),
-@@ -300,10 +365,18 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+ 	FIELD_ARRAY_RO(u8, RCPI, "rcpi"),
++	FIELD_ARRAY_RO(s8, RSSI, "rssi"),
+ 	FIELD_ARRAY_RO(s8, IB_RSSI, "ib_rssi"),
+ 	FIELD_ARRAY_RO(s8, WB_RSSI, "wb_rssi"),
+ 	FIELD_RO(s8, SNR, "snr"),
+@@ -261,6 +327,7 @@ static const struct tm_field rx_fields[NUM_MT76_TM_RX_ATTRS] = {
+ static struct nla_policy rx_policy[NUM_MT76_TM_RX_ATTRS] = {
+ 	[MT76_TM_RX_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
+ 	[MT76_TM_RX_ATTR_RCPI] = { .type = NLA_NESTED },
++	[MT76_TM_RX_ATTR_RSSI] = { .type = NLA_NESTED },
+ 	[MT76_TM_RX_ATTR_IB_RSSI] = { .type = NLA_NESTED },
+ 	[MT76_TM_RX_ATTR_WB_RSSI] = { .type = NLA_NESTED },
+ 	[MT76_TM_RX_ATTR_SNR] = { .type = NLA_U8 },
+@@ -291,6 +358,7 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+ 	FIELD_ENUM(STATE, "state", testmode_state),
+ 	FIELD_RO(string, MTD_PART, "mtd_part"),
+ 	FIELD_RO(u32, MTD_OFFSET, "mtd_offset"),
++	FIELD(u8, SKU_EN, "sku_en"),
+ 	FIELD(u32, TX_COUNT, "tx_count"),
+ 	FIELD(u32, TX_LENGTH, "tx_length"),
+ 	FIELD_ENUM(TX_RATE_MODE, "tx_rate_mode", testmode_tx_mode),
+@@ -300,10 +368,18 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
  	FIELD(u8, TX_RATE_LDPC, "tx_rate_ldpc"),
  	FIELD(u8, TX_RATE_STBC, "tx_rate_stbc"),
  	FIELD(u8, TX_LTF, "tx_ltf"),
@@ -3066,7 +3186,15 @@
  	FIELD_NESTED_RO(STATS, stats, "",
  			.print_extra = print_extra_stats),
  };
-@@ -322,9 +395,16 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
+@@ -313,6 +389,7 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
+ 	[MT76_TM_ATTR_STATE] = { .type = NLA_U8 },
+ 	[MT76_TM_ATTR_MTD_PART] = { .type = NLA_STRING },
+ 	[MT76_TM_ATTR_MTD_OFFSET] = { .type = NLA_U32 },
++	[MT76_TM_ATTR_SKU_EN] = { .type = NLA_U8 },
+ 	[MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 },
+ 	[MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 },
+ 	[MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 },
+@@ -322,9 +399,16 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
  	[MT76_TM_ATTR_TX_RATE_LDPC] = { .type = NLA_U8 },
  	[MT76_TM_ATTR_TX_RATE_STBC] = { .type = NLA_U8 },
  	[MT76_TM_ATTR_TX_LTF] = { .type = NLA_U8 },
@@ -3084,7 +3212,7 @@
  };
  
 diff --git a/tx.c b/tx.c
-index 6cc26cc6..5d7bf340 100644
+index 1809b03..f1dd9f6 100644
 --- a/tx.c
 +++ b/tx.c
 @@ -259,8 +259,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
@@ -3098,5 +3226,5 @@
  			wake_up(&dev->tx_wait);
  
 -- 
-2.39.2
+2.18.0
 
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 dff4e09..f789822 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 431feba8fc3c13f6181fce8da33d4df29ce626a2 Mon Sep 17 00:00:00 2001
+From c1b540f4e8ec1de754a3325f1f7abe8099108309 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 1010/1034] wifi: mt76: testmode: add pre-cal support
+Subject: [PATCH] wifi: mt76: testmode: add pre-cal support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -36,10 +36,10 @@
  
  out_put_node:
 diff --git a/mt76.h b/mt76.h
-index a5908de4..7d83d406 100644
+index 597488db..66495b17 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -658,6 +658,7 @@ struct mt76_testmode_ops {
+@@ -671,6 +671,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 e3980c37..acbc07da 100644
+index 7a7dbf48..a6449d1c 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -994,6 +994,7 @@ enum {
+@@ -998,6 +998,7 @@ enum {
  
  /* ext event table */
  enum {
@@ -113,10 +113,10 @@
  
  #endif
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 6a5f204c..b6f50daf 100644
+index 0d1e09c3..474bed1b 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -393,6 +393,9 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -395,6 +395,9 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	case MCU_EXT_EVENT_BF_STATUS_READ:
  		mt7915_tm_txbf_status_read(dev, skb);
  		break;
@@ -126,7 +126,7 @@
  #endif
  	default:
  		break;
-@@ -2930,7 +2933,7 @@ int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
+@@ -2939,7 +2942,7 @@ int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
  	u8 idx = 0, *cal = dev->cal, *eep = dev->mt76.eeprom.data;
  	u32 total = MT_EE_CAL_GROUP_SIZE;
  
@@ -135,7 +135,7 @@
  		return 0;
  
  	/*
-@@ -3010,11 +3013,29 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
+@@ -3019,11 +3022,29 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
  {
  	struct mt7915_dev *dev = phy->dev;
  	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
@@ -168,10 +168,10 @@
  
  	idx = mt7915_dpd_freq_idx(center_freq, chandef->width);
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index c91415f7..863624f4 100644
+index b91af946..ce128ab5 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -355,6 +355,10 @@ struct mt7915_dev {
+@@ -359,6 +359,10 @@ struct mt7915_dev {
  	struct rchan *relay_fwlog;
  
  	void *cal;
@@ -182,7 +182,7 @@
  
  	struct {
  		u8 debug_wm;
-@@ -591,6 +595,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
+@@ -595,6 +599,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
  void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
  void mt7915_mcu_exit(struct mt7915_dev *dev);
  int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb);
@@ -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 1e72bf2a..7d285ebc 100644
+index 83672046..3a4516ef 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -5,6 +5,7 @@
@@ -202,7 +202,7 @@
  
  enum {
  	TM_CHANGED_TXPOWER,
-@@ -1599,18 +1600,16 @@ mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper)
+@@ -1602,18 +1603,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),
  	};
-@@ -1695,6 +1694,316 @@ out:
+@@ -1698,6 +1697,316 @@ out:
  				 sizeof(req), true);
  }
  
@@ -540,7 +540,7 @@
  static void
  mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
  {
-@@ -1739,6 +2048,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -1746,6 +2055,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) ||
-@@ -1909,9 +2222,113 @@ mt7915_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
+@@ -1926,9 +2239,113 @@ mt7915_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
  	return ret;
  }
  
@@ -734,10 +734,10 @@
  	TAM_ARB_OP_MODE_NORMAL = 1,
  	TAM_ARB_OP_MODE_TEST,
 diff --git a/testmode.c b/testmode.c
-index d2cef5b9..b1b643c3 100644
+index b39fef4f..26e2de24 100644
 --- a/testmode.c
 +++ b/testmode.c
-@@ -767,6 +767,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -771,6 +771,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  
  	mutex_lock(&dev->mutex);
  
@@ -756,7 +756,7 @@
  	if (tb[MT76_TM_ATTR_STATS]) {
  		err = -EINVAL;
  
-@@ -800,7 +812,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+@@ -804,7 +816,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
  
  	if (dev->test_mtd.name &&
  	    (nla_put_string(msg, MT76_TM_ATTR_MTD_PART, dev->test_mtd.name) ||
@@ -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 8c55fa0f..109a556a 100644
+index 7a686250..e4c1b521 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -19,6 +19,7 @@
@@ -776,9 +776,9 @@
   * @MT76_TM_ATTR_MTD_OFFSET: offset of eeprom data within the partition (u32)
 + * @MT76_TM_ATTR_BAND_IDX: band idx of the chip (u8)
   *
+  * @MT76_TM_ATTR_SKU_EN: config txpower sku is enabled or disabled in testmode (u8)
   * @MT76_TM_ATTR_TX_COUNT: configured number of frames to send when setting
-  *	state to MT76_TM_STATE_TX_FRAMES (u32)
-@@ -40,6 +41,11 @@
+@@ -41,6 +42,11 @@
   *
   * @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr)
   *
@@ -790,15 +790,15 @@
   * @MT76_TM_ATTR_TX_SPE_IDX: tx spatial extension index (u8)
   *
   * @MT76_TM_ATTR_TX_DUTY_CYCLE: packet tx duty cycle (u8)
-@@ -67,6 +73,7 @@ enum mt76_testmode_attr {
+@@ -68,6 +74,7 @@ enum mt76_testmode_attr {
  
  	MT76_TM_ATTR_MTD_PART,
  	MT76_TM_ATTR_MTD_OFFSET,
 +	MT76_TM_ATTR_BAND_IDX,
  
+ 	MT76_TM_ATTR_SKU_EN,
  	MT76_TM_ATTR_TX_COUNT,
- 	MT76_TM_ATTR_TX_LENGTH,
-@@ -85,6 +92,8 @@ enum mt76_testmode_attr {
+@@ -87,6 +94,8 @@ enum mt76_testmode_attr {
  	MT76_TM_ATTR_FREQ_OFFSET,
  
  	MT76_TM_ATTR_STATS,
@@ -807,7 +807,7 @@
  
  	MT76_TM_ATTR_TX_SPE_IDX,
  
-@@ -184,6 +193,14 @@ enum mt76_testmode_state {
+@@ -188,6 +197,14 @@ enum mt76_testmode_state {
  	MT76_TM_STATE_TX_FRAMES,
  	MT76_TM_STATE_RX_FRAMES,
  	MT76_TM_STATE_TX_CONT,
@@ -823,7 +823,7 @@
  
  	/* keep last */
 diff --git a/tools/fields.c b/tools/fields.c
-index 7e564a3b..3ca5cd1f 100644
+index 406ba77c..27801dbe 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -11,6 +11,14 @@ static const char * const testmode_state[] = {
@@ -842,5 +842,5 @@
  
  static const char * const testmode_tx_mode[] = {
 -- 
-2.39.2
+2.18.0
 
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 67b3062..b476e79 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 439452d1e6ee75c69c94292b50e065b2f1ee0112 Mon Sep 17 00:00:00 2001
+From bc3169129e2978e3ec2e1a630023a30e78d18237 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/1034] wifi: mt76: testmode: add iBF command mode support
+Subject: [PATCH 1011/1040] wifi: mt76: testmode: add iBF command mode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  4 files changed, 85 insertions(+), 7 deletions(-)
 
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 7d285ebc..f735cae8 100644
+index 5ff183a..86deae6 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)
@@ -50,7 +50,7 @@
  			break;
  		case IBF_PHASE_CAL_VERIFY:
  		case IBF_PHASE_CAL_VERIFY_INSTRUMENT:
-@@ -884,7 +887,6 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
+@@ -885,7 +888,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 {
-@@ -942,8 +944,8 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -943,8 +945,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:
-@@ -961,10 +963,17 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -962,10 +964,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;
  	};
-@@ -1091,7 +1100,6 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
+@@ -1092,7 +1101,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)
-@@ -1456,7 +1464,6 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1457,7 +1465,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,7 +104,7 @@
  		mt7915_tm_set_tx_len(phy, tx_time);
  
 diff --git a/testmode.c b/testmode.c
-index b1b643c3..f415beca 100644
+index b1b643c..f415bec 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -534,6 +534,42 @@ out:
@@ -163,7 +163,7 @@
  		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 109a556a..d2675ddc 100644
+index 109a556..d2675dd 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -281,8 +281,10 @@ enum mt76_testmode_txbf_act {
@@ -178,7 +178,7 @@
  
  	/* keep last */
 diff --git a/tools/fields.c b/tools/fields.c
-index 3ca5cd1f..6bf4c046 100644
+index 3ca5cd1..6bf4c04 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -32,6 +32,20 @@ static const char * const testmode_tx_mode[] = {
@@ -238,5 +238,5 @@
  
  const struct tm_field msg_field = {
 -- 
-2.39.2
+2.18.0
 
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 c0b9eba..abeb149 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 ddb1f053f52c744d0bcbf10563c8e904f6bffa17 Mon Sep 17 00:00:00 2001
+From 1334f63638dc3cfc7bbcd8f14ee72d2b9847dd6d 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/1034] wifi: mt76: testmode: add ZWDFS test mode support
+Subject: [PATCH 1012/1040] 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 7d83d406..75b28748 100644
+index ed1c864..ed69106 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -741,6 +741,15 @@ struct mt76_testmode_data {
+@@ -754,6 +754,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 acbc07da..e55e548e 100644
+index a6449d1..2848179 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1195,6 +1195,7 @@ enum {
+@@ -1206,6 +1206,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,
-@@ -1205,6 +1206,7 @@ enum {
+@@ -1216,6 +1217,7 @@ enum {
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_CERT_CFG = 0xb7,
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
@@ -58,10 +58,10 @@
  
  enum {
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index b6f50daf..020780d3 100644
+index 474bed1..2cd772b 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -2661,6 +2661,7 @@ mt7915_mcu_background_chain_ctrl(struct mt7915_phy *phy,
+@@ -2670,6 +2670,7 @@ mt7915_mcu_background_chain_ctrl(struct mt7915_phy *phy,
  		req.monitor_chan = chandef->chan->hw_value;
  		req.monitor_central_chan =
  			ieee80211_frequency_to_channel(chandef->center_freq1);
@@ -69,7 +69,7 @@
  		req.band_idx = phy->mt76->band_idx;
  		req.scan_mode = 2;
  		break;
-@@ -4699,3 +4700,68 @@ int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable)
+@@ -4708,3 +4709,68 @@ int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable)
  	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MEC_CTRL), &req, sizeof(req), true);
  }
  #endif
@@ -139,7 +139,7 @@
 +	return 0;
 +}
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 99827354..f4c3bf4e 100644
+index 9982735..f4c3bf4 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -686,6 +686,52 @@ struct csi_data {
@@ -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 863624f4..88e45298 100644
+index 18881c0..33ac2d2 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;
-@@ -707,6 +708,9 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
+@@ -710,6 +711,9 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
  				  struct ieee80211_sta *sta);
  #endif
  
@@ -218,10 +218,10 @@
  int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir);
  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/regs.h b/mt7915/regs.h
-index 428f4820..482b3fee 100644
+index 6783797..44863e8 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
-@@ -1208,6 +1208,8 @@ enum offs_rev {
+@@ -1209,6 +1209,8 @@ enum offs_rev {
  #define MT_WF_IRPI_NSS(phy, nss)	MT_WF_IRPI(0x6000 + ((phy) << 20) + ((nss) << 16))
  #define MT_WF_IRPI_NSS_MT7916(phy, nss)	MT_WF_IRPI(0x1000 + ((phy) << 20) + ((nss) << 16))
  
@@ -231,7 +231,7 @@
  #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 f735cae8..2e51dcd5 100644
+index 86deae6..e321848 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -13,6 +13,12 @@ enum {
@@ -260,7 +260,7 @@
  };
  
  struct reg_band {
-@@ -981,6 +993,272 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -982,6 +994,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)
-@@ -1268,6 +1546,8 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
+@@ -1269,6 +1547,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 @@
  	}
  }
  
-@@ -2027,6 +2307,14 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
+@@ -2028,6 +2308,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,7 +558,7 @@
  
  static int
 diff --git a/testmode.c b/testmode.c
-index f415beca..babae8d4 100644
+index f415bec..babae8d 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -25,6 +25,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
@@ -622,7 +622,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/testmode.h b/testmode.h
-index d2675ddc..97e75964 100644
+index d2675dd..97e7596 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -63,6 +63,20 @@
@@ -690,7 +690,7 @@
 +
  #endif
 diff --git a/tools/fields.c b/tools/fields.c
-index 6bf4c046..fc01043e 100644
+index 6bf4c04..fc01043 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -46,6 +46,14 @@ static const char * const testmode_txbf_act[] = {
@@ -737,5 +737,5 @@
  
  const struct tm_field msg_field = {
 -- 
-2.39.2
+2.18.0
 
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 f88823a..e6f1971 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 7598ccc4626d9d41807a59fa8304649a7260b9ed Mon Sep 17 00:00:00 2001
+From ea0393c4c9076db02c3ebe34b87dc381c34e5a3d 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 1013/1040] 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, 857 insertions(+), 324 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 75b2874..af29bde 100644
+index ed69106..fa9c6a4 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -703,6 +703,7 @@ struct mt76_testmode_data {
+@@ -716,6 +716,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;
-@@ -731,6 +732,9 @@ struct mt76_testmode_data {
+@@ -744,6 +745,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 74b63f0..e6b468c 100644
+index 60e159c..07bd57b 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -2767,6 +2767,7 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
+@@ -2796,6 +2796,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;
-@@ -2826,6 +2827,8 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
+@@ -2855,6 +2856,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 6c9401d..1e0bee7 100644
+index bd0efd5..4244177 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -729,8 +729,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 d7bcd5f..9694bd7 100644
+index 3b18c95..169d597 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 020780d..c8b97e8 100644
+index 2cd772b..83d974c 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,
@@ -186,7 +186,7 @@
  	if (ret)
  		return ret;
  
-@@ -389,10 +390,12 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -391,10 +392,12 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	case MCU_EXT_EVENT_BCC_NOTIFY:
  		mt7915_mcu_rx_bcc_notify(dev, skb);
  		break;
@@ -201,7 +201,7 @@
  	case MCU_EXT_EVENT_RF_TEST:
  		mt7915_tm_rf_test_event(dev, skb);
  		break;
-@@ -681,11 +684,22 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
+@@ -683,11 +686,22 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
  	if (enable)
  		mt76_connac_mcu_bss_omac_tlv(skb, vif);
  
@@ -227,7 +227,7 @@
  
  	if (enable) {
  		mt7915_mcu_bss_rfch_tlv(skb, vif, phy);
-@@ -3431,6 +3445,7 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
+@@ -3440,6 +3454,7 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
  
  int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
  {
@@ -235,7 +235,7 @@
  	struct {
  		u8 action;
  		union {
-@@ -3457,7 +3472,6 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
+@@ -3466,7 +3481,6 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
  		.action = action,
  	};
  
@@ -243,7 +243,7 @@
  	switch (action) {
  	case MT_BF_SOUNDING_ON:
  		req.snd.snd_mode = MT_BF_PROCESSING;
-@@ -4592,6 +4606,9 @@ int mt7915_mcu_set_txbf_sound_info(struct mt7915_phy *phy, u8 action,
+@@ -4601,6 +4615,9 @@ int mt7915_mcu_set_txbf_sound_info(struct mt7915_phy *phy, u8 action,
  		req.he_opt = v2;
  		req.glo_opt = v3;
  		break;
@@ -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 6505d76..25c3fe2 100644
+index 87a5c5c..6dd6eca 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -133,6 +133,7 @@ static const u32 mt7915_offs[] = {
@@ -468,7 +468,7 @@
  	[AGG_AALCR0]		= 0x028,
  	[AGG_AWSCR0]		= 0x030,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 88e4529..4572066 100644
+index 33ac2d2..135b39b 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -274,7 +274,6 @@ struct mt7915_phy {
@@ -479,7 +479,7 @@
  		bool bf_ever_en;
  	} test;
  #endif
-@@ -376,7 +375,7 @@ struct mt7915_dev {
+@@ -379,7 +378,7 @@ struct mt7915_dev {
  	void __iomem *dcm;
  	void __iomem *sku;
  
@@ -488,7 +488,7 @@
  	struct {
  		void *txbf_phase_cal;
  		void *txbf_pfmu_data;
-@@ -515,6 +514,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
+@@ -518,6 +517,7 @@ 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_phy *phy);
@@ -496,7 +496,7 @@
  void mt7915_reset(struct mt7915_dev *dev);
  int mt7915_run(struct ieee80211_hw *hw);
  int mt7915_mcu_init(struct mt7915_dev *dev);
-@@ -595,8 +595,10 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
+@@ -598,8 +598,10 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
  int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
  void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
  void mt7915_mcu_exit(struct mt7915_dev *dev);
@@ -508,7 +508,7 @@
  
  static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
  {
-@@ -731,4 +733,10 @@ enum {
+@@ -734,4 +736,10 @@ enum {
  
  #endif
  
@@ -520,10 +520,10 @@
 +
  #endif
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 9bb6dd0..6d9d009 100644
+index 96655db..7fc6a3f 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
-@@ -2892,6 +2892,36 @@ mt7915_txpower_level_set(void *data, u64 val)
+@@ -2890,6 +2890,36 @@ mt7915_txpower_level_set(void *data, u64 val)
  DEFINE_DEBUGFS_ATTRIBUTE(fops_txpower_level, NULL,
  			 mt7915_txpower_level_set, "%lld\n");
  
@@ -560,7 +560,7 @@
  /* usage: echo 0x[arg3][arg2][arg1] > fw_wa_set */
  static int
  mt7915_wa_set(void *data, u64 val)
-@@ -3651,6 +3681,11 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+@@ -3649,6 +3679,11 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  	debugfs_create_file("txpower_level", 0400, dir, dev,
  			    &fops_txpower_level);
  
@@ -836,7 +836,7 @@
 +}
 +#endif
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 482b3fe..44da7b8 100644
+index 44863e8..1f1f8b9 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
 @@ -61,6 +61,7 @@ enum offs_rev {
@@ -847,7 +847,7 @@
  	RMAC_MIB_AIRTIME14,
  	AGG_AALCR0,
  	AGG_AWSCR0,
-@@ -533,6 +534,9 @@ enum offs_rev {
+@@ -534,6 +535,9 @@ enum offs_rev {
  #define MT_ARB_DRNGR0(_band, _n)	MT_WF_ARB(_band, (__OFFS(ARB_DRNGR0) +	\
  							  (_n) * 4))
  
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 704b730..ce08209 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,7 +1,7 @@
-From 0d52f2e48810848f5e9203551554fc893d04ecbf Mon Sep 17 00:00:00 2001
+From 6f767bac12cec3502c3760984abffcf2d806b70f 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/1034] wifi: mt76: mt7915: init rssi in WTBL when add
+Subject: [PATCH 1014/1040] wifi: mt76: mt7915: init rssi in WTBL when add
  station
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 9694bd71..d43dd584 100644
+index 169d597..e11ae9f 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -749,6 +749,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -761,6 +761,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 +20,7 @@
  
  	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
  	if (idx < 0)
-@@ -773,6 +774,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -785,6 +786,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (ret)
  		return ret;
  
@@ -31,5 +31,5 @@
  	mt7915_vendor_amnt_sta_remove(mvif->phy, sta);
  #endif
 -- 
-2.39.2
+2.18.0
 
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 afa2b05..f7936c9 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 1d14e8d3170e8cad4b0a03a94231f720f8b8938c Mon Sep 17 00:00:00 2001
+From c1864400a5aa6b60aebe412f8625109b61db04c0 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/1034] wifi: mt76: connac: airtime fairness feature off in
+Subject: [PATCH 1015/1040] 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 ed1d659b..25ec4330 100644
+index fccf26d..ad3a5e2 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -437,7 +437,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
+@@ -440,7 +440,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);
@@ -21,5 +21,5 @@
  
  	wiphy->available_antennas_tx = phy->antenna_mask;
 -- 
-2.39.2
+2.18.0
 
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 0536615..c018337 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,7 +1,7 @@
-From 68772db4cdffdeceb9c65823ec060b4ec0642136 Mon Sep 17 00:00:00 2001
+From c30637769e5ab91210b3ef958fb5e27212ed89e4 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/1034] wifi: mt76: mt7915: add mt7986 and mt7916
+Subject: [PATCH 1016/1040] wifi: mt76: mt7915: add mt7986 and mt7916
  pre-calibration
 
 Add pre-calibration for mt7986 and mt7916. It has different data size
@@ -16,7 +16,7 @@
  3 files changed, 62 insertions(+), 26 deletions(-)
 
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index f5ab3319..a5c99a5e 100644
+index f5ab331..a5c99a5 100644
 --- a/mt7915/eeprom.c
 +++ b/mt7915/eeprom.c
 @@ -9,23 +9,22 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
@@ -51,7 +51,7 @@
  
  static int mt7915_check_eeprom(struct mt7915_dev *dev)
 diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h
-index 88aaa16a..fdae347e 100644
+index 88aaa16..fdae347 100644
 --- a/mt7915/eeprom.h
 +++ b/mt7915/eeprom.h
 @@ -19,6 +19,7 @@ enum mt7915_eeprom_field {
@@ -63,10 +63,10 @@
  	MT_EE_RATE_DELTA_5G =	0x29d,
  	MT_EE_TX0_POWER_2G =	0x2fc,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index c8b97e89..fa2c6919 100644
+index 83d974c..8202a4e 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -2946,7 +2946,8 @@ static int mt7915_mcu_set_pre_cal(struct mt7915_dev *dev, u8 idx,
+@@ -2955,7 +2955,8 @@ static int mt7915_mcu_set_pre_cal(struct mt7915_dev *dev, u8 idx,
  int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
  {
  	u8 idx = 0, *cal = dev->cal, *eep = dev->mt76.eeprom.data;
@@ -76,7 +76,7 @@
  
  	if (!(eep[offs] & MT_EE_WIFI_CAL_GROUP))
  		return 0;
-@@ -2984,9 +2985,9 @@ static int mt7915_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)
+@@ -2993,9 +2994,9 @@ static int mt7915_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)
  	return -1;
  }
  
@@ -88,7 +88,7 @@
  		5180, 5200, 5220, 5240,
  		5260, 5280, 5300, 5320,
  		5500, 5520, 5540, 5560,
-@@ -2994,34 +2995,69 @@ static int mt7915_dpd_freq_idx(u16 freq, u8 bw)
+@@ -3003,34 +3004,69 @@ static int mt7915_dpd_freq_idx(u16 freq, u8 bw)
  		5660, 5680, 5700, 5745,
  		5765, 5785, 5805, 5825
  	};
@@ -168,7 +168,7 @@
  }
  
  int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
-@@ -3053,24 +3089,24 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
+@@ -3062,24 +3098,24 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
  	if (!(eep[offs] & dpd_mask))
  		return 0;
  
@@ -199,5 +199,5 @@
  
  	return 0;
 -- 
-2.39.2
+2.18.0
 
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 91dd627..3562374 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,7 +1,7 @@
-From cb99b4cd73793df9da8e7723cef7c2c125a5d012 Mon Sep 17 00:00:00 2001
+From 4bca02444e44f948a9d8d26fb155c7c1f1304f31 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/1034] wifi: mt76: mt7915: add phy capability vendor
+Subject: [PATCH 1017/1040] wifi: mt76: mt7915: add phy capability vendor
  command
 
 ---
@@ -11,7 +11,7 @@
  3 files changed, 78 insertions(+)
 
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 4572066b..a3575b66 100644
+index 135b39b..b41c96b 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -11,6 +11,7 @@
@@ -23,7 +23,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 df1cac3f..3dbbd326 100644
+index df1cac3..3dbbd32 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -50,6 +50,18 @@ rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
@@ -100,7 +100,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 2be5fc89..ffdb466b 100644
+index 2be5fc8..ffdb466 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -9,6 +9,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -141,5 +141,5 @@
 +
  #endif
 -- 
-2.39.2
+2.18.0
 
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 c03b8b8..b7ed3aa 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 77df44ad45a75af9eb84e40fc81a57b39776cb17 Mon Sep 17 00:00:00 2001
+From fb237147a73b10808a651273198583b938003338 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/1034] wifi: mt76: mt7915: add vendor subcmd EDCCA ctrl
+Subject: [PATCH 1018/1040] 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 e55e548e..da2f5dd0 100644
+index 2848179..4905411 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1205,6 +1205,7 @@ enum {
+@@ -1216,6 +1216,7 @@ enum {
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_CERT_CFG = 0xb7,
@@ -28,7 +28,7 @@
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
  };
 diff --git a/mt7915/main.c b/mt7915/main.c
-index d43dd584..85524e91 100644
+index e11ae9f..287ca99 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -478,6 +478,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
@@ -42,10 +42,10 @@
  		ret = mt7915_set_channel(phy);
  		if (ret)
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index fa2c6919..96c47273 100644
+index 8202a4e..83ceb2e 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4818,3 +4818,76 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w
+@@ -4827,3 +4827,76 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w
  
  	return 0;
  }
@@ -123,7 +123,7 @@
 +	return 0;
 +}
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index c95d9900..d271e2be 100644
+index c95d990..d271e2b 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -1116,6 +1116,27 @@ enum {
@@ -155,10 +155,10 @@
  
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index a3575b66..c01e0522 100644
+index b41c96b..c5f4e94 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -710,7 +710,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
+@@ -713,7 +713,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 3dbbd326..afba18e4 100644
+index 3dbbd32..afba18e 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -62,6 +62,24 @@ phy_capa_dump_policy[NUM_MTK_VENDOR_ATTRS_PHY_CAPA_DUMP] = {
@@ -326,7 +326,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index ffdb466b..0c96377f 100644
+index ffdb466..0c96377 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -2,6 +2,7 @@
@@ -377,5 +377,5 @@
  
  enum mtk_capi_control_changed {
 -- 
-2.39.2
+2.18.0
 
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 8b25711..9ab86d5 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,7 +1,7 @@
-From 9d3a10ebaa4a56d53182845525098e878b5df462 Mon Sep 17 00:00:00 2001
+From 21c0d49738d105ad23e248a213da069e4e57dd21 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 1019/1034] wifi: mt76: mt7915: implement bin file mode
+Subject: [PATCH 1019/1040] wifi: mt76: mt7915: implement bin file mode
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
@@ -15,7 +15,7 @@
  6 files changed, 111 insertions(+), 3 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index 9b637992..eb532c77 100644
+index 9b63799..eb532c7 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)
@@ -46,10 +46,10 @@
  mt76_eeprom_override(struct mt76_phy *phy)
  {
 diff --git a/mt76.h b/mt76.h
-index af29bdeb..b4e34296 100644
+index fa9c6a4..13796ad 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -925,6 +925,9 @@ struct mt76_dev {
+@@ -941,6 +941,9 @@ struct mt76_dev {
  		struct mt76_usb usb;
  		struct mt76_sdio sdio;
  	};
@@ -59,7 +59,7 @@
  };
  
  /* per-phy stats.  */
-@@ -1156,6 +1159,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
+@@ -1173,6 +1176,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);
@@ -68,7 +68,7 @@
  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 a5c99a5e..fd08d42a 100644
+index a5c99a5..fd08d42 100644
 --- a/mt7915/eeprom.c
 +++ b/mt7915/eeprom.c
 @@ -47,8 +47,11 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev)
@@ -149,7 +149,7 @@
  		if (ret)
  			return ret;
 diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h
-index fdae347e..9056d786 100644
+index fdae347..9056d78 100644
 --- a/mt7915/eeprom.h
 +++ b/mt7915/eeprom.h
 @@ -108,6 +108,13 @@ enum mt7915_sku_rate_group {
@@ -167,10 +167,10 @@
  mt7915_get_channel_group_5g(int channel, bool is_7976)
  {
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index c01e0522..6c4f407b 100644
+index c5f4e94..b6a564e 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -349,6 +349,8 @@ struct mt7915_dev {
+@@ -350,6 +350,8 @@ struct mt7915_dev {
  
  	bool dbdc_support;
  	bool flash_mode;
@@ -179,7 +179,7 @@
  	bool muru_debug;
  	bool ibf;
  
-@@ -723,6 +725,7 @@ void mt7915_dump_tmac_info(u8 *tmac_info);
+@@ -726,6 +728,7 @@ void mt7915_dump_tmac_info(u8 *tmac_info);
  int mt7915_mcu_set_txpower_level(struct mt7915_phy *phy, u8 drop_level);
  void mt7915_packet_log_to_host(struct mt7915_dev *dev, const void *data, int len, int type, int des_len);
  int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable);
@@ -188,7 +188,7 @@
  #define PKT_BIN_DEBUG_MAGIC	0xc8763123
  enum {
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 6d9d009d..bc683db8 100644
+index 7fc6a3f..b949ad7 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -3,6 +3,7 @@
@@ -199,7 +199,7 @@
  
  #ifdef MTK_DEBUG
  #define LWTBL_IDX2BASE_ID		GENMASK(14, 8)
-@@ -3602,6 +3603,47 @@ static int mt7915_fw_wm_info_read(struct seq_file *s, void *data)
+@@ -3600,6 +3601,47 @@ static int mt7915_fw_wm_info_read(struct seq_file *s, void *data)
  	return 0;
  }
  
@@ -247,7 +247,7 @@
  int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  {
  	struct mt7915_dev *dev = phy->dev;
-@@ -3688,6 +3730,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+@@ -3686,6 +3728,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  
  	debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
  
@@ -257,5 +257,5 @@
  }
  #endif
 -- 
-2.39.2
+2.18.0
 
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 d7f07bf..013b88f 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 7f2833b672a467aa6684b100b00bfbd6d0c4d07f Mon Sep 17 00:00:00 2001
+From ffa6ac27f043615593e71b38734e47521cb066c0 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/1034] wifi: mt76: mt7915: Add mu dump support
+Subject: [PATCH 1020/1040] 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 afba18e4..0c0b47e7 100644
+index afba18e..0c0b47e 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -37,6 +37,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -59,7 +59,7 @@
  		.maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX,
  	},
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 0c96377f..d8e23d34 100644
+index 0c96377..d8e23d3 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -72,6 +72,7 @@ enum mtk_vendor_attr_mu_ctrl {
@@ -71,5 +71,5 @@
  	/* keep last */
  	NUM_MTK_VENDOR_ATTRS_MU_CTRL,
 -- 
-2.39.2
+2.18.0
 
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 7abb63f..7f0aff5 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,7 +1,7 @@
-From 07c6e8cd0e8ad51a294d4d2d3747f62dd22124ab Mon Sep 17 00:00:00 2001
+From fc0376cf18d75e6691d1c1dee207a0a7536a8d4f 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/1034] wifi: mt76: mt7915: add vendor subcmd three wire
+Subject: [PATCH 1021/1040] wifi: mt76: mt7915: add vendor subcmd three wire
  (PTA) ctrl
 
 Change-Id: Ic1044698f294455594a0c6254f55326fdab90580
@@ -16,10 +16,10 @@
  6 files changed, 111 insertions(+), 29 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index da2f5dd0..daeec01f 100644
+index 4905411..3b5c58b 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1204,7 +1204,7 @@ enum {
+@@ -1215,7 +1215,7 @@ enum {
  	/* for vendor csi and air monitor */
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
@@ -29,10 +29,10 @@
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 96c47273..4aee1268 100644
+index 83ceb2e..7e33386 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4517,37 +4517,33 @@ void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable)
+@@ -4526,37 +4526,33 @@ void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable)
  			&req, sizeof(req), false);
  }
  
@@ -94,7 +94,7 @@
  
  void mt7915_mcu_set_bypass_smthint(struct mt7915_phy *phy, u8 val)
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index d271e2be..5fc4e2ef 100644
+index d271e2b..5fc4e2e 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -904,6 +904,35 @@ struct mt7915_mcu_rdd_ipi_scan {
@@ -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 6c4f407b..b5f76a32 100644
+index b6a564e..febe070 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -704,6 +704,7 @@ void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
+@@ -707,6 +707,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 0c0b47e7..b651cea2 100644
+index 0c0b47e..b651cea 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -40,6 +40,11 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
@@ -229,7 +229,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index d8e23d34..de3cbe2c 100644
+index d8e23d3..de3cbe2 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -12,6 +12,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -268,5 +268,5 @@
  	CAPI_RFEATURE_CHANGED		= BIT(16),
  	CAPI_WIRELESS_CHANGED		= BIT(17),
 -- 
-2.39.2
+2.18.0
 
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 bece1c8..479b39f 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 68d1ed6b4959520cab2864c81f9322e983d1adee Mon Sep 17 00:00:00 2001
+From a16d1b2e363994a284d5542c4f980a693fdbe326 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/1034] wifi: mt76: mt7915: add ibf control vendor cmd
+Subject: [PATCH 1022/1040] 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 b651cea2..b661ea4e 100644
+index b651cea..b661ea4 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -86,6 +86,11 @@ edcca_dump_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP] = {
@@ -100,7 +100,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index de3cbe2c..a6309a32 100644
+index de3cbe2..a6309a3 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -12,7 +12,8 @@ enum mtk_nl80211_vendor_subcmds {
@@ -141,5 +141,5 @@
 +
  #endif
 -- 
-2.39.2
+2.18.0
 
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
index 60261c6..408e5b6 100644
--- 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
@@ -1,7 +1,7 @@
-From a3c96bd2d17ffd8777dd7c3afe429daa3aada222 Mon Sep 17 00:00:00 2001
+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/1034] wifi: mt76: mt7915: add E3 re-bonding for low yield
+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>
@@ -11,7 +11,7 @@
  2 files changed, 29 insertions(+)
 
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index fd08d42a..3b44a9d7 100644
+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,
@@ -57,10 +57,10 @@
  	if (ret)
  		return ret;
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index b5f76a32..851caa99 100644
+index febe070..a3d7b4b 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -503,6 +503,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+@@ -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);
@@ -69,5 +69,5 @@
  void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
  				struct mt7915_phy *phy);
 -- 
-2.39.2
+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 f42e269..0ac0f94 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 ea7179a6774f9ca965731738b4e171f26767ae4e Mon Sep 17 00:00:00 2001
+From bf55d4819b6c12dd7c6e13a51f8ee28636265345 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/1034] wifi: mt76: mt7915: support on off SW ACI through
+Subject: [PATCH 1024/1040] 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 daeec01f..8228bbb1 100644
+index 3b5c58b..4925890 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1206,6 +1206,7 @@ enum {
+@@ -1217,6 +1217,7 @@ enum {
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_SET_CFG = 0xb7,
  	MCU_EXT_CMD_EDCCA = 0xba,
@@ -24,10 +24,10 @@
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
  };
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index bc683db8..48e2edcf 100644
+index b949ad7..ef5d581 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
-@@ -3644,6 +3644,25 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
+@@ -3642,6 +3642,25 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
  	return 0;
  }
  
@@ -53,7 +53,7 @@
  int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  {
  	struct mt7915_dev *dev = phy->dev;
-@@ -3732,6 +3751,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+@@ -3730,6 +3749,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  
  	debugfs_create_devm_seqfile(dev->mt76.dev, "eeprom_mode", dir,
  				    mt7915_show_eeprom_mode);
@@ -63,5 +63,5 @@
  }
  #endif
 -- 
-2.39.2
+2.18.0
 
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 38f5d75..17d289a 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,7 +1,7 @@
-From de4b50e7a8564367603e5de2e967315fd13ffb82 Mon Sep 17 00:00:00 2001
+From f793f54b26302abc942574b2e6f19f609b3a1c0e 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/1034] wifi: mt76: mt7915: add bf backoff limit table
+Subject: [PATCH 1025/1040] wifi: mt76: mt7915: add bf backoff limit table
  support
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
@@ -16,7 +16,7 @@
  7 files changed, 220 insertions(+), 39 deletions(-)
 
 diff --git a/debugfs.c b/debugfs.c
-index 4a8e1864..4bb46799 100644
+index 1c8328d..19a835c 100644
 --- a/debugfs.c
 +++ b/debugfs.c
 @@ -95,7 +95,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
@@ -29,7 +29,7 @@
  		seq_printf(file, " %2d", val[i]);
  	seq_puts(file, "\n");
 diff --git a/eeprom.c b/eeprom.c
-index eb532c77..41895252 100644
+index eb532c7..4189525 100644
 --- a/eeprom.c
 +++ b/eeprom.c
 @@ -367,12 +367,16 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
@@ -86,13 +86,13 @@
  EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
  
 diff --git a/mt76.h b/mt76.h
-index b4e34296..2f801de4 100644
+index 13796ad..05c1874 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -1030,6 +1030,14 @@ struct mt76_power_limits {
- 	s8 ofdm[8];
+@@ -1047,6 +1047,14 @@ struct mt76_power_limits {
  	s8 mcs[4][10];
  	s8 ru[7][12];
+ 	s8 eht[16][16];
 +
 +	struct {
 +		s8 cck[4];
@@ -105,7 +105,7 @@
  
  struct mt76_ethtool_worker_info {
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index f1813776..19a37b53 100644
+index f181377..19a37b5 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -1019,7 +1019,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
@@ -217,10 +217,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 4aee1268..10fade27 100644
+index 7e33386..f65f0ec 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3302,7 +3302,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3311,7 +3311,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  	int ret;
  	s8 txpower_sku[MT7915_SKU_RATE_NUM];
  
@@ -230,7 +230,7 @@
  	if (ret)
  		return ret;
  
-@@ -3344,51 +3345,106 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3353,51 +3354,106 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  
  int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy)
  {
@@ -362,7 +362,7 @@
  	struct mt7915_dev *dev = phy->dev;
  	struct {
  		u8 format_id;
-@@ -3397,10 +3453,9 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
+@@ -3406,10 +3462,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,
@@ -374,7 +374,7 @@
  	struct sk_buff *skb;
  	int ret, i;
  
-@@ -3410,9 +3465,15 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
+@@ -3419,9 +3474,15 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
  	if (ret)
  		return ret;
  
@@ -393,7 +393,7 @@
  
  	dev_kfree_skb(skb);
  
-@@ -3454,9 +3515,18 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
+@@ -3463,9 +3524,18 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
  		.band_idx = phy->mt76->band_idx,
  		.sku_enable = enable,
  	};
@@ -413,7 +413,7 @@
  				 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
  				 sizeof(req), true);
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 5fc4e2ef..142bfc1f 100644
+index 5fc4e2e..142bfc1 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -502,12 +502,18 @@ enum {
@@ -436,7 +436,7 @@
  	SPR_ENABLE = 0x1,
  	SPR_ENABLE_SD = 0x3,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 851caa99..04cf2dc3 100644
+index a3d7b4b..4dc3825 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -72,6 +72,7 @@
@@ -447,7 +447,7 @@
  
  #define MT7915_MAX_TWT_AGRT		16
  #define MT7915_MAX_STA_TWT_AGRT		8
-@@ -569,7 +570,8 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
+@@ -572,7 +573,8 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
  int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
  int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
  int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
@@ -458,5 +458,5 @@
  int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  				 struct ieee80211_vif *vif,
 -- 
-2.39.2
+2.18.0
 
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 06e99af..4dd0383 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 061bb8523b47ea25999e64469237fea3091097b8 Mon Sep 17 00:00:00 2001
+From ff2283c46ffd78340efabfe1e614dfd69405bd6d 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/1034] wifi: mt76: mt7915: amsdu set and get control
+Subject: [PATCH 1026/1040] wifi: mt76: mt7915: amsdu set and get control
 
 ---
  mt7915/mac.c    |  7 +++++++
@@ -11,7 +11,7 @@
  4 files changed, 50 insertions(+)
 
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 1e0bee7b..fe2e2d65 100644
+index 4244177..51073ab 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -2032,6 +2032,13 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
@@ -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 04cf2dc3..b4727082 100644
+index 4dc3825..75967f9 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -695,6 +695,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -698,6 +698,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 b661ea4e..0105d2f0 100644
+index b661ea4..0105d2f 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -30,10 +30,16 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -105,7 +105,7 @@
  		.maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX,
  	},
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index a6309a32..33c75dc9 100644
+index a6309a3..33c75dc 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -74,6 +74,7 @@ enum mtk_vendor_attr_wireless_ctrl {
@@ -135,5 +135,5 @@
  	MTK_VENDOR_ATTR_MU_CTRL_UNSPEC,
  
 -- 
-2.39.2
+2.18.0
 
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 9077694..cf5d9b7 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,7 +1,7 @@
-From b3ecd93f877b8ec4577996607a5d884979062b48 Mon Sep 17 00:00:00 2001
+From 7bf557aff6961e6d224f599b1be6068393c68bfc 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/1034] wifi: mt76: mt7915: Add vendor command attribute
+Subject: [PATCH 1027/1040] 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 10fade27..15915c97 100644
+index f65f0ec..12ee063 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4603,6 +4603,12 @@ int mt7915_mcu_set_cfg(struct mt7915_phy *phy, u8 cfg_info, u8 type)
+@@ -4612,6 +4612,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;
@@ -30,7 +30,7 @@
  		tlv_len = sizeof(struct three_wire_cfg);
  		req.three_wire.tag = cpu_to_le16(cfg_info);
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 142bfc1f..286f7a59 100644
+index 142bfc1..286f7a5 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -924,6 +924,13 @@ struct three_wire_cfg {
@@ -62,7 +62,7 @@
  };
  
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 0105d2f0..fb2fe829 100644
+index 0105d2f..fb2fe82 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -33,6 +33,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -84,7 +84,7 @@
  
  	return 0;
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 33c75dc9..6001ce4a 100644
+index 33c75dc..6001ce4 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -76,6 +76,7 @@ enum mtk_vendor_attr_wireless_ctrl {
@@ -96,5 +96,5 @@
  	MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA, /* reserve */
  	/* keep last */
 -- 
-2.39.2
+2.18.0
 
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 96e5f45..2dd5226 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 60bfaa45b94737dd895da224677411beceef97bc Mon Sep 17 00:00:00 2001
+From cbfad5aeabda8196ffa1e21f23ebdeb3864b9860 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/1034] wifi: mt76: mt7915: add vendor cmd to get available
+Subject: [PATCH 1028/1040] 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 fb2fe829..94c4aad5 100644
+index fb2fe82..94c4aad 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -98,6 +98,11 @@ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
@@ -76,7 +76,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 6001ce4a..358a16f2 100644
+index 6001ce4..358a16f 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -14,6 +14,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -103,5 +103,5 @@
 +};
  #endif
 -- 
-2.39.2
+2.18.0
 
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 1829e95..1e0c6d6 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 99a9068d0e73d70b9587febcb6763882eecc0fba Mon Sep 17 00:00:00 2001
+From 9720802e9abc886c7676d3994e3735aa440ed78e 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/1034] wifi: mt76: mt7915: disable SW-ACI by default
+Subject: [PATCH 1029/1040] 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 85524e91..9011d69b 100644
+index 287ca99..5b4581c 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 15915c97..a542031b 100644
+index 12ee063..fe00519 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4963,3 +4963,18 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value)
+@@ -4972,3 +4972,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 b4727082..38486776 100644
+index 75967f9..722f3bc 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -719,6 +719,7 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
+@@ -722,6 +722,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,10 +74,10 @@
  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 48e2edcf..55c54436 100644
+index ef5d581..80b7bc1 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
-@@ -3647,16 +3647,12 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
+@@ -3645,16 +3645,12 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
  static int
  mt7915_sw_aci_set(void *data, u64 val)
  {
@@ -100,5 +100,5 @@
  
  
 -- 
-2.39.2
+2.18.0
 
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 2bab8a5..3503c08 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,7 +1,7 @@
-From 6c3d6f5f7af8213f2262c19b18de9973f157f99a Mon Sep 17 00:00:00 2001
+From babeb3948faef2769f838dd35050eb71c7194175 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/1034] wifi: mt76: mt7915: add muru user number debug
+Subject: [PATCH 1030/1040] wifi: mt76: mt7915: add muru user number debug
  command
 
 ---
@@ -11,10 +11,10 @@
  3 files changed, 17 insertions(+), 1 deletion(-)
 
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 38486776..4c0e1ac1 100644
+index 722f3bc..9f62e5e 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -583,6 +583,7 @@ int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev,
+@@ -586,6 +586,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 +23,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 94c4aad5..b4508088 100644
+index 94c4aad..b450808 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -45,6 +45,8 @@ static const struct nla_policy
@@ -65,7 +65,7 @@
  
  	return 0;
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index 358a16f2..20526eae 100644
+index 358a16f..20526ea 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -102,6 +102,8 @@ enum mtk_vendor_attr_mu_ctrl {
@@ -78,5 +78,5 @@
  	/* keep last */
  	NUM_MTK_VENDOR_ATTRS_MU_CTRL,
 -- 
-2.39.2
+2.18.0
 
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 d3f44b3..a194c24 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 5d876ac0a3bcd35368d35122d63d7d35b62822fe Mon Sep 17 00:00:00 2001
+From 0b6b1f1ab13a801b23459161251b54ee94e41562 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/1034] wifi: mt76: mt7915: add debugfs for fw coredump.
+Subject: [PATCH 1031/1040] wifi: mt76: mt7915: add debugfs for fw coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  4 files changed, 58 insertions(+), 9 deletions(-)
 
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index 19a37b53..ae291a3f 100644
+index 19a37b5..ae291a3 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -82,8 +82,10 @@ mt7915_sys_recovery_set(struct file *file, const char __user *user_buf,
@@ -67,7 +67,7 @@
  	/* SER statistics */
  	desc += scnprintf(buff + desc, bufsz - desc,
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index fe2e2d65..21e8383a 100644
+index 51073ab..e4f46e0 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -1725,10 +1725,34 @@ void mt7915_mac_dump_work(struct work_struct *work)
@@ -117,7 +117,7 @@
  	}
  
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 286f7a59..583caca7 100644
+index 286f7a5..583caca 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -745,8 +745,12 @@ enum {
@@ -135,7 +135,7 @@
  	SER_ENABLE = 2,
  	SER_RECOVER
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 4c0e1ac1..d8a321b6 100644
+index 9f62e5e..16f2661 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -91,6 +91,13 @@ struct mt7915_sta;
@@ -160,7 +160,7 @@
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
  		struct mt7915_crash_data *crash_data[__MT76_RAM_TYPE_MAX];
-@@ -521,6 +529,7 @@ int mt7915_txbf_init(struct mt7915_dev *dev);
+@@ -524,6 +532,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);
@@ -169,5 +169,5 @@
  int mt7915_mcu_init(struct mt7915_dev *dev);
  int mt7915_mcu_init_firmware(struct mt7915_dev *dev);
 -- 
-2.39.2
+2.18.0
 
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 9e96c1e..cad5964 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 c89f91b82e1b1516ee6c6bd150c6c0dda29de573 Mon Sep 17 00:00:00 2001
+From 45e1cac480f32d75ec7f13389594768eb471ca66 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/1034] wifi: mt76: mt7915: remove BW160 support
+Subject: [PATCH 1032/1040] 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 6d1c0f71..ac61febb 100644
+index d908a58..a942bc2 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -434,11 +434,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+@@ -431,11 +431,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;
-@@ -896,13 +891,9 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,
+@@ -891,13 +886,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)
-@@ -982,15 +973,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
+@@ -977,15 +968,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;
@@ -61,5 +61,5 @@
  
  	for (i = 0; i < 8; i++) {
 -- 
-2.39.2
+2.18.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 f59ad29..78dba54 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 f2174e027d82494ec89c81d896f9b13284f1add8 Mon Sep 17 00:00:00 2001
+From a8a300579541b1e29f498d887e4711c481af1809 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/1034] wifi: mt76: mt7915: add txpower info dump support
+Subject: [PATCH 1033/1040] wifi: mt76: mt7915: add txpower info dump support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -11,7 +11,7 @@
  3 files changed, 91 insertions(+), 1 deletion(-)
 
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index ae291a3f..2bf907c0 100644
+index ae291a3..2bf907c 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -1258,6 +1258,91 @@ mt7915_txpower_path_show(struct seq_file *file, void *data)
@@ -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 a542031b..d2e3e82b 100644
+index fe00519..344ba85 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3473,6 +3473,8 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
+@@ -3482,6 +3482,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);
@@ -129,7 +129,7 @@
  
  	dev_kfree_skb(skb);
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 583caca7..6e6f320b 100644
+index 583caca..6e6f320 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -510,7 +510,8 @@ enum {
@@ -143,5 +143,5 @@
  };
  
 -- 
-2.39.2
+2.18.0
 
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 197a473..d987346 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,7 +1,7 @@
-From a6806476cc67d25ab77a3b0aef4fbc4870f12cbe Mon Sep 17 00:00:00 2001
+From 1118417f6ad1e37fe5031701522f1287dfd38491 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/1034] wifi: mt76: mt7915: report tx and rx byte to
+Subject: [PATCH 1034/1040] 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 ee5177fd..ff3cefad 100644
+index e26fcf8..c2f31bf 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -608,9 +608,15 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
+@@ -596,9 +596,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);
-@@ -651,10 +657,6 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
+@@ -639,10 +645,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 25c3fe2b..57dfda3a 100644
+index 6dd6eca..b47bfff 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -666,6 +666,7 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
+@@ -704,6 +704,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);
  
-@@ -676,6 +677,10 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
+@@ -714,6 +715,10 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
  
  	wcid = rcu_dereference(dev->mt76.wcid[idx]);
  	if (wcid) {
@@ -65,5 +65,5 @@
  		wcid->stats.rx_packets += le32_to_cpu(stats->rx_pkt_cnt);
  		wcid->stats.rx_errors += le32_to_cpu(stats->rx_err_cnt);
 -- 
-2.39.2
+2.18.0
 
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 a6eb593..8de22b4 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 faa6a52a5f0429d401b7615cc34734c6f5b8fe01 Mon Sep 17 00:00:00 2001
+From 170d9117dbf1f31f9a5ccc1f5824c547b6209533 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] wifi: mt76: mt7915: Establish BA in VO queue
+Subject: [PATCH 1035/1040] 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 ff3cefa..b87b733 100644
+index c2f31bf..02d5232 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -1126,8 +1126,6 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+@@ -1114,8 +1114,6 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
  		return;
  
  	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
@@ -21,5 +21,5 @@
  	val = le32_to_cpu(txwi[2]);
  	fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
 -- 
-2.39.0
+2.18.0
 
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 2ce9ef0..47b364d 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,15 +1,16 @@
-From 4cb59dc3fc13de7cfb32800927cb586036f9ec7b Mon Sep 17 00:00:00 2001
+From c499d09d496d723dab109aee2e3af8a28278a54c 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 1035/1035] wifi: mt76: mt7915: Disable RegDB when enable
+Subject: [PATCH 1036/1040] wifi: mt76: mt7915: Disable RegDB when enable
  single sku
 
 ---
  eeprom.c         |  3 ++-
  mt76.h           |  3 +++
- mt7915/debugfs.c | 43 +++++++++++++++++++++++++++++++++++++++++--
+ mt7915/debugfs.c | 49 +++++++++++++++++++++++++++++++++++++++++++-----
  mt7915/init.c    |  9 ++++++++-
- 4 files changed, 54 insertions(+), 4 deletions(-)
+ mt7915/regs.h    |  8 ++++----
+ 5 files changed, 61 insertions(+), 11 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
 index 4189525..38b0a58 100644
@@ -33,10 +34,10 @@
  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 2f801de..aece4ec 100644
+index 05c1874..91da8c5 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -1655,6 +1655,9 @@ mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd,
+@@ -1673,6 +1673,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);
  
@@ -47,7 +48,7 @@
  			      struct ieee80211_channel *chan,
  			      struct mt76_power_limits *dest,
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index 2bf907c..bb312ee 100644
+index 2bf907c..6dcee10 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -1019,10 +1019,16 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
@@ -68,14 +69,20 @@
  	ssize_t ret;
  	char *buf;
  	u32 reg;
-@@ -1084,9 +1090,36 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
- 	reg = is_mt7915(&dev->mt76) ? MT_WF_PHY_TPC_CTRL_STAT(band) :
- 	      MT_WF_PHY_TPC_CTRL_STAT_MT7916(band);
+@@ -1081,11 +1087,38 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
+ 	len += scnprintf(buf + len, sz - len, "BW160/");
+ 	mt7915_txpower_puts(HE_RU2x996, 17);
+ 
+-	reg = is_mt7915(&dev->mt76) ? MT_WF_PHY_TPC_CTRL_STAT(band) :
+-	      MT_WF_PHY_TPC_CTRL_STAT_MT7916(band);
++	reg = is_mt7915(&dev->mt76) ? MT_WF_IRPI_TPC_CTRL_STAT(band) :
++	      MT_WF_IRPI_TPC_CTRL_STAT_MT7916(band);
  
 -	len += scnprintf(buf + len, sz - len, "\nTx power (bbp)  : %6ld\n",
+-			 mt76_get_field(dev, reg, MT_WF_PHY_TPC_POWER));
 +	len += scnprintf(buf + len, sz - len, "\nTx power (bbp)  : %6ld [0.5 dBm]\n",
- 			 mt76_get_field(dev, reg, MT_WF_PHY_TPC_POWER));
- 
++			 mt76_get_field(dev, reg, MT_WF_IRPI_TPC_POWER));
++
 +	len += scnprintf(buf + len, sz - len, "RegDB maximum power:\t%d [dBm]\n",
 +			 chan->max_reg_power);
 +
@@ -102,10 +109,9 @@
 +
 +	len += scnprintf(buf + len, sz - len, "nss_delta:\t%d [0.5 dBm]\n",
 +			 nss_delta);
-+
+ 
  	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
  
- out:
 @@ -1262,6 +1295,8 @@ static int
  mt7915_txpower_info_show(struct seq_file *file, void *data)
  {
@@ -134,10 +140,10 @@
  	return ret;
  }
 diff --git a/mt7915/init.c b/mt7915/init.c
-index f8ecaf3..623b070 100644
+index a942bc2..82fe443 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -286,7 +286,9 @@ void __mt7915_init_txpower(struct mt7915_phy *phy,
+@@ -283,7 +283,9 @@ 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;
@@ -147,7 +153,7 @@
  	for (i = 0; i < sband->n_channels; i++) {
  		struct ieee80211_channel *chan = &sband->channels[i];
  		u32 target_power = 0;
-@@ -305,8 +307,13 @@ void __mt7915_init_txpower(struct mt7915_phy *phy,
+@@ -302,8 +304,13 @@ void __mt7915_init_txpower(struct mt7915_phy *phy,
  							  target_power);
  		target_power += nss_delta;
  		target_power = DIV_ROUND_UP(target_power, 2);
@@ -162,6 +168,32 @@
  		chan->orig_mpwr = target_power;
  	}
  }
+diff --git a/mt7915/regs.h b/mt7915/regs.h
+index 1f1f8b9..3c2fd2d 100644
+--- a/mt7915/regs.h
++++ b/mt7915/regs.h
+@@ -1213,6 +1213,10 @@ enum offs_rev {
+ #define MT_WF_IRPI_NSS(phy, nss)	MT_WF_IRPI(0x6000 + ((phy) << 20) + ((nss) << 16))
+ #define MT_WF_IRPI_NSS_MT7916(phy, nss)	MT_WF_IRPI(0x1000 + ((phy) << 20) + ((nss) << 16))
+ 
++#define MT_WF_IRPI_TPC_CTRL_STAT(_phy)		MT_WF_IRPI(0xc794 + ((_phy) << 16))
++#define MT_WF_IRPI_TPC_CTRL_STAT_MT7916(_phy)	MT_WF_IRPI(0xc794 + ((_phy) << 20))
++#define MT_WF_IRPI_TPC_POWER			GENMASK(31, 24)
++
+ #define MT_WF_IPI_RESET			0x831a3008
+ 
+ /* PHY */
+@@ -1229,10 +1233,6 @@ enum offs_rev {
+ #define MT_WF_PHY_RXTD12_IRPI_SW_CLR_ONLY	BIT(18)
+ #define MT_WF_PHY_RXTD12_IRPI_SW_CLR		BIT(29)
+ 
+-#define MT_WF_PHY_TPC_CTRL_STAT(_phy)		MT_WF_PHY(0xe7a0 + ((_phy) << 16))
+-#define MT_WF_PHY_TPC_CTRL_STAT_MT7916(_phy)	MT_WF_PHY(0xe7a0 + ((_phy) << 20))
+-#define MT_WF_PHY_TPC_POWER			GENMASK(15, 8)
+-
+ #define MT_MCU_WM_CIRQ_BASE			0x89010000
+ #define MT_MCU_WM_CIRQ(ofs)			(MT_MCU_WM_CIRQ_BASE + (ofs))
+ #define MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR	MT_MCU_WM_CIRQ(0x80)
 -- 
 2.18.0
 
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 776c24d..0258ff1 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 dda8d4eb5890b402eec2ace7b4e05f4f45fa416c Mon Sep 17 00:00:00 2001
+From d7300215f0c2ca425ee97339618051a5e810608d 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 01/11] wifi: mt76: mt7915: enable the mac80211 hw bmc ps
+Subject: [PATCH 1037/1040] 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 623b070..be6eb54 100644
+index 82fe443..36621ad 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -408,6 +408,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+@@ -405,6 +405,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 e05e710..ebaf572 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,7 +1,8 @@
-From 47058b5552a9597c2dad3e45b3d0396a5b69dfd7 Mon Sep 17 00:00:00 2001
+From e4019ba63d7bb60ac0b56618e3fd9421c97ce474 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] wifi: mt76: update debugfs knob to dump token pending time
+Subject: [PATCH 1038/1040] wifi: mt76: update debugfs knob to dump token
+ pending time
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
 ---
@@ -11,10 +12,10 @@
  3 files changed, 10 insertions(+), 4 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index aece4eca..9237b22e 100644
+index 91da8c5..ad1402a 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -365,6 +365,8 @@ struct mt76_txwi_cache {
+@@ -368,6 +368,8 @@ struct mt76_txwi_cache {
  	struct list_head list;
  	dma_addr_t dma_addr;
  
@@ -24,7 +25,7 @@
  		struct sk_buff *skb;
  		void *ptr;
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 21e8383a..67b42006 100644
+index e4f46e0..817763a 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,
@@ -55,7 +56,7 @@
  	}
  
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 80b7bc1a..46f1b0b6 100644
+index 80b7bc1..46f1b0b 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 646fb60..5b0a6bc 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,8 +1,8 @@
-From f8b4b17a84bf10198c67434b246de4a05e3e54dd Mon Sep 17 00:00:00 2001
+From ac7a0356360173149824d63e9f5803adb7c94ae4 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] wifi: mt76: mt7915: support enable/disable spatial reuse
- through debugfs
+Subject: [PATCH 1039/1040] 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 f6ba2d5..e8e563e 100644
+index 344ba85..cd4f472 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3607,8 +3607,7 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
+@@ -3609,8 +3609,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 1c2f113..12049d1 100644
+index 16f2661..72d6cc0 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -733,6 +733,7 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value);
+@@ -735,6 +735,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);
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
new file mode 100644
index 0000000..378596d
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/1040-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch
@@ -0,0 +1,47 @@
+From b010edba440f66a02eb9b72fb55831befb60107f 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.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+---
+ mt7915/mac.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index 817763a..e51440d 100644
+--- a/mt7915/mac.c
++++ b/mt7915/mac.c
+@@ -1570,6 +1570,9 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 	if (!(READ_ONCE(dev->recovery.state) & MT_MCU_CMD_STOP_DMA))
+ 		return;
+ 
++	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)) {
+ 		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)
+ 		ieee80211_queue_delayed_work(ext_phy->hw,
+ 					     &phy2->mt76->mac_work,
+ 					     MT7915_WATCHDOG_TIME);
++
++	dev_info(dev->mt76.dev,"\n%s L1 SER recovery completed.",
++		 wiphy_name(dev->mt76.hw->wiphy));
+ }
+ 
+ /* firmware coredump */
+@@ -1763,6 +1769,9 @@ void mt7915_coredump(struct mt7915_dev *dev, u8 state)
+ 
+ void mt7915_reset(struct mt7915_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/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
new file mode 100644
index 0000000..705bd74
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/1041-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch
@@ -0,0 +1,27 @@
+From 134bea3d6ba955e2dcccad2b2af144e163d4b2c1 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
+ station dump
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7915/mac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index ec0de9b..b696f02 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,
+ 		if (v0 & MT_PRXV_HT_AD_CODE)
+ 			status->enc_flags |= RX_ENC_FLAG_LDPC;
+ 
+-		status->chains = mphy->antenna_mask;
++		status->chains = mphy->chainmask >> (status->phy_idx * dev->chainshift);
+ 		status->chain_signal[0] = to_rssi(MT_PRXV_RCPI0, v1);
+ 		status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, v1);
+ 		status->chain_signal[2] = to_rssi(MT_PRXV_RCPI2, v1);
+-- 
+2.18.0
+
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
new file mode 100644
index 0000000..42c1246
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/1042-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch
@@ -0,0 +1,54 @@
+From ddd20028e31060d5bbbc72bd6e465c45819adb56 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
+
+---
+ mt7915/mt7915.h      |  1 +
+ mt7915/mtk_debugfs.c | 11 +++++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index e8a6ee68..2a01bd62 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,
+ 		       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);
++int mt7915_mcu_set_mu_prot_frame_th(struct mt7915_phy *phy, u32 val);
+ void mt7915_mcu_set_ppdu_tx_type(struct mt7915_phy *phy, u8 ppdu_type);
+ 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
+--- 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)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_tx_amsdu, NULL,
+ 			 mt7915_sta_tx_amsdu_set, "%llx\n");
+ 
++static int mt7915_muru_set_prot_thr(void *data, u64 val)
++{
++	struct mt7915_phy *phy = data;
++
++	return mt7915_mcu_set_mu_prot_frame_th(phy, (u32)val);
++}
++
++DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_set_prot_thr, NULL,
++			 mt7915_muru_set_prot_thr, "%lld\n");
++
+ static int mt7915_red_enable_set(void *data, u64 en)
+ {
+ 	struct mt7915_dev *dev = data;
+@@ -3735,6 +3745,7 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+ 	debugfs_create_devm_seqfile(dev->mt76.dev, "fw_wm_info", dir,
+ 				    mt7915_fw_wm_info_read);
+ 
++	debugfs_create_file("prot_thr", 0200, dir, phy, &fops_muru_set_prot_thr);
+ 	debugfs_create_file("red_en", 0600, dir, dev,
+ 			    &fops_red_en);
+ 	debugfs_create_file("red_show_sta", 0600, dir, dev,
+-- 
+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 fa412b8..4a0e51b 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,7 +1,7 @@
-From 5874aad8bb03d3e8d568dca2f0df74b2591eaf55 Mon Sep 17 00:00:00 2001
+From 9ea9f8159f6d14dd41c65bf437cde772efcbb8ea 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] wifi: mt76: mt7915: wed: add wed tx support
+Subject: [PATCH 2000/2011] wifi: mt76: mt7915: wed: add wed tx support
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
@@ -13,7 +13,7 @@
  5 files changed, 14 insertions(+), 8 deletions(-)
 
 diff --git a/mt76_connac.h b/mt76_connac.h
-index 4560ab79..431e4d79 100644
+index 6f5cf18..76f9555 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
 @@ -130,6 +130,7 @@ struct mt76_connac_sta_key_conf {
@@ -25,7 +25,7 @@
  struct mt76_connac_fw_txp {
  	__le16 flags;
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 67b42006..94cfab61 100644
+index e51440d..3c6b308 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)
@@ -68,10 +68,10 @@
  
  static void
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 6b3b9e06..0032f463 100644
+index 5b4581c..7274b5d 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1673,14 +1673,14 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1685,14 +1685,14 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
  	if (!mtk_wed_device_active(wed))
  		return -ENODEV;
  
@@ -89,7 +89,7 @@
  
  	ctx->dev = NULL;
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index b47bfffc..cae8b810 100644
+index b47bfff..cae8b81 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -13,7 +13,7 @@
@@ -119,7 +119,7 @@
  	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
  	if (ret)
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 1c2f1132..dded050a 100644
+index 72d6cc0..af9e3ae 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 a288041..da1686e 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,7 +1,7 @@
-From b02c433e89bae9520bf37eae1f40dda3f5fe3944 Mon Sep 17 00:00:00 2001
+From 3256ae03ed8d4b0c9aca091c7c183b91ca595db7 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/2010] wifi: mt76: mt7915: wed: add wds support when wed
+Subject: [PATCH 2001/2011] wifi: mt76: mt7915: wed: add wds support when wed
  is enabled
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
@@ -15,7 +15,7 @@
  6 files changed, 82 insertions(+), 10 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 2f801de4..e315fc1e 100644
+index ad1402a..d00ef21 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -68,6 +68,12 @@ enum mt76_wed_type {
@@ -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 89e994f9..2f4677ec 100644
+index 7274b5d..e274f02 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -761,8 +761,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -773,8 +773,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;
  
-@@ -1241,6 +1248,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
+@@ -1253,6 +1260,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);
  }
  
-@@ -1679,8 +1693,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1692,8 +1706,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,10 +81,10 @@
  	ctx->dev = NULL;
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index d2e3e82b..4eaeed68 100644
+index cd4f472..d8b9318 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -2388,10 +2388,18 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev)
+@@ -2397,10 +2397,18 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev)
  	if (ret)
  		return ret;
  
@@ -108,7 +108,7 @@
  	ret = mt7915_mcu_set_mwds(dev, 1);
  	if (ret)
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 6e6f320b..825bb7df 100644
+index 6e6f320..825bb7d 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -339,6 +339,7 @@ enum {
@@ -120,7 +120,7 @@
  	MCU_WA_PARAM_RED_SHOW_STA = 0xf,
  	MCU_WA_PARAM_RED_TARGET_DELAY = 0x10,
 diff --git a/util.c b/util.c
-index fc76c66f..61b2d30a 100644
+index fc76c66..61b2d30 100644
 --- a/util.c
 +++ b/util.c
 @@ -42,9 +42,14 @@ bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
@@ -188,7 +188,7 @@
  int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy)
  {
 diff --git a/util.h b/util.h
-index 260965dd..99b7263c 100644
+index 260965d..99b7263 100644
 --- a/util.h
 +++ b/util.h
 @@ -27,7 +27,12 @@ enum {
@@ -206,5 +206,5 @@
  static inline void
  mt76_wcid_mask_set(u32 *mask, int idx)
 -- 
-2.39.2
+2.18.0
 
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 a41a99f..a3eadce 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 dd879c2a2e307c09f356fbf47cd4ae7451fb3bf4 Mon Sep 17 00:00:00 2001
+From db9a693311a05bb9df09d59b940b0006953ea93f 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/2010] wifi: mt76: mt7915: wed: add fill receive path to
+Subject: [PATCH 2002/2011] wifi: mt76: mt7915: wed: add fill receive path to
  report wed idx
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 18 insertions(+)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 2f4677ec..00c66000 100644
+index e274f02..f08fb2d 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1705,6 +1705,23 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1718,6 +1718,23 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
  	return 0;
  }
  
@@ -37,7 +37,7 @@
  static int
  mt7915_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		    struct net_device *netdev, enum tc_setup_type type,
-@@ -1772,6 +1789,7 @@ const struct ieee80211_ops mt7915_ops = {
+@@ -1785,6 +1802,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,
@@ -46,5 +46,5 @@
  #endif
  };
 -- 
-2.39.2
+2.18.0
 
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 70230bc..16b9a1a 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 2423861357760af2716618d87d65a8d1dff7319c Mon Sep 17 00:00:00 2001
+From 51125c922550f392c705ef3aa1151eb92105e88a 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/2010] wifi: mt76: mt7915: wed: find rx token by physical
+Subject: [PATCH 2003/2011] 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,10 +13,10 @@
  1 file changed, 24 insertions(+), 1 deletion(-)
 
 diff --git a/dma.c b/dma.c
-index fc92e391..3047f8ba 100644
+index 8049830..e877d26 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -403,9 +403,32 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -405,9 +405,32 @@ 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);
@@ -51,5 +51,5 @@
  			return NULL;
  
 -- 
-2.39.2
+2.18.0
 
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 0df2d7b..a083852 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,24 +1,25 @@
-From e2b7b9b7d48b69eed36443ce889efba749da9347 Mon Sep 17 00:00:00 2001
+From 9c5767343f681ede3166f07b3051ab69cf75305a 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] 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>
 ---
  mt76_connac_mcu.h    |   2 +
  mt7915/debugfs.c     | 405 +++++++++++++++++++++++++++++++++++++++++++
- mt7915/init.c        |  39 +++++
- mt7915/main.c        |  15 ++
- mt7915/mcu.c         | 165 ++++++++++++++++++
- mt7915/mt7915.h      |  68 ++++++++
+ mt7915/init.c        |  58 +++++++
+ mt7915/main.c        |  14 ++
+ mt7915/mcu.c         | 169 +++++++++++++++++-
+ mt7915/mt7915.h      |  69 ++++++++
  mt7915/mtk_debugfs.c | 131 +++++++++++++-
- 7 files changed, 824 insertions(+), 1 deletion(-)
+ 7 files changed, 844 insertions(+), 4 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 8228bbb1..1257dfa1 100644
+index 49258905..9ad18833 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1164,6 +1164,7 @@ enum {
+@@ -1175,6 +1175,7 @@ enum {
  	MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
  	MCU_EXT_CMD_WTBL_UPDATE = 0x32,
  	MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
@@ -26,7 +27,7 @@
  	MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
  	MCU_EXT_CMD_ATE_CTRL = 0x3d,
  	MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
-@@ -1173,6 +1174,7 @@ enum {
+@@ -1184,6 +1185,7 @@ enum {
  	MCU_EXT_CMD_MUAR_UPDATE = 0x48,
  	MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
  	MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a,
@@ -35,7 +36,7 @@
  	MCU_EXT_CMD_EFUSE_FREE_BLOCK = 0x4f,
  	MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index bb312eeb..fefa4540 100644
+index 6dcee10c..ca42b698 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -12,6 +12,10 @@
@@ -465,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 623b0703..bfcdf3eb 100644
+index 36621ad3..db627500 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -602,10 +602,46 @@ mt7915_init_led_mux(struct mt7915_dev *dev)
+@@ -600,10 +600,65 @@ mt7915_init_led_mux(struct mt7915_dev *dev)
  	}
  }
  
@@ -507,6 +508,25 @@
 +	return;
 +}
 +
++/* Assignment of BSS group index aligns FW.
++ * 0: Band 0 - BSS 0
++ * 4: Band 1 - BSS 0
++ * 9..23: Band 0 - BSS 0x11..0x1f
++ * 25..39: Band 1 - BSS 0x11..0x1f
++ */
++void mt7915_vow_init_sta_bss_grp(struct mt7915_sta *sta)
++{
++	const u8 hw_bssid_num = HW_BSSID_MAX + 1;
++	struct mt76_vif *vif = &sta->vif->mt76;
++
++	if (vif->omac_idx < hw_bssid_num)
++		sta->vow_sta_cfg.bss_grp_idx = vif->band_idx * hw_bssid_num + vif->omac_idx;
++	else { /* Extended BSS */
++		u8 ext_bss_ofs = hw_bssid_num * 2 + (vif->band_idx == 0 ? 1 : 17);
++		sta->vow_sta_cfg.bss_grp_idx = ext_bss_ofs + vif->omac_idx - EXT_BSSID_1;
++	}
++}
++
  void mt7915_mac_init(struct mt7915_dev *dev)
  {
  	int i;
@@ -515,7 +535,7 @@
  
  	/* config pse qid6 wfdma port selection */
  	if (!is_mt7915(&dev->mt76) && dev->hif2)
-@@ -629,6 +665,9 @@ void mt7915_mac_init(struct mt7915_dev *dev)
+@@ -627,6 +682,9 @@ void mt7915_mac_init(struct mt7915_dev *dev)
  		mt7915_mac_init_band(dev, i);
  
  	mt7915_init_led_mux(dev);
@@ -526,7 +546,7 @@
  
  int mt7915_txbf_init(struct mt7915_dev *dev)
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 7a853825..deef1bb6 100644
+index 2dd4881f..8bcffd3f 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -217,6 +217,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
@@ -547,7 +567,7 @@
  	return ret;
  }
  
-@@ -757,6 +761,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -769,6 +773,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;
@@ -555,7 +575,7 @@
  #ifdef CONFIG_MTK_VENDOR
  	struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy;
  #endif
-@@ -807,6 +812,16 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -819,6 +824,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
@@ -564,7 +584,6 @@
 +		msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI] = 2;
 +		msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE] = 1;
 +		msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK] = 0;
-+		mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_BSS_GROUP);
 +		mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_PAUSE_SETTING);
 +		mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_ALL);
 +	}
@@ -573,10 +592,39 @@
  }
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 490058df..06b8acdf 100644
+index d8b93180..e5bfca3d 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3560,6 +3560,171 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
+@@ -1674,7 +1674,7 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ {
+ #define MT_STA_BSS_GROUP		1
+ 	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+-	struct mt7915_sta *msta;
++	struct mt7915_sta *msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
+ 	struct {
+ 		__le32 action;
+ 		u8 wlan_idx_lo;
+@@ -1685,10 +1685,9 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ 		u8 rsv1[8];
+ 	} __packed req = {
+ 		.action = cpu_to_le32(MT_STA_BSS_GROUP),
+-		.val = cpu_to_le32(mvif->mt76.idx % 16),
++		.val = cpu_to_le32(msta->vow_sta_cfg.bss_grp_idx)
+ 	};
+ 
+-	msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
+ 	req.wlan_idx_lo = to_wcid_lo(msta->wcid.idx);
+ 	req.wlan_idx_hi = to_wcid_hi(msta->wcid.idx);
+ 
+@@ -1746,6 +1745,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ 		mt7915_mcu_sta_bfee_tlv(dev, skb, vif, sta);
+ 	}
+ 
++	mt7915_vow_init_sta_bss_grp(msta);
+ 	ret = mt7915_mcu_add_group(dev, vif, sta);
+ 	if (ret) {
+ 		dev_kfree_skb(skb);
+@@ -3568,6 +3568,169 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
  				 &req, sizeof(req), false);
  }
  
@@ -607,9 +655,7 @@
 +
 +	switch (subcmd) {
 +		case VOW_DRR_STA_ALL:{
-+			setting |= 0x00;
-+			setting |= msta->vif->mt76.idx;
-+			setting |= msta->vow_sta_cfg.ac_change_rule << 4;
++			setting |= msta->vow_sta_cfg.bss_grp_idx;
 +			setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO] << 8);
 +			setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI] << 12);
 +			setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE] << 16);
@@ -621,7 +667,7 @@
 +		}
 +
 +		case VOW_DRR_STA_BSS_GROUP:
-+			req.air_time_ctrl.com_value = cpu_to_le32(0x0);
++			req.air_time_ctrl.com_value = cpu_to_le32(msta->vow_sta_cfg.bss_grp_idx);
 +			break;
 +
 +		case VOW_DRR_STA_PAUSE_SETTING:
@@ -737,7 +783,7 @@
 +	} __packed req = {
 +		.action = cpu_to_le16(0x1),
 +		.sub_action = cpu_to_le16(0x4),
-+		.group_idx = mvif->mt76.band_idx * 4 + mvif->mt76.omac_idx % 4,
++		.group_idx = mvif->sta.vow_sta_cfg.bss_grp_idx,
 +		.band_idx = mvif->mt76.band_idx,
 +	};
 +
@@ -749,7 +795,7 @@
  {
  #define MT_BF_PROCESSING	4
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index dded050a..c60521b1 100644
+index 1d89814e..2b4ed04c 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -141,6 +141,58 @@ struct mt7915_twt_flow {
@@ -788,8 +834,8 @@
 +};
 +
 +struct mt7915_vow_sta_cfg{
++	u8 bss_grp_idx;
 +	u8 dwrr_quantum[IEEE80211_NUM_ACS];
-+	u8 ac_change_rule;
 +	bool paused;
 +};
 +
@@ -819,7 +865,7 @@
  };
  
  struct mt7915_vif_cap {
-@@ -417,6 +470,8 @@ struct mt7915_dev {
+@@ -420,6 +473,8 @@ struct mt7915_dev {
  	} dbg;
  	const struct mt7915_dbg_reg_desc *dbg_reg;
  #endif
@@ -828,7 +874,7 @@
  };
  
  enum {
-@@ -449,6 +504,15 @@ enum mt7915_rdd_cmd {
+@@ -452,6 +507,15 @@ enum mt7915_rdd_cmd {
  	RDD_IRQ_OFF,
  };
  
@@ -844,7 +890,7 @@
  static inline struct mt7915_phy *
  mt7915_hw_phy(struct ieee80211_hw *hw)
  {
-@@ -578,6 +642,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
+@@ -581,6 +645,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);
@@ -852,11 +898,12 @@
 +                                u32 subcmd);
 +int mt7915_mcu_set_vow_feature_ctrl(struct mt7915_dev *dev);
 +int mt7915_mcu_set_vow_band(struct mt7915_dev *dev, struct mt7915_vif *mvif);
++void mt7915_vow_init_sta_bss_grp(struct mt7915_sta *sta);
  int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
  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 80b7bc1a..b12aff80 100644
+index a9570ced..e90a928f 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[] = {
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 5a29596..ecffb76 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,7 +1,8 @@
-From cc7a9202984360cdc476d3aa860bebd9fc248a16 Mon Sep 17 00:00:00 2001
+From a71cacc640b5c4ddacdb4e3ce7c3571a08a2daa4 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] wifi: mt76: mt7915: wed: add rxwi for further in chip rro
+Subject: [PATCH 2005/2011] wifi: mt76: mt7915: wed: add rxwi for further in
+ chip rro
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
@@ -15,10 +16,10 @@
  7 files changed, 87 insertions(+), 80 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 3047f8ba..b210e39c 100644
+index e877d26..e3e2f38 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -59,17 +59,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
+@@ -64,17 +64,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
  	return t;
  }
  
@@ -42,7 +43,7 @@
  }
  
  static struct mt76_txwi_cache *
-@@ -88,20 +88,20 @@ __mt76_get_txwi(struct mt76_dev *dev)
+@@ -93,20 +93,20 @@ __mt76_get_txwi(struct mt76_dev *dev)
  	return t;
  }
  
@@ -70,7 +71,7 @@
  }
  
  static struct mt76_txwi_cache *
-@@ -115,13 +115,13 @@ mt76_get_txwi(struct mt76_dev *dev)
+@@ -120,13 +120,13 @@ mt76_get_txwi(struct mt76_dev *dev)
  	return mt76_alloc_txwi(dev);
  }
  
@@ -88,7 +89,7 @@
  
  	return mt76_alloc_rxwi(dev);
  }
-@@ -140,14 +140,14 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+@@ -145,14 +145,14 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
  EXPORT_SYMBOL_GPL(mt76_put_txwi);
  
  void
@@ -108,7 +109,7 @@
  }
  EXPORT_SYMBOL_GPL(mt76_put_rxwi);
  
-@@ -168,13 +168,13 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
+@@ -173,13 +173,13 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
  void
  mt76_free_pending_rxwi(struct mt76_dev *dev)
  {
@@ -127,7 +128,7 @@
  	}
  	local_bh_enable();
  }
-@@ -212,7 +212,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -217,7 +217,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
  {
  	struct mt76_desc *desc = &q->desc[q->head];
  	struct mt76_queue_entry *entry = &q->entry[q->head];
@@ -136,7 +137,7 @@
  	u32 buf1 = 0, ctrl;
  	int idx = q->head;
  	int rx_token;
-@@ -220,13 +220,13 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -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);
  
  	if (mt76_queue_is_wed_rx(q)) {
@@ -154,7 +155,7 @@
  			return -ENOMEM;
  		}
  
-@@ -241,7 +241,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -246,7 +246,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
  
  	entry->dma_addr[0] = buf->addr;
  	entry->dma_len[0] = buf->len;
@@ -163,7 +164,7 @@
  	entry->buf = data;
  	entry->wcid = 0xffff;
  	entry->skip_buf1 = true;
-@@ -254,7 +254,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -259,7 +259,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
  static int
  mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
  		 struct mt76_queue_buf *buf, int nbufs, u32 info,
@@ -172,7 +173,7 @@
  {
  	struct mt76_queue_entry *entry;
  	struct mt76_desc *desc;
-@@ -307,6 +307,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -312,6 +312,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
  	}
  
  	q->entry[idx].txwi = txwi;
@@ -180,7 +181,7 @@
  	q->entry[idx].skb = skb;
  	q->entry[idx].wcid = 0xffff;
  
-@@ -405,13 +406,13 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -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);
  		u32 id, find = 0;
  		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
@@ -197,7 +198,7 @@
  					find = 1;
  					token = id;
  
-@@ -428,19 +429,19 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -430,19 +431,19 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  				return NULL;
  		}
  
@@ -224,7 +225,7 @@
  
  		if (drop) {
  			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
-@@ -504,7 +505,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -506,7 +507,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
  	buf.len = skb->len;
  
  	spin_lock_bh(&q->lock);
@@ -233,7 +234,7 @@
  	mt76_dma_kick_queue(dev, q);
  	spin_unlock_bh(&q->lock);
  
-@@ -584,7 +585,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -586,7 +587,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,
@@ -243,10 +244,10 @@
  unmap:
  	for (n--; n > 0; n--)
 diff --git a/mac80211.c b/mac80211.c
-index 25ec4330..35cd297c 100644
+index ad3a5e2..6232534 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -603,7 +603,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+@@ -607,7 +607,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);
@@ -254,7 +255,7 @@
  	mutex_init(&dev->mutex);
  	init_waitqueue_head(&dev->tx_wait);
  
-@@ -636,6 +635,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+@@ -640,6 +639,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,7 +264,7 @@
  	for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
  		skb_queue_head_init(&dev->rx_skb[i]);
 diff --git a/mt76.h b/mt76.h
-index 70146064..828d3e8b 100644
+index d00ef21..968bf08 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -173,6 +173,7 @@ struct mt76_queue_entry {
@@ -274,7 +275,7 @@
  		struct urb *urb;
  		int buf_sz;
  	};
-@@ -373,10 +374,15 @@ struct mt76_txwi_cache {
+@@ -376,10 +377,15 @@ struct mt76_txwi_cache {
  
  	unsigned long jiffies;
  
@@ -294,7 +295,7 @@
  };
  
  struct mt76_rx_tid {
-@@ -462,6 +468,7 @@ struct mt76_driver_ops {
+@@ -465,6 +471,7 @@ struct mt76_driver_ops {
  	u16 txwi_size;
  	u16 token_size;
  	u8 mcs_rates;
@@ -302,7 +303,7 @@
  
  	void (*update_survey)(struct mt76_phy *phy);
  
-@@ -835,7 +842,6 @@ struct mt76_dev {
+@@ -851,7 +858,6 @@ struct mt76_dev {
  
  	struct ieee80211_hw *hw;
  
@@ -310,7 +311,7 @@
  	spinlock_t lock;
  	spinlock_t cc_lock;
  
-@@ -1525,8 +1531,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
+@@ -1543,8 +1549,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);
@@ -321,7 +322,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);
-@@ -1681,9 +1687,9 @@ struct mt76_txwi_cache *
+@@ -1699,9 +1705,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);
@@ -334,7 +335,7 @@
  static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
  {
 diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 59a44d79..326c8c8c 100644
+index 59a44d7..326c8c8 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)
@@ -354,7 +355,7 @@
  
  		/* rx data queue for band1 */
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index cae8b810..d7393901 100644
+index cae8b81..d739390 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)
@@ -444,7 +445,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 c60521b1..4d3ff13b 100644
+index 764edc5..c1f3a0a 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -64,6 +64,7 @@
@@ -456,10 +457,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 5d7bf340..2594a625 100644
+index f1dd9f6..e290aef 100644
 --- a/tx.c
 +++ b/tx.c
-@@ -774,16 +774,16 @@ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
+@@ -842,16 +842,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,
@@ -480,7 +481,7 @@
  	}
  	spin_unlock_bh(&dev->rx_token_lock);
  
-@@ -820,15 +820,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
+@@ -888,15 +888,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/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 36e68cc..ac5bfb1 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,7 +1,8 @@
-From 99ebe10c9bc4259528c225fd6ab64edaa02d9d15 Mon Sep 17 00:00:00 2001
+From 999021989ad387b46c8ff4ffed43cc0017322c5e 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] wifi: mt76: add debugfs knob to show packet error rate
+Subject: [PATCH 2006/2011] wifi: mt76: add debugfs knob to show packet error
+ rate
 
 Get tx count and tx failed from mcu command
 ---
@@ -14,7 +15,7 @@
  6 files changed, 194 insertions(+), 1 deletion(-)
 
 diff --git a/mt76.h b/mt76.h
-index 828d3e8..3fbe02a 100644
+index 968bf08..3032cdd 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -297,8 +297,10 @@ struct mt76_sta_stats {
@@ -29,10 +30,10 @@
  	u64 rx_bytes;
  	u32 rx_packets;
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 1257dfa..cfdee7c 100644
+index 9ad1883..2d6e610 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1162,6 +1162,7 @@ enum {
+@@ -1173,6 +1173,7 @@ enum {
  	MCU_EXT_CMD_EDCA_UPDATE = 0x27,
  	MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
  	MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
@@ -41,10 +42,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 170b3f1..148a687 100644
+index b2b5c76..d4b0617 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4232,6 +4232,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
+@@ -4233,6 +4233,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
  		return mt7915_mcu_get_tx_rate_v2(phy, wcidx);
  }
  
@@ -199,10 +200,10 @@
     CAPI_SU,
     CAPI_MU,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index e36fb84..e8f7ca5 100644
+index c1f3a0a..d47abcf 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -675,6 +675,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+@@ -677,6 +677,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);
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 a4e9fa7..83cda65 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 8011cfeea1db4876c4d2775d203c03854334b013 Mon Sep 17 00:00:00 2001
+From 1d021dcf4503c9003919b805f5ead1d78b50ad7a 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/2010] wifi: mt76: mt7915: add ctxd support for mt7916
+Subject: [PATCH 2007/2011] wifi: mt76: mt7915: add ctxd support for mt7916
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
 ---
@@ -10,7 +10,7 @@
  2 files changed, 35 insertions(+)
 
 diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 326c8c8c..f71ec55b 100644
+index 326c8c8..f71ec55 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)
@@ -41,10 +41,10 @@
  	} else {
  		mt76_clear(dev, MT_WFDMA_HOST_CONFIG, MT_WFDMA_HOST_CONFIG_WED);
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 44da7b82..bc963ac8 100644
+index 3c2fd2d..32d1f1e 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
-@@ -606,6 +606,7 @@ enum offs_rev {
+@@ -607,6 +607,7 @@ enum offs_rev {
  #define MT_WFDMA0_GLO_CFG		MT_WFDMA0(0x208)
  #define MT_WFDMA0_GLO_CFG_TX_DMA_EN	BIT(0)
  #define MT_WFDMA0_GLO_CFG_RX_DMA_EN	BIT(2)
@@ -52,7 +52,7 @@
  #define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO	BIT(28)
  #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO	BIT(27)
  #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2	BIT(21)
-@@ -615,6 +616,17 @@ enum offs_rev {
+@@ -616,6 +617,17 @@ enum offs_rev {
  #define MT_WFDMA0_EXT0_CFG		MT_WFDMA0(0x2b0)
  #define MT_WFDMA0_EXT0_RXWB_KEEP	BIT(10)
  
@@ -70,7 +70,7 @@
  #define MT_WFDMA0_PRI_DLY_INT_CFG0	MT_WFDMA0(0x2f0)
  #define MT_WFDMA0_PRI_DLY_INT_CFG1	MT_WFDMA0(0x2f4)
  #define MT_WFDMA0_PRI_DLY_INT_CFG2	MT_WFDMA0(0x2f8)
-@@ -658,6 +670,8 @@ enum offs_rev {
+@@ -659,6 +671,8 @@ enum offs_rev {
  #define MT_WFDMA_WED_RING_CONTROL_TX1	GENMASK(12, 8)
  #define MT_WFDMA_WED_RING_CONTROL_RX1	GENMASK(20, 16)
  
@@ -79,7 +79,7 @@
  #define MT_WFDMA_EXT_CSR_HIF_MISC	MT_WFDMA_EXT_CSR_PHYS(0x44)
  #define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY	BIT(0)
  
-@@ -1186,6 +1200,7 @@ enum offs_rev {
+@@ -1187,6 +1201,7 @@ enum offs_rev {
  
  #define MT_HW_BOUND			0x70010020
  #define MT_HW_REV			0x70010204
@@ -88,5 +88,5 @@
  
  /* PCIE MAC */
 -- 
-2.39.2
+2.18.0
 
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 db22ea4..a50ea6c 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,7 +1,7 @@
-From 5a6a17438c96f92e7fa27123467384ad6e8dbd7f Mon Sep 17 00:00:00 2001
+From 7a963d92dd37bb16d00cc9ba7684f131d3331a78 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/2010] wifi: mt76: connac: wed: add wed rx copy skb
+Subject: [PATCH 2008/2011] wifi: mt76: connac: wed: add wed rx copy skb
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
@@ -10,10 +10,10 @@
  2 files changed, 85 insertions(+), 26 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index b210e39c..4daa64da 100644
+index e3e2f38..7c5e623 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -208,11 +208,11 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -213,11 +213,11 @@ 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,
@@ -27,7 +27,7 @@
  	u32 buf1 = 0, ctrl;
  	int idx = q->head;
  	int rx_token;
-@@ -220,9 +220,11 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -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);
  
  	if (mt76_queue_is_wed_rx(q)) {
@@ -42,7 +42,7 @@
  
  		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
  		if (rx_token < 0) {
-@@ -387,7 +389,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
+@@ -389,7 +391,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 +51,7 @@
  {
  	struct mt76_queue_entry *e = &q->entry[idx];
  	struct mt76_desc *desc = &q->desc[idx];
-@@ -437,11 +439,43 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -439,11 +441,43 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  				 SKB_WITH_OVERHEAD(q->buf_size),
  				 DMA_FROM_DEVICE);
  
@@ -99,7 +99,7 @@
  
  		if (drop) {
  			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
-@@ -480,7 +514,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
+@@ -482,7 +516,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
  	q->tail = (q->tail + 1) % q->ndesc;
  	q->queued--;
  
@@ -108,7 +108,7 @@
  }
  
  static int
-@@ -620,6 +654,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -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;
@@ -116,7 +116,7 @@
  
  	if (!q->ndesc)
  		return 0;
-@@ -643,7 +678,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -645,7 +680,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
  		qbuf.addr = addr + offset;
  		qbuf.len = len - offset;
  		qbuf.skip_unmap = false;
@@ -125,7 +125,7 @@
  			dma_unmap_single(dev->dma_dev, addr, len,
  					 DMA_FROM_DEVICE);
  			skb_free_frag(buf);
-@@ -652,7 +687,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -654,7 +689,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
  		frames++;
  	}
  
@@ -137,7 +137,7 @@
  		mt76_dma_kick_queue(dev, q);
  
  	spin_unlock_bh(&q->lock);
-@@ -775,12 +813,14 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -777,12 +815,14 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  
  	spin_unlock_bh(&q->lock);
  
@@ -158,10 +158,10 @@
  
  static void
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index a59e3118..89523a52 100644
+index d739390..aa5c5dd 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -576,6 +576,7 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+@@ -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)
  {
  	struct mt7915_dev *dev;
@@ -169,7 +169,7 @@
  	u32 length;
  	int i;
  
-@@ -592,13 +593,33 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -630,13 +631,33 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  
  		dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
  				 wed->wlan.rx_size, DMA_FROM_DEVICE);
@@ -204,7 +204,7 @@
  }
  
  static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
-@@ -615,35 +636,33 @@ 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)
  	for (i = 0; i < size; i++) {
  		struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
  		dma_addr_t phy_addr;
@@ -246,5 +246,5 @@
  			goto unmap;
  		}
 -- 
-2.39.2
+2.18.0
 
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
new file mode 100644
index 0000000..97e343a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch
@@ -0,0 +1,30 @@
+From 8b5f1f9d44e11290d97dbae675457d1cf5030374 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
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt7915/debugfs.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
+index ca42b69..fd35b57 100644
+--- a/mt7915/debugfs.c
++++ b/mt7915/debugfs.c
+@@ -988,7 +988,11 @@ mt7915_fw_debug_wa_set(void *data, u64 val)
+ 	struct mt7915_dev *dev = data;
+ 	int ret;
+ 
+-	dev->fw.debug_wa = val ? MCU_FW_LOG_TO_HOST : 0;
++	/* bit 0: log to uart, bit 1: log to Host */
++	if (val > 3)
++		return -EINVAL;
++
++	dev->fw.debug_wa = val;
+ 
+ 	ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev->fw.debug_wa);
+ 	if (ret)
+-- 
+2.18.0
+
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
new file mode 100644
index 0000000..d004b61
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch
@@ -0,0 +1,31 @@
+From 7dabeeff8a38468359c857c5df6da076faa95444 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
+ receive invalid token id
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt7915/mac.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index 3c6b308..a5369ea 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)
+ 			} else {
+ 				msdu = FIELD_GET(MT_TX_FREE_MSDU_ID, info);
+ 			}
++
++			/* Todo: check if msdu is sw token */
++			if (msdu > MT7915_TOKEN_SIZE)
++				dev_err(mdev->dev, "Receive invalid token id(%d)\n",
++					msdu);
++
+ 			count++;
+ 			txwi = mt76_token_release(mdev, msdu, &wake);
+ 			if (!txwi)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/2011-mt76-wifi-mt7915-wed-setting-wed-hw-tx-token-to-8192.patch b/recipes-wifi/linux-mt76/files/patches/2011-mt76-wifi-mt7915-wed-setting-wed-hw-tx-token-to-8192.patch
new file mode 100644
index 0000000..13d1f48
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/2011-mt76-wifi-mt7915-wed-setting-wed-hw-tx-token-to-8192.patch
@@ -0,0 +1,122 @@
+From 467bdd35a3ec4603761f1a7e2281a78a3776a0bb 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 2011/2011] mt76: wifi: mt7915: wed: setting wed hw tx token to
+ 8192
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ mt7915/mmio.c   |  8 ++++----
+ mt7915/mt7915.h |  4 ++--
+ tx.c            | 26 ++++++++------------------
+ 3 files changed, 14 insertions(+), 24 deletions(-)
+
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index aa5c5dd..b677947 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_TOKEN_SIZE - MT7915_HW_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_TOKEN_SIZE - MT7915_HW_TOKEN_SIZE;
+ 	spin_unlock_bh(&dev->mt76.token_lock);
+ }
+ 
+@@ -841,7 +841,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+ 	wed->wlan.tx_tbit[0] = is_mt7915(&dev->mt76) ? 4 : 30;
+ 	wed->wlan.tx_tbit[1] = is_mt7915(&dev->mt76) ? 5 : 31;
+ 	wed->wlan.txfree_tbit = is_mt798x(&dev->mt76) ? 2 : 1;
+-	wed->wlan.token_start = MT7915_TOKEN_SIZE - wed->wlan.nbuf;
++	wed->wlan.token_start = 0;
+ 	wed->wlan.wcid_512 = !is_mt7915(&dev->mt76);
+ 
+ 	wed->wlan.rx_nbuf = 65536;
+@@ -874,7 +874,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+ 
+ 	*irq = wed->irq;
+ 	dev->mt76.dma_dev = wed->dev;
+-	dev->mt76.token_size = wed->wlan.token_start;
++	dev->mt76.token_size = MT7915_TOKEN_SIZE - MT7915_HW_TOKEN_SIZE;
+ 
+ 	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
+ 	if (ret)
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index d47abcf..5f3b84e 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -62,8 +62,8 @@
+ #define MT7916_EEPROM_SIZE		4096
+ 
+ #define MT7915_EEPROM_BLOCK_SIZE	16
+-#define MT7915_HW_TOKEN_SIZE		7168
+-#define MT7915_TOKEN_SIZE		8192
++#define MT7915_HW_TOKEN_SIZE		8192
++#define MT7915_TOKEN_SIZE		9216
+ #define MT7915_RX_TOKEN_SIZE		4096
+ 
+ #define MT7915_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
+diff --git a/tx.c b/tx.c
+index e290aef..96f9009 100644
+--- a/tx.c
++++ b/tx.c
+@@ -818,20 +818,18 @@ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
+ 
+ int mt76_token_consume(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);
+-	if (token >= 0)
++	token = idr_alloc(&dev->token, *ptxwi, start, start + dev->token_size,
++			  GFP_ATOMIC);
++	if (token >= start)
+ 		dev->token_count++;
+ 
+-#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+-	if (mtk_wed_device_active(&dev->mmio.wed) &&
+-	    token >= dev->mmio.wed.wlan.token_start)
+-		dev->wed_token_count++;
+-#endif
+-
+ 	if (dev->token_count >= dev->token_size - MT76_TOKEN_FREE_THR)
+ 		__mt76_set_tx_blocked(dev, true);
+ 
+@@ -867,17 +865,9 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
+ 	spin_lock_bh(&dev->token_lock);
+ 
+ 	txwi = idr_remove(&dev->token, token);
+-	if (txwi) {
++	if (txwi)
+ 		dev->token_count--;
+ 
+-#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+-		if (mtk_wed_device_active(&dev->mmio.wed) &&
+-		    token >= dev->mmio.wed.wlan.token_start &&
+-		    --dev->wed_token_count == 0)
+-			wake_up(&dev->tx_wait);
+-#endif
+-	}
+-
+ 	if (dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR &&
+ 	    dev->phy.q_tx[0]->blocked)
+ 		*wake = true;
+-- 
+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 95eeb1e..3d2e07e 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,4 +1,4 @@
-From 7b82a7ca86e377e26747dd57ec4cd5badc9d4bcb Mon Sep 17 00:00:00 2001
+From 87cc43ed074bca81b765e0961bd24da23f6e997e 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] mt76: revert for backports-5.15 wireless stack
@@ -6,12 +6,12 @@
 wifi: mt76: mt7915: add support for he ldpc control from hostapd
 ---
  dma.c             |   2 +-
- mac80211.c        |   4 +-
+ mac80211.c        |  15 +--
  mt7615/dma.c      |   4 +-
  mt7615/main.c     |   6 +-
  mt7615/mcu.c      |   8 +-
  mt76_connac_mac.c |   2 +-
- mt76_connac_mcu.c | 108 ++++++++++----------
+ mt76_connac_mcu.c | 117 ++++++++++------------
  mt76x02_mac.c     |   6 +-
  mt7915/debugfs.c  |   4 +-
  mt7915/dma.c      |   4 +-
@@ -21,13 +21,13 @@
  mt7915/mmio.c     |   2 +-
  mt7915/testmode.c |   8 +-
  tx.c              |  22 ++---
- 16 files changed, 256 insertions(+), 209 deletions(-)
+ 16 files changed, 259 insertions(+), 226 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 4daa64da..220e684a 100644
+index 7c5e623c..908852c0 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -994,7 +994,7 @@ mt76_dma_init(struct mt76_dev *dev,
+@@ -996,7 +996,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,28 @@
  		napi_enable(&dev->napi[i]);
  	}
 diff --git a/mac80211.c b/mac80211.c
-index 35cd297c..629770c0 100644
+index 62325345..137c5204 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -1521,7 +1521,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power);
+@@ -1046,14 +1046,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;
+-	if (status->encoding == RX_ENC_EHT) {
+-		status->eht.ru = mstat.eht.ru;
+-		status->eht.gi = mstat.eht.gi;
+-	} else {
+-		status->he_ru = mstat.he_ru;
+-		status->he_gi = mstat.he_gi;
+-		status->he_dcm = mstat.he_dcm;
+-	}
++	status->he_ru = mstat.he_ru;
++	status->he_gi = mstat.he_gi;
++	status->he_dcm = mstat.he_dcm;
+ 	status->rate_idx = mstat.rate_idx;
+ 	status->nss = mstat.nss;
+ 	status->band = mstat.band;
+@@ -1573,7 +1568,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power);
  static void
  __mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
  {
@@ -49,7 +67,7 @@
  		ieee80211_csa_finish(vif);
  }
  
-@@ -1543,7 +1543,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
+@@ -1595,7 +1590,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
  {
  	struct mt76_dev *dev = priv;
  
@@ -74,7 +92,7 @@
  
  	mt76_poll(dev, MT_WPDMA_GLO_CFG,
 diff --git a/mt7615/main.c b/mt7615/main.c
-index 200b1752..53f30a0f 100644
+index dab16b5f..d32a7520 100644
 --- a/mt7615/main.c
 +++ b/mt7615/main.c
 @@ -473,7 +473,7 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
@@ -105,7 +123,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 86061e95..a79308b6 100644
+index db337aad..c4d97434 100644
 --- a/mt7615/mcu.c
 +++ b/mt7615/mcu.c
 @@ -353,7 +353,7 @@ out:
@@ -145,10 +163,10 @@
  		.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
  	};
 diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index b87b7335..08a92ace 100644
+index 02d52328..faeae26d 100644
 --- a/mt76_connac_mac.c
 +++ b/mt76_connac_mac.c
-@@ -1122,7 +1122,7 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+@@ -1110,7 +1110,7 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
  	u32 val;
  
  	if (!sta ||
@@ -158,10 +176,10 @@
  
  	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index e6b468c4..220c1335 100644
+index 07bd57b8..aa99bd78 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -197,7 +197,7 @@ int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
+@@ -198,7 +198,7 @@ int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
  			      */
  	} req = {
  		.bss_idx = mvif->idx,
@@ -170,7 +188,7 @@
  	};
  
  	if (vif->type != NL80211_IFTYPE_STATION)
-@@ -409,7 +409,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -410,7 +410,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);
@@ -179,7 +197,7 @@
  		break;
  	case NL80211_IFTYPE_ADHOC:
  		basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
-@@ -553,7 +553,7 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
+@@ -554,7 +554,7 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
  
  	if (sta) {
  		if (vif->type == NL80211_IFTYPE_STATION)
@@ -188,7 +206,7 @@
  		else
  			generic->partial_aid = cpu_to_le16(sta->aid);
  		memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
-@@ -602,14 +602,14 @@ mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+@@ -603,14 +603,14 @@ mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  	    vif->type != NL80211_IFTYPE_STATION)
  		return;
  
@@ -205,7 +223,7 @@
  			       IEEE80211_MAX_MPDU_LEN_VHT_7991;
  
  	wcid->amsdu = true;
-@@ -620,7 +620,7 @@ mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+@@ -621,7 +621,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)
  {
@@ -214,7 +232,7 @@
  	struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
  	struct sta_rec_he *he;
  	struct tlv *tlv;
-@@ -708,7 +708,7 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -709,7 +709,7 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  
  	he->he_cap = cpu_to_le32(cap);
  
@@ -223,8 +241,8 @@
  	case IEEE80211_STA_RX_BW_160:
  		if (elem->phy_cap_info[0] &
  		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
-@@ -753,7 +753,7 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
- static void
+@@ -754,7 +754,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)
  {
 -	struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
@@ -232,7 +250,7 @@
  	struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
  	struct sta_rec_he_v2 *he;
  	struct tlv *tlv;
-@@ -764,7 +764,7 @@ mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -765,7 +765,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));
  
@@ -241,29 +259,62 @@
  	case IEEE80211_STA_RX_BW_160:
  		if (elem->phy_cap_info[0] &
  		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
-@@ -780,7 +780,7 @@ mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -781,7 +781,7 @@ mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
  		break;
  	}
  
 -	he->pkt_ext = IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US;
 +	he->pkt_ext = IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US;
  }
+ EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_he_tlv_v2);
  
- static u8
-@@ -793,9 +793,9 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+@@ -792,14 +792,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;
+-	const struct ieee80211_sta_eht_cap *eht_cap;
  	u8 mode = 0;
  
  	if (sta) {
 -		ht_cap = &sta->deflink.ht_cap;
 -		vht_cap = &sta->deflink.vht_cap;
 -		he_cap = &sta->deflink.he_cap;
+-		eht_cap = &sta->deflink.eht_cap;
 +		ht_cap = &sta->ht_cap;
 +		vht_cap = &sta->vht_cap;
 +		he_cap = &sta->he_cap;
  	} else {
  		struct ieee80211_supported_band *sband;
  
+@@ -807,7 +805,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);
+-		eht_cap = ieee80211_get_eht_iftype_cap(sband, vif->type);
+ 	}
+ 
+ 	if (band == NL80211_BAND_2GHZ) {
+@@ -818,9 +815,6 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+ 
-@@ -844,25 +844,25 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+ 		if (he_cap && he_cap->has_he)
+ 			mode |= PHY_TYPE_BIT_HE;
+-
+-		if (eht_cap && eht_cap->has_eht)
+-			mode |= PHY_TYPE_BIT_BE;
+ 	} 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,
+ 
+ 		if (he_cap && he_cap->has_he)
+ 			mode |= PHY_TYPE_BIT_HE;
+-
+-		if (eht_cap && eht_cap->has_eht)
+-			mode |= PHY_TYPE_BIT_BE;
+ 	}
+ 
+ 	return mode;
+@@ -858,25 +849,25 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  	u16 supp_rates;
  
  	/* starec ht */
@@ -295,7 +346,7 @@
  	}
  
  	/* starec uapsd */
-@@ -871,11 +871,11 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -885,11 +876,11 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  	if (!is_mt7921(dev))
  		return;
  
@@ -309,7 +360,7 @@
  		mt76_connac_mcu_sta_he_tlv(skb, sta);
  		mt76_connac_mcu_sta_he_tlv_v2(skb, sta);
  		if (band == NL80211_BAND_6GHZ &&
-@@ -885,7 +885,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -899,7 +890,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;
@@ -318,7 +369,7 @@
  		}
  	}
  
-@@ -895,14 +895,14 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -909,14 +900,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,
@@ -336,7 +387,7 @@
  	if (band == NL80211_BAND_2GHZ)
  		supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) |
  			     FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf);
-@@ -911,18 +911,18 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
+@@ -925,18 +916,18 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  
  	ra_info->legacy = cpu_to_le16(supp_rates);
  
@@ -360,7 +411,7 @@
  			IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
  	}
  }
-@@ -938,7 +938,7 @@ void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb,
+@@ -952,7 +943,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;
@@ -369,7 +420,7 @@
  }
  EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_smps_tlv);
  
-@@ -950,27 +950,27 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -964,27 +955,27 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  	struct tlv *tlv;
  	u32 flags = 0;
  
@@ -405,7 +456,7 @@
  		struct wtbl_vht *vht;
  		u8 af;
  
-@@ -979,18 +979,18 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -993,18 +984,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 &&
@@ -427,7 +478,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;
-@@ -1000,15 +1000,15 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
+@@ -1014,15 +1005,15 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  						     sizeof(*raw), wtbl_tlv,
  						     sta_wtbl);
  
@@ -448,7 +499,7 @@
  				flags |= MT_WTBL_W5_SHORT_GI_160;
  		}
  		raw = (struct wtbl_raw *)tlv;
-@@ -1297,9 +1297,9 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1311,9 +1302,9 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
  		return 0x38;
  
  	if (sta) {
@@ -461,7 +512,7 @@
  	} else {
  		struct ieee80211_supported_band *sband;
  
-@@ -1619,7 +1619,6 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1636,7 +1627,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;
@@ -469,7 +520,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);
-@@ -1759,7 +1758,6 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
+@@ -1776,7 +1766,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);
  	}
@@ -477,7 +528,7 @@
  	req->match_num = sreq->n_match_sets;
  	for (i = 0; i < req->match_num; i++) {
  		match = &sreq->match_sets[i];
-@@ -2246,10 +2244,8 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
+@@ -2272,10 +2261,8 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
  				      struct mt76_vif *vif,
  				      struct ieee80211_bss_conf *info)
  {
@@ -489,7 +540,7 @@
  			   IEEE80211_BSS_ARP_ADDR_LIST_LEN);
  	struct {
  		struct {
-@@ -2277,7 +2273,7 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
+@@ -2303,7 +2290,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++)
@@ -524,10 +575,10 @@
  		if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
  			ba_size = 0;
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index fefa4540..848ba4ee 100644
+index fd35b579..117ebb56 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
-@@ -2045,8 +2045,8 @@ static ssize_t mt7915_sta_fixed_rate_set(struct file *file,
+@@ -2049,8 +2049,8 @@ static ssize_t mt7915_sta_fixed_rate_set(struct file *file,
  
  	phy.ldpc = (phy.bw || phy.ldpc) * GENMASK(2, 0);
  	for (i = 0; i <= phy.bw; i++) {
@@ -554,10 +605,10 @@
  
  	mt7915_dma_enable(dev, false);
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 2e9c94fb..b30aaea2 100644
+index db627500..0ce17775 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -1157,8 +1157,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
+@@ -1173,8 +1173,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
  			mt76_connac_gen_ppe_thresh(he_cap->ppe_thres, nss);
  		} else {
  			he_cap_elem->phy_cap_info[9] |=
@@ -568,10 +619,10 @@
  
  		if (band == NL80211_BAND_6GHZ) {
 diff --git a/mt7915/main.c b/mt7915/main.c
-index deef1bb6..14b691a2 100644
+index 8bcffd3f..7af49404 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -532,7 +532,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
+@@ -538,7 +538,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
  
  static int
  mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -580,7 +631,7 @@
  	       const struct ieee80211_tx_queue_params *params)
  {
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-@@ -627,7 +627,7 @@ mt7915_update_bss_color(struct ieee80211_hw *hw,
+@@ -639,7 +639,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,
@@ -589,7 +640,7 @@
  {
  	struct mt7915_phy *phy = mt7915_hw_phy(hw);
  	struct mt7915_dev *dev = mt7915_hw_dev(hw);
-@@ -643,7 +643,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+@@ -655,7 +655,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)
@@ -598,7 +649,7 @@
  	if (changed & BSS_CHANGED_BEACON_ENABLED &&
  	    vif->type != NL80211_IFTYPE_AP)
  		set_bss_info = set_sta = info->enable_beacon;
-@@ -691,27 +691,8 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+@@ -703,27 +703,8 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
  	mutex_unlock(&dev->mt76.mutex);
  }
  
@@ -627,7 +678,7 @@
  {
  	struct mt7915_phy *phy = mt7915_hw_phy(hw);
  	struct mt7915_dev *dev = mt7915_hw_dev(hw);
-@@ -719,8 +700,6 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -731,8 +712,6 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  
  	mutex_lock(&dev->mt76.mutex);
  
@@ -636,7 +687,7 @@
  	err = mt7915_mcu_add_bss_info(phy, vif, true);
  	if (err)
  		goto out;
-@@ -732,8 +711,7 @@ out:
+@@ -744,8 +723,7 @@ out:
  }
  
  static void
@@ -646,7 +697,7 @@
  {
  	struct mt7915_dev *dev = mt7915_hw_dev(hw);
  
-@@ -1296,10 +1274,10 @@ static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw,
+@@ -1307,10 +1285,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);
@@ -660,7 +711,7 @@
  
  	mutex_lock(&dev->mt76.mutex);
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 7c3e25c6..8dce1dea 100644
+index ebacfd27..95c4188d 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,
@@ -718,12 +769,12 @@
  static void
  mt7915_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
  {
--	if (vif->bss_conf.csa_active && vif->type != NL80211_IFTYPE_STATION)
-+	if (vif->csa_active && vif->type != NL80211_IFTYPE_STATION)
- 		ieee80211_csa_finish(vif);
- }
+-	if (!vif->bss_conf.csa_active || vif->type == NL80211_IFTYPE_STATION)
++	if (!vif->csa_active || vif->type == NL80211_IFTYPE_STATION)
+ 		return;
  
-@@ -337,7 +337,7 @@ mt7915_mcu_rx_log_message(struct mt7915_dev *dev, struct sk_buff *skb)
+ 	ieee80211_csa_finish(vif);
+@@ -339,7 +339,7 @@ mt7915_mcu_rx_log_message(struct mt7915_dev *dev, struct sk_buff *skb)
  static void
  mt7915_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
  {
@@ -732,7 +783,7 @@
  		return;
  
  	ieee80211_color_change_finish(vif);
-@@ -752,13 +752,13 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+@@ -754,13 +754,13 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  		      struct ieee80211_vif *vif)
  {
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
@@ -748,7 +799,7 @@
  		return;
  
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));
-@@ -844,8 +844,8 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+@@ -846,8 +846,8 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  
  	he->he_cap = cpu_to_le32(cap);
  
@@ -759,7 +810,7 @@
  	case IEEE80211_STA_RX_BW_160:
  		if (elem->phy_cap_info[0] &
  		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
-@@ -895,7 +895,7 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -897,7 +897,7 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  			struct ieee80211_sta *sta, struct ieee80211_vif *vif)
  {
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
@@ -768,7 +819,7 @@
  	struct mt7915_phy *phy = mvif->phy;
  	struct sta_rec_muru *muru;
  	struct tlv *tlv;
-@@ -920,11 +920,11 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -922,11 +922,11 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	muru->cfg.ofdma_dl_en = !!(phy->muru_onoff & OFDMA_DL);
  	muru->cfg.ofdma_ul_en = !!(phy->muru_onoff & OFDMA_UL);
  
@@ -783,7 +834,7 @@
  		return;
  
  	muru->mimo_dl.partial_bw_dl_mimo =
-@@ -960,13 +960,13 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -962,13 +962,13 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  	struct sta_rec_ht *ht;
  	struct tlv *tlv;
  
@@ -799,7 +850,7 @@
  }
  
  static void
-@@ -975,15 +975,15 @@ mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -977,15 +977,15 @@ mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  	struct sta_rec_vht *vht;
  	struct tlv *tlv;
  
@@ -819,7 +870,7 @@
  }
  
  static void
-@@ -998,7 +998,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1000,7 +1000,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	    vif->type != NL80211_IFTYPE_AP)
  		return;
  
@@ -828,7 +879,7 @@
  	    return;
  
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
-@@ -1007,7 +1007,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1009,7 +1009,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	amsdu->amsdu_en = true;
  	msta->wcid.amsdu = true;
  
@@ -837,7 +888,7 @@
  	case IEEE80211_MAX_MPDU_LEN_VHT_11454:
  		if (!is_mt7915(&dev->mt76)) {
  			amsdu->max_mpdu_size =
-@@ -1070,8 +1070,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+@@ -1072,8 +1072,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  	if (!bfee && sts < 2)
  		return false;
  
@@ -848,7 +899,7 @@
  
  		if (bfee)
  			return mvif->cap.he_su_ebfee &&
-@@ -1081,8 +1081,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+@@ -1083,8 +1083,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  			       HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]);
  	}
  
@@ -859,7 +910,7 @@
  
  		if (bfee)
  			return mvif->cap.vht_su_ebfee &&
-@@ -1108,7 +1108,7 @@ static void
+@@ -1110,7 +1110,7 @@ static void
  mt7915_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
  		       struct sta_rec_bf *bf)
  {
@@ -868,7 +919,7 @@
  	u8 n = 0;
  
  	bf->tx_mode = MT_PHY_TYPE_HT;
-@@ -1133,7 +1133,7 @@ static void
+@@ -1135,7 +1135,7 @@ static void
  mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
  			struct sta_rec_bf *bf, bool explicit)
  {
@@ -877,7 +928,7 @@
  	struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap;
  	u16 mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map);
  	u8 nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
-@@ -1154,14 +1154,14 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
+@@ -1156,14 +1156,14 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
  		bf->ncol = min_t(u8, nss_mcs, bf->nrow);
  		bf->ibf_ncol = bf->ncol;
  
@@ -894,7 +945,7 @@
  			bf->ibf_nrow = 1;
  	}
  }
-@@ -1170,7 +1170,7 @@ static void
+@@ -1172,7 +1172,7 @@ static void
  mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
  		       struct mt7915_phy *phy, struct sta_rec_bf *bf)
  {
@@ -903,7 +954,7 @@
  	struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
  	const struct ieee80211_sta_he_cap *vc =
  		mt76_connac_get_he_phy_cap(phy->mt76, vif);
-@@ -1195,7 +1195,7 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
+@@ -1197,7 +1197,7 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
  	bf->ncol = min_t(u8, nss_mcs, bf->nrow);
  	bf->ibf_ncol = bf->ncol;
  
@@ -912,7 +963,7 @@
  		return;
  
  	/* go over for 160MHz and 80p80 */
-@@ -1243,7 +1243,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1245,7 +1245,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	};
  	bool ebf;
  
@@ -921,7 +972,7 @@
  		return;
  
  	ebf = mt7915_is_ebf_supported(phy, vif, sta, false);
-@@ -1257,21 +1257,21 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1259,21 +1259,21 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	 * vht: support eBF and iBF
  	 * ht: iBF only, since mac80211 lacks of eBF support
  	 */
@@ -949,7 +1000,7 @@
  		bf->ibf_timeout = 0x48;
  	else
  		bf->ibf_timeout = 0x18;
-@@ -1281,7 +1281,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1283,7 +1283,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	else
  		bf->mem_20m = matrix[bf->nrow][bf->ncol];
  
@@ -958,7 +1009,7 @@
  	case IEEE80211_STA_RX_BW_160:
  	case IEEE80211_STA_RX_BW_80:
  		bf->mem_total = bf->mem_20m * 2;
-@@ -1306,7 +1306,7 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1308,7 +1308,7 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	struct tlv *tlv;
  	u8 nrow = 0;
  
@@ -967,7 +1018,7 @@
  		return;
  
  	if (!mt7915_is_ebf_supported(phy, vif, sta, true))
-@@ -1315,13 +1315,13 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1317,13 +1317,13 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee));
  	bfee = (struct sta_rec_bfee *)tlv;
  
@@ -985,7 +1036,7 @@
  
  		nrow = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
  				 pc->cap);
-@@ -1377,7 +1377,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
+@@ -1379,7 +1379,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
  			ra->phy = *phy;
  		break;
  	case RATE_PARAM_MMPS_UPDATE:
@@ -994,7 +1045,7 @@
  		break;
  	case RATE_PARAM_SPE_UPDATE:
  		ra->spe_idx = *(u8 *)data;
-@@ -1452,7 +1452,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+@@ -1454,7 +1454,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
  	do {									\
  		u8 i, gi = mask->control[band]._gi;				\
  		gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI;		\
@@ -1003,7 +1054,7 @@
  			phy.sgi |= gi << (i << (_he));				\
  			phy.he_ltf |= mask->control[band].he_ltf << (i << (_he));\
  		}								\
-@@ -1466,11 +1466,11 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+@@ -1468,11 +1468,11 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
  		}								\
  	} while (0)
  
@@ -1018,7 +1069,7 @@
  		__sta_phy_bitrate_mask_check(ht_mcs, gi, 1, 0);
  	} else {
  		nrates = hweight32(mask->control[band].legacy);
-@@ -1504,7 +1504,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+@@ -1506,7 +1506,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
  		 * actual txrate hardware sends out.
  		 */
  		addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7);
@@ -1027,7 +1078,7 @@
  			mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi);
  		else
  			mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi);
-@@ -1537,7 +1537,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+@@ -1539,7 +1539,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
  	enum nl80211_band band = chandef->chan->band;
  	struct sta_rec_ra *ra;
  	struct tlv *tlv;
@@ -1036,7 +1087,7 @@
  	u32 cap = sta->wme ? STA_CAP_WMM : 0;
  
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra));
-@@ -1547,9 +1547,9 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+@@ -1549,9 +1549,9 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
  	ra->auto_rate = true;
  	ra->phy_mode = mt76_connac_get_phy_mode(mphy, vif, band, sta);
  	ra->channel = chandef->chan->hw_value;
@@ -1049,7 +1100,7 @@
  
  	if (supp_rate) {
  		supp_rate &= mask->control[band].legacy;
-@@ -1569,22 +1569,22 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+@@ -1571,22 +1571,22 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
  		}
  	}
  
@@ -1080,7 +1131,7 @@
  			cap |= STA_CAP_LDPC;
  
  		mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs,
-@@ -1592,37 +1592,37 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+@@ -1594,37 +1594,37 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
  		ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs;
  	}
  
@@ -1128,7 +1179,7 @@
  					       IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
  	}
  
-@@ -1831,7 +1831,7 @@ mt7915_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb,
+@@ -1833,7 +1833,7 @@ mt7915_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb,
  	if (!offs->cntdwn_counter_offs[0])
  		return;
  
@@ -1137,7 +1188,7 @@
  	tlv = mt7915_mcu_add_nested_subtlv(rskb, sub_tag, sizeof(*info),
  					   &bcn->sub_ntlv, &bcn->len);
  	info = (struct bss_info_bcn_cntdwn *)tlv;
-@@ -1916,9 +1916,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1918,9 +1918,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	if (offs->cntdwn_counter_offs[0]) {
  		u16 offset = offs->cntdwn_counter_offs[0];
  
@@ -1149,7 +1200,7 @@
  			cont->bcc_ofs = cpu_to_le16(offset - 3);
  	}
  
-@@ -1928,6 +1928,85 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1930,6 +1930,85 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
  }
  
@@ -1235,7 +1286,7 @@
  int
  mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  			     u32 changed)
-@@ -2041,7 +2120,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -2043,7 +2122,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	if (!en)
  		goto out;
  
@@ -1244,7 +1295,7 @@
  	if (!skb) {
  		dev_kfree_skb(rskb);
  		return -EINVAL;
-@@ -2057,6 +2136,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -2059,6 +2138,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	info = IEEE80211_SKB_CB(skb);
  	info->hw_queue = FIELD_PREP(MT_TX_HW_QUEUE_PHY, ext_phy);
  
@@ -1252,7 +1303,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);
-@@ -3329,17 +3409,17 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3331,17 +3411,17 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  	if (txpower) {
  		u32 offs, len, i;
  
@@ -1274,7 +1325,7 @@
  					len = sku_len[SKU_HE_RU242] * 4;
  				}
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index aa5c5dd6..08e7c52f 100644
+index b6779474..1e998113 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)
@@ -1287,10 +1338,10 @@
  			skb_free_frag(ptr);
  			mt76_put_rxwi(&dev->mt76, r);
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index d5c74dfd..38ac79d6 100644
+index 5e20cb9e..a765f387 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
-@@ -416,12 +416,12 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
+@@ -418,12 +418,12 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
  		memcpy(sta->addr, td->addr[0], ETH_ALEN);
  
  	if (td->tx_rate_mode >= MT76_TM_TX_MODE_HT)
@@ -1308,7 +1359,7 @@
  	sta->wme = 1;
  
 diff --git a/tx.c b/tx.c
-index 2594a625..26fa6650 100644
+index 96f9009b..23a1e4e2 100644
 --- a/tx.c
 +++ b/tx.c
 @@ -60,20 +60,15 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
@@ -1364,5 +1415,5 @@
  		ieee80211_tx_status_ext(hw, &status);
  		spin_unlock_bh(&dev->rx_lock);
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/patches.inc b/recipes-wifi/linux-mt76/files/patches/patches.inc
index 167020d..61b3646 100644
--- a/recipes-wifi/linux-mt76/files/patches/patches.inc
+++ b/recipes-wifi/linux-mt76/files/patches/patches.inc
@@ -1,20 +1,12 @@
 #patch patches (come from openwrt/lede/target/linux/mediatek)
 SRC_URI_append = " \
-    file://0001-wifi-mt76-mt7915-update-beacon-size-limitation.patch \
-    file://0002-wifi-mt76-mt7915-check-sta-rx-control-frame-to-multi.patch \
-    file://0003-wifi-mt76-mt7915-fix-potential-memory-leak-of-beacon.patch \
-    file://0004-wifi-mt76-mt7915-get-rid-of-false-alamrs-of-tx-emiss.patch \
-    file://0005-wifi-mt76-mt7915-fix-per-band-IEEE80211_CONF_MONITOR.patch \
-    file://0006-wifi-mt76-mt7915-check-vif-type-before-reporting-cca.patch \
-    file://0007-wifi-mt76-mt7915-update-mpdu-density-capability.patch \
-    file://0008-wifi-mt76-mt7915-fix-beamforming-availability-check.patch \
-    file://0009-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch \
-    file://0010-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch \
-    file://0011-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch \
-    file://0012-wifi-mt76-mt7915-fix-txpower-issues.patch \
-    file://0013-wifi-mt76-mt7915-rework-init-txpower.patch \
-    file://0014-wifi-mt76-mt7915-rework-mmio-access-flow.patch \
-    file://0015-wifi-mt76-disable-HW-AMSDU-when-using-fixed-rate.patch \
+    file://0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch \
+    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://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 \
@@ -56,6 +48,9 @@
     file://1037-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch \
     file://1038-wifi-mt76-update-debugfs-knob-to-dump-token-pending-.patch \
     file://1039-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch \
+    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://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 \
@@ -65,5 +60,8 @@
     file://2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch \
     file://2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch \
     file://2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch \
+    file://2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch \
+    file://2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch \
+    file://2011-mt76-wifi-mt7915-wed-setting-wed-hw-tx-token-to-8192.patch \
     file://9999-mt76-revert-for-backports-5.15-wireless-stack.patch \
     "
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7981_eeprom.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7981_eeprom.bin
new file mode 100644
index 0000000..109fe88
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7981_eeprom.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_rom_patch.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_rom_patch.bin
index 8460c44..a03b417 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_rom_patch.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_rom_patch.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_rom_patch_mt7975.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_rom_patch_mt7975.bin
index 87531e4..353fc55 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_rom_patch_mt7975.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_rom_patch_mt7975.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wa.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wa.bin
index c90d3d4..2757f0b 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wa.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wa.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wm.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wm.bin
index 4597f31..9917559 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wm.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wm.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wm_mt7975.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wm_mt7975.bin
index d36e93e..d8ec355 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wm_mt7975.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wm_mt7975.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wo_0.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wo_0.bin
index aeb2778..49f9863 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wo_0.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wo_0.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wo_1.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wo_1.bin
index b7014ae..6590938 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wo_1.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7986_wo_1.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom.bin
new file mode 100644
index 0000000..a564d91
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom_23.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom_23.bin
new file mode 100644
index 0000000..6e0794c
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom_23.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom_24.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom_24.bin
new file mode 100644
index 0000000..2fdf1ec
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7992_eeprom_24.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 1c7710b..ada308b 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_rom_patch.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin
index 7b151c9..c391788 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 b0433e8..20d91ee 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 7188830..b6ca1a9 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 9ddee02..98d6517 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/linux-mt76_3.x.bb b/recipes-wifi/linux-mt76/linux-mt76_3.x.bb
index e77841d..b9a69c7 100644
--- a/recipes-wifi/linux-mt76/linux-mt76_3.x.bb
+++ b/recipes-wifi/linux-mt76/linux-mt76_3.x.bb
@@ -5,7 +5,7 @@
 
 inherit module
 
-require mt76-3x.inc
+require mt76.inc
 SRC_URI = " \
     git://git@github.com/openwrt/mt76.git;protocol=https \
     file://COPYING;subdir=git \
diff --git a/recipes-wifi/linux-mt76/mt76-3x.inc b/recipes-wifi/linux-mt76/mt76-3x.inc
deleted file mode 100644
index 2cb6ffc..0000000
--- a/recipes-wifi/linux-mt76/mt76-3x.inc
+++ /dev/null
@@ -1 +0,0 @@
-SRCREV_mt7990 = "969b7b5ebd129068ca56e4b0d831593a2f92382f"
diff --git a/recipes-wifi/linux-mt76/mt76-test.bb b/recipes-wifi/linux-mt76/mt76-test.bb
index 63e8e3e..db836fc 100644
--- a/recipes-wifi/linux-mt76/mt76-test.bb
+++ b/recipes-wifi/linux-mt76/mt76-test.bb
@@ -10,7 +10,6 @@
 PV = "1.0"
 
 require mt76.inc
-require mt76-3x.inc
 
 SRC_URI = " \
     git://git@github.com/openwrt/mt76.git;protocol=https \
diff --git a/recipes-wifi/linux-mt76/mt76.inc b/recipes-wifi/linux-mt76/mt76.inc
index b81583a..b025358 100644
--- a/recipes-wifi/linux-mt76/mt76.inc
+++ b/recipes-wifi/linux-mt76/mt76.inc
@@ -1 +1 @@
-SRCREV ?= "b14c2351ddb8601c322576d84029e463d456caef"
+SRCREV ?= "2afc7285f75dca5a0583fd917285bf33f1429cc6"
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/011-mesh-use-deterministic-channel-on-channel-switch.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/011-mesh-use-deterministic-channel-on-channel-switch.patch
index 9b11f0e..07b7a59 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/011-mesh-use-deterministic-channel-on-channel-switch.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/011-mesh-use-deterministic-channel-on-channel-switch.patch
@@ -29,7 +29,7 @@
  
  
  enum dfs_channel_type {
-@@ -521,9 +522,14 @@ dfs_get_valid_channel(struct hostapd_ifa
+@@ -526,9 +527,14 @@ dfs_get_valid_channel(struct hostapd_ifa
  	int num_available_chandefs;
  	int chan_idx, chan_idx2;
  	int sec_chan_idx_80p80 = -1;
@@ -44,7 +44,7 @@
  	wpa_printf(MSG_DEBUG, "DFS: Selecting random channel");
  	*secondary_channel = 0;
  	*oper_centr_freq_seg0_idx = 0;
-@@ -543,8 +549,20 @@ dfs_get_valid_channel(struct hostapd_ifa
+@@ -548,8 +554,20 @@ dfs_get_valid_channel(struct hostapd_ifa
  	if (num_available_chandefs == 0)
  		return NULL;
  
@@ -68,7 +68,7 @@
  	if (!chan) {
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -10977,6 +10977,10 @@ static int nl80211_switch_channel(void *
+@@ -11017,6 +11017,10 @@ static int nl80211_switch_channel(void *
  	if (ret)
  		goto error;
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/021-fix-sta-add-after-previous-connection.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/021-fix-sta-add-after-previous-connection.patch
index 4ee43b5..edf599e 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/021-fix-sta-add-after-previous-connection.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/021-fix-sta-add-after-previous-connection.patch
@@ -1,6 +1,6 @@
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -4601,6 +4601,13 @@ static int add_associated_sta(struct hos
+@@ -4621,6 +4621,13 @@ static int add_associated_sta(struct hos
  	 * drivers to accept the STA parameter configuration. Since this is
  	 * after a new FT-over-DS exchange, a new TK has been derived, so key
  	 * reinstallation is not a concern for this case.
@@ -14,7 +14,7 @@
  	 */
  	wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR
  		   " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
-@@ -4614,7 +4621,8 @@ static int add_associated_sta(struct hos
+@@ -4634,7 +4641,8 @@ static int add_associated_sta(struct hos
  	    (!(sta->flags & WLAN_STA_AUTHORIZED) ||
  	     (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) ||
  	     (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) &&
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch
index 19248e8..ef2bb40 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch
@@ -92,7 +92,7 @@
  
  	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
  		wpa_printf(MSG_DEBUG,
-@@ -11843,13 +11840,14 @@ static int wpa_driver_br_add_ip_neigh(vo
+@@ -11883,13 +11880,14 @@ static int wpa_driver_br_add_ip_neigh(vo
  				      const u8 *ipaddr, int prefixlen,
  				      const u8 *addr)
  {
@@ -112,7 +112,7 @@
  	int res;
  
  	if (!ipaddr || prefixlen == 0 || !addr)
-@@ -11868,85 +11866,66 @@ static int wpa_driver_br_add_ip_neigh(vo
+@@ -11908,85 +11906,66 @@ static int wpa_driver_br_add_ip_neigh(vo
  	}
  
  	if (version == 4) {
@@ -220,7 +220,7 @@
  		addrsize = 16;
  	} else {
  		return -EINVAL;
-@@ -11964,41 +11943,30 @@ static int wpa_driver_br_delete_ip_neigh
+@@ -12004,41 +11983,30 @@ static int wpa_driver_br_delete_ip_neigh
  		return -1;
  	}
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/040-mesh-allow-processing-authentication-frames-in-block.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/040-mesh-allow-processing-authentication-frames-in-block.patch
index f98d380..b7bf9e3 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/040-mesh-allow-processing-authentication-frames-in-block.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/040-mesh-allow-processing-authentication-frames-in-block.patch
@@ -16,7 +16,7 @@
 
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -3012,15 +3012,6 @@ static void handle_auth(struct hostapd_d
+@@ -3020,15 +3020,6 @@ static void handle_auth(struct hostapd_d
  				       seq_ctrl);
  			return;
  		}
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch
index 148c268..e967cff 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch
@@ -903,7 +903,7 @@
      for exp, flags in tests:
          hapd.disable()
          hapd.set("tls_flags", flags)
-@@ -7115,6 +7173,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde
+@@ -7138,6 +7196,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde
  def test_eap_tls_ext_cert_check(dev, apdev):
      """EAP-TLS and external server certification validation"""
      # With internal server certificate chain validation
@@ -911,7 +911,7 @@
      id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS",
                          identity="tls user",
                          ca_cert="auth_serv/ca.pem",
-@@ -7127,6 +7186,7 @@ def test_eap_tls_ext_cert_check(dev, apd
+@@ -7150,6 +7209,7 @@ def test_eap_tls_ext_cert_check(dev, apd
  def test_eap_ttls_ext_cert_check(dev, apdev):
      """EAP-TTLS and external server certification validation"""
      # Without internal server certificate chain validation
@@ -919,7 +919,7 @@
      id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
                          identity="pap user", anonymous_identity="ttls",
                          password="password", phase2="auth=PAP",
-@@ -7137,6 +7197,7 @@ def test_eap_ttls_ext_cert_check(dev, ap
+@@ -7160,6 +7220,7 @@ def test_eap_ttls_ext_cert_check(dev, ap
  def test_eap_peap_ext_cert_check(dev, apdev):
      """EAP-PEAP and external server certification validation"""
      # With internal server certificate chain validation
@@ -927,7 +927,7 @@
      id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP",
                          identity="user", anonymous_identity="peap",
                          ca_cert="auth_serv/ca.pem",
-@@ -7147,6 +7208,7 @@ def test_eap_peap_ext_cert_check(dev, ap
+@@ -7170,6 +7231,7 @@ def test_eap_peap_ext_cert_check(dev, ap
  
  def test_eap_fast_ext_cert_check(dev, apdev):
      """EAP-FAST and external server certification validation"""
@@ -935,7 +935,7 @@
      check_eap_capa(dev[0], "FAST")
      # With internal server certificate chain validation
      dev[0].request("SET blob fast_pac_auth_ext ")
-@@ -7161,10 +7223,6 @@ def test_eap_fast_ext_cert_check(dev, ap
+@@ -7184,10 +7246,6 @@ def test_eap_fast_ext_cert_check(dev, ap
      run_ext_cert_check(dev, apdev, id)
  
  def run_ext_cert_check(dev, apdev, net_id):
@@ -948,7 +948,7 @@
  
 --- a/tests/hwsim/test_ap_ft.py
 +++ b/tests/hwsim/test_ap_ft.py
-@@ -2471,11 +2471,11 @@ def test_ap_ft_ap_oom5(dev, apdev):
+@@ -2474,11 +2474,11 @@ def test_ap_ft_ap_oom5(dev, apdev):
          # This will fail to roam
          dev[0].roam(bssid1, check_bssid=False)
  
@@ -1138,7 +1138,7 @@
      heavy_groups = [14, 15, 16]
      suitable_groups = [15, 16, 17, 18, 19, 20, 21]
      groups = [str(g) for g in sae_groups]
-@@ -2188,6 +2193,8 @@ def run_sae_pwe_group(dev, apdev, group)
+@@ -2193,6 +2198,8 @@ def run_sae_pwe_group(dev, apdev, group)
              logger.info("Add Brainpool EC groups since OpenSSL is new enough")
          elif tls.startswith("wolfSSL"):
              logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL")
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch
index 710a3c8..b0151b0 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch
@@ -120,7 +120,7 @@
  		 * Convert 80+80 MHz channel width to new style as interop
 --- a/src/common/hw_features_common.c
 +++ b/src/common/hw_features_common.c
-@@ -808,6 +808,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co
+@@ -811,6 +811,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co
  	VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB);
  	VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN);
  	VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN);
@@ -130,7 +130,7 @@
  #undef VHT_CAP_CHECK_MAX
 --- a/src/common/ieee802_11_defs.h
 +++ b/src/common/ieee802_11_defs.h
-@@ -1348,6 +1348,8 @@ struct ieee80211_ampe_ie {
+@@ -1349,6 +1349,8 @@ struct ieee80211_ampe_ie {
  #define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB     ((u32) BIT(26) | BIT(27))
  #define VHT_CAP_RX_ANTENNA_PATTERN                  ((u32) BIT(28))
  #define VHT_CAP_TX_ANTENNA_PATTERN                  ((u32) BIT(29))
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch
deleted file mode 100644
index 7b0435a..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 7 Aug 2023 21:55:57 +0200
-Subject: [PATCH] BSS coloring: fix CCA with multiple BSS
-
-Pass bss->ctx instead of drv->ctx in order to avoid multiple reports for
-the first bss. The first report would otherwise clear hapd->cca_color and
-subsequent reports would cause the iface bss color to be set to 0.
-In order to avoid any issues with cancellations, only overwrite the color
-based on hapd->cca_color if it was actually set.
-
-Fixes: 33c4dd26cd11 ("BSS coloring: Handle the collision and CCA events coming from the kernel")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/src/ap/drv_callbacks.c
-+++ b/src/ap/drv_callbacks.c
-@@ -2260,7 +2260,8 @@ void wpa_supplicant_event(void *ctx, enu
- 	case EVENT_CCA_NOTIFY:
- 		wpa_printf(MSG_DEBUG, "CCA finished on on %s",
- 			   hapd->conf->iface);
--		hapd->iface->conf->he_op.he_bss_color = hapd->cca_color;
-+		if (hapd->cca_color)
-+			hapd->iface->conf->he_op.he_bss_color = hapd->cca_color;
- 		hostapd_cleanup_cca_params(hapd);
- 		break;
- #endif /* CONFIG_IEEE80211AX */
---- a/src/drivers/driver_nl80211_event.c
-+++ b/src/drivers/driver_nl80211_event.c
-@@ -3653,7 +3653,7 @@ static void nl80211_assoc_comeback(struc
- 
- #ifdef CONFIG_IEEE80211AX
- 
--static void nl80211_obss_color_collision(struct wpa_driver_nl80211_data *drv,
-+static void nl80211_obss_color_collision(struct i802_bss *bss,
- 					 struct nlattr *tb[])
- {
- 	union wpa_event_data data;
-@@ -3667,37 +3667,37 @@ static void nl80211_obss_color_collision
- 
- 	wpa_printf(MSG_DEBUG, "nl80211: BSS color collision - bitmap %08llx",
- 		   (long long unsigned int) data.bss_color_collision.bitmap);
--	wpa_supplicant_event(drv->ctx, EVENT_BSS_COLOR_COLLISION, &data);
-+	wpa_supplicant_event(bss->ctx, EVENT_BSS_COLOR_COLLISION, &data);
- }
- 
- 
- static void
--nl80211_color_change_announcement_started(struct wpa_driver_nl80211_data *drv)
-+nl80211_color_change_announcement_started(struct i802_bss *bss)
- {
- 	union wpa_event_data data = {};
- 
- 	wpa_printf(MSG_DEBUG, "nl80211: CCA started");
--	wpa_supplicant_event(drv->ctx, EVENT_CCA_STARTED_NOTIFY, &data);
-+	wpa_supplicant_event(bss->ctx, EVENT_CCA_STARTED_NOTIFY, &data);
- }
- 
- 
- static void
--nl80211_color_change_announcement_aborted(struct wpa_driver_nl80211_data *drv)
-+nl80211_color_change_announcement_aborted(struct i802_bss *bss)
- {
- 	union wpa_event_data data = {};
- 
- 	wpa_printf(MSG_DEBUG, "nl80211: CCA aborted");
--	wpa_supplicant_event(drv->ctx, EVENT_CCA_ABORTED_NOTIFY, &data);
-+	wpa_supplicant_event(bss->ctx, EVENT_CCA_ABORTED_NOTIFY, &data);
- }
- 
- 
- static void
--nl80211_color_change_announcement_completed(struct wpa_driver_nl80211_data *drv)
-+nl80211_color_change_announcement_completed(struct i802_bss *bss)
- {
- 	union wpa_event_data data = {};
- 
- 	wpa_printf(MSG_DEBUG, "nl80211: CCA completed");
--	wpa_supplicant_event(drv->ctx, EVENT_CCA_NOTIFY, &data);
-+	wpa_supplicant_event(bss->ctx, EVENT_CCA_NOTIFY, &data);
- }
- 
- #endif /* CONFIG_IEEE80211AX */
-@@ -3957,16 +3957,16 @@ static void do_process_drv_event(struct
- 		break;
- #ifdef CONFIG_IEEE80211AX
- 	case NL80211_CMD_OBSS_COLOR_COLLISION:
--		nl80211_obss_color_collision(drv, tb);
-+		nl80211_obss_color_collision(bss, tb);
- 		break;
- 	case NL80211_CMD_COLOR_CHANGE_STARTED:
--		nl80211_color_change_announcement_started(drv);
-+		nl80211_color_change_announcement_started(bss);
- 		break;
- 	case NL80211_CMD_COLOR_CHANGE_ABORTED:
--		nl80211_color_change_announcement_aborted(drv);
-+		nl80211_color_change_announcement_aborted(bss);
- 		break;
- 	case NL80211_CMD_COLOR_CHANGE_COMPLETED:
--		nl80211_color_change_announcement_completed(drv);
-+		nl80211_color_change_announcement_completed(bss);
- 		break;
- #endif /* CONFIG_IEEE80211AX */
- 	default:
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch
new file mode 100644
index 0000000..4929c58
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch
@@ -0,0 +1,20 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 14 Sep 2023 10:53:50 +0200
+Subject: [PATCH] driver_nl80211: fix setting QoS map on secondary BSSs
+
+The setting is per-BSS, not per PHY
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -11341,7 +11341,7 @@ static int nl80211_set_qos_map(void *pri
+ 	wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
+ 		    qos_map_set, qos_map_set_len);
+ 
+-	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_QOS_MAP)) ||
++	if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_QOS_MAP)) ||
+ 	    nla_put(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set)) {
+ 		nlmsg_free(msg);
+ 		return -ENOBUFS;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch
new file mode 100644
index 0000000..adfb21f
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch
@@ -0,0 +1,18 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 14 Sep 2023 11:28:03 +0200
+Subject: [PATCH] driver_nl80211: update drv->ifindex on removing the first
+ BSS
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -8867,6 +8867,7 @@ static int wpa_driver_nl80211_if_remove(
+ 		if (drv->first_bss->next) {
+ 			drv->first_bss = drv->first_bss->next;
+ 			drv->ctx = drv->first_bss->ctx;
++			drv->ifindex = drv->first_bss->ifindex;
+ 			os_free(bss);
+ 		} else {
+ 			wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch
new file mode 100644
index 0000000..395c645
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch
@@ -0,0 +1,34 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 18 Sep 2023 16:47:41 +0200
+Subject: [PATCH] nl80211: move nl80211_put_freq_params call outside of
+ 802.11ax #ifdef
+
+The relevance of this call is not specific to 802.11ax, so it should be done
+even with CONFIG_IEEE80211AX disabled.
+
+Fixes: b3921db426ea ("nl80211: Add frequency info in start AP command")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -5226,6 +5226,9 @@ static int wpa_driver_nl80211_set_ap(voi
+ 		nla_nest_end(msg, ftm);
+ 	}
+ 
++	if (params->freq && nl80211_put_freq_params(msg, params->freq) < 0)
++		goto fail;
++
+ #ifdef CONFIG_IEEE80211AX
+ 	if (params->he_spr_ctrl) {
+ 		struct nlattr *spr;
+@@ -5260,9 +5263,6 @@ static int wpa_driver_nl80211_set_ap(voi
+ 		nla_nest_end(msg, spr);
+ 	}
+ 
+-	if (params->freq && nl80211_put_freq_params(msg, params->freq) < 0)
+-		goto fail;
+-
+ 	if (params->freq && params->freq->he_enabled) {
+ 		struct nlattr *bss_color;
+ 
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch
new file mode 100644
index 0000000..fe81318
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch
@@ -0,0 +1,28 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 20 Sep 2023 13:41:10 +0200
+Subject: [PATCH] hostapd: cancel channel_list_update_timeout in
+ hostapd_cleanup_iface_partial
+
+Fixes a crash when disabling an interface during channel list update
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -569,6 +569,7 @@ static void sta_track_deinit(struct host
+ void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
+ {
+ 	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
++	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
+ #ifdef NEED_AP_MLME
+ 	hostapd_stop_setup_timers(iface);
+ #endif /* NEED_AP_MLME */
+@@ -598,7 +599,6 @@ void hostapd_cleanup_iface_partial(struc
+ static void hostapd_cleanup_iface(struct hostapd_iface *iface)
+ {
+ 	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+-	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
+ 	eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
+ 			     NULL);
+ 
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/200-multicall.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/200-multicall.patch
index 8ebbed0..e3ed00f 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/200-multicall.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/200-multicall.patch
@@ -156,7 +156,7 @@
  wpa_cli.exe: wpa_cli
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -6651,8 +6651,8 @@ union wpa_event_data {
+@@ -6667,8 +6667,8 @@ union wpa_event_data {
   * Driver wrapper code should call this function whenever an event is received
   * from the driver.
   */
@@ -167,7 +167,7 @@
  
  /**
   * wpa_supplicant_event_global - Report a driver event for wpa_supplicant
-@@ -6664,7 +6664,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -6680,7 +6680,7 @@ void wpa_supplicant_event(void *ctx, enu
   * Same as wpa_supplicant_event(), but we search for the interface in
   * wpa_global.
   */
@@ -178,7 +178,7 @@
  /*
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -1994,8 +1994,8 @@ err:
+@@ -2184,8 +2184,8 @@ err:
  #endif /* CONFIG_OWE */
  
  
@@ -189,7 +189,7 @@
  {
  	struct hostapd_data *hapd = ctx;
  #ifndef CONFIG_NO_STDOUT_DEBUG
-@@ -2272,7 +2272,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -2489,7 +2489,7 @@ void wpa_supplicant_event(void *ctx, enu
  }
  
  
@@ -231,7 +231,7 @@
  	os_memset(&global, 0, sizeof(global));
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
-@@ -5345,8 +5345,8 @@ static void wpas_link_reconfig(struct wp
+@@ -5353,8 +5353,8 @@ static void wpas_link_reconfig(struct wp
  }
  
  
@@ -242,7 +242,7 @@
  {
  	struct wpa_supplicant *wpa_s = ctx;
  	int resched;
-@@ -6264,7 +6264,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -6272,7 +6272,7 @@ void wpa_supplicant_event(void *ctx, enu
  }
  
  
@@ -253,7 +253,7 @@
  	struct wpa_supplicant *wpa_s;
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -7435,7 +7435,6 @@ struct wpa_interface * wpa_supplicant_ma
+@@ -7462,7 +7462,6 @@ struct wpa_interface * wpa_supplicant_ma
  	return NULL;
  }
  
@@ -261,7 +261,7 @@
  /**
   * wpa_supplicant_match_existing - Match existing interfaces
   * @global: Pointer to global data from wpa_supplicant_init()
-@@ -7470,6 +7469,11 @@ static int wpa_supplicant_match_existing
+@@ -7497,6 +7496,11 @@ static int wpa_supplicant_match_existing
  
  #endif /* CONFIG_MATCH_IFACE */
  
@@ -273,7 +273,7 @@
  
  /**
   * wpa_supplicant_add_iface - Add a new network interface
-@@ -7726,6 +7730,8 @@ struct wpa_global * wpa_supplicant_init(
+@@ -7753,6 +7757,8 @@ struct wpa_global * wpa_supplicant_init(
  #ifndef CONFIG_NO_WPA_MSG
  	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
  #endif /* CONFIG_NO_WPA_MSG */
@@ -284,7 +284,7 @@
  		wpa_debug_open_file(params->wpa_debug_file_path);
 --- a/hostapd/main.c
 +++ b/hostapd/main.c
-@@ -685,6 +685,11 @@ fail:
+@@ -698,6 +698,11 @@ fail:
  	return -1;
  }
  
@@ -296,7 +296,7 @@
  
  #ifdef CONFIG_WPS
  static int gen_uuid(const char *txt_addr)
-@@ -778,6 +783,8 @@ int main(int argc, char *argv[])
+@@ -791,6 +796,8 @@ int main(int argc, char *argv[])
  		return -1;
  #endif /* CONFIG_DPP */
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/300-noscan.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/300-noscan.patch
index 1ea8904..3b5f432 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/300-noscan.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/300-noscan.patch
@@ -13,7 +13,7 @@
  	} else if (os_strcmp(buf, "ht_capab") == 0) {
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1072,6 +1072,8 @@ struct hostapd_config {
+@@ -1075,6 +1075,8 @@ struct hostapd_config {
  
  	int ht_op_mode_fixed;
  	u16 ht_capab;
@@ -24,7 +24,7 @@
  	int no_pri_sec_switch;
 --- a/src/ap/hw_features.c
 +++ b/src/ap/hw_features.c
-@@ -517,7 +517,8 @@ static int ieee80211n_check_40mhz(struct
+@@ -546,7 +546,8 @@ static int ieee80211n_check_40mhz(struct
  	int ret;
  
  	/* Check that HT40 is used and PRI / SEC switch is allowed */
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/310-rescan_immediately.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/310-rescan_immediately.patch
index a47546d..e12b205 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/310-rescan_immediately.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/310-rescan_immediately.patch
@@ -1,6 +1,6 @@
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -5740,7 +5740,7 @@ wpa_supplicant_alloc(struct wpa_supplica
+@@ -5767,7 +5767,7 @@ wpa_supplicant_alloc(struct wpa_supplica
  	if (wpa_s == NULL)
  		return NULL;
  	wpa_s->scan_req = INITIAL_SCAN_REQ;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/380-disable_ctrl_iface_mib.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/380-disable_ctrl_iface_mib.patch
index 54a736f..f7720fc 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/380-disable_ctrl_iface_mib.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/380-disable_ctrl_iface_mib.patch
@@ -51,7 +51,7 @@
  		if (wpa_s->ap_iface) {
  			pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
  							    end - pos,
-@@ -11964,6 +11964,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12087,6 +12087,7 @@ char * wpa_supplicant_ctrl_iface_process
  			reply_len = -1;
  	} else if (os_strncmp(buf, "NOTE ", 5) == 0) {
  		wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
@@ -59,7 +59,7 @@
  	} else if (os_strcmp(buf, "MIB") == 0) {
  		reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
  		if (reply_len >= 0) {
-@@ -11976,6 +11977,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12099,6 +12100,7 @@ char * wpa_supplicant_ctrl_iface_process
  				reply_size - reply_len);
  #endif /* CONFIG_MACSEC */
  		}
@@ -67,7 +67,7 @@
  	} else if (os_strncmp(buf, "STATUS", 6) == 0) {
  		reply_len = wpa_supplicant_ctrl_iface_status(
  			wpa_s, buf + 6, reply, reply_size);
-@@ -12464,6 +12466,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12587,6 +12589,7 @@ char * wpa_supplicant_ctrl_iface_process
  		reply_len = wpa_supplicant_ctrl_iface_bss(
  			wpa_s, buf + 4, reply, reply_size);
  #ifdef CONFIG_AP
@@ -75,7 +75,7 @@
  	} else if (os_strcmp(buf, "STA-FIRST") == 0) {
  		reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
  	} else if (os_strncmp(buf, "STA ", 4) == 0) {
-@@ -12472,12 +12475,15 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12595,12 +12598,15 @@ char * wpa_supplicant_ctrl_iface_process
  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
  		reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
  						   reply_size);
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/390-wpa_ie_cap_workaround.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/390-wpa_ie_cap_workaround.patch
index 40c39ff..4592c34 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/390-wpa_ie_cap_workaround.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/390-wpa_ie_cap_workaround.patch
@@ -1,6 +1,6 @@
 --- a/src/common/wpa_common.c
 +++ b/src/common/wpa_common.c
-@@ -2719,6 +2719,31 @@ u32 wpa_akm_to_suite(int akm)
+@@ -2841,6 +2841,31 @@ u32 wpa_akm_to_suite(int akm)
  }
  
  
@@ -32,7 +32,7 @@
  int wpa_compare_rsn_ie(int ft_initial_assoc,
  		       const u8 *ie1, size_t ie1len,
  		       const u8 *ie2, size_t ie2len)
-@@ -2726,8 +2751,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
+@@ -2848,8 +2873,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
  	if (ie1 == NULL || ie2 == NULL)
  		return -1;
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/420-indicate-features.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/420-indicate-features.patch
index 3b28b6e..07df8e5 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/420-indicate-features.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/420-indicate-features.patch
@@ -9,7 +9,7 @@
  
  struct hapd_global {
  	void **drv_priv;
-@@ -786,7 +786,7 @@ int main(int argc, char *argv[])
+@@ -799,7 +799,7 @@ int main(int argc, char *argv[])
  	wpa_supplicant_event = hostapd_wpa_event;
  	wpa_supplicant_event_global = hostapd_wpa_event_global;
  	for (;;) {
@@ -18,7 +18,7 @@
  		if (c < 0)
  			break;
  		switch (c) {
-@@ -823,6 +823,8 @@ int main(int argc, char *argv[])
+@@ -836,6 +836,8 @@ int main(int argc, char *argv[])
  			break;
  #endif /* CONFIG_DEBUG_LINUX_TRACING */
  		case 'v':
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
index e50c609..c6fe54e 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
@@ -174,7 +174,7 @@
  	 * macsec_policy - Determines the policy for MACsec secure session
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -4149,6 +4149,12 @@ static void wpas_start_assoc_cb(struct w
+@@ -4175,6 +4175,12 @@ static void wpas_start_assoc_cb(struct w
  			params.beacon_int = ssid->beacon_int;
  		else
  			params.beacon_int = wpa_s->conf->beacon_int;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/463-add-mcast_rate-to-11s.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/463-add-mcast_rate-to-11s.patch
index be9e050..daa36c2 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/463-add-mcast_rate-to-11s.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/463-add-mcast_rate-to-11s.patch
@@ -29,7 +29,7 @@
  struct wpa_driver_set_key_params {
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -11626,6 +11626,18 @@ static int nl80211_put_mesh_id(struct nl
+@@ -11667,6 +11667,18 @@ static int nl80211_put_mesh_id(struct nl
  }
  
  
@@ -48,7 +48,7 @@
  static int nl80211_put_mesh_config(struct nl_msg *msg,
  				   struct wpa_driver_mesh_bss_params *params)
  {
-@@ -11687,6 +11699,7 @@ static int nl80211_join_mesh(struct i802
+@@ -11728,6 +11740,7 @@ static int nl80211_join_mesh(struct i802
  	    nl80211_put_basic_rates(msg, params->basic_rates) ||
  	    nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
  	    nl80211_put_beacon_int(msg, params->beacon_int) ||
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/600-ubus_support.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/600-ubus_support.patch
index 5b2745a..bc80ef0 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/600-ubus_support.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/600-ubus_support.patch
@@ -84,7 +84,7 @@
  		   __func__, driver, drv_priv);
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -2778,7 +2778,7 @@ static void handle_auth(struct hostapd_d
+@@ -2786,7 +2786,7 @@ static void handle_auth(struct hostapd_d
  	u16 auth_alg, auth_transaction, status_code;
  	u16 resp = WLAN_STATUS_SUCCESS;
  	struct sta_info *sta = NULL;
@@ -93,7 +93,7 @@
  	u16 fc;
  	const u8 *challenge = NULL;
  	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
-@@ -2787,6 +2787,11 @@ static void handle_auth(struct hostapd_d
+@@ -2795,6 +2795,11 @@ static void handle_auth(struct hostapd_d
  	struct radius_sta rad_info;
  	const u8 *dst, *sa, *bssid;
  	bool mld_sta = false;
@@ -105,7 +105,7 @@
  
  	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
  		wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
-@@ -2978,6 +2983,13 @@ static void handle_auth(struct hostapd_d
+@@ -2986,6 +2991,13 @@ static void handle_auth(struct hostapd_d
  		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
  		goto fail;
  	}
@@ -119,7 +119,7 @@
  	if (res == HOSTAPD_ACL_PENDING)
  		return;
  
-@@ -5141,7 +5153,7 @@ static void handle_assoc(struct hostapd_
+@@ -5161,7 +5173,7 @@ static void handle_assoc(struct hostapd_
  	int resp = WLAN_STATUS_SUCCESS;
  	u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
  	const u8 *pos;
@@ -128,7 +128,7 @@
  	struct sta_info *sta;
  	u8 *tmp = NULL;
  #ifdef CONFIG_FILS
-@@ -5354,6 +5366,11 @@ static void handle_assoc(struct hostapd_
+@@ -5374,6 +5386,11 @@ static void handle_assoc(struct hostapd_
  		left = res;
  	}
  #endif /* CONFIG_FILS */
@@ -140,7 +140,7 @@
  
  	/* followed by SSID and Supported rates; and HT capabilities if 802.11n
  	 * is used */
-@@ -5452,6 +5469,13 @@ static void handle_assoc(struct hostapd_
+@@ -5472,6 +5489,13 @@ static void handle_assoc(struct hostapd_
  	}
  #endif /* CONFIG_FILS */
  
@@ -154,7 +154,7 @@
   fail:
  
  	/*
-@@ -5733,6 +5757,7 @@ static void handle_disassoc(struct hosta
+@@ -5753,6 +5777,7 @@ static void handle_disassoc(struct hosta
  			   (unsigned long) len);
  		return;
  	}
@@ -162,7 +162,7 @@
  
  	sta = ap_get_sta(hapd, mgmt->sa);
  	if (!sta) {
-@@ -5764,6 +5789,8 @@ static void handle_deauth(struct hostapd
+@@ -5784,6 +5809,8 @@ static void handle_deauth(struct hostapd
  	/* Clear the PTKSA cache entries for PASN */
  	ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
  
@@ -201,7 +201,7 @@
  
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -260,6 +260,10 @@ int hostapd_notif_assoc(struct hostapd_d
  	u16 reason = WLAN_REASON_UNSPECIFIED;
  	int status = WLAN_STATUS_SUCCESS;
  	const u8 *p2p_dev_addr = NULL;
@@ -212,7 +212,7 @@
  
  	if (addr == NULL) {
  		/*
-@@ -237,6 +241,12 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -396,6 +400,12 @@ int hostapd_notif_assoc(struct hostapd_d
  		goto fail;
  	}
  
@@ -348,7 +348,7 @@
  CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -7566,6 +7566,8 @@ struct wpa_supplicant * wpa_supplicant_a
+@@ -7593,6 +7593,8 @@ struct wpa_supplicant * wpa_supplicant_a
  	}
  #endif /* CONFIG_P2P */
  
@@ -357,7 +357,7 @@
  	return wpa_s;
  }
  
-@@ -7592,6 +7594,8 @@ int wpa_supplicant_remove_iface(struct w
+@@ -7619,6 +7621,8 @@ int wpa_supplicant_remove_iface(struct w
  	struct wpa_supplicant *parent = wpa_s->parent;
  #endif /* CONFIG_MESH */
  
@@ -366,7 +366,7 @@
  	/* Remove interface from the global list of interfaces */
  	prev = global->ifaces;
  	if (prev == wpa_s) {
-@@ -7938,8 +7942,12 @@ int wpa_supplicant_run(struct wpa_global
+@@ -7965,8 +7969,12 @@ int wpa_supplicant_run(struct wpa_global
  	eloop_register_signal_terminate(wpa_supplicant_terminate, global);
  	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
  
@@ -398,7 +398,7 @@
  };
  
  
-@@ -650,6 +653,7 @@ struct wpa_supplicant {
+@@ -685,6 +688,7 @@ struct wpa_supplicant {
  	unsigned char own_addr[ETH_ALEN];
  	unsigned char perm_addr[ETH_ALEN];
  	char ifname[100];
@@ -508,7 +508,7 @@
  
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1211,6 +1211,8 @@ int hostapd_dfs_pre_cac_expired(struct h
+@@ -1216,6 +1216,8 @@ int hostapd_dfs_pre_cac_expired(struct h
  		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
  		freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
  
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 e0bbf13..de182b9 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
@@ -26,7 +26,7 @@
  ifdef CONFIG_CODE_COVERAGE
 --- a/hostapd/main.c
 +++ b/hostapd/main.c
-@@ -994,6 +994,7 @@ int main(int argc, char *argv[])
+@@ -1007,6 +1007,7 @@ int main(int argc, char *argv[])
  	}
  
  	hostapd_global_ctrl_iface_init(&interfaces);
@@ -34,7 +34,7 @@
  
  	if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
  		wpa_printf(MSG_ERROR, "Failed to start eloop");
-@@ -1003,6 +1004,7 @@ int main(int argc, char *argv[])
+@@ -1016,6 +1017,7 @@ int main(int argc, char *argv[])
  	ret = 0;
  
   out:
@@ -107,14 +107,14 @@
  	hostapd_ubus_free_bss(hapd);
  	accounting_deinit(hapd);
  	hostapd_deinit_wpa(hapd);
-@@ -599,6 +602,7 @@ void hostapd_cleanup_iface_partial(struc
+@@ -600,6 +603,7 @@ void hostapd_cleanup_iface_partial(struc
  static void hostapd_cleanup_iface(struct hostapd_iface *iface)
  {
  	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
 +	hostapd_ucode_free_iface(iface);
- 	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
  	eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
  			     NULL);
+ 
 @@ -1189,6 +1193,7 @@ static int hostapd_start_beacon(struct h
  		hapd->driver->set_operstate(hapd->drv_priv, 1);
  
@@ -142,6 +142,16 @@
  {
  	if (!hapd)
  		return;
+@@ -3491,7 +3495,8 @@ int hostapd_remove_iface(struct hapd_int
+ 		hapd_iface = interfaces->iface[i];
+ 		if (hapd_iface == NULL)
+ 			return -1;
+-		if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
++		if (!os_strcmp(hapd_iface->phy, buf) ||
++		    !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
+ 			wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
+ 			hapd_iface->driver_ap_teardown =
+ 				!!(hapd_iface->drv_flags &
 --- a/wpa_supplicant/Makefile
 +++ b/wpa_supplicant/Makefile
 @@ -195,8 +195,20 @@ endif
@@ -186,7 +196,7 @@
  
  #ifdef CONFIG_BGSCAN
  	if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid)
-@@ -7567,6 +7568,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);
@@ -194,7 +204,7 @@
  
  	return wpa_s;
  }
-@@ -7594,6 +7596,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 */
  
@@ -202,7 +212,7 @@
  	wpas_ubus_free_bss(wpa_s);
  
  	/* Remove interface from the global list of interfaces */
-@@ -7904,6 +7907,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);
@@ -210,7 +220,7 @@
  
  	return global;
  }
-@@ -7942,12 +7946,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);
  
@@ -223,7 +233,7 @@
  	return 0;
  }
  
-@@ -7980,6 +7980,8 @@ void wpa_supplicant_deinit(struct wpa_gl
+@@ -8007,6 +8007,8 @@ void wpa_supplicant_deinit(struct wpa_gl
  
  	wpas_notify_supplicant_deinitialized(global);
  
@@ -242,7 +252,7 @@
  
  extern const char *const wpa_supplicant_version;
  extern const char *const wpa_supplicant_license;
-@@ -654,6 +655,7 @@ struct wpa_supplicant {
+@@ -689,6 +690,7 @@ struct wpa_supplicant {
  	unsigned char perm_addr[ETH_ALEN];
  	char ifname[100];
  	struct wpas_ubus_bss ubus;
@@ -270,7 +280,33 @@
  
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -6426,6 +6426,7 @@ union wpa_event_data {
+@@ -3787,6 +3787,25 @@ struct wpa_driver_ops {
+ 			 const char *ifname);
+ 
+ 	/**
++	 * if_rename - Rename a virtual interface
++	 * @priv: Private driver interface data
++	 * @type: Interface type
++	 * @ifname: Interface name of the virtual interface to be renamed
++	 *	    (NULL when renaming the AP BSS interface)
++	 * @new_name: New interface name of the virtual interface
++	 * Returns: 0 on success, -1 on failure
++	 */
++	int (*if_rename)(void *priv, enum wpa_driver_if_type type,
++			 const char *ifname, const char *new_name);
++
++	/**
++	 * set_first_bss - Make a virtual interface the first (primary) bss
++	 * @priv: Private driver interface data
++	 * Returns: 0 on success, -1 on failure
++	 */
++	int (*set_first_bss)(void *priv);
++
++	/**
+ 	 * set_sta_vlan - Bind a station into a specific interface (AP only)
+ 	 * @priv: Private driver interface data
+ 	 * @ifname: Interface (main or virtual BSS or VLAN)
+@@ -6440,6 +6459,7 @@ union wpa_event_data {
  
  	/**
  	 * struct ch_switch
@@ -278,7 +314,7 @@
  	 * @freq: Frequency of new channel in MHz
  	 * @ht_enabled: Whether this is an HT channel
  	 * @ch_offset: Secondary channel offset
-@@ -6436,6 +6437,7 @@ union wpa_event_data {
+@@ -6450,6 +6470,7 @@ union wpa_event_data {
  	 * @punct_bitmap: Puncturing bitmap
  	 */
  	struct ch_switch {
@@ -305,7 +341,7 @@
  
  	if (finished)
  		bss->flink->freq = data.ch_switch.freq;
-@@ -3848,6 +3851,7 @@ static void do_process_drv_event(struct
+@@ -3912,6 +3915,7 @@ static void do_process_drv_event(struct
  				     tb[NL80211_ATTR_CENTER_FREQ1],
  				     tb[NL80211_ATTR_CENTER_FREQ2],
  				     tb[NL80211_ATTR_PUNCT_BITMAP],
@@ -313,7 +349,7 @@
  				     0);
  		break;
  	case NL80211_CMD_CH_SWITCH_NOTIFY:
-@@ -3860,6 +3864,7 @@ static void do_process_drv_event(struct
+@@ -3924,6 +3928,7 @@ static void do_process_drv_event(struct
  				     tb[NL80211_ATTR_CENTER_FREQ1],
  				     tb[NL80211_ATTR_CENTER_FREQ2],
  				     tb[NL80211_ATTR_PUNCT_BITMAP],
@@ -323,7 +359,7 @@
  	case NL80211_CMD_DISCONNECT:
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
-@@ -5381,6 +5381,7 @@ void supplicant_event(void *ctx, enum wp
+@@ -5389,6 +5389,7 @@ void supplicant_event(void *ctx, enum wp
  		event_to_string(event), event);
  #endif /* CONFIG_NO_STDOUT_DEBUG */
  
@@ -331,3 +367,187 @@
  	switch (event) {
  	case EVENT_AUTH:
  #ifdef CONFIG_FST
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -393,6 +393,23 @@ static inline int hostapd_drv_stop_ap(st
+ 	return hapd->driver->stop_ap(hapd->drv_priv);
+ }
+ 
++static inline int hostapd_drv_if_rename(struct hostapd_data *hapd,
++					enum wpa_driver_if_type type,
++					const char *ifname,
++					const char *new_name)
++{
++	if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv)
++		return -1;
++	return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name);
++}
++
++static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd)
++{
++	if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv)
++		return 0;
++	return hapd->driver->set_first_bss(hapd->drv_priv);
++}
++
+ static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
+ 					   struct wpa_channel_info *ci)
+ {
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -1333,7 +1333,7 @@ static void wpa_driver_nl80211_event_rtm
+ 		}
+ 		wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
+ 			   namebuf, ifname);
+-		if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
++		if (drv->first_bss->ifindex != ifi->ifi_index) {
+ 			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
+ 		}
+ 		wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
+ 			   namebuf, ifname);
+-		if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
++		if (drv->first_bss->ifindex != ifi->ifi_index) {
+ 			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
+ 	char master_ifname[IFNAMSIZ];
+ 	int ifindex, br_ifindex = 0;
+ 	int br_added = 0;
++	int err;
+ 
+ 	bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
+ 					  params->global_priv, 1,
+@@ -8491,21 +8492,17 @@ static void *i802_init(struct hostapd_da
+ 	    (params->num_bridge == 0 || !params->bridge[0]))
+ 		add_ifidx(drv, br_ifindex, drv->ifindex);
+ 
+-	if (bss->added_if_into_bridge || bss->already_in_bridge) {
+-		int err;
+-
+-		drv->rtnl_sk = nl_socket_alloc();
+-		if (drv->rtnl_sk == NULL) {
+-			wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
+-			goto failed;
+-		}
++	drv->rtnl_sk = nl_socket_alloc();
++	if (drv->rtnl_sk == NULL) {
++		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
++		goto failed;
++	}
+ 
+-		err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
+-		if (err) {
+-			wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
+-				   nl_geterror(err));
+-			goto failed;
+-		}
++	err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
++	if (err) {
++		wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
++			   nl_geterror(err));
++		goto failed;
+ 	}
+ 
+ 	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
+@@ -8875,6 +8872,50 @@ static int wpa_driver_nl80211_if_remove(
+ 	return 0;
+ }
+ 
++static int wpa_driver_nl80211_if_rename(struct i802_bss *bss,
++					enum wpa_driver_if_type type,
++					const char *ifname, const char *new_name)
++{
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct ifinfomsg ifi = {
++		.ifi_family = AF_UNSPEC,
++		.ifi_index = bss->ifindex,
++	};
++	struct nl_msg *msg;
++	int res = -ENOMEM;
++
++	if (ifname)
++		ifi.ifi_index = if_nametoindex(ifname);
++
++	msg = nlmsg_alloc_simple(RTM_SETLINK, 0);
++	if (!msg)
++		return res;
++
++	if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
++		goto out;
++
++	if (nla_put_string(msg, IFLA_IFNAME, new_name))
++		goto out;
++
++	res = nl_send_auto_complete(drv->rtnl_sk, msg);
++	if (res < 0)
++		goto out;
++
++	res = nl_wait_for_ack(drv->rtnl_sk);
++	if (res) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Renaming device %s to %s failed: %s",
++			   ifname ? ifname : bss->ifname, new_name, nl_geterror(res));
++		goto out;
++	}
++
++	if (type == WPA_IF_AP_BSS && !ifname)
++		os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname));
++
++out:
++	nlmsg_free(msg);
++	return res;
++}
+ 
+ static int cookie_handler(struct nl_msg *msg, void *arg)
+ {
+@@ -10513,6 +10554,37 @@ static int driver_nl80211_if_remove(void
+ }
+ 
+ 
++static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type,
++				    const char *ifname, const char *new_name)
++{
++	struct i802_bss *bss = priv;
++	return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name);
++}
++
++
++static int driver_nl80211_set_first_bss(void *priv)
++{
++	struct i802_bss *bss = priv, *tbss;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++
++	if (drv->first_bss == bss)
++		return 0;
++
++	for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
++		if (tbss->next != bss)
++			continue;
++
++		tbss->next = bss->next;
++		bss->next = drv->first_bss;
++		drv->first_bss = bss;
++		drv->ctx = bss->ctx;
++		return 0;
++	}
++
++	return -1;
++}
++
++
+ 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
+ 	.set_acl = wpa_driver_nl80211_set_acl,
+ 	.if_add = wpa_driver_nl80211_if_add,
+ 	.if_remove = driver_nl80211_if_remove,
++	.if_rename = driver_nl80211_if_rename,
++	.set_first_bss = driver_nl80211_set_first_bss,
+ 	.send_mlme = driver_nl80211_send_mlme,
+ 	.get_hw_feature_data = nl80211_get_hw_feature_data,
+ 	.sta_add = wpa_driver_nl80211_sta_add,
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/701-reload_config_inline.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/701-reload_config_inline.patch
index 44c8892..3c62bf6 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/701-reload_config_inline.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/701-reload_config_inline.patch
@@ -1,6 +1,6 @@
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4810,7 +4810,12 @@ struct hostapd_config * hostapd_config_r
+@@ -4816,7 +4816,12 @@ struct hostapd_config * hostapd_config_r
  	int errors = 0;
  	size_t i;
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/720-iface_max_num_sta.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/720-iface_max_num_sta.patch
index 1aa4456..089c1dd 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/720-iface_max_num_sta.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/720-iface_max_num_sta.patch
@@ -70,7 +70,7 @@
  			   " since no room for additional STA",
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1036,6 +1036,8 @@ struct hostapd_config {
+@@ -1039,6 +1039,8 @@ struct hostapd_config {
  	unsigned int track_sta_max_num;
  	unsigned int track_sta_max_age;
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/740-snoop_iface.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/740-snoop_iface.patch
index 6b6cc0f..ce64513 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/740-snoop_iface.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/740-snoop_iface.patch
@@ -10,7 +10,7 @@
  	int bridge_hairpin; /* hairpin_mode on bridge members */
 --- a/src/ap/x_snoop.c
 +++ b/src/ap/x_snoop.c
-@@ -33,14 +33,16 @@ int x_snoop_init(struct hostapd_data *ha
+@@ -33,28 +33,31 @@ int x_snoop_init(struct hostapd_data *ha
  
  	hapd->x_snoop_initialized = true;
  
@@ -29,13 +29,20 @@
  		wpa_printf(MSG_DEBUG,
  			   "x_snoop: Failed to enable proxyarp on the bridge port");
  		return -1;
-@@ -54,7 +56,8 @@ int x_snoop_init(struct hostapd_data *ha
  	}
  
+ 	if (hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT,
+-					 1)) {
++					 conf->snoop_iface[0] ? conf->snoop_iface : NULL, 1)) {
+ 		wpa_printf(MSG_DEBUG,
+ 			   "x_snoop: Failed to enable accepting gratuitous ARP on the bridge");
+ 		return -1;
+ 	}
+ 
  #ifdef CONFIG_IPV6
 -	if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) {
 +	if (!conf->snoop_iface[0] &&
-+	    hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) {
++	    hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, NULL, 1)) {
  		wpa_printf(MSG_DEBUG,
  			   "x_snoop: Failed to enable multicast snooping on the bridge");
  		return -1;
@@ -44,15 +51,29 @@
  	struct hostapd_bss_config *conf = hapd->conf;
  	struct l2_packet_data *l2;
 +	const char *ifname = conf->bridge;
- 
--	l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1);
++
 +	if (conf->snoop_iface[0])
 +		ifname = conf->snoop_iface;
-+
+ 
+-	l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1);
 +	l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1);
  	if (l2 == NULL) {
  		wpa_printf(MSG_DEBUG,
  			   "x_snoop: Failed to initialize L2 packet processing %s",
+@@ -127,9 +134,12 @@ void x_snoop_mcast_to_ucast_convert_send
+ 
+ void x_snoop_deinit(struct hostapd_data *hapd)
+ {
++	struct hostapd_bss_config *conf = hapd->conf;
++
+ 	if (!hapd->x_snoop_initialized)
+ 		return;
+-	hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, 0);
++	hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT,
++				     conf->snoop_iface[0] ? conf->snoop_iface : NULL, 0);
+ 	hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 0);
+ 	hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 0);
+ 	hapd->x_snoop_initialized = false;
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
 @@ -2322,6 +2322,8 @@ static int hostapd_config_fill(struct ho
@@ -64,3 +85,55 @@
  	} else if (os_strcmp(buf, "vlan_bridge") == 0) {
  		os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
  	} else if (os_strcmp(buf, "wds_bridge") == 0) {
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -366,12 +366,12 @@ static inline int hostapd_drv_br_port_se
+ 
+ static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd,
+ 					       enum drv_br_net_param param,
+-					       unsigned int val)
++					       const char *ifname, unsigned int val)
+ {
+ 	if (hapd->driver == NULL || hapd->drv_priv == NULL ||
+ 	    hapd->driver->br_set_net_param == NULL)
+ 		return -1;
+-	return hapd->driver->br_set_net_param(hapd->drv_priv, param, val);
++	return hapd->driver->br_set_net_param(hapd->drv_priv, param, ifname, val);
+ }
+ 
+ static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd,
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -4209,7 +4209,7 @@ struct wpa_driver_ops {
+ 	 * Returns: 0 on success, negative (<0) on failure
+ 	 */
+ 	int (*br_set_net_param)(void *priv, enum drv_br_net_param param,
+-				unsigned int val);
++				const char *ifname, unsigned int val);
+ 
+ 	/**
+ 	 * get_wowlan - Get wake-on-wireless status
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -12168,7 +12168,7 @@ static const char * drv_br_net_param_str
+ 
+ 
+ static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
+-				       unsigned int val)
++				       const char *ifname, unsigned int val)
+ {
+ 	struct i802_bss *bss = priv;
+ 	char path[128];
+@@ -12194,8 +12194,11 @@ static int wpa_driver_br_set_net_param(v
+ 			return -EINVAL;
+ 	}
+ 
++	if (!ifname)
++		ifname = bss->brname;
++
+ 	os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s",
+-		    ip_version, bss->brname, param_txt);
++		    ip_version, ifname, param_txt);
+ 
+ set_val:
+ 	if (linux_write_system_file(path, val))
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/770-radius_server.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/770-radius_server.patch
index e4690c7..8837a26 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/770-radius_server.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/770-radius_server.patch
@@ -21,7 +21,7 @@
  
  #ifndef CONFIG_NO_HOSTAPD_LOGGER
  static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
-@@ -758,6 +759,11 @@ int main(int argc, char *argv[])
+@@ -771,6 +772,11 @@ int main(int argc, char *argv[])
  	if (os_program_init())
  		return -1;
  
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch
index 51690de..5809a3b 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch
@@ -13,7 +13,7 @@
 
 --- a/wpa_supplicant/ctrl_iface.c
 +++ b/wpa_supplicant/ctrl_iface.c
-@@ -12640,7 +12640,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12763,7 +12763,7 @@ char * wpa_supplicant_ctrl_iface_process
  		if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18))
  			reply_len = -1;
  #endif /* CONFIG_WNM */
@@ -22,7 +22,7 @@
  	} else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) {
  		if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18))
  			reply_len = -1;
-@@ -12650,7 +12650,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -12773,7 +12773,7 @@ char * wpa_supplicant_ctrl_iface_process
  	} else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) {
  		if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11))
  			reply_len = -1;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/991-Fix-OpenWrt-13156.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/991-Fix-OpenWrt-13156.patch
index 3f10fb1..097d62a 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/991-Fix-OpenWrt-13156.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/991-Fix-OpenWrt-13156.patch
@@ -20,7 +20,7 @@
 
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
-@@ -3563,6 +3563,8 @@ int hostapd_remove_iface(struct hapd_int
+@@ -3564,6 +3564,8 @@ int hostapd_remove_iface(struct hapd_int
  void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
  			   int reassoc)
  {
@@ -29,7 +29,7 @@
  	if (hapd->tkip_countermeasures) {
  		hostapd_drv_sta_deauth(hapd, sta->addr,
  				       WLAN_REASON_MICHAEL_MIC_FAILURE);
-@@ -3570,10 +3572,16 @@ void hostapd_new_assoc_sta(struct hostap
+@@ -3571,10 +3573,16 @@ void hostapd_new_assoc_sta(struct hostap
  	}
  
  #ifdef CONFIG_IEEE80211BE
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
index ebd951f..7c00526 100644
--- 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
@@ -1,7 +1,7 @@
-From 66102db35a595a1b2754e13a95123e55d378332e Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add neighbor report and BSS Termination
+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 ()
@@ -59,7 +59,7 @@
  
  
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 44b62f8..774f64e 100644
+index 0790478..82338e2 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
 @@ -558,6 +558,7 @@ struct hostapd_bss_config {
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
index 70486da..d9b0cba 100644
--- 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
@@ -1,7 +1,7 @@
-From a915b2e10f342705ab26158efebaa7a7024042ae Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: print sae groups by hostapd ctrl
+Subject: [PATCH 02/38] hostapd: mtk: print sae groups by hostapd ctrl
 
 ---
  hostapd/ctrl_iface.c | 13 +++++++++++++
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
index 377b04a..85ffb3b 100644
--- 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
@@ -1,7 +1,7 @@
-From e2ecc047a72c3069c9f05975e612a37864da5885 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: add support for runtime set in-band
+Subject: [PATCH 03/38] hostapd: mtk: add support for runtime set in-band
  discovery
 
 Usage:
@@ -143,7 +143,7 @@
  };
  
 diff --git a/src/ap/beacon.c b/src/ap/beacon.c
-index 9454cdf..3dc217f 100644
+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,
@@ -166,7 +166,7 @@
  						  &params->fd_frame_tmpl_len);
  
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 99870a6..7867e69 100644
+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,
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-hostapd-mtk-Add-mtk_vendor.h.patch
index 11971cd..13a7d1d 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-hostapd-mtk-Add-mtk_vendor.h.patch
@@ -1,7 +1,7 @@
-From bb0f79fb5a04b7ba10bf3ff03634110dd25aa31f Mon Sep 17 00:00:00 2001
+From 86553b9434ad98e4ec3dd19fbc5589ca24501f4d 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/40] hostapd: mtk: Add mtk_vendor.h
+Subject: [PATCH 04/38] hostapd: mtk: Add mtk_vendor.h
 
 ---
  src/common/mtk_vendor.h | 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-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch
index 272ebf8..868adca 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-hostapd-mtk-Support-EDCCA-hostapd-configuration.patch
@@ -1,7 +1,7 @@
-From 6b321709940a2feaa79a5e6d63f19a83bde83bb7 Mon Sep 17 00:00:00 2001
+From 906a70c7df5918c40c9552e078690ab7305ed40e 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/40] hostapd: mtk: Support EDCCA hostapd configuration
+Subject: [PATCH 05/38] hostapd: mtk: Support EDCCA hostapd configuration
 
 edcca_enable and edcca_compensation and implement edcca related handlers.
 ---
@@ -20,12 +20,12 @@
  12 files changed, 428 insertions(+), 6 deletions(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 3557bef..1fc6456 100644
+index 4b0f99f..d281026 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4803,6 +4803,40 @@ static int hostapd_config_fill(struct hostapd_config *conf,
- 	} else if (os_strcmp(buf, "mld_id") == 0) {
- 		bss->mld_id = atoi(pos);
+@@ -4809,6 +4809,40 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 			return 1;
+ 		}
  #endif /* CONFIG_IEEE80211BE */
 +	} else if (os_strcmp(buf, "edcca_threshold") == 0) {
 +		if (hostapd_parse_intlist(&conf->edcca_threshold, pos) ||
@@ -237,10 +237,10 @@
  	wpabuf_free(conf->civic);
  
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 774f64e..0e829c0 100644
+index 82338e2..24d540d 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1190,8 +1190,38 @@ struct hostapd_config {
+@@ -1193,8 +1193,38 @@ struct hostapd_config {
  		MBSSID_ENABLED = 1,
  		ENHANCED_MBSSID_ENABLED = 2,
  	} mbssid;
@@ -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 331b0ea..8806217 100644
+index 96c8c4e..6ca693b 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 96ab02b..b34c9d2 100644
+index 6746de2..1b9ce6f 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2511,6 +2511,13 @@ dfs_offload:
@@ -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 969cbda..443c4a7 100644
+index cc49011..fca2035 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5080,6 +5080,10 @@ struct wpa_driver_ops {
+@@ -5102,6 +5102,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 7867e69..5a3e208 100644
+index c7745b6..0a159d5 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
-@@ -13632,6 +13634,174 @@ static int testing_nl80211_radio_disable(void *priv, int disabled)
+@@ -13748,6 +13750,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",
-@@ -13786,4 +13956,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -13904,4 +14074,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 */
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
index 7ae38e3..43f214c 100644
--- 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
@@ -1,7 +1,7 @@
-From 2ae0d6fb6b676f76081a9edd3416d93b26091400 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH 06/38] hostapd: mtk: Add hostapd MU SET/GET control
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -20,7 +20,7 @@
  13 files changed, 251 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 1fc6456..0e67796 100644
+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,
@@ -168,10 +168,10 @@
  
  	/* 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 0e829c0..0bd6254 100644
+index 24d540d..421e6a6 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1143,6 +1143,7 @@ struct hostapd_config {
+@@ -1146,6 +1146,7 @@ struct hostapd_config {
  	u8 he_6ghz_tx_ant_pat;
  	u8 he_6ghz_reg_pwr_type;
  	bool require_he;
@@ -202,7 +202,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 8806217..6e0cf81 100644
+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);
@@ -215,7 +215,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index b34c9d2..4251699 100644
+index 1b9ce6f..865991e 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2517,6 +2517,8 @@ dfs_offload:
@@ -261,7 +261,7 @@
  #define ETH_ALEN 6
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 443c4a7..1471ba2 100644
+index fca2035..542dd45 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
 @@ -176,6 +176,11 @@ struct hostapd_channel_data {
@@ -276,7 +276,7 @@
  };
  
  #define HE_MAC_CAPAB_0		0
-@@ -5084,6 +5089,14 @@ struct wpa_driver_ops {
+@@ -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);
@@ -292,10 +292,10 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 5a3e208..8e8a4fd 100644
+index 0a159d5..07c72f5 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13497,6 +13497,114 @@ fail:
+@@ -13613,6 +13613,114 @@ fail:
  }
  
  
@@ -410,7 +410,7 @@
  #ifdef CONFIG_DPP
  static int nl80211_dpp_listen(void *priv, bool enable)
  {
-@@ -13947,6 +14055,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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
index 0488ba3..5967879 100644
--- 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
@@ -1,7 +1,7 @@
-From 74fde855e7d167f93908a70b50b029c42b796be8 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add three wire PTA ctrl hostapd vendor
+Subject: [PATCH 07/38] hostapd: mtk: Add three wire PTA ctrl hostapd vendor
  command
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -20,10 +20,10 @@
  11 files changed, 93 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index 0e67796..c716630 100644
+index ec3b41a..d515b6e 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4846,6 +4846,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+@@ -4852,6 +4852,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
  			return 1;
  		}
  		conf->edcca_compensation = (s8) val;
@@ -47,10 +47,10 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 0bd6254..8f4f79e 100644
+index 421e6a6..52df2e0 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1195,6 +1195,19 @@ struct hostapd_config {
+@@ -1198,6 +1198,19 @@ struct hostapd_config {
  	u8 edcca_enable;
  	s8 edcca_compensation;
  	int *edcca_threshold;
@@ -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 6e0cf81..960a110 100644
+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,
@@ -102,7 +102,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 4251699..798852e 100644
+index 865991e..cad5d67 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2519,6 +2519,8 @@ dfs_offload:
@@ -149,10 +149,10 @@
  	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 1471ba2..cd7afef 100644
+index 542dd45..07af191 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5097,6 +5097,14 @@ struct wpa_driver_ops {
+@@ -5119,6 +5119,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 8e8a4fd..621515d 100644
+index 07c72f5..cf1f2d0 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13910,6 +13910,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
+@@ -14026,6 +14026,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value)
  	return ret;
  }
  
@@ -210,7 +210,7 @@
  
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
-@@ -14070,4 +14102,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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
index 6d807ee..de3e848 100644
--- 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
@@ -1,7 +1,7 @@
-From a527e4f9a557f751fa0b3ef8b3d40e5edef56d38 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add hostapd iBF control
+Subject: [PATCH 08/38] hostapd: mtk: Add hostapd iBF control
 
 Signed-off-by: mtk27835 <shurong.wen@mediatek.com>
 ---
@@ -21,10 +21,10 @@
  13 files changed, 224 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index c716630..dea124a 100644
+index d515b6e..f8560a7 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4850,6 +4850,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+@@ -4856,6 +4856,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
  		u8 en = atoi(pos);
  
  		conf->three_wire_enable = en;
@@ -118,10 +118,10 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 8f4f79e..9758439 100644
+index 52df2e0..ffbc4fb 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1196,6 +1196,7 @@ struct hostapd_config {
+@@ -1199,6 +1199,7 @@ struct hostapd_config {
  	s8 edcca_compensation;
  	int *edcca_threshold;
  	u8 three_wire_enable;
@@ -129,7 +129,7 @@
  };
  
  enum three_wire_mode {
-@@ -1321,6 +1322,7 @@ hostapd_set_oper_centr_freq_seg1_idx(struct hostapd_config *conf,
+@@ -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;
  }
  
@@ -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 960a110..3f1df5d 100644
+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);
@@ -174,7 +174,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 798852e..a513236 100644
+index cad5d67..227580e 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2521,6 +2521,8 @@ dfs_offload:
@@ -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 cd7afef..7ac0284 100644
+index 07af191..0a99078 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
-@@ -5105,6 +5110,20 @@ struct wpa_driver_ops {
+@@ -5127,6 +5132,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 621515d..936a4f8 100644
+index cf1f2d0..a05e047 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13943,6 +13943,112 @@ static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
+@@ -14059,6 +14059,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",
-@@ -14103,4 +14209,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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
index 40fccf5..ba1aa44 100644
--- 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
@@ -1,7 +1,7 @@
-From 46e29c26ddaa503b6af4dc33784a2998c453d6c9 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Do not include HE capab IE if associated
+Subject: [PATCH 09/38] hostapd: mtk: Do not include HE capab IE if associated
  sta's HE capab IE is invalid
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index db48b7c..1bf5bea 100644
+index db404a6..110ad8c 100644
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -4843,7 +4843,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
+@@ -4863,7 +4863,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
  #endif /* CONFIG_IEEE80211AC */
  
  #ifdef CONFIG_IEEE80211AX
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-hostapd-mtk-Add-DFS-detection-mode.patch
index 1b4dadf..3049a6b 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-hostapd-mtk-Add-DFS-detection-mode.patch
@@ -1,7 +1,7 @@
-From a257091386c0bf12de2934730b874d240f34d1bb Mon Sep 17 00:00:00 2001
+From e825b01701aeb6536321a9bf1bd5b4760a0cdc04 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/40] hostapd: mtk: Add DFS detection mode
+Subject: [PATCH 10/38] hostapd: mtk: 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,10 +17,10 @@
  4 files changed, 50 insertions(+)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index dea124a..a4a8e71 100644
+index f8560a7..50e2993 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4853,6 +4853,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+@@ -4859,6 +4859,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
  	} else if (os_strcmp(buf, "ibf_enable") == 0) { /*ibf setting is per device*/
  		int val = atoi(pos);
  		conf->ibf_enable = !!val;
@@ -73,10 +73,10 @@
  		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 9758439..c50c2e2 100644
+index ffbc4fb..6576d79 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1197,6 +1197,7 @@ struct hostapd_config {
+@@ -1200,6 +1200,7 @@ struct hostapd_config {
  	int *edcca_threshold;
  	u8 three_wire_enable;
  	u8 ibf_enable;
@@ -84,7 +84,7 @@
  };
  
  enum three_wire_mode {
-@@ -1211,6 +1212,18 @@ enum three_wire_mode {
+@@ -1214,6 +1215,18 @@ enum three_wire_mode {
  		NUM_THREE_WIRE_MODE - 1
  };
  
@@ -104,10 +104,10 @@
  	EDCCA_MODE_FORCE_DISABLE = 0,
  	EDCCA_MODE_AUTO = 1,
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index a19afb0..644a7ea 100644
+index 29d2683..2e138e2 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1322,6 +1322,11 @@ hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
+@@ -1327,6 +1327,11 @@ hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
  		   __func__, iface->radar_background.cac_started ? "yes" : "no",
  		   hostapd_csa_in_progress(iface) ? "yes" : "no");
  
@@ -119,7 +119,7 @@
  	/* Check if CSA in progress */
  	if (hostapd_csa_in_progress(iface))
  		return 0;
-@@ -1370,6 +1375,11 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
+@@ -1375,6 +1380,11 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
  		   __func__, iface->cac_started ? "yes" : "no",
  		   hostapd_csa_in_progress(iface) ? "yes" : "no");
  
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-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
index 11b11fc..39cb7f2 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-hostapd-mtk-Add-DFS-offchan-channel-switch.patch
@@ -1,7 +1,7 @@
-From 4802aabaad0a2e7a02d32a365f6d8fec344d264c Mon Sep 17 00:00:00 2001
+From 34d1517322d42ea45b6b2a792b9d7f7dd256bef6 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/40] hostapd: mtk: Add DFS offchan channel switch
+Subject: [PATCH 11/38] 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.
@@ -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 644a7ea..48c5fc9 100644
+index 2e138e2..23e6527 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
 @@ -19,13 +19,6 @@
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
index aa32d0f..de63341 100644
--- 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
@@ -1,7 +1,7 @@
-From 4f54451e436ca42946b3f0f294b6e784d2f61862 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add amsdu set get ctrl
+Subject: [PATCH 12/38] hostapd: mtk: Add amsdu set get ctrl
 
 ---
  hostapd/config_file.c             |   9 +++
@@ -20,10 +20,10 @@
  13 files changed, 207 insertions(+), 1 deletion(-)
 
 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
-index a4a8e71..d17e50e 100644
+index 50e2993..0b2f3dc 100644
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -4857,6 +4857,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+@@ -4863,6 +4863,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
  		u8 en = strtol(pos, NULL, 10);
  
  		conf->dfs_detect_mode = en;
@@ -123,10 +123,10 @@
  	return conf;
  }
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index c50c2e2..b8f6680 100644
+index 6576d79..9f3cea2 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1198,6 +1198,7 @@ struct hostapd_config {
+@@ -1201,6 +1201,7 @@ struct hostapd_config {
  	u8 three_wire_enable;
  	u8 ibf_enable;
  	u8 dfs_detect_mode;
@@ -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 3f1df5d..422cb52 100644
+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);
@@ -172,7 +172,7 @@
  #include "drivers/driver.h"
  
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index a513236..24e5df8 100644
+index 227580e..a166de4 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2523,6 +2523,8 @@ dfs_offload:
@@ -220,10 +220,10 @@
  	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 7ac0284..87a5a9b 100644
+index 0a99078..38f6e8b 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5124,6 +5124,15 @@ struct wpa_driver_ops {
+@@ -5146,6 +5146,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 936a4f8..ce09d9f 100644
+index a05e047..808db17 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -14049,6 +14049,118 @@ fail:
+@@ -14165,6 +14165,118 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -362,7 +362,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14211,4 +14323,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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
index dd96623..2182cc1 100644
--- 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
@@ -1,7 +1,7 @@
-From ea7da2297d396febe75de0d7cf77cba9d2eab778 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add he_ldpc configuration
+Subject: [PATCH 13/38] hostapd: mtk: 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 d17e50e..04ca433 100644
+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,
@@ -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 30fb06d..fd42c50 100644
+index bafc923..f16e3b0 100644
 --- a/hostapd/hostapd.conf
 +++ b/hostapd/hostapd.conf
 @@ -833,6 +833,11 @@ wmm_ac_vo_acm=0
@@ -54,10 +54,10 @@
  		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 b8f6680..5b2dbff 100644
+index 9f3cea2..d0e27b2 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -956,6 +956,7 @@ struct hostapd_bss_config {
+@@ -959,6 +959,7 @@ struct hostapd_bss_config {
   * struct he_phy_capabilities_info - HE PHY capabilities
   */
  struct he_phy_capabilities_info {
@@ -84,10 +84,10 @@
  		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 0b7b776..cf3ef98 100644
+index e7c3f17..69f1591 100644
 --- a/src/common/ieee802_11_defs.h
 +++ b/src/common/ieee802_11_defs.h
-@@ -2357,6 +2357,9 @@ struct ieee80211_spatial_reuse {
+@@ -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))
  
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
index 6003cfb..eac9292 100644
--- 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
@@ -1,7 +1,7 @@
-From 41ccc468e3ce6727b237390bcedf1ab734d749e4 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add vendor command attribute for RTS BW
+Subject: [PATCH 14/38] hostapd: mtk: Add vendor command attribute for RTS BW
  signaling.
 
 Signed-off-by: himanshu.goyal <himanshu.goyal@mediatek.com>
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
index 3b19e78..a955f11 100644
--- 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
@@ -1,17 +1,17 @@
-From 0381565e342ecf407ffb6a32212c6d7123417c73 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: 6G band does not require DFS
+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 48c5fc9..dcf89ce 100644
+index 23e6527..0a8486a 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1511,6 +1511,7 @@ int hostapd_is_dfs_required(struct hostapd_iface *iface)
+@@ -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 ||
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
index 206a8d3..76d6e0b 100644
--- 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
@@ -1,7 +1,7 @@
-From b810754f20e0bad1b1be74bd71fc96f6b74b8c4d Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Fix sending wrong VHT operation IE in CSA
+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>
@@ -10,10 +10,10 @@
  1 file changed, 9 insertions(+), 5 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index dcf89ce..e5ed645 100644
+index 0a8486a..cfc3508 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1115,6 +1115,14 @@ static int
+@@ -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);
@@ -28,7 +28,7 @@
  
  	iface->conf->channel = iface->radar_background.channel;
  	iface->freq = iface->radar_background.freq;
-@@ -1127,11 +1135,7 @@ hostapd_dfs_start_channel_switch_background(struct hostapd_iface *iface)
+@@ -1132,11 +1140,7 @@ hostapd_dfs_start_channel_switch_background(struct hostapd_iface *iface)
  
  	hostpad_dfs_update_background_chain(iface);
  
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
index f2e966a..e29ecce 100644
--- 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
@@ -1,7 +1,7 @@
-From 20f21e3ff3c5d5db5daea650e22c6fa8ca6071a4 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add sta-assisted DFS state update
+Subject: [PATCH 17/38] hostapd: mtk: Add sta-assisted DFS state update
  mechanism
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,10 +16,10 @@
  7 files changed, 78 insertions(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index e5ed645..d52a60e 100644
+index cfc3508..9d002cf 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1508,6 +1508,26 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
+@@ -1513,6 +1513,26 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
  }
  
  
@@ -61,10 +61,10 @@
  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 903eab3..c3fc419 100644
+index f6093c1..e7f1f19 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -1912,6 +1912,24 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
+@@ -2086,6 +2086,24 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
  			      radar->cf1, radar->cf2);
  }
  
@@ -89,7 +89,7 @@
  #endif /* NEED_AP_MLME */
  
  
-@@ -2190,6 +2208,16 @@ void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
+@@ -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;
@@ -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 ccff0ee..e209ac6 100644
+index 416e0d6..62f042e 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 87a5a9b..592f506 100644
+index 38f6e8b..0469694 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5760,6 +5760,20 @@ enum wpa_event_type {
+@@ -5782,6 +5782,20 @@ enum wpa_event_type {
  	 * EVENT_LINK_RECONFIG - Notification that AP links removed
  	 */
  	EVENT_LINK_RECONFIG,
@@ -144,10 +144,10 @@
  
  
 diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
-index 8566b2a..ab988fa 100644
+index 701c32e..63d4401 100644
 --- a/src/drivers/driver_nl80211_event.c
 +++ b/src/drivers/driver_nl80211_event.c
-@@ -2447,6 +2447,12 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
+@@ -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;
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-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch
index a9c1842..c2296fb 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-hostapd-mtk-Mark-DFS-channel-as-available-for-CSA.patch
@@ -1,7 +1,7 @@
-From 2471c86d25da6898dd8840b7267211a5dba036b1 Mon Sep 17 00:00:00 2001
+From f3a98bc033de56fee900d0da3a33775165b714ad 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/40] hostapd: mtk: Mark DFS channel as available for CSA.
+Subject: [PATCH 18/38] hostapd: mtk: Mark DFS channel as available for CSA.
 
 ---
  hostapd/ctrl_iface.c   | 10 ++++++++++
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-hostapd-mtk-Add-available-color-bitmap.patch
index 01aa4d5..d4ce7cc 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-hostapd-mtk-Add-available-color-bitmap.patch
@@ -1,7 +1,7 @@
-From 236e82d01cd015135468166e6d00b05b16e4c5f8 Mon Sep 17 00:00:00 2001
+From d77b2e1d3821e51f557f1292a0ccaa0a211ea11f 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/40] hostapd: mtk: Add available color bitmap
+Subject: [PATCH 19/38] hostapd: mtk: Add available color bitmap
 
 Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 ---
@@ -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 422cb52..136ea23 100644
+index 88bc430..ecaa71f 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);
@@ -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 592f506..91cb475 100644
+index 0469694..130143e 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5133,6 +5133,14 @@ struct wpa_driver_ops {
+@@ -5155,6 +5155,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 ce09d9f..8b8ddfa 100644
+index 808db17..ee0912f 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -12733,7 +12733,6 @@ static void nl80211_parse_btm_candidate_info(struct candidate_list *candidate,
+@@ -12849,7 +12849,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)
  {
-@@ -14161,6 +14160,203 @@ fail:
+@@ -14277,6 +14276,203 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -440,7 +440,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14325,4 +14521,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14443,4 +14639,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,
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
index 67950bf..84087de 100644
--- 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
@@ -1,7 +1,7 @@
-From 4518e45497260d319663621eca8cea4c0f79b668 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Fix ZWDFS issue in BW 160
+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.
@@ -14,7 +14,7 @@
  1 file changed, 79 insertions(+), 19 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index d52a60e..2f5c86e 100644
+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)
@@ -96,7 +96,7 @@
  }
  
  
-@@ -831,8 +839,12 @@ static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
+@@ -836,8 +844,12 @@ static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
   */
  int hostapd_handle_dfs(struct hostapd_iface *iface)
  {
@@ -110,7 +110,7 @@
  
  	if (is_6ghz_freq(iface->freq))
  		return 1;
-@@ -895,7 +907,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+@@ -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,
@@ -119,7 +119,7 @@
  	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,
-@@ -905,6 +917,16 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+@@ -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);
  
@@ -136,7 +136,7 @@
  	res = hostapd_start_dfs_cac(
  		iface, iface->conf->hw_mode, iface->freq, iface->conf->channel,
  		iface->conf->ieee80211n, iface->conf->ieee80211ac,
-@@ -913,14 +935,14 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+@@ -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),
@@ -153,7 +153,7 @@
  		/* Cache background radar parameters. */
  		iface->radar_background.channel = iface->conf->channel;
  		iface->radar_background.secondary_channel =
-@@ -941,6 +963,35 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+@@ -946,6 +968,35 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
  
  		iface->radar_background.temp_ch = 1;
  		return 1;
@@ -189,7 +189,7 @@
  	}
  
  	return 0;
-@@ -1190,6 +1241,15 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
+@@ -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;
  			}
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
index 43905c6..c6c039e 100644
--- 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
@@ -1,7 +1,7 @@
-From 014cf359542aeefc995d936ab4843491c4a3b8b6 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add vendor for CAPI certification
+Subject: [PATCH 21/38] hostapd: mtk: Add vendor for CAPI certification
  commands
 
 ---
@@ -167,7 +167,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 136ea23..946ee2d 100644
+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);
@@ -260,10 +260,10 @@
  	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
  
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 91cb475..3efea9f 100644
+index 130143e..91aa9b1 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5141,6 +5141,28 @@ struct wpa_driver_ops {
+@@ -5163,6 +5163,28 @@ struct wpa_driver_ops {
  	 *
  	 */
  	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
@@ -293,7 +293,7 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 8b8ddfa..6a42633 100644
+index ee0912f..592435c 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
 @@ -76,6 +76,58 @@ enum nlmsgerr_attrs {
@@ -355,7 +355,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14522,4 +14574,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -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,
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-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch
index 90f9965..7808d50 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-hostapd-mtk-Air-Monitor-support-in-hostapd-by-vendor.patch
@@ -1,7 +1,7 @@
-From 7e2055111b854c61eaa7ad485ebd3bf171b93df5 Mon Sep 17 00:00:00 2001
+From 8fe238bed8756a0015567c41b9c31577755d1015 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/40] hostapd: mtk: Air Monitor support in hostapd by vendor
+Subject: [PATCH 22/38] hostapd: mtk: Air Monitor support in hostapd by vendor
 
 Signed-off-by: mtk23888 <dipanshu.mittal@mediatek.com>
 ---
@@ -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 946ee2d..1e2a92a 100644
+index 32e6fc1..8a97e0f 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
@@ -247,10 +247,10 @@
 +
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 3efea9f..5c70ec7 100644
+index 91aa9b1..8733bb5 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5163,6 +5163,22 @@ struct wpa_driver_ops {
+@@ -5185,6 +5185,22 @@ struct wpa_driver_ops {
  	* @type: trigger type
  	*/
  	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
@@ -274,7 +274,7 @@
  
  /**
 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 6a42633..3d8cb95 100644
+index 592435c..c55d034 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] = {
@@ -297,7 +297,7 @@
  static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  {
  	struct nl_sock *handle;
-@@ -14409,6 +14422,171 @@ fail:
+@@ -14525,6 +14538,171 @@ fail:
  	return -ENOBUFS;
  }
  
@@ -469,7 +469,7 @@
  const struct wpa_driver_ops wpa_driver_nl80211_ops = {
  	.name = "nl80211",
  	.desc = "Linux nl80211/cfg80211",
-@@ -14577,4 +14755,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14695,4 +14873,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,
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-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch
index cd30f92..06ceae8 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-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch
@@ -1,7 +1,7 @@
-From a397fa2ee7a72fafbfa5480adfacad75352d7d2a Mon Sep 17 00:00:00 2001
+From be727db37e753f0041b2789af3ecc1eff8c0f5db 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/40] hostapd: mtk: Fix setting wrong seg0 index for 5G
+Subject: [PATCH 23/38] hostapd: mtk: Fix setting wrong seg0 index for 5G
  center chan 159 BW40
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
-index 5b2dbff..b329e81 100644
+index d0e27b2..f03a957 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1305,7 +1305,8 @@ hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf,
+@@ -1308,7 +1308,8 @@ hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf,
  #ifdef CONFIG_IEEE80211BE
  	if (conf->ieee80211be)
  		conf->eht_oper_centr_freq_seg0_idx = oper_centr_freq_seg0_idx;
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-hostapd-mtk-Add-muru-user-number-debug-command.patch
index 95dae39..68d2e5b 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-hostapd-mtk-Add-muru-user-number-debug-command.patch
@@ -1,7 +1,7 @@
-From de53629544ee0f9508554049bc5927ce2f04fcf9 Mon Sep 17 00:00:00 2001
+From 5644beb4dc1a11a236d909d4a8f8ad4aa86c6c34 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/40] hostapd: mtk: Add muru user number debug command
+Subject: [PATCH 24/38] hostapd: mtk: Add muru user number debug command
 
 ---
  hostapd/ctrl_iface.c         | 13 ++++++++++++-
@@ -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 1e2a92a..5dd701e 100644
+index 8a97e0f..464efba 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 24e5df8..25ae08f 100644
+index a166de4..28482c6 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -57,6 +57,7 @@
@@ -133,10 +133,10 @@
 +};
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 5c70ec7..84387a6 100644
+index 8733bb5..a29b6ff 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5096,11 +5096,11 @@ struct wpa_driver_ops {
+@@ -5118,11 +5118,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 3d8cb95..b682620 100644
+index c55d034..fce3ec9 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13562,13 +13562,13 @@ fail:
+@@ -13678,13 +13678,13 @@ fail:
  
  
  #ifdef CONFIG_IEEE80211AX
@@ -170,7 +170,7 @@
  
  	if (!drv->mtk_mu_vendor_cmd_avail) {
  		wpa_printf(MSG_INFO,
-@@ -13579,17 +13579,38 @@ static int nl80211_mu_onoff(void *priv, u8 mu_onoff)
+@@ -13695,17 +13695,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 @@
  }
  
  
-@@ -14731,7 +14752,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+@@ -14849,7 +14870,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-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch
index 19a3c79..2a2a578 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-hostapd-mtk-add-connac3-PHY-MURU-manual-mode-config-.patch
@@ -1,7 +1,7 @@
-From 7f1a652729514a0f9a885be30185810c18110c4d Mon Sep 17 00:00:00 2001
+From 033f4f509e60c698d9754057e194f4760af39845 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/40] hostapd: mtk: add connac3 PHY MURU manual mode config
+Subject: [PATCH 25/38] hostapd: mtk: add connac3 PHY MURU manual mode config
  support
 
 This commit supports read the following two formats to set MU/RU manual
@@ -327,10 +327,10 @@
  		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 b329e81..d43f1a6 100644
+index f03a957..7c0d12a 100644
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -1200,6 +1200,7 @@ struct hostapd_config {
+@@ -1203,6 +1203,7 @@ struct hostapd_config {
  	u8 ibf_enable;
  	u8 dfs_detect_mode;
  	u8 amsdu;
@@ -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 5dd701e..741fdab 100644
+index 464efba..1e7ae7a 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 25ae08f..0dc86bf 100644
+index 28482c6..3e184b5 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -2518,7 +2518,7 @@ dfs_offload:
@@ -567,10 +567,10 @@
 +
  #endif /* MTK_VENDOR_H */
 diff --git a/src/drivers/driver.h b/src/drivers/driver.h
-index 84387a6..9ec0e96 100644
+index a29b6ff..ebc1d27 100644
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5100,7 +5100,7 @@ struct wpa_driver_ops {
+@@ -5122,7 +5122,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 b682620..22c56f9 100644
+index fce3ec9..25e5910 100644
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -13562,12 +13562,13 @@ fail:
+@@ -13678,12 +13678,13 @@ fail:
  
  
  #ifdef CONFIG_IEEE80211AX
@@ -598,7 +598,7 @@
  	int ret = -ENOBUFS;
  
  	if (!drv->mtk_mu_vendor_cmd_avail) {
-@@ -13584,17 +13585,16 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
+@@ -13700,17 +13701,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;
  	}
-@@ -13602,9 +13602,8 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
+@@ -13718,9 +13718,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
index a93ae69..cc30d42 100644
--- 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
@@ -1,7 +1,7 @@
-From 963b6800d4416d5a88053097128a33d8bdc8f56b Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Add HE capabilities check
+Subject: [PATCH 26/38] hostapd: mtk: Add HE capabilities check
 
 Add HE capabilities check.
 Since "HE capabilities" check has been removed by driver,
@@ -11,10 +11,10 @@
  1 file changed, 26 insertions(+)
 
 diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
-index 828b926..991af2c 100644
+index 9d22725..9a36bcb 100644
 --- a/src/ap/hw_features.c
 +++ b/src/ap/hw_features.c
-@@ -680,6 +680,32 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
+@@ -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)
  {
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
index 1134253..0ba1a38 100644
--- 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
@@ -1,7 +1,7 @@
-From b79b625e3790f0d9152f736629fbc0dcd826bf62 Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Fix background channel overlapping
+Subject: [PATCH 27/38] hostapd: mtk: Fix background channel overlapping
  operating channel issue
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 18 insertions(+)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index 2f5c86e..c9a9c6c 100644
+index 3b1df6d..6f76354 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -807,6 +807,20 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
+@@ -812,6 +812,20 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq,
  }
  
  
@@ -34,7 +34,7 @@
  static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
  				     int start_chan_idx, int n_chans)
  {
-@@ -1127,6 +1141,8 @@ static void hostpad_dfs_update_background_chain(struct hostapd_iface *iface)
+@@ -1132,6 +1146,8 @@ static void hostpad_dfs_update_background_chain(struct hostapd_iface *iface)
  						  &oper_centr_freq_seg1_idx,
  						  &channel_type);
  	if (!channel ||
@@ -43,7 +43,7 @@
  	    hostapd_start_dfs_cac(iface, iface->conf->hw_mode,
  				  channel->freq, channel->chan,
  				  iface->conf->ieee80211n,
-@@ -1361,6 +1377,7 @@ static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
+@@ -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;
@@ -51,7 +51,7 @@
  
  	hostapd_setup_interface_complete(iface, err);
  	return err;
-@@ -1488,6 +1505,7 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
+@@ -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);
  
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-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch
index b85fdca..57395ca 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-hostapd-mtk-Fix-hostapd_dfs_start_cac-log.patch
@@ -1,7 +1,7 @@
-From aeabc47685135ee69cdeca5f5753c4057ca0f608 Mon Sep 17 00:00:00 2001
+From 57fd7fc979251fd178175c506e64a724433c8d6d 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/40] hostapd: mtk: Fix hostapd_dfs_start_cac log
+Subject: [PATCH 28/38] hostapd: mtk: Fix hostapd_dfs_start_cac log
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -9,10 +9,10 @@
  1 file changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/src/ap/dfs.c b/src/ap/dfs.c
-index c9a9c6c..593a468 100644
+index 6f76354..95119a3 100644
 --- a/src/ap/dfs.c
 +++ b/src/ap/dfs.c
-@@ -1650,9 +1650,11 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+@@ -1655,9 +1655,11 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
  	/* TODO: How to check CAC time for ETSI weather channels? */
  	iface->dfs_cac_ms = 60000;
  	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
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
index 3d6f958..c247137 100644
--- 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
@@ -1,7 +1,7 @@
-From 1bc32b7308d9460116954f048eca89f02204825c Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
+Subject: [PATCH 29/38] hostapd: mtk: Check the bridge after ioctl SIOCBRADDIF
  failed
 
 If ioctl returns EBUSY on command SIOCBRADDIF, the interface might
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-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch
index 8073974..50e4e63 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-hostapd-mtk-Update-parameter_set_count-in-MU-EDCA-IE.patch
@@ -1,7 +1,7 @@
-From c6557f76857bc80128d2d02e615ce32de8a0c998 Mon Sep 17 00:00:00 2001
+From 65f2475fbf84a7b71e5dcba2b8f7ae77eee4f36d 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/40] hostapd: mtk: Update parameter_set_count in MU EDCA IE
+Subject: [PATCH 30/38] hostapd: mtk: Update parameter_set_count in MU EDCA IE
 
 without this patch, MU EDCA Parameter update count not equal to
 WMM Parameter set count.
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
index 52deb06..2abbb0b 100644
--- 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
@@ -1,7 +1,7 @@
-From de15bbc394a478d141e416114297213d4e4b027d Mon Sep 17 00:00:00 2001
+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/40] hostapd: mtk: add extension IE list for non-inherit IE
+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
@@ -19,10 +19,10 @@
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
 old mode 100644
 new mode 100755
-index 1bf5bea..d36798e
+index 110ad8c..e05a06b
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -7639,7 +7639,7 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
+@@ -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)
@@ -31,7 +31,7 @@
  
  		if (len + nontx_profile_len > 255)
  			break;
-@@ -7780,11 +7780,16 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
+@@ -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;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-11vmbss-aid-using-wrong-pool.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-11vmbss-aid-using-wrong-pool.patch
deleted file mode 100644
index 7eb42ad..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-11vmbss-aid-using-wrong-pool.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From b99fd7f0b86a87fc82d63ec809fd9a73f308dd08 Mon Sep 17 00:00:00 2001
-From: "Allen.Ye" <allen.ye@mediatek.com>
-Date: Wed, 2 Aug 2023 18:33:31 +0800
-Subject: [PATCH 32/40] hostapd: mtk: Fix 11vmbss aid using wrong pool
-
-Fix 11vmbss aid using wrong pool.
-All STAs use the aid pool in transmitted bss.
-
-Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
----
- src/ap/ieee802_11.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index d36798e..f20073c 100755
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -3307,6 +3307,9 @@ int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
- {
- 	int i, j = 32, aid;
- 
-+	if (hapd->iconf->mbssid)
-+		hapd = hostapd_mbssid_get_tx_bss(hapd);
-+
- 	/* get a unique AID */
- 	if (sta->aid > 0) {
- 		wpa_printf(MSG_DEBUG, "  old AID %d", sta->aid);
--- 
-2.18.0
-
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
similarity index 78%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
index c9df793..52c74f9 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
@@ -1,7 +1,7 @@
-From ee4aa23d0c87c8fe69f8ba28fe5faf95bf0103d8 Mon Sep 17 00:00:00 2001
+From e9f856156f861845c160538d2d5907bf338fa489 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 33/40] hostapd: mtk: Fix rnr ie length when no need to report
+Subject: [PATCH 32/38] hostapd: mtk: 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,10 +13,10 @@
  1 file changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index f20073c..ef520c8 100755
+index e05a06b..7b6aabb 100755
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -7494,8 +7494,10 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
+@@ -7511,8 +7511,10 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
  		}
  
  		start = i;
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
deleted file mode 100644
index c9df793..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From ee4aa23d0c87c8fe69f8ba28fe5faf95bf0103d8 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 33/40] hostapd: mtk: 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
-TBTT then don't change the length of the ie (*size_offset).
-
-Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
----
- src/ap/ieee802_11.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
-index f20073c..ef520c8 100755
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -7494,8 +7494,10 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
- 		}
- 
- 		start = i;
--		*tbtt_count_pos = RNR_TBTT_INFO_COUNT(tbtt_count - 1);
--		*size_offset = (eid - size_offset) - 1;
-+		if (tbtt_count != 0) {
-+			*tbtt_count_pos = RNR_TBTT_INFO_COUNT(tbtt_count - 1);
-+			*size_offset = (eid - size_offset) - 1;
-+		}
- 	}
- 
- 	if (tbtt_count == 0)
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
similarity index 91%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
index 80b7589..47e2970 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0033-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch
@@ -1,7 +1,7 @@
-From 26e0cd2739dc56e02cc7e1b5582220d0fcde795b Mon Sep 17 00:00:00 2001
+From 5b750f3f78cec3b64ebb9bb3b74def424c7d57fd 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 34/40] hostapd: mtk: add back ht vht cap missing field before
+Subject: [PATCH 33/38] hostapd: mtk: 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,7 +22,7 @@
  1 file changed, 7 insertions(+)
 
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 0dc86bf..2283b19 100644
+index 3e184b5..b8ae8de 100644
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
 @@ -4111,6 +4111,13 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
similarity index 74%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
index 05b2121..5412153 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0034-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
@@ -1,7 +1,7 @@
-From ef5f744c72f2e6ec6b7d4ec1ce4f233470ff7689 Mon Sep 17 00:00:00 2001
+From d46e85faec291f813d6b5578122cd267421e84fa 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 35/40] hostapd: mtk: update op_class when AP channel switching
+Subject: [PATCH 34/38] hostapd: mtk: update op_class when AP channel switching
 
 Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
 ---
@@ -9,10 +9,10 @@
  1 file changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index c3fc419..1911f85 100644
+index e7f1f19..f749b33 100644
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -873,7 +873,7 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
+@@ -1041,7 +1041,7 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
  {
  #ifdef NEED_AP_MLME
  	int channel, chwidth, is_dfs0, is_dfs;
@@ -21,7 +21,7 @@
  	size_t i;
  
  	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
-@@ -995,6 +995,9 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
+@@ -1169,6 +1169,9 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
  		hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
  
  	hapd->iconf->secondary_channel = offset;
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-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
similarity index 90%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
index 3dd5457..4dad332 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0036-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
@@ -1,7 +1,7 @@
-From eaff9afb87f172b09eac63237b099f7c4e5def3c Mon Sep 17 00:00:00 2001
+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 36/40] hostapd: mtk: Add support for gtk rekeying in hostapd
+Subject: [PATCH 35/38] hostapd: mtk: Add support for gtk rekeying in hostapd
  cli
 
 Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
deleted file mode 100644
index 05b2121..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From ef5f744c72f2e6ec6b7d4ec1ce4f233470ff7689 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 35/40] hostapd: mtk: update op_class when AP channel switching
-
-Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
----
- src/ap/drv_callbacks.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
-index c3fc419..1911f85 100644
---- a/src/ap/drv_callbacks.c
-+++ b/src/ap/drv_callbacks.c
-@@ -873,7 +873,7 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
- {
- #ifdef NEED_AP_MLME
- 	int channel, chwidth, is_dfs0, is_dfs;
--	u8 seg0_idx = 0, seg1_idx = 0;
-+	u8 seg0_idx = 0, seg1_idx = 0, op_class, chan_no;
- 	size_t i;
- 
- 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
-@@ -995,6 +995,9 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
- 		hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
- 
- 	hapd->iconf->secondary_channel = offset;
-+	ieee80211_freq_to_channel_ext(freq, offset, chwidth,
-+				      &op_class, &chan_no);
-+	hapd->iconf->op_class = op_class;
- 	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);
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
deleted file mode 100644
index 3dd5457..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From eaff9afb87f172b09eac63237b099f7c4e5def3c Mon Sep 17 00:00:00 2001
-From: mtk23510 <rudra.shahi@mediatek.com>
-Date: Fri, 26 May 2023 14:52:35 +0800
-Subject: [PATCH 36/40] 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-0038-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
similarity index 93%
copy from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
copy to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0036-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
index 27beaf7..2b0f254 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0038-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
@@ -1,7 +1,7 @@
-From b52a1f04b4a897e88b5a14f61befd71f65cdc062 Mon Sep 17 00:00:00 2001
+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 38/40] hostapd: mtk: Set WMM and TX queue parameters for
+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
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Fix-wpa_supplicant-configuration-parsing.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Fix-wpa_supplicant-configuration-parsing.patch
deleted file mode 100644
index f7f22d8..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Fix-wpa_supplicant-configuration-parsing.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From a1fd2056b0e3820920778fd9252cec645cbb6389 Mon Sep 17 00:00:00 2001
-From: Michael Lee <michael-cy.lee@mediatek.com>
-Date: Fri, 7 Jul 2023 17:14:40 +0800
-Subject: [PATCH 37/40] hostapd: mtk: Fix wpa_supplicant configuration parsing
- error
-
-In the original flow, after hostapd_config_tx_queue successfully
-parses a tx_queue variable, it would not return immediately. Then it
-would print out "unknow global field" later and set return val to -1.
-
-This patch returns immediately after hostapd_config_tx_queue
-successfully parses a tx_queue variable.
-
-Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
----
- wpa_supplicant/config.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
-index 325ab8d..2652c8a 100644
---- a/wpa_supplicant/config.c
-+++ b/wpa_supplicant/config.c
-@@ -5715,6 +5715,7 @@ int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
- 					   line);
- 				return -1;
- 			}
-+			return ret;
- 		}
- 
- 		if (os_strncmp(pos, "wmm_ac_", 7) == 0) {
--- 
-2.18.0
-
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0039-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
similarity index 89%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0039-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
index 9c8c63b..a6a86d8 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0039-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0037-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch
@@ -1,7 +1,7 @@
-From 55837ad406c9af8a398d6073809151f7a3779b74 Mon Sep 17 00:00:00 2001
+From 33cbd77949640d337e4e39d462bbb6b575792de3 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 39/40] hostapd: mtk: Set STA TX queue parameters configuration
+Subject: [PATCH 37/38] hostapd: mtk: 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 48953c1..0699689 100644
+index dcf5764..36ff854 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,10 +40,10 @@
  				    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 03442f5..5eb5248 100644
+index 3b8596d..f5ac62e 100644
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
-@@ -3557,6 +3557,20 @@ out:
+@@ -3559,6 +3559,20 @@ out:
  	return wpa_sm_set_mlo_params(wpa_s->wpa, &wpa_mlo);
  }
  
@@ -64,7 +64,7 @@
  
  static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
  				       union wpa_event_data *data)
-@@ -3884,6 +3898,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
+@@ -3886,6 +3900,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
  
  	if (wpa_s->current_ssid && wpa_s->current_ssid->enable_4addr_mode)
  		wpa_supplicant_set_4addr_mode(wpa_s);
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
deleted file mode 100644
index 27beaf7..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From b52a1f04b4a897e88b5a14f61befd71f65cdc062 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 38/40] 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/wpa-supplicant/files/patches-2.10.3/mtk-0040-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
similarity index 79%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0040-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0038-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.patch
index d31b6c2..e076eae 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0040-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
@@ -1,7 +1,7 @@
-From 100dae9224afa0c9dbd1117ab97b60e427657afc Mon Sep 17 00:00:00 2001
+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 40/40] hostapd: mtk: avoid color switch when beacon is not set
+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>
 ---
@@ -9,7 +9,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
-index 2283b19..6d86993 100644
+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)
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
new file mode 100644
index 0000000..105e188
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
@@ -0,0 +1,29 @@
+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-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
new file mode 100644
index 0000000..1695996
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
@@ -0,0 +1,85 @@
+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/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-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch
new file mode 100644
index 0000000..f02f935
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0043-hostapd-mtk-change-the-flow-to-create-Wide-Bandwidth.patch
@@ -0,0 +1,168 @@
+From 92caaf40a058d4eac8061c0e3240f0b23aba69ce 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
+
+This patch changes the flow to create Wide Bandwidth Channel Switch IE:
+1. 2 GHz: Wide Bandwidth Channel Switch IE should not present.
+2. 5 GHz: fill the subfields according to VHT operation.
+3. 6 GHz: fill the subfields according to VHT operation and HE operation
+   in HE mode and EHT mode, respectively.
+   This is because the definition of the subfields of Wide Bandwidth
+   Channel Switch IE is ambiguous:
+   1. 802.11ac: the definition of subfields follows VHT operation
+      (IEEE80211-2020 9.4.2.160)
+   2. 802.11ax: the definition of subfields is not specified
+   3. 802.11be: the definition of subfields follows VHT operation in 5
+      GHz and HE operation in 6 GHz (IEEE P802.11be D3.2 9.4.2.159)
+
+To support 320 MHz
+   channel switch, set width to 4
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ src/ap/ieee802_11.c | 99 ++++++++++++++++++++++++++++++++++-----------
+ 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
+--- 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)
+ 
+ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
+ {
+-	u8 bw, chan1, chan2 = 0;
+-	int freq1;
++	u8 new_bw_field, ccfs0_chan, ccfs1_chan = 0;
++	int ccfs0_freq = 0, ccfs1_freq = 0;
++	int control_freq, center_freq1, center_freq2, bandwidth;
++	int base_freq, offset;
++	bool is_6ghz, use_he_oper;
+ 
+ 	if (!hapd->cs_freq_params.channel ||
++	    hapd->cs_freq_params.bandwidth == 20 ||
+ 	    (!hapd->cs_freq_params.vht_enabled &&
+ 	     !hapd->cs_freq_params.he_enabled &&
+ 	     !hapd->cs_freq_params.eht_enabled))
+ 		return eid;
+ 
+-	/* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80, 4: 320 */
+-	switch (hapd->cs_freq_params.bandwidth) {
++	control_freq = hapd->cs_freq_params.freq;
++	center_freq1 = hapd->cs_freq_params.center_freq1;
++	center_freq2 = hapd->cs_freq_params.center_freq2;
++	bandwidth = hapd->cs_freq_params.bandwidth;
++
++	/* center_freq2 is used if and only if bandwidth is
++	 * 80+80 MHz and phy mode is not EHT
++	 */
++	if (center_freq2 &&
++	    (bandwidth != 80 || hapd->cs_freq_params.eht_enabled))
++		return eid;
++
++	is_6ghz = is_6ghz_freq(control_freq);
++	use_he_oper = is_6ghz && hapd->cs_freq_params.eht_enabled;
++	base_freq = is_6ghz ? 5955 : 5180;
++
++	/* About the subfields of the Wide Bandwidth Channel Switch IE,
++	 * IEEE802.11-2020 9.4.2.160 specifies that the subfields New
++	 * Channel Width, New Channel Center Frequency Segment 0 and New
++	 * Channel Center Frequency Segment 1 have the same definition as
++	 * they are in the VHT operation information field.
++	 * However, the standard does not specify the definition of these
++	 * subfields when it comes to HE phy-mode in 6 GHz.
++	 * And in IEEE P802.11be D3.2 9.4.2.159, it specifies that the
++	 * defition should follow VHT operation in 5 GHz, and follow HE
++	 * oepration in 6 GHz.
++	 * Problem happens here for some HE STAs in 6 GHz, they might still
++	 * use VHT operation to parse these subfields.
++	 *
++	 * Here we follow the new Standard to build the IE, meanwhile we have
++	 * a workaround for HE mode in 6 GHz.
++	 *
++	 * 5 GHz: VHT operation
++	 * HE mode in 6 GHz: VHT operation
++	 * EHT mode in 6 GHz: HE operation
++	 */
++	ccfs0_freq = center_freq1;
++	ccfs1_freq = center_freq2;
++	switch (bandwidth) {
+ 	case 40:
+-		bw = 0;
++		new_bw_field = use_he_oper ? 1 : 0;
+ 		break;
+ 	case 80:
+-		/* check if it's 80+80 */
+-		if (!hapd->cs_freq_params.center_freq2)
+-			bw = 1;
++		if (ccfs1_freq)
++			new_bw_field = use_he_oper ? 3 : 1;
+ 		else
+-			bw = 3;
++			new_bw_field = use_he_oper ? 2 : 1;
+ 		break;
+ 	case 160:
+-		bw = 2;
++		new_bw_field = use_he_oper ? 3 : 1;
++
++		/* ccfs0 is primary 80 MHz
++		 * ccfs1 is center frequency
++		 */
++		offset = (control_freq - base_freq) / 20;
++		ccfs0_freq = control_freq + 30 - (offset & 3) * 20;
++		ccfs1_freq = center_freq1;
+ 		break;
+ 	case 320:
+-		bw = 4;
++		/* TODO switch to bandwidth 320 MHz should be
++		 * indicated by Bandwidth indication IE.
++		 */
++		new_bw_field = 4;
++
++		/* ccfs0 is primary 160 MHz
++		 * ccfs1 is center frequency
++		 */
++		offset = (control_freq - base_freq) / 20;
++		ccfs0_freq = control_freq + 70 - (offset & 7) * 20;
++		ccfs1_freq = center_freq1;
+ 		break;
+ 	default:
+-		/* not valid VHT bandwidth or not in CSA */
++		/* not a valid VHT/HE bandwidth or not in CSA */
+ 		return eid;
+ 	}
+ 
+-	freq1 = hapd->cs_freq_params.center_freq1 ?
+-		hapd->cs_freq_params.center_freq1 :
+-		hapd->cs_freq_params.freq;
+-	if (ieee80211_freq_to_chan(freq1, &chan1) !=
+-	    HOSTAPD_MODE_IEEE80211A)
++	if (ieee80211_freq_to_chan(ccfs0_freq, &ccfs0_chan) !=
++			HOSTAPD_MODE_IEEE80211A)
+ 		return eid;
+ 
+-	if (hapd->cs_freq_params.center_freq2 &&
+-	    ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2,
+-				   &chan2) != HOSTAPD_MODE_IEEE80211A)
++	if (ccfs1_freq && ieee80211_freq_to_chan(ccfs1_freq, &ccfs1_chan) !=
++			HOSTAPD_MODE_IEEE80211A)
+ 		return eid;
+ 
+ 	*eid++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER;
+ 	*eid++ = 5; /* Length of Channel Switch Wrapper */
+ 	*eid++ = WLAN_EID_WIDE_BW_CHSWITCH;
+ 	*eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */
+-	*eid++ = bw; /* New Channel Width */
+-	*eid++ = chan1; /* New Channel Center Frequency Segment 0 */
+-	*eid++ = chan2; /* New Channel Center Frequency Segment 1 */
++	*eid++ = new_bw_field; /* New Channel Width */
++	*eid++ = ccfs0_chan; /* New Channel Center Frequency Segment 0 */
++	*eid++ = ccfs1_chan; /* New Channel Center Frequency Segment 1 */
+ 
+ 	return eid;
+ }
+-- 
+2.25.1
+
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
new file mode 100755
index 0000000..b699fc5
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
@@ -0,0 +1,96 @@
+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-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
index e2c6d87..5092a61 100644
--- 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
@@ -1,7 +1,7 @@
-From 3b4b9812c97b0b75579829c96a19e8a8cc0bfa7b Mon Sep 17 00:00:00 2001
+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/1004] hostapd: mtk: update eht operation element
+Subject: [PATCH 1001/1005] hostapd: mtk: update eht operation element
 
 ---
  src/ap/ieee802_11_eht.c | 6 +++---
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
index 1b51a28..9c23287 100644
--- 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
@@ -1,7 +1,7 @@
-From 5ed678c7562b1acf04f1b6c63ab25a5f3043325f Mon Sep 17 00:00:00 2001
+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/1004] hostapd: mtk: ucode: add support for ucode to parse
+Subject: [PATCH 1002/1005] hostapd: mtk: ucode: add support for ucode to parse
  BW320MHz info
 
 ---
@@ -9,7 +9,7 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/src/utils/ucode.c b/src/utils/ucode.c
-index 896ef46..4448738 100644
+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)
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
index 74c685b..5a63279 100644
--- 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
@@ -1,61 +1,279 @@
-From 25b1c0f5e4f674ea2b72949bce83c05204d19653 Mon Sep 17 00:00:00 2001
+From 804f9b03e7f143d3a80741cb67721810e27ed2d8 Mon Sep 17 00:00:00 2001
 From: Michael-CY Lee <michael-cy.lee@mediatek.com>
-Date: Thu, 24 Aug 2023 16:44:30 +0800
+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/utils/ucode.c      |  1 +
- wpa_supplicant/ucode.c | 10 ++++++++++
- 2 files changed, 11 insertions(+)
+ 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 44169f0..41c19fb 100644
+index 122c619..0990e7b 100644
 --- a/src/utils/ucode.c
 +++ b/src/utils/ucode.c
-@@ -115,6 +115,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
+@@ -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 (!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 d0a78d1..dbf57fa 100644
+index 6cba73d..d5489ea 100644
 --- a/wpa_supplicant/ucode.c
 +++ b/wpa_supplicant/ucode.c
-@@ -6,6 +6,7 @@
+@@ -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;
-@@ -194,6 +195,9 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
+@@ -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;
-@@ -222,6 +226,12 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
- 
- 		ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan));
- 		ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq));
+@@ -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);
-+		ieee80211_chaninfo_to_channel(ci.frequency, ci.chanwidth,
-+					      sec_chan, &op_class, &channel);
++		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));
  	}
  
- 	return ret;
+ #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
new file mode 100644
index 0000000..23aa563
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1004-hostapd-mtk-Add-support-for-updating-background-chan.patch
@@ -0,0 +1,339 @@
+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-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
new file mode 100644
index 0000000..fcfd0bf
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1005-hostapd-mtk-add-zwdfs-mode-ctrl-for-eagle-efem-hwits.patch
@@ -0,0 +1,278 @@
+From 5bcd4472062750b192c98d944b74e07b14ab3af5 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
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ hostapd/config_file.c             |  2 ++
+ hostapd/ctrl_iface.c              | 30 +++++++++++++++++++++++++++
+ src/ap/ap_config.h                |  6 ++++++
+ src/ap/ap_drv_ops.c               | 14 +++++++++++++
+ src/ap/dfs.c                      |  6 ++++++
+ 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 +++
+ 10 files changed, 115 insertions(+)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index 9e3dbb2..a751993 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -3183,6 +3183,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 		conf->acs_exclude_6ghz_non_psc = atoi(pos);
+ 	} else if (os_strcmp(buf, "enable_background_radar") == 0) {
+ 		conf->enable_background_radar = atoi(pos);
++	} else if (os_strcmp(buf, "background_radar_mode") == 0) {
++		conf->background_radar_mode = atoi(pos);
+ 	} else if (os_strcmp(buf, "min_tx_power") == 0) {
+ 		int val = atoi(pos);
+ 
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index c288352..517ebd6 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,
+ 		return pos - buf;
+ }
+ 
++static int
++hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cmd,
++					     char *buf, size_t buflen)
++{
++	struct hostapd_iface *iface = hapd->iface;
++	char *pos, *param;
++
++	param = os_strchr(cmd, ' ');
++	if (!param)
++		return -1;
++	*param++ = '\0';
++
++	pos = os_strstr(param, "mode=");
++	if (!pos)
++		return -1;
++
++	if (os_strncmp(pos + 5, "cert", 4) == 0)
++		iface->conf->background_radar_mode = BACKGROUND_RADAR_CERT_MODE;
++	else if (os_strncmp(pos + 5, "normal", 6) == 0)
++		iface->conf->background_radar_mode = BACKGROUND_RADAR_NORMAL_MODE;
++
++	if (hostapd_drv_background_radar_mode(hapd) < 0)
++		return -1;
++
++	return os_snprintf(buf, buflen, "OK\n");
++}
++
+ 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,
+ 		if (pos)
+ 			*pos = ' ';
+ 		reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 23, reply, reply_size);
++	} 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 {
+ 		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
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -1025,6 +1025,7 @@ struct hostapd_config {
+ 	bool hw_mode_set;
+ 	int acs_exclude_6ghz_non_psc;
+ 	int enable_background_radar;
++	int background_radar_mode;
+ 	enum {
+ 		LONG_PREAMBLE = 0,
+ 		SHORT_PREAMBLE = 1
+@@ -1218,6 +1219,11 @@ enum three_wire_mode {
+ 		NUM_THREE_WIRE_MODE - 1
+ };
+ 
++enum background_radar_mode {
++	BACKGROUND_RADAR_NORMAL_MODE,
++	BACKGROUND_RADAR_CERT_MODE,
++};
++
+ enum dfs_mode {
+ 	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
+--- 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_
+ 		return 0;
+ 	return hapd->driver->amnt_dump(hapd->drv_priv, amnt_idx, amnt_dump_buf);
+ }
++
++int hostapd_drv_background_radar_mode(struct hostapd_data *hapd)
++{
++	if (!hapd->driver || !hapd->driver->background_radar_mode ||
++	    !(hapd->iface->drv_flags2 & WPA_DRIVER_RADAR_BACKGROUND) ||
++	    !hapd->iface->conf->enable_background_radar)
++		return 0;
++	if (hapd->iconf->background_radar_mode > BACKGROUND_RADAR_CERT_MODE) {
++		wpa_printf(MSG_INFO, "Invalid value for background radar mode\n");
++		return 0;
++	}
++	return hapd->driver->background_radar_mode(hapd->drv_priv,
++						   hapd->iconf->background_radar_mode);
++}
+diff --git a/src/ap/dfs.c b/src/ap/dfs.c
+index 008596b..2564168 100644
+--- a/src/ap/dfs.c
++++ b/src/ap/dfs.c
+@@ -983,6 +983,9 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+ 		if (res < 0)
+ 			return res;
+ 
++		if (hostapd_drv_background_radar_mode(iface->bss[0]) < 0)
++			return -1;
++
+ 		iface->radar_background.temp_ch = 1;
+ 		return 1;
+ 	} else if (dfs_use_radar_background(iface)) {
+@@ -1023,6 +1026,9 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
+ 		iface->radar_background.secondary_channel = sec;
+ 		iface->radar_background.centr_freq_seg0_idx = cf1;
+ 		iface->radar_background.centr_freq_seg1_idx = cf2;
++
++		if (hostapd_drv_background_radar_mode(iface->bss[0]) < 0)
++			return -1;
+ 	}
+ 
+ 	return 0;
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index e140de6..5bc1e04 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -16,6 +16,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 {
+@@ -244,6 +245,17 @@ enum mtk_vendor_attr_bss_color_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL - 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
++};
++
+ #define CSI_MAX_COUNT 256
+ #define ETH_ALEN 6
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index a9f48a1..bc82d28 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -5201,6 +5201,13 @@ struct wpa_driver_ops {
+ 	* @amnt_dump_buf: Buffer to print
+ 	*/
+ 	int (*amnt_dump)(void *priv, u8 amnt_idx, u8 *amnt_dump_buf);
++
++	/**
++	 * background_radar_mode - set background radar mode
++	 * @priv: Private driver interface data
++	 * @background_radar_mode: background radar mode
++	 */
++	int (*background_radar_mode)(void *priv, u8 background_radar_mode);
+ };
+ 
+ /**
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index 25e5910..73401fd 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -14723,6 +14723,39 @@ fail:
+ 	return -ENOBUFS;
+ }
+ 
++static int nl80211_background_radar_mode(void *priv, const u8 background_radar_mode)
++{
++	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_background_radar_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting background radar mode");
++		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_BACKGROUND_RADAR_CTRL) ||
++	    !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
++	    nla_put_u8(msg, MTK_VENDOR_ATTR_BACKGROUND_RADAR_CTRL_MODE, background_radar_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 background radar mode. ret=%d (%s) ",
++			   ret, strerror(-ret));
++	}
++	return ret;
++}
++
+ 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 = {
+ 	.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
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -210,6 +210,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_bss_color_vendor_cmd_avail:1;
+ 	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;
+ 
+ 	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
+--- 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)
+ 				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
+ 					drv->mtk_rfeatures_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL:
++					drv->mtk_background_radar_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+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
new file mode 100644
index 0000000..4178b68
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
@@ -0,0 +1,374 @@
+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
new file mode 100644
index 0000000..d2b117c
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
@@ -0,0 +1,431 @@
+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 02810bf..4c214c1 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
@@ -16,7 +16,10 @@
     file://150-add-NULL-checks-encountered-during-tests-hwsim.patch \
     file://160-dpp_pkex-EC-point-mul-w-value-prime.patch \
     file://170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch \
-    file://180-BSS-coloring-fix-CCA-with-multiple-BSS.patch \
+    file://180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch \
+    file://181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch \
+    file://182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch \
+    file://183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch \
     file://200-multicall.patch \
     file://300-noscan.patch \
     file://301-mesh-noscan.patch \
@@ -88,16 +91,22 @@
     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-11vmbss-aid-using-wrong-pool.patch \
-    file://mtk-0033-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch \
-    file://mtk-0034-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch \
-    file://mtk-0035-hostapd-mtk-update-op_class-when-AP-channel-switchin.patch \
-    file://mtk-0036-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch \
-    file://mtk-0037-hostapd-mtk-Fix-wpa_supplicant-configuration-parsing.patch \
-    file://mtk-0038-hostapd-mtk-Set-WMM-and-TX-queue-parameters-for-wpa_.patch \
-    file://mtk-0039-hostapd-mtk-Set-STA-TX-queue-parameters-configuratio.patch \
-    file://mtk-0040-hostapd-mtk-avoid-color-switch-when-beacon-is-not-se.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 \
     "
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
new file mode 100644
index 0000000..105e188
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0041-hostapd-mtk-6g-bss-connect-ignore-ht-opera.patch
@@ -0,0 +1,29 @@
+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/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
new file mode 100644
index 0000000..277f5fa
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0042-hostapd-mtk-avoid-unnecessary-beacon-update-for-6-GH.patch
@@ -0,0 +1,85 @@
+From 401cb8a661c5e7d796a17bb289209663a6c42741 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 c67d08b..02f4f87 100644
+--- a/src/ap/beacon.c
++++ b/src/ap/beacon.c
+@@ -2098,6 +2098,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;
+@@ -2121,7 +2127,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
+ 		if (colocated == iface || !colocated || !colocated->conf)
+ 			continue;
+ 
+-		if (is_6g == is_6ghz_op_class(colocated->conf->op_class))
++		if (!is_6g || is_6ghz_op_class(colocated->conf->op_class))
+ 			continue;
+ 
+ 		for (i = 0; i < colocated->num_bss; i++) {
+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 78fd9d8..9e247da 100644
+--- a/src/ap/bss_load.c
++++ b/src/ap/bss_load.c
+@@ -58,7 +58,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 (hapd->conf->chan_util_avg_period) {
+ 		iface->chan_util_samples_sum += iface->channel_utilization;
+-- 
+2.25.1
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
new file mode 100755
index 0000000..2ad19e1
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.patch
@@ -0,0 +1,96 @@
+From 6b4c9657caeafecd1fc5c796327c5e6689ef1f24 Mon Sep 17 00:00:00 2001
+From: "fancy.liu" <fancy.liu@mediatek.com>
+Date: Sun, 8 Oct 2023 15:16:55 +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 bf5eeb7..89594ec 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -1119,6 +1119,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
+ {
+ 	int ret;
+ 	char *pos, *end;
++	int i;
+ 
+ 	pos = buf;
+ 	end = buf + buflen;
+@@ -1290,6 +1291,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/patches.inc b/recipes-wifi/wpa-supplicant/files/patches/patches.inc
index 34e183e..0574840 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/patches.inc
+++ b/recipes-wifi/wpa-supplicant/files/patches/patches.inc
@@ -103,4 +103,7 @@
     file://mtk-0037-hostapd-mtk-add-back-ht-vht-cap-missing-field-before.patch \
     file://mtk-0038-hostapd-mtk-Fix-rnr-ie-length-when-no-need-to-report.patch \
     file://mtk-0039-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-0044-hostapd-mtk-Add-ACS-chanlist-info-in-get_config.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 0326f6f..af97091 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
@@ -8,6 +8,7 @@
 #include "hw_features.h"
 #include "ap_drv_ops.h"
 #include "dfs.h"
+#include "acs.h"
 #include <libubox/uloop.h>
 
 static uc_resource_type_t *global_type, *bss_type, *iface_type;
@@ -110,6 +111,94 @@
 	return NULL;
 }
 
+static struct hostapd_vlan *
+bss_conf_find_vlan(struct hostapd_bss_config *bss, int id)
+{
+	struct hostapd_vlan *vlan;
+
+	for (vlan = bss->vlan; vlan; vlan = vlan->next)
+		if (vlan->vlan_id == id)
+			return vlan;
+
+	return NULL;
+}
+
+static int
+bss_conf_rename_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
+		     const char *ifname)
+{
+	if (!strcmp(ifname, vlan->ifname))
+		return 0;
+
+	hostapd_drv_if_rename(hapd, WPA_IF_AP_VLAN, vlan->ifname, ifname);
+	os_strlcpy(vlan->ifname, ifname, sizeof(vlan->ifname));
+
+	return 0;
+}
+
+static int
+bss_reload_vlans(struct hostapd_data *hapd, struct hostapd_bss_config *bss)
+{
+	struct hostapd_bss_config *old_bss = hapd->conf;
+	struct hostapd_vlan *vlan, *vlan_new, *wildcard;
+	char ifname[IFNAMSIZ + 1], vlan_ifname[IFNAMSIZ + 1], *pos;
+	int ret;
+
+	vlan = bss_conf_find_vlan(old_bss, VLAN_ID_WILDCARD);
+	wildcard = bss_conf_find_vlan(bss, VLAN_ID_WILDCARD);
+	if (!!vlan != !!wildcard)
+		return -1;
+
+	if (vlan && wildcard && strcmp(vlan->ifname, wildcard->ifname) != 0)
+		strcpy(vlan->ifname, wildcard->ifname);
+	else
+		wildcard = NULL;
+
+	for (vlan = bss->vlan; vlan; vlan = vlan->next) {
+		if (vlan->vlan_id == VLAN_ID_WILDCARD ||
+		    vlan->dynamic_vlan > 0)
+			continue;
+
+		if (!bss_conf_find_vlan(old_bss, vlan->vlan_id))
+			return -1;
+	}
+
+	for (vlan = old_bss->vlan; vlan; vlan = vlan->next) {
+		if (vlan->vlan_id == VLAN_ID_WILDCARD)
+			continue;
+
+		if (vlan->dynamic_vlan == 0) {
+			vlan_new = bss_conf_find_vlan(bss, vlan->vlan_id);
+			if (!vlan_new)
+				return -1;
+
+			if (bss_conf_rename_vlan(hapd, vlan, vlan_new->ifname))
+				return -1;
+
+			continue;
+		}
+
+		if (!wildcard)
+			continue;
+
+		os_strlcpy(ifname, wildcard->ifname, sizeof(ifname));
+		pos = os_strchr(ifname, '#');
+		if (!pos)
+			return -1;
+
+		*pos++ = '\0';
+		ret = os_snprintf(vlan_ifname, sizeof(vlan_ifname), "%s%d%s",
+				  ifname, vlan->vlan_id, pos);
+	        if (os_snprintf_error(sizeof(vlan_ifname), ret))
+			return -1;
+
+		if (bss_conf_rename_vlan(hapd, vlan, vlan_ifname))
+			return -1;
+	}
+
+	return 0;
+}
+
 static uc_value_t *
 uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
 {
@@ -119,6 +208,7 @@
 	struct hostapd_config *conf;
 	uc_value_t *file = uc_fn_arg(0);
 	uc_value_t *index = uc_fn_arg(1);
+	uc_value_t *files_only = uc_fn_arg(2);
 	unsigned int i, idx = 0;
 	int ret = -1;
 
@@ -130,9 +220,28 @@
 
 	iface = hapd->iface;
 	conf = interfaces->config_read_cb(ucv_string_get(file));
-	if (!conf || idx > conf->num_bss || !conf->bss[idx])
+	if (!conf)
 		goto out;
 
+	if (idx > conf->num_bss || !conf->bss[idx])
+		goto free;
+
+	if (ucv_boolean_get(files_only)) {
+		struct hostapd_bss_config *bss = conf->bss[idx];
+		struct hostapd_bss_config *old_bss = hapd->conf;
+
+#define swap_field(name)				\
+	do {								\
+		void *ptr = old_bss->name;		\
+		old_bss->name = bss->name;		\
+		bss->name = ptr;				\
+	} while (0)
+
+		swap_field(ssid.wpa_psk_file);
+		ret = bss_reload_vlans(hapd, bss);
+		goto done;
+	}
+
 	hostapd_bss_deinit_no_free(hapd);
 	hostapd_drv_stop_ap(hapd);
 	hostapd_free_hapd_data(hapd);
@@ -143,12 +252,14 @@
 			iface->conf->bss[i] = conf->bss[idx];
 	hapd->conf = conf->bss[idx];
 	conf->bss[idx] = old_bss;
-	hostapd_config_free(conf);
 
-	hostapd_setup_bss(hapd, hapd == iface->bss[0], !iface->conf->mbssid);
+	hostapd_setup_bss(hapd, hapd == iface->bss[0], true);
+	hostapd_ucode_update_interfaces();
 
+done:
 	ret = 0;
-
+free:
+	hostapd_config_free(conf);
 out:
 	return ucv_int64_new(ret);
 }
@@ -179,10 +290,15 @@
 	struct hostapd_iface *iface;
 	int i, idx;
 
-	if (!hapd || hapd == hapd->iface->bss[0])
+	if (!hapd)
 		return NULL;
 
 	iface = hapd->iface;
+	if (iface->num_bss == 1) {
+		wpa_printf(MSG_ERROR, "trying to delete last bss of an iface: %s\n", hapd->conf->iface);
+		return NULL;
+	}
+
 	for (idx = 0; idx < iface->num_bss; idx++)
 		if (iface->bss[idx] == hapd)
 			break;
@@ -192,8 +308,13 @@
 
 	for (i = idx + 1; i < iface->num_bss; i++)
 		iface->bss[i - 1] = iface->bss[i];
+
 	iface->num_bss--;
 
+	iface->bss[0]->interface_added = 0;
+	hostapd_drv_set_first_bss(iface->bss[0]);
+	hapd->interface_added = 1;
+
 	hostapd_drv_stop_ap(hapd);
 	hostapd_bss_deinit(hapd);
 	hostapd_remove_iface_bss_conf(iface->conf, hapd->conf);
@@ -268,6 +389,58 @@
 }
 
 static uc_value_t *
+uc_hostapd_iface_set_bss_order(uc_vm_t *vm, size_t nargs)
+{
+	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
+	uc_value_t *bss_list = uc_fn_arg(0);
+	struct hostapd_data **new_bss;
+	struct hostapd_bss_config **new_conf;
+
+	if (!iface)
+		return NULL;
+
+	if (ucv_type(bss_list) != UC_ARRAY ||
+	    ucv_array_length(bss_list) != iface->num_bss)
+		return NULL;
+
+	new_bss = calloc(iface->num_bss, sizeof(*new_bss));
+	new_conf = calloc(iface->num_bss, sizeof(*new_conf));
+	for (size_t i = 0; i < iface->num_bss; i++) {
+		struct hostapd_data *bss;
+
+		bss = ucv_resource_data(ucv_array_get(bss_list, i), "hostapd.bss");
+		if (bss->iface != iface)
+			goto free;
+
+		for (size_t k = 0; k < i; k++)
+			if (new_bss[k] == bss)
+				goto free;
+
+		new_bss[i] = bss;
+		new_conf[i] = bss->conf;
+	}
+
+	new_bss[0]->interface_added = 0;
+	for (size_t i = 1; i < iface->num_bss; i++)
+		new_bss[i]->interface_added = 1;
+
+	free(iface->bss);
+	iface->bss = new_bss;
+
+	free(iface->conf->bss);
+	iface->conf->bss = new_conf;
+	iface->conf->num_bss = iface->num_bss;
+	hostapd_drv_set_first_bss(iface->bss[0]);
+
+	return ucv_boolean_new(true);
+
+free:
+	free(new_bss);
+	free(new_conf);
+	return NULL;
+}
+
+static uc_value_t *
 uc_hostapd_bss_ctrl(uc_vm_t *vm, size_t nargs)
 {
 	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
@@ -292,18 +465,44 @@
 	return ucv_string_new_length(reply, reply_len);
 }
 
+static void
+uc_hostapd_disable_iface(struct hostapd_iface *iface)
+{
+	switch (iface->state) {
+	case HAPD_IFACE_DISABLED:
+		break;
+#ifdef CONFIG_ACS
+	case HAPD_IFACE_ACS:
+		acs_cleanup(iface);
+		iface->scan_cb = NULL;
+		/* fallthrough */
+#endif
+	default:
+		hostapd_disable_iface(iface);
+		break;
+	}
+}
+
 static uc_value_t *
 uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs)
 {
 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
 	int i;
 
+	if (!iface)
+		return NULL;
+
+	if (iface->state != HAPD_IFACE_ENABLED)
+		uc_hostapd_disable_iface(iface);
+
 	for (i = 0; i < iface->num_bss; i++) {
 		struct hostapd_data *hapd = iface->bss[i];
 
 		hostapd_drv_stop_ap(hapd);
-		hapd->started = 0;
+		hapd->beacon_set_done = 0;
 	}
+
+	return NULL;
 }
 
 static uc_value_t *
@@ -312,27 +511,37 @@
 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
 	uc_value_t *info = uc_fn_arg(0);
 	struct hostapd_config *conf;
+	bool changed = false;
 	uint64_t intval;
 	int i;
 
 	if (!iface)
 		return NULL;
 
-	if (!info)
+	if (!info) {
+		iface->freq = 0;
 		goto out;
+	}
 
 	if (ucv_type(info) != UC_OBJECT)
 		return NULL;
 
+#define UPDATE_VAL(field, name)							\
+	if ((intval = ucv_int64_get(ucv_object_get(info, name, NULL))) &&	\
+		!errno && intval != conf->field) do {				\
+		conf->field = intval;						\
+		changed = true;							\
+	} while(0)
+
 	conf = iface->conf;
-	if ((intval = ucv_int64_get(ucv_object_get(info, "op_class", NULL))) &&	!errno)
-		conf->op_class = intval;
-	if ((intval = ucv_int64_get(ucv_object_get(info, "hw_mode", NULL))) && !errno)
-		conf->hw_mode = intval;
-	if ((intval = ucv_int64_get(ucv_object_get(info, "channel", NULL))) && !errno)
-		conf->channel = intval;
-	if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno)
-		conf->secondary_channel = intval;
+	UPDATE_VAL(op_class, "op_class");
+	UPDATE_VAL(hw_mode, "hw_mode");
+	UPDATE_VAL(channel, "channel");
+	UPDATE_VAL(secondary_channel, "sec_channel");
+	if (!changed &&
+	    (iface->bss[0]->beacon_set_done ||
+	     iface->state == HAPD_IFACE_DFS))
+		return ucv_boolean_new(true);
 
 	intval = ucv_int64_get(ucv_object_get(info, "center_seg0_idx", NULL));
 	if (!errno)
@@ -346,13 +555,30 @@
 	if (!errno)
 		hostapd_set_oper_chwidth(conf, intval);
 
+	intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL));
+	if (!errno)
+		iface->freq = intval;
+	else
+		iface->freq = 0;
+	conf->acs = 0;
+
 out:
-	if (conf->channel)
+	switch (iface->state) {
+	case HAPD_IFACE_ENABLED:
+		if (!hostapd_is_dfs_required(iface) ||
+			hostapd_is_dfs_chan_available(iface))
+			break;
+		wpa_printf(MSG_INFO, "DFS CAC required on new channel, restart interface");
+		/* fallthrough */
+	default:
+		uc_hostapd_disable_iface(iface);
+		break;
+	}
+
+	if (conf->channel && !iface->freq)
 		iface->freq = hostapd_hw_get_freq(iface->bss[0], conf->channel);
 
-	if (hostapd_is_dfs_required(iface) && !hostapd_is_dfs_chan_available(iface)) {
-		wpa_printf(MSG_INFO, "DFS CAC required on new channel, restart interface");
-		hostapd_disable_iface(iface);
+	if (iface->state != HAPD_IFACE_ENABLED) {
 		hostapd_enable_iface(iface);
 		return ucv_boolean_new(true);
 	}
@@ -361,7 +587,6 @@
 		struct hostapd_data *hapd = iface->bss[i];
 		int ret;
 
-		hapd->started = 1;
 		hapd->conf->start_disabled = 0;
 		hostapd_set_freq(hapd, conf->hw_mode, iface->freq,
 				 conf->channel,
@@ -428,6 +653,55 @@
 	return ucv_boolean_new(!ret);
 }
 
+static uc_value_t *
+uc_hostapd_bss_rename(uc_vm_t *vm, size_t nargs)
+{
+	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
+	uc_value_t *ifname_arg = uc_fn_arg(0);
+	char prev_ifname[IFNAMSIZ + 1];
+	struct sta_info *sta;
+	const char *ifname;
+	int ret;
+
+	if (!hapd || ucv_type(ifname_arg) != UC_STRING)
+		return NULL;
+
+	os_strlcpy(prev_ifname, hapd->conf->iface, sizeof(prev_ifname));
+	ifname = ucv_string_get(ifname_arg);
+
+	hostapd_ubus_free_bss(hapd);
+	if (interfaces->ctrl_iface_deinit)
+		interfaces->ctrl_iface_deinit(hapd);
+
+	ret = hostapd_drv_if_rename(hapd, WPA_IF_AP_BSS, NULL, ifname);
+	if (ret)
+		goto out;
+
+	for (sta = hapd->sta_list; sta; sta = sta->next) {
+		char cur_name[IFNAMSIZ + 1], new_name[IFNAMSIZ + 1];
+
+		if (!(sta->flags & WLAN_STA_WDS) || sta->pending_wds_enable)
+			continue;
+
+		snprintf(cur_name, sizeof(cur_name), "%s.sta%d", prev_ifname, sta->aid);
+		snprintf(new_name, sizeof(new_name), "%s.sta%d", ifname, sta->aid);
+		hostapd_drv_if_rename(hapd, WPA_IF_AP_VLAN, cur_name, new_name);
+	}
+
+	if (!strncmp(hapd->conf->ssid.vlan, hapd->conf->iface, sizeof(hapd->conf->ssid.vlan)))
+		os_strlcpy(hapd->conf->ssid.vlan, ifname, sizeof(hapd->conf->ssid.vlan));
+	os_strlcpy(hapd->conf->iface, ifname, sizeof(hapd->conf->iface));
+	hostapd_ubus_add_bss(hapd);
+
+	hostapd_ucode_update_interfaces();
+out:
+	if (interfaces->ctrl_iface_init)
+		interfaces->ctrl_iface_init(hapd);
+
+	return ret ? NULL : ucv_boolean_new(true);
+}
+
+
 int hostapd_ucode_init(struct hapd_interfaces *ifaces)
 {
 	static const uc_function_list_t global_fns[] = {
@@ -441,9 +715,11 @@
 	static const uc_function_list_t bss_fns[] = {
 		{ "ctrl", uc_hostapd_bss_ctrl },
 		{ "set_config", uc_hostapd_bss_set_config },
+		{ "rename", uc_hostapd_bss_rename },
 		{ "delete", uc_hostapd_bss_delete },
 	};
 	static const uc_function_list_t iface_fns[] = {
+		{ "set_bss_order", uc_hostapd_iface_set_bss_order },
 		{ "add_bss", uc_hostapd_iface_add_bss },
 		{ "stop", uc_hostapd_iface_stop },
 		{ "start", uc_hostapd_iface_start },
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 896ef46..2beeb9a 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
@@ -298,9 +298,15 @@
 uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx)
 {
 	uc_value_t *val = wpa_ucode_registry_get(reg, idx);
+	void **dataptr;
+
+	if (!val)
+		return NULL;
 
-	if (val)
-		ucv_array_set(reg, idx - 1, NULL);
+	ucv_array_set(reg, idx - 1, NULL);
+	dataptr = ucv_resource_dataptr(val, NULL);
+	if (dataptr)
+		*dataptr = NULL;
 
 	return val;
 }
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 d120ed6..6cba73d 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
@@ -2,6 +2,7 @@
 #include "utils/common.h"
 #include "utils/ucode.h"
 #include "drivers/driver.h"
+#include "ap/hostapd.h"
 #include "wpa_supplicant_i.h"
 #include "wps_supplicant.h"
 #include "bss.h"
@@ -135,6 +136,7 @@
 uc_wpas_add_iface(uc_vm_t *vm, size_t nargs)
 {
 	uc_value_t *info = uc_fn_arg(0);
+	uc_value_t *driver = ucv_object_get(info, "driver", NULL);
 	uc_value_t *ifname = ucv_object_get(info, "iface", NULL);
 	uc_value_t *bridge = ucv_object_get(info, "bridge", NULL);
 	uc_value_t *config = ucv_object_get(info, "config", NULL);
@@ -153,6 +155,22 @@
 		.ctrl_interface = ucv_string_get(ctrl),
 	};
 
+	if (driver) {
+		const char *drvname;
+		if (ucv_type(driver) != UC_STRING)
+			goto out;
+
+		iface.driver = NULL;
+		drvname = ucv_string_get(driver);
+		for (int i = 0; wpa_drivers[i]; i++) {
+			if (!strcmp(drvname, wpa_drivers[i]->name))
+				iface.driver = wpa_drivers[i]->name;
+		}
+
+		if (!iface.driver)
+			goto out;
+	}
+
 	if (!iface.ifname || !iface.confname)
 		goto out;
 
@@ -224,6 +242,15 @@
 		ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan));
 		ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq));
 	}
+
+#ifdef CONFIG_MESH
+	if (wpa_s->ifmsh) {
+		struct hostapd_iface *ifmsh = wpa_s->ifmsh;
+
+		ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(ifmsh->conf->secondary_channel));
+		ucv_object_add(ret, "frequency", ucv_int64_new(ifmsh->freq));
+	}
+#endif
 
 	return ret;
 }
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 f3bb828..94af977 100644
--- a/recipes-wifi/wpa-supplicant/wpa-supplicant_2.10.3.bb
+++ b/recipes-wifi/wpa-supplicant/wpa-supplicant_2.10.3.bb
@@ -10,7 +10,7 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
 FILESEXTRAPATHS_prepend := "${THISDIR}/files/patches-${PV}:"
 
-SRCREV ?= "599d00be9de2846c6ea18c1487d8329522ade22b"
+SRCREV ?= "e5ccbfc69ecf297590341ae8b461edba9d8e964c"
 SRC_URI = "git://w1.fi/hostap.git;protocol=https;branch=main \
            file://wpa-supplicant.sh \
            file://wpa_supplicant.conf \