Browse Source

qcacld-3.0: Handle eMLSR STA concurrencies in policy mgr

Handle the following the eMLSR STA concurrency scenarios

1) eMLSR STA + SAP/P2P GO/NAN - Send a force disable link request to
FW on any one of the eMLSR links. FW will decide which link to disable.
2) eMLSR STA + STA/P2P Client - Send a force disable link request to
FW on any one of the eMLSR links. FW will decide which link to disable.
This action happens before vdev start of the new connection request.
3) eMLSR STA + TDLS - TDLS connection is not allowed since eMLSR STA is
given higher priority.
4) If there is already an existing connection, then eMLSR is not allowed.

Once the other connection goes down, the disabled eMLSR link is restored.
The concurrency handling API is invoked from corresponding interface
manager APIs.

Change-Id: Ib7d5da5dcb8eb3ea16c6e50c8fcadc20972d7d05
CRs-Fixed: 3185078
Gururaj Pandurangi 3 years ago
parent
commit
61dfd77555

+ 8 - 0
components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c

@@ -28,6 +28,7 @@
 #include "wlan_p2p_cfg_api.h"
 #include "wlan_tdls_api.h"
 #include "wlan_p2p_api.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
 
 QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev,
 			       struct if_mgr_event_data *event_data)
@@ -45,6 +46,10 @@ QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev,
 
 	wlan_tdls_teardown_links_sync(psoc);
 
