Parcourir la source

qcacld-3.0: wma to target_if migration of wmi_roam_event

Currently, wmi_roam_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. As the legacy CSR/LIM is not
yet converged, have a wrapper from connection mgr to wma to call
these legacy APIs.

Change-Id: I0e22bbccfe21200b90771a01f9ee7454f4ecb119
CRs-Fixed: 2990355
Srinivas Dasari il y a 3 ans
Parent
commit
78cb3008e6

+ 0 - 3
components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -1528,9 +1528,6 @@ QDF_STATUS psoc_mlme_ext_hdl_create(struct psoc_mlme_obj *psoc_mlme)
 
 	target_if_wfatestcmd_register_tx_ops(
 			&psoc_mlme->ext_psoc_ptr->wfa_testcmd.tx_ops);
-#ifdef ROAM_TARGET_IF_CONVERGENCE
-	target_if_roam_offload_register_events(psoc_mlme->psoc);
-#endif /* ROAM_TARGET_IF_CONVERGENCE */
 	target_if_cm_roam_register_rx_ops(
 			&psoc_mlme->ext_psoc_ptr->rso_rx_ops);
 

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

@@ -56,6 +56,16 @@ target_if_cm_roam_sync_frame_event(ol_scn_t scn,
 				   uint8_t *event,
 				   uint32_t len);
 
+/**
+ * target_if_cm_roam_event() - Target IF handler for roam events
+ * @scn: target handle
+ * @event: event buffer
+ * @len: event buffer length
+ *
+ * Return: int for success or error code
+ */
+int target_if_cm_roam_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
@@ -90,6 +100,12 @@ target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
+
+static inline int
+target_if_cm_roam_event(ol_scn_t scn, uint8_t *event, uint32_t len)
+{
+	return 0;
+}
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 #endif

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

@@ -28,6 +28,7 @@
 #include "wlan_psoc_mlme_api.h"
 #include "wlan_mlme_main.h"
 #include <../../core/src/wlan_cm_roam_i.h>
+#include "wlan_cm_roam_api.h"
 
 static inline struct wlan_cm_roam_rx_ops *
 target_if_cm_get_roam_rx_ops(struct wlan_objmgr_psoc *psoc)
@@ -55,6 +56,7 @@ target_if_cm_roam_register_rx_ops(struct wlan_cm_roam_rx_ops *rx_ops)
 #ifdef ROAM_TARGET_IF_CONVERGENCE
 	rx_ops->roam_sync_event = cm_roam_sync_event_handler;
 	rx_ops->roam_sync_frame_event = cm_roam_sync_frame_event_handler;
+	rx_ops->roam_event_rx = cm_roam_event_handler;
 #endif
 }
 
@@ -165,6 +167,48 @@ err:
 	return status;
 }
 
+int target_if_cm_roam_event(ol_scn_t scn, uint8_t *event, uint32_t len)
+{
+	QDF_STATUS qdf_status;
+	int status = 0;
+	struct wmi_unified *wmi_handle;
+	struct roam_offload_roam_event roam_event = {0};
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_cm_roam_rx_ops *roam_rx_ops;
+
+	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_event(wmi_handle, event, len,
+					    &roam_event);
+	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_event_rx) {
+		target_if_err("No valid roam rx ops");
+		status = -EINVAL;
+		goto err;
+	}
+	qdf_status = roam_rx_ops->roam_event_rx(roam_event);
+	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)
 {
@@ -195,6 +239,13 @@ target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
 		target_if_err("wmi event registration failed, ret: %d", ret);
 		return QDF_STATUS_E_FAILURE;
 	}
+	ret = wmi_unified_register_event_handler(handle, wmi_roam_event_id,
+						 target_if_cm_roam_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;
 }

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

