Browse Source

qcacld-3.0: Move MLO STA concurreny handling to Policy Mgr

Move MLO STA-SAP concurreny handling to Policy Mgr which
is present in CSR currently.
Also, Move MLO STA-STA concurreny handling to Policy Mgr
which was part of If Mgr currently.

Change-Id: I2b8de17c3d31b43ff1f6b81a7de07b88888d7fb5
CRs-Fixed: 3153393
Utkarsh Bhatnagar 3 years ago
parent
commit
fea133e371

+ 3 - 377
components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c

@@ -106,381 +106,6 @@ QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev,
 	return QDF_STATUS_SUCCESS;
 }
 
-#ifdef WLAN_FEATURE_11BE_MLO
-static uint8_t
-if_mgr_get_affected_links_for_sbs(struct wlan_objmgr_psoc *psoc,
-				  uint8_t num_ml, qdf_freq_t *freq_list,
-				  uint8_t *vdev_id_list,
-				  uint8_t *ml_vdev_lst,
-				  uint8_t *ml_idx, qdf_freq_t freq)
-{
-	uint8_t i = 0;
-	bool same_band_sta_allowed;
-
-	/*
-	 * STA freq:      ML STA combo:  SBS Action
-	 * ---------------------------------------------------
-	 * 2Ghz           2Ghz+5/6Ghz    Disable 2Ghz(Same MAC)
-	 * 5Ghz           2Ghz+5/6Ghz    Disable 2.4Ghz if 5Ghz lead to SBS
-	 *                               (SBS, same MAC) and same band STA
-	 *                               allowed, else disable 5/6Ghz
-	 *                               (NON SBS, same MAC)
-	 * 5Ghz(lower)    5Ghz+6Ghz      Disable 5Ghz (NON SBS, same MAC)
-	 * 5Ghz(higher)   5Ghz+6Ghz      Disable 6Ghz (NON SBS, Same MAC)
-	 * 2Ghz           5Ghz+6Ghz      Disable Any
-	 */
-
-	/* If non-ML STA is 2.4Ghz disable 2.4Ghz if present OR disable any */
-	if (wlan_reg_is_24ghz_ch_freq(freq)) {
-		while (i < num_ml) {
-			if (wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) {
-				/* Affected ML STA link on 2.4Ghz */
-				ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
-				return 1;
-			}
-			/* Fill non effected vdev in list */
-			ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
-			i++;
-		}
-		/* No link affected return num_ml to disable any */
-		return i;
-	}
-
-	/* This mean non-ML STA is 5Ghz */
-
-	/* check if ML STA is DBS */
-	i = 0;
-	while (i < num_ml &&
-	       !wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]]))
-		i++;
-
-	same_band_sta_allowed = wlan_cm_same_band_sta_allowed(psoc);
-
-	/*
-	 * if ML STA is DBS ie 2.4Ghz link present and if same_band_sta_allowed
-	 * is false, disable 5/6Ghz link to make sure we dont have all link
-	 * on 5Ghz
-	 */
-	if (i < num_ml && !same_band_sta_allowed)
-		goto check_dbs_ml;
-
-	/* check if any link lead to SBS, so that we can disable the other*/
-	i = 0;
-	while (i < num_ml &&
-	       !policy_mgr_are_sbs_chan(psoc, freq, freq_list[ml_idx[i]]))
-		i++;
-
-	/*
-	 * if i < num_ml then i is the SBS link, in this case disable the other
-	 * non SBS link, this mean ML STA is 5+6 or 2+5/6.
-	 */
-	if (i < num_ml) {
-		i = 0;
-		while (i < num_ml) {
-			if (!policy_mgr_are_sbs_chan(psoc, freq,
-						     freq_list[ml_idx[i]])) {
-				/* Affected non SBS ML STA link */
-				ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
-				return 1;
-			}
-			/* Fill non effected vdev in list */
-			ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
-			i++;
-		}
-		/* All link lead to SBS, disable any, This should not happen */
-		return i;
-	}
-
-check_dbs_ml:
-	/*
-	 * None of the link can lead to SBS, i.e. its 2+ 5/6 ML STA in this case
-	 * disable 5Ghz link.
-	 */
-	i = 0;
-	while (i < num_ml) {
-		if (!wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) {
-			/* Affected 5/6Ghz ML STA link */
-			ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
-			return 1;
-		}
-		/* Fill non effected vdev in list */
-		ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
-		i++;
-	}
-
-	/* No link affected, This should not happen */
-	return i;
-}
-
-/*
- * if_mgr_get_concurrent_num_links() - get links which are affected
- * if no affected then return num ml. Also fills the ml_vdev_lst to send.
- * @num_ml: number of ML vdev
- * @freq_list: freq list of all vdev
- * @vdev_id_list: vdev id list
- * @ml_vdev_lst: ML vdev list
- * @ml_idx: ML index
- * @freq: non ML STA freq
- *
- * Return: number of the affected links, else total link and ml_vdev_lst list.
- */
-static uint8_t
-if_mgr_get_concurrent_num_links(struct wlan_objmgr_vdev *vdev,
-				uint8_t num_ml, qdf_freq_t *freq_list,
-				uint8_t *vdev_id_list,
-				uint8_t *ml_vdev_lst,
-				uint8_t *ml_idx, qdf_freq_t freq)
-{
-	uint8_t i = 0;
-	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
-
-	if (!psoc)
-		return 0;
-
-	while (i < num_ml && (freq_list[ml_idx[i]] != freq))
-		i++;
-
-	if (i < num_ml) {
-		/* if one link is SCC then no need to disable any link */
-		ifmgr_debug("vdev %d: ML vdev %d lead to SCC, STA freq %d ML freq %d, no need to disable link",
-			    wlan_vdev_get_id(vdev), vdev_id_list[ml_idx[i]],
-			    freq, freq_list[ml_idx[i]]);
-		return 0;
-	}
-
-	if (policy_mgr_is_hw_sbs_capable(psoc))
-		return if_mgr_get_affected_links_for_sbs(psoc, num_ml,
-							 freq_list,
-							 vdev_id_list,
-							 ml_vdev_lst,
-							 ml_idx, freq);
-
-	/*
-	 * STA freq:      STA ML combo:  NON SBS Action:
-	 * -------------------------------------------------
-	 * 2Ghz           2Ghz+5/6Ghz    Disable 2Ghz (Same MAC)
-	 * 5Ghz           2Ghz+5/6Ghz    Disable 5Ghz (Same MAC)
-	 * 5Ghz           5Ghz+6Ghz      Disable Any of 5/6Ghz (Same MAC)
-	 * 2Ghz           5Ghz+6Ghz      Disable Any
-	 */
-	/*
-	 * Check if any of the link is on same MAC/band(for non SBS) as non ML
-	 * STA's freq. Same MAC/band mean both are either 5Ghz/6Ghz/2.4Ghz
-	 * OR both are non 2.4Ghz (ie one is 5Ghz and other is 6Ghz)
-	 */
-	i = 0;
-	while (i < num_ml &&
-	       !(wlan_reg_is_same_band_freqs(freq_list[ml_idx[i]], freq) ||
-		 (!wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]]) &&
-		  !wlan_reg_is_24ghz_ch_freq(freq)))) {
-		/* Fill non effected vdev in list */
-		ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
-		i++;
-	}
-
-	if (i < num_ml) {
-		/* affected ML link on the same MAC/band with non ML STA */
-		ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
-		return 1;
-	}
-
-	/* No link affected return num_ml to disable any */
-	return i;
-}
-
-static void
-if_mgr_handle_sap_plus_ml_sta_connect(struct wlan_objmgr_psoc *psoc,
-				      struct wlan_objmgr_vdev *vdev)
-{
-	uint32_t sap_num = 0;
-	qdf_freq_t sap_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-	uint8_t sap_vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-	bool is_ml_sbs;
-	uint8_t ml_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-	uint8_t num_ml;
-	uint8_t vdev_id = wlan_vdev_get_id(vdev);
-
-	sap_num = policy_mgr_get_mode_specific_conn_info(psoc, sap_freq_list,
-							 sap_vdev_id_list,
-							 PM_SAP_MODE);
-
-	ifmgr_debug("vdev %d: sap_num %d sap_chan %d", vdev_id, sap_num,
-		    sap_freq_list[0]);
-	if (sap_num != 1)
-		return;
-
-	if (!wlan_reg_is_24ghz_ch_freq(sap_freq_list[0]))
-		return;
-	is_ml_sbs = policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE,
-						  ml_vdev_lst, &num_ml);
-	if (num_ml < 2)
-		return;
-
-	ifmgr_debug("vdev %d: num_ml %d is_ml_sbs %d sap_chan %d", vdev_id,
-		    num_ml, is_ml_sbs, sap_freq_list[0]);
-
-	if (!is_ml_sbs) {
-		/*
-		 * re-enable both link in case if this was roaming from sbs to
-		 * dbs ML STA, with sap on 2.4Ghz.
-		 */
-		if (wlan_cm_is_vdev_roaming(vdev))
-			wlan_mlo_sta_mlo_concurency_set_link(vdev,
-					MLO_LINK_FORCE_REASON_DISCONNECT,
-					MLO_LINK_FORCE_MODE_NO_FORCE,
-					num_ml, ml_vdev_lst);
-
-		return;
-	}
-
-	/* If ML STA is SBS and SAP is 2.4Ghz, Disable one of the links. */
-	wlan_mlo_sta_mlo_concurency_set_link(vdev,
-					     MLO_LINK_FORCE_REASON_CONNECT,
-					     MLO_LINK_FORCE_MODE_ACTIVE_NUM,
-					     num_ml, ml_vdev_lst);
-}
-
-static void
-if_mgr_ml_sta_concurency_on_connect(struct wlan_objmgr_psoc *psoc,
-				    struct wlan_objmgr_vdev *vdev,
-				    uint8_t num_ml, uint8_t *ml_idx,
-				    uint8_t num_non_ml, uint8_t *non_ml_idx,
-				    qdf_freq_t *freq_list,
-				    uint8_t *vdev_id_list)
-{
-	qdf_freq_t freq = 0;
-	struct wlan_channel *bss_chan;
-	uint8_t vdev_id = wlan_vdev_get_id(vdev);
-	uint8_t ml_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-	uint8_t affected_links = 0;
-	enum mlo_link_force_mode mode = MLO_LINK_FORCE_MODE_ACTIVE_NUM;
-
-	/* non ML STA doesn't exist, no need to change to link.*/
-	if (!num_non_ml) {
-		/* Check if SAP exist and any link change is required */
-		if_mgr_handle_sap_plus_ml_sta_connect(psoc, vdev);
-		return;
-	}
-
-	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
-		freq = freq_list[non_ml_idx[0]];
-	} else {
-		bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
-		if (bss_chan)
-			freq = bss_chan->ch_freq;
-	}
-	ifmgr_debug("vdev %d: Freq %d (non ML vdev id %d), is ML STA %d",
-		    vdev_id, freq, non_ml_idx[0],
-		    wlan_vdev_mlme_is_mlo_vdev(vdev));
-	if (!freq)
-		return;
-
-	affected_links =
-		if_mgr_get_concurrent_num_links(vdev, num_ml, freq_list,
-						vdev_id_list, ml_vdev_lst,
-						ml_idx, freq);
-
-	if (!affected_links) {
-		ifmgr_debug("vdev %d: no affected link found", vdev_id);
-		return;
-	}
-
-	/*
-	 * If affected link is less than num_ml, ie not all link are affected,
-	 * send MLO_LINK_FORCE_MODE_INACTIVE.
-	 */
-	if (affected_links < num_ml &&
-	    affected_links <= MAX_NUMBER_OF_CONC_CONNECTIONS) {
-		if (mlo_is_sta_inactivity_allowed_with_quiet(psoc, vdev_id_list,
-							     num_ml, ml_idx,
-							     affected_links,
-							     ml_vdev_lst)) {
-			mode = MLO_LINK_FORCE_MODE_INACTIVE;
-		} else {
-			ifmgr_debug("vdev %d: force inactivity is not allowed",
-				    ml_vdev_lst[0]);
-			return;
-		}
-	}
-
-	wlan_mlo_sta_mlo_concurency_set_link(vdev,
-					     MLO_LINK_FORCE_REASON_CONNECT,
-					     mode, affected_links,
-					     ml_vdev_lst);
-}
-
-static void
-if_mgr_ml_sta_concurency_on_disconnect(struct wlan_objmgr_vdev *vdev,
-				       uint8_t num_ml, uint8_t *ml_idx,
-				       uint8_t num_non_ml,
-				       uint8_t *vdev_id_list)
-{
-	uint8_t i = 0;
-	uint8_t ml_vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-
-	/*
-	 * If non ML STA exist, no need to change to link.
-	 * Only change when legasy sta is disconnected and
-	 * only ML STA is present.
-	 */
-	if (num_non_ml)
-		return;
-
-	/*
-	 * On non ML STA disconnect if  MLO has >= 2 links, need to send
-	 * MLO_LINK_FORCE_MODE_NO_FORCE for all MLO Vdevs for letting FW enable
-	 * all the links.
-	 */
-	while (i < num_ml) {
-		ml_vdev_list[i] = vdev_id_list[ml_idx[i]];
-		i++;
-	}
-
-	wlan_mlo_sta_mlo_concurency_set_link(vdev,
-					     MLO_LINK_FORCE_REASON_DISCONNECT,
-					     MLO_LINK_FORCE_MODE_NO_FORCE,
-					     num_ml, ml_vdev_list);
-}
-
-static void
-if_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
-				      struct wlan_objmgr_vdev *vdev,
-				      bool is_connect)
-{
-	uint8_t num_ml = 0, num_non_ml = 0;
-	uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-	uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-
-	policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx,
-					       &num_non_ml, non_ml_idx,
-					       freq_list, vdev_id_list);
-
-	ifmgr_debug("vdev %d: num_ml %d num_non_ml %d is_connect %d",
-		    wlan_vdev_get_id(vdev), num_ml, num_non_ml, is_connect);
-	/* ML STA is not up */
-	if (num_ml < 2 || num_ml > MAX_NUMBER_OF_CONC_CONNECTIONS)
-		return;
-
-	if (is_connect)
-		if_mgr_ml_sta_concurency_on_connect(psoc, vdev, num_ml,
-						    ml_idx, num_non_ml,
-						    non_ml_idx, freq_list,
-						    vdev_id_list);
-	else
-		if_mgr_ml_sta_concurency_on_disconnect(vdev, num_ml, ml_idx,
-						       num_non_ml,
-						       vdev_id_list);
-}
-#else
-static inline void
-if_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
-				      struct wlan_objmgr_vdev *vdev,
-				      bool is_connect)
-{}
-#endif
-
 QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev,
 				   struct if_mgr_event_data *event_data)
 {
@@ -520,7 +145,8 @@ QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev,
 			if_mgr_enable_roaming(pdev, vdev, RSO_CONNECT_START);
 		}
 		if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
