浏览代码

qcacld-3.0: Set the RSO state before sending cmds to firmware

Currently, switch_to_rso_stop happens based on the
current state check and the expected state is
RSO_ENABLED/ROAMING_IN_PROGRESS/ROAM_SYNC_IN_PROGRESS.
The thread(e.g. user thread) that is sending rso_stop to
firmware might have got the expected state value when
it has read the state and proceeded with commands needed
to send to firmware. ROAM_SCAN_MODE is one of these commands
and firmware sends a response for the same. The response
gets processed in scheduler thread.

The expected sequence as per the current implementation is,
1. Check the current RSO state and proceed if it's any of
   RSO_ENABLED/ROAMING_IN_PROGRESS/ROAM_SYNC_IN_PROGRESS.
2. Send all commands corresponds to switch_to_rso_stop to fw
3. Set the new state to RSO_STOPPED
4. In scheduler thread, get response for
   ROAM_SCAN_MODE(one of the commands sent in step2) and
   proceed from RSO state RSO_STOPPED
5. scheduler thread sets the state to DEINIT.

But the user thread may get suspended while sending commands
to firmware (step2) and may get resumed after step4. The new
sequence could be,
1. Check the current RSO state and proceed if it's any of
   RSO_ENABLED/ROAMING_IN_PROGRESS/ROAM_SYNC_IN_PROGRESS.
2. Send some commands corresponds to switch_to_rso_stop and
   thread gets suspended. Assume it has sent ROAM_SCAN_MODE.
3. In scheduler thread, get response for
   ROAM_SCAN_MODE(one of the commands sent in step2) and
   proceed from RSO state RSO_ENABLED.
4. As part of step-3, scheduler thread moves the state to
   RSO_STOPPED and then to RSO_DEINIT.
5. User thread gets resumed and sets the new state
   to RSO_STOPPED. This leaves the RSO state in invalid
   state even after disconnect.

Set the state to RSO_STOPPED before sending any commands
to firmware. This is to ensure the state is not corrupted by
the scheduler thread.

Change-Id: I4d43508bdee2b33caba28579939fffdebfab121d
CRs-Fixed: 3278047
Srinivas Dasari 2 年之前
父节点
当前提交
e85f7f098c
共有 1 个文件被更改,包括 14 次插入0 次删除
  1. 14 0
      components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

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

@@ -3701,6 +3701,15 @@ 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);
@@ -3721,6 +3730,11 @@ 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;