@@ -903,6 +903,30 @@ void wlan_cm_get_psk_pmk(struct wlan_objmgr_pdev *pdev,
 QDF_STATUS
 cm_akm_roam_allowed(struct wlan_objmgr_psoc *psoc,
 		    struct wlan_objmgr_vdev *vdev);
+
+#ifdef ROAM_TARGET_IF_CONVERGENCE
+
+/**
+ * cm_invalid_roam_reason_handler() - Handler for invalid roam reason
+ * @vdev_id: vdev id
+ * @notif: roam notification of type enum cm_roam_notif
+ *
+ * Return: QDF_STATUS
+ */
+void cm_invalid_roam_reason_handler(uint32_t vdev_id, enum cm_roam_notif notif);
+
+/**
+ * cm_handle_roam_reason_ho_failed() - Handler for roam due to ho failure
+ * @vdev_id: vdev id
+ * @bssid: carries the BSSID mac address
+ * @hw_mode_trans_ind: hw_mode transition indication
+ *
+ * Return: None
+ */
+void
+cm_handle_roam_reason_ho_failed(uint8_t vdev_id, struct qdf_mac_addr bssid,
+				struct cm_hw_mode_trans_ind *hw_mode_trans_ind);
+#endif
 #else
 static inline
 void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc,
@@ -1017,5 +1041,92 @@ cm_akm_roam_allowed(struct wlan_objmgr_psoc *psoc,
 {
 	return false;
 }
+
+#ifdef ROAM_TARGET_IF_CONVERGENCE
+static inline void
+cm_handle_roam_reason_ho_failed(uint8_t vdev_id, struct qdf_mac_addr bssid,
+				struct cm_hw_mode_trans_ind *hw_mode_trans_ind)
+{}
+#endif
 #endif  /* FEATURE_ROAM_OFFLOAD */
+
+#ifdef ROAM_TARGET_IF_CONVERGENCE
+/**
+ * cm_rso_cmd_status_event_handler() - Handler for rso cmd status
+ * @vdev_id: vdev id
+ * @notif: roam notification of type enum cm_roam_notif
+ *
+ * Return: QDF_STATUS
+ */
+int cm_rso_cmd_status_event_handler(uint8_t vdev_id, enum cm_roam_notif notif);
+
+/**
+ * cm_handle_roam_reason_invoke_roam_fail() - Handler for roam invoke fail event
+ * @vdev_id: vdev id
+ * @notif_params: contains roam invoke fail reason from wmi_roam_invoke_error_t
+ * @trans_ind: hw_mode transition indication
+ *
+ * Return: None
+ */
+void
+cm_handle_roam_reason_invoke_roam_fail(uint8_t vdev_id,	uint32_t notif_params,
+				       struct cm_hw_mode_trans_ind *trans_ind);
+
+/**
+ * cm_handle_roam_reason_deauth() - Handler for roam due to deauth from AP
+ * @vdev_id: vdev id
+ * @notif_params: contains roam invoke fail reason from wmi_roam_invoke_error_t
+ * @deauth_disassoc_frame: Disassoc or deauth frame
+ * @frame_len: Contains the length of @deauth_disassoc_frame
+ *
+ * Return: None
+ */
+void cm_handle_roam_reason_deauth(uint8_t vdev_id, uint32_t notif_params,
+				  uint8_t *deauth_disassoc_frame,
+				  uint32_t frame_len);
+
+/**
+ * cm_handle_roam_reason_btm() - Handler for roam due to btm from AP
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void cm_handle_roam_reason_btm(uint8_t vdev_id);
+
+/**
+ * cm_handle_roam_reason_bmiss() - Handler for roam due to bmiss
+ * @vdev_id: vdev id
+ * @rssi: RSSI value
+ *
+ * Return: None
+ */
+void cm_handle_roam_reason_bmiss(uint8_t vdev_id, uint32_t rssi);
+
+/**
+ * cm_handle_roam_reason_better_ap() - Handler for roam due to better AP
+ * @vdev_id: vdev id
+ * @rssi: RSSI value
+ *
+ * Return: None
+ */
+void cm_handle_roam_reason_better_ap(uint8_t vdev_id, uint32_t rssi);
+
+/**
+ * cm_handle_roam_reason_suitable_ap() - Handler for roam due to suitable AP
+ * @vdev_id: vdev id
+ * @rssi: RSSI value
+ *
+ * Return: None
+ */
+void cm_handle_roam_reason_suitable_ap(uint8_t vdev_id, uint32_t rssi);
+
+/**
+ * cm_roam_event_handler() - Carries extracted roam info
+ * @roam_event: data carried by roam event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+cm_roam_event_handler(struct roam_offload_roam_event roam_event);
+#endif
 #endif  /* WLAN_CM_ROAM_API_H__ */

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

@@ -1707,6 +1707,101 @@ struct roam_invoke_req {
 	bool forced_roaming;
 };
 
+/**
+ * enum cm_roam_notif: roaming notification
+ * @CM_ROAM_NOTIF_INVALID: invalid notification. Do not interpret notif field
+ * @CM_ROAM_NOTIF_ROAM_START: indicate that roaming is started. sent only in
+			      non WOW state
+ * @CM_ROAM_NOTIF_ROAM_ABORT: indicate that roaming is aborted. sent only in
+			      non WOW state
+ * @CM_ROAM_NOTIF_ROAM_REASSOC: indicate that reassociation is done. sent only
+				in non WOW state
+ * @CM_ROAM_NOTIF_SCAN_MODE_SUCCESS: indicate that roaming scan mode is
+				     successful
+ * @CM_ROAM_NOTIF_SCAN_MODE_FAIL: indicate that roaming scan mode is failed due
+				  to internal roaming state
+ * @CM_ROAM_NOTIF_DISCONNECT: indicate that roaming not allowed due BTM req
+ * @CM_ROAM_NOTIF_SUBNET_CHANGED: indicate that subnet has changed
+ * @CM_ROAM_NOTIF_SCAN_START: indicate roam scan start, notif_params to be sent
+			      as WMI_ROAM_TRIGGER_REASON_ID
+ * @CM_ROAM_NOTIF_DEAUTH_RECV: indicate deauth received, notif_params to be sent
+			       as reason code, notif_params1 to be sent as
+			       frame length
+ * @CM_ROAM_NOTIF_DISASSOC_RECV: indicate disassoc received, notif_params to be
+				 sent as reason code, notif_params1 to be sent
+				 as frame length
+ */
+enum cm_roam_notif {
+	CM_ROAM_NOTIF_INVALID = 0,
+	CM_ROAM_NOTIF_ROAM_START,
+	CM_ROAM_NOTIF_ROAM_ABORT,
+	CM_ROAM_NOTIF_ROAM_REASSOC,
+	CM_ROAM_NOTIF_SCAN_MODE_SUCCESS,
+	CM_ROAM_NOTIF_SCAN_MODE_FAIL,
+	CM_ROAM_NOTIF_DISCONNECT,
+	CM_ROAM_NOTIF_SUBNET_CHANGED,
+	CM_ROAM_NOTIF_SCAN_START,
+	CM_ROAM_NOTIF_DEAUTH_RECV,
+	CM_ROAM_NOTIF_DISASSOC_RECV,
+};
+
+/**
+ * enum roam_reason: Roam reason
+ * @ROAM_REASON_INVALID: invalid reason. Do not interpret reason field
+ * @ROAM_REASON_BETTER_AP: found a better AP
+ * @ROAM_REASON_BMISS: beacon miss detected
+ * @ROAM_REASON_LOW_RSSI: connected AP's low rssi condition detected
+ * @ROAM_REASON_SUITABLE_AP: found another AP that matches SSID and Security
+ *  profile in WMI_ROAM_AP_PROFILE, found during scan triggered upon FINAL_BMISS
+ * @ROAM_REASON_HO_FAILED: LFR3.0 roaming failed, indicate the disconnection
+ *			   to host
+ * @ROAM_REASON_INVOKE_ROAM_FAIL: Result code of WMI_ROAM_INVOKE_CMDID. Any
+ *  roaming failure before reassociation will be indicated to host with this
+ *  reason. Any roaming failure after reassociation will be indicated to host
+ *  with WMI_ROAM_REASON_HO_FAILED no matter WMI_ROAM_INVOKE_CMDID is
+ *  called or not.
+ * @ROAM_REASON_RSO_STATUS
+ * @ROAM_REASON_BTM: Roaming because of BTM request received
+ * @ROAM_REASON_DEAUTH: deauth/disassoc received
+ */
+enum roam_reason {
+	ROAM_REASON_INVALID,
+	ROAM_REASON_BETTER_AP,
+	ROAM_REASON_BMISS,
+	ROAM_REASON_LOW_RSSI,
+	ROAM_REASON_SUITABLE_AP,
+	ROAM_REASON_HO_FAILED,
+	ROAM_REASON_INVOKE_ROAM_FAIL,
+	ROAM_REASON_RSO_STATUS,
+	ROAM_REASON_BTM,
+	ROAM_REASON_DEAUTH,
+};
+
+/**
+ * struct roam_offload_roam_event: Data carried by roam event
+ * @vdev_id: vdev id
+ * @reason: reason for roam event of type @enum roam_reason
+ * @rssi: associated AP's rssi calculated by FW when reason code
+ *	  is WMI_ROAM_REASON_LOW_RSSI
+ * @notif: roam notification
+ * @notif_params: Contains roam invoke fail reason from wmi_roam_invoke_error_t
+ *		  if reason is WMI_ROAM_REASON_INVOKE_ROAM_FAIL.
+ * @notif_params1: notif_params1 is exact frame length of deauth or disassoc if
+ *		   reason is WMI_ROAM_REASON_DEAUTH.
+ * @hw_mode_trans_ind: HW mode transition indication
+ * @deauth_disassoc_frame: Deauth/disassoc frame received from AP
+ */
+struct roam_offload_roam_event {
+	uint8_t vdev_id;
+	enum roam_reason reason;
+	uint32_t rssi;
+	enum cm_roam_notif notif;
+	uint32_t notif_params;
+	uint32_t notif_params1;
+	struct cm_hw_mode_trans_ind *hw_mode_trans_ind;
+	uint8_t *deauth_disassoc_frame;
+};
+
 /**
  * wlan_cm_roam_tx_ops  - structure of tx function pointers for
  * roaming related commands
@@ -1752,6 +1847,7 @@ struct wlan_cm_roam_tx_ops {
  * roaming related commands
  * @roam_sync_event: RX ops function pointer for roam sync event
  * @roam_sync_frame_event: Rx ops function pointer for roam sync frame event
+ * @roam_event_rx: Rx ops function pointer for roam info event
  */
 struct wlan_cm_roam_rx_ops {
 	QDF_STATUS (*roam_sync_event)(struct wlan_objmgr_psoc *psoc,
@@ -1760,6 +1856,7 @@ struct wlan_cm_roam_rx_ops {
 				      uint8_t vdev_id);
 	QDF_STATUS (*roam_sync_frame_event)(struct wlan_objmgr_psoc *psoc,
 					    struct roam_synch_frame_ind *frm);
+	QDF_STATUS (*roam_event_rx)(struct roam_offload_roam_event roam_event);
 };
 
 /**

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

@@ -29,6 +29,7 @@
 #include "wlan_crypto_global_api.h"
 #include <wlan_cm_api.h>
 #include "connection_mgr/core/src/wlan_cm_roam.h"
+#include "wlan_cm_roam_api.h"
 
 /* Support for "Fast roaming" (i.e., ESE, LFR, or 802.11r.) */
 #define BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15
@@ -1965,3 +1966,87 @@ uint32_t wlan_cm_get_roam_states(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 	return roam_states;
 }
 #endif
+
+#ifdef ROAM_TARGET_IF_CONVERGENCE
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static void
+cm_handle_roam_offload_events(struct roam_offload_roam_event roam_event)
+{
+	switch (roam_event.reason) {
+	case ROAM_REASON_HO_FAILED: {
+		struct qdf_mac_addr bssid;
+
+		bssid.bytes[0] = roam_event.notif_params >> 0 & 0xFF;
+		bssid.bytes[1] = roam_event.notif_params >> 8 & 0xFF;
+		bssid.bytes[2] = roam_event.notif_params >> 16 & 0xFF;
+		bssid.bytes[3] = roam_event.notif_params >> 24 & 0xFF;
+		bssid.bytes[4] = roam_event.notif_params1 >> 0 & 0xFF;
+		bssid.bytes[5] = roam_event.notif_params1 >> 8 & 0xFF;
+		cm_handle_roam_reason_ho_failed(roam_event.vdev_id, bssid,
+						roam_event.hw_mode_trans_ind);
+	}
+	break;
+	case ROAM_REASON_INVALID:
+		cm_invalid_roam_reason_handler(roam_event.vdev_id,
+					       roam_event.notif);
+		break;
+	default:
+		break;
+	}
+}
+#else
+static void
+cm_handle_roam_offload_events(struct roam_offload_roam_event roam_event)
+{
+	mlme_debug("Unhandled roam event with reason 0x%x for vdev_id %u",
+		   roam_event.reason, roam_event.vdev_id);
+}
+#endif
+
+QDF_STATUS
+cm_roam_event_handler(struct roam_offload_roam_event roam_event)
+{
+	switch (roam_event.reason) {
+	case ROAM_REASON_BTM:
+		cm_handle_roam_reason_btm(roam_event.vdev_id);
+		break;
+	case ROAM_REASON_BMISS:
+		cm_handle_roam_reason_bmiss(roam_event.vdev_id,
+					    roam_event.rssi);
+		break;
+	case ROAM_REASON_BETTER_AP:
+		cm_handle_roam_reason_better_ap(roam_event.vdev_id,
+						roam_event.rssi);
+		break;
+	case ROAM_REASON_SUITABLE_AP:
+		cm_handle_roam_reason_suitable_ap(roam_event.vdev_id,
+						  roam_event.rssi);
+		break;
+	case ROAM_REASON_HO_FAILED:
+	case ROAM_REASON_INVALID:
+		cm_handle_roam_offload_events(roam_event);
+		break;
+	case ROAM_REASON_RSO_STATUS:
+		cm_rso_cmd_status_event_handler(roam_event.vdev_id,
+						roam_event.notif);
+		break;
+	case ROAM_REASON_INVOKE_ROAM_FAIL:
+		cm_handle_roam_reason_invoke_roam_fail(roam_event.vdev_id,
+						roam_event.notif_params,
+						roam_event.hw_mode_trans_ind);
+		break;
+	case ROAM_REASON_DEAUTH:
+		cm_handle_roam_reason_deauth(roam_event.vdev_id,
+					     roam_event.notif_params,
+					     roam_event.deauth_disassoc_frame,
+					     roam_event.notif_params1);
+		break;
+	default:
+		mlme_debug("Unhandled roam event with reason 0x%x for vdev_id %u",
+			   roam_event.reason, roam_event.vdev_id);
+		break;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif

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

@@ -264,6 +264,20 @@ QDF_STATUS
 wmi_extract_roam_sync_frame_event(wmi_unified_t wmi_handle, void *event,
 				  uint32_t len,
 				  struct roam_synch_frame_ind *frame_ptr);
+
+/**
+ * wmi_extract_roam_event  - Extract roam event
+ * @wmi_handle: WMI handle
+ * @event: Event data received from firmware
+ * @data_len: Event data length received from firmware
+ * @roam_event: Extract the event and fill in roam_event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_extract_roam_event(wmi_unified_t wmi_handle, uint8_t *event,
+		       uint32_t data_len,
+		       struct roam_offload_roam_event *roam_event);
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 

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

@@ -365,5 +365,18 @@ wmi_extract_roam_sync_frame_event(wmi_unified_t wmi_handle, void *event,
 
 	return QDF_STATUS_E_FAILURE;
 }
+
+QDF_STATUS
+wmi_extract_roam_event(wmi_unified_t wmi_handle, uint8_t *event,
+		       uint32_t data_len,
+		       struct roam_offload_roam_event *roam_event)
+{
+	if (wmi_handle->ops->extract_roam_event)
+		return wmi_handle->ops->extract_roam_event(wmi_handle, event,
+							   data_len,
+							   roam_event);
+
+	return QDF_STATUS_E_FAILURE;
+}
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif

+ 246 - 1
components/wmi/src/wmi_unified_roam_tlv.c

@@ -20,7 +20,13 @@
 
 #include <wmi_unified_priv.h>
 #include <wmi_unified_roam_api.h>
+#include <wmi_unified_roam_param.h>
 #include "wmi.h"
+#include "wlan_roam_debug.h"
+#include "ol_defines.h"
+
+#define WMI_MAC_TO_PDEV_MAP(x) ((x) + (1))
+#define WMI_PDEV_TO_MAC_MAP(x) ((x) - (1))
 
 #ifdef FEATURE_LFR_SUBNET_DETECTION
 /**
@@ -1829,7 +1835,238 @@ extract_roam_sync_frame_event_tlv(wmi_unified_t wmi_handle, void *event,
 
 	return QDF_STATUS_SUCCESS;
 }
-#endif /* ROAM_TARGET_IF_CONVERGENCE */
+
+static char *wmi_get_roam_event_reason_string(uint32_t reason)
+{
+	switch (reason) {
+	case WMI_ROAM_REASON_INVALID:
+		return "Default";
+	case WMI_ROAM_REASON_BETTER_AP:
+		return "Better AP";
+	case WMI_ROAM_REASON_BMISS:
+		return "BMISS";
+	case WMI_ROAM_REASON_LOW_RSSI:
+		return "Low Rssi";
+	case WMI_ROAM_REASON_SUITABLE_AP:
+		return "Suitable AP";
+	case WMI_ROAM_REASON_HO_FAILED:
+		return "Hand-off Failed";
+	case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
+		return "Roam Invoke failed";
+	case WMI_ROAM_REASON_RSO_STATUS:
+		return "RSO status";
+	case WMI_ROAM_REASON_BTM:
+		return "BTM";
+	case WMI_ROAM_REASON_DEAUTH:
+		return "Deauth";
+	default:
+		return "Invalid";
+	}
+
+	return "Invalid";
+}
+
+static void
+wmi_extract_pdev_hw_mode_trans_ind(
+	wmi_pdev_hw_mode_transition_event_fixed_param *fixed_param,
+	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry,
+	struct cm_hw_mode_trans_ind *hw_mode_trans_ind)
+{
+	uint32_t i;
+
+	if (fixed_param->num_vdev_mac_entries > MAX_VDEV_SUPPORTED) {
+		wmi_err("Number of Vdev mac entries %d exceeded max vdev supported %d",
+			fixed_param->num_vdev_mac_entries,
+			MAX_VDEV_SUPPORTED);
+		return;
+	}
+	hw_mode_trans_ind->old_hw_mode_index = fixed_param->old_hw_mode_index;
+	hw_mode_trans_ind->new_hw_mode_index = fixed_param->new_hw_mode_index;
+	hw_mode_trans_ind->num_vdev_mac_entries =
+					fixed_param->num_vdev_mac_entries;
+	wmi_debug("old_hw_mode_index:%d new_hw_mode_index:%d entries=%d",
+		  fixed_param->old_hw_mode_index,
+		  fixed_param->new_hw_mode_index,
+		  fixed_param->num_vdev_mac_entries);
+
+	if (!vdev_mac_entry) {
+		wmi_err("Invalid vdev_mac_entry");
+		return;
+	}
+
+	/* Store the vdev-mac map in WMA and send to policy manager */
+	for (i = 0; i < fixed_param->num_vdev_mac_entries; i++) {
+		uint32_t vdev_id, mac_id, pdev_id;
+
+		vdev_id = vdev_mac_entry[i].vdev_id;
+		pdev_id = vdev_mac_entry[i].pdev_id;
+
+		if (pdev_id == OL_TXRX_PDEV_ID) {
+			wmi_err("soc level id received for mac id");
+			return;
+		}
+		if (vdev_id >= WLAN_MAX_VDEVS) {
+			wmi_err("vdev_id: %d is invalid, max_bssid: %d",
+				vdev_id, WLAN_MAX_VDEVS);
+			return;
+		}
+
+		mac_id = WMI_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id);
+
+		hw_mode_trans_ind->vdev_mac_map[i].vdev_id = vdev_id;
+		hw_mode_trans_ind->vdev_mac_map[i].mac_id = mac_id;
+
+		wmi_debug("vdev_id:%d mac_id:%d", vdev_id, mac_id);
+	}
+}
+
+static enum roam_reason
+wmi_convert_fw_reason_to_cm_reason(uint32_t reason)
+{
+	switch (reason) {
+	case WMI_ROAM_REASON_INVALID:
+		return ROAM_REASON_INVALID;
+	case WMI_ROAM_REASON_BETTER_AP:
+		return ROAM_REASON_BETTER_AP;
+	case WMI_ROAM_REASON_BMISS:
+		return ROAM_REASON_BMISS;
+	case WMI_ROAM_REASON_LOW_RSSI:
+		return ROAM_REASON_LOW_RSSI;
+	case WMI_ROAM_REASON_SUITABLE_AP:
+		return ROAM_REASON_SUITABLE_AP;
+	case WMI_ROAM_REASON_HO_FAILED:
+		return ROAM_REASON_HO_FAILED;
+	case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
+		return ROAM_REASON_INVOKE_ROAM_FAIL;
+	case WMI_ROAM_REASON_RSO_STATUS:
+		return ROAM_REASON_RSO_STATUS;
+	case WMI_ROAM_REASON_BTM:
+		return ROAM_REASON_BTM;
+	case WMI_ROAM_REASON_DEAUTH:
+		return ROAM_REASON_DEAUTH;
+	default:
+		return ROAM_REASON_INVALID;
+	}
+
+	return ROAM_REASON_INVALID;
+}
+
+static enum cm_roam_notif
+wmi_convert_fw_notif_to_cm_notif(uint32_t fw_notif)
+{
+	switch (fw_notif) {
+	case WMI_ROAM_NOTIF_ROAM_START:
+		return CM_ROAM_NOTIF_ROAM_START;
+	case WMI_ROAM_NOTIF_ROAM_ABORT:
+		return CM_ROAM_NOTIF_ROAM_ABORT;
+	case WMI_ROAM_NOTIF_ROAM_REASSOC:
+		return CM_ROAM_NOTIF_ROAM_REASSOC;
+	case WMI_ROAM_NOTIF_SCAN_MODE_SUCCESS:
+		return CM_ROAM_NOTIF_SCAN_MODE_SUCCESS;
+	case WMI_ROAM_NOTIF_SCAN_MODE_FAIL:
+		return CM_ROAM_NOTIF_SCAN_MODE_FAIL;
+	case WMI_ROAM_NOTIF_DISCONNECT:
+		return CM_ROAM_NOTIF_DISCONNECT;
+	case WMI_ROAM_NOTIF_SUBNET_CHANGED:
+		return CM_ROAM_NOTIF_SUBNET_CHANGED;
+	case WMI_ROAM_NOTIF_SCAN_START:
+		return CM_ROAM_NOTIF_SCAN_START;
+	case WMI_ROAM_NOTIF_DEAUTH_RECV:
+		return CM_ROAM_NOTIF_DEAUTH_RECV;
+	case WMI_ROAM_NOTIF_DISASSOC_RECV:
+		return CM_ROAM_NOTIF_DISASSOC_RECV;
+	default:
+		return CM_ROAM_NOTIF_INVALID;
+	}
+
+	return CM_ROAM_NOTIF_INVALID;
+}
+
+/**
+ * extract_roam_sync_event_tlv() - Extract the roam event
+ * @wmi_handle: wmi handle
+ * @evt_buf: Pointer to the event buffer
+ * @len: Data length
+ * @roam_event: Roam event data
+ */
+static QDF_STATUS
+extract_roam_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, uint32_t len,
+		       struct roam_offload_roam_event *roam_event)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	wmi_roam_event_fixed_param *wmi_event = NULL;
+	WMI_ROAM_EVENTID_param_tlvs *param_buf = NULL;
+	struct cm_hw_mode_trans_ind *hw_mode_trans_ind;
+
+	if (!evt_buf) {
+		wmi_debug("Empty roam_sync_event param buf");
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	param_buf = (WMI_ROAM_EVENTID_param_tlvs *)evt_buf;
+	if (!param_buf) {
+		wmi_debug("received null buf from target");
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	wmi_event = param_buf->fixed_param;
+	if (!wmi_event) {
+		wmi_debug("received null event data from target");
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+	roam_event->vdev_id = wmi_event->vdev_id;
+
+	if (roam_event->vdev_id >= WLAN_MAX_VDEVS) {
+		wmi_err("Invalid vdev id from firmware: %u",
+			roam_event->vdev_id);
+		return -EINVAL;
+	}
+
+	roam_event->reason =
+			wmi_convert_fw_reason_to_cm_reason(wmi_event->reason);
+	roam_event->rssi = wmi_event->rssi;
+	roam_event->notif = wmi_convert_fw_notif_to_cm_notif(wmi_event->notif);
+	roam_event->notif_params = wmi_event->notif_params;
+	roam_event->notif_params1 = wmi_event->notif_params1;
+
+	wlan_roam_debug_log(roam_event->vdev_id, DEBUG_ROAM_EVENT,
+			    DEBUG_INVALID_PEER_ID, NULL, NULL,
+			    roam_event->reason,
+			    (roam_event->reason == WMI_ROAM_REASON_INVALID) ?
+			    roam_event->notif : roam_event->rssi);
+
+	DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
+		roam_event->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
+		QDF_PROTO_TYPE_EVENT, QDF_ROAM_EVENTID));
+
+	wmi_debug("FW_ROAM_EVT: Reason:%s[%d], Notif %x for vdevid %x, rssi %d",
+		  wmi_get_roam_event_reason_string(roam_event->reason),
+		  roam_event->reason,
+		  roam_event->notif, roam_event->vdev_id, roam_event->rssi);
+
+	if (param_buf->hw_mode_transition_fixed_param) {
+		hw_mode_trans_ind = qdf_mem_malloc(sizeof(*hw_mode_trans_ind));
+		if (!hw_mode_trans_ind) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		wmi_extract_pdev_hw_mode_trans_ind(
+		    param_buf->hw_mode_transition_fixed_param,
+		    param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping,
+		    hw_mode_trans_ind);
+		roam_event->hw_mode_trans_ind = hw_mode_trans_ind;
+	}
+
+	if (wmi_event->notif_params1)
+		roam_event->deauth_disassoc_frame =
+			param_buf->deauth_disassoc_frame;
+end:
+	return status;
+}
+#endif
 
 void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
 {
@@ -1842,6 +2079,7 @@ void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
 #ifdef ROAM_TARGET_IF_CONVERGENCE
 	ops->extract_roam_sync_event = extract_roam_sync_event_tlv;
 	ops->extract_roam_sync_frame_event = extract_roam_sync_frame_event_tlv;
+	ops->extract_roam_event = extract_roam_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 =
@@ -1887,6 +2125,13 @@ extract_roam_sync_frame_event(wmi_unified_t wmi_handle, void *evt_buf,
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
+
+static inline QDF_STATUS
+extract_roam_event(wmi_unified_t wmi_handle, void *evt_buf, uint32_t len,
+		   struct roam_offload_roam_event *roam_event)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 

+ 3 - 2
core/wma/inc/wma_internal.h

@@ -1113,13 +1113,14 @@ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info,
 
 /**
  * wma_rso_cmd_status_event_handler() - RSO Command status event handler
- * @wmi_event: WMI event
+ * @vdev_id: VDEV id
+ * @notif: roam notification
  *
  * This function is used to send RSO command status to upper layer
  *
  * Return: 0 for success
  */
-int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event);
+int wma_rso_cmd_status_event_handler(uint8_t vdev_id, uint32_t notif);
 
 int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info,
 			    uint32_t len);

+ 6 - 0
core/wma/src/wma_features.c

@@ -71,6 +71,7 @@
 #include "wlan_cm_api.h"
 #include <wlan_crypto_global_api.h>
 #include "cdp_txrx_host_stats.h"
+#include "target_if_cm_roam_event.h"
 
 /**
  * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE
@@ -2735,8 +2736,13 @@ static int wma_wake_event_piggybacked(
 				    NULL, NULL, wake_reason,
 				    pb_event_len);
 		if (pb_event_len > 0) {
+#ifdef ROAM_TARGET_IF_CONVERGENCE
+			errno = target_if_cm_roam_event(wma, pb_event,
+							pb_event_len);
+#else
 			errno = wma_roam_event_callback(wma, pb_event,
 							pb_event_len);
+#endif
 		} else {
 			/*
 			 * No wow_packet_buffer means a better AP beacon

+ 7 - 0
core/wma/src/wma_main.c

@@ -115,6 +115,7 @@
 #endif
 
 #include "wlan_pkt_capture_ucfg_api.h"
+#include "target_if_cm_roam_event.h"
 
 #define WMA_LOG_COMPLETION_TIMER 3000 /* 3 seconds */
 #define WMI_TLV_HEADROOM 128
@@ -3081,6 +3082,10 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
 	/* Register Converged Event handlers */
 	init_deinit_register_tgt_psoc_ev_handlers(psoc);
 
+#ifdef ROAM_TARGET_IF_CONVERGENCE
+	target_if_roam_offload_register_events(psoc);
+#endif /* ROAM_TARGET_IF_CONVERGENCE */
+
 	/* Initialize max_no_of_peers for wma_get_number_of_peers_supported() */
 	cds_cfg->max_station = wma_init_max_no_of_peers(wma_handle,
 							cds_cfg->max_station);
@@ -4089,6 +4094,7 @@ QDF_STATUS wma_start(void)
 		goto end;
 	}
 
+#ifndef ROAM_TARGET_IF_CONVERGENCE
 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
 						    wmi_roam_event_id,
 						    wma_roam_event_callback,
@@ -4098,6 +4104,7 @@ QDF_STATUS wma_start(void)
 		qdf_status = QDF_STATUS_E_FAILURE;
 		goto end;
 	}
+#endif
 
 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
 						    wmi_wow_wakeup_host_event_id,

+ 281 - 61
core/wma/src/wma_scan_roam.c

@@ -4014,6 +4014,7 @@ void wma_roam_better_ap_handler(tp_wma_handle wma, uint32_t vdev_id)
 		qdf_mem_free(msg.bodyptr);
 }
 
