Explorar o código

qcacmn: Add MLO bridge vdev APIs

Add MLO bridge vdev APIs to support 4 chip
RDP STA associations.

Change-Id: Iea4c4e3301bc29d470144d5ae0964bb80f2ae68d
CRs-Fixed: 3560194
Balaganapathy Palanisamy %!s(int64=2) %!d(string=hai) anos
pai
achega
9d048b9e4d

+ 83 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h

@@ -214,6 +214,7 @@ struct wlan_beacon_process {
  * @ref_cnt:           Ref count
  * @ref_id_dbg:        Array to track Ref count
  * @wlan_mlo_vdev_count: MLO VDEVs count
+ * @wlan_mlo_bridge_vdev_count: MLO bridge VDEVs count
  * @bcn:               Struct to keep track of beacon count
  */
 struct wlan_objmgr_pdev_objmgr {
@@ -231,6 +232,7 @@ struct wlan_objmgr_pdev_objmgr {
 	qdf_atomic_t ref_id_dbg[WLAN_REF_ID_MAX];
 #ifdef WLAN_FEATURE_11BE_MLO
 	qdf_atomic_t wlan_mlo_vdev_count;
+	qdf_atomic_t wlan_mlo_bridge_vdev_count;
 #endif
 	struct wlan_beacon_process bcn;
 };
@@ -1397,6 +1399,66 @@ void wlan_pdev_dec_mlo_vdev_count(struct wlan_objmgr_pdev *pdev)
 
 	qdf_atomic_dec(&pdev->pdev_objmgr.wlan_mlo_vdev_count);
 }
+
+/**
+ * wlan_pdev_init_mlo_bridge_vdev_count() - Initialize PDEV MLO bridge
+ *					    vdev count
+ * @pdev: PDEV object
+ *
+ * API to initialize MLO bridge vdev count from PDEV
+ *
+ * Return: void
+ */
+static inline
+void wlan_pdev_init_mlo_bridge_vdev_count(struct wlan_objmgr_pdev *pdev)
+{
+	qdf_atomic_init(&pdev->pdev_objmgr.wlan_mlo_bridge_vdev_count);
+}
+
+/**
+ * wlan_pdev_get_mlo_bridge_vdev_count() - get PDEV MLO bridge vdev count
+ * @pdev: PDEV object
+ *
+ * API to get MLO bridge vdev count from PDEV
+ *
+ * Return: MLO vdev_count - pdev's MLO bridge vdev count
+ */
+static inline
+uint32_t wlan_pdev_get_mlo_bridge_vdev_count(struct wlan_objmgr_pdev *pdev)
+{
+	return qdf_atomic_read(&pdev->pdev_objmgr.wlan_mlo_bridge_vdev_count);
+}
+
+/**
+ * wlan_pdev_inc_mlo_bridge_vdev_count() - Increment PDEV MLO bridge vdev count
+ * @pdev: PDEV object
+ *
+ * API to increment MLO bridge vdev count from PDEV
+ *
+ * Return: void
+ */
+static inline
+void wlan_pdev_inc_mlo_bridge_vdev_count(struct wlan_objmgr_pdev *pdev)
+{
+	qdf_atomic_inc(&pdev->pdev_objmgr.wlan_mlo_bridge_vdev_count);
+}
+
+/**
+ * wlan_pdev_dec_mlo_bridge_vdev_count() - Decrement PDEV MLO bridge vdev count
+ * @pdev: PDEV object
+ *
+ * API to decrement MLO bridge vdev count from PDEV
+ *
+ * Return: void
+ */
+static inline
+void wlan_pdev_dec_mlo_bridge_vdev_count(struct wlan_objmgr_pdev *pdev)
+{
+	qdf_assert_always
+	(qdf_atomic_read(&pdev->pdev_objmgr.wlan_mlo_bridge_vdev_count));
+
+	qdf_atomic_dec(&pdev->pdev_objmgr.wlan_mlo_bridge_vdev_count);
+}
 #else
 static inline
 void wlan_pdev_init_mlo_vdev_count(struct wlan_objmgr_pdev *pdev)
@@ -1418,6 +1480,27 @@ static inline
 void wlan_pdev_dec_mlo_vdev_count(struct wlan_objmgr_pdev *pdev)
 {
 }
+
+static inline
+void wlan_pdev_init_mlo_bridge_vdev_count(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+uint32_t wlan_pdev_get_mlo_bridge_vdev_count(struct wlan_objmgr_pdev *pdev)
+{
+	return 0;
+}
+
+static inline
+void wlan_pdev_inc_mlo_bridge_vdev_count(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+void wlan_pdev_dec_mlo_bridge_vdev_count(struct wlan_objmgr_pdev *pdev)
+{
+}
 #endif /* WLAN_FEATURE_11BE_MLO */
 
 /**

+ 1 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c

@@ -140,6 +140,7 @@ struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create(
 	pdev->pdev_objmgr.temp_peer_count = 0;
 	pdev->pdev_objmgr.max_peer_count = wlan_psoc_get_max_peer_count(psoc);
 	wlan_pdev_init_mlo_vdev_count(pdev);
+	wlan_pdev_init_mlo_bridge_vdev_count(pdev);
 	/* Save HDD/OSIF pointer */
 	pdev->pdev_nif.pdev_ospriv = osdev_priv;
 	qdf_atomic_init(&pdev->pdev_objmgr.ref_cnt);

+ 5 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h

@@ -129,6 +129,11 @@ enum MLO_SOC_LIST {
 #define MAX_MLO_CHIPS 5
 #define MAX_ADJ_CHIPS 2
 
+/* MLO Bridge link */
+#define MLO_NUM_CHIPS_FOR_BRIDGE_LINK 4
+#define MLO_MAX_BRIDGE_LINKS_PER_MLD 2
+#define MLO_MAX_BRIDGE_LINKS_PER_RADIO 8
+
 /**
  * struct mlo_chip_info: MLO chip info per link
  * @info_valid: If the info here is valid or not

+ 12 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_setup.h

@@ -250,6 +250,18 @@ QDF_STATUS mlo_check_all_pdev_state(struct wlan_objmgr_psoc *psoc,
  */
 void mlo_update_tsf_sync_support(struct wlan_objmgr_psoc *psoc,
 				 bool tsf_sync_enab);
+
+/**
+ * mlo_pdev_derive_bridge_link_pdevs() - API to get the list of pdevs
+ *					 for creating bridge vdevs.
+ *
+ * @pdev: pdev of the mlo group
+ * @pdev_list: list where pdevs for creating bridge vdevs need to be populated
+ *
+ * Return: true if success otherwise false.
+ */
+bool mlo_pdev_derive_bridge_link_pdevs(struct wlan_objmgr_pdev *pdev,
+				       struct wlan_objmgr_pdev **pdev_list);
 #else
 static inline void mlo_setup_init(uint8_t total_grp)
 {

+ 3 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_ap.c

@@ -49,7 +49,9 @@ bool mlo_ap_vdev_attach(struct wlan_objmgr_vdev *vdev,
 
 	dev_ctx = vdev->mlo_dev_ctx;
 	wlan_vdev_set_link_id(vdev, link_id);
-	wlan_vdev_mlme_set_mlo_vdev(vdev);
+
+	if (!vdev->vdev_objmgr.mlo_bridge_vdev)
+		wlan_vdev_mlme_set_mlo_vdev(vdev);
 
 	/*
 	 * every link will trigger mlo_ap_vdev_attach,

+ 90 - 0
umac/mlo_mgr/src/wlan_mlo_mgr_setup.c

@@ -1161,4 +1161,94 @@ void mlo_update_tsf_sync_support(struct wlan_objmgr_psoc *psoc,
 }
 
 qdf_export_symbol(mlo_update_tsf_sync_support);
+
+bool mlo_pdev_derive_bridge_link_pdevs(struct wlan_objmgr_pdev *pdev,
+				       struct wlan_objmgr_pdev **pdev_list)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_psoc *grp_soc_list[MAX_MLO_CHIPS];
+	struct wlan_objmgr_pdev *tmp_pdev;
+	uint8_t tot_grp_socs;
+	uint8_t grp_id;
+	uint8_t psoc_id, tmp_psoc_id;
+	uint8_t idx;
+	uint8_t is_adjacent;
+	QDF_STATUS status;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+
+	/* Initialize pdev list to NULL by default */
+	for (idx = 0; idx < MLO_MAX_BRIDGE_LINKS_PER_MLD; idx++)
+		pdev_list[idx] = NULL;
+
+	if (!mlo_psoc_get_grp_id(psoc, &grp_id)) {
+		qdf_err("Unable to get group id");
+		return false;
+	}
+
+	/* Get the total SOCs in the MLO group */
+	tot_grp_socs = mlo_setup_get_total_socs(grp_id);
+	if (!tot_grp_socs || tot_grp_socs > MAX_MLO_CHIPS) {
+		qdf_err("Unable to get total SOCs");
+		return false;
+	}
+	qdf_info("Total SOCs in MLO group%d: %d", grp_id, tot_grp_socs);
+
+	/* Get the SOC list in the MLO group */
+	mlo_get_soc_list(grp_soc_list, grp_id, tot_grp_socs,
+			 WLAN_MLO_GROUP_DEFAULT_SOC_LIST);
+
+	psoc_id = wlan_psoc_get_id(psoc);
+
+	/*
+	 * Check the current pdev for num bridge links created and
+	 * add to the pdev list if possible otherwise find opposite pdev
+	 */
+	if (wlan_pdev_get_mlo_bridge_vdev_count(pdev)
+	    < MLO_MAX_BRIDGE_LINKS_PER_RADIO)
+		pdev_list[0] = pdev;
+
+	/*
+	 * Iterate over the MLO group SOC list
+	 * and get the pdevs for bridge links
+	 */
+	for (idx = 0; idx < tot_grp_socs; idx++) {
+		if (!grp_soc_list[idx])
+			continue;
+
+		if (grp_soc_list[idx] == psoc)
+			continue;
+
+		/* Skip the pdev if bridge link quota is over */
+		tmp_pdev = grp_soc_list[idx]->soc_objmgr.wlan_pdev_list[0];
+
+		if (wlan_pdev_get_mlo_bridge_vdev_count(tmp_pdev)
+		    >= MLO_MAX_BRIDGE_LINKS_PER_RADIO)
+			continue;
+
+		tmp_psoc_id = wlan_psoc_get_id(grp_soc_list[idx]);
+
+		qdf_info("Checking adjacency of soc %d and %d",
+			 psoc_id, tmp_psoc_id);
+		status = mlo_chip_adjacent(psoc_id, tmp_psoc_id, &is_adjacent);
+		if (status != QDF_STATUS_SUCCESS) {
+			qdf_info("Check adjacency failed");
+			return false;
+		}
+
+		if (is_adjacent) {
+			if (!pdev_list[1])
+				pdev_list[1] = tmp_pdev;
+		} else if (!pdev_list[0]) {
+			pdev_list[0] = tmp_pdev;
+		}
+
+		if (pdev_list[0] && pdev_list[1])
+			return true;
+	}
+
+	return false;
+}
+
+qdf_export_symbol(mlo_pdev_derive_bridge_link_pdevs);
 #endif /*WLAN_MLO_MULTI_CHIP*/