Merge "qcacmn: Add DFS APIs to reset ADFS and reinitialize DFS Timers"
diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c
index fe507f6..dda29ba 100644
--- a/dp/wifi3.0/dp_tx.c
+++ b/dp/wifi3.0/dp_tx.c
@@ -303,8 +303,8 @@
  * Return: HTT metadata size
  *
  */
-uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
-				   struct dp_tx_msdu_info_s *msdu_info)
+static uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
+					  struct dp_tx_msdu_info_s *msdu_info)
 {
 	uint32_t *meta_data = msdu_info->meta_data;
 	struct htt_tx_msdu_desc_ext2_t *desc_ext =
diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h
index f00006f..419e36f 100644
--- a/dp/wifi3.0/dp_tx.h
+++ b/dp/wifi3.0/dp_tx.h
@@ -333,5 +333,3 @@
 }
 /* TODO TX_FEATURE_NOT_YET */
 #endif
-uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
-				   struct dp_tx_msdu_info_s *msdu_info);
diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h
index 6d5c228..8b1eb7f 100644
--- a/dp/wifi3.0/dp_types.h
+++ b/dp/wifi3.0/dp_types.h
@@ -1824,6 +1824,7 @@
 
 	/* dp_peer special list */
 	TAILQ_HEAD(, dp_peer) mpass_peer_list;
+	DP_MUTEX_TYPE mpass_peer_mutex;
 #endif
 };
 
diff --git a/hif/src/ce/ce_assignment.h b/hif/src/ce/ce_assignment.h
index 7defdfe..9a73c9f 100644
--- a/hif/src/ce/ce_assignment.h
+++ b/hif/src/ce/ce_assignment.h
@@ -64,6 +64,7 @@
 /* Maximum number of Copy Engine's supported */
 #define CE_HTT_H2T_MSG_SRC_NENTRIES 2048
 #define CE_HTT_H2T_MSG_SRC_NENTRIES_AR900B 4096
+#define CE_HTT_H2T_MSG_SRC_NENTRIES_QCN7605 4096
 
 #define EPPING_CE_FLAGS_POLL \
 	(CE_ATTR_DISABLE_INTR|CE_ATTR_ENABLE_POLL|CE_ATTR_FLAGS)
