Browse Source

qcacld-3.0: Cleanup link VDEV SM on roam HO failure

In case of legacy to multi-link MLO roaming, if roam sync event
handling fails, then the pe_session is deleted for the link
VDEV and the cleanup happens only for the assoc vdev. Since,
the link vdev doesn't have proper session/vdev params, the
cleanup fails in link VDEV. This leaves the link vdev in UP
state, even after disconnection. Therefore, subsequent attempts
to connect to an MLO-AP would fail since the partner link is
never cleaned up and is in invalid state(UP).

To fix this, propagate the HO-failure error through state machine
and move the VDEV SM from UP->DOWN directly.

Change-Id: I6480a1821ab4c8cf9af6cd96af0f7889307c3b18
CRs-Fixed: 3362995
Surya Prakash Sivaraj 2 years ago
parent
commit
c76288d024

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

@@ -78,7 +78,7 @@ QDF_STATUS cm_fw_roam_sync_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 				     event_data_len, event);
 
 	if (QDF_IS_STATUS_ERROR(status)) {
-		mlme_err("EV ROAM SYNC REQ not handled");
+		mlme_err("Roam sync was not handled");
 		cm_fw_roam_abort_req(psoc, vdev_id);
 		cm_roam_stop_req(psoc, vdev_id, REASON_ROAM_SYNCH_FAILED,
 				 NULL, false);

+ 1 - 1
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -3294,7 +3294,7 @@ cm_roam_stop_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 
 	if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) {
 		mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id);
-		return QDF_STATUS_SUCCESS;
+		goto rel_vdev_ref;
 	}
 
 	rso_cfg = wlan_cm_get_rso_config(vdev);

+ 9 - 6
components/umac/mlme/mlo_mgr/inc/wlan_mlo_mgr_roam.h

@@ -318,8 +318,9 @@ void mlo_roam_connect_complete(struct wlan_objmgr_psoc *psoc,
  *
  * Return: qdf status
  */
-void mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
-			 void *event, uint32_t event_data_len);
+QDF_STATUS
+mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
+		    void *event, uint32_t event_data_len);
 #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
 
 /**
@@ -397,13 +398,15 @@ mlo_roam_get_link_id(uint8_t vdev_id,
 }
 
 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
-void mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
-			 void *event, uint32_t event_data_len);
+QDF_STATUS mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
+			       void *event, uint32_t event_data_len);
 #else
-static inline void
+static inline QDF_STATUS
 mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
 		    void *event, uint32_t event_data_len)
-{}
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 
 static inline bool

+ 7 - 5
components/umac/mlme/mlo_mgr/src/wlan_mlo_mgr_roam.c

@@ -274,8 +274,8 @@ QDF_STATUS mlo_fw_roam_sync_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 }
 
 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
-void mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
-			 void *event, uint32_t event_data_len)
+QDF_STATUS mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
+			       void *event, uint32_t event_data_len)
 {
 	QDF_STATUS status;
 	struct roam_offload_synch_ind *sync_ind;
@@ -303,7 +303,7 @@ void mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
 	 * link vdev will be initialized after set key is complete.
 	 */
 	if (sync_ind->auth_status == ROAM_AUTH_STATUS_CONNECTED)
-		return;
+		return QDF_STATUS_SUCCESS;
 
 	for (i = 0; i < sync_ind->num_setup_links; i++) {
 		if (vdev_id == sync_ind->ml_link[i].vdev_id)
@@ -315,7 +315,7 @@ void mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
 
 		if (!link_vdev) {
 			mlo_err("Link vdev is null");
-			return;
+			return QDF_STATUS_E_FAILURE;
 		}
 
 		if (mlo_check_connect_req_bmap(link_vdev)) {
@@ -330,12 +330,14 @@ void mlo_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev,
 						   sync_ind->ml_link[i].vdev_id);
 				wlan_objmgr_vdev_release_ref(link_vdev,
 							     WLAN_MLME_SB_ID);
-				return;
+				return QDF_STATUS_E_FAILURE;
 			}
 		}
 		wlan_objmgr_vdev_release_ref(link_vdev,
 					     WLAN_MLME_SB_ID);
 	}
+
+	return QDF_STATUS_SUCCESS;
 }
 #endif
 

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

@@ -3021,6 +3021,7 @@ cm_roam_pe_sync_callback(struct roam_offload_synch_ind *sync_ind,
 {
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
 	struct pe_session *pe_session;
+	bool new_link_session = false;
 	QDF_STATUS status;
 
 	if (!wma)
@@ -3028,6 +3029,7 @@ cm_roam_pe_sync_callback(struct roam_offload_synch_ind *sync_ind,
 
 	pe_session = pe_find_session_by_vdev_id(wma->mac_context, vdev_id);
 	if (!pe_session) {
+		new_link_session = true;
 		/* Legacy to MLO roaming: create new pe session */
 		status = lim_create_and_fill_link_session(wma->mac_context,
 							  vdev_id,
@@ -3043,6 +3045,13 @@ cm_roam_pe_sync_callback(struct roam_offload_synch_ind *sync_ind,
 				vdev_id, sync_ind, ie_len,
 				SIR_ROAM_SYNCH_PROPAGATION);
 
+	/* delete newly added pe session in case of failure */
+	if (new_link_session && QDF_IS_STATUS_ERROR(status)) {
+		pe_session = pe_find_session_by_vdev_id(wma->mac_context,
+							vdev_id);
+		if (pe_session)
+			pe_delete_session(wma->mac_context, pe_session);
+	}
 	return status;
 }