+	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);
+
 	if (policy_mgr_is_hw_mode_change_in_progress(psoc)) {
 		if (!QDF_IS_STATUS_SUCCESS(
 		    policy_mgr_wait_for_connection_update(psoc))) {
@@ -119,6 +124,9 @@ if_mgr_ap_stop_bss_complete(struct wlan_objmgr_vdev *vdev,
 	if (!psoc)
 		return QDF_STATUS_E_FAILURE;
 
+	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);
 	/*
 	 * Due to audio share glitch with P2P GO caused by
 	 * roam scan on concurrent interface, disable

+ 9 - 0
components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c

@@ -34,6 +34,7 @@
 #include <wlan_mlo_mgr_cmn.h>
 #include <wlan_cm_roam_api.h>
 #include "wlan_nan_api.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
 #ifdef WLAN_FEATURE_11BE_MLO
 #include <wlan_mlo_mgr_sta.h>
 #endif
@@ -68,6 +69,10 @@ QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev,
 							 &vdev_id_list[sta_cnt],
 							 PM_SAP_MODE);
 	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);
+
 	if (op_mode == QDF_P2P_CLIENT_MODE || sap_cnt || sta_cnt) {
 		for (i = 0; i < sta_cnt + sap_cnt; i++) {
 			if (vdev_id_list[i] == wlan_vdev_get_id(vdev))
@@ -200,6 +205,10 @@ QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev,
 	if (!psoc)
 		return QDF_STATUS_E_FAILURE;
 
+	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);
+
 	status = if_mgr_enable_roaming_after_p2p_disconnect(pdev, vdev,
 							RSO_INVALID_REQUESTOR);
 	if (status) {

+ 38 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -2951,6 +2951,19 @@ bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc);
  */
 bool policy_mgr_is_current_hwmode_sbs(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * policy_mgr_is_curr_hwmode_emlsr() - Function to check if current HW mode is
+ * eMLSR
+ *
+ * @psoc: Pointer to psoc
+ *
+ * This Function checks if current HW mode is eMLSR
+ *
+ * Return:True if current HW mode is eMLSR.
+ *
+ */
+bool policy_mgr_is_curr_hwmode_emlsr(struct wlan_objmgr_psoc *psoc);
+
 /**
  * policy_mgr_is_dp_hw_dbs_capable() - if hardware is capable of dbs 2x2
  * or 1X1 for Data Path (HW mode)
@@ -4290,6 +4303,20 @@ bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
 				   enum policy_mgr_con_mode mode,
 				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo);
 
+/**
+ * policy_mgr_is_mlo_in_mode_emlsr() - Check whether current connection is eMLSR
+ * @psoc: PSOC object information
+ * @mlo_vdev_lst: Pointer to mlo vdev list, this function wil fill this with
+ *                list of mlo vdev
+ * @num_mlo: Pointer to number of mlo link, this function will fill this with
+ *           number of mlo links
+ *
+ * Return: True if current connection is in eMLSR mode i.e. Both STA and AP
+ *         support eMLSR connection along with vendor command selection
+ */
+bool policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *mlo_vdev_lst, uint8_t *num_mlo);
+
 /*
  * policy_mgr_handle_ml_sta_links_on_vdev_up_csa() - Handle enable/disable
  * link on vdev UP and channel change
@@ -4331,6 +4358,10 @@ void policy_mgr_handle_ml_sta_link_on_traffic_type_change(
 void policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc *psoc,
 						 enum QDF_OPMODE mode,
 						 uint8_t vdev_id);
+
+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);
 #else
 
 static inline bool policy_mgr_is_mlo_sap_concurrency_allowed(
@@ -4373,6 +4404,13 @@ policy_mgr_handle_ml_sta_link_on_traffic_type_change(
 {
 }
 
+static inline
+bool policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	return false;
+}
+
 static inline
 void policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc *psoc,
 						 enum QDF_OPMODE mode,

+ 111 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -1287,6 +1287,7 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc,
 		hw_config_type = tmp->hw_mode_config_type;
 		dbs_mode = HW_MODE_DBS_NONE;
 		sbs_mode = HW_MODE_SBS_NONE;
+		emlsr_mode = HW_MODE_EMLSR_NONE;
 		mac1_ss_bw_info.mac_tx_stream = 0;
 		mac1_ss_bw_info.mac_rx_stream = 0;
 		mac1_ss_bw_info.mac_bw = 0;
@@ -4762,6 +4763,116 @@ bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
 	return is_sbs_link;
 }
 
+bool policy_mgr_is_curr_hwmode_emlsr(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_hw_mode_params hw_mode;
+
+	if (!policy_mgr_is_hw_emlsr_capable(psoc))
+		return false;
+
+	if (QDF_STATUS_SUCCESS != policy_mgr_get_current_hw_mode(psoc,
+								 &hw_mode))
+		return false;
+
+	if (!hw_mode.emlsr_cap)
+		return false;
+
+	return true;
+}
+
+bool policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	bool emlsr_connection = false;
+	uint32_t mode_num = 0;
+	uint8_t i, mlo_idx = 0;
+	struct wlan_objmgr_vdev *temp_vdev;
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+
+	mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							  vdev_id_list,
+							  PM_STA_MODE);
+
+	if (!mode_num || mode_num < 2)
+		goto end;
+
+	for (i = 0; i < mode_num; i++) {
+		temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+							psoc, vdev_id_list[i],
+							WLAN_POLICY_MGR_ID);
+		if (!temp_vdev) {
+			policy_mgr_err("invalid vdev for id %d",
+				       vdev_id_list[i]);
+			goto end;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
+			if (mlo_vdev_lst)
+				mlo_vdev_lst[mlo_idx] = vdev_id_list[i];
+			mlo_idx++;
+		}
+		/* Check if existing vdev is eMLSR STA */
+		if (wlan_vdev_mlme_get_emlsr_caps(temp_vdev))
+			emlsr_connection = true;
+
+		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
+	}
+end:
+	if (num_mlo)
+		*num_mlo = mlo_idx;
+
+	return emlsr_connection;
+}
+
+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)
+{
+	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;
+
+	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",
+				 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);
+
+	if (!is_mlo_emlsr)
+		return;
+
+	if (ap_coming_up || sta_coming_up) {
+		/*
+		 * During SAP/STA up, If eMLSR STA is present,
+		 * then Disable one of the links. FW will decide which link.
+		 */
+		policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
+					    MLO_LINK_FORCE_MODE_INACTIVE_NUM,
+					    num_mlo, mlo_vdev_lst);
+		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);
+}
+
 static uint8_t
 policy_mgr_get_affected_links_for_sta_sta(struct wlan_objmgr_psoc *psoc,
 					  uint8_t num_ml, qdf_freq_t *freq_list,

+ 21 - 0
components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h

@@ -527,4 +527,25 @@ QDF_STATUS wlan_sap_stop_bss(uint8_t vdev_id);
  */
 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.
+ *
+ * @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
+ *
+ * Return: none
+ */
+void
+wlan_handle_emlsr_sta_concurrency(struct wlan_objmgr_vdev *vdev,
+				  bool ap_coming_up, bool 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)
+{
+}
+#endif
 #endif

+ 16 - 0
components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -464,6 +464,22 @@ static QDF_STATUS ap_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
 	return lim_ap_mlme_vdev_up_send(vdev_mlme, data_len, data);
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+void wlan_handle_emlsr_sta_concurrency(struct wlan_objmgr_vdev *vdev,
+				       bool ap_coming_up, bool sta_coming_up)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+
+	if (!psoc) {
+		mlme_legacy_debug("psoc Null");
+		return;
+	}
+
+	policy_mgr_handle_emlsr_sta_concurrency(psoc, vdev, ap_coming_up,
+						sta_coming_up);
+}
+#endif
+
 /**
  * ap_mlme_vdev_notify_up_complete() - callback to notify up completion
  * @vdev_mlme: vdev mlme object

+ 0 - 4
core/mac/src/pe/include/lim_global.h

@@ -247,7 +247,6 @@ typedef struct tLimPreAuthTable {
  * @owe_ie:         Pointer to OWE IE
  * @owe_ie_len:     Length of OWE IE
  * @eht_capable:     802.11be EHT capability
- * @emlsr_capable:   802.11be eMLSR capability
  */
 struct lim_sta_context {
 	tLimMlmStates mlmState;
@@ -276,9 +275,6 @@ struct lim_sta_context {
 #ifdef WLAN_FEATURE_11BE
 	bool eht_capable;
 #endif
-#ifdef WLAN_FEATURE_11BE_MLO
-	bool emlsr_capable;
-#endif
 };
 
 /* Structure definition to hold deferred messages queue parameters */

+ 0 - 1
core/mac/src/pe/include/lim_session.h

@@ -805,7 +805,6 @@ struct pe_session {
 	struct mlo_partner_info ml_partner_info;
 	uint16_t mlo_ie_total_len;
 	struct wlan_mlo_ie mlo_ie;
-	bool is_emlsr_capable;
 #endif
 #endif /* WLAN_FEATURE_11BE */
 	uint8_t user_edca_set;

+ 2 - 2
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -207,8 +207,6 @@ void lim_update_assoc_sta_datas(struct mac_context *mac_ctx,
 	lim_update_stads_eht_caps(mac_ctx, sta_ds, assoc_rsp,
 				  session_entry, beacon);
 
-	lim_update_stads_emlsr_caps(mac_ctx, sta_ds, assoc_rsp);
-
 	if (lim_is_sta_he_capable(sta_ds))
 		he_cap = &assoc_rsp->he_cap;
 
@@ -1417,6 +1415,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 		goto assocReject;
 	}
 
+	lim_objmgr_update_emlsr_caps(mac_ctx->psoc, session_entry->smeSessionId,
+				     assoc_rsp);
 	/*
 	 * Extract the AP capabilities from the beacon that
 	 * was received earlier

+ 26 - 0
core/mac/src/pe/lim/lim_prop_exts_utils.c

@@ -406,6 +406,32 @@ static void lim_extract_eht_op(struct pe_session *session,
 }
 #endif
 
+#ifdef WLAN_FEATURE_11BE_MLO
+void lim_objmgr_update_emlsr_caps(struct wlan_objmgr_psoc *psoc,
+				  uint8_t vdev_id, tpSirAssocRsp assoc_rsp)
+{
+	struct wlan_objmgr_vdev *vdev;
+	bool ap_emlsr_cap = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_LEGACY_MAC_ID);
+	if (!vdev) {
+		pe_err("vdev not found for id: %d", vdev_id);
+		return;
+	}
+
+	ap_emlsr_cap =
+		assoc_rsp->mlo_ie.mlo_ie.eml_capabilities_info.emlsr_support;
+	if (!ap_emlsr_cap)
+		pe_debug("eMLSR cap not present in assoc rsp");
+
+	wlan_vdev_obj_lock(vdev);
+	wlan_vdev_mlme_set_emlsr_caps(vdev, ap_emlsr_cap);
+	wlan_vdev_obj_unlock(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+}
+#endif
+
 void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
 				uint8_t vdev_id, uint8_t nss)
 {

+ 12 - 0
core/mac/src/pe/lim/lim_prop_exts_utils.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2014, 2016, 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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
@@ -79,4 +80,15 @@ void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
  */
 void lim_update_he_mcs_12_13_map(struct wlan_objmgr_psoc *psoc,
 				 uint8_t vdev_id, uint16_t he_mcs_12_13_map);
+
+#ifdef WLAN_FEATURE_11BE_MLO
+void lim_objmgr_update_emlsr_caps(struct wlan_objmgr_psoc *psoc,
+				  uint8_t vdev_id, tpSirAssocRsp assoc_rsp);
+#else
+static inline
+void lim_objmgr_update_emlsr_caps(struct wlan_objmgr_psoc *psoc,
+				  uint8_t vdev_id, tpSirAssocRsp assoc_rsp)
+{
+}
+#endif /* WLAN_FEATURE_11BE_MLO */
 #endif /* __LIM_PROP_EXTS_UTILS_H */

+ 9 - 37
core/mac/src/pe/lim/lim_utils.c

@@ -8863,24 +8863,19 @@ void lim_update_stads_eht_bw_320mhz(struct pe_session *session,
 #endif
 
 #ifdef WLAN_FEATURE_11BE_MLO
-void lim_update_stads_emlsr_caps(struct mac_context *mac_ctx,
-				 tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp)
-{
-	if (!assoc_rsp->mlo_ie.mlo_ie.eml_capabilities_info.emlsr_support) {
-		pe_debug("eMLSR cap not present in assoc rsp");
-		sta_ds->mlmStaContext.emlsr_capable = false;
-		return;
-	}
-
-	sta_ds->mlmStaContext.emlsr_capable = true;
-}
-
 void lim_intersect_ap_emlsr_caps(struct pe_session *session,
 				 struct bss_params *add_bss,
 				 tpSirAssocRsp assoc_rsp)
 {
-	if (session->is_emlsr_capable && assoc_rsp &&
-	    assoc_rsp->mlo_ie.mlo_ie.eml_capabilities_info.emlsr_support) {
+	struct vdev_mlme_obj *mlme_obj;
+
+	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(session->vdev);
+	if (!mlme_obj) {
+		pe_err("vdev component object is NULL");
+		return;
+	}
+
+	if (wlan_vdev_mlme_get_emlsr_caps(session->vdev)) {
 		add_bss->staContext.emlsr_support = true;
 		add_bss->staContext.link_id =
 		    assoc_rsp->mlo_ie.mlo_ie.link_id;
@@ -8890,29 +8885,6 @@ void lim_intersect_ap_emlsr_caps(struct pe_session *session,
 		add_bss->staContext.emlsr_support = false;
 	}
 }
-
-bool lim_is_mlo_in_emlsr_mode(struct mac_context *mac_ctx, uint8_t vdev_id)
-{
-	struct pe_session *session;
-	tpDphHashNode sta_ds = NULL;
-	uint16_t aid;
-
-	session = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
-	if (!session) {
-		pe_err("Session does not exist for given vdev_id %d", vdev_id);
-		return false;
-	}
-
-	sta_ds = dph_lookup_hash_entry(mac_ctx, session->bssId, &aid,
-				       &session->dph.dphHashTable);
-	if (!sta_ds) {
-		pe_debug("No STA DS entry found for " QDF_MAC_ADDR_FMT,
-			 QDF_MAC_ADDR_REF(session->bssId));
-		return false;
-	}
-
-	return session->is_emlsr_capable && sta_ds->mlmStaContext.emlsr_capable;
-}
 #endif
 
 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)

+ 0 - 33
core/mac/src/pe/lim/lim_utils.h

@@ -2200,27 +2200,6 @@ lim_update_stads_eht_bw_320mhz(struct pe_session *session,
 void lim_intersect_ap_emlsr_caps(struct pe_session *session,
 				 struct bss_params *add_bss,
 				 tpSirAssocRsp assoc_rsp);
-
-/**
- * lim_update_stads_emlsr_caps() - Copy eMLSR capability into STA DPH hash table
- *                                 entry
- * @mac_ctx: pointer to mac context
- * @sta_ds: pointer to sta dph hash table entry
- * @assoc_rsp: pointer to assoc response
- *
- * Return: None
- */
-void lim_update_stads_emlsr_caps(struct mac_context *mac_ctx,
-				 tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp);
-
-/**
- * lim_is_mlo_in_emlsr_mode() - Check if MLO is in eMLSR mode.
- * @mac_ctx: pointer to mac context
- * @vdev_id: vdev ID
- *
- * Return: True if both STA and peer support eMLSR capability, else False
- */
-bool lim_is_mlo_in_emlsr_mode(struct mac_context *mac_ctx, uint8_t vdev_id);
 #else
 static inline void
 lim_intersect_ap_emlsr_caps(struct pe_session *session,
@@ -2228,18 +2207,6 @@ lim_intersect_ap_emlsr_caps(struct pe_session *session,
 			    tpSirAssocRsp assoc_rsp)
 {
 }
-
-static inline
-void lim_update_stads_emlsr_caps(struct mac_context *mac_ctx,
-				 tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp)
-{
-}
-
-static inline
-bool lim_is_mlo_in_emlsr_mode(struct mac_context *mac_ctx, uint8_t vdev_id)
-{
-	return false;
-}
 #endif /* WLAN_FEATURE_11BE_MLO */
 
 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)

+ 15 - 2
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -10771,6 +10771,7 @@ QDF_STATUS populate_dot11f_assoc_req_mlo_ie(struct mac_context *mac_ctx,
 	QDF_STATUS status;
 	bool emlsr_cap, emlsr_enabled = false;
 	struct wlan_objmgr_psoc *psoc;
+	struct vdev_mlme_obj *mlme_obj;
 	tDot11fIEnon_inheritance sta_prof_non_inherit;
 	tDot11fFfCapabilities mlo_cap;
 	tDot11fIEHTCaps ht_caps;
@@ -10793,6 +10794,12 @@ QDF_STATUS populate_dot11f_assoc_req_mlo_ie(struct mac_context *mac_ctx,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev);
+	if (!mlme_obj) {
+		pe_err(" VDEV MLME component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	pe_debug("Populate Assoc req MLO IEs");
 
 	mlo_ie = &pe_session->mlo_ie;
@@ -10820,12 +10827,18 @@ QDF_STATUS populate_dot11f_assoc_req_mlo_ie(struct mac_context *mac_ctx,
 		mlo_ie->mld_capabilities_info.aar_support = 0;
 	}
 
+	/* Check if HW supports eMLSR mode */
 	emlsr_cap = policy_mgr_is_hw_emlsr_capable(psoc);
 
+	/* Check if eMLSR is selected through vendor cmd */
 	wlan_mlme_get_emlsr_mode_enabled(psoc, &emlsr_enabled);
-	pe_session->is_emlsr_capable = emlsr_cap && emlsr_enabled;
 
-	if (pe_session->is_emlsr_capable) {
+	wlan_vdev_mlme_set_emlsr_caps(pe_session->vdev,
+				      emlsr_cap && emlsr_enabled);
+
+	/* If there is an existing connection, then do not allow eMLSR */
+	if (emlsr_cap && emlsr_enabled &&
+	    !policy_mgr_get_connection_count(psoc)) {
 		mlo_ie->eml_capab_present = 1;
 		presence_bitmap |= WLAN_ML_BV_CTRL_PBM_EMLCAP_P;
 		mlo_ie->common_info_length += WLAN_ML_BV_CINFO_EMLCAP_SIZE;