-			if_mgr_handle_ml_sta_link_concurrency(psoc, vdev, true);
+			policy_mgr_handle_ml_sta_link_concurrency(psoc, vdev,
+								  true);
 	} else {
 		/* notify connect failure on final failure */
 		ucfg_tdls_notify_connect_failure(psoc);
@@ -591,7 +217,7 @@ QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev,
 	}
 
 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
-		if_mgr_handle_ml_sta_link_concurrency(psoc, vdev, false);
+		policy_mgr_handle_ml_sta_link_concurrency(psoc, vdev, false);
 
 	return QDF_STATUS_SUCCESS;
 }

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

@@ -4196,6 +4196,28 @@ 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_handle_sap_mlo_sta_concurrency() - Handle SAP MLO STA concurrency
+ *                                             such as:
+ *       1) If MLO STA is present with both links in 5/6 Ghz then SAP comes up
+ *          on 2.4 Ghz, then Disable one of the links
+ *       2) If MLO STA is present with both links in 5/6 Ghz and SAP, which was
+ *          present on 2.4 ghz, stops then renable both the as one of the links
+ *          were disabled because of sap on 2.4 ghz.
+ *
+ * @vdev: vdev mlme object
+ * @is_ap_up: bool to represent sap state
+ *
+ * Return: Void
+ */
+void policy_mgr_handle_sap_mlo_sta_concurrency(struct wlan_objmgr_psoc *psoc,
+					       struct wlan_objmgr_vdev *vdev,
+					       bool is_ap_up);
+
+void policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
+					       struct wlan_objmgr_vdev *vdev,
+					       bool is_connect);
+
 #else
 
 static inline bool policy_mgr_is_mlo_sap_concurrency_allowed(
@@ -4223,6 +4245,20 @@ bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
 {
 	return false;
 }
+
+static inline
+void policy_mgr_handle_sap_mlo_sta_concurrency(struct wlan_objmgr_psoc *psoc,
+					       struct wlan_objmgr_vdev *vdev,
+					       bool is_ap_up)
+{
+}
+
+static inline
+void policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
+					       struct wlan_objmgr_vdev *vdev,
+					       bool is_connect)
+{
+}
 #endif
 
 /**

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

@@ -42,6 +42,7 @@
 #include "wlan_mlme_vdev_mgr_interface.h"
 #include "wlan_mlo_mgr_sta.h"
 #include "wlan_cm_ucfg_api.h"
+#include "wlan_cm_roam_api.h"
 
 /* invalid channel id. */
 #define INVALID_CHANNEL_ID 0
