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

[Description]
9403fa9 [[MAC80211][misc] increase beacon loss count from 7 to 20]
b11c297 [MAC80211][mt76][Change panther's prek info encoded mask to be compatible with eagle]
9e0f9b9 [MAC80211][app][Add atenl prek support in eagle]
e9aefca [[MAC80211][misc] add CONFIG option in wpa_supplicant config files]
822c722 [MAC80211][mt76][Disable SW-ACI by default]
b792365 [MAC80211][misc][Add autofill EHT BF config in netifd script]
a3776b8 [MAC80211][hostapd][Add vendor command for certification]

[Release-log]

Change-Id: I117d597ff9068fdd0fee4cdcca699c8d610e945e
diff --git a/recipes-wifi/atenl/files/src/atenl.h b/recipes-wifi/atenl/files/src/atenl.h
index 13f7b95..9f8b796 100644
--- a/recipes-wifi/atenl/files/src/atenl.h
+++ b/recipes-wifi/atenl/files/src/atenl.h
@@ -24,11 +24,11 @@
 #define RACFG_HLEN		12
 #define RACFG_MAGIC_NO		0x18142880
 #define PRE_CAL_INFO		16
-#define DPD_INFO_CH_SHIFT	24
-#define DPD_INFO_2G_SHIFT 	16
-#define DPD_INFO_5G_SHIFT	8
+#define DPD_INFO_CH_SHIFT	30
+#define DPD_INFO_2G_SHIFT	20
+#define DPD_INFO_5G_SHIFT	10
 #define DPD_INFO_6G_SHIFT	0
-#define DPD_INFO_MASK 		GENMASK(7, 0)
+#define DPD_INFO_MASK		GENMASK(9, 0)
 #define MT_EE_CAL_UNIT		1024
 
 #define RACFG_CMD_TYPE_MASK	GENMASK(14, 0)
diff --git a/recipes-wifi/atenl/files/src/eeprom.c b/recipes-wifi/atenl/files/src/eeprom.c
index b71708e..f63bc9e 100644
--- a/recipes-wifi/atenl/files/src/eeprom.c
+++ b/recipes-wifi/atenl/files/src/eeprom.c
@@ -6,7 +6,7 @@
 
 #include "atenl.h"
 
-#define EEPROM_PART_SIZE 0x64000
+#define EEPROM_PART_SIZE 0xFF000
 char *eeprom_file;
 
 static int
diff --git a/recipes-wifi/atenl/files/src/nl.c b/recipes-wifi/atenl/files/src/nl.c
index beada05..a8e2ea9 100644
--- a/recipes-wifi/atenl/files/src/nl.c
+++ b/recipes-wifi/atenl/files/src/nl.c
@@ -1387,17 +1387,21 @@
 
 int atenl_nl_precal_sync_from_driver(struct atenl *an, enum prek_ops ops)
 {
-#define GROUP_IND_MASK  	BIT(0)
-#define DPD_IND_MASK  		GENMASK(3, 1)
+#define GROUP_IND_MASK		BIT(0)
+#define GROUP_IND_MASK_7996	GENMASK(2, 0)
+#define DPD_IND_MASK		GENMASK(3, 1)
+#define DPD_IND_MASK_7996	GENMASK(5, 3)
 	int ret;
 	u32 i, times, group_size, dpd_size, total_size, transmit_size, offs;
-	u32 dpd_per_chan_size, dpd_chan_num[3], total_chan_num;
-	u32 size, base, base_idx, *size_ptr;
-	u8 cal_indicator, *precal_info;
+	u32 dpd_per_chan_size, dpd_chan_ratio[3], total_ratio;
+	u32 size, base, base_idx, dpd_base_map, *size_ptr;
+	u8 cal_indicator, group_ind_mask, dpd_ind_mask, *precal_info;
 	struct atenl_nl_priv nl_priv = { .an = an };
 
 	offs = an->eeprom_prek_offs;
 	cal_indicator = an->eeprom_data[offs];
+	group_ind_mask = is_mt7996(an) ? GROUP_IND_MASK_7996 : GROUP_IND_MASK;
+	dpd_ind_mask = is_mt7996(an) ? DPD_IND_MASK_7996 : DPD_IND_MASK;
 
 	if (cal_indicator) {
 		precal_info = an->eeprom_data + an->eeprom_size;
@@ -1405,33 +1409,43 @@
 		group_size = an->cal_info[0];
 		dpd_size = an->cal_info[1];
 		total_size = group_size + dpd_size;
-		dpd_chan_num[0] = (an->cal_info[2] >> DPD_INFO_6G_SHIFT) & DPD_INFO_MASK;
-		dpd_chan_num[1] = (an->cal_info[2] >> DPD_INFO_5G_SHIFT) & DPD_INFO_MASK;
-		dpd_chan_num[2] = (an->cal_info[2] >> DPD_INFO_2G_SHIFT) & DPD_INFO_MASK;
-		dpd_per_chan_size = (an->cal_info[2] >> DPD_INFO_CH_SHIFT) & DPD_INFO_MASK;
-		total_chan_num = dpd_chan_num[0] + dpd_chan_num[1] + dpd_chan_num[2];
+		dpd_chan_ratio[0] = (an->cal_info[2] >> DPD_INFO_6G_SHIFT) &
+				    DPD_INFO_MASK;
+		dpd_chan_ratio[1] = (an->cal_info[2] >> DPD_INFO_5G_SHIFT) &
+				    DPD_INFO_MASK;
+		dpd_chan_ratio[2] = (an->cal_info[2] >> DPD_INFO_2G_SHIFT) &
+				    DPD_INFO_MASK;
+		dpd_per_chan_size = (an->cal_info[2] >> DPD_INFO_CH_SHIFT) &
+				    DPD_INFO_MASK;
+		total_ratio = dpd_chan_ratio[0] + dpd_chan_ratio[1] +
+			      dpd_chan_ratio[2];
 	}
 
 	switch (ops){
 	case PREK_SYNC_ALL:
 		size_ptr = &total_size;
 		base_idx = 0;
+		dpd_base_map = 0;
 		goto start;
 	case PREK_SYNC_GROUP:
 		size_ptr = &group_size;
 		base_idx = 0;
+		dpd_base_map = 0;
 		goto start;
 	case PREK_SYNC_DPD_6G:
 		size_ptr = &dpd_size;
 		base_idx = 0;
+		dpd_base_map = is_mt7996(an) ? GENMASK(2, 1) : 0;
 		goto start;
 	case PREK_SYNC_DPD_5G:
 		size_ptr = &dpd_size;
 		base_idx = 1;
+		dpd_base_map = is_mt7996(an) ? BIT(2) : BIT(0);
 		goto start;
 	case PREK_SYNC_DPD_2G:
 		size_ptr = &dpd_size;
 		base_idx = 2;
+		dpd_base_map = is_mt7996(an) ? 0 : GENMASK(1, 0);
 
 start:
 		if (unl_genl_init(&nl_priv.unl, "nl80211") < 0) {
@@ -1446,19 +1460,27 @@
 		group_size = an->cal_info[0];
 		dpd_size = an->cal_info[1];
 		total_size = group_size + dpd_size;
-		dpd_chan_num[0] = (an->cal_info[2] >> DPD_INFO_6G_SHIFT) & DPD_INFO_MASK;
-		dpd_chan_num[1] = (an->cal_info[2] >> DPD_INFO_5G_SHIFT) & DPD_INFO_MASK;
-		dpd_chan_num[2] = (an->cal_info[2] >> DPD_INFO_2G_SHIFT) & DPD_INFO_MASK;
-		dpd_per_chan_size = (an->cal_info[2] >> DPD_INFO_CH_SHIFT) & DPD_INFO_MASK;
-		total_chan_num = dpd_chan_num[0] + dpd_chan_num[1] + dpd_chan_num[2];
+		dpd_chan_ratio[0] = (an->cal_info[2] >> DPD_INFO_6G_SHIFT) &
+				    DPD_INFO_MASK;
+		dpd_chan_ratio[1] = (an->cal_info[2] >> DPD_INFO_5G_SHIFT) &
+				    DPD_INFO_MASK;
+		dpd_chan_ratio[2] = (an->cal_info[2] >> DPD_INFO_2G_SHIFT) &
+				    DPD_INFO_MASK;
+		dpd_per_chan_size = (an->cal_info[2] >> DPD_INFO_CH_SHIFT) &
+				    DPD_INFO_MASK;
+		total_ratio = dpd_chan_ratio[0] + dpd_chan_ratio[1] +
+			      dpd_chan_ratio[2];
 		transmit_size = an->cal_info[3];
 
 		size = *size_ptr;
-		size = (size_ptr == &dpd_size) ? (size / total_chan_num * dpd_chan_num[base_idx]) :
-						 size;
+		if (size_ptr == &dpd_size)
+			size = size / total_ratio * dpd_chan_ratio[base_idx];
+
 		base = 0;
-		for (i = 0; i < base_idx; i++) {
-			base += dpd_chan_num[i] * dpd_per_chan_size * MT_EE_CAL_UNIT;
+		for (i = 0; i < 3; i++) {
+			if (dpd_base_map & BIT(i))
+				base += dpd_chan_ratio[i] * dpd_per_chan_size *
+					MT_EE_CAL_UNIT;
 		}
 		base += (size_ptr == &dpd_size) ? group_size : 0;
 
@@ -1475,15 +1497,15 @@
 		ret = atenl_eeprom_update_precal(an, base, size);
 		break;
 	case PREK_CLEAN_GROUP:
-		if (!(cal_indicator & GROUP_IND_MASK))
+		if (!(cal_indicator & group_ind_mask))
 			return 0;
-		an->cal_info[4] = cal_indicator & (u8) ~GROUP_IND_MASK;
+		an->cal_info[4] = cal_indicator & group_ind_mask;
 		ret = atenl_eeprom_update_precal(an, 0, group_size);
 		break;
 	case PREK_CLEAN_DPD:
-		if (!(cal_indicator & DPD_IND_MASK))
+		if (!(cal_indicator & dpd_ind_mask))
 			return 0;
-		an->cal_info[4] = cal_indicator & (u8) ~DPD_IND_MASK;
+		an->cal_info[4] = cal_indicator & dpd_ind_mask;
 		ret = atenl_eeprom_update_precal(an, group_size, dpd_size);
 		break;
 	default:
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
index 1ecf08b..14a9603 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
@@ -217,7 +217,7 @@
 +void wpa_supplicant_apply_eht_overrides(
 +	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 +	struct wpa_driver_associate_params *params);
-+#endif CONFIG_EHT_OVERRIDES
++#endif /* CONFIG_EHT_OVERRIDES */
 +
  
  int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
new file mode 100644
index 0000000..5b9f4df
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
@@ -0,0 +1,527 @@
+From 47b475634804175c77621d492ad6129a31dcda4d 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] hostapd: mtk: Add vendor for CAPI certification commands
+
+---
+ hostapd/ctrl_iface.c              |  95 +++++++++++++++
+ src/ap/ap_drv_ops.c               |  21 ++++
+ src/ap/ap_drv_ops.h               |   3 +
+ src/common/mtk_vendor.h           |  32 +-----
+ src/drivers/driver.h              |  22 ++++
+ src/drivers/driver_nl80211.c      | 185 ++++++++++++++++++++++++++++++
+ src/drivers/driver_nl80211.h      |   1 +
+ src/drivers/driver_nl80211_capa.c |   3 +
+ 8 files changed, 332 insertions(+), 30 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index e1e9270..58bb710 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -38,6 +38,7 @@
+ #endif /* CONFIG_DPP */
+ #include "common/wpa_ctrl.h"
+ #include "common/ptksa_cache.h"
++#include "common/mtk_vendor.h"
+ #include "crypto/tls.h"
+ #include "drivers/driver.h"
+ #include "eapol_auth/eapol_auth_sm.h"
+@@ -3715,6 +3716,96 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
+ 	return pos - buf;
+ }
+ 
++static int
++hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
++					 char *buf, size_t buflen)
++{
++	char *pos, *value, *config = cmd;
++	enum mtk_vendor_attr_wireless_ctrl sub_cmd;
++
++	pos = os_strchr(config, '=');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if(pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strncmp(config, "fixed_mcs", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS;
++	else if (os_strncmp(config, "ofdma", 5) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA;
++	else if (os_strncmp(config, "ppdu_type", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE;
++	else if (os_strncmp(config, "nusers_ofdma", 12) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA;
++	else if (os_strncmp(config, "add_ba_req_bufsize", 18) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE;
++	else if (os_strncmp(config, "mimo", 4) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO;
++	else if (os_strncmp(config, "cert", 4) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT ;
++	else {
++		wpa_printf(MSG_ERROR,
++			"Unsupported parameter %s for ap_wireless", config);
++		return -1;
++	}
++
++	if (hostapd_drv_ap_wireless(hapd, (u8) sub_cmd, atoi(value)) != 0)
++		return -1;
++
++	return os_snprintf(buf, buflen, "OK\n");
++}
++
++static int
++hostapd_ctrl_iface_ap_rfeatures(struct hostapd_data *hapd, char *cmd,
++					 char *buf, size_t buflen)
++{
++	char *pos, *value, *type, *config = cmd;
++	enum mtk_vendor_attr_rfeature_ctrl sub_cmd;
++
++	pos = os_strchr(config, '=');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if(pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strncmp(config, "he_gi", 5) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI;
++	else if (os_strncmp(config, "he_ltf", 6) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF;
++	else if (os_strncmp(config, "trig_type", 9) == 0) {
++		pos = os_strchr(value, ',');
++		if (pos == NULL)
++			return -1;
++		*pos++ = '\0';
++		if(pos == NULL)
++			return -1;
++		type = pos;
++		goto trigtype;
++	} else if (os_strcmp(config, "ack_policy") == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY;
++	else {
++		wpa_printf(MSG_ERROR,
++			"Unsupported parameter %s for ap_rfeatures", config);
++		return -1;
++	}
++
++	if (hostapd_drv_ap_rfeatures(hapd, (u8) sub_cmd, atoi(value)) != 0)
++		return -1;
++	goto exit;
++
++trigtype:
++	if (hostapd_drv_ap_trig_type(hapd, atoi(value), atoi(type)) != 0)
++		return -1;
++
++exit:
++	return os_snprintf(buf, buflen, "OK\n");
++}
+ 
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+@@ -4286,6 +4377,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 		reply_len = hostapd_ctrl_iface_get_bss_color(hapd, reply, reply_size);
+ 	} else if (os_strncmp(buf, "AVAL_COLOR_BMP", 14) == 0) {
+ 		reply_len = hostapd_ctrl_iface_get_aval_color_bmp(hapd, reply, reply_size);
++	} else if (os_strncmp(buf, "ap_wireless ", 12) == 0) {
++		reply_len = hostapd_ctrl_iface_ap_wireless(hapd, buf + 12, reply, reply_size);
++	} else if (os_strncmp(buf, "ap_rfeatures ", 13) == 0) {
++		reply_len = hostapd_ctrl_iface_ap_rfeatures(hapd, buf + 13, reply, reply_size);
+ 	} else {
+ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ 		reply_len = 16;
+diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
+index 40b9a20..52d0fff 100644
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -1100,3 +1100,24 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
+ 		return 0;
+ 	return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
+ }
++
++int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
++{
++	if (!hapd->driver || !hapd->driver->ap_wireless)
++		return 0;
++	return hapd->driver->ap_wireless(hapd->drv_priv, sub_vendor_id, value);
++}
++
++int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
++{
++	if (!hapd->driver || !hapd->driver->ap_rfeatures)
++		return 0;
++	return hapd->driver->ap_rfeatures(hapd->drv_priv, sub_vendor_id, value);
++}
++
++int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type)
++{
++	if (!hapd->driver || !hapd->driver->ap_trigtype)
++		return 0;
++	return hapd->driver->ap_trigtype(hapd->drv_priv, enable, type);
++}
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index 136a3ac..659c3f8 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -151,6 +151,9 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
+ int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu);
+ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd,
+ 				       u64 *aval_color_bmp);
++int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
++int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
++int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
+ 
+ #include "drivers/driver.h"
+ 
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index a99e6f2..32438af 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -48,16 +48,6 @@ enum mtk_vendor_attr_edcca_dump {
+ 		NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP - 1
+ };
+ 
+-
+-static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_3wire_ctrl {
+ 	MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC,
+ 
+@@ -69,10 +59,6 @@ enum mtk_vendor_attr_3wire_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1
+ };
+ 
+-static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
+-	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_csi_ctrl {
+ 	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
+ 
+@@ -169,7 +155,7 @@ enum mtk_vendor_attr_wireless_ctrl {
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
+-	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA,
+ 
+ 	/* keep last */
+@@ -189,11 +175,6 @@ enum mtk_vendor_attr_wireless_dump {
+ 		NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
+ };
+ 
+-static const struct nla_policy
+-wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
+-	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_rfeature_ctrl {
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
+ 
+@@ -203,6 +184,7 @@ enum mtk_vendor_attr_rfeature_ctrl {
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
+ 
+ 	/* keep last */
+ 	NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
+@@ -244,16 +226,6 @@ enum mtk_vendor_attr_ibf_dump {
+ 		NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
+ };
+ 
+-static struct nla_policy
+-ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
+-	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
+-};
+-
+-static struct nla_policy
+-ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
+-	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_bss_color_ctrl {
+ 	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index 7f6392f..d4f34b6 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -4779,6 +4779,28 @@ struct wpa_driver_ops {
+ 	 *
+ 	 */
+ 	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
++
++	/**
++	* ap_wireless - set wireless command
++	* @priv: Private driver interface data
++	* @value: value
++	*/
++	int (*ap_wireless)(void *priv, u8 mode, int value);
++
++	/**
++	* ap_rfeatures - set ap rf features command
++	* @priv: Private driver interface data
++	* @value: value
++	*/
++	int (*ap_rfeatures)(void *priv, u8 mode, int value);
++
++	/**
++	* ap_trigtype - set trigger type
++	* @priv: Private driver interface data
++	* @enable: enable or disable
++	* @type: trigger type
++	*/
++	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
+ };
+ 
+ /**
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index f9a8763..9c1717f 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -74,6 +74,57 @@ enum nlmsgerr_attrs {
+ #endif /* ANDROID */
+ 
+ 
++static struct nla_policy
++ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
++	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
++};
++
++static struct nla_policy
++ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
++	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
++};
++
++static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
++	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
++};
++
++static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
++	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
++};
++
+ static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
+ {
+ 	struct nl_sock *handle;
+@@ -13005,6 +13056,137 @@ fail:
+ 	return -ENOBUFS;
+ }
+ 
++static int nl80211_ap_wireless(void *priv, u8 sub_vendor_id, int value)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data;
++	int ret;
++
++	if (!drv->mtk_wireless_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap wireless control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	if (sub_vendor_id == MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE)
++		nla_put_u16(msg, sub_vendor_id, (u16) value);
++	else
++		nla_put_u8(msg, sub_vendor_id, (u8) value);
++
++	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 ap_wireless. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
++static int nl80211_ap_rfeatures(void *priv, u8 sub_vendor_id, int value)
++{
++	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_rfeatures_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap rfeatures control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	nla_put_u8(msg, sub_vendor_id, (u8) value);
++
++	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 rf_features. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
++static int nl80211_ap_trigtype(void *priv, u8 enable, u8 type)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data, *data2;
++	int ret;
++
++	if (!drv->mtk_rfeatures_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap rfeatures control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	data2 = nla_nest_start(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG);
++	if (!data2)
++		goto fail;
++
++	nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN, enable);
++	nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE, type);
++
++	nla_nest_end(msg, data2);
++	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 trig_type. 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",
+@@ -13162,4 +13344,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.amsdu_ctrl = nl80211_enable_amsdu,
+ 	.amsdu_dump = nl80211_dump_amsdu,
+ 	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
++	.ap_wireless = nl80211_ap_wireless,
++	.ap_rfeatures = nl80211_ap_rfeatures,
++	.ap_trigtype = nl80211_ap_trigtype,
+ };
+diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
+index 72c7abd..7a03446 100644
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -187,6 +187,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_ibf_vendor_cmd_avail:1;
+ 	unsigned int mtk_wireless_vendor_cmd_avail:1;
+ 	unsigned int mtk_bss_color_vendor_cmd_avail:1;
++	unsigned int mtk_rfeatures_vendor_cmd_avail:1;
+ 
+ 	u64 vendor_scan_cookie;
+ 	u64 remain_on_chan_cookie;
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index e7c6f39..6f4d029 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1095,6 +1095,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+ 				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
+ 					drv->mtk_bss_color_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
++					drv->mtk_rfeatures_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc b/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
index 7b5afa4..e83e1b4 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
@@ -87,5 +87,6 @@
     file://mtk-0023-hostapd-mtk-Add-channel-information-for-hostapd-relo.patch \
     file://mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch \
     file://mtk-0025-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch \
+    file://mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch \
     file://mtk-0100-hostapd-mtk-update-eht-operation-elem.patch \
     "
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch b/recipes-wifi/hostapd/files/patches/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
index 1ecf08b..14a9603 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
@@ -217,7 +217,7 @@
 +void wpa_supplicant_apply_eht_overrides(
 +	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 +	struct wpa_driver_associate_params *params);
-+#endif CONFIG_EHT_OVERRIDES
++#endif /* CONFIG_EHT_OVERRIDES */
 +
  
  int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch b/recipes-wifi/hostapd/files/patches/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
new file mode 100644
index 0000000..5b9f4df
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
@@ -0,0 +1,527 @@
+From 47b475634804175c77621d492ad6129a31dcda4d 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] hostapd: mtk: Add vendor for CAPI certification commands
+
+---
+ hostapd/ctrl_iface.c              |  95 +++++++++++++++
+ src/ap/ap_drv_ops.c               |  21 ++++
+ src/ap/ap_drv_ops.h               |   3 +
+ src/common/mtk_vendor.h           |  32 +-----
+ src/drivers/driver.h              |  22 ++++
+ src/drivers/driver_nl80211.c      | 185 ++++++++++++++++++++++++++++++
+ src/drivers/driver_nl80211.h      |   1 +
+ src/drivers/driver_nl80211_capa.c |   3 +
+ 8 files changed, 332 insertions(+), 30 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index e1e9270..58bb710 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -38,6 +38,7 @@
+ #endif /* CONFIG_DPP */
+ #include "common/wpa_ctrl.h"
+ #include "common/ptksa_cache.h"
++#include "common/mtk_vendor.h"
+ #include "crypto/tls.h"
+ #include "drivers/driver.h"
+ #include "eapol_auth/eapol_auth_sm.h"
+@@ -3715,6 +3716,96 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
+ 	return pos - buf;
+ }
+ 
++static int
++hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
++					 char *buf, size_t buflen)
++{
++	char *pos, *value, *config = cmd;
++	enum mtk_vendor_attr_wireless_ctrl sub_cmd;
++
++	pos = os_strchr(config, '=');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if(pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strncmp(config, "fixed_mcs", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS;
++	else if (os_strncmp(config, "ofdma", 5) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA;
++	else if (os_strncmp(config, "ppdu_type", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE;
++	else if (os_strncmp(config, "nusers_ofdma", 12) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA;
++	else if (os_strncmp(config, "add_ba_req_bufsize", 18) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE;
++	else if (os_strncmp(config, "mimo", 4) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO;
++	else if (os_strncmp(config, "cert", 4) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT ;
++	else {
++		wpa_printf(MSG_ERROR,
++			"Unsupported parameter %s for ap_wireless", config);
++		return -1;
++	}
++
++	if (hostapd_drv_ap_wireless(hapd, (u8) sub_cmd, atoi(value)) != 0)
++		return -1;
++
++	return os_snprintf(buf, buflen, "OK\n");
++}
++
++static int
++hostapd_ctrl_iface_ap_rfeatures(struct hostapd_data *hapd, char *cmd,
++					 char *buf, size_t buflen)
++{
++	char *pos, *value, *type, *config = cmd;
++	enum mtk_vendor_attr_rfeature_ctrl sub_cmd;
++
++	pos = os_strchr(config, '=');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if(pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strncmp(config, "he_gi", 5) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI;
++	else if (os_strncmp(config, "he_ltf", 6) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF;
++	else if (os_strncmp(config, "trig_type", 9) == 0) {
++		pos = os_strchr(value, ',');
++		if (pos == NULL)
++			return -1;
++		*pos++ = '\0';
++		if(pos == NULL)
++			return -1;
++		type = pos;
++		goto trigtype;
++	} else if (os_strcmp(config, "ack_policy") == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY;
++	else {
++		wpa_printf(MSG_ERROR,
++			"Unsupported parameter %s for ap_rfeatures", config);
++		return -1;
++	}
++
++	if (hostapd_drv_ap_rfeatures(hapd, (u8) sub_cmd, atoi(value)) != 0)
++		return -1;
++	goto exit;
++
++trigtype:
++	if (hostapd_drv_ap_trig_type(hapd, atoi(value), atoi(type)) != 0)
++		return -1;
++
++exit:
++	return os_snprintf(buf, buflen, "OK\n");
++}
+ 
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+@@ -4286,6 +4377,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 		reply_len = hostapd_ctrl_iface_get_bss_color(hapd, reply, reply_size);
+ 	} else if (os_strncmp(buf, "AVAL_COLOR_BMP", 14) == 0) {
+ 		reply_len = hostapd_ctrl_iface_get_aval_color_bmp(hapd, reply, reply_size);
++	} else if (os_strncmp(buf, "ap_wireless ", 12) == 0) {
++		reply_len = hostapd_ctrl_iface_ap_wireless(hapd, buf + 12, reply, reply_size);
++	} else if (os_strncmp(buf, "ap_rfeatures ", 13) == 0) {
++		reply_len = hostapd_ctrl_iface_ap_rfeatures(hapd, buf + 13, reply, reply_size);
+ 	} else {
+ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ 		reply_len = 16;
+diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
+index 40b9a20..52d0fff 100644
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -1100,3 +1100,24 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
+ 		return 0;
+ 	return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
+ }
++
++int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
++{
++	if (!hapd->driver || !hapd->driver->ap_wireless)
++		return 0;
++	return hapd->driver->ap_wireless(hapd->drv_priv, sub_vendor_id, value);
++}
++
++int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
++{
++	if (!hapd->driver || !hapd->driver->ap_rfeatures)
++		return 0;
++	return hapd->driver->ap_rfeatures(hapd->drv_priv, sub_vendor_id, value);
++}
++
++int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type)
++{
++	if (!hapd->driver || !hapd->driver->ap_trigtype)
++		return 0;
++	return hapd->driver->ap_trigtype(hapd->drv_priv, enable, type);
++}
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index 136a3ac..659c3f8 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -151,6 +151,9 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
+ int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu);
+ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd,
+ 				       u64 *aval_color_bmp);
++int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
++int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
++int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
+ 
+ #include "drivers/driver.h"
+ 
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index a99e6f2..32438af 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -48,16 +48,6 @@ enum mtk_vendor_attr_edcca_dump {
+ 		NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP - 1
+ };
+ 
+-
+-static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_3wire_ctrl {
+ 	MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC,
+ 
+@@ -69,10 +59,6 @@ enum mtk_vendor_attr_3wire_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1
+ };
+ 
+-static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
+-	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_csi_ctrl {
+ 	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
+ 
+@@ -169,7 +155,7 @@ enum mtk_vendor_attr_wireless_ctrl {
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
+-	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA,
+ 
+ 	/* keep last */
+@@ -189,11 +175,6 @@ enum mtk_vendor_attr_wireless_dump {
+ 		NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
+ };
+ 
+-static const struct nla_policy
+-wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
+-	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_rfeature_ctrl {
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
+ 
+@@ -203,6 +184,7 @@ enum mtk_vendor_attr_rfeature_ctrl {
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
+ 
+ 	/* keep last */
+ 	NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
+@@ -244,16 +226,6 @@ enum mtk_vendor_attr_ibf_dump {
+ 		NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
+ };
+ 
+-static struct nla_policy
+-ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
+-	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
+-};
+-
+-static struct nla_policy
+-ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
+-	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_bss_color_ctrl {
+ 	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index 7f6392f..d4f34b6 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -4779,6 +4779,28 @@ struct wpa_driver_ops {
+ 	 *
+ 	 */
+ 	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
++
++	/**
++	* ap_wireless - set wireless command
++	* @priv: Private driver interface data
++	* @value: value
++	*/
++	int (*ap_wireless)(void *priv, u8 mode, int value);
++
++	/**
++	* ap_rfeatures - set ap rf features command
++	* @priv: Private driver interface data
++	* @value: value
++	*/
++	int (*ap_rfeatures)(void *priv, u8 mode, int value);
++
++	/**
++	* ap_trigtype - set trigger type
++	* @priv: Private driver interface data
++	* @enable: enable or disable
++	* @type: trigger type
++	*/
++	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
+ };
+ 
+ /**
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index f9a8763..9c1717f 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -74,6 +74,57 @@ enum nlmsgerr_attrs {
+ #endif /* ANDROID */
+ 
+ 
++static struct nla_policy
++ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
++	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
++};
++
++static struct nla_policy
++ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
++	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
++};
++
++static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
++	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
++};
++
++static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
++	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
++};
++
+ static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
+ {
+ 	struct nl_sock *handle;
+@@ -13005,6 +13056,137 @@ fail:
+ 	return -ENOBUFS;
+ }
+ 
++static int nl80211_ap_wireless(void *priv, u8 sub_vendor_id, int value)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data;
++	int ret;
++
++	if (!drv->mtk_wireless_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap wireless control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	if (sub_vendor_id == MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE)
++		nla_put_u16(msg, sub_vendor_id, (u16) value);
++	else
++		nla_put_u8(msg, sub_vendor_id, (u8) value);
++
++	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 ap_wireless. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
++static int nl80211_ap_rfeatures(void *priv, u8 sub_vendor_id, int value)
++{
++	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_rfeatures_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap rfeatures control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	nla_put_u8(msg, sub_vendor_id, (u8) value);
++
++	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 rf_features. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
++static int nl80211_ap_trigtype(void *priv, u8 enable, u8 type)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data, *data2;
++	int ret;
++
++	if (!drv->mtk_rfeatures_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap rfeatures control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	data2 = nla_nest_start(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG);
++	if (!data2)
++		goto fail;
++
++	nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN, enable);
++	nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE, type);
++
++	nla_nest_end(msg, data2);
++	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 trig_type. 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",
+@@ -13162,4 +13344,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.amsdu_ctrl = nl80211_enable_amsdu,
+ 	.amsdu_dump = nl80211_dump_amsdu,
+ 	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
++	.ap_wireless = nl80211_ap_wireless,
++	.ap_rfeatures = nl80211_ap_rfeatures,
++	.ap_trigtype = nl80211_ap_trigtype,
+ };
+diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
+index 72c7abd..7a03446 100644
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -187,6 +187,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_ibf_vendor_cmd_avail:1;
+ 	unsigned int mtk_wireless_vendor_cmd_avail:1;
+ 	unsigned int mtk_bss_color_vendor_cmd_avail:1;
++	unsigned int mtk_rfeatures_vendor_cmd_avail:1;
+ 
+ 	u64 vendor_scan_cookie;
+ 	u64 remain_on_chan_cookie;
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index e7c6f39..6f4d029 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1095,6 +1095,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+ 				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
+ 					drv->mtk_bss_color_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
++					drv->mtk_rfeatures_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches/patches.inc b/recipes-wifi/hostapd/files/patches/patches.inc
index c38c7f6..7bc6508 100644
--- a/recipes-wifi/hostapd/files/patches/patches.inc
+++ b/recipes-wifi/hostapd/files/patches/patches.inc
@@ -87,4 +87,5 @@
     file://mtk-0023-hostapd-mtk-Add-channel-information-for-hostapd-relo.patch \
     file://mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch \
     file://mtk-0025-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch \
+    file://mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch \
     "
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0104-mac80211-mtk-inrease-beacon-loss-count.patch b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0104-mac80211-mtk-inrease-beacon-loss-count.patch
new file mode 100644
index 0000000..4a6a1da
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0104-mac80211-mtk-inrease-beacon-loss-count.patch
@@ -0,0 +1,33 @@
+From 80bf9fd1e3e551641514c0d0a3fd3608b3c8dbe7 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] inrease beacon loss count
+
+as per eagle code beacone loss time out is
+4 seconds.
+in 2G connection getting beacon loss logs in routed client
+scenario.
+
+so increasing beacon loss count from 7 to 20
+
+Signed-off-by: Amit Khatri <amit.khatri@mediatek.com>
+---
+ net/mac80211/mlme.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 8ab5c52..37657f7 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -61,7 +61,7 @@ MODULE_PARM_DESC(max_probe_tries,
+  * probe on beacon miss before declaring the connection lost
+  * default to what we want.
+  */
+-static int beacon_loss_count = 7;
++static int beacon_loss_count = 20;
+ module_param(beacon_loss_count, int, 0644);
+ MODULE_PARM_DESC(beacon_loss_count,
+ 		 "Number of beacon intervals before we decide beacon was lost.");
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc b/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
index 0f32537..2523b9d 100644
--- a/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
+++ b/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
@@ -71,6 +71,7 @@
     file://mtk-0015-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch \
     file://mtk-0016-mac80211-mtk-track-obss-color-bitmap.patch \
     file://mtk-0017-mac80211-mtk-aging-color-bitmap.patch \
+    file://mtk-0104-mac80211-mtk-inrease-beacon-loss-count.patch \
     file://mtk-9900-mac80211-mtk-mask-kernel-version-limitation-and-fil.patch \
     file://mtk-9901-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-i.patch \
     file://mtk-9902-mac80211-mtk-add-support-for-letting-drivers-registe.patch \
diff --git a/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch b/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch
index 82a210f..54a0f22 100644
--- a/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch
@@ -559,10 +559,10 @@
 +static int
 +mt7915_tm_dump_precal(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int type)
 +{
-+#define DPD_PER_CHAN_SIZE_MASK		GENMASK(31, 24)
-+#define DPD_CHAN_NUM_2G_MASK		GENMASK(23, 16)
-+#define DPD_CHAN_NUM_5G_MASK		GENMASK(15, 8)
-+#define DPD_CHAN_NUM_6G_MASK		GENMASK(7, 0)
++#define DPD_PER_CHAN_SIZE_MASK		GENMASK(31, 30)
++#define DPD_CHAN_NUM_2G_MASK		GENMASK(29, 20)
++#define DPD_CHAN_NUM_5G_MASK		GENMASK(19, 10)
++#define DPD_CHAN_NUM_6G_MASK		GENMASK(9, 0)
 +	struct mt7915_phy *phy = mphy->priv;
 +	struct mt7915_dev *dev = phy->dev;
 +	u32 i, group_size, dpd_size, total_size, dpd_per_chan_size, dpd_info = 0;
diff --git a/recipes-wifi/linux-mt76/files/patches/1135-mt76-mt7915-disable-SW-ACI-by-default.patch b/recipes-wifi/linux-mt76/files/patches/1135-mt76-mt7915-disable-SW-ACI-by-default.patch
new file mode 100644
index 0000000..6c465e9
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/1135-mt76-mt7915-disable-SW-ACI-by-default.patch
@@ -0,0 +1,104 @@
+From 3ef36d16305af80f400ef6ee3d087cd75c195191 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] 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.
+---
+ mt7915/main.c        |  8 ++++++++
+ mt7915/mcu.c         | 15 +++++++++++++++
+ mt7915/mt7915.h      |  1 +
+ mt7915/mtk_debugfs.c | 14 +++++---------
+ 4 files changed, 29 insertions(+), 9 deletions(-)
+
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 99ae9e86..81fd6742 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -8,6 +8,10 @@
+ #include "mt7915.h"
+ #include "mcu.h"
+ 
++static bool sw_aci_enable = false;
++module_param(sw_aci_enable, bool, 0644);
++MODULE_PARM_DESC(sw_aci_enable, "Enable the feature of Adjacent Channel Interference Detection");
++
+ static bool mt7915_dev_running(struct mt7915_dev *dev)
+ {
+ 	struct mt7915_phy *phy;
+@@ -41,6 +45,10 @@ int mt7915_run(struct ieee80211_hw *hw)
+ 			goto out;
+ 
+ 		mt7915_mac_enable_nf(dev, dev->phy.mt76->band_idx);
++
++		ret = mt7915_mcu_sw_aci_set(dev, sw_aci_enable);
++		if (ret)
++			goto out;
+ 	}
+ 
+ 	if (phy != &dev->phy) {
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 5790fc60..deefb558 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -4780,3 +4780,18 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value)
+ 
+ 	return 0;
+ }
++
++int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val)
++{
++#define SWLNA_ENABLE 6
++	struct {
++		u32 subcmd;
++		u8 enable;
++	} req = {
++		.subcmd = SWLNA_ENABLE,
++		.enable = val ? 1 : 0,
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SWLNA_ACI_CTRL), &req,
++				 sizeof(req), NULL);
++}
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 36593a2e..1885b906 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -774,6 +774,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);
++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/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
+index 6f74caff..2e24a371 100644
+--- a/mt7915/mtk_debugfs.c
++++ b/mt7915/mtk_debugfs.c
+@@ -3043,16 +3043,12 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
+ static int
+ mt7915_sw_aci_set(void *data, u64 val)
+ {
+-#define SWLNA_ENABLE 6
+ 	struct mt7915_dev *dev = data;
+-	struct {
+-		u32 subcmd;
+-		u8 enable;
+-	} req = {
+-		.subcmd = SWLNA_ENABLE,
+-		.enable = (u8) val,
+-	};
+-	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SWLNA_ACI_CTRL), &req, sizeof(req), NULL);
++
++	if (val > 1)
++		return -EINVAL;
++
++	return mt7915_mcu_sw_aci_set(dev, !!val);
+ }
+ 
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/patches.inc b/recipes-wifi/linux-mt76/files/patches/patches.inc
index 8f9eeda..e55fc75 100644
--- a/recipes-wifi/linux-mt76/files/patches/patches.inc
+++ b/recipes-wifi/linux-mt76/files/patches/patches.inc
@@ -37,6 +37,7 @@
     file://1030-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch \
     file://1031-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch \
     file://110-wifi-mt76-ignore-key-disable-commands.patch \
+    file://1135-mt76-mt7915-disable-SW-ACI-by-default.patch \
     file://3000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch \
     file://3001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch \
     file://3002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch \
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
index 1ecf08b..14a9603 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
@@ -217,7 +217,7 @@
 +void wpa_supplicant_apply_eht_overrides(
 +	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 +	struct wpa_driver_associate_params *params);
-+#endif CONFIG_EHT_OVERRIDES
++#endif /* CONFIG_EHT_OVERRIDES */
 +
  
  int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
new file mode 100644
index 0000000..5b9f4df
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
@@ -0,0 +1,527 @@
+From 47b475634804175c77621d492ad6129a31dcda4d 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] hostapd: mtk: Add vendor for CAPI certification commands
+
+---
+ hostapd/ctrl_iface.c              |  95 +++++++++++++++
+ src/ap/ap_drv_ops.c               |  21 ++++
+ src/ap/ap_drv_ops.h               |   3 +
+ src/common/mtk_vendor.h           |  32 +-----
+ src/drivers/driver.h              |  22 ++++
+ src/drivers/driver_nl80211.c      | 185 ++++++++++++++++++++++++++++++
+ src/drivers/driver_nl80211.h      |   1 +
+ src/drivers/driver_nl80211_capa.c |   3 +
+ 8 files changed, 332 insertions(+), 30 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index e1e9270..58bb710 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -38,6 +38,7 @@
+ #endif /* CONFIG_DPP */
+ #include "common/wpa_ctrl.h"
+ #include "common/ptksa_cache.h"
++#include "common/mtk_vendor.h"
+ #include "crypto/tls.h"
+ #include "drivers/driver.h"
+ #include "eapol_auth/eapol_auth_sm.h"
+@@ -3715,6 +3716,96 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
+ 	return pos - buf;
+ }
+ 
++static int
++hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
++					 char *buf, size_t buflen)
++{
++	char *pos, *value, *config = cmd;
++	enum mtk_vendor_attr_wireless_ctrl sub_cmd;
++
++	pos = os_strchr(config, '=');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if(pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strncmp(config, "fixed_mcs", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS;
++	else if (os_strncmp(config, "ofdma", 5) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA;
++	else if (os_strncmp(config, "ppdu_type", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE;
++	else if (os_strncmp(config, "nusers_ofdma", 12) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA;
++	else if (os_strncmp(config, "add_ba_req_bufsize", 18) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE;
++	else if (os_strncmp(config, "mimo", 4) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO;
++	else if (os_strncmp(config, "cert", 4) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT ;
++	else {
++		wpa_printf(MSG_ERROR,
++			"Unsupported parameter %s for ap_wireless", config);
++		return -1;
++	}
++
++	if (hostapd_drv_ap_wireless(hapd, (u8) sub_cmd, atoi(value)) != 0)
++		return -1;
++
++	return os_snprintf(buf, buflen, "OK\n");
++}
++
++static int
++hostapd_ctrl_iface_ap_rfeatures(struct hostapd_data *hapd, char *cmd,
++					 char *buf, size_t buflen)
++{
++	char *pos, *value, *type, *config = cmd;
++	enum mtk_vendor_attr_rfeature_ctrl sub_cmd;
++
++	pos = os_strchr(config, '=');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if(pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strncmp(config, "he_gi", 5) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI;
++	else if (os_strncmp(config, "he_ltf", 6) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF;
++	else if (os_strncmp(config, "trig_type", 9) == 0) {
++		pos = os_strchr(value, ',');
++		if (pos == NULL)
++			return -1;
++		*pos++ = '\0';
++		if(pos == NULL)
++			return -1;
++		type = pos;
++		goto trigtype;
++	} else if (os_strcmp(config, "ack_policy") == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY;
++	else {
++		wpa_printf(MSG_ERROR,
++			"Unsupported parameter %s for ap_rfeatures", config);
++		return -1;
++	}
++
++	if (hostapd_drv_ap_rfeatures(hapd, (u8) sub_cmd, atoi(value)) != 0)
++		return -1;
++	goto exit;
++
++trigtype:
++	if (hostapd_drv_ap_trig_type(hapd, atoi(value), atoi(type)) != 0)
++		return -1;
++
++exit:
++	return os_snprintf(buf, buflen, "OK\n");
++}
+ 
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+@@ -4286,6 +4377,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 		reply_len = hostapd_ctrl_iface_get_bss_color(hapd, reply, reply_size);
+ 	} else if (os_strncmp(buf, "AVAL_COLOR_BMP", 14) == 0) {
+ 		reply_len = hostapd_ctrl_iface_get_aval_color_bmp(hapd, reply, reply_size);
++	} else if (os_strncmp(buf, "ap_wireless ", 12) == 0) {
++		reply_len = hostapd_ctrl_iface_ap_wireless(hapd, buf + 12, reply, reply_size);
++	} else if (os_strncmp(buf, "ap_rfeatures ", 13) == 0) {
++		reply_len = hostapd_ctrl_iface_ap_rfeatures(hapd, buf + 13, reply, reply_size);
+ 	} else {
+ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ 		reply_len = 16;
+diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
+index 40b9a20..52d0fff 100644
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -1100,3 +1100,24 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
+ 		return 0;
+ 	return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
+ }
++
++int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
++{
++	if (!hapd->driver || !hapd->driver->ap_wireless)
++		return 0;
++	return hapd->driver->ap_wireless(hapd->drv_priv, sub_vendor_id, value);
++}
++
++int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
++{
++	if (!hapd->driver || !hapd->driver->ap_rfeatures)
++		return 0;
++	return hapd->driver->ap_rfeatures(hapd->drv_priv, sub_vendor_id, value);
++}
++
++int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type)
++{
++	if (!hapd->driver || !hapd->driver->ap_trigtype)
++		return 0;
++	return hapd->driver->ap_trigtype(hapd->drv_priv, enable, type);
++}
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index 136a3ac..659c3f8 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -151,6 +151,9 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
+ int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu);
+ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd,
+ 				       u64 *aval_color_bmp);
++int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
++int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
++int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
+ 
+ #include "drivers/driver.h"
+ 
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index a99e6f2..32438af 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -48,16 +48,6 @@ enum mtk_vendor_attr_edcca_dump {
+ 		NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP - 1
+ };
+ 
+-
+-static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_3wire_ctrl {
+ 	MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC,
+ 
+@@ -69,10 +59,6 @@ enum mtk_vendor_attr_3wire_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1
+ };
+ 
+-static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
+-	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_csi_ctrl {
+ 	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
+ 
+@@ -169,7 +155,7 @@ enum mtk_vendor_attr_wireless_ctrl {
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
+-	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA,
+ 
+ 	/* keep last */
+@@ -189,11 +175,6 @@ enum mtk_vendor_attr_wireless_dump {
+ 		NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
+ };
+ 
+-static const struct nla_policy
+-wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
+-	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_rfeature_ctrl {
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
+ 
+@@ -203,6 +184,7 @@ enum mtk_vendor_attr_rfeature_ctrl {
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
+ 
+ 	/* keep last */
+ 	NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
+@@ -244,16 +226,6 @@ enum mtk_vendor_attr_ibf_dump {
+ 		NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
+ };
+ 
+-static struct nla_policy
+-ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
+-	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
+-};
+-
+-static struct nla_policy
+-ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
+-	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_bss_color_ctrl {
+ 	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index 7f6392f..d4f34b6 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -4779,6 +4779,28 @@ struct wpa_driver_ops {
+ 	 *
+ 	 */
+ 	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
++
++	/**
++	* ap_wireless - set wireless command
++	* @priv: Private driver interface data
++	* @value: value
++	*/
++	int (*ap_wireless)(void *priv, u8 mode, int value);
++
++	/**
++	* ap_rfeatures - set ap rf features command
++	* @priv: Private driver interface data
++	* @value: value
++	*/
++	int (*ap_rfeatures)(void *priv, u8 mode, int value);
++
++	/**
++	* ap_trigtype - set trigger type
++	* @priv: Private driver interface data
++	* @enable: enable or disable
++	* @type: trigger type
++	*/
++	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
+ };
+ 
+ /**
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index f9a8763..9c1717f 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -74,6 +74,57 @@ enum nlmsgerr_attrs {
+ #endif /* ANDROID */
+ 
+ 
++static struct nla_policy
++ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
++	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
++};
++
++static struct nla_policy
++ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
++	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
++};
++
++static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
++	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
++};
++
++static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
++	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
++};
++
+ static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
+ {
+ 	struct nl_sock *handle;
+@@ -13005,6 +13056,137 @@ fail:
+ 	return -ENOBUFS;
+ }
+ 
++static int nl80211_ap_wireless(void *priv, u8 sub_vendor_id, int value)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data;
++	int ret;
++
++	if (!drv->mtk_wireless_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap wireless control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	if (sub_vendor_id == MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE)
++		nla_put_u16(msg, sub_vendor_id, (u16) value);
++	else
++		nla_put_u8(msg, sub_vendor_id, (u8) value);
++
++	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 ap_wireless. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
++static int nl80211_ap_rfeatures(void *priv, u8 sub_vendor_id, int value)
++{
++	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_rfeatures_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap rfeatures control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	nla_put_u8(msg, sub_vendor_id, (u8) value);
++
++	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 rf_features. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
++static int nl80211_ap_trigtype(void *priv, u8 enable, u8 type)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data, *data2;
++	int ret;
++
++	if (!drv->mtk_rfeatures_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap rfeatures control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	data2 = nla_nest_start(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG);
++	if (!data2)
++		goto fail;
++
++	nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN, enable);
++	nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE, type);
++
++	nla_nest_end(msg, data2);
++	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 trig_type. 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",
+@@ -13162,4 +13344,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.amsdu_ctrl = nl80211_enable_amsdu,
+ 	.amsdu_dump = nl80211_dump_amsdu,
+ 	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
++	.ap_wireless = nl80211_ap_wireless,
++	.ap_rfeatures = nl80211_ap_rfeatures,
++	.ap_trigtype = nl80211_ap_trigtype,
+ };
+diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
+index 72c7abd..7a03446 100644
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -187,6 +187,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_ibf_vendor_cmd_avail:1;
+ 	unsigned int mtk_wireless_vendor_cmd_avail:1;
+ 	unsigned int mtk_bss_color_vendor_cmd_avail:1;
++	unsigned int mtk_rfeatures_vendor_cmd_avail:1;
+ 
+ 	u64 vendor_scan_cookie;
+ 	u64 remain_on_chan_cookie;
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index e7c6f39..6f4d029 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1095,6 +1095,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+ 				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
+ 					drv->mtk_bss_color_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
++					drv->mtk_rfeatures_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc
index 7b5afa4..e83e1b4 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
@@ -87,5 +87,6 @@
     file://mtk-0023-hostapd-mtk-Add-channel-information-for-hostapd-relo.patch \
     file://mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch \
     file://mtk-0025-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch \
+    file://mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch \
     file://mtk-0100-hostapd-mtk-update-eht-operation-elem.patch \
     "
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
index 1ecf08b..14a9603 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch
@@ -217,7 +217,7 @@
 +void wpa_supplicant_apply_eht_overrides(
 +	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 +	struct wpa_driver_associate_params *params);
-+#endif CONFIG_EHT_OVERRIDES
++#endif /* CONFIG_EHT_OVERRIDES */
 +
  
  int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
new file mode 100644
index 0000000..5b9f4df
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch
@@ -0,0 +1,527 @@
+From 47b475634804175c77621d492ad6129a31dcda4d 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] hostapd: mtk: Add vendor for CAPI certification commands
+
+---
+ hostapd/ctrl_iface.c              |  95 +++++++++++++++
+ src/ap/ap_drv_ops.c               |  21 ++++
+ src/ap/ap_drv_ops.h               |   3 +
+ src/common/mtk_vendor.h           |  32 +-----
+ src/drivers/driver.h              |  22 ++++
+ src/drivers/driver_nl80211.c      | 185 ++++++++++++++++++++++++++++++
+ src/drivers/driver_nl80211.h      |   1 +
+ src/drivers/driver_nl80211_capa.c |   3 +
+ 8 files changed, 332 insertions(+), 30 deletions(-)
+
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index e1e9270..58bb710 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -38,6 +38,7 @@
+ #endif /* CONFIG_DPP */
+ #include "common/wpa_ctrl.h"
+ #include "common/ptksa_cache.h"
++#include "common/mtk_vendor.h"
+ #include "crypto/tls.h"
+ #include "drivers/driver.h"
+ #include "eapol_auth/eapol_auth_sm.h"
+@@ -3715,6 +3716,96 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
+ 	return pos - buf;
+ }
+ 
++static int
++hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
++					 char *buf, size_t buflen)
++{
++	char *pos, *value, *config = cmd;
++	enum mtk_vendor_attr_wireless_ctrl sub_cmd;
++
++	pos = os_strchr(config, '=');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if(pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strncmp(config, "fixed_mcs", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS;
++	else if (os_strncmp(config, "ofdma", 5) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA;
++	else if (os_strncmp(config, "ppdu_type", 9) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE;
++	else if (os_strncmp(config, "nusers_ofdma", 12) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA;
++	else if (os_strncmp(config, "add_ba_req_bufsize", 18) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE;
++	else if (os_strncmp(config, "mimo", 4) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO;
++	else if (os_strncmp(config, "cert", 4) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT ;
++	else {
++		wpa_printf(MSG_ERROR,
++			"Unsupported parameter %s for ap_wireless", config);
++		return -1;
++	}
++
++	if (hostapd_drv_ap_wireless(hapd, (u8) sub_cmd, atoi(value)) != 0)
++		return -1;
++
++	return os_snprintf(buf, buflen, "OK\n");
++}
++
++static int
++hostapd_ctrl_iface_ap_rfeatures(struct hostapd_data *hapd, char *cmd,
++					 char *buf, size_t buflen)
++{
++	char *pos, *value, *type, *config = cmd;
++	enum mtk_vendor_attr_rfeature_ctrl sub_cmd;
++
++	pos = os_strchr(config, '=');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if(pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strncmp(config, "he_gi", 5) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI;
++	else if (os_strncmp(config, "he_ltf", 6) == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF;
++	else if (os_strncmp(config, "trig_type", 9) == 0) {
++		pos = os_strchr(value, ',');
++		if (pos == NULL)
++			return -1;
++		*pos++ = '\0';
++		if(pos == NULL)
++			return -1;
++		type = pos;
++		goto trigtype;
++	} else if (os_strcmp(config, "ack_policy") == 0)
++		sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY;
++	else {
++		wpa_printf(MSG_ERROR,
++			"Unsupported parameter %s for ap_rfeatures", config);
++		return -1;
++	}
++
++	if (hostapd_drv_ap_rfeatures(hapd, (u8) sub_cmd, atoi(value)) != 0)
++		return -1;
++	goto exit;
++
++trigtype:
++	if (hostapd_drv_ap_trig_type(hapd, atoi(value), atoi(type)) != 0)
++		return -1;
++
++exit:
++	return os_snprintf(buf, buflen, "OK\n");
++}
+ 
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+@@ -4286,6 +4377,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 		reply_len = hostapd_ctrl_iface_get_bss_color(hapd, reply, reply_size);
+ 	} else if (os_strncmp(buf, "AVAL_COLOR_BMP", 14) == 0) {
+ 		reply_len = hostapd_ctrl_iface_get_aval_color_bmp(hapd, reply, reply_size);
++	} else if (os_strncmp(buf, "ap_wireless ", 12) == 0) {
++		reply_len = hostapd_ctrl_iface_ap_wireless(hapd, buf + 12, reply, reply_size);
++	} else if (os_strncmp(buf, "ap_rfeatures ", 13) == 0) {
++		reply_len = hostapd_ctrl_iface_ap_rfeatures(hapd, buf + 13, reply, reply_size);
+ 	} else {
+ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ 		reply_len = 16;
+diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
+index 40b9a20..52d0fff 100644
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -1100,3 +1100,24 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
+ 		return 0;
+ 	return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
+ }
++
++int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
++{
++	if (!hapd->driver || !hapd->driver->ap_wireless)
++		return 0;
++	return hapd->driver->ap_wireless(hapd->drv_priv, sub_vendor_id, value);
++}
++
++int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
++{
++	if (!hapd->driver || !hapd->driver->ap_rfeatures)
++		return 0;
++	return hapd->driver->ap_rfeatures(hapd->drv_priv, sub_vendor_id, value);
++}
++
++int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type)
++{
++	if (!hapd->driver || !hapd->driver->ap_trigtype)
++		return 0;
++	return hapd->driver->ap_trigtype(hapd->drv_priv, enable, type);
++}
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index 136a3ac..659c3f8 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -151,6 +151,9 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
+ int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu);
+ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd,
+ 				       u64 *aval_color_bmp);
++int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
++int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
++int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
+ 
+ #include "drivers/driver.h"
+ 
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index a99e6f2..32438af 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -48,16 +48,6 @@ enum mtk_vendor_attr_edcca_dump {
+ 		NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP - 1
+ };
+ 
+-
+-static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
+-	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_3wire_ctrl {
+ 	MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC,
+ 
+@@ -69,10 +59,6 @@ enum mtk_vendor_attr_3wire_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1
+ };
+ 
+-static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
+-	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_csi_ctrl {
+ 	MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
+ 
+@@ -169,7 +155,7 @@ enum mtk_vendor_attr_wireless_ctrl {
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
+-	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT,
++	MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
+ 	MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA,
+ 
+ 	/* keep last */
+@@ -189,11 +175,6 @@ enum mtk_vendor_attr_wireless_dump {
+ 		NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
+ };
+ 
+-static const struct nla_policy
+-wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
+-	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_rfeature_ctrl {
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
+ 
+@@ -203,6 +184,7 @@ enum mtk_vendor_attr_rfeature_ctrl {
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
+ 	MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
++	MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
+ 
+ 	/* keep last */
+ 	NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
+@@ -244,16 +226,6 @@ enum mtk_vendor_attr_ibf_dump {
+ 		NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
+ };
+ 
+-static struct nla_policy
+-ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
+-	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
+-};
+-
+-static struct nla_policy
+-ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
+-	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
+-};
+-
+ enum mtk_vendor_attr_bss_color_ctrl {
+ 	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index 7f6392f..d4f34b6 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -4779,6 +4779,28 @@ struct wpa_driver_ops {
+ 	 *
+ 	 */
+ 	int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
++
++	/**
++	* ap_wireless - set wireless command
++	* @priv: Private driver interface data
++	* @value: value
++	*/
++	int (*ap_wireless)(void *priv, u8 mode, int value);
++
++	/**
++	* ap_rfeatures - set ap rf features command
++	* @priv: Private driver interface data
++	* @value: value
++	*/
++	int (*ap_rfeatures)(void *priv, u8 mode, int value);
++
++	/**
++	* ap_trigtype - set trigger type
++	* @priv: Private driver interface data
++	* @enable: enable or disable
++	* @type: trigger type
++	*/
++	int (*ap_trigtype)(void *priv, u8 enable, u8 type);
+ };
+ 
+ /**
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index f9a8763..9c1717f 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -74,6 +74,57 @@ enum nlmsgerr_attrs {
+ #endif /* ANDROID */
+ 
+ 
++static struct nla_policy
++ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
++	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
++};
++
++static struct nla_policy
++ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
++	[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
++};
++
++static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
++	[MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
++};
++
++static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
++	[MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
++	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
++};
++
++static const struct nla_policy
++wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU] = {.type = NLA_U8 },
++	[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
++};
++
+ static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
+ {
+ 	struct nl_sock *handle;
+@@ -13005,6 +13056,137 @@ fail:
+ 	return -ENOBUFS;
+ }
+ 
++static int nl80211_ap_wireless(void *priv, u8 sub_vendor_id, int value)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data;
++	int ret;
++
++	if (!drv->mtk_wireless_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap wireless control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	if (sub_vendor_id == MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE)
++		nla_put_u16(msg, sub_vendor_id, (u16) value);
++	else
++		nla_put_u8(msg, sub_vendor_id, (u8) value);
++
++	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 ap_wireless. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
++static int nl80211_ap_rfeatures(void *priv, u8 sub_vendor_id, int value)
++{
++	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_rfeatures_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap rfeatures control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	nla_put_u8(msg, sub_vendor_id, (u8) value);
++
++	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 rf_features. ret=%d (%s)", ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
++static int nl80211_ap_trigtype(void *priv, u8 enable, u8 type)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data, *data2;
++	int ret;
++
++	if (!drv->mtk_rfeatures_vendor_cmd_avail) {
++		wpa_printf(MSG_INFO,
++			   "nl80211: Driver does not support setting ap rfeatures control");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++		nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	data2 = nla_nest_start(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG);
++	if (!data2)
++		goto fail;
++
++	nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN, enable);
++	nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE, type);
++
++	nla_nest_end(msg, data2);
++	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 trig_type. 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",
+@@ -13162,4 +13344,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.amsdu_ctrl = nl80211_enable_amsdu,
+ 	.amsdu_dump = nl80211_dump_amsdu,
+ 	.get_aval_color_bmp = nl80211_get_aval_color_bmp,
++	.ap_wireless = nl80211_ap_wireless,
++	.ap_rfeatures = nl80211_ap_rfeatures,
++	.ap_trigtype = nl80211_ap_trigtype,
+ };
+diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
+index 72c7abd..7a03446 100644
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -187,6 +187,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_ibf_vendor_cmd_avail:1;
+ 	unsigned int mtk_wireless_vendor_cmd_avail:1;
+ 	unsigned int mtk_bss_color_vendor_cmd_avail:1;
++	unsigned int mtk_rfeatures_vendor_cmd_avail:1;
+ 
+ 	u64 vendor_scan_cookie;
+ 	u64 remain_on_chan_cookie;
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index e7c6f39..6f4d029 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1095,6 +1095,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+ 				case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
+ 					drv->mtk_bss_color_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
++					drv->mtk_rfeatures_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches/patches.inc b/recipes-wifi/wpa-supplicant/files/patches/patches.inc
index c38c7f6..7bc6508 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/patches.inc
+++ b/recipes-wifi/wpa-supplicant/files/patches/patches.inc
@@ -87,4 +87,5 @@
     file://mtk-0023-hostapd-mtk-Add-channel-information-for-hostapd-relo.patch \
     file://mtk-0024-hostapd-mtk-Add-support-for-masking-EHT-capabilities.patch \
     file://mtk-0025-hostapd-mtk-Fix-ZWDFS-issue-in-BW-160.patch \
+    file://mtk-0026-hostapd-mtk-Add-vendor-for-CAPI-certification-comman.patch \
     "