diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index f4b3d9ad59..c0b94ad9a2 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/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, diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 46cf08ce15..3c3c27f3f9 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/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: diff --git a/components/umac/mlme/mlo_mgr/src/wlan_mlo_link_force.c b/components/umac/mlme/mlo_mgr/src/wlan_mlo_link_force.c index 424342ba75..118e8cbeb3 100644 --- a/components/umac/mlme/mlo_mgr/src/wlan_mlo_link_force.c +++ b/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,