소스 검색

qcacmn: Back to back connect changes

Currently, the code does not handle an MLO connect when in
non-init state. Add logic to clean up any existing connection
before going ahead with the latest request.

Change-Id: Ia5a10bcc1e0d2c8e82d6ea0d82d1a5bf0604a1e5
CRs-fixed: 3116687
Lincoln Tran 3 년 전
부모
커밋
badb6230e2
3개의 변경된 파일75개의 추가작업 그리고 0개의 파일을 삭제
  1. 3 0
      umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c
  2. 13 0
      umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h
  3. 59 0
      umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

+ 3 - 0
umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c

@@ -295,6 +295,9 @@ void cm_initiate_internal_disconnect(struct cnx_mgr *cm_ctx)
 	disconnect_req->req.vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
 	disconnect_req->req.source = CM_INTERNAL_DISCONNECT;
 
+	if (wlan_vdev_mlme_is_mlo_vdev(cm_ctx->vdev))
+		mlo_internal_disconnect_links(cm_ctx->vdev);
+
 	status = cm_add_disconnect_req_to_list(cm_ctx, disconnect_req);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		mlme_err(CM_PREFIX_FMT "failed to add disconnect req",

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

@@ -472,6 +472,15 @@ QDF_STATUS mlo_sta_up_active_notify(struct wlan_objmgr_vdev *vdev);
  */
 bool mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev,
 				  struct csa_offload_params *csa_param);
+
+/**
+ * mlo_internal_disconnect_links - Internal disconnect for connection manager
+ *
+ * @vdev: vdev obj mgr
+ *
+ * Return: none
+ */
+void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev);
 #else
 static inline
 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
@@ -594,5 +603,9 @@ mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev,
 {
 	return false;
 }
+
+static inline void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev)
+{
+}
 #endif
 #endif

+ 59 - 0
umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

@@ -1535,4 +1535,63 @@ done:
 
 	return handled;
 }
+
+void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_mlo_dev_context *mlo_dev_ctx = NULL;
+	struct wlan_mlo_sta *sta_ctx = NULL;
+	uint8_t i;
+
+	if (!vdev)
+		return;
+
+	if (!wlan_vdev_mlme_is_assoc_sta_vdev(vdev)) {
+		mlo_debug("Not an assoc vdev, so ignore disconnect req");
+		return;
+	}
+
+	mlo_dev_ctx = vdev->mlo_dev_ctx;
+	if (mlo_dev_ctx) {
+		sta_ctx = mlo_dev_ctx->sta_ctx;
+	} else {
+		mlo_err("Invalid mlo_dev_ctx");
+		return;
+	}
+
+	if (sta_ctx) {
+		copied_conn_req_lock_acquire(sta_ctx);
+		if (sta_ctx->copied_conn_req) {
+			mlo_free_connect_ies(sta_ctx->copied_conn_req);
+			qdf_mem_free(sta_ctx->copied_conn_req);
+			sta_ctx->copied_conn_req = NULL;
+		}
+		copied_conn_req_lock_release(sta_ctx);
+	} else {
+		mlo_err("Invalid sta_ctx");
+		return;
+	}
+
+	mlo_dev_lock_acquire(mlo_dev_ctx);
+	if (sta_ctx->connect_req) {
+		mlo_free_connect_ies(sta_ctx->connect_req);
+		qdf_mem_free(sta_ctx->connect_req);
+		sta_ctx->connect_req = NULL;
+	}
+
+	for (i =  0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
+		if (!mlo_dev_ctx->wlan_vdev_list[i])
+			continue;
+
+		if (qdf_test_bit(i,
+				 mlo_dev_ctx->sta_ctx->wlan_connected_links) &&
+		    mlo_dev_ctx->wlan_vdev_list[i] !=
+		    mlo_get_assoc_link_vdev(mlo_dev_ctx))
+			wlan_cm_disconnect(mlo_dev_ctx->wlan_vdev_list[i],
+					   CM_INTERNAL_DISCONNECT,
+					   REASON_UNSPEC_FAILURE,
+					   NULL);
+	}
+
+	mlo_dev_lock_release(mlo_dev_ctx);
+}
 #endif