+#ifndef ROAM_TARGET_IF_CONVERGENCE
 /**
  * wma_handle_hw_mode_in_roam_fail() - Fill hw mode info if present in policy
  * manager.
@@ -4053,6 +4054,7 @@ static int wma_handle_hw_mode_transition(tp_wma_handle wma,
 
 	return 0;
 }
+#endif
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 /**
@@ -4067,14 +4069,14 @@ static int wma_handle_hw_mode_transition(tp_wma_handle wma,
  */
 static void wma_invalid_roam_reason_handler(tp_wma_handle wma_handle,
 					    uint32_t vdev_id,
-					    uint32_t notif)
+					    enum cm_roam_notif notif)
 {
 	struct roam_offload_synch_ind *roam_synch_data;
 	enum sir_roam_op_code op_code;
 
-	if (notif == WMI_ROAM_NOTIF_ROAM_START) {
+	if (notif == CM_ROAM_NOTIF_ROAM_START) {
 		op_code = SIR_ROAMING_START;
-	} else if (notif == WMI_ROAM_NOTIF_ROAM_ABORT) {
+	} else if (notif == CM_ROAM_NOTIF_ROAM_ABORT) {
 		op_code = SIR_ROAMING_ABORT;
 		lim_sae_auth_cleanup_retry(wma_handle->mac_context, vdev_id);
 	} else {
@@ -4086,11 +4088,11 @@ static void wma_invalid_roam_reason_handler(tp_wma_handle wma_handle,
 		return;
 
 	roam_synch_data->roamed_vdev_id = vdev_id;
-	if (notif != WMI_ROAM_NOTIF_ROAM_START)
+	if (notif != CM_ROAM_NOTIF_ROAM_START)
 		wma_handle->pe_roam_synch_cb(wma_handle->mac_context,
 					     roam_synch_data, NULL, op_code);
 
-	if (notif == WMI_ROAM_NOTIF_ROAM_START)
+	if (notif == CM_ROAM_NOTIF_ROAM_START)
 		cm_fw_roam_start_req(wma_handle->psoc, vdev_id);
 	else
 		cm_fw_roam_abort_req(wma_handle->psoc, vdev_id);
@@ -4102,10 +4104,269 @@ void wma_handle_roam_sync_timeout(tp_wma_handle wma_handle,
 				  struct roam_sync_timeout_timer_info *info)
 {
 	wma_invalid_roam_reason_handler(wma_handle, info->vdev_id,
-					WMI_ROAM_NOTIF_ROAM_ABORT);
+					CM_ROAM_NOTIF_ROAM_ABORT);
+}
+
+#ifdef ROAM_TARGET_IF_CONVERGENCE
+void cm_invalid_roam_reason_handler(uint32_t vdev_id, enum cm_roam_notif notif)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		QDF_ASSERT(0);
+		return;
+	}
+	wma_invalid_roam_reason_handler(wma_handle, vdev_id, notif);
 }
 #endif
+#endif
+
+static void
+wma_handle_roam_reason_invoke_roam_fail(tp_wma_handle wma_handle,
+					uint8_t vdev_id, uint32_t notif_params)
+{
+	struct roam_offload_synch_ind *roam_synch_data;
+
+	roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
+	if (!roam_synch_data)
+		return;
+
+	lim_sae_auth_cleanup_retry(wma_handle->mac_context, vdev_id);
+	roam_synch_data->roamed_vdev_id = vdev_id;
+	cm_fw_roam_invoke_fail(wma_handle->psoc, vdev_id);
+	wlan_cm_update_roam_states(wma_handle->psoc, vdev_id,
+				   notif_params,
+				   ROAM_INVOKE_FAIL_REASON);
+	qdf_mem_free(roam_synch_data);
+}
+
+static void wma_handle_roam_reason_btm(uint8_t vdev_id)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		QDF_ASSERT(0);
+		return;
+	}
+	/*
+	 * This event is received from firmware if firmware is unable to
+	 * find candidate AP after roam scan and BTM request from AP
+	 * has disassoc imminent bit set.
+	 */
+	wma_debug("Kickout due to btm request");
+	wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_BTM, vdev_id, NULL);
+	wma_handle_disconnect_reason(wma_handle, vdev_id,
+			HAL_DEL_STA_REASON_CODE_BTM_DISASSOC_IMMINENT);
+}
+
+static void wma_handle_roam_reason_bmiss(uint8_t vdev_id, uint32_t rssi)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		QDF_ASSERT(0);
+		return;
+	}
+	/*
+	 * WMI_ROAM_REASON_BMISS can get called in soft IRQ context, so
+	 * avoid using CSR/PE structure directly
+	 */
+	wma_debug("Beacon Miss for vdevid %x", vdev_id);
+	wma_beacon_miss_handler(wma_handle, vdev_id, rssi);
+	wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_BMISS, vdev_id, NULL);
+}
+
+static void wma_handle_roam_reason_better_ap(uint8_t vdev_id, uint32_t rssi)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		QDF_ASSERT(0);
+		return;
+	}
+	/*
+	 * WMI_ROAM_REASON_BETTER_AP can get called in soft IRQ context,
+	 * so avoid using CSR/PE structure directly.
+	 */
+	wma_debug("Better AP found for vdevid %x, rssi %d", vdev_id, rssi);
+	mlme_set_roam_reason_better_ap(wma_handle->interfaces[vdev_id].vdev,
+				       false);
+	wma_roam_better_ap_handler(wma_handle, vdev_id);
+}
+
+static void wma_handle_roam_reason_suitable_ap(uint8_t vdev_id, uint32_t rssi)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		QDF_ASSERT(0);
+		return;
+	}
+	/*
+	 * WMI_ROAM_REASON_SUITABLE_AP can get called in soft IRQ
+	 * context, so avoid using CSR/PE structure directly.
+	 */
+	mlme_set_roam_reason_better_ap(wma_handle->interfaces[vdev_id].vdev,
+				       true);
+	mlme_set_hb_ap_rssi(wma_handle->interfaces[vdev_id].vdev, rssi);
+	wma_debug("Bmiss scan AP found for vdevid %x, rssi %d", vdev_id, rssi);
+	wma_roam_better_ap_handler(wma_handle, vdev_id);
+}
+
+#ifdef ROAM_TARGET_IF_CONVERGENCE
+static void
+wma_update_pdev_hw_mode_trans_ind(tp_wma_handle wma,
+				  struct cm_hw_mode_trans_ind *trans_ind)
+{
+	uint32_t i;
+
+	/* Store the vdev-mac map in WMA and send to policy manager */
+	for (i = 0; i < trans_ind->num_vdev_mac_entries; i++)
+		wma_update_intf_hw_mode_params(
+				trans_ind->vdev_mac_map[i].vdev_id,
+				trans_ind->vdev_mac_map[i].mac_id,
+				trans_ind->new_hw_mode_index);
+
+	wma->old_hw_mode_index = trans_ind->old_hw_mode_index;
+	wma->new_hw_mode_index = trans_ind->new_hw_mode_index;
+	policy_mgr_update_new_hw_mode_index(wma->psoc,
+					    trans_ind->new_hw_mode_index);
+	policy_mgr_update_old_hw_mode_index(wma->psoc,
+					    trans_ind->old_hw_mode_index);
+
+	wma_debug("Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
+		  wma->old_hw_mode_index, wma->new_hw_mode_index);
+}
+
+static void
+wma_handle_hw_mode_trans_ind(tp_wma_handle wma_handle,
+			     struct cm_hw_mode_trans_ind *hw_mode_trans_ind)
+{
+	struct scheduler_msg sme_msg = {0};
+	QDF_STATUS status;
+
+	if (hw_mode_trans_ind) {
+		wma_update_pdev_hw_mode_trans_ind(wma_handle,
+						  hw_mode_trans_ind);
+		wma_debug("Update HW mode");
+		sme_msg.type = eWNI_SME_HW_MODE_TRANS_IND;
+		sme_msg.bodyptr = hw_mode_trans_ind;
 
+		status = scheduler_post_message(QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_SME, &sme_msg);
+		if (QDF_IS_STATUS_ERROR(status))
+			qdf_mem_free(hw_mode_trans_ind);
+	} else {
+		wma_debug("hw_mode transition fixed param is NULL");
+	}
+}
+
+int cm_rso_cmd_status_event_handler(uint8_t vdev_id, enum cm_roam_notif notif)
+{
+	return wma_rso_cmd_status_event_handler(vdev_id, notif);
+}
+
+void
+cm_handle_roam_reason_invoke_roam_fail(uint8_t vdev_id,	uint32_t notif_params,
+				       struct cm_hw_mode_trans_ind *trans_ind)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		QDF_ASSERT(0);
+		return;
+	}
+	wma_handle_hw_mode_trans_ind(wma_handle, trans_ind);
+	wma_handle_roam_reason_invoke_roam_fail(wma_handle, vdev_id,
+						notif_params);
+}
+
+static void
+wma_handle_roam_reason_deauth(uint8_t vdev_id, uint32_t notif_params,
+			      uint32_t notif_params1,
+			      uint8_t *deauth_disassoc_frame)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	struct roam_offload_synch_ind *roam_synch_data;
+
+	if (!wma_handle) {
+		QDF_ASSERT(0);
+		return;
+	}
+	wma_debug("Received disconnect roam event reason:%d", notif_params);
+	wma_handle->pe_disconnect_cb(wma_handle->mac_context,
+				     vdev_id,
+				     deauth_disassoc_frame, notif_params1,
+				     notif_params);
+	roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
+	if (!roam_synch_data)
+		return;
+
+	roam_synch_data->roamed_vdev_id = vdev_id;
+	qdf_mem_free(roam_synch_data);
+}
+
+void cm_handle_roam_reason_deauth(uint8_t vdev_id, uint32_t notif_params,
+				  uint8_t *deauth_disassoc_frame,
+				  uint32_t frame_len)
+{
+	wma_handle_roam_reason_deauth(vdev_id, notif_params, frame_len,
+				      deauth_disassoc_frame);
+}
+
+void cm_handle_roam_reason_btm(uint8_t vdev_id)
+{
+	wma_handle_roam_reason_btm(vdev_id);
+}
+
+void cm_handle_roam_reason_bmiss(uint8_t vdev_id, uint32_t rssi)
+{
+	wma_handle_roam_reason_bmiss(vdev_id, rssi);
+}
+
+void cm_handle_roam_reason_better_ap(uint8_t vdev_id, uint32_t rssi)
+{
+	wma_handle_roam_reason_better_ap(vdev_id, rssi);
+}
+
+void cm_handle_roam_reason_suitable_ap(uint8_t vdev_id, uint32_t rssi)
+{
+	wma_handle_roam_reason_suitable_ap(vdev_id, rssi);
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static void
+wma_handle_roam_reason_ho_failed(uint8_t vdev_id, struct qdf_mac_addr bssid,
+				 struct cm_hw_mode_trans_ind *hw_mode_trans_ind)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		QDF_ASSERT(0);
+		return;
+	}
+	/*
+	 * WMI_ROAM_REASON_HO_FAILED can get called in soft IRQ context,
+	 * so avoid using CSR/PE structure directly.
+	 */
+	wma_err("LFR3:Hand-Off Failed for vdevid %x", vdev_id);
+	wma_debug("mac addr to avoid " QDF_MAC_ADDR_FMT,
+		  QDF_MAC_ADDR_REF(bssid.bytes));
+	wma_handle_hw_mode_trans_ind(wma_handle, hw_mode_trans_ind);
+	cm_fw_ho_fail_req(wma_handle->psoc, vdev_id, bssid);
+	lim_sae_auth_cleanup_retry(wma_handle->mac_context, vdev_id);
+}
+
+void
+cm_handle_roam_reason_ho_failed(uint8_t vdev_id, struct qdf_mac_addr bssid,
+				struct cm_hw_mode_trans_ind *hw_mode_trans_ind)
+{
+	wma_handle_roam_reason_ho_failed(vdev_id, bssid, hw_mode_trans_ind);
+}
+#endif
+
+#else
 static char *wma_get_roam_event_reason_string(uint32_t reason)
 {
 	switch (reason) {
@@ -4186,52 +4447,19 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
 
 	switch (wmi_event->reason) {
 	case WMI_ROAM_REASON_BTM:
-		/*
-		 * This event is received from firmware if firmware is unable to
-		 * find candidate AP after roam scan and BTM request from AP
-		 * has disassoc imminent bit set.
-		 */
-		wma_debug("Kickout due to btm request");
-		wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_BTM,
-				      wmi_event->vdev_id, NULL);
-		wma_handle_disconnect_reason(wma_handle, wmi_event->vdev_id,
-				HAL_DEL_STA_REASON_CODE_BTM_DISASSOC_IMMINENT);
+		wma_handle_roam_reason_btm(wmi_event->vdev_id);
 		break;
 	case WMI_ROAM_REASON_BMISS:
-		/*
-		 * WMI_ROAM_REASON_BMISS can get called in soft IRQ context, so
-		 * avoid using CSR/PE structure directly
-		 */
-		wma_debug("Beacon Miss for vdevid %x", wmi_event->vdev_id);
-		wma_beacon_miss_handler(wma_handle, wmi_event->vdev_id,
-					wmi_event->rssi);
-		wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_BMISS,
-						wmi_event->vdev_id, NULL);
+		wma_handle_roam_reason_bmiss(wmi_event->vdev_id,
+					     wmi_event->rssi);
 		break;
 	case WMI_ROAM_REASON_BETTER_AP:
-		/*
-		 * WMI_ROAM_REASON_BETTER_AP can get called in soft IRQ context,
-		 * so avoid using CSR/PE structure directly.
-		 */
-		wma_debug("Better AP found for vdevid %x, rssi %d",
-			 wmi_event->vdev_id, wmi_event->rssi);
-		mlme_set_roam_reason_better_ap(
-			wma_handle->interfaces[wmi_event->vdev_id].vdev, false);
-		wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id);
+		wma_handle_roam_reason_better_ap(wmi_event->vdev_id,
+						 wmi_event->rssi);
 		break;
 	case WMI_ROAM_REASON_SUITABLE_AP:
