diff --git a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c index 2a901d87bf..add2be80e9 100644 --- a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c +++ b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c @@ -50,7 +50,7 @@ QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev, if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE || wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) - wlan_handle_emlsr_sta_concurrency(vdev, true, false); + wlan_handle_emlsr_sta_concurrency(vdev, true, false, false); if (policy_mgr_is_hw_mode_change_in_progress(psoc)) { if (!QDF_IS_STATUS_SUCCESS( @@ -132,7 +132,7 @@ if_mgr_ap_stop_bss_complete(struct wlan_objmgr_vdev *vdev, if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE || wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) - wlan_handle_emlsr_sta_concurrency(vdev, false, false); + wlan_handle_emlsr_sta_concurrency(vdev, false, false, true); /* * Due to audio share glitch with P2P GO caused by * roam scan on concurrent interface, disable diff --git a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c index 75f74d4ee7..6b32639c13 100644 --- a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c +++ b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c @@ -72,7 +72,7 @@ QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev, op_mode = wlan_vdev_mlme_get_opmode(vdev); if (op_mode == QDF_STA_MODE || op_mode == QDF_P2P_CLIENT_MODE) - wlan_handle_emlsr_sta_concurrency(vdev, false, true); + wlan_handle_emlsr_sta_concurrency(vdev, false, true, false); if (op_mode == QDF_P2P_CLIENT_MODE || sap_cnt || sta_cnt) { for (i = 0; i < sta_cnt + sap_cnt; i++) { @@ -165,6 +165,9 @@ QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev, } policy_mgr_check_n_start_opportunistic_timer(psoc); + if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE && + wlan_vdev_mlme_is_mlo_vdev(vdev)) + wlan_handle_emlsr_sta_concurrency(vdev, false, false, true); if (!wlan_cm_is_vdev_roaming(vdev)) policy_mgr_check_concurrent_intf_and_restart_sap(psoc, @@ -209,7 +212,7 @@ QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev, if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE || wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) - wlan_handle_emlsr_sta_concurrency(vdev, false, false); + wlan_handle_emlsr_sta_concurrency(vdev, false, false, true); status = if_mgr_enable_roaming_after_p2p_disconnect(pdev, vdev, RSO_CONNECT_START); 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 85bd4bac91..3b0133ebae 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 @@ -4598,19 +4598,25 @@ void policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); /** - * policy_mgr_handle_emlsr_sta_concurrency() - Handle EMLSR STA concurrency - * cases - * + * policy_mgr_handle_emlsr_sta_concurrency() - Handle concurrency scenarios with + * EMLSR STA. * @psoc: objmgr psoc - * @vdev: pointer to vdev on which new connection is coming up - * @is_ap_up: flag to check if new connection is SAP/P2P GO - * @sta_coming_up: flag to check if new connection is STA/P2P client + * @vdev: pointer to vdev + * @ap_coming_up: Check if the new connection request is SAP/P2P GO/NAN + * @sta_coming_up: Check if the new connection request is STA/P2P Client + * @emlsr_sta_coming_up: Check if the new connection request is EMLSR STA * - * Return: void + * The API handles concurrency scenarios with existing EMLSR connection when a + * new connection request is received OR with an existing legacy connection when + * an EMLSR sta comes up. + * + * Return: none */ void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, - bool is_ap_up, bool sta_coming_up); + bool ap_coming_up, + bool sta_coming_up, + bool emlsr_sta_coming_up); /** * policy_mgr_activate_mlo_links() - Force active ML links based on user 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 24456661ea..602b6a377b 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 @@ -5542,36 +5542,37 @@ end: void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, bool ap_coming_up, - bool sta_coming_up) + bool sta_coming_up, + bool emlsr_sta_coming_up) { uint8_t num_mlo = 0; uint8_t mlo_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; - bool is_mlo_emlsr; - struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_SME); - - if (!mac_ctx) - return; + bool is_mlo_emlsr = false; is_mlo_emlsr = policy_mgr_is_mlo_in_mode_emlsr(psoc, mlo_vdev_lst, &num_mlo); if (num_mlo < 2) { - policy_mgr_debug("vdev %d AP_state %d MLO Sta links %d", + policy_mgr_debug("vdev %d ap state %d num mlo sta links %d", wlan_vdev_get_id(vdev), ap_coming_up, num_mlo); return; } - policy_mgr_debug("vdev %d: AP coming up %d STA coming up %d num_mlo %d is_mlo_emlsr %d", - wlan_vdev_get_id(vdev), ap_coming_up, sta_coming_up, - num_mlo, is_mlo_emlsr); + policy_mgr_debug("vdev %d num_mlo %d is_mlo_emlsr %d", + wlan_vdev_get_id(vdev), num_mlo, is_mlo_emlsr); + policy_mgr_debug("ap state %d legacy sta state %d emlsr sta state %d", + ap_coming_up, sta_coming_up, emlsr_sta_coming_up); if (!is_mlo_emlsr) return; - if (ap_coming_up || sta_coming_up) { + if (ap_coming_up || sta_coming_up || (emlsr_sta_coming_up && + policy_mgr_get_connection_count(psoc) > 2)) { /* - * During SAP/STA up, If eMLSR STA is present, - * then Disable one of the links. FW will decide which link. + * Force disable one of the links (FW will decide which link) if + * 1) EMLSR STA is present and new SAP/STA connection comes up. + * 2) There is a legacy connection (SAP/P2P) and a STA comes + * up in EMLSR mode. */ policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT, MLO_LINK_FORCE_MODE_INACTIVE_NUM, @@ -5579,13 +5580,19 @@ void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc, return; } - /* - * During SAP/STA down, if eMLSR STA is present, re-enable both the - * links, as one of them was disabled during up. - */ - policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_DISCONNECT, - MLO_LINK_FORCE_MODE_NO_FORCE, - num_mlo, mlo_vdev_lst); + if (!(ap_coming_up || sta_coming_up) && emlsr_sta_coming_up) + /* + * No force i.e. Re-enable the disabled link if- + * 1) EMLSR STA is present and new SAP/STA connection goes down. + * One of the links was disabled while a new connection came up. + * 2) Legacy connection (SAP/P2P) goes down and if STA is 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); } static uint8_t diff --git a/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h b/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h index de5f1f10e4..52cd857b83 100644 --- a/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h +++ b/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -551,21 +551,27 @@ qdf_freq_t wlan_get_conc_freq(void); #ifdef WLAN_FEATURE_11BE_MLO /** * wlan_handle_emlsr_sta_concurrency() - Handle concurrency scenarios with - * existing eMLSR connection when a new cktn request is received. + * EMLSR STA. + * @vdev: pointer to vdev + * @ap_coming_up: Check if the new connection request is SAP/P2P GO/NAN + * @sta_coming_up: Check if the new connection request is STA/P2P Client + * @emlsr_sta_coming_up: Check if the new connection request is EMLSR STA * - * @vdev: pointer to vdev on which new connection is coming up - * @ap_coming_up: Check if the new cktn request is SAP/P2P GO/NAN - * @sta_coming_up: Check if the new cktn request is STA/P2P Client + * The API handles concurrency scenarios with existing EMLSR connection when a + * new connection request is received OR with an existing legacy connection when + * an EMLSR sta comes up. * * Return: none */ void wlan_handle_emlsr_sta_concurrency(struct wlan_objmgr_vdev *vdev, - bool ap_coming_up, bool sta_coming_up); + bool ap_coming_up, bool sta_coming_up, + bool emlsr_sta_coming_up); #else static inline void wlan_handle_emlsr_sta_concurrency(struct wlan_objmgr_vdev *vdev, - bool ap_coming_up, bool sta_coming_up) + bool ap_coming_up, bool sta_coming_up, + bool emlsr_sta_coming_up) { } #endif diff --git a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c index ac391d85bc..095eb2f1a9 100644 --- a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c +++ b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -467,7 +467,8 @@ static QDF_STATUS ap_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme, #ifdef WLAN_FEATURE_11BE_MLO void wlan_handle_emlsr_sta_concurrency(struct wlan_objmgr_vdev *vdev, - bool ap_coming_up, bool sta_coming_up) + bool ap_coming_up, bool sta_coming_up, + bool emlsr_sta_coming_up) { struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); @@ -477,7 +478,8 @@ void wlan_handle_emlsr_sta_concurrency(struct wlan_objmgr_vdev *vdev, } policy_mgr_handle_emlsr_sta_concurrency(psoc, vdev, ap_coming_up, - sta_coming_up); + sta_coming_up, + emlsr_sta_coming_up); } #endif diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index b6d1665ad8..338b921be5 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -11346,12 +11346,8 @@ QDF_STATUS populate_dot11f_assoc_req_mlo_ie(struct mac_context *mac_ctx, mlo_ie->mld_capab_and_op_info.aar_support = 0; } - /* - * Check if STA supports eMLSR and vendor command prefers eMLSR mode. - * Also, if there is an existing connection, then do not allow eMLSR. - */ - if (wlan_vdev_mlme_cap_get(pe_session->vdev, WLAN_VDEV_C_EMLSR_CAP) && - !policy_mgr_get_connection_count(psoc)) { + /* Check if STA supports EMLSR and vendor command prefers EMLSR mode */ + if (wlan_vdev_mlme_cap_get(pe_session->vdev, WLAN_VDEV_C_EMLSR_CAP)) { wlan_mlme_get_eml_params(psoc, &eml_cap); mlo_ie->eml_capab_present = 1; presence_bitmap |= WLAN_ML_BV_CTRL_PBM_EMLCAP_P;