Browse Source

qcacld-3.0: Clear force active bitmap before exit eMLSR

If any force active link bitmap is present, we have
to clear the force active bitmap from target. Otherwise
that will be conflict with the force inactive num bitmap,
then target can't handle force inactive num 1 command to
exit EMLSR.

Change-Id: Ia3fbcc3ca188ce1e1c93f4d0b0439ac126aeb8cb
CRs-Fixed: 3616604
Liangwei Dong 1 year ago
parent
commit
24d789f53e

+ 2 - 2
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -1164,7 +1164,7 @@ polic_mgr_send_pcl_to_fw(struct wlan_objmgr_psoc *psoc,
  * policy_mgr_mlo_sta_set_nlink() - Set link mode for MLO STA
  * by link id bitmap
  * @psoc: psoc object
- * @vdev: vdev object
+ * @vdev_id: vdev id
  * @reason: reason to set
  * @mode: mode to set
  * @link_num: number of link, valid for mode:
@@ -1183,7 +1183,7 @@ polic_mgr_send_pcl_to_fw(struct wlan_objmgr_psoc *psoc,
  */
 QDF_STATUS
 policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc,
-			     struct wlan_objmgr_vdev *vdev,
+			     uint8_t vdev_id,
 			     enum mlo_link_force_reason reason,
 			     enum mlo_link_force_mode mode,
 			     uint8_t link_num,

+ 86 - 10
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -6142,7 +6142,8 @@ policy_mgr_mlo_sta_set_link_by_linkid(struct wlan_objmgr_psoc *psoc,
 		return QDF_STATUS_E_INVAL;
 	}
 
-	return policy_mgr_mlo_sta_set_nlink(psoc, vdev, reason, mode,
+	return policy_mgr_mlo_sta_set_nlink(psoc, wlan_vdev_get_id(vdev),
+					    reason, mode,
 					    link_num, link_bitmap,
 					    link_bitmap2, link_control_flags);
 }
@@ -6281,7 +6282,7 @@ policy_mgr_mlo_sta_set_link(struct wlan_objmgr_psoc *psoc,
 
 QDF_STATUS
 policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc,
-			     struct wlan_objmgr_vdev *vdev,
+			     uint8_t vdev_id,
 			     enum mlo_link_force_reason reason,
 			     enum mlo_link_force_mode mode,
 			     uint8_t link_num,
@@ -6292,6 +6293,7 @@ policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc,
 	struct mlo_link_set_active_req *req;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
@@ -6303,10 +6305,15 @@ policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc,
 	if (!req)
 		return QDF_STATUS_E_NOMEM;
 
-	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_POLICY_MGR_ID);
-	if (QDF_IS_STATUS_ERROR(status)) {
+	vdev =
+	wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+					     vdev_id,
+					     WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d",
+			       vdev_id);
 		qdf_mem_free(req);
-		return QDF_STATUS_E_FAILURE;
+		return QDF_STATUS_E_INVAL;
 	}
 
 	policy_mgr_set_link_in_progress(pm_ctx, true);
@@ -6839,6 +6846,63 @@ end:
 	return emlsr_connection;
 }
 
+static void policy_mgr_restore_no_force(struct wlan_objmgr_psoc *psoc,
+					uint8_t num_mlo,
+					uint8_t mlo_vdev_lst[],
+					bool conc_con_coming_up)
+{
+	struct ml_link_force_state force_cmd = {0};
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (num_mlo < 1) {
+		policy_mgr_err("invalid num_mlo %d",
+			       num_mlo);
+		return;
+	}
+
+	vdev =
+	wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+					     mlo_vdev_lst[0],
+					     WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d",
+			       mlo_vdev_lst[0]);
+		return;
+	}
+
+	ml_nlink_get_curr_force_state(psoc, vdev, &force_cmd);
+	if (!conc_con_coming_up || force_cmd.force_active_bitmap) {
+		if (ml_is_nlink_service_supported(psoc))
+			status = policy_mgr_mlo_sta_set_nlink(
+					psoc, mlo_vdev_lst[0],
+					MLO_LINK_FORCE_REASON_DISCONNECT,
+					MLO_LINK_FORCE_MODE_NO_FORCE,
+					0, 0, 0, 0);
+		else
+			status = policy_mgr_mlo_sta_set_link(
+					psoc,
+					MLO_LINK_FORCE_REASON_DISCONNECT,
+					MLO_LINK_FORCE_MODE_NO_FORCE,
+					num_mlo, mlo_vdev_lst);
+		/* If concurrency vdev is coming up and force active bitmap
+		 * is present, we need to wait for the respone of no force
+		 * command.
+		 */
+		if (force_cmd.force_active_bitmap && conc_con_coming_up) {
+			if (status == QDF_STATUS_E_PENDING)
+				policy_mgr_wait_for_set_link_update(psoc);
+			else
+				policy_mgr_err("status %d", status);
+
+			ml_nlink_get_curr_force_state(psoc, vdev, &force_cmd);
+			ml_nlink_dump_force_state(&force_cmd, "");
+		}
+	}
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
 void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc,
 					     bool conc_con_coming_up,
 					     bool emlsr_sta_coming_up)