@@ -3919,6 +3920,449 @@ bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
 
 	return is_sbs_link;
 }
+
+void policy_mgr_handle_sap_mlo_sta_concurrency(struct wlan_objmgr_psoc *psoc,
+					       struct wlan_objmgr_vdev *vdev,
+					       bool is_ap_up)
+{
+	uint8_t num_mlo = 0;
+	qdf_freq_t sap_chan = 0;
+	struct wlan_channel *bss_chan = NULL;
+	uint8_t mlo_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	bool is_mlo_sbs;
+	struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
+
+	if (!mac_ctx)
+		return;
+
+	is_mlo_sbs = policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE,
+						   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), is_ap_up, num_mlo);
+		return;
+	}
+
+	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
+	if (bss_chan)
+		sap_chan = bss_chan->ch_freq;
+	if (!sap_chan) {
+		policy_mgr_debug("Invalid SAP Chan");
+		return;
+	}
+
+	policy_mgr_debug("vdev %d: is_ap_up %d num_mlo %d is_mlo_sbs %d sap_chan %d",
+			 wlan_vdev_get_id(vdev), is_ap_up, num_mlo, is_mlo_sbs,
+			 sap_chan);
+
+	if (!is_mlo_sbs)
+		return;
+
+	if (is_ap_up) {
+		/*
+		 * During 2.4Ghz SAP up, If SBS MLO STA is present,
+		 * then Disable one of the links.
+		 */
+		if (wlan_reg_is_24ghz_ch_freq(sap_chan))
+			wlan_mlo_sta_mlo_concurency_set_link(vdev,
+						MLO_LINK_FORCE_REASON_CONNECT,
+						MLO_LINK_FORCE_MODE_ACTIVE_NUM,
+						num_mlo, mlo_vdev_lst);
+		/*
+		 * During 2.4Ghz SAP up, If there is channel switch for sap from
+		 * 2.4 ghz to 5 ghz, enable both the links, as one of them was
+		 * disabled by previous up operations when sap was on 2.4 ghz
+		 */
+		else
+			wlan_mlo_sta_mlo_concurency_set_link(vdev,
+						MLO_LINK_FORCE_REASON_CONNECT,
+						MLO_LINK_FORCE_MODE_NO_FORCE,
+						num_mlo, mlo_vdev_lst);
+
+		return;
+	}
+
+	/*
+	 * During 2.4Ghz SAP down, if SBS MLO STA is present, renable both the
+	 * links, as one of them was disabled during up.
+	 */
+	if (wlan_reg_is_24ghz_ch_freq(sap_chan))
+		wlan_mlo_sta_mlo_concurency_set_link(vdev,
+					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_sbs(struct wlan_objmgr_psoc *psoc,
+				      uint8_t num_ml, qdf_freq_t *freq_list,
+				      uint8_t *vdev_id_list,
+				      uint8_t *ml_vdev_lst,
+				      uint8_t *ml_idx, qdf_freq_t freq)
+{
+	uint8_t i = 0;
+	bool same_band_sta_allowed;
+
+	/*
+	 * STA freq:      ML STA combo:  SBS Action
+	 * ---------------------------------------------------
+	 * 2Ghz           2Ghz+5/6Ghz    Disable 2Ghz(Same MAC)
+	 * 5Ghz           2Ghz+5/6Ghz    Disable 2.4Ghz if 5Ghz lead to SBS
+	 *                               (SBS, same MAC) and same band STA
+	 *                               allowed, else disable 5/6Ghz
+	 *                               (NON SBS, same MAC)
+	 * 5Ghz(lower)    5Ghz+6Ghz      Disable 5Ghz (NON SBS, same MAC)
+	 * 5Ghz(higher)   5Ghz+6Ghz      Disable 6Ghz (NON SBS, Same MAC)
+	 * 2Ghz           5Ghz+6Ghz      Disable Any
+	 */
+
+	/* If non-ML STA is 2.4Ghz disable 2.4Ghz if present OR disable any */
+	if (wlan_reg_is_24ghz_ch_freq(freq)) {
+		while (i < num_ml) {
+			if (wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) {
+				/* Affected ML STA link on 2.4Ghz */
+				ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
+				return 1;
+			}
+			/* Fill non effected vdev in list */
+			ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
+			i++;
+		}
+		/* No link affected return num_ml to disable any */
+		return i;
+	}
+
+	/* This mean non-ML STA is 5Ghz */
+
+	/* check if ML STA is DBS */
+	i = 0;
+	while (i < num_ml &&
+	       !wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]]))
+		i++;
+
+	same_band_sta_allowed = wlan_cm_same_band_sta_allowed(psoc);
+
+	/*
+	 * if ML STA is DBS ie 2.4Ghz link present and if same_band_sta_allowed
+	 * is false, disable 5/6Ghz link to make sure we dont have all link
+	 * on 5Ghz
+	 */
+	if (i < num_ml && !same_band_sta_allowed)
+		goto check_dbs_ml;
+
+	/* check if any link lead to SBS, so that we can disable the other*/
+	i = 0;
+	while (i < num_ml &&
+	       !policy_mgr_are_sbs_chan(psoc, freq, freq_list[ml_idx[i]]))
+		i++;
+
+	/*
+	 * if i < num_ml then i is the SBS link, in this case disable the other
+	 * non SBS link, this mean ML STA is 5+6 or 2+5/6.
+	 */
+	if (i < num_ml) {
+		i = 0;
+		while (i < num_ml) {
+			if (!policy_mgr_are_sbs_chan(psoc, freq,
+						     freq_list[ml_idx[i]])) {
+				/* Affected non SBS ML STA link */
+				ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
+				return 1;
+			}
+			/* Fill non effected vdev in list */
+			ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
+			i++;
+		}
+		/* All link lead to SBS, disable any, This should not happen */
+		return i;
+	}
+
+check_dbs_ml:
+	/*
+	 * None of the link can lead to SBS, i.e. its 2+ 5/6 ML STA in this case
+	 * disable 5Ghz link.
+	 */
+	i = 0;
+	while (i < num_ml) {
+		if (!wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) {
+			/* Affected 5/6Ghz ML STA link */
+			ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
+			return 1;
+		}
+		/* Fill non effected vdev in list */
+		ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
+		i++;
+	}
+
+	/* No link affected, This should not happen */
+	return i;
+}
+
+/*
+ * policy_mgr_get_concurrent_num_links() - get links which are affected
+ * if no affected then return num ml. Also fills the ml_vdev_lst to send.
+ * @num_ml: number of ML vdev
+ * @freq_list: freq list of all vdev
+ * @vdev_id_list: vdev id list
+ * @ml_vdev_lst: ML vdev list
+ * @ml_idx: ML index
+ * @freq: non ML STA freq
+ *
+ * Return: number of the affected links, else total link and ml_vdev_lst list.
+ */
+static uint8_t
+policy_mgr_get_concurrent_num_links(struct wlan_objmgr_vdev *vdev,
+				    uint8_t num_ml, qdf_freq_t *freq_list,
+				    uint8_t *vdev_id_list,
+				    uint8_t *ml_vdev_lst,
+				    uint8_t *ml_idx, qdf_freq_t freq)
+{
+	uint8_t i = 0;
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+
+	if (!psoc)
+		return 0;
+
+	while (i < num_ml && (freq_list[ml_idx[i]] != freq))
+		i++;
+
+	if (i < num_ml) {
+		/* if one link is SCC then no need to disable any link */
+		policy_mgr_debug("vdev %d: ML vdev %d lead to SCC, STA freq %d ML freq %d, no need to disable link",
+				 wlan_vdev_get_id(vdev),
+				 vdev_id_list[ml_idx[i]],
+				 freq, freq_list[ml_idx[i]]);
+		return 0;
+	}
+
+	if (policy_mgr_is_hw_sbs_capable(psoc))
+		return policy_mgr_get_affected_links_for_sbs(psoc, num_ml,
+							     freq_list,
+							     vdev_id_list,
+							     ml_vdev_lst,
+							     ml_idx, freq);
+
+	/*
+	 * STA freq:      STA ML combo:  NON SBS Action:
+	 * -------------------------------------------------
+	 * 2Ghz           2Ghz+5/6Ghz    Disable 2Ghz (Same MAC)
+	 * 5Ghz           2Ghz+5/6Ghz    Disable 5Ghz (Same MAC)
+	 * 5Ghz           5Ghz+6Ghz      Disable Any of 5/6Ghz (Same MAC)
+	 * 2Ghz           5Ghz+6Ghz      Disable Any
+	 */
+	/*
+	 * Check if any of the link is on same MAC/band(for non SBS) as non ML
+	 * STA's freq. Same MAC/band mean both are either 5Ghz/6Ghz/2.4Ghz
+	 * OR both are non 2.4Ghz (ie one is 5Ghz and other is 6Ghz)
+	 */
+	i = 0;
+	while (i < num_ml &&
+	       !(wlan_reg_is_same_band_freqs(freq_list[ml_idx[i]], freq) ||
+		 (!wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]]) &&
+		  !wlan_reg_is_24ghz_ch_freq(freq)))) {
+		/* Fill non effected vdev in list */
+		ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
+		i++;
+	}
+
+	if (i < num_ml) {
+		/* affected ML link on the same MAC/band with non ML STA */
+		ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
+		return 1;
+	}
+
+	/* No link affected return num_ml to disable any */
+	return i;
+}
+
+static void
+policy_mgr_handle_sap_plus_ml_sta_connect(struct wlan_objmgr_psoc *psoc,
+					  struct wlan_objmgr_vdev *vdev)
+{
+	uint32_t sap_num = 0;
+	qdf_freq_t sap_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t sap_vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	bool is_ml_sbs;
+	uint8_t ml_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t num_ml;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+
+	sap_num = policy_mgr_get_mode_specific_conn_info(psoc, sap_freq_list,
+							 sap_vdev_id_list,
+							 PM_SAP_MODE);
+
+	policy_mgr_debug("vdev %d: sap_num %d sap_chan %d", vdev_id, sap_num,
+			 sap_freq_list[0]);
+	if (sap_num != 1)
+		return;
+
+	if (!wlan_reg_is_24ghz_ch_freq(sap_freq_list[0]))
+		return;
+	is_ml_sbs = policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE,
+						  ml_vdev_lst, &num_ml);
+	if (num_ml < 2)
+		return;
+
+	policy_mgr_debug("vdev %d: num_ml %d is_ml_sbs %d sap_chan %d", vdev_id,
+			 num_ml, is_ml_sbs, sap_freq_list[0]);
+
+	if (!is_ml_sbs) {
+		/*
+		 * re-enable both link in case if this was roaming from sbs to
+		 * dbs ML STA, with sap on 2.4Ghz.
+		 */
+		if (wlan_cm_is_vdev_roaming(vdev))
+			wlan_mlo_sta_mlo_concurency_set_link(vdev,
+					MLO_LINK_FORCE_REASON_DISCONNECT,
+					MLO_LINK_FORCE_MODE_NO_FORCE,
+					num_ml, ml_vdev_lst);
+
+		return;
+	}
+
+	/* If ML STA is SBS and SAP is 2.4Ghz, Disable one of the links. */
+	wlan_mlo_sta_mlo_concurency_set_link(vdev,
+					     MLO_LINK_FORCE_REASON_CONNECT,
+					     MLO_LINK_FORCE_MODE_ACTIVE_NUM,
+					     num_ml, ml_vdev_lst);
+}
+
+static void
+policy_mgr_ml_sta_concurency_on_connect(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_objmgr_vdev *vdev,
+				    uint8_t num_ml, uint8_t *ml_idx,
+				    uint8_t num_non_ml, uint8_t *non_ml_idx,
+				    qdf_freq_t *freq_list,
+				    uint8_t *vdev_id_list)
+{
+	qdf_freq_t freq = 0;
+	struct wlan_channel *bss_chan;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	uint8_t ml_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t affected_links = 0;
+	enum mlo_link_force_mode mode = MLO_LINK_FORCE_MODE_ACTIVE_NUM;
+
+	/* non ML STA doesn't exist, no need to change to link.*/
+	if (!num_non_ml) {
+		/* Check if SAP exist and any link change is required */
+		policy_mgr_handle_sap_plus_ml_sta_connect(psoc, vdev);
+		return;
+	}
+
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		freq = freq_list[non_ml_idx[0]];
+	} else {
+		bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
+		if (bss_chan)
+			freq = bss_chan->ch_freq;
+	}
+	policy_mgr_debug("vdev %d: Freq %d (non ML vdev id %d), is ML STA %d",
+			 vdev_id, freq, non_ml_idx[0],
+			 wlan_vdev_mlme_is_mlo_vdev(vdev));
+	if (!freq)
+		return;
+
+	affected_links =
+		policy_mgr_get_concurrent_num_links(vdev, num_ml, freq_list,
+						    vdev_id_list, ml_vdev_lst,
+						    ml_idx, freq);
+
+	if (!affected_links) {
+		policy_mgr_debug("vdev %d: no affected link found", vdev_id);
+		return;
+	}
+
+	/*
+	 * If affected link is less than num_ml, ie not all link are affected,
+	 * send MLO_LINK_FORCE_MODE_INACTIVE.
+	 */
+	if (affected_links < num_ml &&
+	    affected_links <= MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		if (mlo_is_sta_inactivity_allowed_with_quiet(psoc, vdev_id_list,
+							     num_ml, ml_idx,
+							     affected_links,
+							     ml_vdev_lst)) {
+			mode = MLO_LINK_FORCE_MODE_INACTIVE;
+		} else {
+			policy_mgr_debug("vdev %d: force inactivity is not allowed",
+					 ml_vdev_lst[0]);
+			return;
+		}
+	}
+
+	wlan_mlo_sta_mlo_concurency_set_link(vdev,
+					     MLO_LINK_FORCE_REASON_CONNECT,
+					     mode, affected_links,
+					     ml_vdev_lst);
+}
+
+static void
+policy_mgr_ml_sta_concurency_on_disconnect(struct wlan_objmgr_vdev *vdev,
+				       uint8_t num_ml, uint8_t *ml_idx,
+				       uint8_t num_non_ml,
+				       uint8_t *vdev_id_list)
+{
+	uint8_t i = 0;
+	uint8_t ml_vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+
+	/*
+	 * If non ML STA exist, no need to change to link.
+	 * Only change when legasy sta is disconnected and
+	 * only ML STA is present.
+	 */
+	if (num_non_ml)
+		return;
+
+	/*
+	 * On non ML STA disconnect if  MLO has >= 2 links, need to send
+	 * MLO_LINK_FORCE_MODE_NO_FORCE for all MLO Vdevs for letting FW enable
+	 * all the links.
+	 */
+	while (i < num_ml) {
+		ml_vdev_list[i] = vdev_id_list[ml_idx[i]];
+		i++;
+	}
+
+	wlan_mlo_sta_mlo_concurency_set_link(vdev,
+					     MLO_LINK_FORCE_REASON_DISCONNECT,
+					     MLO_LINK_FORCE_MODE_NO_FORCE,
+					     num_ml, ml_vdev_list);
+}
+
+void
+policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      bool is_connect)
+{
+	uint8_t num_ml = 0, num_non_ml = 0;
+	uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+
+	policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx,
+					       &num_non_ml, non_ml_idx,
+					       freq_list, vdev_id_list);
+
+	policy_mgr_debug("vdev %d: num_ml %d num_non_ml %d is_connect %d",
+			 wlan_vdev_get_id(vdev), num_ml, num_non_ml,
+			 is_connect);
+	/* ML STA is not up */
+	if (num_ml < 2 || num_ml > MAX_NUMBER_OF_CONC_CONNECTIONS)
+		return;
+
+	if (is_connect)
+		policy_mgr_ml_sta_concurency_on_connect(psoc, vdev, num_ml,
+						    ml_idx, num_non_ml,
+						    non_ml_idx, freq_list,
+						    vdev_id_list);
+	else
+		policy_mgr_ml_sta_concurency_on_disconnect(vdev, num_ml, ml_idx,
+						       num_non_ml,
+						       vdev_id_list);
+}
+
 #else
 static bool
 policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc,

