소스 검색

qcacmn: Add support to populate target 11AX wireless modes

Add support to populate 11AX wireless modes advetised in ext2 service
ready message. To support older FW that do not advertise this, use
existing host workaround to populate these in host  itself.

Change-Id: I3b3b280672592c858bd3f6f0e368909a16bd30ee
CRs-Fixed: 2650136
Shashikala Prabhu 5 년 전
부모
커밋
a76f88adb8

+ 10 - 1
target_if/core/inc/target_if.h

@@ -134,10 +134,12 @@ struct comp_hdls {
  *
  * @num_modes: Number of modes supported
  * @hw_mode_ids: List of HW mode ids
+ * @phy_bit_map: List of Phy bit maps
  */
 struct target_supported_modes {
 	uint8_t num_modes;
 	uint32_t hw_mode_ids[WMI_HOST_HW_MODE_MAX];
+	uint32_t phy_bit_map[WMI_HOST_HW_MODE_MAX];
 };
 
 /**
@@ -2037,14 +2039,21 @@ static inline void target_if_print_service_ready_ext_param(
  *
  * Return: none
  */
+#ifdef QCA_HOST_ADD_11AX_MODE_WAR
 static inline void target_if_add_11ax_modes(struct wlan_objmgr_psoc *psoc,
-					struct target_psoc_info *tgt_hdl)
+					    struct target_psoc_info *tgt_hdl)
 {
 	if ((tgt_hdl->tif_ops) &&
 		(tgt_hdl->tif_ops->add_11ax_modes)) {
 		tgt_hdl->tif_ops->add_11ax_modes(psoc, tgt_hdl);
 	}
 }
