Kaynağa Gözat

qcacmn: Connect if pri_umac & assoc link are same

Some devices in WDS station mode have limitation when connected
in 3 LINK MLD association where the Primary umac selected and assoc
link should be same. Make sure to have a sanity check before
going for association in such cases.

If the primary umac and assoc links are set to be different then
the connection will be rejected.

Change-Id: If56461a140d4685ba279b1babe04709d919d1650
CRs-Fixed: 3443733
Uraj Sasan 2 yıl önce
ebeveyn
işleme
ab8cf64ef0

+ 46 - 0
os_if/linux/mlme/src/osif_cm_req.c

@@ -33,6 +33,10 @@
 #endif
 #include <wlan_mlo_mgr_sta.h>
 #include <utils_mlo.h>
+#include <wlan_mgmt_txrx_rx_reo_utils_api.h>
+#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
+#include <wlan_mlo_mgr_setup.h>
+#endif
 
 static void osif_cm_free_wep_key_params(struct wlan_cm_connect_req *connect_req)
 {
@@ -526,6 +530,12 @@ QDF_STATUS osif_update_mlo_partner_info(
 	uint8_t linkid = 0;
 	enum wlan_ml_variant variant;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t psoc_ids[WLAN_UMAC_MLO_MAX_VDEVS];
+	uint8_t i, idx = 0;
+	uint8_t central_umac_id;
+	uint8_t tot_grp_socs, ml_grp_id;
+	struct wlan_objmgr_pdev *pdev = NULL;
+	struct wlan_objmgr_vdev *vdev_iter;
 
 	if (!vdev || !connect_req || !req)
 		return status;
@@ -534,6 +544,12 @@ QDF_STATUS osif_update_mlo_partner_info(
 		osif_debug("ML ctx is NULL, ignore ML IE");
 		return QDF_STATUS_SUCCESS;
 	}
+	pdev = wlan_vdev_get_pdev(vdev);
+
+	if (!pdev) {
+		osif_debug("null pdev");
+		return QDF_STATUS_SUCCESS;
+	}
 
 	osif_debug("ML IE search start");
 	if (req->ie_len) {
@@ -597,6 +613,36 @@ QDF_STATUS osif_update_mlo_partner_info(
 		mlo_clear_connect_req_links_bmap(vdev);
 		mlo_update_connect_req_links(vdev, 1);
 		osif_update_partner_vdev_info(vdev, partner_info);
+
+		/* Incase of 4-LINK RDP in 3-LINK NON-AP MLD mode there is
+		 * restriction to have the primary umac and association
+		 * link to be same.
+		 * Note: It also means restriction on umac migration
+		 */
+		ml_grp_id = wlan_get_mlo_grp_id_from_pdev(pdev);
+		tot_grp_socs = mlo_setup_get_total_socs(ml_grp_id);
+		if (tot_grp_socs == WLAN_UMAC_MLO_MAX_VDEVS) {
+			for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
+				vdev_iter = vdev->mlo_dev_ctx->wlan_vdev_list[i];
+				if (!vdev_iter)
+					continue;
+				/* Store the psoc_ids of the links */
+				psoc_ids[idx] = wlan_vdev_get_psoc_id(vdev_iter);
+				idx++;
+			}
+			/* Check if the primary umac and assoc links are same */
+			if (idx == WLAN_UMAC_MLO_ASSOC_MAX_SUPPORTED_LINKS) {
+				central_umac_id = mlo_get_central_umac_id(psoc_ids);
+				if (central_umac_id != -1) {
+					if (wlan_vdev_get_psoc_id(vdev) != central_umac_id) {
+						osif_err("Rejecting connection as primary umac soc %d and assoc link %d are different ",
+							 central_umac_id, wlan_vdev_get_psoc_id(vdev));
+						return QDF_STATUS_E_FAILURE;
+					}
+				}
+			}
+		}
+
 		mlo_mlme_sta_op_class(vdev, ml_ie);
 	}
 

+ 11 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h

@@ -164,6 +164,17 @@ bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev);
 void ucfg_mlo_mld_clear_mlo_cap(struct wlan_objmgr_vdev *vdev);
 #endif
 
+#ifdef WLAN_MLO_MULTI_CHIP
+/**
+ * mlo_get_central_umac_id - get central umac in 3 link topology
+ * @psoc_ids: pointer to psoc_ids
+ *
+ * Return: central umac if success, -1 all soc are adjacent to each other
+ */
+
+int8_t mlo_get_central_umac_id(uint8_t *psoc_ids);
+#endif
+
 /**
  * wlan_mlo_get_tdls_link_vdev() - API to get tdls link vdev
  * @vdev: vdev object

+ 32 - 13
umac/mlo_mgr/src/wlan_mlo_mgr_primary_umac.c

@@ -455,25 +455,17 @@ static void mlo_peer_calculate_avg_rssi(
 }
 
 #ifdef WLAN_MLO_MULTI_CHIP
-static QDF_STATUS mlo_set_3_link_primary_umac(
-		struct wlan_mlo_peer_context *ml_peer,
-		struct wlan_objmgr_vdev *link_vdevs[])
+int8_t mlo_get_central_umac_id(
+		uint8_t *psoc_ids)
 {
-	uint8_t prim_psoc_id, psoc_ids[MAX_MLO_CHIPS];
+	uint8_t prim_psoc_id = -1;
 	uint8_t adjacent = 0;
 
-	if (ml_peer->max_links != 3)
-		return QDF_STATUS_E_FAILURE;
-
 	/* Some 3 link RDPs have restriction on the primary umac.
 	 * Only the link that is adjacent to both the links can be
 	 * a primary umac.
 	 * Note: it means umac migration is also restricted.
 	 */
-	psoc_ids[0] = wlan_vdev_get_psoc_id(link_vdevs[0]);
-	psoc_ids[1] = wlan_vdev_get_psoc_id(link_vdevs[1]);
-	psoc_ids[2] = wlan_vdev_get_psoc_id(link_vdevs[2]);
-
 	mlo_chip_adjacent(psoc_ids[0], psoc_ids[1], &adjacent);
 	if (!adjacent) {
 		prim_psoc_id = psoc_ids[2];
@@ -491,11 +483,38 @@ static QDF_STATUS mlo_set_3_link_primary_umac(
 			if (!adjacent)
 				prim_psoc_id = psoc_ids[0];
 			else
-				return QDF_STATUS_E_FAILURE;
+				return prim_psoc_id;
 		}
 	}
 
-	ml_peer->primary_umac_psoc_id = prim_psoc_id;
+	return prim_psoc_id;
+}
+
+static QDF_STATUS mlo_set_3_link_primary_umac(
+		struct wlan_mlo_peer_context *ml_peer,
+		struct wlan_objmgr_vdev *link_vdevs[])
+{
+	uint8_t psoc_ids[WLAN_UMAC_MLO_MAX_VDEVS];
+	int8_t central_umac_id;
+
+	if (ml_peer->max_links != 3)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Some 3 link RDPs have restriction on the primary umac.
+	 * Only the link that is adjacent to both the links can be
+	 * a primary umac.
+	 * Note: it means umac migration is also restricted.
+	 */
+	psoc_ids[0] = wlan_vdev_get_psoc_id(link_vdevs[0]);
+	psoc_ids[1] = wlan_vdev_get_psoc_id(link_vdevs[1]);
+	psoc_ids[2] = wlan_vdev_get_psoc_id(link_vdevs[2]);
+
+	central_umac_id = mlo_get_central_umac_id(psoc_ids);
+	if (central_umac_id != -1)
+		ml_peer->primary_umac_psoc_id = central_umac_id;
+	else
+		return QDF_STATUS_E_FAILURE;
+
 	mlo_peer_assign_primary_umac(ml_peer,
 				     &ml_peer->peer_list[0]);