瀏覽代碼

qcacmn: WDS STATION send bridge partner details

Send bridge partner details during peer create and peer
assoc. The partner of bridge peer are saved which are used later
during bridge peer create and assoc. Also add bridge peer partner
details while sending peer create and assoc on actual links.

CRs-Fixed: 3574656
Change-Id: I755614a131f6552ac28377d2c7648db4fd87b8df
Uraj Sasan 1 年之前
父節點
當前提交
082bbef13c

+ 21 - 4
os_if/linux/mlme/src/osif_cm_req.c

@@ -461,11 +461,17 @@ void osif_update_partner_vdev_info(struct wlan_objmgr_vdev *vdev,
 				   struct mlo_partner_info partner_info)
 {
 	struct wlan_objmgr_vdev *tmp_vdev;
+	struct wlan_mlo_dev_context *ml_dev = NULL;
 	uint8_t i;
+	uint8_t link_id;
 
 	if (!vdev)
 		return;
 
+	ml_dev = vdev->mlo_dev_ctx;
+	if (!ml_dev)
+		return;
+
 	for (i = 0; i < partner_info.num_partner_links; i++) {
 		tmp_vdev = mlo_get_ml_vdev_by_mac(
 				vdev,
@@ -474,9 +480,14 @@ void osif_update_partner_vdev_info(struct wlan_objmgr_vdev *vdev,
 			mlo_update_connect_req_links(tmp_vdev, 1);
 			wlan_vdev_mlme_set_mlo_vdev(tmp_vdev);
 			wlan_vdev_mlme_set_mlo_link_vdev(tmp_vdev);
-			wlan_vdev_set_link_id(
-				tmp_vdev,
-				partner_info.partner_link_info[i].link_id);
+			/* Set link id for bridge sta vap */
+			if (mlo_is_sta_bridge_vdev(tmp_vdev)) {
+				link_id = ml_dev->bridge_sta_ctx->bridge_link_id;
+				wlan_vdev_set_link_id(tmp_vdev, link_id);
+			} else
+				wlan_vdev_set_link_id(
+					tmp_vdev,
+					partner_info.partner_link_info[i].link_id);
 			osif_debug("link id %d",
 				   tmp_vdev->vdev_mlme.mlo_link_id);
 		}
@@ -501,11 +512,13 @@ QDF_STATUS osif_update_mlo_partner_info(
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct wlan_objmgr_pdev *pdev = NULL;
 	struct wlan_objmgr_psoc *psoc;
+	struct wlan_mlo_dev_context *ml_dev = NULL;
 
 	if (!vdev || !connect_req || !req)
 		return status;
 
-	if (!vdev->mlo_dev_ctx) {
+	ml_dev = vdev->mlo_dev_ctx;
+	if (!ml_dev) {
 		osif_debug("ML ctx is NULL, ignore ML IE");
 		return QDF_STATUS_SUCCESS;
 	}
@@ -591,6 +604,10 @@ QDF_STATUS osif_update_mlo_partner_info(
 			osif_err("Topology check failed prevent association\n");
 			return QDF_STATUS_E_FAILURE;
 		}
+
+		if (mlo_sta_bridge_exists(vdev))
+			mlo_update_partner_bridge_info(ml_dev, &partner_info);
+
 		mlo_update_connect_req_links(vdev, 1);
 		osif_update_partner_vdev_info(vdev, partner_info);
 		mlo_mlme_sta_op_class(vdev, ml_ie);

+ 20 - 14
umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h

@@ -747,20 +747,6 @@ struct wlan_mlo_dev_context {
 	struct mlo_link_switch_context *link_ctx;
 };
 
-/**
- * struct wlan_mlo_bridge_sta - MLO bridge sta context
- * @bridge_umac_id: umac id for bridge
- * @bridge_link_id: link id used by bridge vdev
- * @is_force_central_primary: Flag to tell if bridge should be primary umac
- * @bridge_vap_exists: If there is bridge vap
- */
-struct wlan_mlo_bridge_sta {
-	uint8_t bridge_umac_id;
-	uint8_t bridge_link_id;
-	bool is_force_central_primary;
-	bool bridge_vap_exists;
-};
-
 /**
  * struct wlan_mlo_link_peer_entry - Link peer entry
  * @link_peer: Object manager peer
@@ -1039,6 +1025,26 @@ struct mlo_tgt_partner_info {
 	struct mlo_tgt_link_info link_info[WLAN_UMAC_MLO_MAX_VDEVS];
 };
 
+/**
+ * struct wlan_mlo_bridge_sta - MLO bridge sta context
+ * @bridge_partners: mlo_partner_info of partners of a bridge
+ * @bridge_ml_links: mlo_tgt_partner_info of partners of bridge
+ * @bridge_umac_id: umac id for bridge
+ * @bridge_link_id: link id used by bridge vdev
+ * @is_force_central_primary: Flag to tell if bridge should be primary umac
+ * @bridge_vap_exists: If there is bridge vap
+ * @bridge_node_auth: Is bridge node auth done
+ */
+struct wlan_mlo_bridge_sta {
+	struct mlo_partner_info bridge_partners;
+	struct mlo_tgt_partner_info bridge_ml_links;
+	uint8_t bridge_umac_id;
+	uint8_t bridge_link_id;
+	bool is_force_central_primary;
+	bool bridge_vap_exists;
+	bool bridge_node_auth;
+};
+
 /**
  * struct mlo_mlme_ext_ops - MLME callback functions
  * @mlo_mlme_ext_validate_conn_req: Callback to validate connect request

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

@@ -186,6 +186,33 @@ int8_t mlo_get_central_umac_id(uint8_t *psoc_ids);
 QDF_STATUS mlo_check_topology(struct wlan_objmgr_pdev *pdev,
 			      struct wlan_objmgr_vdev *vdev,
 			      uint8_t aplinks);
+/**
+ * mlo_update_partner_bridge_info() - Update parter info of bridge vap
+ * @ml_dev: ML dev context
+ * @partner_info: partner info that needs to be updated
+ *
+ * Return: none
+ */
+
+void mlo_update_partner_bridge_info(struct wlan_mlo_dev_context *ml_dev,
+				    struct mlo_partner_info *partner_info);
+
+/**
+ * mlo_is_sta_bridge_vdev() - Check if the vdev is sta bridge vdev
+ * @vdev: vdev pointer
+ *
+ * Return: True if STA bridge vdev else false
+ */
+
+bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlo_sta_bridge_exists() - Check if bridge vdev exists in a STA MLD
+ * @vdev: vdev pointer
+ *
+ * Return: True if Bridge Vdev exists else false
+ */
+bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev);
 
 /**
  * mlo_get_total_links() - get total links supported by device

+ 58 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_primary_umac.c

@@ -59,6 +59,8 @@ struct mlo_all_link_rssi {
 #define ML_PRIMARY_TQM_CONGESTION 30
 /* PTQM migration timeout value in ms */
 #define ML_PRIMARY_TQM_MIGRATRION_TIMEOUT 4000
+/* Link ID used for WDS Bridge*/
+#define WDS_BRIDGE_VDEV_LINK_ID (WLAN_LINK_ID_INVALID - 1)
 
 static void wlan_mlo_peer_get_rssi(struct wlan_objmgr_psoc *psoc,
 				   void *obj, void *args)
@@ -691,7 +693,7 @@ QDF_STATUS mlo_check_topology(struct wlan_objmgr_pdev *pdev,
 						ml_dev->bridge_sta_ctx->is_force_central_primary = true;
 						ml_dev->bridge_sta_ctx->bridge_umac_id = bridge_umac;
 						ml_dev->bridge_sta_ctx->bridge_vap_exists = true;
-						ml_dev->bridge_sta_ctx->bridge_link_id = link_id;
+						ml_dev->bridge_sta_ctx->bridge_link_id = WDS_BRIDGE_VDEV_LINK_ID;
 					}
 				}
 			}
@@ -702,6 +704,61 @@ QDF_STATUS mlo_check_topology(struct wlan_objmgr_pdev *pdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+void mlo_update_partner_bridge_info(struct wlan_mlo_dev_context *ml_dev,
+				    struct mlo_partner_info *partner_info)
+{
+	struct wlan_objmgr_vdev *bridge_vdev = NULL;
+	uint8_t bridge_umac_id = -1;
+	uint8_t bridge_index = partner_info->num_partner_links;
+
+	if (!ml_dev || !ml_dev->bridge_sta_ctx)
+		return;
+
+	bridge_umac_id = ml_dev->bridge_sta_ctx->bridge_umac_id;
+	bridge_vdev = mlo_get_link_vdev_from_psoc_id(ml_dev, bridge_umac_id, false);
+	if (bridge_vdev) {
+		partner_info->partner_link_info[bridge_index].link_id = bridge_vdev->vdev_mlme.mlo_link_id;
+		qdf_mem_copy(&partner_info->partner_link_info[bridge_index].link_addr,
+			     wlan_vdev_mlme_get_macaddr(bridge_vdev), sizeof(struct qdf_mac_addr));
+		/* Account for bridge peer here */
+		partner_info->num_partner_links++;
+		wlan_objmgr_vdev_release_ref(bridge_vdev, WLAN_MLO_MGR_ID);
+	}
+}
+
+bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev)
+{
+#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
+	struct wlan_mlo_dev_context *ml_dev = vdev->mlo_dev_ctx;
+
+	if (!ml_dev || !ml_dev->bridge_sta_ctx)
+		return false;
+
+	if (vdev->vdev_objmgr.mlo_central_vdev &&
+	    ml_dev->bridge_sta_ctx->bridge_vap_exists)
+		return true;
+#endif
+	return false;
+}
+
+qdf_export_symbol(mlo_is_sta_bridge_vdev);
+
+bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev)
+{
+#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
+	struct wlan_mlo_dev_context *ml_dev = vdev->mlo_dev_ctx;
+
+	if (!ml_dev || !ml_dev->bridge_sta_ctx)
+		return false;
+
+	if (ml_dev->bridge_sta_ctx->bridge_vap_exists)
+		return true;
+#endif
+	return false;
+}
+
+qdf_export_symbol(mlo_sta_bridge_exists);
+
 uint8_t mlo_get_total_links(struct wlan_objmgr_pdev *pdev)
 {
 	uint8_t ml_grp_id;