@@ -85,7 +86,7 @@
 	{ /* CE3 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,},
 	/* host->target HTT */
 	{ /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,
-		CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,},
+		CE_HTT_H2T_MSG_SRC_NENTRIES_QCN7605, 256, 0, NULL,},
 #ifdef IPA_OFFLOAD
 	/* ipa_uc->target HTC control */
 	{ /* CE5 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,
diff --git a/target_if/core/src/target_if_main.c b/target_if/core/src/target_if_main.c
index 7af4ae1..64cda92 100644
--- a/target_if/core/src/target_if_main.c
+++ b/target_if/core/src/target_if_main.c
@@ -577,7 +577,6 @@
 		return QDF_STATUS_E_INVAL;
 	}
 	init_deinit_chainmask_table_free(ext_param);
-	init_deinit_rf_characterization_entries_free(ext_param);
 	init_deinit_dbr_ring_cap_free(tgt_psoc_info);
 	init_deinit_spectral_scaling_params_free(tgt_psoc_info);
 
diff --git a/target_if/init_deinit/inc/service_ready_param.h b/target_if/init_deinit/inc/service_ready_param.h
index 8d3c2fb..3b55101 100644
--- a/target_if/init_deinit/inc/service_ready_param.h
+++ b/target_if/init_deinit/inc/service_ready_param.h
@@ -289,20 +289,6 @@
 	struct wlan_psoc_host_chainmask_capabilities *cap_list;
 };
 
-#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
-/**
- * struct wlan_psoc_host_rf_characterization_entry - rf characterization table
- * @freq: center frequency of primary channel
- * @bw: bandwidth of primary channel
- * @chan_metric: primary channel-specific metric
- */
-struct wlan_psoc_host_rf_characterization_entry {
-	uint16_t freq;
-	wmi_host_channel_width bw;
-	uint8_t chan_metric;
-};
-#endif
-
 /**
  * struct wlan_psoc_host_service_ext_param - EXT service base params in event
  * @default_conc_scan_config_bits: Default concurrenct scan config
@@ -322,8 +308,6 @@
  * @max_bssid_indicator: Maximum number of VAPs in MBSS IE
  * @num_bin_scaling_params: Number of Spectral bin scaling parameters
  * @chainmask_table: Available chain mask tables.
- * @num_rf_characterization_entries: Number of RF characterization info entries
- * @rf_characterization_entries: Channel RF characterization information entries
  * @sar_version: SAR version info
  */
 struct wlan_psoc_host_service_ext_param {
@@ -342,11 +326,6 @@
 	uint32_t num_bin_scaling_params;
 	struct wlan_psoc_host_chainmask_table
 		chainmask_table[PSOC_MAX_CHAINMASK_TABLES];
-#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
-	uint32_t num_rf_characterization_entries;
-	struct wlan_psoc_host_rf_characterization_entry
-		*rf_characterization_entries;
-#endif
 	uint32_t sar_version;
 };
 
diff --git a/target_if/init_deinit/inc/service_ready_util.h b/target_if/init_deinit/inc/service_ready_util.h
index d8e3345..6293931 100644
--- a/target_if/init_deinit/inc/service_ready_util.h
+++ b/target_if/init_deinit/inc/service_ready_util.h
@@ -27,51 +27,6 @@
 #include "service_ready_param.h"
 #include "target_if.h"
 
-#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
-/**
- * init_deinit_populate_rf_characterization_entries()
- *	- allocates space for and populates the RF characterization information
- * @handle: WMI handle pointer
- * @evt: event buffer received from FW
- * @service_ext_param: pointer to server ext param
- *
- * Allocates space for and populates the RF characterization information
- *
- * Return: QDF Status
- */
-QDF_STATUS init_deinit_populate_rf_characterization_entries(
-		wmi_unified_t handle,
-		uint8_t *evt,
-		struct wlan_psoc_host_service_ext_param *service_ext_par);
-
-/**
- * init_deinit_rf_characterization_entries_free()
- *	- free RF characterization information
- * @service_ext_param: pointer to server ext param
- *
- * Frees RF characterization information
- *
- * Return: QDF Status
- */
-QDF_STATUS init_deinit_rf_characterization_entries_free(
-		struct wlan_psoc_host_service_ext_param *service_ext_par);
-#else
-static inline
-QDF_STATUS init_deinit_populate_rf_characterization_entries(
-		wmi_unified_t handle, uint8_t *evt,
-		struct wlan_psoc_host_service_ext_param *ser_ext_par)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
-static inline
-QDF_STATUS init_deinit_rf_characterization_entries_free(
-		struct wlan_psoc_host_service_ext_param *ser_ext_par)
-{
-	return QDF_STATUS_SUCCESS;
-}
-#endif
-
 /**
  * init_deinit_chainmask_table_alloc()
  *	- allocate chainmask table capability list.
diff --git a/target_if/init_deinit/src/init_event_handler.c b/target_if/init_deinit/src/init_event_handler.c
index f769386..a7aac22 100644
--- a/target_if/init_deinit/src/init_event_handler.c
+++ b/target_if/init_deinit/src/init_event_handler.c
@@ -268,13 +268,6 @@
 			goto exit;
 	}
 
-	err_code = init_deinit_populate_rf_characterization_entries(
-						wmi_handle,
-						event,
-						&info->service_ext_param);
-	if (err_code)
-		goto exit;
-
 	err_code = init_deinit_populate_dbr_ring_cap(psoc, wmi_handle,
 						event, info);
 	if (err_code)
diff --git a/target_if/init_deinit/src/service_ready_util.c b/target_if/init_deinit/src/service_ready_util.c
index c9c1db6..2b038aa 100644
--- a/target_if/init_deinit/src/service_ready_util.c
+++ b/target_if/init_deinit/src/service_ready_util.c
@@ -26,51 +26,6 @@
 #include <target_type.h>
 #include <qdf_module.h>
 
-#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
-QDF_STATUS init_deinit_populate_rf_characterization_entries(
-		wmi_unified_t handle, uint8_t *evt,
-		struct wlan_psoc_host_service_ext_param *ser_ext_par)
-{
-	uint32_t alloc_size;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-
-	if (ser_ext_par->num_rf_characterization_entries == 0)
-		return QDF_STATUS_SUCCESS;
-
-	alloc_size = (sizeof(struct wlan_psoc_host_rf_characterization_entry) *
-				ser_ext_par->num_rf_characterization_entries);
-
-	ser_ext_par->rf_characterization_entries = qdf_mem_malloc(alloc_size);
-	if (!ser_ext_par->rf_characterization_entries) {
-		init_deinit_rf_characterization_entries_free(ser_ext_par);
-		return QDF_STATUS_E_NOMEM;
-	}
-
-	status = wmi_extract_rf_characterization_entries(handle, evt,
-				ser_ext_par->rf_characterization_entries);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		target_if_err("failed to parse wmi service ready ext param");
-		init_deinit_rf_characterization_entries_free(ser_ext_par);
-	}
-
-	return status;
-}
-
-qdf_export_symbol(init_deinit_populate_rf_characterization_entries);
-
-QDF_STATUS init_deinit_rf_characterization_entries_free(
-		struct wlan_psoc_host_service_ext_param *ser_ext_par)
-{
-	qdf_mem_free(ser_ext_par->rf_characterization_entries);
-	ser_ext_par->rf_characterization_entries = NULL;
-	ser_ext_par->num_rf_characterization_entries = 0;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-qdf_export_symbol(init_deinit_rf_characterization_entries_free);
-#endif
-
 QDF_STATUS init_deinit_chainmask_table_alloc(
 		struct wlan_psoc_host_service_ext_param *ser_ext_par)
 {
diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h
index 4dc9c14..b143538 100644
--- a/umac/dfs/core/src/dfs.h
+++ b/umac/dfs/core/src/dfs.h
@@ -2655,4 +2655,18 @@
 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
 bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs);
 #endif
+
+/**
+ * dfs_reset_agile_config() - Reset the ADFS config variables.
+ * @dfs: Pointer to dfs_soc_priv_obj.
+ */
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_reset_agile_config(struct dfs_soc_priv_obj *dfs_soc);
+#endif
+
+/**
+ * dfs_reinit_timers() - Reinit timers in DFS.
+ * @dfs: Pointer to wlan_dfs.
+ */
+int dfs_reinit_timers(struct wlan_dfs *dfs);
 #endif  /* _DFS_H_ */
diff --git a/umac/dfs/core/src/dfs_zero_cac.h b/umac/dfs/core/src/dfs_zero_cac.h
index 5ddacd1..be79903 100644
--- a/umac/dfs/core/src/dfs_zero_cac.h
+++ b/umac/dfs/core/src/dfs_zero_cac.h
@@ -63,6 +63,10 @@
 #define MIN_WEATHER_PRECAC_DURATION          (60 * 60 * 1000) /* 1 hour */
 #define MAX_PRECAC_DURATION              (4 * 60 * 60 * 1000) /* 4 hours */
 #define MAX_WEATHER_PRECAC_DURATION     (24 * 60 * 60 * 1000) /* 24 hours */
+
+#define PCAC_DFS_INDEX_ZERO               0
+#define PCAC_TIMER_NOT_RUNNING            0
+#define PRECAC_NOT_STARTED                0
 /**
  * struct precac_tree_node - Individual tree node structure for every node in
  *                           the precac forest maintained.
diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c
index 0c2a3a0..230d8e6 100644
--- a/umac/dfs/core/src/misc/dfs.c
+++ b/umac/dfs/core/src/misc/dfs.c
@@ -755,3 +755,12 @@
 	dfs->dfs_curchan->dfs_ch_flags = flags;
 	dfs->dfs_curchan->dfs_ch_flagext = flagext;
 }
+
+int dfs_reinit_timers(struct wlan_dfs *dfs)
+{
+	dfs_cac_attach(dfs);
+	dfs_zero_cac_timer_init(dfs->dfs_soc_obj);
+	dfs_nol_timer_init(dfs);
+	dfs_main_task_testtimer_init(dfs);
+	return 0;
+}
diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h
index 35f6f7f..110f3d6 100644
--- a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h
+++ b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h
@@ -434,4 +434,32 @@
  */
 QDF_STATUS ucfg_dfs_get_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev,
 					       bool *nol_subchannel_marking);