+#else
+static inline void target_if_add_11ax_modes(struct wlan_objmgr_psoc *psoc,
+					    struct target_psoc_info *tgt_hdl)
+{
+}
+#endif
 
 /**
  * target_if_set_default_config - Set default config in init command

+ 16 - 0
target_if/init_deinit/inc/service_ready_param.h

@@ -137,6 +137,7 @@ struct wlan_psoc_host_hal_reg_cap_ext {
  *        by hw_mode_id.
  * @pdev_id: pdev_id starts with 1. pdev_id 1 => phy_id 0, pdev_id 2 => phy_id 1
  * @phy_id: Starts with 0
+ * @phy_idx: Index to mac phy caps structure for the given hw_mode_id and phy_id
  * @hw_mode_config_type: holds the enum wmi_hw_mode_config_type
  * @bitmap of supported modulations
  * @supported_bands: supported bands, enum WLAN_BAND_CAPABILITY
@@ -188,6 +189,7 @@ struct wlan_psoc_host_mac_phy_caps {
 	uint32_t hw_mode_id;
 	uint32_t pdev_id;
 	uint32_t phy_id;
+	uint8_t phy_idx;
 	int hw_mode_config_type;
 	uint32_t supports_11b:1,
 		 supports_11g:1,
@@ -239,6 +241,20 @@ struct wlan_psoc_host_hw_mode_caps {
 	uint32_t hw_mode_config_type;
 };
 
+/*
+ * struct wlan_psoc_host_mac_phy_caps_ext2 - Phy caps received in EXT2 service
+ * @hw_mode_id: HW mode id
+ * @pdev_id: Pdev id
+ * @phy_id: Phy id
+ * @wireless_modes_ext: Extended wireless modes
+ */
+struct wlan_psoc_host_mac_phy_caps_ext2 {
+	uint32_t hw_mode_id;
+	uint32_t pdev_id;
+	uint32_t phy_id;
+	uint32_t wireless_modes_ext;
+};
+
 /**
  * struct wlan_psoc_host_dbr_ring_caps - Direct buffer rx module ring
  *                                       capability maintained by PSOC

+ 29 - 1
target_if/init_deinit/inc/service_ready_util.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -250,6 +250,34 @@ int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc,
 				     struct tgt_info *info,
 				     bool service_ready);
 
+/**
+ * init_deinit_populate_hal_reg_cap_ext2() - Populate HAL reg capabilities from
+ * service ready ext2 event.
+ * @handle: WMI handle pointer
+ * @event: event buffer received from FW
+ * @info: tgt_info object
+ *
+ * API to populate HAL reg capabilities from service ready ext2 event.
+ *
+ * Return: zero on successful parsing of physical reg capability or failure flag
+ */
+int init_deinit_populate_hal_reg_cap_ext2(wmi_unified_t handle, uint8_t *event,
+					  struct tgt_info *info);
+
+/**
+ * init_deinit_populate_mac_phy_cap_ext2() - populate mac phy capabilities from
+ * service ready ext2 event
+ * @handle: WMI handle pointer
+ * @event: event buffer received from FW
+ * @info: tgt_info object
+ *
+ * API to populate mac phy capability from service ready ext2 event.
+ *
+ * Return: zero on successful population of mac physical capability or failure
+ */
+int init_deinit_populate_mac_phy_cap_ext2(wmi_unified_t handle, uint8_t *event,
+					  struct tgt_info *info);
+
 /**
  * init_deinit_validate_160_80p80_fw_caps() - validate 160 80p80 fw caps
  * @psoc: PSOC object

+ 31 - 4
target_if/init_deinit/src/init_event_handler.c

@@ -32,6 +32,7 @@
 #include <service_ready_param.h>
 #include <init_cmd_api.h>
 #include <cdp_txrx_cmn.h>
+#include <wlan_reg_ucfg_api.h>
 
 static void init_deinit_set_send_init_cmd(struct wlan_objmgr_psoc *psoc,
 					  struct target_psoc_info *tgt_hdl)
@@ -226,23 +227,28 @@ static int init_deinit_service_ext2_ready_event_handler(ol_scn_t scn_handle,
 	struct tgt_info *info;
 
 	if (!scn_handle) {
-		target_if_err("scn handle NULL in service ready handler");
+		target_if_err("scn handle NULL in service ready ext2 handler");
 		return -EINVAL;
 	}
 
 	psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
 	if (!psoc) {
-		target_if_err("psoc is null in service ready handler");
+		target_if_err("psoc is null in service ready ext2 handler");
 		return -EINVAL;
 	}
 
 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
 	if (!tgt_hdl) {
-		target_if_err("target_psoc_info is null in service ready ev");
+		target_if_err("target_psoc_info is null in service ready ext2 handler");
 		return -EINVAL;
 	}
 
 	wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null in service ready ext2 handler");
+		return -EINVAL;
+	}
+
 	info = (&tgt_hdl->info);
 
 	err_code = init_deinit_populate_service_ready_ext2_param(wmi_handle,
@@ -259,6 +265,22 @@ static int init_deinit_service_ext2_ready_event_handler(ol_scn_t scn_handle,
 			goto exit;
 	}
 
+	err_code = init_deinit_populate_hal_reg_cap_ext2(wmi_handle, event,
+							 info);
+	if (err_code) {
+		target_if_err("failed to populate hal reg cap ext2");
+		goto exit;
+	}
+
+	err_code = init_deinit_populate_mac_phy_cap_ext2(wmi_handle, event,
+							 info);
+	if (err_code) {
+		target_if_err("failed to populate mac phy cap ext2");
+		goto exit;
+	}
+
+	target_if_add_11ax_modes(psoc, tgt_hdl);
+
 	/* send init command */
 	init_deinit_set_send_init_cmd(psoc, tgt_hdl);
 
@@ -329,7 +351,12 @@ static int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle,
 	if (err_code)
 		goto exit;
 
