Răsfoiți Sursa

qcacmn: Cleanup link vdev SM on roam HO failure

In legacy to MLO roaming case, the link vdev will be
moved from INIT->UP via EV_ROAM event. Similarly, if
the Hand-off fails in host due to host-related handling,
treat the failure as HO-FAILURE and move the link VDEV
SM from UP->INIT directly.

Change-Id: Ia6bfeb958f0302a934d24c9b40fadd4a8f557236
CRs-Fixed: 3389148
Surya Prakash Sivaraj 2 ani în urmă
părinte
comite
c595a4abdf

+ 17 - 7
umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2015,2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 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
@@ -78,8 +78,10 @@ bool cm_handle_fw_roaming_event(struct cnx_mgr *cm_ctx, uint16_t event,
 		break;
 	case WLAN_CM_SM_EV_ROAM_SYNC:
 		cm_sm_transition_to(cm_ctx, WLAN_CM_SS_ROAM_SYNC);
-		cm_sm_deliver_event_sync(cm_ctx, event,
-					 data_len, data);
+		status = cm_sm_deliver_event_sync(cm_ctx, event,
+						  data_len, data);
+		if (QDF_IS_STATUS_ERROR(status))
+			event_handled = false;
 		break;
 	default:
 		event_handled = false;
@@ -390,6 +392,7 @@ bool cm_subst_roam_start_event(void *ctx, uint16_t event,
 {
 	bool event_handled = true;
 	struct cnx_mgr *cm_ctx = ctx;
+	QDF_STATUS status;
 
 	switch (event) {
 	case WLAN_CM_SM_EV_CONNECT_REQ:
@@ -414,8 +417,10 @@ bool cm_subst_roam_start_event(void *ctx, uint16_t event,
 		break;
 	case WLAN_CM_SM_EV_ROAM_SYNC:
 		cm_sm_transition_to(cm_ctx, WLAN_CM_SS_ROAM_SYNC);
-		cm_sm_deliver_event_sync(cm_ctx, event,
-					 data_len, data);
+		status = cm_sm_deliver_event_sync(cm_ctx, event,
+						  data_len, data);
+		if (QDF_IS_STATUS_ERROR(status))
+			event_handled = false;
 		break;
 	default:
 		event_handled = false;
@@ -444,6 +449,7 @@ bool cm_subst_roam_sync_event(void *ctx, uint16_t event,
 {
 	bool event_handled = true;
 	struct cnx_mgr *cm_ctx = ctx;
+	QDF_STATUS status;
 
 	switch (event) {
 	case WLAN_CM_SM_EV_CONNECT_REQ:
@@ -455,9 +461,13 @@ bool cm_subst_roam_sync_event(void *ctx, uint16_t event,
 		break;
 	case WLAN_CM_SM_EV_ROAM_SYNC:
 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
-		mlo_cm_roam_sync_cb(cm_ctx->vdev, data, data_len);
+		status = mlo_cm_roam_sync_cb(cm_ctx->vdev, data, data_len);
+		if (QDF_IS_STATUS_ERROR(status))
+			event_handled = false;
 #endif
-		cm_fw_send_vdev_roam_event(cm_ctx, data_len, data);
+		status = cm_fw_send_vdev_roam_event(cm_ctx, data_len, data);
+		if (QDF_IS_STATUS_ERROR(status))
+			event_handled = false;
 		break;
 	case WLAN_CM_SM_EV_ROAM_DONE:
 		cm_sm_transition_to(cm_ctx, WLAN_CM_S_CONNECTED);

+ 11 - 4
umac/mlme/connection_mgr/core/src/wlan_cm_sm.c

@@ -131,9 +131,13 @@ static bool cm_state_init_event(void *ctx, uint16_t event,
 		 */
 		if (wlan_vdev_mlme_is_mlo_link_vdev(cm_ctx->vdev)) {
 			cm_sm_transition_to(cm_ctx, WLAN_CM_S_CONNECTED);
-			cm_sm_deliver_event_sync(cm_ctx,
-						 WLAN_CM_SM_EV_ROAM_SYNC,
-						 data_len, data);
+			status = cm_sm_deliver_event_sync(cm_ctx,
+							  WLAN_CM_SM_EV_ROAM_SYNC,
+							  data_len, data);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				cm_sm_transition_to(cm_ctx, WLAN_CM_S_INIT);
+				event_handled = false;
+			}
 		} else {
 			event_handled = false;
 		}
@@ -279,7 +283,10 @@ bool cm_handle_fw_roam_connected_event(struct cnx_mgr *cm_ctx, uint16_t event,
 			break;
 		}
 		cm_sm_transition_to(cm_ctx, WLAN_CM_S_ROAMING);
-		cm_sm_deliver_event_sync(cm_ctx, event, data_len, data);
+		status = cm_sm_deliver_event_sync(cm_ctx, event, data_len,
+						  data);
+		if (QDF_IS_STATUS_ERROR(status))
+			event_handled = false;
 		break;
 	case WLAN_CM_SM_EV_ROAM_DONE:
 		cm_fw_roam_complete(cm_ctx, data);

+ 22 - 9
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c

@@ -156,6 +156,7 @@ static bool mlme_vdev_state_init_event(void *ctx, uint16_t event,
 	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
 	bool status;
 	enum QDF_OPMODE mode;
+	QDF_STATUS sm_status;
 
 	mode = wlan_vdev_mlme_get_opmode(vdev_mlme->vdev);
 
@@ -211,9 +212,17 @@ static bool mlme_vdev_state_init_event(void *ctx, uint16_t event,
 		 */
 		if (wlan_vdev_mlme_is_mlo_link_vdev(vdev_mlme->vdev)) {
 			mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP);
-			mlme_vdev_sm_deliver_event(vdev_mlme, event,
-						   event_data_len, event_data);
-			status = true;
+			sm_status = mlme_vdev_sm_deliver_event(vdev_mlme, event,
+							       event_data_len,
+							       event_data);
+			status = !sm_status;
+			/*
+			 * Error in handling link-vdev roam event, move the
+			 * SM back to INIT.
+			 */
+			if (QDF_IS_STATUS_ERROR(sm_status))
+				mlme_vdev_sm_transition_to(vdev_mlme,
+							   WLAN_VDEV_S_INIT);
 		} else {
 			status = false;
 		}
@@ -468,6 +477,7 @@ static bool mlme_vdev_state_up_event(void *ctx, uint16_t event,
 	enum QDF_OPMODE mode;
 	struct wlan_objmgr_vdev *vdev;
 	bool status;
+	QDF_STATUS sm_status;
 
 	vdev = vdev_mlme->vdev;
 	mode = wlan_vdev_mlme_get_opmode(vdev);
@@ -509,9 +519,10 @@ static bool mlme_vdev_state_up_event(void *ctx, uint16_t event,
 		if (wlan_vdev_mlme_is_mlo_link_vdev(vdev_mlme->vdev)) {
 			mlme_vdev_sm_transition_to(vdev_mlme,
 						   WLAN_VDEV_SS_UP_ACTIVE);
-			mlme_vdev_sm_deliver_event(vdev_mlme, event,
-						   event_data_len, event_data);
-			status = true;
+			sm_status = mlme_vdev_sm_deliver_event(vdev_mlme, event,
+							       event_data_len,
+							       event_data);
+			status = !sm_status;
 		} else {
 			status = false;
 		}
@@ -1837,6 +1848,7 @@ static bool mlme_vdev_subst_up_active_event(void *ctx, uint16_t event,
 	enum QDF_OPMODE mode;
 	struct wlan_objmgr_vdev *vdev;
 	bool status;
+	QDF_STATUS sm_status;
 
 	vdev = vdev_mlme->vdev;
 	mode = wlan_vdev_mlme_get_opmode(vdev);
@@ -1915,9 +1927,10 @@ static bool mlme_vdev_subst_up_active_event(void *ctx, uint16_t event,
 		break;
 
 	case WLAN_VDEV_SM_EV_ROAM:
-		mlme_vdev_notify_roam_start(vdev_mlme, event_data_len,
-					    event_data);
-		status = true;
+		sm_status = mlme_vdev_notify_roam_start(vdev_mlme,
+							event_data_len,
+							event_data);
+		status = !sm_status;
 		break;
 
 	default: