Sfoglia il codice sorgente

qcacmn: Handle bridge peer creation in WDS station

Handle case where device topology needs bridge peer.
So if the device have connection on two opposite links
create bridge peer on the central vap.
Sample topology:
AP
2 GHz<-->6 GHz MLO Links
STA topology
       (5 GHz Low VAP)
         chip0
      /         \
 (2 GHz VAP)chip1    chip2 (6 GHz VAP)
      \         /
         chip3
       (5 GHz High VAP)
In the above case we will have Bridge peer on either
5 GHz Low or 5 GHz High VAP

CRs-Fixed: 3575939
Change-Id: I923cc01b3c6e23099436a25565cbabab5a08d93c
Uraj Sasan 1 anno fa
parent
commit
85dafccb66

+ 54 - 2
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -570,6 +570,7 @@ cm_candidate_mlo_update(struct scan_cache_entry *scan_entry,
 	validate_bss_info->is_mlo = !!scan_entry->ie_list.multi_link_bv;
 	validate_bss_info->scan_entry = scan_entry;
 }
+
 #else
 static inline
 void cm_set_vdev_link_id(struct cnx_mgr *cm_ctx,
@@ -612,6 +613,20 @@ static void cm_create_bss_peer(struct cnx_mgr *cm_ctx,
 		mlme_err("invalid cm_ctx");
 		return;
 	}
+
+	if (mlo_is_sta_bridge_vdev(cm_ctx->vdev) && req) {
+		/* Acquire lock as required by wlan_vdev_mlme_get_mldaddr() */
+		wlan_vdev_obj_lock(cm_ctx->vdev);
+		bssid = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(cm_ctx->vdev);
+		wlan_vdev_obj_unlock(cm_ctx->vdev);
+		mld_mac = mlo_get_sta_ctx_bss_mld_addr(cm_ctx->vdev);
+		status = mlme_cm_bss_peer_create_req(cm_ctx->vdev,
+						     bssid,
+						     mld_mac,
+						     is_assoc_link);
+		goto peer_create_fail;
+	}
+
 	if (!req || !req->cur_candidate || !req->cur_candidate->entry) {
 		mlme_err("invalid req");
 		return;
@@ -624,12 +639,14 @@ static void cm_create_bss_peer(struct cnx_mgr *cm_ctx,
 		cm_set_vdev_link_id(cm_ctx, req);
 		wlan_mlo_init_cu_bpcc(cm_ctx->vdev);
 		mld_mac = cm_get_bss_peer_mld_addr(req);
+		mlo_set_sta_ctx_bss_mld_addr(cm_ctx->vdev, mld_mac);
 		is_assoc_link = cm_bss_peer_is_assoc_peer(req);
 	}
 
 	bssid = &req->cur_candidate->entry->bssid;
 	status = mlme_cm_bss_peer_create_req(cm_ctx->vdev, bssid,
 					     mld_mac, is_assoc_link);
+peer_create_fail:
 	if (QDF_IS_STATUS_ERROR(status)) {
 		struct wlan_cm_connect_resp *resp;
 		uint8_t vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
@@ -1782,6 +1799,15 @@ QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx,
 		}
 	}
 
+	if (mlo_is_sta_bridge_vdev(cm_ctx->vdev)) {
+		status = cm_ser_connect_req(pdev, cm_ctx, cm_req);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			reason = CM_SER_FAILURE;
+			goto connect_err;
+		}
+
+		return QDF_STATUS_SUCCESS;
+	}
 	status = cm_connect_get_candidates(pdev, cm_ctx, cm_req);
 
 	/* In case of status pending connect will continue after scan */
@@ -2265,7 +2291,11 @@ QDF_STATUS cm_connect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 	cm_fill_vdev_crypto_params(cm_ctx, req);
 	cm_store_wep_key(cm_ctx, &req->crypto, *cm_id);
 
-	status = cm_get_valid_candidate(cm_ctx, cm_req, NULL, NULL);
+	if (mlo_is_sta_bridge_vdev(cm_ctx->vdev))
+		status = QDF_STATUS_SUCCESS;
+	else
+		status = cm_get_valid_candidate(cm_ctx, cm_req, NULL, NULL);
+
 	if (QDF_IS_STATUS_ERROR(status))
 		goto connect_err;
 