-	target_if_add_11ax_modes(psoc, tgt_hdl);
+	/* Host receives 11AX wireless modes from target in service ext2
+	 * message. Therefore, call target_if_add_11ax_modes() from service ext2
+	 * event handler as well.
+	 */
+	if (!wmi_service_enabled(wmi_handle, wmi_service_ext2_msg))
+		target_if_add_11ax_modes(psoc, tgt_hdl);
 
 	if (init_deinit_chainmask_table_alloc(
 				&(info->service_ext_param)) ==

+ 106 - 0
target_if/init_deinit/src/service_ready_util.c

@@ -343,6 +343,8 @@ int init_deinit_populate_hw_mode_capability(
 		if (hw_idx < WMI_HOST_HW_MODE_MAX) {
 			info->hw_modes.hw_mode_ids[hw_idx] =
 				hw_mode_caps[hw_idx].hw_mode_id;
+			info->hw_modes.phy_bit_map[hw_idx] =
+				hw_mode_caps[hw_idx].phy_id_map;
 			info->hw_modes.num_modes++;
 		}
 
@@ -647,6 +649,110 @@ int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc,
 	return qdf_status_to_os_return(status);
 }
 
+int init_deinit_populate_mac_phy_cap_ext2(wmi_unified_t wmi_handle,
+					  uint8_t *event,
+					  struct tgt_info *info)
+{
+	struct wlan_psoc_host_mac_phy_caps_ext2
+		mac_phy_caps_ext2[PSOC_MAX_MAC_PHY_CAP] = {{0} };
+	uint32_t num_hw_modes;
+	uint8_t hw_idx;
+	uint32_t hw_mode_id;
+	uint32_t phy_bit_map;
+	uint8_t phy_id;
+	uint8_t mac_phy_count = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
+
+	if (!event)
+		return -EINVAL;
+
+	num_hw_modes = info->hw_modes.num_modes;
+
+	for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) {
+		hw_mode_id = info->hw_modes.hw_mode_ids[hw_idx];
+		phy_bit_map = info->hw_modes.phy_bit_map[hw_idx];
+
+		phy_id = info->mac_phy_cap[mac_phy_count].phy_id;
+		while (phy_bit_map) {
+			if (mac_phy_count >= info->total_mac_phy_cnt) {
+				target_if_err("total MAC PHY count exceeds max limit %d, mac_phy_count = %d",
+					      info->total_mac_phy_cnt,
+					      mac_phy_count);
+				return -EINVAL;
+			}
+
+			mac_phy_cap = &info->mac_phy_cap[mac_phy_count];
+			status = wmi_extract_mac_phy_cap_service_ready_ext2(
+					wmi_handle, event, hw_mode_id, phy_id,
+					mac_phy_cap->phy_idx,
+					&mac_phy_caps_ext2[mac_phy_count]);
+
+			if (QDF_IS_STATUS_ERROR(status)) {
+				target_if_err("failed to parse mac phy capability ext2");
+				return qdf_status_to_os_return(status);
+			}
+
+			mac_phy_cap->reg_cap_ext.wireless_modes |=
+				mac_phy_caps_ext2[phy_id].wireless_modes_ext;
+
+			mac_phy_count++;
+			phy_bit_map &= (phy_bit_map - 1);
+			phy_id++;
+		}
+	}
+
+	return 0;
+}
+
+int init_deinit_populate_hal_reg_cap_ext2(wmi_unified_t wmi_handle,
+					  uint8_t *event,
+					  struct tgt_info *info)
+{
+	struct wlan_psoc_host_hal_reg_capabilities_ext2
+		reg_cap[PSOC_MAX_PHY_REG_CAP] = {{0} };
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t num_phy_reg_cap;
+	uint8_t reg_idx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!event) {
+		target_if_err("event buffer is null");
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(wmi_handle->scn_handle);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	num_phy_reg_cap = info->service_ext_param.num_phy;
+	if (num_phy_reg_cap > PSOC_MAX_PHY_REG_CAP) {
+		target_if_err("Invalid num_phy_reg_cap %d", num_phy_reg_cap);
+		return -EINVAL;
+	}
+
+	for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) {
+		status = wmi_extract_hal_reg_cap_ext2(
+				wmi_handle, event, reg_idx, &reg_cap[reg_idx]);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("failed to parse hal reg cap ext2");
+			return qdf_status_to_os_return(status);
+		}
+
+		status = ucfg_reg_update_hal_reg_cap(
+				psoc, reg_cap[reg_idx].wireless_modes_ext,
+				reg_idx);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Failed to update hal reg cap");
+			return qdf_status_to_os_return(status);
+		}
+	}
+
+	return 0;
+}
+
 static bool init_deinit_regdmn_160mhz_support(
 		struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap)
 {

+ 11 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h

@@ -395,6 +395,17 @@ struct wlan_psoc_host_hal_reg_capabilities_ext {
 	uint32_t high_5ghz_chan;
 };
 
+/**
+ * struct wlan_psoc_host_hal_reg_capabilities_ext2 - HAL reg capabilities
+ * from service ready ext2 event.
+ * @phy_id: phy id starts with 0
+ * @wireless_modes_ext: REGDMN MODE, see REGDMN_MODE_ enum
+ */
+struct wlan_psoc_host_hal_reg_capabilities_ext2 {
+	uint32_t phy_id;
+	uint32_t wireless_modes_ext;
+};
+
 /**
  ** APIs to Create/Delete Global object APIs
  */

+ 36 - 0
wmi/inc/wmi_unified_api.h

@@ -2335,6 +2335,22 @@ QDF_STATUS
 wmi_extract_hal_reg_cap(wmi_unified_t wmi_handle, void *evt_buf,
 			struct wlan_psoc_hal_reg_capability *hal_reg_cap);
 
+/**
+ * wmi_extract_hal_reg_cap_ext2() - Extract HAL reg capabilities from service
+ * ready ext2 event
+ * @wmi_handle: wmi handle
+ * @evt_buf: Pointer to event buffer
+ * @phy_idx: Phy id
+ * @wireless_modes: 11AX wireless modes
+ * @hal_reg_cap: pointer to hold HAL reg capabilities ext2 structure
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS
+wmi_extract_hal_reg_cap_ext2(
+		wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx,
+		struct wlan_psoc_host_hal_reg_capabilities_ext2 *hal_reg_cap);
+
 /**
  * wmi_extract_num_mem_reqs_from_service_ready() - Extract number of memory
  *                                                 entries requested
@@ -3238,6 +3254,26 @@ QDF_STATUS wmi_extract_mac_phy_cap_service_ready_ext(
 			uint8_t phy_id,
 			struct wlan_psoc_host_mac_phy_caps *param);
 
+/**
+ * wmi_extract_mac_phy_cap_service_ready_ext2() - Extract MAC phy cap from
+ * service ready ext2 event.
+ * @wmi_handle: wmi handle
+ * @evt_buf: pointer to event buffer
+ * @hw_mode_id: hw mode id of hw_mode_caps
+ * @phy_id: phy_id within hw_mode_cap
+ * @phy_idx: index to hw_mode_cap for the given hw_mode_id and phy_id
+ * @mac_phy_cap: Pointer to mac_phy_cap_ext2 structure
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wmi_extract_mac_phy_cap_service_ready_ext2(
+			wmi_unified_t wmi_handle,
+			uint8_t *evt_buf,
+			uint8_t hw_mode_id,
+			uint8_t phy_id,
+			uint8_t phy_idx,
+			struct wlan_psoc_host_mac_phy_caps_ext2 *mac_phy_cap);
+
 /**
  * wmi_extract_reg_cap_service_ready_ext() -
  *       extract REG cap from service ready event

+ 15 - 2
wmi/inc/wmi_unified_priv.h

@@ -1332,8 +1332,13 @@ QDF_STATUS (*extract_fw_version)(wmi_unified_t wmi_handle,
 QDF_STATUS (*extract_fw_abi_version)(wmi_unified_t wmi_handle,
 				void *ev, struct wmi_host_fw_abi_ver *fw_ver);
 
-QDF_STATUS (*extract_hal_reg_cap)(wmi_unified_t wmi_handle, void *evt_buf,
-	struct wlan_psoc_hal_reg_capability *hal_reg_cap);
+QDF_STATUS (*extract_hal_reg_cap)(
+		wmi_unified_t wmi_handle, void *evt_buf,
+		struct wlan_psoc_hal_reg_capability *hal_reg_cap);
+
+QDF_STATUS (*extract_hal_reg_cap_ext2)(
+		wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx,
+		struct wlan_psoc_host_hal_reg_capabilities_ext2 *hal_reg_cap);
 
 uint32_t (*extract_num_mem_reqs)(wmi_unified_t wmi_handle,
 				 void *evt_buf);
@@ -1801,6 +1806,14 @@ QDF_STATUS (*extract_mac_phy_cap_service_ready_ext)(
 			uint8_t phy_id,
 			struct wlan_psoc_host_mac_phy_caps *param);
 
+QDF_STATUS (*extract_mac_phy_cap_service_ready_ext2)(
+			wmi_unified_t wmi_handle,
+			uint8_t *evt_buf,
+			uint8_t hw_mode_id,
+			uint8_t phy_id,
+			uint8_t phy_idx,
+			struct wlan_psoc_host_mac_phy_caps_ext2 *mac_phy_cap);
+
 QDF_STATUS (*extract_reg_cap_service_ready_ext)(
 			wmi_unified_t wmi_handle,
 			uint8_t *evt_buf, uint8_t phy_idx,

+ 28 - 0
wmi/src/wmi_unified_api.c

@@ -1660,6 +1660,18 @@ wmi_extract_hal_reg_cap(wmi_unified_t wmi_handle, void *evt_buf,
 	return QDF_STATUS_E_FAILURE;
 }
 
+QDF_STATUS
+wmi_extract_hal_reg_cap_ext2(
+		wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx,
+		struct wlan_psoc_host_hal_reg_capabilities_ext2 *hal_reg_cap)
+{
+	if (wmi_handle->ops->extract_hal_reg_cap_ext2)
+		return wmi_handle->ops->extract_hal_reg_cap_ext2(
+			wmi_handle, evt_buf, phy_idx, hal_reg_cap);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 uint32_t
 wmi_extract_num_mem_reqs_from_service_ready(
 		wmi_unified_t wmi_handle,
@@ -2483,6 +2495,22 @@ QDF_STATUS wmi_extract_mac_phy_cap_service_ready_ext(
 	return QDF_STATUS_E_FAILURE;
 }
 
+QDF_STATUS wmi_extract_mac_phy_cap_service_ready_ext2(
+			wmi_unified_t wmi_handle,
+			uint8_t *evt_buf,
+			uint8_t hw_mode_id,
+			uint8_t phy_id,
+			uint8_t phy_idx,
+			struct wlan_psoc_host_mac_phy_caps_ext2 *mac_phy_cap)
+{
+	if (wmi_handle->ops->extract_mac_phy_cap_service_ready_ext2)
+		return wmi_handle->ops->extract_mac_phy_cap_service_ready_ext2(
+				wmi_handle, evt_buf, hw_mode_id, phy_id,
+				phy_idx, mac_phy_cap);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 QDF_STATUS wmi_extract_reg_cap_service_ready_ext(
 			wmi_unified_t wmi_handle,
 			uint8_t *evt_buf, uint8_t phy_idx,

+ 116 - 0
wmi/src/wmi_unified_tlv.c

@@ -9406,6 +9406,43 @@ static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap)
 	return phybitmap;
 }
 
+static inline uint32_t convert_wireless_modes_ext_tlv(
+		uint32_t target_wireless_modes_ext)
+{
+	uint32_t wireless_modes_ext = 0;
+
+	WMI_LOGD("Target wireless mode: 0x%x", target_wireless_modes_ext);
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE20;
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE40PLUS;
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE40MINUS;
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE20;
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE40PLUS;
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE40MINUS;
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE80;
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE160;
+
+	if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80)
+		wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE80_80;
+
+	return wireless_modes_ext;
+}
+
 /**
  * extract_hal_reg_cap_tlv() - extract HAL registered capabilities
  * @wmi_handle: wmi handle
@@ -9434,6 +9471,43 @@ static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle,
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext
+ * @wmi_handle: wmi handle
+ * @param evt_buf: Pointer to event buffer
+ * @param cap: pointer to hold HAL reg capabilities
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS extract_hal_reg_cap_ext2_tlv(
+		wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx,
+		struct wlan_psoc_host_hal_reg_capabilities_ext2 *param)
+{
+	WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf;
+	WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps;
+
+	if (!evt_buf) {
+		WMI_LOGE("null evt_buf");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf;
+
+	if (!param_buf->num_hal_reg_caps)
+		return QDF_STATUS_SUCCESS;
+
+	if (phy_idx >= param_buf->num_hal_reg_caps)
+		return QDF_STATUS_E_INVAL;
+
+	reg_caps = &param_buf->hal_reg_caps[phy_idx];
+
+	param->phy_id = reg_caps->phy_id;
+	param->wireless_modes_ext = convert_wireless_modes_ext_tlv(
+			reg_caps->wireless_modes_ext);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * extract_num_mem_reqs_tlv() - Extract number of memory entries requested
  * @wmi_handle: wmi handle
@@ -11242,6 +11316,7 @@ static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv(
 	mac_phy_caps = &param_buf->mac_phy_caps[phy_idx];
 
 	param->hw_mode_id = mac_phy_caps->hw_mode_id;
+	param->phy_idx = phy_idx;
 	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
 							wmi_handle,
 							mac_phy_caps->pdev_id);
@@ -11310,6 +11385,44 @@ static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv(
 	return QDF_STATUS_SUCCESS;
 }
 
+static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv(
+			wmi_unified_t wmi_handle,
+			uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id,
+			uint8_t phy_idx,
+			struct wlan_psoc_host_mac_phy_caps_ext2 *param)
+{
+	WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf;
+	WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps;
+
+	if (!event) {
+		WMI_LOGE("null evt_buf");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event;
+
+	if (!param_buf->num_mac_phy_caps)
+		return QDF_STATUS_SUCCESS;
+
+	if (phy_idx >= param_buf->num_mac_phy_caps)
+		return QDF_STATUS_E_INVAL;
+
+	mac_phy_caps = &param_buf->mac_phy_caps[phy_idx];
+
+	if ((hw_mode_id != mac_phy_caps->hw_mode_id) ||
+	    (phy_id != mac_phy_caps->phy_id))
+		return QDF_STATUS_E_INVAL;
+
+	param->hw_mode_id = mac_phy_caps->hw_mode_id;
+	param->phy_id = mac_phy_caps->phy_id;
+	param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
+			wmi_handle, mac_phy_caps->pdev_id);
+	param->wireless_modes_ext = convert_wireless_modes_ext_tlv(
+			mac_phy_caps->wireless_modes_ext);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * extract_reg_cap_service_ready_ext_tlv() -
  *       extract REG cap from service ready event
@@ -14225,8 +14338,11 @@ struct wmi_ops tlv_ops =  {
 				extract_hw_mode_cap_service_ready_ext_tlv,
 	.extract_mac_phy_cap_service_ready_ext =
 				extract_mac_phy_cap_service_ready_ext_tlv,
+	.extract_mac_phy_cap_service_ready_ext2 =
+				extract_mac_phy_cap_service_ready_ext2_tlv,
 	.extract_reg_cap_service_ready_ext =
 				extract_reg_cap_service_ready_ext_tlv,
+	.extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv,
 	.extract_dbr_ring_cap_service_ready_ext =
 				extract_dbr_ring_cap_service_ready_ext_tlv,
 	.extract_dbr_ring_cap_service_ready_ext2 =