Browse Source

qcacld-3.0: wma to target_if migration of roam pmkid request evt

Currently, wmi_roam_pmkid_request_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: I3fad4e4d7ceeb85c632723e161809bf980d5375f
CRs-Fixed: 3014248
Srinivas Dasari 3 years ago
parent
commit
3aeaeefe07

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

@@ -121,6 +121,18 @@ target_if_cm_roam_vdev_disconnect_event_handler(ol_scn_t scn, uint8_t *event,
 int
 target_if_cm_roam_scan_chan_list_event_handler(ol_scn_t scn, uint8_t *event,
 					       uint32_t len);
+
+/**
+ * target_if_pmkid_request_event_handler - pmkid request event handler
+ * @scn: target handle
+ * @event: event buffer
+ * @len: event buffer length
+ *
+ * Return: int for success or error code
+ */
+int
+target_if_pmkid_request_event_handler(ol_scn_t scn, uint8_t *event,
+				      uint32_t len);
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 
 /**
@@ -166,6 +178,13 @@ target_if_cm_roam_scan_chan_list_event_handler(ol_scn_t scn, uint8_t *event,
 {
 	return 0;
 }
+
+static inline int
+target_if_pmkid_request_event_handler(ol_scn_t scn, uint8_t *event,
+				      uint32_t len)
+{
+	return 0;
+}
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 #endif

+ 192 - 32
components/target_if/connection_mgr/src/target_if_cm_roam_event.c

@@ -62,6 +62,7 @@ target_if_cm_roam_register_rx_ops(struct wlan_cm_roam_rx_ops *rx_ops)
 	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;
 	rx_ops->roam_auth_offload_event = cm_roam_auth_offload_event_handler;
+	rx_ops->roam_pmkid_request_event_rx = cm_roam_pmkid_request_handler;
 #endif
 }
 
@@ -177,14 +178,111 @@ err:
 	return status;
 }
 
+static QDF_STATUS target_if_roam_event_dispatcher(struct scheduler_msg *msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_cm_roam_rx_ops *roam_rx_ops;
+
+	switch (msg->type) {
+	case ROAM_PMKID_REQ_EVENT:
+	{
+		struct roam_pmkid_req_event *data = msg->bodyptr;
+
+		if (!data->psoc) {
+			target_if_err("psoc is null");
+			status = QDF_STATUS_E_NULL_VALUE;
+			goto done;
+		}
+		roam_rx_ops = target_if_cm_get_roam_rx_ops(data->psoc);
+		if (!roam_rx_ops || !roam_rx_ops->roam_pmkid_request_event_rx) {
+			target_if_err("No valid roam rx ops");
+			status = QDF_STATUS_E_INVAL;
+			goto done;
+		}
+
+		status = roam_rx_ops->roam_pmkid_request_event_rx(data);
+	}
+	break;
+	case ROAM_EVENT:
+	{
+		struct roam_offload_roam_event *data = msg->bodyptr;
+
+		if (!data->psoc) {
+			target_if_err("psoc is null");
+			status = QDF_STATUS_E_NULL_VALUE;
+			goto done;
+		}
+		roam_rx_ops = target_if_cm_get_roam_rx_ops(data->psoc);
+		if (!roam_rx_ops || !roam_rx_ops->roam_event_rx) {
+			target_if_err("No valid roam rx ops");
+			status = QDF_STATUS_E_INVAL;
+			goto done;
+		}
+
+		status = roam_rx_ops->roam_event_rx(data);
+	}
+	break;
+	case ROAM_VDEV_DISCONNECT_EVENT:
+	{
+		struct vdev_disconnect_event_data *data = msg->bodyptr;
+
+		if (!data->psoc) {
+			target_if_err("psoc is null");
+			status = QDF_STATUS_E_NULL_VALUE;
+			goto done;
+		}
+
+		roam_rx_ops = target_if_cm_get_roam_rx_ops(data->psoc);
+		if (!roam_rx_ops || !roam_rx_ops->vdev_disconnect_event) {
+			target_if_err("No valid roam rx ops");
+			status = -EINVAL;
+			goto done;
+		}
+		status = roam_rx_ops->vdev_disconnect_event(data);
+	}
+	break;
+	default:
+		target_if_err("invalid msg type %d", msg->type);
+		status = QDF_STATUS_E_INVAL;
+	}
+
+done:
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+	return status;
+}
+
+static QDF_STATUS target_if_roam_event_flush_cb(struct scheduler_msg *msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	switch (msg->type) {
+	case ROAM_PMKID_REQ_EVENT:
+	case ROAM_EVENT:
+	case ROAM_VDEV_DISCONNECT_EVENT:
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	default:
+		target_if_err("invalid msg type %d", msg->type);
+		status = QDF_STATUS_E_INVAL;
+		goto free_res;
+	}
+	return status;
+
+free_res:
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+	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 roam_offload_roam_event *roam_event = NULL;
 	struct wlan_objmgr_psoc *psoc;
-	struct wlan_cm_roam_rx_ops *roam_rx_ops;
+	struct scheduler_msg msg = {0};
 
 	psoc = target_if_get_psoc_from_scn_hdl(scn);
 	if (!psoc) {
@@ -198,25 +296,29 @@ int target_if_cm_roam_event(ol_scn_t scn, uint8_t *event, uint32_t len)
 		return -EINVAL;
 	}
 
-	qdf_status = wmi_extract_roam_event(wmi_handle, event, len,
-					    &roam_event);
+	roam_event = qdf_mem_malloc(sizeof(*roam_event));
+	if (!roam_event)
+		return -ENOMEM;
+
+	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);
+		qdf_mem_free(roam_event);
 		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);
+	msg.bodyptr = roam_event;
+	msg.type = ROAM_EVENT;
+	msg.callback = target_if_roam_event_dispatcher;
+	msg.flush_callback = target_if_roam_event_flush_cb;
+	target_if_debug("ROAM_EVENT sent: %d", msg.type);
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					    QDF_MODULE_ID_TARGET_IF,
+					    QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(qdf_status))
-		status = -EINVAL;
+		target_if_roam_event_flush_cb(&msg);
 
-err:
-	return status;
+	return qdf_status_to_os_return(qdf_status);
 }
 
 static int
@@ -251,13 +353,15 @@ target_if_cm_btm_blacklist_event(ol_scn_t scn, uint8_t *event, uint32_t len)
 	roam_rx_ops = target_if_cm_get_roam_rx_ops(psoc);
 	if (!roam_rx_ops || !roam_rx_ops->btm_blacklist_event) {
 		target_if_err("No valid roam rx ops");
-		qdf_mem_free(dst_list);
-		return -EINVAL;
+		status = -EINVAL;
+		goto done;
 	}
 	qdf_status = roam_rx_ops->btm_blacklist_event(psoc, dst_list);
 	if (QDF_IS_STATUS_ERROR(qdf_status))
 		status = -EINVAL;
 
+done:
+	qdf_mem_free(dst_list);
 	return status;
 }
 
@@ -266,11 +370,10 @@ target_if_cm_roam_vdev_disconnect_event_handler(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 vdev_disconnect_event_data data = {0};
+	struct vdev_disconnect_event_data *data;
+	struct scheduler_msg msg = {0};
 
 	psoc = target_if_get_psoc_from_scn_hdl(scn);
 	if (!psoc) {
@@ -284,25 +387,29 @@ target_if_cm_roam_vdev_disconnect_event_handler(ol_scn_t scn, uint8_t *event,
 		return -EINVAL;
 	}
 
+	data = qdf_mem_malloc(sizeof(*data));
+	if (!data)
+		return -ENOMEM;
 	qdf_status = wmi_extract_vdev_disconnect_event(wmi_handle, event, len,
-						       &data);
+						       data);
 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
 		target_if_err("parsing of event failed, %d", qdf_status);
+		qdf_mem_free(data);
 		return -EINVAL;
 	}
 
-	roam_rx_ops = target_if_cm_get_roam_rx_ops(psoc);
-	if (!roam_rx_ops || !roam_rx_ops->vdev_disconnect_event) {
-		target_if_err("No valid roam rx ops");
-		status = -EINVAL;
-		goto err;
-	}
-	qdf_status = roam_rx_ops->vdev_disconnect_event(&data);
+	msg.bodyptr = data;
+	msg.type = ROAM_VDEV_DISCONNECT_EVENT;
+	msg.callback = target_if_roam_event_dispatcher;
+	msg.flush_callback = target_if_roam_event_flush_cb;
+	target_if_debug("ROAM_VDEV_DISCONNECT_EVENT sent: %d", msg.type);
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					    QDF_MODULE_ID_TARGET_IF,
+					    QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(qdf_status))
-		status = -EINVAL;
+		target_if_roam_event_flush_cb(&msg);
 
-err:
-	return status;
+	return qdf_status_to_os_return(qdf_status);
 }
 
 int
@@ -438,6 +545,50 @@ target_if_cm_roam_auth_offload_event(ol_scn_t scn, uint8_t *event, uint32_t len)
 	return status;
 }
 
+int
+target_if_pmkid_request_event_handler(ol_scn_t scn, uint8_t *event,
+				      uint32_t len)
+{
+	QDF_STATUS qdf_status;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct roam_pmkid_req_event *data = NULL;
+	struct scheduler_msg msg = {0};
+
+	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_pmkid_request(wmi_handle, event, len,
+						    &data);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		target_if_err("parsing of event failed, %d", qdf_status);
+		qdf_mem_free(data);
+		return -EINVAL;
+	}
+
+	msg.bodyptr = data;
+	msg.type = ROAM_PMKID_REQ_EVENT;
+	msg.callback = target_if_roam_event_dispatcher;
+	msg.flush_callback = target_if_roam_event_flush_cb;
+	target_if_debug("ROAM_PMKID_REQ_EVENT sent: %d", msg.type);
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					    QDF_MODULE_ID_TARGET_IF,
+					    QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		target_if_roam_event_flush_cb(&msg);
+
+	return qdf_status_to_os_return(qdf_status);
+}
+
 QDF_STATUS
 target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
 {
@@ -525,7 +676,16 @@ 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_pmkid_request_event_id,
+				target_if_pmkid_request_event_handler,
+				WMI_RX_SERIALIZER_CTX);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		target_if_err("wmi event(%u) registration failed, ret: %d",
+			      wmi_roam_stats_event_id, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	return QDF_STATUS_SUCCESS;
 }
-
 #endif

+ 0 - 37
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c

@@ -1127,43 +1127,6 @@ void cm_fw_ho_fail_req(struct wlan_objmgr_psoc *psoc,
 	}
 }
 
-#ifdef WLAN_FEATURE_FIPS
-QDF_STATUS cm_roam_pmkid_req_ind(struct wlan_objmgr_psoc *psoc,
-				 uint8_t vdev_id,
-				 struct roam_pmkid_req_event *src_lst)
-{
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	struct wlan_objmgr_vdev *vdev;
-	struct qdf_mac_addr *dst_list;
-	uint32_t num_entries, i;
-
-	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
-						    WLAN_MLME_SB_ID);
-	if (!vdev) {
-		mlme_err("vdev object is NULL");
-		return QDF_STATUS_E_NULL_VALUE;
-	}
-
-	num_entries = src_lst->num_entries;
-	mlme_debug("Num entries %d", num_entries);
-	for (i = 0; i < num_entries; i++) {
-		dst_list = &src_lst->ap_bssid[i];
-		status = mlme_cm_osif_pmksa_candidate_notify(vdev, dst_list,
-							     1, false);
-		if (QDF_IS_STATUS_ERROR(status)) {
-			mlme_err("Number %d Notify failed for " QDF_MAC_ADDR_FMT,
-				 i, QDF_MAC_ADDR_REF(dst_list->bytes));
-			goto rel_ref;
-		}
-	}
-
-rel_ref:
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
-
-	return status;
-}
-#endif /* WLAN_FEATURE_FIPS */
-
 #ifdef ROAM_TARGET_IF_CONVERGENCE
 QDF_STATUS wlan_cm_free_roam_synch_frame_ind(struct rso_config *rso_cfg)
 {

+ 0 - 20
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_i.h

@@ -167,26 +167,6 @@ void cm_fw_ho_fail_req(struct wlan_objmgr_psoc *psoc,
  */
 QDF_STATUS cm_fw_roam_invoke_fail(struct wlan_objmgr_psoc *psoc,
 				  uint8_t vdev_id);
-
-#ifdef WLAN_FEATURE_FIPS
-/**
- * cm_roam_pmkid_req_ind() - Function to handle
- * roam event from firmware for pmkid generation.
- * @psoc: psoc pointer
- * @vdev_id: Vdev id
- * @bss_list: candidate AP bssid list
- */
-QDF_STATUS
-cm_roam_pmkid_req_ind(struct wlan_objmgr_psoc *psoc,
-		      uint8_t vdev_id, struct roam_pmkid_req_event *bss_list);
-#else /* WLAN_FEATURE_FIPS */
-static inline QDF_STATUS
-cm_roam_pmkid_req_ind(struct wlan_objmgr_psoc *psoc,
-		      uint8_t vdev_id, struct roam_pmkid_req_event *bss_list)
-{
-	return QDF_STATUS_SUCCESS;
-}
-#endif /* WLAN_FEATURE_FIPS */
 #else /*WLAN_FEATURE_ROAM_OFFLOAD */
 static inline
 QDF_STATUS cm_fw_roam_invoke_fail(struct wlan_objmgr_psoc *psoc,

+ 30 - 1
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -1160,6 +1160,26 @@ cm_handle_scan_ch_list_data(struct cm_roam_scan_ch_resp *data)
 #endif
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 
+#ifdef WLAN_FEATURE_FIPS
+/**
+ * cm_roam_pmkid_req_ind() - Function to handle
+ * roam event from firmware for pmkid generation.
+ * @psoc: psoc pointer
+ * @vdev_id: Vdev id
+ * @bss_list: candidate AP bssid list
+ */
+QDF_STATUS
+cm_roam_pmkid_req_ind(struct wlan_objmgr_psoc *psoc,
+		      uint8_t vdev_id, struct roam_pmkid_req_event *bss_list);
+#else /* WLAN_FEATURE_FIPS */
+static inline QDF_STATUS
+cm_roam_pmkid_req_ind(struct wlan_objmgr_psoc *psoc,
+		      uint8_t vdev_id, struct roam_pmkid_req_event *bss_list)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_FIPS */
+
 /**
  * wlan_get_chan_by_bssid_from_rnr: get chan from rnr through bssid
  * @vdev: vdev
@@ -1269,7 +1289,7 @@ void cm_handle_roam_reason_suitable_ap(uint8_t vdev_id, uint32_t rssi);
  * Return: QDF_STATUS
  */
 QDF_STATUS
-cm_roam_event_handler(struct roam_offload_roam_event roam_event);
+cm_roam_event_handler(struct roam_offload_roam_event *roam_event);
 
 /**
  * cm_btm_blacklist_event_handler() - Black list the given BSSID due to btm
@@ -1338,6 +1358,15 @@ cm_handle_auth_offload(struct auth_offload_event *auth_event);
 QDF_STATUS
 cm_roam_auth_offload_event_handler(struct auth_offload_event *auth_event);
 
+/*
+ * cm_roam_pmkid_request_handler() - Carries extracted pmkid list info
+ * @data: Pmkid event with entries
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+cm_roam_pmkid_request_handler(struct roam_pmkid_req_event *data);
+
 /**
  * cm_roam_update_vdev() - Update the STA and BSS
  * @sync_ind: Information needed for roam sync propagation

+ 36 - 11
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -1835,10 +1835,12 @@ enum cm_vdev_disconnect_reason {
 /*
  * struct vdev_disconnect_event_data - Roam disconnect event data
  * @vdev_id: vdev id
+ * @psoc: psoc object
  * @reason: roam reason of type @enum cm_vdev_disconnect_reason
  */
 struct vdev_disconnect_event_data {
 	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
 	enum cm_vdev_disconnect_reason reason;
 };
 
@@ -1855,11 +1857,26 @@ struct cm_roam_scan_ch_resp {
 	uint32_t command_resp;
 	uint32_t *chan_list;
 };
+
+/**
+ * enum roam_dispatcher_events - Roam events to post to scheduler thread
+ * @ROAM_EVENT_INVALID: Invalid event
+ * @ROAM_PMKID_REQ_EVENT: Roam pmkid request event
+ * @ROAM_EVENT: Roam event
+ * @ROAM_VDEV_DISCONNECT_EVENT: Roam disconnect event
+ */
+enum roam_dispatcher_events {
+	ROAM_EVENT_INVALID,
+	ROAM_PMKID_REQ_EVENT,
+	ROAM_EVENT,
+	ROAM_VDEV_DISCONNECT_EVENT,
+};
 #endif
 
 /**
  * struct roam_offload_roam_event: Data carried by roam event
  * @vdev_id: vdev id
+ * @psoc: psoc object
  * @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
@@ -1873,6 +1890,7 @@ struct cm_roam_scan_ch_resp {
  */
 struct roam_offload_roam_event {
 	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
 	enum roam_reason reason;
 	uint32_t rssi;
 	enum cm_roam_notif notif;
@@ -1918,6 +1936,20 @@ struct auth_offload_event {
 	struct qdf_mac_addr ap_bssid;
 };
 
+/*
+ * struct roam_pmkid_req_event - Pmkid event with entries destination structure
+ * @vdev_id: VDEV id
+ * @psoc: psoc object
+ * @num_entries: total entries sent over the event
+ * @ap_bssid: bssid list
+ */
+struct roam_pmkid_req_event {
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t num_entries;
+	struct qdf_mac_addr ap_bssid[];
+};
+
 /**
  * wlan_cm_roam_tx_ops  - structure of tx function pointers for
  * roaming related commands
@@ -2046,16 +2078,6 @@ struct cm_hw_mode_trans_ind {
 	struct policy_mgr_vdev_mac_map vdev_mac_map[MAX_VDEV_SUPPORTED];
 };
 
-/*
- * struct roam_pmkid_req_event - Pmkid event with entries destination structure
- * @num_entries: total entries sent over the event
- * @ap_bssid: bssid list
- */
-struct roam_pmkid_req_event {
-	uint32_t num_entries;
-	struct qdf_mac_addr ap_bssid[];
-};
-
 /*
  * struct ml_setup_link_param - MLO setup link param
  * @vdev_id: vdev id of the link
@@ -2150,6 +2172,7 @@ struct roam_offload_synch_ind {
  * @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
  * @roam_auth_offload_event: Rx ops function pointer for auth offload event
+ * @roam_pmkid_request_event_rx: Rx ops function pointer for roam pmkid event
  */
 struct wlan_cm_roam_rx_ops {
 	QDF_STATUS (*roam_sync_event)(struct wlan_objmgr_psoc *psoc,
@@ -2158,7 +2181,7 @@ struct wlan_cm_roam_rx_ops {
 				      struct roam_offload_synch_ind *sync_ind);
 	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);
+	QDF_STATUS (*roam_event_rx)(struct roam_offload_roam_event *roam_event);
 #ifdef ROAM_TARGET_IF_CONVERGENCE
 	QDF_STATUS (*btm_blacklist_event)(struct wlan_objmgr_psoc *psoc,
 					  struct roam_blacklist_event *list);
@@ -2171,6 +2194,8 @@ struct wlan_cm_roam_rx_ops {
 			       struct roam_stats_event *stats_info);
 	QDF_STATUS
 	(*roam_auth_offload_event)(struct auth_offload_event *auth_event);
+	QDF_STATUS
+	(*roam_pmkid_request_event_rx)(struct roam_pmkid_req_event *list);
 #endif
 };
 #endif

+ 92 - 34
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -2135,25 +2135,25 @@ QDF_STATUS wlan_cm_sta_mlme_vdev_roam_notify(struct vdev_mlme_obj *vdev_mlme,
 #ifdef ROAM_TARGET_IF_CONVERGENCE
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 static void
-cm_handle_roam_offload_events(struct roam_offload_roam_event roam_event)
+cm_handle_roam_offload_events(struct roam_offload_roam_event *roam_event)
 {
-	switch (roam_event.reason) {
+	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);
+		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);
+		cm_invalid_roam_reason_handler(roam_event->vdev_id,
+					       roam_event->notif);
 		break;
 	default:
 		break;
@@ -2171,12 +2171,27 @@ cm_roam_auth_offload_event_handler(struct auth_offload_event *auth_event)
 {
 	return cm_handle_auth_offload(auth_event);
 }
+
+QDF_STATUS
+cm_roam_pmkid_request_handler(struct roam_pmkid_req_event *data)
+{
+	QDF_STATUS status;
+
+	status = cm_roam_pmkid_req_ind(data->psoc, data->vdev_id, data);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlme_err("Pmkid request failed");
+		qdf_mem_free(data);
+		return status;
+	}
+
+	return status;
+}
 #else
 static void
-cm_handle_roam_offload_events(struct roam_offload_roam_event roam_event)
+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);
+		   roam_event->reason, roam_event->vdev_id);
 }
 
 QDF_STATUS
@@ -2184,49 +2199,55 @@ cm_vdev_disconnect_event_handler(struct vdev_disconnect_event_data *data)
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS
+cm_roam_pmkid_request_handler(struct roam_pmkid_req_event *data)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 
 QDF_STATUS
-cm_roam_event_handler(struct roam_offload_roam_event roam_event)
+cm_roam_event_handler(struct roam_offload_roam_event *roam_event)
 {
-	switch (roam_event.reason) {
+	switch (roam_event->reason) {
 	case ROAM_REASON_BTM:
-		cm_handle_roam_reason_btm(roam_event.vdev_id);
+		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);
+		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);
+		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);
+		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);
+		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);
+		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);
+		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);
+			   roam_event->reason, roam_event->vdev_id);
 		break;
 	}
 
