Преглед на файлове

qcacmn: CM changes for ML connection

CM changes for ML connection

Change-Id: I7718734b0f08c8e73702b2c1c7c297bf71b6b5e3
Himanshu Batra преди 4 години
родител
ревизия
73f871654f

+ 178 - 0
os_if/linux/mlme/src/osif_cm_connect_rsp.c

@@ -28,6 +28,7 @@
 #include "osif_cm_util.h"
 #include "wlan_cfg80211.h"
 #include "wlan_cfg80211_scan.h"
+#include "wlan_mlo_mgr_sta.h"
 
 #ifdef CONN_MGR_ADV_FEATURE
 void osif_cm_get_assoc_req_ie_data(struct element_info *assoc_req,
@@ -472,6 +473,108 @@ static inline int osif_update_connect_results(struct net_device *dev,
 }
 #endif /* WLAN_FEATURE_FILS_SK && CFG80211_CONNECT_DONE */
 
+#ifdef WLAN_FEATURE_11BE_MLO
+#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
+static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
+					 struct vdev_osif_priv *osif_priv,
+					 struct wlan_cm_connect_resp *rsp)
+{
+	struct cfg80211_bss *bss = NULL;
+	struct ieee80211_channel *chan;
+
+	if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
+		chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
+					     rsp->freq);
+		bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
+					    rsp->bssid.bytes,
+					    rsp->ssid.ssid,
+					    rsp->ssid.length);
+	}
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		if (osif_update_connect_results(osif_priv->wdev->netdev, bss,
+						rsp, vdev))
+			osif_connect_bss(osif_priv->wdev->netdev, bss, rsp);
+		return;
+	}
+
+	if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev)) {
+		if (osif_update_connect_results(
+				osif_priv->wdev->netdev, bss,
+				rsp, vdev))
+			osif_connect_bss(osif_priv->wdev->netdev,
+					 bss, rsp);
+	}
+
+}
+#else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
+static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
+					 struct vdev_osif_priv *osif_priv,
+					 struct wlan_cm_connect_resp *rsp)
+{
+	struct cfg80211_bss *bss = NULL;
+	struct ieee80211_channel *chan;
+	struct wlan_objmgr_vdev *assoc_vdev = NULL;
+	struct vdev_osif_priv *tmp_osif_priv = NULL;
+	qdf_freq_t freq;
+	struct qdf_mac_addr macaddr = {0};
+	struct wlan_cm_connect_resp resp = {0};
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
+			chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
+						     rsp->freq);
+			bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy,
+						    chan,
+						    rsp->bssid.bytes,
+						    rsp->ssid.ssid,
+						    rsp->ssid.length);
+		}
+		if (osif_update_connect_results(osif_priv->wdev->netdev, bss,
+						rsp, vdev))
+			osif_connect_bss(osif_priv->wdev->netdev, bss, rsp);
+		return;
+	}
+
+	if ((QDF_IS_STATUS_SUCCESS(rsp->connect_status) &&
+	    ucfg_mlo_is_mld_connected(vdev)) ||
+	    (QDF_IS_STATUS_ERROR(rsp->connect_status) &&
+	    ucfg_mlo_is_mld_disconnected(vdev))) {
+		assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
+		if (!assoc_vdev)
+			return;
+		tmp_osif_priv  = wlan_vdev_get_ospriv(assoc_vdev);
+		freq = vdev->vdev_mlme.bss_chan->ch_freq;
+		wlan_vdev_get_bss_peer_mac(assoc_vdev, &macaddr);
+		if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
+			chan = ieee80211_get_channel(tmp_osif_priv->wdev->wiphy,
+						     freq);
+			bss = wlan_cfg80211_get_bss(tmp_osif_priv->wdev->wiphy,
+						    chan,
+						    macaddr.bytes,
+						    rsp->ssid.ssid,
+						    rsp->ssid.length);
+		}
+		qdf_mem_copy(resp.bssid.bytes, macaddr.bytes,
+			     QDF_MAC_ADDR_SIZE);
+		qdf_mem_copy(resp.ssid.ssid, rsp->ssid.ssid,
+			     rsp->ssid.length);
+		resp.ssid.length = rsp->ssid.length;
+		resp.freq = freq;
+		resp.connect_status = rsp->connect_status;
+		resp.reason = rsp->reason;
+		resp.status_code = rsp->status_code;
+		resp.connect_ies.assoc_req.ptr = rsp->connect_ies.assoc_req.ptr;
+		resp.connect_ies.assoc_req.len = rsp->connect_ies.assoc_req.len;
+		resp.connect_ies.assoc_rsp.ptr = rsp->connect_ies.assoc_rsp.ptr;
+		resp.connect_ies.assoc_rsp.len = rsp->connect_ies.assoc_rsp.len;
+		if (osif_update_connect_results(tmp_osif_priv->wdev->netdev, bss,
+						&resp, vdev))
+			osif_connect_bss(tmp_osif_priv->wdev->netdev, bss, &resp);
+	}
+}
+#endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
+#else /* WLAN_FEATURE_11BE_MLO */
 static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
 					 struct vdev_osif_priv *osif_priv,
 					 struct wlan_cm_connect_resp *rsp)
