Browse Source

qcacld-3.0: Synchronize disconnect in RSO stop req-resp path

Host driver sends RSO stop request to firmware as part of
disconnect and waits for RSO stop response. It pauses the
disconnection and resumes once RSO stop response is received
from the firmware.
But cm_lock is not taken when disconnection is resumed from RSO
stop response path. This causes synchronization issues with
north bound thread which issued the disconnection.
Acquire cm_lock by using cm_sm_deliver_event() API to avoid
this issue.
Disconnect initiator thread and scheduler thread are
synchronized with this change. So, no need to set the RSO
state to STOPPED before sending RSO stop command to
firmware. So the change: I4d43508bdee2b33caba28579939fffdebfab121d
can be reverted.

Change-Id: Id29cd992ecd1bd75cb1b32eebb9e46ca5dcc728d
CRs-Fixed: 3285154
Srinivas Dasari 2 years ago
parent
commit
0d8db0609e

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

@@ -3701,15 +3701,6 @@ cm_roam_switch_to_rso_stop(struct wlan_objmgr_pdev *pdev,
 	switch (cur_state) {
 	case WLAN_ROAM_RSO_ENABLED:
 	case WLAN_ROAMING_IN_PROG:
-		/*
-		 * Set the roam state to RSO_STOPPED for RSO_ENABLED
-		 * and ROAMING_IN_PROGRESS. cm_roam_stop_req() has a check
-		 * for ROAM_SYNC_IN_PROGRESS and return.
-		 * This is moved here i.e. before calling cm_roam_stop_req()
-		 * as the state may get modified from another thread while
-		 * cm_roam_stop_req is sending commands to firmware.
-		 */
-		mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_STOPPED);
 	case WLAN_ROAM_SYNCH_IN_PROG:
 		status = cm_roam_stop_req(psoc, vdev_id, reason,
 					  send_resp, start_timer);
@@ -3730,11 +3721,6 @@ cm_roam_switch_to_rso_stop(struct wlan_objmgr_pdev *pdev,
 
 		return QDF_STATUS_SUCCESS;
 	}
-	/*
-	 * This shall make sure the state is set to STOPPED in
-	 * ROAM_SYNC_IN_PROGRESS state also.
-	 * No harm in setting the state again to STOPPED in other cases.
-	 */
 	mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_STOPPED);
 
 	return QDF_STATUS_SUCCESS;
@@ -7075,12 +7061,10 @@ cm_send_rso_stop(struct wlan_objmgr_vdev *vdev)
 			     &send_resp, start_timer);
 	/*
 	 * RSO stop resp is not supported or RSO STOP timer/req failed,
-	 * then send resp from here
+	 * send QDF_STATUS_E_NOSUPPORT so that we continue from the caller
 	 */
 	if (send_resp)
-		wlan_cm_rso_stop_continue_disconnect(wlan_vdev_get_psoc(vdev),
-						     wlan_vdev_get_id(vdev),
-						     false);
+		return QDF_STATUS_E_NOSUPPORT;
 
 	return QDF_STATUS_SUCCESS;
 }

+ 11 - 2
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_disconnect.c

@@ -445,7 +445,8 @@ wlan_cm_mlo_update_disconnecting_vdev_id(struct wlan_objmgr_psoc *psoc,
 
 	for (i = 0; i < num_links; i++) {
 		if (wlan_vdev_mlme_is_mlo_link_vdev(vdev_list[i]) &&
-		    wlan_cm_is_vdev_disconnecting(vdev_list[i]) &&
+		    (wlan_cm_is_vdev_disconnecting(vdev_list[i]) ||
+		     wlan_cm_is_vdev_connecting(vdev_list[i])) &&
 		    wlan_cm_get_active_req_type(vdev_list[i]) ==
 							CM_DISCONNECT_ACTIVE) {
 			/*
@@ -503,7 +504,15 @@ wlan_cm_rso_stop_continue_disconnect(struct wlan_objmgr_psoc *psoc,
 		status = QDF_STATUS_E_EXISTS;
 		goto done;
 	}
-	wlan_cm_disc_cont_after_rso_stop(vdev, is_ho_fail, req);
+
+	if (is_ho_fail) {
+		req->req.source = CM_MLME_DISCONNECT;
+		req->req.reason_code = REASON_FW_TRIGGERED_ROAM_FAILURE;
+		mlme_debug(CM_PREFIX_FMT "Updating source(%d) and reason code (%d) to RSO reason and source as ho fail is received in RSO stop",
+			   CM_PREFIX_REF(req->req.vdev_id, req->cm_id),
+			   req->req.source, req->req.reason_code);
+	}
+	wlan_cm_disc_cont_after_rso_stop(vdev, req);
 
 done:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);