Browse Source

qcacmn: Copy assoc IE for MLO link connect

When associating the partner link in an MLO connecting, reuse the
association IEs from the original connection. To do this, store the
connection manager connection request to query later, since this
holds the assoc IE data.

Change-Id: I100351a4c9cd439222af202ca3e80ef50554e1e3
CRs-fixed: 3016095
Lincoln Tran 3 years ago
parent
commit
50e7e5c6ae

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

@@ -127,6 +127,7 @@ struct wlan_mlo_key_mgmt {
  * @wlan_connect_req_links: list of vdevs selected for connection with the MLAP
  * @wlan_connect_req_links: list of vdevs selected for connection with the MLAP
  * @wlan_connected_links: list of vdevs associated with this MLO connection
  * @wlan_connected_links: list of vdevs associated with this MLO connection
  * @connect req: connect params
  * @connect req: connect params
+ * @orig_conn_req: original connect req
  * @assoc_rsp: Raw assoc response frame
  * @assoc_rsp: Raw assoc response frame
  */
  */
 struct wlan_mlo_sta {
 struct wlan_mlo_sta {
@@ -134,6 +135,7 @@ struct wlan_mlo_sta {
 	qdf_bitmap(wlan_connected_links, WLAN_UMAC_MLO_MAX_VDEVS);
 	qdf_bitmap(wlan_connected_links, WLAN_UMAC_MLO_MAX_VDEVS);
 	struct wlan_mlo_key_mgmt key_mgmt[WLAN_UMAC_MLO_MAX_VDEVS - 1];
 	struct wlan_mlo_key_mgmt key_mgmt[WLAN_UMAC_MLO_MAX_VDEVS - 1];
 	struct wlan_cm_connect_req *connect_req;
 	struct wlan_cm_connect_req *connect_req;
+	struct wlan_cm_connect_req *orig_conn_req;
 	struct element_info assoc_rsp;
 	struct element_info assoc_rsp;
 };
 };
 
 

+ 60 - 3
umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

@@ -167,7 +167,7 @@ mlo_cm_handle_connect_in_disconnection_state(struct wlan_objmgr_vdev *vdev,
 		qdf_mem_copy(sta_ctx->connect_req, req,
 		qdf_mem_copy(sta_ctx->connect_req, req,
 			     sizeof(struct wlan_cm_connect_req));
 			     sizeof(struct wlan_cm_connect_req));
 	else
 	else
-		qdf_err("Failed to allocate connect req");
+		mlo_err("Failed to allocate connect req");
 }
 }
 
 
 static void
 static void
@@ -221,12 +221,33 @@ QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
 		       struct wlan_cm_connect_req *req)
 		       struct wlan_cm_connect_req *req)
 {
 {
 	struct wlan_mlo_dev_context *mlo_dev_ctx;
 	struct wlan_mlo_dev_context *mlo_dev_ctx;
+	struct wlan_mlo_sta *sta_ctx;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 
+	if (qdf_mem_cmp(vdev->vdev_mlme.macaddr,
+			vdev->vdev_mlme.linkaddr,
+			QDF_MAC_ADDR_SIZE))
+		return wlan_cm_start_connect(vdev, req);
+
 	mlo_dev_ctx = vdev->mlo_dev_ctx;
 	mlo_dev_ctx = vdev->mlo_dev_ctx;
+	sta_ctx = mlo_dev_ctx->sta_ctx;
 	if (mlo_dev_ctx && wlan_vdev_mlme_is_mlo_vdev(vdev)) {
 	if (mlo_dev_ctx && wlan_vdev_mlme_is_mlo_vdev(vdev)) {
 		mlo_dev_lock_acquire(mlo_dev_ctx);
 		mlo_dev_lock_acquire(mlo_dev_ctx);
 		status = mlo_validate_connect_req(mlo_dev_ctx, req);
 		status = mlo_validate_connect_req(mlo_dev_ctx, req);
+
+		if (!sta_ctx->orig_conn_req)
+			sta_ctx->orig_conn_req = qdf_mem_malloc(
+					sizeof(struct wlan_cm_connect_req));
+
+		mlo_debug("storing orig connect req");
+		if (sta_ctx->orig_conn_req) {
+			qdf_mem_copy(sta_ctx->orig_conn_req, req,
+				     sizeof(struct wlan_cm_connect_req));
+		} else {
+			mlo_err("Failed to allocate orig connect req");
+			return QDF_STATUS_E_NOMEM;
+		}
+
 		if (QDF_IS_STATUS_SUCCESS(status))
 		if (QDF_IS_STATUS_SUCCESS(status))
 			status = wlan_cm_start_connect(vdev, req);
 			status = wlan_cm_start_connect(vdev, req);
 
 
@@ -255,10 +276,16 @@ mlo_prepare_and_send_connect(struct wlan_objmgr_vdev *vdev,
 			     struct wlan_ssid ssid)
 			     struct wlan_ssid ssid)
 {
 {
 	struct wlan_cm_connect_req req = {0};
 	struct wlan_cm_connect_req req = {0};
+	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
+	struct wlan_mlo_sta *sta_ctx = mlo_dev_ctx->sta_ctx;
 
 
 	mlo_debug("Partner link connect mac:" QDF_MAC_ADDR_FMT "vdev_id:%d",
 	mlo_debug("Partner link connect mac:" QDF_MAC_ADDR_FMT "vdev_id:%d",
 		  QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)),
 		  QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)),
 		  wlan_vdev_get_id(vdev));
 		  wlan_vdev_get_id(vdev));
+
+	qdf_mem_copy(&req, sta_ctx->orig_conn_req,
+		     sizeof(struct wlan_cm_connect_req));
+
 	qdf_mem_copy(req.bssid.bytes,
 	qdf_mem_copy(req.bssid.bytes,
 		     link_info.link_addr.bytes,
 		     link_info.link_addr.bytes,
 		     QDF_MAC_ADDR_SIZE);
 		     QDF_MAC_ADDR_SIZE);
@@ -268,10 +295,25 @@ mlo_prepare_and_send_connect(struct wlan_objmgr_vdev *vdev,
 		     sizeof(struct mlo_partner_info));
 		     sizeof(struct mlo_partner_info));
 
 
 	req.ssid.length = ssid.length;
 	req.ssid.length = ssid.length;