@@ -2517,6 +2547,7 @@ cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 	struct security_info *neg_sec_info;
 	uint8_t country_code[REG_ALPHA2_LEN + 1] = {0};
 	struct wlan_objmgr_psoc *psoc;
+	struct cm_connect_req *conn_req = NULL;
 
 	psoc = wlan_pdev_get_psoc(wlan_vdev_get_pdev(cm_ctx->vdev));
 
@@ -2524,6 +2555,27 @@ cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 	if (!cm_req)
 		return QDF_STATUS_E_FAILURE;
 
+	conn_req = &cm_req->connect_req;
+	/* Handle WDS bridge vdev */
+	if (mlo_is_sta_bridge_vdev(cm_ctx->vdev) && conn_req) {
+		req.vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
+		req.cm_id = *cm_id;
+		req.force_rsne_override = conn_req->req.force_rsne_override;
+		req.is_wps_connection = conn_req->req.is_wps_connection;
+		req.is_osen_connection = conn_req->req.is_osen_connection;
+		req.assoc_ie = conn_req->req.assoc_ie;
+		req.scan_ie = conn_req->req.scan_ie;
+		cm_copy_fils_info(&req, cm_req);
+		req.ht_caps = conn_req->req.ht_caps;
+		req.ht_caps_mask = conn_req->req.ht_caps_mask;
+		req.vht_caps = conn_req->req.vht_caps;
+		req.vht_caps_mask = conn_req->req.vht_caps_mask;
+		req.is_non_assoc_link = conn_req->req.is_non_assoc_link;
+		cm_update_ml_partner_info(cm_ctx->vdev, &conn_req->req, &req);
+		wlan_reg_get_cc_and_src(psoc, country_code);
+		goto connect_req;
+	}
+
 	/*
 	 * As keymgmt and ucast cipher can be multiple.
 	 * Choose one keymgmt and one ucastcipherset based on higher security.
@@ -2567,7 +2619,7 @@ cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 		       req.is_osen_connection, req.force_rsne_override,
 		       country_code[0],
 		       country_code[1]);
-
+connect_req:
 	status = mlme_cm_connect_req(cm_ctx->vdev, &req);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		mlme_err(CM_PREFIX_FMT "connect request failed",

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

@@ -1038,6 +1038,7 @@ struct mlo_tgt_partner_info {
  * @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
+ * @bss_mld_addr: MLD address of the BSS
  */
 struct wlan_mlo_bridge_sta {
 	struct mlo_partner_info bridge_partners;
@@ -1047,6 +1048,7 @@ struct wlan_mlo_bridge_sta {
 	bool is_force_central_primary;
 	bool bridge_vap_exists;
 	bool bridge_node_auth;
+	struct qdf_mac_addr bss_mld_addr;
 };
 
 /**

+ 124 - 5
umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h

@@ -196,6 +196,14 @@ QDF_STATUS mlo_check_topology(struct wlan_objmgr_pdev *pdev,
 
 void mlo_update_partner_bridge_info(struct wlan_mlo_dev_context *ml_dev,
 				    struct mlo_partner_info *partner_info);
+/**
+ * mlo_get_total_links() - get total links supported by device
+ * @pdev: pdev pointer
+ *
+ * Return: Number of total links supported
+ */
+
+uint8_t mlo_get_total_links(struct wlan_objmgr_pdev *pdev);
 
 /**
  * mlo_is_sta_bridge_vdev() - Check if the vdev is sta bridge vdev
@@ -215,15 +223,97 @@ bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev);
 bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev);
 
 /**
- * mlo_get_total_links() - get total links supported by device
- * @pdev: pdev pointer
+ * mlo_is_force_central_primary() - Check if central vdev is forced
+ * as primary
+ * @vdev: vdev pointer
  *
- * Return: Number of total links supported
+ * Return: True if Central Vdev is force as primary else false
  */
 
-uint8_t mlo_get_total_links(struct wlan_objmgr_pdev *pdev);
-#endif
+bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * mlo_set_sta_ctx_bss_mld_addr() - Save BSS MLD in sta ctx
+ * @vdev: vdev pointer
+ * @bss_mld_addr: MLD Address of BSS
+ *
+ * Return: none
+ */
+
+static inline
+void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev,
+				  struct qdf_mac_addr *bss_mld_addr)
+{
+	struct wlan_mlo_dev_context *ml_dev = NULL;
+
+	if (!vdev || !vdev->mlo_dev_ctx || !bss_mld_addr)
+		return;
+
+	ml_dev = vdev->mlo_dev_ctx;
+	if (mlo_sta_bridge_exists(vdev) &&
+	    qdf_is_macaddr_zero(&ml_dev->bridge_sta_ctx->bss_mld_addr)) {
+		if (qdf_is_macaddr_zero(bss_mld_addr))
+			return;
+		qdf_copy_macaddr(&ml_dev->bridge_sta_ctx->bss_mld_addr,
+				 bss_mld_addr);
+	}
+}
+
+/**
+ * mlo_get_sta_ctx_bss_mld_addr() - Get BSS MLD from sta ctx
+ * @vdev: vdev pointer
+ *
+ * Return: pointer to qdf_mac_addr
+ */
+
+static inline
+struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_mlo_dev_context *ml_dev = NULL;
+	struct qdf_mac_addr *mld_addr;
+
+	if (!vdev || !vdev->mlo_dev_ctx)
+		return NULL;
+
+	ml_dev = vdev->mlo_dev_ctx;
+	if (mlo_sta_bridge_exists(vdev) &&
+	    !qdf_is_macaddr_zero(&ml_dev->bridge_sta_ctx->bss_mld_addr)) {
+		mld_addr = &ml_dev->bridge_sta_ctx->bss_mld_addr;
+		return mld_addr;
+	}
+	return NULL;
+}
+
+#else
+static inline
+void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev,
+				  struct qdf_mac_addr *bss_mld_addr)
+{ }
+
+static inline
+struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev)
+{
+	return NULL;
+}
+
+static inline
+bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+
+static inline
+bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+
+static inline
+bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+#endif
 /**
  * wlan_mlo_get_tdls_link_vdev() - API to get tdls link vdev
  * @vdev: vdev object
@@ -781,6 +871,35 @@ mlo_get_link_state_context(struct wlan_objmgr_psoc *psoc,
 			   get_ml_link_state_cb *resp_cb,
 			   void **context, uint8_t vdev_id);
 #else
+static inline
+void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev,
+				  struct qdf_mac_addr *bss_mld_addr)
+{ }
+
+static inline
+struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev)
+{
+	return NULL;
+}
+
+static inline
+bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+
+static inline
+bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+
+static inline
+bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+
 static inline
 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
 		       struct wlan_cm_connect_req *req)

+ 34 - 6
umac/mlo_mgr/src/wlan_mlo_mgr_primary_umac.c

@@ -728,8 +728,12 @@ void mlo_update_partner_bridge_info(struct wlan_mlo_dev_context *ml_dev,
 
 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;
+	struct wlan_mlo_dev_context *ml_dev = NULL;
+
+	if (!vdev)
+		return false;
+
+	ml_dev = vdev->mlo_dev_ctx;
 
 	if (!ml_dev || !ml_dev->bridge_sta_ctx)
 		return false;
@@ -737,7 +741,7 @@ bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev)
 	if (vdev->vdev_objmgr.mlo_central_vdev &&
 	    ml_dev->bridge_sta_ctx->bridge_vap_exists)
 		return true;
-#endif
+
 	return false;
 }
 
@@ -745,20 +749,44 @@ 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;
+	struct wlan_mlo_dev_context *ml_dev = NULL;
+
+	if (!vdev)
+		return false;
+
+	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);
 
+bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_mlo_dev_context *ml_dev = NULL;
+
+	if (!vdev)
+		return false;
+
+	ml_dev = vdev->mlo_dev_ctx;
+
+	if (!ml_dev || !ml_dev->bridge_sta_ctx)
+		return false;
+
+	if (ml_dev->bridge_sta_ctx->is_force_central_primary)
+		return true;
+
+	return false;
+}
+
+qdf_export_symbol(mlo_is_force_central_primary);
+
 uint8_t mlo_get_total_links(struct wlan_objmgr_pdev *pdev)
 {
 	uint8_t ml_grp_id;