@@ -492,7 +595,81 @@ static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
 					rsp, vdev))
 		osif_connect_bss(osif_priv->wdev->netdev, bss, rsp);
 }
+#endif /* WLAN_FEATURE_11BE_MLO */
 #else  /* CFG80211_CONNECT_BSS */
+#ifdef WLAN_FEATURE_11BE_MLO
+#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
+static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
+					 struct vdev_osif_priv *osif_priv,
+					 struct wlan_cm_connect_resp *rsp)
+{
+	enum ieee80211_statuscode status;
+	size_t req_len = 0;
+	const uint8_t *req_ptr = NULL;
+	size_t rsp_len = 0;
+	const uint8_t *rsp_ptr = NULL;
+	struct wlan_objmgr_vdev *assoc_vdev = NULL;
+	struct vdev_osif_priv *tmp_osif_priv = NULL;
+
+	status = osif_get_connect_status_code(rsp);
+	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
+				      &req_len, &req_ptr);
+	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
+				      &rsp_len, &rsp_ptr);
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+			cfg80211_connect_result(
+				osif_priv->wdev->netdev,
+				rsp->bssid.bytes, req_ptr, req_len,
+				rsp_ptr, rsp_len, status, GFP_KERNEL);
+	} else {
+		cfg80211_connect_result(osif_priv->wdev->netdev,
+					rsp->bssid.bytes, req_ptr, req_len,
+					rsp_ptr, rsp_len, status, GFP_KERNEL);
+	}
+}
+#else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
+static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
+					 struct vdev_osif_priv *osif_priv,
+					 struct wlan_cm_connect_resp *rsp)
+{
+	enum ieee80211_statuscode status;
+	size_t req_len = 0;
+	const uint8_t *req_ptr = NULL;
+	size_t rsp_len = 0;
+	const uint8_t *rsp_ptr = NULL;
+	struct wlan_objmgr_vdev *assoc_vdev = NULL;
+	struct vdev_osif_priv *tmp_osif_priv = NULL;
+	struct qdf_mac_addr macaddr = {0};
+
+	status = osif_get_connect_status_code(rsp);
+	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
+				      &req_len, &req_ptr);
+	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
+				      &rsp_len, &rsp_ptr);
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		if ((QDF_IS_STATUS_SUCCESS(rsp->connect_status) &&
+		    ucfg_mlo_is_mld_connected(vdev)) ||
+		    (QDF_IS_STATUS_ERROR(rsp->connect_status) &&
+		    ucfg_mlo_is_mld_disconnected(vdev))) {
+			assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
+			if (!assoc_vdev)
+				return;
+			tmp_osif_priv  = wlan_vdev_get_ospriv(assoc_vdev);
+			wlan_vdev_get_bss_peer_mac(assoc_vdev, &macaddr);
+			cfg80211_connect_result(tmp_osif_priv->wdev->netdev,
+						macaddr.bytes, req_ptr,
+						req_len, rsp_ptr, rsp_len,
+						status, GFP_KERNEL);
+		}
+	} else {
+		cfg80211_connect_result(osif_priv->wdev->netdev,
+					rsp->bssid.bytes, req_ptr, req_len,
+					rsp_ptr, rsp_len, status, GFP_KERNEL);
+	}
+}
+#endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
+#else /* WLAN_FEATURE_11BE_MLO */
 static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
 					 struct vdev_osif_priv *osif_priv,
 					 struct wlan_cm_connect_resp *rsp)