-		/*
-		 * WMI_ROAM_REASON_SUITABLE_AP can get called in soft IRQ
-		 * context, so avoid using CSR/PE structure directly.
-		 */
-		mlme_set_roam_reason_better_ap(
-			wma_handle->interfaces[wmi_event->vdev_id].vdev, true);
-		mlme_set_hb_ap_rssi(
-			wma_handle->interfaces[wmi_event->vdev_id].vdev,
-			wmi_event->rssi);
-		wma_debug("Bmiss scan AP found for vdevid %x, rssi %d",
-			 wmi_event->vdev_id, wmi_event->rssi);
-		wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id);
+		wma_handle_roam_reason_suitable_ap(wmi_event->vdev_id,
+						   wmi_event->rssi);
 		break;
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	case WMI_ROAM_REASON_HO_FAILED:
@@ -4261,27 +4489,18 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
 		break;
 #endif
 	case WMI_ROAM_REASON_RSO_STATUS:
-		wma_rso_cmd_status_event_handler(wmi_event);
+		wma_rso_cmd_status_event_handler(wmi_event->vdev_id,
+						 wmi_event->notif);
 		break;
 	case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
 		wma_handle_hw_mode_transition(wma_handle, param_buf);
-		roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
-		if (!roam_synch_data)
-			return -ENOMEM;
-
-		lim_sae_auth_cleanup_retry(wma_handle->mac_context,
-					   wmi_event->vdev_id);
-		roam_synch_data->roamed_vdev_id = wmi_event->vdev_id;
-		cm_fw_roam_invoke_fail(wma_handle->psoc, wmi_event->vdev_id);
-		wlan_cm_update_roam_states(wma_handle->psoc, wmi_event->vdev_id,
-					   wmi_event->notif_params,
-					   ROAM_INVOKE_FAIL_REASON);
-
-		qdf_mem_free(roam_synch_data);
+		wma_handle_roam_reason_invoke_roam_fail(wma_handle,
+						wmi_event->vdev_id,
+						wmi_event->notif_params);
 		break;
 	case WMI_ROAM_REASON_DEAUTH:
 		wma_debug("Received disconnect roam event reason:%d",
-			 wmi_event->notif_params);
+			  wmi_event->notif_params);
 		if (wmi_event->notif_params1)
 			frame = param_buf->deauth_disassoc_frame;
 		wma_handle->pe_disconnect_cb(wma_handle->mac_context,
@@ -4302,6 +4521,7 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
 	}
 	return 0;
 }