@@ -2838,4 +2859,41 @@ err:
 	qdf_mem_free(stats_info);
 	return status;
 }
-#endif
+#endif /* ROAM_TARGET_IF_CONVERGENCE */
+
+#ifdef WLAN_FEATURE_FIPS
+QDF_STATUS cm_roam_pmkid_req_ind(struct wlan_objmgr_psoc *psoc,
+				 uint8_t vdev_id,
+				 struct roam_pmkid_req_event *src_lst)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_objmgr_vdev *vdev;
+	struct qdf_mac_addr *dst_list;
+	uint32_t num_entries, i;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_SB_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	num_entries = src_lst->num_entries;
+	mlme_debug("Num entries %d", num_entries);
+	for (i = 0; i < num_entries; i++) {
+		dst_list = &src_lst->ap_bssid[i];
+		status = mlme_cm_osif_pmksa_candidate_notify(vdev, dst_list,
+							     1, false);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			mlme_err("Number %d Notify failed for " QDF_MAC_ADDR_FMT,
+				 i, QDF_MAC_ADDR_REF(dst_list->bytes));
+			goto rel_ref;
+		}
+	}
+
+rel_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
+
+	return status;
+}
+#endif /* WLAN_FEATURE_FIPS */

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

@@ -395,6 +395,20 @@ QDF_STATUS
 wmi_extract_auth_offload_event(wmi_unified_t wmi_handle,
 			       uint8_t *event, uint32_t data_len,
 			       struct auth_offload_event *auth_event);