@@ -512,6 +689,7 @@ static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
 				rsp->bssid.bytes, req_ptr, req_len,
 				rsp_ptr, rsp_len, status, GFP_KERNEL);
 }
+#endif /* WLAN_FEATURE_11BE_MLO */
 #endif /* CFG80211_CONNECT_BSS */
 
 #ifdef CONN_MGR_ADV_FEATURE

+ 58 - 4
os_if/linux/mlme/src/osif_cm_disconnect_rsp.c

@@ -26,6 +26,7 @@
 #include "osif_cm_rsp.h"
 #include "wlan_osif_priv.h"
 #include "osif_cm_util.h"
+#include "wlan_mlo_mgr_sta.h"
 
 /**
  * osif_validate_disconnect_and_reset_src_id() - Validate disconnection
@@ -78,17 +79,69 @@ rel_lock:
 
 #if defined(CFG80211_DISCONNECTED_V2) || \
 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
+#ifdef WLAN_FEATURE_11BE_MLO
+#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
 static void
-osif_cm_indicate_disconnect(struct net_device *dev,
+osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
+			    struct net_device *dev,
+			    enum ieee80211_reasoncode reason,
+			    bool locally_generated, const u8 *ie,
+			    size_t ie_len, gfp_t gfp)
+{
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+			cfg80211_disconnected(dev, reason, ie,
+					      ie_len, locally_generated, gfp);
+	} else {
+		cfg80211_disconnected(dev, reason, ie,
+				      ie_len, locally_generated, gfp);
+	}
+}
+#else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
+static void
+osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
+			    struct net_device *dev,
+			    enum ieee80211_reasoncode reason,
+			    bool locally_generated, const u8 *ie,
+			    size_t ie_len, gfp_t gfp)
+{
+	struct net_device *netdev = dev;
+	struct vdev_osif_priv *osif_priv = NULL;
+	struct wlan_objmgr_vdev *assoc_vdev = NULL;
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		cfg80211_disconnected(netdev, reason, ie, ie_len,
+				      locally_generated, gfp);
+		return;
+	}
+
+	if (ucfg_mlo_is_mld_disconnected(vdev)) {
+		assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
+		if (!assoc_vdev)
+			return;
+		osif_priv  = wlan_vdev_get_ospriv(assoc_vdev);
+		netdev = osif_priv->wdev->netdev;
+		cfg80211_disconnected(netdev, reason,
+				      ie, ie_len,
+				      locally_generated, gfp);
+	}
+}
+#endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
+#else /* WLAN_FEATURE_11BE_MLO */
+static void
+osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
+			    struct net_device *dev,
 			    enum ieee80211_reasoncode reason,
 			    bool locally_generated, const u8 *ie,
 			    size_t ie_len, gfp_t gfp)
 {
 	cfg80211_disconnected(dev, reason, ie, ie_len, locally_generated, gfp);
 }
+#endif /* WLAN_FEATURE_11BE_MLO */
 #else
 static void
-osif_cm_indicate_disconnect(struct net_device *dev,
+osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
+			    struct net_device *dev,
 			    enum ieee80211_reasoncode reason,
 			    bool locally_generated, const u8 *ie,
 			    size_t ie_len, gfp_t gfp)
@@ -175,8 +228,9 @@ QDF_STATUS osif_disconnect_handler(struct wlan_objmgr_vdev *vdev,
 	}
 
 	osif_cm_disconnect_comp_ind(vdev, rsp, OSIF_PRE_USERSPACE_UPDATE);
