diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h index 9b46bd0b83..cb2135b0e2 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h @@ -129,11 +129,14 @@ enum sap_csa_reason_code { * @link_ctrl_f_dynamic_force_link_num: indicate fw to use force link number * instead of force link bitmaps. Used with MLO_LINK_FORCE_MODE_ACTIVE_NUM. * MLO_LINK_FORCE_MODE_INACTIVE_NUM, MLO_LINK_FORCE_MODE_NO_FORCE. + * @link_ctrl_f_post_re_evaluate: run link state check again after command + * response handled. */ enum link_control_flags { link_ctrl_f_overwrite_active_bitmap = 1 << 0, link_ctrl_f_overwrite_inactive_bitmap = 1 << 1, link_ctrl_f_dynamic_force_link_num = 1 << 2, + link_ctrl_f_post_re_evaluate = 1 << 3, }; /** 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 f6faec2b8b..c4ed51eeb4 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 @@ -4714,6 +4714,7 @@ policy_mgr_handle_link_enable_disable_resp(struct wlan_objmgr_vdev *vdev, struct mlo_link_set_active_req *req = arg; struct wlan_objmgr_psoc *psoc; struct policy_mgr_psoc_priv_obj *pm_ctx; + QDF_STATUS status = QDF_STATUS_SUCCESS; psoc = wlan_vdev_get_psoc(vdev); if (!psoc) { @@ -4776,10 +4777,17 @@ policy_mgr_handle_link_enable_disable_resp(struct wlan_objmgr_vdev *vdev, complete_evnt: policy_mgr_set_link_in_progress(pm_ctx, false); + if (ml_is_nlink_service_supported(psoc) && + req && resp && !resp->status && + req->param.control_flags.post_re_evaluate) + status = ml_nlink_conn_change_notify( + psoc, wlan_vdev_get_id(vdev), + ml_nlink_connection_updated_evt, NULL); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* reschedule force scc workqueue after link state changes */ - if (req && resp && !resp->status) + if (req && resp && !resp->status && + status == QDF_STATUS_SUCCESS) policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false); } #else @@ -6300,6 +6308,8 @@ policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc, true; if (link_control_flags & link_ctrl_f_dynamic_force_link_num) req->param.control_flags.dynamic_force_link_num = true; + if (link_control_flags & link_ctrl_f_post_re_evaluate) + req->param.control_flags.post_re_evaluate = true; status = wlan_vdev_get_bss_peer_mld_mac(vdev, diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c index b6ad46995d..7e465ff6b6 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c @@ -1086,9 +1086,10 @@ QDF_STATUS cm_connect_start_ind(struct wlan_objmgr_vdev *vdev, wlan_vdev_get_id(vdev), HS_20_AP, &src_cfg); } - ml_nlink_conn_change_notify( - psoc, wlan_vdev_get_id(vdev), - ml_nlink_connect_start_evt, NULL); + if (req->source != CM_MLO_LINK_SWITCH_CONNECT) + ml_nlink_conn_change_notify( + psoc, wlan_vdev_get_id(vdev), + ml_nlink_connect_start_evt, NULL); return QDF_STATUS_SUCCESS; } diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_disconnect.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_disconnect.c index 1b2b37a440..24cfdcac76 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_disconnect.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_disconnect.c @@ -75,9 +75,10 @@ QDF_STATUS cm_disconnect_start_ind(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_INVAL; } mlo_sta_stop_reconfig_timer(vdev); - ml_nlink_conn_change_notify( - psoc, wlan_vdev_get_id(vdev), - ml_nlink_disconnect_start_evt, NULL); + if (req->source != CM_MLO_LINK_SWITCH_DISCONNECT) + ml_nlink_conn_change_notify( + psoc, wlan_vdev_get_id(vdev), + ml_nlink_disconnect_start_evt, NULL); if (cm_csr_is_ss_wait_for_key(req->vdev_id)) { mlme_debug("Stop Wait for key timer"); cm_stop_wait_for_key_timer(psoc, req->vdev_id); 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 709b496237..f210a661c6 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 @@ -428,13 +428,15 @@ bool ml_is_nlink_service_supported(struct wlan_objmgr_psoc *psoc) } /* Exclude AP removed link */ -#define NLINK_EXCLUDE_REMOVED_LINK 0x01 +#define NLINK_EXCLUDE_REMOVED_LINK 0x01 /* Include AP removed link only, can't work with other flags */ #define NLINK_INCLUDE_REMOVED_LINK_ONLY 0x02 /* Exclude QUITE link */ -#define NLINK_EXCLUDE_QUIET_LINK 0x04 +#define NLINK_EXCLUDE_QUIET_LINK 0x04 /* Exclude standby link information */ -#define NLINK_EXCLUDE_STANDBY_LINK 0x08 +#define NLINK_EXCLUDE_STANDBY_LINK 0x08 +/* Dump link information */ +#define NLINK_DUMP_LINK 0x10 static void ml_nlink_get_standby_link_info(struct wlan_objmgr_psoc *psoc, @@ -500,12 +502,12 @@ ml_nlink_get_standby_link_info(struct wlan_objmgr_psoc *psoc, ml_vdev_lst[*ml_num_link] = WLAN_INVALID_VDEV_ID; ml_linkid_lst[*ml_num_link] = link_info->link_id; *ml_link_bitmap |= 1 << link_info->link_id; - - mlo_debug("vdev %d link %d freq %d bitmap 0x%x flag 0x%x", - ml_vdev_lst[*ml_num_link], - ml_linkid_lst[*ml_num_link], - ml_freq_lst[*ml_num_link], - *ml_link_bitmap, flag); + if (flag & NLINK_DUMP_LINK) + mlo_debug("vdev %d link %d freq %d bitmap 0x%x flag 0x%x", + ml_vdev_lst[*ml_num_link], + ml_linkid_lst[*ml_num_link], + ml_freq_lst[*ml_num_link], + *ml_link_bitmap, flag); (*ml_num_link)++; } @@ -615,10 +617,11 @@ static void ml_nlink_get_link_info(struct wlan_objmgr_psoc *psoc, ml_vdev_lst[num_link] = vdev_id; ml_linkid_lst[num_link] = link_id; link_bitmap |= 1 << link_id; - - mlo_debug("vdev %d link %d freq %d bitmap 0x%x flag 0x%x", - ml_vdev_lst[num_link], ml_linkid_lst[num_link], - ml_freq_lst[num_link], link_bitmap, flag); + if (flag & NLINK_DUMP_LINK) + mlo_debug("vdev %d link %d freq %d bitmap 0x%x flag 0x%x", + ml_vdev_lst[num_link], + ml_linkid_lst[num_link], + ml_freq_lst[num_link], link_bitmap, flag); num_link++; } /* Add standby link only if mlo sta is connected */ @@ -716,7 +719,8 @@ ml_nlink_handle_mcc_links(struct wlan_objmgr_psoc *psoc, uint8_t ml_linkid_lst[MAX_NUMBER_OF_CONC_CONNECTIONS]; struct ml_link_info ml_link_info[MAX_NUMBER_OF_CONC_CONNECTIONS]; - ml_nlink_get_link_info(psoc, vdev, NLINK_INCLUDE_REMOVED_LINK_ONLY, + ml_nlink_get_link_info(psoc, vdev, NLINK_INCLUDE_REMOVED_LINK_ONLY | + NLINK_DUMP_LINK, QDF_ARRAY_SIZE(ml_linkid_lst), ml_link_info, ml_freq_lst, ml_vdev_lst, ml_linkid_lst, &ml_num_link, @@ -727,7 +731,8 @@ ml_nlink_handle_mcc_links(struct wlan_objmgr_psoc *psoc, mlo_debug("AP removed link 0x%x", force_inactive_link_bitmap); } - ml_nlink_get_link_info(psoc, vdev, NLINK_EXCLUDE_REMOVED_LINK, + ml_nlink_get_link_info(psoc, vdev, NLINK_EXCLUDE_REMOVED_LINK | + NLINK_DUMP_LINK, QDF_ARRAY_SIZE(ml_linkid_lst), ml_link_info, ml_freq_lst, ml_vdev_lst, ml_linkid_lst, &ml_num_link, @@ -1683,7 +1688,9 @@ ml_nlink_update_force_inactive(struct wlan_objmgr_psoc *psoc, MLO_LINK_FORCE_MODE_INACTIVE, 0, new->force_inactive_bitmap, - 0, link_ctrl_f_overwrite_inactive_bitmap); + 0, + link_ctrl_f_overwrite_inactive_bitmap | + link_ctrl_f_post_re_evaluate); } end: @@ -1709,7 +1716,8 @@ ml_nlink_update_force_inactive_num(struct wlan_objmgr_psoc *psoc, new->force_inactive_num, new->force_inactive_num_bitmap, 0, - link_ctrl_f_dynamic_force_link_num); + link_ctrl_f_dynamic_force_link_num | + link_ctrl_f_post_re_evaluate); } return status; @@ -1785,6 +1793,12 @@ static QDF_STATUS ml_nlink_state_change(struct wlan_objmgr_psoc *psoc, goto end; if (!mlo_check_if_all_links_up(vdev)) goto end; + if (mlo_mgr_is_link_switch_in_progress(vdev) && + evt != ml_nlink_connect_completion_evt) { + mlo_debug("mlo vdev %d link switch in progress!", + wlan_vdev_get_id(vdev)); + goto end; + } ml_nlink_get_curr_force_state(psoc, vdev, &curr_force_state);