+/**
+ * ucfg_dfs_reinit_timers() - Init DFS timers.
+ * @pdev: Pointer to wlan_objmgr_pdev structure.
+ *
+ * Wrapper function to reset CAC, NOL, DFS Test Timer and ZeroCAC Timer.
+ * This is invoked per pdev to reinitialize timers after HW Mode Switch is
+ * triggered.
+ */
+QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_dfs_reset_agile_config() - Reset ADFS config.
+ * @pdev: Pointer to wlan_objmgr_pdev structure.
+ *
+ * Wrapper function to reset Agile DFS config such as the variables which hold
+ * information about the state of the preCAC timer, active precac
+ * dfs index and OCAC status. It is invoked before HW Mode switch is triggered
+ * to ensure ADFS config is in a well known consistent state.
+ */
+#ifdef QCA_SUPPORT_AGILE_DFS
+QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc *psoc);
+#else
+static inline QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc
+						    *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #endif /* _WLAN_DFS_UCFG_API_H_ */
diff --git a/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c b/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c
index 2f284b4..93c42ed 100644
--- a/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c
+++ b/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c
@@ -341,7 +341,7 @@
 	dfs = wlan_pdev_get_dfs_obj(pdev);
 	if (!dfs) {
 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
-		return  false;
+		return;
 	}
 
 	return dfs_is_hw_pulses_allowed(dfs);