-	osif_cm_indicate_disconnect(osif_priv->wdev->netdev, ieee80211_reason,
-				    locally_generated, rsp->ap_discon_ie.ptr,
+	osif_cm_indicate_disconnect(vdev, osif_priv->wdev->netdev,
+				    ieee80211_reason, locally_generated,
+				    rsp->ap_discon_ie.ptr,
 				    rsp->ap_discon_ie.len, GFP_KERNEL);
 
 	osif_cm_disconnect_comp_ind(vdev, rsp, OSIF_POST_USERSPACE_UPDATE);

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

@@ -30,6 +30,7 @@
 #ifdef WLAN_FEATURE_FILS_SK
 #include <wlan_mlme_ucfg_api.h>
 #endif
+#include <wlan_mlo_mgr_sta.h>
 
 static void osif_cm_free_wep_key_params(struct wlan_cm_connect_req *connect_req)
 {
@@ -431,6 +432,21 @@ static void osif_cm_free_connect_req(struct wlan_cm_connect_req *connect_req)
 	qdf_mem_free(connect_req);
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static inline
+void osif_update_mlo_partner_info(struct wlan_cm_connect_req *connect_req,
+				  const struct cfg80211_connect_params *req)
+{
+	//Update ml partner info in connect_req
+}
+#else
+static inline
+void osif_update_mlo_partner_info(struct wlan_cm_connect_req *connect_req,
+				  const struct cfg80211_connect_params *req)
+{
+}
+#endif
+
 int osif_cm_connect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
 		    const struct cfg80211_connect_params *req,
 		    const struct osif_connect_params *params)
@@ -526,7 +542,9 @@ int osif_cm_connect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
 
 	osif_cm_fill_connect_params(connect_req, params);
 
-	status = ucfg_cm_start_connect(vdev, connect_req);
+	osif_update_mlo_partner_info(connect_req, req);
+
+	status = mlo_connect(vdev, connect_req);
 	if (QDF_IS_STATUS_ERROR(status))
 		osif_err("Connect failed with status %d", status);
 
@@ -540,21 +558,12 @@ static QDF_STATUS osif_cm_send_disconnect(struct wlan_objmgr_vdev *vdev,
 					  uint16_t reason)
 {
 	QDF_STATUS status;
-	struct wlan_cm_disconnect_req *req;
 
 	status = osif_cm_reset_id_and_src(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
 		return qdf_status_to_os_return(status);
 
-	req = qdf_mem_malloc(sizeof(*req));
-	if (!req)
-		return QDF_STATUS_E_NOMEM;
-
-	req->vdev_id = wlan_vdev_get_id(vdev);
-	req->source = CM_OSIF_DISCONNECT;
-	req->reason_code = reason;
-	status = ucfg_cm_start_disconnect(vdev, req);
-	qdf_mem_free(req);
+	status = mlo_disconnect(vdev, CM_OSIF_DISCONNECT, reason, NULL);
 
 	return status;
 }
@@ -584,7 +593,7 @@ int osif_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, uint16_t reason)
 	osif_info("vdevid-%d: Received Disconnect reason:%d %s",
 		  vdev_id, reason, ucfg_cm_reason_code_to_str(reason));
 
-	status = ucfg_cm_disconnect_sync(vdev, CM_OSIF_DISCONNECT, reason);
+	status = mlo_sync_disconnect(vdev, CM_OSIF_DISCONNECT, reason, NULL);
 
 	return qdf_status_to_os_return(status);
 }

+ 94 - 3
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -31,6 +31,7 @@
 #include "wlan_cm_roam_api.h"
 #endif
 #include <wlan_utility.h>