+
+/**
+ * wmi_extract_roam_pmkid_request - Extract roam pmkid list
+ * @wmi_handle: WMI handle
+ * @event: Event data received from firmware
+ * @data_len: Event data length received from firmware
+ * @data: Extract the event and fill in data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_extract_roam_pmkid_request(wmi_unified_t wmi_handle,
+			       uint8_t *event, uint32_t data_len,
+			       struct roam_pmkid_req_event **data);
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 

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

@@ -474,5 +474,19 @@ wmi_extract_auth_offload_event(wmi_unified_t wmi_handle,
 								   auth_event);
 	return QDF_STATUS_E_FAILURE;
 }
+
+QDF_STATUS
+wmi_extract_roam_pmkid_request(wmi_unified_t wmi_handle,
+			       uint8_t *event, uint32_t data_len,
+			       struct roam_pmkid_req_event **list)
+{
+	if (wmi_handle->ops->extract_roam_pmkid_request)
+		return wmi_handle->ops->extract_roam_pmkid_request(wmi_handle,
+								   event,
+								   data_len,
+								   list);
+
+	return QDF_STATUS_E_FAILURE;
+}
 #endif /* ROAM_TARGET_IF_CONVERGENCE */
 #endif

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

@@ -3029,6 +3029,90 @@ extract_auth_offload_event_tlv(wmi_unified_t wmi_handle,
 
 	return QDF_STATUS_SUCCESS;
 }
