Browse Source

qcacld-3.0: wma to target_if migration of roam_stats_event

Currently, wmi_roam_stats_event_id data is extracted and
processing is also done in wma. This is not inline with component
model where target_if takes care of data extraction and handover
the extracted data to corresponding component(connection mgr in
this case). Add changes to support the same.

Change-Id: I5e336b01e1a2183e49b3e6eeb125c7c9fd0fd73c
CRs-Fixed: 3003125
Sai Pavan Akhil Remella 3 years ago
parent
commit
b35419136e

+ 11 - 0
components/target_if/connection_mgr/inc/target_if_cm_roam_event.h

@@ -66,6 +66,17 @@ target_if_cm_roam_sync_frame_event(ol_scn_t scn,
  */
 int target_if_cm_roam_event(ol_scn_t scn, uint8_t *event, uint32_t len);
 
+/**
+ * target_if_cm_roam_stats_event() - Target IF handler for roam stats event
+ * @scn: target handle
+ * @event: event buffer
+ * @len: event buffer length
+ *
+ * Return: int for success or error code
+ */
+int
+target_if_cm_roam_stats_event(ol_scn_t scn, uint8_t *event, uint32_t len);
+
 /**
  * target_if_roam_offload_register_events() - register roam events
  * @psoc: pointer to psoc object

+ 59 - 0
components/target_if/connection_mgr/src/target_if_cm_roam_event.c

@@ -60,6 +60,7 @@ target_if_cm_roam_register_rx_ops(struct wlan_cm_roam_rx_ops *rx_ops)
 	rx_ops->btm_blacklist_event = cm_btm_blacklist_event_handler;
 	rx_ops->vdev_disconnect_event = cm_vdev_disconnect_event_handler;
 	rx_ops->roam_scan_chan_list_event = cm_roam_scan_ch_list_event_handler;
+	rx_ops->roam_stats_event_rx = cm_roam_stats_event_handler;
 #endif
 }
 
@@ -346,6 +347,55 @@ target_if_cm_roam_scan_chan_list_event_handler(ol_scn_t scn, uint8_t *event,
 	return status;
 }
 
+int
+target_if_cm_roam_stats_event(ol_scn_t scn, uint8_t *event, uint32_t len)
+{
+	QDF_STATUS qdf_status;
+	int status = 0;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_cm_roam_rx_ops *roam_rx_ops;
+	struct roam_stats_event *stats_info = NULL;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return -EINVAL;
+	}
+
+	qdf_status = wmi_extract_roam_stats_event(wmi_handle, event, len,
+						  &stats_info);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		target_if_err("parsing of event failed, %d", qdf_status);
+		return -EINVAL;
+	}
+
+	roam_rx_ops = target_if_cm_get_roam_rx_ops(psoc);
+	if (!roam_rx_ops || !roam_rx_ops->roam_stats_event_rx) {
+		target_if_err("No valid roam rx ops");
+		status = -EINVAL;
+		if (stats_info) {
+			if (stats_info->roam_msg_info)
+				qdf_mem_free(stats_info->roam_msg_info);
+			qdf_mem_free(stats_info);
+		}
+		goto err;
+	}
+
+	qdf_status = roam_rx_ops->roam_stats_event_rx(psoc, stats_info);
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		status = -EINVAL;
+
+err:
+	return status;
+}
+
 QDF_STATUS
 target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
 {
@@ -414,6 +464,15 @@ target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	ret = wmi_unified_register_event_handler(handle,
+						 wmi_roam_stats_event_id,
+						 target_if_cm_roam_stats_event,
+						 WMI_RX_SERIALIZER_CTX);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 11 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -1309,6 +1309,17 @@ cm_handle_disconnect_reason(struct vdev_disconnect_event_data *data);
 QDF_STATUS
 cm_roam_scan_ch_list_event_handler(struct cm_roam_scan_ch_resp *data);
 
+/**
+ * cm_roam_stats_event_handler() - Carries extracted roam stats info
+ * @psoc: PSOC pointer
+ * @stats_info: stats data carried by roam_stats_event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
+			    struct roam_stats_event *stats_info);
+
 /**
  * cm_roam_update_vdev() - Update the STA and BSS
  * @sync_ind: Information needed for roam sync propagation

+ 30 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -1876,6 +1876,32 @@ struct roam_offload_roam_event {
 	uint8_t *deauth_disassoc_frame;
 };
 
+/**
+ * struct roam_stats_event - Data carried by stats event
+ * @vdev_id: vdev id
+ * @num_tlv: Number of roam scans triggered
+ * @num_roam_msg_info: Number of roam_msg_info present in event
+ * @trigger: Roam trigger related details
+ * @scan: Roam scan event details
+ * @result: Roam result related info
+ * @data_11kv: Neighbor report/BTM request related data
+ * @btm_rsp: BTM response related data
+ * @roam_init_info: Roam initial related data
+ * @roam_msg_info: Roam message related information
+ */
+struct roam_stats_event {
+	uint8_t vdev_id;
+	uint8_t num_tlv;
+	uint8_t num_roam_msg_info;
+	struct wmi_roam_trigger_info trigger[MAX_ROAM_SCAN_STATS_TLV];
+	struct wmi_roam_scan_data scan[MAX_ROAM_SCAN_STATS_TLV];
+	struct wmi_roam_result result[MAX_ROAM_SCAN_STATS_TLV];
+	struct wmi_neighbor_report_data data_11kv[MAX_ROAM_SCAN_STATS_TLV];
+	struct roam_btm_response_data btm_rsp[MAX_ROAM_SCAN_STATS_TLV];
+	struct roam_initial_data roam_init_info[MAX_ROAM_SCAN_STATS_TLV];
+	struct roam_msg_info *roam_msg_info;
+};
+
 /**
  * wlan_cm_roam_tx_ops  - structure of tx function pointers for
  * roaming related commands
@@ -2067,6 +2093,7 @@ struct roam_offload_synch_ind {
  * @btm_blacklist_event: Rx ops function pointer for btm blacklist event
  * @vdev_disconnect_event: Rx ops function pointer for vdev disconnect event
  * @roam_scan_chan_list_event: Rx ops function pointer for roam scan ch event
+ * @roam_stats_event_rx: Rx ops function pointer for roam stats event
  */
 struct wlan_cm_roam_rx_ops {
 	QDF_STATUS (*roam_sync_event)(struct wlan_objmgr_psoc *psoc,
@@ -2083,6 +2110,9 @@ struct wlan_cm_roam_rx_ops {
 	(*vdev_disconnect_event)(struct vdev_disconnect_event_data *data);
 	QDF_STATUS
 	(*roam_scan_chan_list_event)(struct cm_roam_scan_ch_resp *data);
+	QDF_STATUS
+	(*roam_stats_event_rx)(struct wlan_objmgr_psoc *psoc,
+			       struct roam_stats_event *stats_info);
 #endif
 };
 #endif

+ 526 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -2306,4 +2306,530 @@ cm_roam_scan_ch_list_event_handler(struct cm_roam_scan_ch_resp *data)
 {
 	return cm_handle_scan_ch_list_data(data);
 }
+
+/**
+ * cm_roam_stats_get_trigger_detail_str - Return roam trigger string from the
+ * enum roam_trigger_reason
+ * @ptr: Pointer to the roam trigger info
+ * @buf: Destination buffer to write the reason string
+ *
+ * Return: None
+ */
+static void
+cm_roam_stats_get_trigger_detail_str(struct wmi_roam_trigger_info *ptr,
+				     char *buf)
+{
+	uint16_t buf_cons, buf_left = MAX_ROAM_DEBUG_BUF_SIZE;
+	char *temp = buf;
+
+	buf_cons = qdf_snprint(temp, buf_left, "Reason: \"%s\" ",
+			       mlme_get_roam_trigger_str(ptr->trigger_reason));
+	temp += buf_cons;
+	buf_left -= buf_cons;
+
+	if (ptr->trigger_sub_reason) {
+		buf_cons = qdf_snprint(temp, buf_left, "Sub-Reason: %s",
+			      mlme_get_sub_reason_str(ptr->trigger_sub_reason));
+		temp += buf_cons;
+		buf_left -= buf_cons;
+	}
+
+	switch (ptr->trigger_reason) {
+	case ROAM_TRIGGER_REASON_PER:
+	case ROAM_TRIGGER_REASON_BMISS:
+	case ROAM_TRIGGER_REASON_HIGH_RSSI:
+	case ROAM_TRIGGER_REASON_MAWC:
+	case ROAM_TRIGGER_REASON_DENSE:
+	case ROAM_TRIGGER_REASON_BACKGROUND:
+	case ROAM_TRIGGER_REASON_IDLE:
+	case ROAM_TRIGGER_REASON_FORCED:
+	case ROAM_TRIGGER_REASON_UNIT_TEST:
+		break;
+	case ROAM_TRIGGER_REASON_BTM:
+		buf_cons = qdf_snprint(temp, buf_left,
+				       "Req_mode: %d Disassoc_timer: %d",
+				       ptr->btm_trig_data.btm_request_mode,
+				       ptr->btm_trig_data.disassoc_timer);
+		temp += buf_cons;
+		buf_left -= buf_cons;
+
+		buf_cons = qdf_snprint(temp, buf_left,
+				"validity_interval: %d candidate_list_cnt: %d resp_status: %d, bss_termination_timeout: %d, mbo_assoc_retry_timeout: %d",
+				ptr->btm_trig_data.validity_interval,
+				ptr->btm_trig_data.candidate_list_count,
+				ptr->btm_trig_data.btm_resp_status,
+				ptr->btm_trig_data.btm_bss_termination_timeout,
+				ptr->btm_trig_data.btm_mbo_assoc_retry_timeout);
+		buf_left -= buf_cons;
+		temp += buf_cons;
+		break;
+	case ROAM_TRIGGER_REASON_BSS_LOAD:
+		buf_cons = qdf_snprint(temp, buf_left, "CU: %d %% ",
+				       ptr->cu_trig_data.cu_load);
+		temp += buf_cons;
+		buf_left -= buf_cons;
+		break;
+	case ROAM_TRIGGER_REASON_DEAUTH:
+		buf_cons = qdf_snprint(temp, buf_left, "Type: %d Reason: %d ",
+				       ptr->deauth_trig_data.type,
+				       ptr->deauth_trig_data.reason);
+		temp += buf_cons;
+		buf_left -= buf_cons;
+		break;
+	case ROAM_TRIGGER_REASON_LOW_RSSI:
+	case ROAM_TRIGGER_REASON_PERIODIC:
+		/*
+		 * Use ptr->current_rssi get the RSSI of current AP after
+		 * roam scan is triggered. This avoids discrepency with the
+		 * next rssi threshold value printed in roam scan details.
+		 * ptr->rssi_trig_data.threshold gives the rssi threshold
+		 * for the Low Rssi/Periodic scan trigger.
+		 */
+		buf_cons = qdf_snprint(temp, buf_left,
+				       "Cur_Rssi threshold:%d Current AP RSSI: %d",
+				       ptr->rssi_trig_data.threshold,
+				       ptr->current_rssi);
+		temp += buf_cons;
+		buf_left -= buf_cons;
+		break;
+	case ROAM_TRIGGER_REASON_WTC_BTM:
+		if (ptr->wtc_btm_trig_data.wtc_candi_rssi_ext_present) {
+			buf_cons = qdf_snprint(temp, buf_left,
+				   "Roaming Mode: %d, Trigger Reason: %d, Sub code:%d, wtc mode:%d, wtc scan mode:%d, wtc rssi th:%d, wtc candi rssi th_2g:%d, wtc_candi_rssi_th_5g:%d, wtc_candi_rssi_th_6g:%d",
+				   ptr->wtc_btm_trig_data.roaming_mode,
+				   ptr->wtc_btm_trig_data.vsie_trigger_reason,
+				   ptr->wtc_btm_trig_data.sub_code,
+				   ptr->wtc_btm_trig_data.wtc_mode,
+				   ptr->wtc_btm_trig_data.wtc_scan_mode,
+				   ptr->wtc_btm_trig_data.wtc_rssi_th,
+				   ptr->wtc_btm_trig_data.wtc_candi_rssi_th,
+				   ptr->wtc_btm_trig_data.wtc_candi_rssi_th_5g,
+				   ptr->wtc_btm_trig_data.wtc_candi_rssi_th_6g);
+		} else {
+			buf_cons = qdf_snprint(temp, buf_left,
+				   "Roaming Mode: %d, Trigger Reason: %d, Sub code:%d, wtc mode:%d, wtc scan mode:%d, wtc rssi th:%d, wtc candi rssi th:%d",
+				   ptr->wtc_btm_trig_data.roaming_mode,
+				   ptr->wtc_btm_trig_data.vsie_trigger_reason,
+				   ptr->wtc_btm_trig_data.sub_code,
+				   ptr->wtc_btm_trig_data.wtc_mode,
+				   ptr->wtc_btm_trig_data.wtc_scan_mode,
+				   ptr->wtc_btm_trig_data.wtc_rssi_th,
+				   ptr->wtc_btm_trig_data.wtc_candi_rssi_th);
+		}
+
+		temp += buf_cons;
+		buf_left -= buf_cons;
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * cm_roam_stats_print_trigger_info  - Roam trigger related details
+ * @data:    Pointer to the roam trigger data
+ * @vdev_id: Vdev ID
+ *
+ * Prints the vdev, roam trigger reason, time of the day at which roaming
+ * was triggered.
+ *
+ * Return: None
+ */
+static void
+cm_roam_stats_print_trigger_info(struct wmi_roam_trigger_info *data,
+				 uint8_t vdev_id)
+{
+	char *buf;
+	char time[TIME_STRING_LEN];
+
+	buf = qdf_mem_malloc(MAX_ROAM_DEBUG_BUF_SIZE);
+	if (!buf)
+		return;
+
+	cm_roam_stats_get_trigger_detail_str(data, buf);
+	mlme_get_converted_timestamp(data->timestamp, time);
+	mlme_nofl_info("%s [ROAM_TRIGGER]: VDEV[%d] %s", time, vdev_id, buf);
+
+	qdf_mem_free(buf);
+}
+
+/**
+ * cm_roam_stats_print_btm_rsp_info - BTM RSP related details
+ * @data:    Pointer to the btm rsp data
+ * @vdev_id: vdev id
+ *
+ * Prints the vdev, btm status, target_bssid and vsie reason
+ *
+ * Return: None
+ */
+static void
+cm_roam_stats_print_btm_rsp_info(struct roam_btm_response_data *data,
+				 uint8_t vdev_id)
+{
+	char time[TIME_STRING_LEN];
+
+	mlme_get_converted_timestamp(data->timestamp, time);
+	mlme_nofl_info("%s [BTM RSP]:VDEV[%d], Status:%d, VSIE reason:%d, BSSID: "
+		       QDF_MAC_ADDR_FMT, time, vdev_id, data->btm_status,
+		       data->vsie_reason,
+		       QDF_MAC_ADDR_REF(data->target_bssid.bytes));
+}
+
+/**
+ * cm_roam_stats_print_roam_initial_info - Roaming related initial details
+ * @data:    Pointer to the btm rsp data
+ * @vdev_id: vdev id
+ *
+ * Prints the vdev, roam_full_scan_count, channel and rssi
+ * utilization threhold and timer
+ *
+ * Return: None
+ */
+static void
+cm_roam_stats_print_roam_initial_info(struct roam_initial_data *data,
+				      uint8_t vdev_id)
+{
+	mlme_nofl_info("[ROAM INIT INFO]: VDEV[%d], roam_full_scan_count: %d, rssi_th: %d, cu_th: %d, fw_cancel_timer_bitmap: %d",
+		       vdev_id, data->roam_full_scan_count, data->rssi_th,
+		       data->cu_th, data->fw_cancel_timer_bitmap);
+}
+
+/**
+ * cm_roam_stats_print_roam_msg_info - Roaming related message details
+ * @data:    Pointer to the btm rsp data
+ * @vdev_id: vdev id
+ *
+ * Prints the vdev, msg_id, msg_param1, msg_param2 and timer
+ *
+ * Return: None
+ */
+static void cm_roam_stats_print_roam_msg_info(struct roam_msg_info *data,
+					      uint8_t vdev_id)
+{
+	char time[TIME_STRING_LEN];
+	static const char msg_id1_str[] = "Roam RSSI TH Reset";
+
+	if (data->msg_id == WMI_ROAM_MSG_RSSI_RECOVERED) {
+		mlme_get_converted_timestamp(data->timestamp, time);
+		mlme_nofl_info("%s [ROAM MSG INFO]: VDEV[%d] %s, Current rssi: %d dbm, next_rssi_threshold: %d dbm",
+			       time, vdev_id, msg_id1_str, data->msg_param1,
+			       data->msg_param2);
+	}
+}
+
+/**
+ * cm_stats_log_roam_scan_candidates  - Print roam scan candidate AP info
+ * @ap:           Pointer to the candidate AP list
+ * @num_entries:  Number of candidate APs
+ *
+ * Print the RSSI, CU load, Cu score, RSSI score, total score, BSSID
+ * and time stamp at which the candidate was found details.
+ *
+ * Return: None
+ */
+static void
+cm_stats_log_roam_scan_candidates(struct wmi_roam_candidate_info *ap,
+				  uint8_t num_entries)
+{
+	uint16_t i;
+	char time[TIME_STRING_LEN], time2[TIME_STRING_LEN];
+
+	mlme_nofl_info("%62s%62s", LINE_STR, LINE_STR);
+	mlme_nofl_info("%13s %16s %8s %4s %4s %5s/%3s %3s/%3s %7s %7s %6s %12s %20s",
+		       "AP BSSID", "TSTAMP", "CH", "TY", "ETP", "RSSI",
+		       "SCR", "CU%", "SCR", "TOT_SCR", "BL_RSN", "BL_SRC",
+		       "BL_TSTAMP", "BL_TIMEOUT(ms)");
+	mlme_nofl_info("%62s%62s", LINE_STR, LINE_STR);
+
+	if (num_entries > MAX_ROAM_CANDIDATE_AP)
+		num_entries = MAX_ROAM_CANDIDATE_AP;
+
+	for (i = 0; i < num_entries; i++) {
+		mlme_get_converted_timestamp(ap->timestamp, time);
+		mlme_get_converted_timestamp(ap->bl_timestamp, time2);
+		mlme_nofl_info(QDF_MAC_ADDR_FMT " %17s %4d %-4s %4d %3d/%-4d %2d/%-4d %5d %7d %7d %17s %9d",
+			       QDF_MAC_ADDR_REF(ap->bssid.bytes), time,
+			  ap->freq,
+			  ((ap->type == 0) ? "C_AP" :
+			  ((ap->type == 2) ? "R_AP" : "P_AP")),
+			  ap->etp, ap->rssi, ap->rssi_score, ap->cu_load,
+			  ap->cu_score, ap->total_score, ap->bl_reason,
+			  ap->bl_source, time2, ap->bl_original_timeout);
+		ap++;
+	}
+}
+
+/**
+ * cm_roam_stats_print_scan_info  - Print the roam scan details and candidate AP
+ * details
+ * @scan:      Pointer to the received tlv after sanitization
+ * @vdev_id:   Vdev ID
+ * @trigger:   Roam scan trigger reason
+ * @timestamp: Host timestamp in millisecs
+ *
+ * Prinst the roam scan details with time of the day when the scan was
+ * triggered and roam candidate AP with score details
+ *
+ * Return: None
+ */
+static void
+cm_roam_stats_print_scan_info(struct wmi_roam_scan_data *scan, uint8_t vdev_id,
+			      uint32_t trigger, uint32_t timestamp)
+{
+	uint16_t num_ch = scan->num_chan;
+	uint16_t buf_cons = 0, buf_left = ROAM_CHANNEL_BUF_SIZE;
+	uint8_t i;
+	char *buf, *buf1, *tmp;
+	char time[TIME_STRING_LEN];
+
+	buf = qdf_mem_malloc(ROAM_CHANNEL_BUF_SIZE);
+	if (!buf)
+		return;
+
+	tmp = buf;
+	/* For partial scans, print the channel info */
+	if (!scan->type) {
+		buf_cons = qdf_snprint(tmp, buf_left, "{");
+		buf_left -= buf_cons;
+		tmp += buf_cons;
+
+		for (i = 0; i < num_ch; i++) {
+			buf_cons = qdf_snprint(tmp, buf_left, "%d ",
+					       scan->chan_freq[i]);
+			buf_left -= buf_cons;
+			tmp += buf_cons;
+		}
+		buf_cons = qdf_snprint(tmp, buf_left, "}");
+		buf_left -= buf_cons;
+		tmp += buf_cons;
+	}
+
+	buf1 = qdf_mem_malloc(ROAM_FAILURE_BUF_SIZE);
+	if (!buf1) {
+		qdf_mem_free(buf);
+		return;
+	}
+
+	if (trigger == ROAM_TRIGGER_REASON_LOW_RSSI ||
+	    trigger == ROAM_TRIGGER_REASON_PERIODIC)
+		qdf_snprint(buf1, ROAM_FAILURE_BUF_SIZE,
+			    "next_rssi_threshold: %d dBm",
+			    scan->next_rssi_threshold);
+
+	mlme_get_converted_timestamp(timestamp, time);
+	mlme_nofl_info("%s [ROAM_SCAN]: VDEV[%d] Scan_type: %s %s %s",
+		       time, vdev_id, mlme_get_roam_scan_type_str(scan->type),
+		       buf1, buf);
+	cm_stats_log_roam_scan_candidates(scan->ap, scan->num_ap);
+
+	qdf_mem_free(buf);
+	qdf_mem_free(buf1);
+}
+
+/**
+ * cm_roam_stats_print_roam_result()  - Print roam result related info
+ * @res:     Roam result strucure pointer
+ * @vdev_id: Vdev id
+ *
+ * Print roam result and failure reason if roaming failed.
+ *
+ * Return: None
+ */
+static void
+cm_roam_stats_print_roam_result(struct wmi_roam_result *res,
+				uint8_t vdev_id)
+{
+	char *buf;
+	char time[TIME_STRING_LEN];
+
+	buf = qdf_mem_malloc(ROAM_FAILURE_BUF_SIZE);
+	if (!buf)
+		return;
+
+	if (res->status == 1)
+		qdf_snprint(buf, ROAM_FAILURE_BUF_SIZE, "Reason: %s",
+			    mlme_get_roam_fail_reason_str(res->fail_reason));
+
+	mlme_get_converted_timestamp(res->timestamp, time);
+	mlme_nofl_info("%s [ROAM_RESULT]: VDEV[%d] %s %s",
+		       time, vdev_id, mlme_get_roam_status_str(res->status),
+		       buf);
+
+	qdf_mem_free(buf);
+}
+
+/**
+ * cm_roam_stats_print_11kv_info  - Print neighbor report/BTM related data
+ * @neigh_rpt: Pointer to the extracted TLV structure
+ * @vdev_id:   Vdev ID
+ *
+ * Print BTM/neighbor report info that is sent by firmware after
+ * connection/roaming to an AP.
+ *
+ * Return: none
+ */
+static void
+cm_roam_stats_print_11kv_info(struct wmi_neighbor_report_data *neigh_rpt,
+			      uint8_t vdev_id)
+{
+	char time[TIME_STRING_LEN], time1[TIME_STRING_LEN];
+	char *buf, *tmp;
+	uint8_t type = neigh_rpt->req_type, i;
+	uint16_t buf_left = ROAM_CHANNEL_BUF_SIZE, buf_cons;
+	uint8_t num_ch = neigh_rpt->num_freq;
+
+	if (!type)
+		return;
+
+	buf = qdf_mem_malloc(ROAM_CHANNEL_BUF_SIZE);
+	if (!buf)
+		return;
+
+	tmp = buf;
+	if (num_ch) {
+		buf_cons = qdf_snprint(tmp, buf_left, "{ ");
+		buf_left -= buf_cons;
+		tmp += buf_cons;
+
+		for (i = 0; i < num_ch; i++) {
+			buf_cons = qdf_snprint(tmp, buf_left, "%d ",
+					       neigh_rpt->freq[i]);
+			buf_left -= buf_cons;
+			tmp += buf_cons;
+		}
+
+		buf_cons = qdf_snprint(tmp, buf_left, "}");
+		buf_left -= buf_cons;
+		tmp += buf_cons;
+	}
+
+	mlme_get_converted_timestamp(neigh_rpt->req_time, time);
+	mlme_nofl_info("%s [%s] VDEV[%d]", time,
+		       (type == 1) ? "BTM_QUERY" : "NEIGH_RPT_REQ", vdev_id);
+
+	if (neigh_rpt->resp_time) {
+		mlme_get_converted_timestamp(neigh_rpt->resp_time, time1);
+		mlme_nofl_info("%s [%s] VDEV[%d] %s", time1,
+			       (type == 1) ? "BTM_REQ" : "NEIGH_RPT_RSP",
+			       vdev_id,
+			       (num_ch > 0) ? buf : "NO Ch update");
+	} else {
+		mlme_nofl_info("%s No response received from AP",
+			       (type == 1) ? "BTM" : "NEIGH_RPT");
+	}
+	qdf_mem_free(buf);
+}
+
+QDF_STATUS
+cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
+			    struct roam_stats_event *stats_info)
+{
+	uint8_t i, rem_tlv = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!stats_info)
+		return QDF_STATUS_E_FAILURE;
+	for (i = 0; i < stats_info->num_tlv; i++) {
+		if (stats_info->trigger[i].present) {
+			cm_roam_stats_print_trigger_info(
+							&stats_info->trigger[i],
+							stats_info->vdev_id);
+		       status = wlan_cm_update_roam_states(psoc,
+					stats_info->vdev_id,
+					stats_info->trigger[i].trigger_reason,
+					ROAM_TRIGGER_REASON);
+			if (QDF_IS_STATUS_ERROR(status))
+				goto err;
+		}
+
+		if (stats_info->scan[i].present &&
+		    stats_info->trigger[i].present)
+			cm_roam_stats_print_scan_info(&stats_info->scan[i],
+					  stats_info->vdev_id,
+					  stats_info->trigger[i].trigger_reason,
+					  stats_info->trigger[i].timestamp);
+
+		if (stats_info->result[i].present) {
+			cm_roam_stats_print_roam_result(&stats_info->result[i],
+							stats_info->vdev_id);
+			status = wlan_cm_update_roam_states(psoc,
+					      stats_info->vdev_id,
+					      stats_info->result[i].fail_reason,
+					      ROAM_FAIL_REASON);
+			if (QDF_IS_STATUS_ERROR(status))
+				goto err;
+		}
+
+		/*
+		 * Print BTM resp TLV info (wmi_roam_btm_response_info) only
+		 * when trigger reason is BTM or WTC_BTM. As for other roam
+		 * triggers this TLV contains zeros, so host should not print.
+		 */
+		if (stats_info->btm_rsp[i].present &&
+		    (stats_info->trigger[i].present &&
+		    (stats_info->trigger[i].trigger_reason ==
+		     ROAM_TRIGGER_REASON_WTC_BTM ||
+		     stats_info->trigger[i].trigger_reason ==
+		     ROAM_TRIGGER_REASON_BTM)))
+			cm_roam_stats_print_btm_rsp_info(
+							&stats_info->btm_rsp[i],
+							stats_info->vdev_id);
+
+		if (stats_info->roam_init_info[i].present)
+			cm_roam_stats_print_roam_initial_info(
+						 &stats_info->roam_init_info[i],
+						 stats_info->vdev_id);
+
+		if (stats_info->roam_msg_info &&
+		    i < stats_info->num_roam_msg_info &&
+		    stats_info->roam_msg_info[i].present) {
+			rem_tlv++;
+			cm_roam_stats_print_roam_msg_info(
+						  &stats_info->roam_msg_info[i],
+						  stats_info->vdev_id);
+			if (stats_info->data_11kv[i].present)
+				cm_roam_stats_print_11kv_info(
+						      &stats_info->data_11kv[i],
+						      stats_info->vdev_id);
+		}
+	}
+
+	if (!stats_info->num_tlv) {
+		if (stats_info->data_11kv[0].present)
+			cm_roam_stats_print_11kv_info(&stats_info->data_11kv[0],
+						      stats_info->vdev_id);
+
+		if (stats_info->trigger[0].present)
+			cm_roam_stats_print_trigger_info(
+							&stats_info->trigger[0],
+							stats_info->vdev_id);
+
+		if (stats_info->scan[0].present &&
+		    stats_info->trigger[0].present)
+			cm_roam_stats_print_scan_info(&stats_info->scan[0],
+					  stats_info->vdev_id,
+					  stats_info->trigger[0].trigger_reason,
+					  stats_info->trigger[0].timestamp);
+
+		if (stats_info->btm_rsp[0].present)
+			cm_roam_stats_print_btm_rsp_info(
+							&stats_info->btm_rsp[0],
+							stats_info->vdev_id);
+	}
+	if (stats_info->roam_msg_info && stats_info->num_roam_msg_info &&
+	    stats_info->num_roam_msg_info - rem_tlv) {
+		for (i = 0; i < (stats_info->num_roam_msg_info-rem_tlv); i++) {
+			if (stats_info->roam_msg_info[rem_tlv + i].present)
+				cm_roam_stats_print_roam_msg_info(
+					&stats_info->roam_msg_info[rem_tlv + i],
+					stats_info->vdev_id);
+		}
+	}
+
+err:
+	if (stats_info->roam_msg_info)
+		qdf_mem_free(stats_info->roam_msg_info);
+	qdf_mem_free(stats_info);
+	return status;
+}
 #endif

+ 55 - 0
components/wmi/inc/wmi_unified_roam_api.h

@@ -326,6 +326,61 @@ QDF_STATUS
 wmi_extract_roam_scan_chan_list(wmi_unified_t wmi_handle,
 				uint8_t *event, uint32_t data_len,
 				struct cm_roam_scan_ch_resp **data);
+
+/**
+ * wmi_unified_extract_roam_btm_response() - Extract BTM response
+ * @wmi:       wmi handle
+ * @evt_buf:   Pointer to the event buffer
+ * @dst:       Pointer to destination structure to fill data
+ * @idx:       TLV id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_unified_extract_roam_btm_response(wmi_unified_t wmi, void *evt_buf,
+				      struct roam_btm_response_data *dst,
+				      uint8_t idx);
+
+/**
+ * wmi_unified_extract_roam_initial_info() - Extract initial info
+ * @wmi:       wmi handle
+ * @evt_buf:   Pointer to the event buffer
+ * @dst:       Pointer to destination structure to fill data
+ * @idx:       TLV id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_unified_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf,
+				      struct roam_initial_data *dst,
+				      uint8_t idx);
+
+/**
+ * wmi_unified_extract_roam_msg_info() - Extract roam msg info
+ * @wmi:       wmi handle
+ * @evt_buf:   Pointer to the event buffer
+ * @dst:       Pointer to destination structure to fill data
+ * @idx:       TLV id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_unified_extract_roam_msg_info(wmi_unified_t wmi, void *evt_buf,
+				  struct roam_msg_info *dst, uint8_t idx);
+
+/**
+ * wmi_extract_roam_stats_event  - Extract roam stats event
+ * @wmi_handle: WMI handle
+ * @event: Event data received from firmware
+ * @data_len: Event data length received from firmware
+ * @stats_info: Extract the event and fill in stats_info
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_extract_roam_stats_event(wmi_unified_t wmi_handle,
+			     uint8_t *event, uint32_t data_len,
+			     struct roam_stats_event **stats_info);
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 

+ 48 - 0
components/wmi/src/wmi_unified_roam_api.c

@@ -413,5 +413,53 @@ wmi_extract_roam_scan_chan_list(wmi_unified_t wmi_handle,
 				wmi_handle, event, data_len, data);
 	return QDF_STATUS_E_FAILURE;
 }
+
+QDF_STATUS
+wmi_unified_extract_roam_btm_response(wmi_unified_t wmi, void *evt_buf,
+				      struct roam_btm_response_data *dst,
+				      uint8_t idx)
+{
+	if (wmi->ops->extract_roam_btm_response_stats)
+		return wmi->ops->extract_roam_btm_response_stats(wmi, evt_buf,
+								 dst, idx);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf,
+				      struct roam_initial_data *dst,
+				      uint8_t idx)
+{
+	if (wmi->ops->extract_roam_initial_info)
+		return wmi->ops->extract_roam_initial_info(wmi, evt_buf,
+							   dst, idx);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_unified_extract_roam_msg_info(wmi_unified_t wmi, void *evt_buf,
+				  struct roam_msg_info *dst, uint8_t idx)
+{
+	if (wmi->ops->extract_roam_msg_info)
+		return wmi->ops->extract_roam_msg_info(wmi, evt_buf, dst, idx);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+wmi_extract_roam_stats_event(wmi_unified_t wmi_handle,
+			     uint8_t *event, uint32_t data_len,
+			     struct roam_stats_event **stats_info)
+{
+	if (wmi_handle->ops->extract_roam_stats_event)
+		return wmi_handle->ops->extract_roam_stats_event(wmi_handle,
+								 event,
+								 data_len,
+								 stats_info);
+
+	return QDF_STATUS_E_FAILURE;
+}
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif

+ 284 - 0
components/wmi/src/wmi_unified_roam_tlv.c

@@ -2658,6 +2658,289 @@ extract_roam_scan_chan_list_tlv(wmi_unified_t wmi_handle,
 	*list = data;
 	return QDF_STATUS_SUCCESS;
 }
+
+/**
+ * extract_roam_stats_event_tlv() - Extract the roam stats event
+ * from the wmi_roam_stats_event_id
+ * @wmi_handle: wmi handle
+ * @evt_buf:    Pointer to the event buffer
+ * @len:        Data length
+ * @data:       Double pointer to roam stats data
+ */
+static QDF_STATUS
+extract_roam_stats_event_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
+			     uint32_t len,
+			     struct roam_stats_event **data)
+{
+	WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
+	wmi_roam_stats_event_fixed_param *fixed_param;
+	struct roam_stats_event *stats_info;
+	struct roam_msg_info *roam_msg_info = NULL;
+	uint8_t vdev_id, i;
+	uint8_t num_tlv = 0, num_chan = 0, num_ap = 0, num_rpt = 0;
+	uint32_t rem_len;
+	QDF_STATUS status;
+
+	param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
+	if (!param_buf) {
+		wmi_err_rl("NULL event received from target");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fixed_param = param_buf->fixed_param;
+	if (!fixed_param) {
+		wmi_err_rl(" NULL fixed param");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	vdev_id = fixed_param->vdev_id;
+
+	if (vdev_id >= WLAN_MAX_VDEVS) {
+		wmi_err_rl("Invalid vdev_id %d", vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	num_tlv = fixed_param->roam_scan_trigger_count;
+	if (num_tlv > MAX_ROAM_SCAN_STATS_TLV) {
+		wmi_err_rl("Limiting roam triggers to 5");
+		num_tlv = MAX_ROAM_SCAN_STATS_TLV;
+	}
+
+	rem_len = WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param);
+	if (rem_len < num_tlv * sizeof(wmi_roam_trigger_reason)) {
+		wmi_err_rl("Invalid roam trigger data");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= num_tlv * sizeof(wmi_roam_trigger_reason);
+	if (rem_len < num_tlv * sizeof(wmi_roam_scan_info)) {
+		wmi_err_rl("Invalid roam scan data");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= num_tlv * sizeof(wmi_roam_scan_info);
+	if (rem_len < num_tlv * sizeof(wmi_roam_result)) {
+		wmi_err_rl("Invalid roam result data");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= num_tlv * sizeof(wmi_roam_result);
+	if (rem_len < (num_tlv * sizeof(wmi_roam_neighbor_report_info))) {
+		wmi_err_rl("Invalid roam neighbor report data");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= num_tlv * sizeof(wmi_roam_neighbor_report_info);
+	if (rem_len < (param_buf->num_roam_scan_chan_info *
+		       sizeof(wmi_roam_scan_channel_info))) {
+		wmi_err_rl("Invalid roam chan data num_tlv:%d",
+			   param_buf->num_roam_scan_chan_info);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= param_buf->num_roam_scan_chan_info *
+		   sizeof(wmi_roam_scan_channel_info);
+
+	if (rem_len < (param_buf->num_roam_ap_info *
+		       sizeof(wmi_roam_ap_info))) {
+		wmi_err_rl("Invalid roam ap data num_tlv:%d",
+			   param_buf->num_roam_ap_info);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= param_buf->num_roam_ap_info * sizeof(wmi_roam_ap_info);
+	if (rem_len < (param_buf->num_roam_neighbor_report_chan_info *
+		       sizeof(wmi_roam_neighbor_report_channel_info))) {
+		wmi_err_rl("Invalid roam neigb rpt chan data num_tlv:%d",
+			   param_buf->num_roam_neighbor_report_chan_info);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= param_buf->num_roam_neighbor_report_chan_info *
+			sizeof(wmi_roam_neighbor_report_channel_info);
+	if (rem_len < param_buf->num_roam_btm_response_info *
+	    sizeof(wmi_roam_btm_response_info)) {
+		wmi_err_rl("Invalid btm rsp data");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= param_buf->num_roam_btm_response_info *
+			sizeof(wmi_roam_btm_response_info);
+	if (rem_len < param_buf->num_roam_initial_info *
+	    sizeof(wmi_roam_initial_info)) {
+		wmi_err_rl("Invalid Initial roam info");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rem_len -= param_buf->num_roam_initial_info *
+			sizeof(wmi_roam_initial_info);
+	if (rem_len < param_buf->num_roam_msg_info *
+	    sizeof(wmi_roam_msg_info)) {
+		wmi_err_rl("Invalid roam msg info");
+		return QDF_STATUS_E_INVAL;
+	}
+	stats_info = qdf_mem_malloc(sizeof(struct roam_stats_event));
+	if (!stats_info) {
+		status = QDF_STATUS_E_NOMEM;
+		goto err;
+	}
+	*data = stats_info;
+	qdf_mem_set(stats_info, sizeof(struct roam_stats_event), 0);
+	stats_info->vdev_id = vdev_id;
+	stats_info->num_roam_msg_info = param_buf->num_roam_msg_info;
+	stats_info->num_tlv = num_tlv;
+
+	for (i = 0; i < num_tlv; i++) {
+		/*
+		 * Roam Trigger id and that specific roam trigger related
+		 * details.
+		 */
+		status = wmi_unified_extract_roam_trigger_stats(wmi_handle,
+						    evt_buf,
+						    &stats_info->trigger[i], i);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_debug_rl("Extract roam trigger stats failed vdev %d at %d iteration",
+				     vdev_id, i);
+			status =  QDF_STATUS_E_INVAL;
+			goto err;
+		}
+
+		/* Roam scan related details - Scan channel, scan type .. */
+		status = wmi_unified_extract_roam_scan_stats(wmi_handle,
+							evt_buf,
+							&stats_info->scan[i], i,
+							num_chan, num_ap);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_debug_rl("Roam scan stats extract failed vdev %d at %d iteration",
+				     vdev_id, i);
+			status = QDF_STATUS_E_INVAL;
+			goto err;
+		}
+		num_chan += stats_info->scan[i].num_chan;
+		num_ap += stats_info->scan[i].num_ap;
+
+		/* Roam result - Success/Failure status, failure reason */
+		status = wmi_unified_extract_roam_result_stats(wmi_handle,
+						     evt_buf,
+						     &stats_info->result[i], i);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_debug_rl("Roam result stats extract failed vdev %d at %d iteration",
+				     vdev_id, i);
+			status = QDF_STATUS_E_INVAL;
+			goto err;
+		}
+
+		/* BTM resp info */
+		status = wmi_unified_extract_roam_btm_response(wmi_handle,
+							evt_buf,
+							&stats_info->btm_rsp[i],
+							i);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_debug_rl("Roam btm rsp stats extract fail vdev %d at %d iteration",
+				     vdev_id, i);
+			status = QDF_STATUS_E_INVAL;
+			goto err;
+		}
+
+		/* Initial Roam info */
+		status = wmi_unified_extract_roam_initial_info(wmi_handle,
+					     evt_buf,
+					     &stats_info->roam_init_info[i], i);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_debug_rl("Initial roam stats extract fail vdev %d at %d iteration",
+				     vdev_id, i);
+			status = QDF_STATUS_E_INVAL;
+			goto err;
+		}
+	}
+	if (!num_tlv) {
+		status = wmi_unified_extract_roam_11kv_stats(wmi_handle,
+					       evt_buf,
+					       &stats_info->data_11kv[0], 0, 0);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_err("Roam 11kv stats extract failed vdev %d",
+				vdev_id);
+			status = QDF_STATUS_E_INVAL;
+			goto err;
+		}
+
+		status = wmi_unified_extract_roam_trigger_stats(wmi_handle,
+						    evt_buf,
+						    &stats_info->trigger[0], 0);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_debug_rl("Extract roamtrigger stats failed vdev %d",
+				     vdev_id);
+			status = QDF_STATUS_E_INVAL;
+			goto err;
+		}
+
+		status = wmi_unified_extract_roam_scan_stats(wmi_handle,
+							   evt_buf,
+							   &stats_info->scan[0],
+							   0, 0, 0);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_debug_rl("Roam scan stats extract failed vdev %d",
+				     vdev_id);
+			status = QDF_STATUS_E_INVAL;
+			goto err;
+		}
+
+		status = wmi_unified_extract_roam_btm_response(wmi_handle,
+							evt_buf,
+							&stats_info->btm_rsp[0],
+							0);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wmi_debug_rl("Roam btm rsp stats extract fail vdev %d",
+				     vdev_id);
+			status = QDF_STATUS_E_INVAL;
+			goto err;
+		}
+	}
+
+	if (param_buf->roam_msg_info && param_buf->num_roam_msg_info) {
+		roam_msg_info = qdf_mem_malloc(param_buf->num_roam_msg_info *
+					       sizeof(*roam_msg_info));
+		if (!roam_msg_info) {
+			status = QDF_STATUS_E_NOMEM;
+			goto err;
+		}
+		stats_info->roam_msg_info = roam_msg_info;
+		for (i = 0; i < param_buf->num_roam_msg_info; i++) {
+			status = wmi_unified_extract_roam_msg_info(wmi_handle,
+							  evt_buf,
+							  &roam_msg_info[i], i);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				wmi_err("roam msg stats extract fail vdev %d",
+					vdev_id);
+				status = QDF_STATUS_E_INVAL;
+				goto err;
+			}
+			if (roam_msg_info[i].present && i < num_tlv) {
+			     /* BTM req/resp or Neighbor report/response info */
+				status = wmi_unified_extract_roam_11kv_stats(
+						      wmi_handle,
+						      evt_buf,
+						      &stats_info->data_11kv[i],
+						      i, num_rpt);
+				if (QDF_IS_STATUS_ERROR(status)) {
+					wmi_debug_rl("Roam 11kv stats extract fail vdev %d iter %d",
+						     vdev_id, i);
+					status = QDF_STATUS_E_INVAL;
+					goto err;
+				}
+				num_rpt += stats_info->data_11kv[i].num_freq;
+			}
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+err:
+	if (stats_info) {
+		if (roam_msg_info)
+			qdf_mem_free(roam_msg_info);
+		qdf_mem_free(stats_info);
+	}
+	return status;
+}
 #endif
 
 void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
@@ -2675,6 +2958,7 @@ void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
 	ops->extract_btm_bl_event = extract_btm_blacklist_event;
 	ops->extract_vdev_disconnect_event = extract_vdev_disconnect_event_tlv;
 	ops->extract_roam_scan_chan_list = extract_roam_scan_chan_list_tlv;
+	ops->extract_roam_stats_event = extract_roam_stats_event_tlv;
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 	ops->send_set_ric_req_cmd = send_set_ric_req_cmd_tlv;
 	ops->send_process_roam_synch_complete_cmd =

+ 6 - 5
core/wma/src/wma_main.c

@@ -3363,17 +3363,18 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
 					wmi_roam_scan_chan_list_id,
 					wma_roam_scan_chan_list_event_handler,
 					WMA_RX_SERIALIZER_CTX);
-#endif /* ROAM_TARGET_IF_CONVERGENCE */
-	wmi_unified_register_event_handler(wma_handle->wmi_handle,
-					   wmi_roam_auth_offload_event_id,
-					   wma_roam_auth_offload_event_handler,
-					   WMA_RX_SERIALIZER_CTX);
 
 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
 					   wmi_roam_stats_event_id,
 					   wma_roam_stats_event_handler,
 					   WMA_RX_SERIALIZER_CTX);
 
+#endif /* ROAM_TARGET_IF_CONVERGENCE */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_roam_auth_offload_event_id,
+					   wma_roam_auth_offload_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
 	wma_register_pmkid_req_event_handler(wma_handle);
 
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */

+ 1 - 1
core/wma/src/wma_scan_roam.c

@@ -1525,7 +1525,6 @@ int wma_roam_scan_chan_list_event_handler(WMA_HANDLE handle,
 
 	return 0;
 }
-#endif
 
 /**
  * wma_get_trigger_detail_str  - Return roam trigger string from the
@@ -2279,6 +2278,7 @@ err:
 	return -EINVAL;
 }
 #endif
+#endif
 
 /**
  * wma_set_ric_req() - set ric request element