@@ -6879,6 +6943,18 @@ void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc,
 	if (conc_con_coming_up ||
 	    (emlsr_sta_coming_up &&
 	     policy_mgr_get_connection_count(psoc) > 2)) {
+		/*
+		 * If any force active link bitmap is present, we have to
+		 * clear the force active bitmap from target. Otherwise that
+		 * will be conflict with the force inactive num bitmap, then
+		 * target can't handle force inactive num 1 command to exit
+		 * EMLSR.
+		 */
+		if (conc_con_coming_up)
+			policy_mgr_restore_no_force(psoc, num_mlo,
+						    mlo_vdev_lst,
+						    conc_con_coming_up);
+
 		/*
 		 * Force disable one of the links (FW will decide which link) if
 		 * 1) EMLSR STA is present and SAP/STA/NAN connection comes up.
@@ -6901,10 +6977,9 @@ void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc,
 		 *    EMLSR capable. One of the links was disabled after EMLSR
 		 *    association.
 		 */
-		policy_mgr_mlo_sta_set_link(psoc,
-					    MLO_LINK_FORCE_REASON_DISCONNECT,
-					    MLO_LINK_FORCE_MODE_NO_FORCE,
-					    num_mlo, mlo_vdev_lst);
+		policy_mgr_restore_no_force(psoc, num_mlo,
+					    mlo_vdev_lst,
+					    conc_con_coming_up);
 }
 
 bool
@@ -8316,7 +8391,8 @@ void policy_mgr_activate_mlo_links_nlink(struct wlan_objmgr_psoc *psoc,
 		link_ctrl_flags = link_ctrl_f_overwrite_active_bitmap;
 	}
 
-	policy_mgr_mlo_sta_set_nlink(psoc, vdev, reason, mode, 0,
+	policy_mgr_mlo_sta_set_nlink(psoc, wlan_vdev_get_id(vdev),
+				     reason, mode, 0,
 				     active_link_bitmap, inactive_link_bitmap,
 				     link_ctrl_flags);
 done:

+ 4 - 3
components/umac/mlme/mlo_mgr/src/wlan_mlo_link_force.c

@@ -1683,7 +1683,8 @@ ml_nlink_update_no_force_for_all(struct wlan_objmgr_psoc *psoc,
 		}
 
 		status = policy_mgr_mlo_sta_set_nlink(
-						psoc, vdev, reason,
+						psoc, wlan_vdev_get_id(vdev),
+						reason,
 						MLO_LINK_FORCE_MODE_NO_FORCE,
 						0, 0, 0, 0);
 	}
@@ -1717,7 +1718,7 @@ ml_nlink_update_force_inactive(struct wlan_objmgr_psoc *psoc,
 			goto end;
 		}
 		status = policy_mgr_mlo_sta_set_nlink(
-				psoc, vdev, reason,
+				psoc, wlan_vdev_get_id(vdev), reason,
 				MLO_LINK_FORCE_MODE_INACTIVE,
 				0,
 				new->force_inactive_bitmap,
@@ -1744,7 +1745,7 @@ ml_nlink_update_force_inactive_num(struct wlan_objmgr_psoc *psoc,
 	    new->force_inactive_num_bitmap !=
 			curr->force_inactive_num_bitmap) {
 		status = policy_mgr_mlo_sta_set_nlink(
-					psoc, vdev, reason,
+					psoc, wlan_vdev_get_id(vdev), reason,
 					MLO_LINK_FORCE_MODE_INACTIVE_NUM,
 					new->force_inactive_num,
 					new->force_inactive_num_bitmap,