-	qdf_mem_copy(&req.ssid.ssid, &ssid.ssid,
-		     ssid.length);
+	qdf_mem_copy(&req.ssid.ssid, &ssid.ssid, ssid.length);
+
+	req.assoc_ie.len = sta_ctx->orig_conn_req->assoc_ie.len;
+	req.assoc_ie.ptr = qdf_mem_malloc(req.assoc_ie.len);
+	if (req.assoc_ie.ptr) {
+		qdf_mem_copy(req.assoc_ie.ptr,
+			     sta_ctx->orig_conn_req->assoc_ie.ptr,
+			     req.assoc_ie.len);
+	} else {
+		req.assoc_ie.len = 0;
+		mlo_err("Failed to allocate assoc IE");
+	}
 
 
 	wlan_cm_start_connect(vdev, &req);
 	wlan_cm_start_connect(vdev, &req);
+	if (req.assoc_ie.ptr) {
+		qdf_mem_free(req.assoc_ie.ptr);
+		req.assoc_ie.ptr = NULL;
+		req.assoc_ie.len = 0;
+	}
 }
 }
 
 
 /**
 /**
@@ -587,6 +629,11 @@ static QDF_STATUS mlo_disconnect_no_lock(struct wlan_objmgr_vdev *vdev,
 			sta_ctx->connect_req = NULL;
 			sta_ctx->connect_req = NULL;
 		}
 		}
 
 
+		if (sta_ctx->orig_conn_req) {
+			qdf_mem_free(sta_ctx->orig_conn_req);
+			sta_ctx->orig_conn_req = NULL;
+		}
+
 		status = mlo_send_link_disconnect(mlo_dev_ctx, source,
 		status = mlo_send_link_disconnect(mlo_dev_ctx, source,
 						  reason_code, bssid);
 						  reason_code, bssid);
 
 
@@ -628,6 +675,11 @@ QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev,
 			sta_ctx->connect_req = NULL;
 			sta_ctx->connect_req = NULL;
 		}
 		}
 
 
+		if (sta_ctx->orig_conn_req) {
+			qdf_mem_free(sta_ctx->orig_conn_req);
+			sta_ctx->orig_conn_req = NULL;
+		}
+
 		status = mlo_send_link_disconnect(mlo_dev_ctx, source,
 		status = mlo_send_link_disconnect(mlo_dev_ctx, source,
 						  reason_code, bssid);
 						  reason_code, bssid);
 
 
@@ -674,6 +726,11 @@ QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev,
 			sta_ctx->connect_req = NULL;
 			sta_ctx->connect_req = NULL;
 		}
 		}
 
 
+		if (sta_ctx->orig_conn_req) {
+			qdf_mem_free(sta_ctx->orig_conn_req);
+			sta_ctx->orig_conn_req = NULL;
+		}
+
 		status = mlo_send_link_disconnect_sync(mlo_dev_ctx, source,
 		status = mlo_send_link_disconnect_sync(mlo_dev_ctx, source,
 						       reason_code, bssid);
 						       reason_code, bssid);