+#include <wlan_mlo_mgr_sta.h>
 
 static void
 cm_fill_failure_resp_from_cm_id(struct cnx_mgr *cm_ctx,
@@ -437,6 +438,39 @@ cm_set_pmf_caps(struct wlan_cm_connect_req *req, struct scan_filter *filter)
 		filter->pmf_cap = WLAN_PMF_DISABLED;
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
+static inline
+void cm_set_vdev_link_id(struct cnx_mgr *cm_ctx,
+			 struct cm_connect_req *req)
+{
+	uint8_t link_id;
+	uint8_t i;
+
+	for (i = 0; i < req->cur_candidate->entry->ml_info->num_links; i++) {
+		if (qdf_mem_cmp(req->cur_candidate->entry->ml_info->link_info[i].link_addr.bytes,
+				req->cur_candidate->entry->mac_addr.bytes, QDF_MAC_ADDR_SIZE))
+			continue;
+		link_id = req->cur_candidate->entry->ml_info->link_info[i].link_id;
+		if (cm_ctx->vdev) {
+			mlme_debug("setting link ID to %d", link_id);
+			wlan_vdev_set_link_id(cm_ctx->vdev, link_id);
+		}
+	}
+}
+#else
+static inline
+void cm_set_vdev_link_id(struct cnx_mgr *cm_ctx,
+			 struct cm_connect_req *req)
+{ }
+#endif
+#else
+static inline
+void cm_set_vdev_link_id(struct cnx_mgr *cm_ctx,
+			 struct cm_connect_req *req)
+{ }
+#endif
+
 static void cm_create_bss_peer(struct cnx_mgr *cm_ctx,
 			       struct cm_connect_req *req)
 {
@@ -444,6 +478,7 @@ static void cm_create_bss_peer(struct cnx_mgr *cm_ctx,
 	struct qdf_mac_addr *bssid;
 
 	bssid = &req->cur_candidate->entry->bssid;
+	cm_set_vdev_link_id(cm_ctx, req);
 	status = mlme_cm_bss_peer_create_req(cm_ctx->vdev, bssid);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		struct wlan_cm_connect_resp *resp;
@@ -905,10 +940,38 @@ static void cm_connect_prepare_scan_filter(struct wlan_objmgr_pdev *pdev,
 	if (!security_valid_for_6ghz)
 		filter->ignore_6ghz_channel = true;
 
+	if (cm_req->req.is_non_assoc_link)
+		filter->ignore_6ghz_channel = false;
+
 	cm_update_security_filter(filter, &cm_req->req);
 	cm_update_advance_filter(pdev, cm_ctx, filter, cm_req);
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
+static QDF_STATUS cm_is_scan_support(struct cm_connect_req *cm_req)
+{
+	if (cm_req->req.is_non_assoc_link)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static QDF_STATUS cm_is_scan_support(struct cm_connect_req *cm_req)
+{
+	if (cm_req->req.ml_parnter_info.num_partner_links)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#else
+static QDF_STATUS cm_is_scan_support(struct cm_connect_req *cm_req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 static QDF_STATUS cm_connect_get_candidates(struct wlan_objmgr_pdev *pdev,
 					    struct cnx_mgr *cm_ctx,
 					    struct cm_connect_req *cm_req)
@@ -957,7 +1020,8 @@ static QDF_STATUS cm_connect_get_candidates(struct wlan_objmgr_pdev *pdev,
 	}
 
 	op_mode = wlan_vdev_mlme_get_opmode(cm_ctx->vdev);
-	if (num_bss && op_mode == QDF_STA_MODE)
+	if (num_bss && op_mode == QDF_STA_MODE &&
+	    !cm_req->req.is_non_assoc_link)
 		cm_calculate_scores(cm_ctx, pdev, filter, candidate_list);
 	qdf_mem_free(filter);
 
@@ -972,9 +1036,11 @@ static QDF_STATUS cm_connect_get_candidates(struct wlan_objmgr_pdev *pdev,
 
 		/*
 		 * If connect scan was already done OR candidate were found
-		 * but none of them were valid return QDF_STATUS_E_EMPTY.
+		 * but none of them were valid OR if ML link connection
+		 * return QDF_STATUS_E_EMPTY.
 		 */
-		if (cm_req->scan_id || num_bss)
+		if (cm_req->scan_id || num_bss ||
+		    QDF_IS_STATUS_ERROR(cm_is_scan_support(cm_req)))
 			return QDF_STATUS_E_EMPTY;
 
 		/* Try connect scan to search for any valid candidate */
@@ -1505,6 +1571,24 @@ static inline void cm_set_fils_connection(struct cnx_mgr *cm_ctx,
 }
 #endif
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static inline
+void cm_update_ml_partner_info(struct wlan_cm_connect_req *req,
+			       struct wlan_cm_vdev_connect_req *connect_req)
+{
+	if (req->ml_parnter_info.num_partner_links)
+		qdf_mem_copy(&connect_req->ml_parnter_info,
+			     &req->ml_parnter_info,
+			     sizeof(struct mlo_partner_info));
+}
+#else
+static inline
+void cm_update_ml_partner_info(struct wlan_cm_connect_req *req,
+			       struct wlan_cm_vdev_connect_req *connect_req)
+{
+}
+#endif
+
 QDF_STATUS
 cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 {
@@ -1557,6 +1641,8 @@ cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 	req.ht_caps_mask = cm_req->connect_req.req.ht_caps_mask;
 	req.vht_caps = cm_req->connect_req.req.vht_caps;
 	req.vht_caps_mask = cm_req->connect_req.req.vht_caps_mask;
+	req.is_non_assoc_link = cm_req->connect_req.req.is_non_assoc_link;
+	cm_update_ml_partner_info(&cm_req->connect_req.req, &req);
 
 	wlan_reg_get_cc_and_src(psoc, country_code);
 	mlme_nofl_info(CM_PREFIX_FMT "Connecting to %.*s " QDF_MAC_ADDR_FMT " rssi: %d freq: %d akm 0x%x cipher: uc 0x%x mc 0x%x, wps %d osen %d force RSN %d CC: %c%c",
@@ -1669,6 +1755,7 @@ QDF_STATUS cm_connect_complete(struct cnx_mgr *cm_ctx,
 
 	if (send_ind) {
 		mlme_cm_connect_complete_ind(cm_ctx->vdev, resp);
+		mlo_sta_link_connect_notify(cm_ctx->vdev, resp);
 		mlme_cm_osif_connect_complete(cm_ctx->vdev, resp);
 		cm_if_mgr_inform_connect_complete(cm_ctx->vdev,
 						  resp->connect_status);
@@ -1991,6 +2078,10 @@ QDF_STATUS cm_connect_start_req(struct wlan_objmgr_vdev *vdev,
 	if (!cm_req)
 		return QDF_STATUS_E_NOMEM;
 
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
+	    wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+		req->is_non_assoc_link = 1;
+
 	connect_req = &cm_req->connect_req;
 	connect_req->req = *req;
 

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

@@ -27,6 +27,7 @@
 #ifdef CONN_MGR_ADV_FEATURE
 #include "wlan_blm_api.h"
 #endif
+#include <wlan_mlo_mgr_sta.h>
 
 void cm_send_disconnect_resp(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id)
 {
@@ -402,6 +403,8 @@ QDF_STATUS cm_disconnect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 	req->req.vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
 	req->req.source = cm_req->discon_req.req.source;
 	req->req.reason_code = cm_req->discon_req.req.reason_code;
+	req->req.is_no_disassoc_disconnect =
+			cm_req->discon_req.req.is_no_disassoc_disconnect;
 
 	cm_update_scan_mlme_on_disconnect(cm_ctx->vdev,
 					  &cm_req->discon_req);
@@ -457,6 +460,7 @@ QDF_STATUS cm_disconnect_complete(struct cnx_mgr *cm_ctx,
 		return QDF_STATUS_SUCCESS;
 
 	mlme_cm_disconnect_complete_ind(cm_ctx->vdev, resp);
+	mlo_sta_link_disconn_notify(cm_ctx->vdev, resp);
 	mlme_cm_osif_disconnect_complete(cm_ctx->vdev, resp);
 	cm_if_mgr_inform_disconnect_complete(cm_ctx->vdev);
 	cm_inform_blm_disconnect_complete(cm_ctx->vdev, resp);
@@ -613,6 +617,10 @@ QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev,
 	if (!cm_req)
 		return QDF_STATUS_E_NOMEM;
 
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
+	    !wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+		req->is_no_disassoc_disconnect = 1;
+
 	disconnect_req = &cm_req->discon_req;
 	disconnect_req->req = *req;
 
@@ -635,6 +643,10 @@ QDF_STATUS cm_disconnect_start_req_sync(struct wlan_objmgr_vdev *vdev,
 	if (!cm_ctx)
 		return QDF_STATUS_E_INVAL;
 
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
+	    !wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+		req->is_no_disassoc_disconnect = 1;
+
 	qdf_event_reset(&cm_ctx->disconnect_complete);
 	status = cm_disconnect_start_req(vdev, req);
 	if (QDF_IS_STATUS_ERROR(status)) {

+ 21 - 1
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h

@@ -26,6 +26,9 @@
 #include <wlan_scan_public_structs.h>
 #include "wlan_crypto_global_def.h"
 #include "qdf_status.h"
+#ifdef WLAN_FEATURE_11BE_MLO
+#include <wlan_mlo_mgr_public_structs.h>
+#endif
 
 #define CM_ID_INVALID 0xFFFFFFFF
 typedef uint32_t wlan_cm_id;
@@ -191,6 +194,8 @@ enum wlan_cm_source {
  * @vht_caps: vht capability information bit mask
  * @vht_caps_mask: mask of valid vht caps
  * @fils_info: Fills related connect info
+ * @is_non_assoc_link: non assoc link
+ * @ml_parnter_info: ml partner link info
  */
 struct wlan_cm_connect_req {
 	uint8_t vdev_id;
@@ -216,7 +221,10 @@ struct wlan_cm_connect_req {
 #ifdef WLAN_FEATURE_FILS_SK
 	struct wlan_fils_con_info fils_info;
 #endif
-	bool is_secondary_link_connect;
+	bool is_non_assoc_link;
+#ifdef WLAN_FEATURE_11BE_MLO
+	struct mlo_partner_info ml_parnter_info;
+#endif
 };
 
 /**
@@ -238,6 +246,8 @@ struct wlan_cm_connect_req {
  * @scan_ie: Default scan ie to be used in the uncast probe req
  * @bss: scan entry for the candidate
  * @fils_info: Fills related connect info
+ * @is_non_assoc_link: non assoc link
+ * @ml_parnter_info: ml partner link info
  */
 struct wlan_cm_vdev_connect_req {
 	uint8_t vdev_id;
@@ -254,6 +264,10 @@ struct wlan_cm_vdev_connect_req {
 	struct scan_cache_node *bss;
 #ifdef WLAN_FEATURE_FILS_SK
 	struct wlan_fils_con_info *fils_info;
+#endif
+	bool is_non_assoc_link;
+#ifdef WLAN_FEATURE_11BE_MLO
+	struct mlo_partner_info ml_parnter_info;
 #endif
 };
 
@@ -301,12 +315,14 @@ struct wlan_cm_vdev_reassoc_req {
  * propitiatory will be used to send in
  * QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON
  * @bssid: bssid of AP
+ * @is_no_disassoc_disconnect: Is disassoc required
  */
 struct wlan_cm_disconnect_req {
 	uint8_t vdev_id;
 	enum wlan_cm_source source;
 	enum wlan_reason_code reason_code;
 	struct qdf_mac_addr bssid;
+	bool is_no_disassoc_disconnect;
 };
 
 /**
@@ -470,6 +486,7 @@ struct wlan_roam_sync_info {
  * @connect_ies: connect related IE required by osif to send to kernel
  * @roaming_info: roam sync info received
  * @is_fils_connection: is fils connection
+ * @ml_parnter_info: ml partner link info
  */
 struct wlan_cm_connect_resp {
 	uint8_t vdev_id;
@@ -492,6 +509,9 @@ struct wlan_cm_connect_resp {
 #ifdef WLAN_FEATURE_FILS_SK
 	bool is_fils_connection;
 #endif
+#ifdef WLAN_FEATURE_11BE_MLO
+	struct mlo_partner_info ml_parnter_info;
+#endif
 };
 
 #ifdef WLAN_FEATURE_PREAUTH_ENABLE