@@ -349,3 +349,49 @@
 
 qdf_export_symbol(ucfg_dfs_is_hw_pulses_allowed);
 #endif
+
+#ifdef QCA_SUPPORT_AGILE_DFS
+QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc *psoc)
+{
+	struct dfs_soc_priv_obj *soc_obj;
+
+	if (!psoc) {
+		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "psoc is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+							WLAN_UMAC_COMP_DFS);
+	if (!soc_obj) {
+		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
+			"Failed to get dfs psoc component");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_reset_agile_config(soc_obj);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(ucfg_dfs_reset_agile_config);
+#endif
+
+QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_dfs *dfs;
+
+	if (!tgt_dfs_is_pdev_5ghz(pdev))
+		return QDF_STATUS_SUCCESS;
+
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dfs_reinit_timers(dfs);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(ucfg_dfs_reinit_timers);
diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h
index ea86aa6..c820888 100644
--- a/wmi/inc/wmi_unified_api.h
+++ b/wmi/inc/wmi_unified_api.h
@@ -2969,17 +2969,32 @@
 
 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
 /**
- * wmi_extract_rf_characterziation_entries - Extract RF characterization metrics
- * received through extended service ready event.
+ * wmi_extract_num_rf_characterziation_entries - Extract number of RF
+ * characterization metrics received from the RF characterization event.
  * @wmi_hdl: WMI handle
  * @evt_buf: Event buffer
+ * @num_rf_characterization_entries: Number of RF characterization metrics
+ *
+ * Return: QDF status of operation
+ */
+QDF_STATUS wmi_extract_num_rf_characterization_entries(wmi_unified_t wmi_hdl,
+				uint8_t *evt_buf,
+				uint32_t *num_rf_characterization_entries);
+
+/**
+ * wmi_extract_rf_characterziation_entries - Extract RF characterization metrics
+ * received from the RF characterization event.
+ * @wmi_hdl: WMI handle
+ * @evt_buf: Event buffer
+ * @num_rf_characterization_entries: Number of RF characterization metrics
  * @rf_characterization_entries: Pointer to RF characterization metrics
  *
  * Return: QDF status of operation
  */
 QDF_STATUS wmi_extract_rf_characterization_entries(wmi_unified_t wmi_hdl,
 	uint8_t *evt_buf,
-	struct wlan_psoc_host_rf_characterization_entry *rf_characterization_entries);
+	uint32_t num_rf_characterization_entries,
+	struct wmi_host_rf_characterization_event_param *rf_characterization_entries);
 #endif
 
 /*
diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h
index 422aef3..2d23dfd 100644
--- a/wmi/inc/wmi_unified_param.h
+++ b/wmi/inc/wmi_unified_param.h
@@ -4860,6 +4860,7 @@
 	wmi_pdev_interop_issues_ap_event_id,
 #endif
 	wmi_coex_report_antenna_isolation_event_id,
+	wmi_chan_rf_characterization_info_event_id,
 	wmi_events_max,
 } wmi_conv_event_id;
 
@@ -7167,6 +7168,18 @@
 	uint32_t pdev_id;
 };
 
+/**
+ * struct wmi_host_rf_characterization_event_param - rf characterization table
+ * @freq: center frequency of primary channel (in MHz)
+ * @bw: bandwidth of primary channel (in MHz)
+ * @chan_metric: primary channel-specific metric
+ */
+struct wmi_host_rf_characterization_event_param {
+	uint16_t freq;
+	wmi_host_channel_width bw;
+	uint8_t chan_metric;
+};
+
 /*
  * struct wmi_host_fips_event_param: FIPS event param
  * @pdev_id: pdev id
diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h
index e2cab3a..3ac2732 100644
--- a/wmi/inc/wmi_unified_priv.h
+++ b/wmi/inc/wmi_unified_priv.h
@@ -1752,9 +1752,15 @@
 		uint32_t len);
 
 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
+QDF_STATUS (*extract_num_rf_characterization_entries)(wmi_unified_t wmi_hdl,
+				uint8_t *evt_buf,
+				uint32_t *num_rf_characterization_entries);
+
+
 QDF_STATUS (*extract_rf_characterization_entries)(wmi_unified_t wmi_handle,
 	uint8_t *evt_buf,
-	struct wlan_psoc_host_rf_characterization_entry *rf_characterization_entries);
+	uint32_t num_rf_characterization_entries,
+	struct wmi_host_rf_characterization_event_param *rf_characterization_entries);
 #endif
 
 QDF_STATUS (*extract_chainmask_tables)(wmi_unified_t wmi_handle,
diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c
index 064cdc7..860032d 100644
--- a/wmi/src/wmi_unified_api.c
+++ b/wmi/src/wmi_unified_api.c
@@ -2471,13 +2471,26 @@
 }
 
 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
+QDF_STATUS wmi_extract_num_rf_characterization_entries(wmi_unified_t wmi_hdl,
+				uint8_t *evt_buf,
+				uint32_t *num_rf_characterization_entries)
+{
+	if (wmi_hdl->ops->extract_num_rf_characterization_entries)
+		return wmi_hdl->ops->extract_num_rf_characterization_entries(wmi_hdl,
+				evt_buf, num_rf_characterization_entries);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 QDF_STATUS wmi_extract_rf_characterization_entries(wmi_unified_t wmi_hdl,
 	uint8_t *evt_buf,
-	struct wlan_psoc_host_rf_characterization_entry *rf_characterization_entries)
+	uint32_t num_rf_characterization_entries,
+	struct wmi_host_rf_characterization_event_param *rf_characterization_entries)
 {
 	if (wmi_hdl->ops->extract_rf_characterization_entries)
 		return wmi_hdl->ops->extract_rf_characterization_entries(wmi_hdl,
-					evt_buf, rf_characterization_entries);
+				evt_buf, num_rf_characterization_entries,
+				rf_characterization_entries);
 
 	return QDF_STATUS_E_FAILURE;
 }
diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c
index 5bbf6be..6fe44ec 100644
--- a/wmi/src/wmi_unified_tlv.c
+++ b/wmi/src/wmi_unified_tlv.c
@@ -9301,24 +9301,46 @@
 }
 
 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
+static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle,
+	uint8_t *event,
+	uint32_t *num_rf_characterization_entries)
+{
+	WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf;
+
+	param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event;
+	if (!param_buf)
+		return QDF_STATUS_E_INVAL;
+
+	*num_rf_characterization_entries =
+			param_buf->num_wmi_chan_rf_characterization_info;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle,
 	uint8_t *event,
-	struct wlan_psoc_host_rf_characterization_entry *rf_characterization_entries)
+	uint32_t num_rf_characterization_entries,
+	struct wmi_host_rf_characterization_event_param *rf_characterization_entries)
 {
-	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
+	WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf;
 	WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry;
 	uint8_t ix;
 
-	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event;
+	param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event;
 	if (!param_buf)
 		return QDF_STATUS_E_INVAL;
 
 	wmi_rf_characterization_entry =
-				param_buf->wmi_chan_rf_characterization_info;
+			param_buf->wmi_chan_rf_characterization_info;
 	if (!wmi_rf_characterization_entry)
 		return QDF_STATUS_E_INVAL;
 
-	for (ix = 0; ix < param_buf->num_wmi_chan_rf_characterization_info; ix++) {
+	/*
+	 * Using num_wmi_chan_rf_characterization instead of param_buf value
+	 * since memory for rf_characterization_entries was allocated using
+	 * the former.
+	 */
+	for (ix = 0; ix < num_rf_characterization_entries; ix++) {
 		rf_characterization_entries[ix].freq =
 				WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET(
 					&wmi_rf_characterization_entry[ix]);
@@ -9447,22 +9469,6 @@
 	return QDF_STATUS_SUCCESS;
 }
 
-#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
-static void populate_num_rf_characterization_entries(
-			struct wlan_psoc_host_service_ext_param *param,
-			WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf)
-{
-	param->num_rf_characterization_entries =
-			param_buf->num_wmi_chan_rf_characterization_info;
-}
-#else
-static void populate_num_rf_characterization_entries(
-			struct wlan_psoc_host_service_ext_param *param,
-			WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf)
-{
-}
-#endif
-
 /**
  * extract_service_ready_ext_tlv() - extract basic extended service ready params
  * from event
@@ -9501,7 +9507,6 @@
 	param->num_dbr_ring_caps = param_buf->num_dma_ring_caps;
 	param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params;
 	param->max_bssid_indicator = ev->max_bssid_indicator;
-	populate_num_rf_characterization_entries(param, param_buf);
 	qdf_mem_copy(&param->ppet, &ev->ppet, sizeof(param->ppet));
 
 	hw_caps = param_buf->soc_hw_mode_caps;
@@ -11864,6 +11869,8 @@
 	.extract_reg_chan_list_update_event =
 		extract_reg_chan_list_update_event_tlv,
 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
+	.extract_num_rf_characterization_entries =
+		extract_num_rf_characterization_entries_tlv,
 	.extract_rf_characterization_entries =
 		extract_rf_characterization_entries_tlv,
 #endif
@@ -12266,6 +12273,8 @@
 				WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID;
 	event_ids[wmi_peer_ratecode_list_event_id] =
 				WMI_PEER_RATECODE_LIST_EVENTID;
+	event_ids[wmi_chan_rf_characterization_info_event_id] =
+				WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID;
 }
 
 /**