+ 8 - 1
components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -469,7 +469,14 @@ static inline void
 wlan_handle_sap_mlo_sta_concurrency(struct wlan_objmgr_vdev *vdev,
 				    bool is_ap_up)
 {
-	csr_handle_sap_mlo_sta_concurrency(vdev, is_ap_up);
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+
+	if (!psoc) {
+		mlme_legacy_debug("psoc Null");
+		return;
+	}
+
+	policy_mgr_handle_sap_mlo_sta_concurrency(psoc, vdev, is_ap_up);
 }
 #else
 static inline void

+ 0 - 19
core/sme/inc/csr_api.h

@@ -956,25 +956,6 @@ QDF_STATUS csr_mlme_vdev_disconnect_all_p2p_client_event(uint8_t vdev_id);
  */
 QDF_STATUS csr_mlme_vdev_stop_bss(uint8_t vdev_id);
 
-/*
- * csr_mlme_handle_sap_mlo_sta_concurrency() - Handle SAP MLO STA concurrency
- *                                             such as:
- *       1) If MLO STA is present with both links in 5/6 Ghz then SAP comes up
- *          on 2.4 Ghz, then Disable one of the links
- *       2) If MLO STA is present with both links in 5/6 Ghz and SAP, which was
- *          present on 2.4 ghz, stops then renable both the as one of the links
- *          were disabled because of sap on 2.4 ghz.
- *
- * @vdev: vdev mlme object
- * @is_ap_up: bool to represent sap state
- *
- * Return: Void
- */
-#ifdef WLAN_FEATURE_11BE_MLO
-void csr_handle_sap_mlo_sta_concurrency(struct wlan_objmgr_vdev *vdev,
-					bool is_ap_up);
-#endif
-
 /*
  * csr_mlme_get_concurrent_operation_freq() - Callback for MLME module to
  *	get the concurrent operation frequency

+ 0 - 74
core/sme/src/csr/csr_util.c

@@ -1424,80 +1424,6 @@ QDF_STATUS csr_mlme_vdev_stop_bss(uint8_t vdev_id)
 				      eCSR_ROAM_RESULT_NONE);
 }
 
-#ifdef WLAN_FEATURE_11BE_MLO
-void csr_handle_sap_mlo_sta_concurrency(struct wlan_objmgr_vdev *vdev,
-					bool is_ap_up)
-{
-	uint8_t num_mlo = 0;
-	qdf_freq_t sap_chan = 0;
-	struct wlan_channel *bss_chan = NULL;
-	uint8_t mlo_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
-	bool is_mlo_sbs;
-	struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
-
-	if (!mac_ctx)
-		return;
-
-	is_mlo_sbs = policy_mgr_is_mlo_in_mode_sbs(mac_ctx->psoc, PM_STA_MODE,
-						   mlo_vdev_lst, &num_mlo);
-
-	if (num_mlo < 2) {
-		sme_debug("vdev %d AP_state %d MLO Sta links %d",
-			  wlan_vdev_get_id(vdev), is_ap_up, num_mlo);
-		return;
-	}
-
-	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
-	if (bss_chan)
-		sap_chan = bss_chan->ch_freq;
-	if (!sap_chan) {
-		sme_debug("Invalid SAP Chan");
-		return;
-	}
-
-	sme_debug("vdev %d: is_ap_up %d num_mlo %d is_mlo_sbs %d sap_chan %d",
-		  wlan_vdev_get_id(vdev), is_ap_up, num_mlo, is_mlo_sbs,
-		  sap_chan);
-
-	if (!is_mlo_sbs)
-		return;
-
-	if (is_ap_up) {
-		/*
-		 * During 2.4Ghz SAP up, If SBS MLO STA is present,
-		 * then Disable one of the links.
-		 */
-		if (wlan_reg_is_24ghz_ch_freq(sap_chan))
-			wlan_mlo_sta_mlo_concurency_set_link(vdev,
-						MLO_LINK_FORCE_REASON_CONNECT,
-						MLO_LINK_FORCE_MODE_ACTIVE_NUM,
-						num_mlo, mlo_vdev_lst);
-		/*
-		 * During 2.4Ghz SAP up, If there is channel switch for sap from
-		 * 2.4 ghz to 5 ghz, enable both the links, as one of them was
-		 * disabled by previous up operations when sap was on 2.4 ghz
-		 */
-		else
-			wlan_mlo_sta_mlo_concurency_set_link(vdev,
-						MLO_LINK_FORCE_REASON_CONNECT,
-						MLO_LINK_FORCE_MODE_NO_FORCE,
-						num_mlo, mlo_vdev_lst);
-
-		return;
-	}
-
-	/*
-	 * During 2.4Ghz SAP down, if SBS MLO STA is present, renable both the
-	 * links, as one of them was disabled during up.
-	 */
-	if (wlan_reg_is_24ghz_ch_freq(sap_chan))
-		wlan_mlo_sta_mlo_concurency_set_link(vdev,
-					MLO_LINK_FORCE_REASON_DISCONNECT,
-					MLO_LINK_FORCE_MODE_NO_FORCE,
-					num_mlo, mlo_vdev_lst);
-}
-#endif
-
 qdf_freq_t csr_mlme_get_concurrent_operation_freq(void)
 {
 	struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_SME);