Browse Source

qcacmn: Handle MLO peer attach failures on connect or roam

If MLO peer attach fails for MLO VDEV, handle the failure and
remove the object manager peer and continue for next candidate
incase of initial connection.

Change-Id: Iba374f9b930db07bde84cea1cb18d36a0960c5b7
CRs-Fixed: 3844761
Vinod Kumar Pirla 1 năm trước cách đây
mục cha
commit
eb34a521c0

+ 45 - 0
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -3275,6 +3275,44 @@ post_err:
 	return qdf_status;
 }
 
+#if defined(CONN_MGR_ADV_FEATURE) && defined(WLAN_FEATURE_11BE_MLO)
+QDF_STATUS cm_bss_peer_create_resp_mlo_attach(struct wlan_objmgr_vdev *vdev,
+					      struct qdf_mac_addr *peer_mac)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_peer *link_peer;
+	struct mlo_partner_info partner_info;
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
+		return QDF_STATUS_SUCCESS;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	link_peer = wlan_objmgr_get_peer_by_mac(psoc, (uint8_t *)peer_mac,
+						WLAN_MLME_CM_ID);
+	if (!link_peer)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	partner_info.num_partner_links = 1;
+	qdf_mem_copy(partner_info.partner_link_info[0].link_addr.bytes,
+		     vdev->vdev_mlme.macaddr, QDF_MAC_ADDR_SIZE);
+	partner_info.partner_link_info[0].link_id = wlan_vdev_get_link_id(vdev);
+
+	status = wlan_mlo_peer_create(vdev, link_peer, &partner_info, NULL, 0);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlme_err("Failed to attach MLO peer " QDF_MAC_ADDR_FMT,
+			 QDF_MAC_ADDR_REF(peer_mac->bytes));
+	}
+
+	wlan_objmgr_peer_release_ref(link_peer, WLAN_MLME_CM_ID);
+
+	return status;
+}
+#endif
+
 QDF_STATUS cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev,
 				  QDF_STATUS status,
 				  struct qdf_mac_addr *peer_mac)
@@ -3300,6 +3338,12 @@ QDF_STATUS cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev,
 	}
 
 	if (QDF_IS_STATUS_SUCCESS(status)) {
+		qdf_status = cm_bss_peer_create_resp_mlo_attach(vdev, peer_mac);
+		if (QDF_IS_STATUS_ERROR(qdf_status)) {
+			mlme_cm_bss_peer_delete_req(vdev);
+			goto next_candidate;
+		}
+
 		qdf_status =
 			cm_sm_deliver_event(vdev,
 					  WLAN_CM_SM_EV_BSS_CREATE_PEER_SUCCESS,
@@ -3311,6 +3355,7 @@ QDF_STATUS cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev,
 		goto post_err;
 	}
 
+next_candidate:
 	/* In case of failure try with next candidate */
 	resp = qdf_mem_malloc(sizeof(*resp));
 	if (!resp) {

+ 23 - 16
umac/mlme/connection_mgr/core/src/wlan_cm_host_roam.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -898,26 +898,33 @@ QDF_STATUS cm_roam_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev,
 		return QDF_STATUS_E_INVAL;
 	}
 
-	if (QDF_IS_STATUS_ERROR(status)) {
-		cm_req = cm_get_req_by_cm_id(cm_ctx, cm_id);
-		if (!cm_req)
-			return QDF_STATUS_E_INVAL;
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		qdf_status = cm_bss_peer_create_resp_mlo_attach(vdev, peer_mac);
+		if (QDF_IS_STATUS_ERROR(qdf_status)) {
+			mlme_cm_bss_peer_delete_req(vdev);
+			goto send_err;
+		}
 
-		return cm_send_reassoc_start_fail(
-				cm_ctx, cm_id,
-				CM_PEER_CREATE_FAILED, false);
-	}
+		qdf_status =
+		    cm_sm_deliver_event(vdev,
+					WLAN_CM_SM_EV_BSS_CREATE_PEER_SUCCESS,
+					sizeof(wlan_cm_id), &cm_id);
+
+		if (QDF_IS_STATUS_ERROR(qdf_status)) {
+			mlme_cm_bss_peer_delete_req(vdev);
+			cm_reassoc_handle_event_post_fail(cm_ctx, cm_id);
+		}
 
-	qdf_status = cm_sm_deliver_event(
-			vdev, WLAN_CM_SM_EV_BSS_CREATE_PEER_SUCCESS,
-			sizeof(wlan_cm_id), &cm_id);
-	if (QDF_IS_STATUS_SUCCESS(qdf_status))
 		return qdf_status;
+	}
 
-	mlme_cm_bss_peer_delete_req(vdev);
-	cm_reassoc_handle_event_post_fail(cm_ctx, cm_id);
+send_err:
+	cm_req = cm_get_req_by_cm_id(cm_ctx, cm_id);
+	if (!cm_req)
+		return QDF_STATUS_E_INVAL;
 
-	return qdf_status;
+	return cm_send_reassoc_start_fail(cm_ctx, cm_id,
+					  CM_PEER_CREATE_FAILED, false);
 }
 
 QDF_STATUS cm_roam_disconnect_rsp(struct wlan_objmgr_vdev *vdev,

+ 22 - 0
umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h

@@ -219,6 +219,28 @@ QDF_STATUS cm_try_next_candidate(struct cnx_mgr *cm_ctx,
 QDF_STATUS
 cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id);
 
+#if defined(CONN_MGR_ADV_FEATURE) && defined(WLAN_FEATURE_11BE_MLO)
+/**
+ * cm_bss_peer_create_resp_mlo_attach() - Create MLO peer and attach objmgr peer
+ * @vdev: VDEV object manager pointer
+ * @peer_mac: MAC addr pointer for BSS peer created
+ *
+ * Creates MLO peer for the peer with @peer_mac and adds the objmgr peer to
+ * the created MLO peer context and holds reference for the MLO peer.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cm_bss_peer_create_resp_mlo_attach(struct wlan_objmgr_vdev *vdev,
+					      struct qdf_mac_addr *peer_mac);
+#else
+static inline QDF_STATUS
+cm_bss_peer_create_resp_mlo_attach(struct wlan_objmgr_vdev *vdev,
+				   struct qdf_mac_addr *peer_mac)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 /**
  * cm_bss_peer_create_rsp() - handle bss peer create response
  * @vdev: vdev