+#endif
 
 #ifdef FEATURE_LFR_SUBNET_DETECTION
 QDF_STATUS wma_set_gateway_params(tp_wma_handle wma,

+ 4 - 4
core/wma/src/wma_utils.c

@@ -3036,7 +3036,7 @@ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info,
 	return 0;
 }
 
-int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event)
+int wma_rso_cmd_status_event_handler(uint8_t vdev_id, enum cm_roam_notif notif)
 {
 	struct rso_cmd_status *rso_status;
 	struct scheduler_msg sme_msg = {0};
@@ -3046,10 +3046,10 @@ int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event)
 	if (!rso_status)
 		return -ENOMEM;
 
-	rso_status->vdev_id = wmi_event->vdev_id;
-	if (WMI_ROAM_NOTIF_SCAN_MODE_SUCCESS == wmi_event->notif)
+	rso_status->vdev_id = vdev_id;
+	if (notif == CM_ROAM_NOTIF_SCAN_MODE_SUCCESS)
 		rso_status->status = true;
-	else if (WMI_ROAM_NOTIF_SCAN_MODE_FAIL == wmi_event->notif)
+	else if (notif == CM_ROAM_NOTIF_SCAN_MODE_FAIL)
 		rso_status->status = false;
 	sme_msg.type = eWNI_SME_RSO_CMD_STATUS_IND;
 	sme_msg.bodyptr = rso_status;