+
+/**
+ * extract_roam_pmkid_request_tlv() - Extract the roam pmkid request event
+ * @wmi_handle: wmi handle
+ * @evt_buf: Pointer to the event buffer
+ * @len: Data length
+ * @list: Extract the data and fill in list
+ */
+static QDF_STATUS
+extract_roam_pmkid_request_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
+			       uint32_t len,
+			       struct roam_pmkid_req_event **list)
+{
+	WMI_ROAM_PMKID_REQUEST_EVENTID_param_tlvs *param_buf;
+	wmi_roam_pmkid_request_event_fixed_param *roam_pmkid_req_ev;
+	wmi_roam_pmkid_request_tlv_param *src_list;
+	struct qdf_mac_addr *roam_bsslist;
+	uint32_t num_entries, i;
+	struct roam_pmkid_req_event *dst_list;
+
+	if (!evt_buf || !len) {
+		wmi_err("received null event from target");
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_ROAM_PMKID_REQUEST_EVENTID_param_tlvs *)evt_buf;
+	if (!param_buf) {
+		wmi_err("received null buf from target");
+		return -EINVAL;
+	}
+
+	roam_pmkid_req_ev = param_buf->fixed_param;
+	if (!roam_pmkid_req_ev) {
+		wmi_err("received null event data from target");
+		return -EINVAL;
+	}
+
+	if (roam_pmkid_req_ev->vdev_id >= WLAN_MAX_VDEVS) {
+		wmi_err_rl("Invalid vdev_id %d", roam_pmkid_req_ev->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	num_entries = param_buf->num_pmkid_request;
+	if (num_entries > MAX_RSSI_AVOID_BSSID_LIST) {
+		wmi_err("num bssid entries:%d exceeds maximum value",
+			num_entries);
+		return -EINVAL;
+	}
+
+	src_list = param_buf->pmkid_request;
+	if (len < (sizeof(*roam_pmkid_req_ev) +
+		(num_entries * sizeof(*src_list)))) {
+		wmi_err("Invalid length: %d", len);
+		return -EINVAL;
+	}
+
+	dst_list = qdf_mem_malloc(sizeof(struct roam_pmkid_req_event) +
+				  (sizeof(struct qdf_mac_addr) * num_entries));
+	if (!dst_list)
+		return -ENOMEM;
+
+	dst_list->vdev_id = roam_pmkid_req_ev->vdev_id;
+
+	for (i = 0; i < num_entries; i++) {
+		roam_bsslist = &dst_list->ap_bssid[i];
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_list->bssid,
+					   roam_bsslist->bytes);
+		if (qdf_is_macaddr_zero(roam_bsslist) ||
+		    qdf_is_macaddr_broadcast(roam_bsslist) ||
+		    qdf_is_macaddr_group(roam_bsslist)) {
+			wmi_err("Invalid bssid");
+			qdf_mem_free(dst_list);
+			return -EINVAL;
+		}
+		wmi_debug("Received pmkid fallback for bssid: " QDF_MAC_ADDR_FMT" vdev_id:%d",
+			  QDF_MAC_ADDR_REF(roam_bsslist->bytes),
+			  roam_pmkid_req_ev->vdev_id);
+		src_list++;
+	}
+	dst_list->num_entries = num_entries;
+	*list = dst_list;
+
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 
 void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
@@ -3048,6 +3132,7 @@ void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
 	ops->extract_roam_scan_chan_list = extract_roam_scan_chan_list_tlv;
 	ops->extract_roam_stats_event = extract_roam_stats_event_tlv;
 	ops->extract_auth_offload_event = extract_auth_offload_event_tlv;
+	ops->extract_roam_pmkid_request = extract_roam_pmkid_request_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 =

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

@@ -2812,8 +2812,13 @@ static int wma_wake_event_piggybacked(
 		break;
 	case WOW_REASON_ROAM_PMKID_REQUEST:
 		wma_debug("Host woken up because of PMKID request event");
+#ifndef ROAM_TARGET_IF_CONVERGENCE
 		errno = wma_roam_pmkid_request_event_handler(wma, pb_event,
 							     pb_event_len);
+#else
+		errno = target_if_pmkid_request_event_handler(wma,
+					pb_event, pb_event_len);
+#endif
 		break;
 	case WOW_REASON_VDEV_DISCONNECT:
 		wma_debug("Host woken up because of vdev disconnect event");

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

@@ -3374,8 +3374,8 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
 					   wmi_roam_auth_offload_event_id,
 					   wma_roam_auth_offload_event_handler,
 					   WMA_RX_SERIALIZER_CTX);
-#endif /* ROAM_TARGET_IF_CONVERGENCE */
 	wma_register_pmkid_req_event_handler(wma_handle);
+#endif /* ROAM_TARGET_IF_CONVERGENCE */
 
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 	wmi_unified_register_event_handler(wma_handle->wmi_handle,

+ 2 - 0
core/wma/src/wma_scan_roam.c

@@ -4861,6 +4861,7 @@ int wma_handle_btm_blacklist_event(void *handle, uint8_t *cmd_param_info,
 #endif
 
 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_FIPS)
+#ifndef ROAM_TARGET_IF_CONVERGENCE
 void wma_register_pmkid_req_event_handler(tp_wma_handle wma_handle)
 {
 	if (wma_validate_handle(wma_handle))
@@ -4955,6 +4956,7 @@ int wma_roam_pmkid_request_event_handler(void *handle, uint8_t *event,
 	return 0;
 }
 #endif
+#endif
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 #ifdef ROAM_TARGET_IF_CONVERGENCE