Browse Source

qcacmn: Reject partner link connection in case of IE parsing failure

Currently while updating the mlo vdev flag host checks whether the
mlie is present, this vdev flag is used to send various ml information
to firmware. In certain cases because of issue due to parsing of
ml probe response or AP issues mlie is not present in the partner link
entry, resulting in host sending ml flags for assoc vdev and not setting
ml flags for partner vdev's resulting in undetermined behaviors in
firmware.

If mlie is not present during the partner link association stay associated
on the available links.

Change-Id: I3134555dc955ffc96a50584c2cfc6713b2673cc4
CRs-Fixed: 3555133
Arun Kumar Khandavalli 2 years ago
parent
commit
4c2b8d81e4

+ 27 - 10
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -464,20 +464,20 @@ void cm_set_vdev_link_id(struct cnx_mgr *cm_ctx,
 	wlan_vdev_set_link_id(cm_ctx->vdev, link_id);
 }
 
-static void cm_update_vdev_mlme_macaddr(struct cnx_mgr *cm_ctx,
-					struct cm_connect_req *req)
+static QDF_STATUS cm_update_vdev_mlme_macaddr(struct cnx_mgr *cm_ctx,
+					      struct cm_connect_req *req)
 {
 	struct qdf_mac_addr *mac;
 	bool eht_capab;
 	uint8_t vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
 
 	if (wlan_vdev_mlme_get_opmode(cm_ctx->vdev) != QDF_STA_MODE)
-		return;
+		return QDF_STATUS_SUCCESS;
 
 	wlan_psoc_mlme_get_11be_capab(wlan_vdev_get_psoc(cm_ctx->vdev),
 				      &eht_capab);
 	if (!eht_capab)
-		return;
+		return QDF_STATUS_SUCCESS;
 
 	mac = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(cm_ctx->vdev);
 
@@ -493,6 +493,13 @@ static void cm_update_vdev_mlme_macaddr(struct cnx_mgr *cm_ctx,
 			   CM_PREFIX_REF(vdev_id, req->cm_id),
 			   QDF_MAC_ADDR_REF(mac->bytes));
 	} else {
+		if (wlan_vdev_mlme_is_mlo_link_vdev(cm_ctx->vdev)) {
+			mlme_debug(CM_PREFIX_FMT "MLIE is not present for partner" QDF_MAC_ADDR_FMT,
+				   CM_PREFIX_REF(vdev_id, req->cm_id),
+				   QDF_MAC_ADDR_REF(mac->bytes));
+			return QDF_STATUS_E_INVAL;
+		}
+
 		/* Use net_dev address for non-ML connection */
 		if (!qdf_is_macaddr_zero(mac)) {
 			wlan_vdev_obj_lock(cm_ctx->vdev);
@@ -504,6 +511,8 @@ static void cm_update_vdev_mlme_macaddr(struct cnx_mgr *cm_ctx,
 		}
 		wlan_vdev_mlme_clear_mlo_vdev(cm_ctx->vdev);
 	}
+
+	return QDF_STATUS_SUCCESS;
 }
 #else
 static inline
@@ -511,9 +520,10 @@ void cm_set_vdev_link_id(struct cnx_mgr *cm_ctx,
 			 struct cm_connect_req *req)
 { }
 
-static void cm_update_vdev_mlme_macaddr(struct cnx_mgr *cm_ctx,
-					struct cm_connect_req *req)
+static QDF_STATUS cm_update_vdev_mlme_macaddr(struct cnx_mgr *cm_ctx,
+					      struct cm_connect_req *req)
 {
+	return QDF_STATUS_SUCCESS;
 }
 #endif
 /**
@@ -564,9 +574,10 @@ void cm_set_vdev_link_id(struct cnx_mgr *cm_ctx,
 			 struct cm_connect_req *req)
 { }
 
-static void cm_update_vdev_mlme_macaddr(struct cnx_mgr *cm_ctx,
-					struct cm_connect_req *req)
+static QDF_STATUS cm_update_vdev_mlme_macaddr(struct cnx_mgr *cm_ctx,
+					      struct cm_connect_req *req)
 {
+	return QDF_STATUS_SUCCESS;
 }
 
 static struct qdf_mac_addr *cm_get_bss_peer_mld_addr(struct cm_connect_req *req)
@@ -2078,7 +2089,10 @@ QDF_STATUS cm_try_next_candidate(struct cnx_mgr *cm_ctx,
 	 */
 	if (status == QDF_STATUS_E_NOSUPPORT) {
 		/* Update vdev mlme mac address based on connection type */
-		cm_update_vdev_mlme_macaddr(cm_ctx, &cm_req->connect_req);
+		status = cm_update_vdev_mlme_macaddr(cm_ctx,
+						     &cm_req->connect_req);
+		if (QDF_IS_STATUS_ERROR(status))
+			goto connect_err;
 
 		cm_create_bss_peer(cm_ctx, &cm_req->connect_req);
 	} else if (QDF_IS_STATUS_ERROR(status)) {
@@ -2172,7 +2186,10 @@ QDF_STATUS cm_connect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 	 */
 	if (status == QDF_STATUS_E_NOSUPPORT) {
 		/* Update vdev mlme mac address based on connection type */
-		cm_update_vdev_mlme_macaddr(cm_ctx, &cm_req->connect_req);
+		status = cm_update_vdev_mlme_macaddr(cm_ctx,
+						     &cm_req->connect_req);
+		if (QDF_IS_STATUS_ERROR(status))
+			goto connect_err;
 
 		cm_create_bss_peer(cm_ctx, &cm_req->connect_req);
 	} else if (QDF_IS_STATUS_ERROR(status)) {

+ 24 - 2
umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

@@ -1171,6 +1171,27 @@ void mlo_handle_pending_disconnect(struct wlan_objmgr_vdev *vdev)
 	}
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
+static bool
+mlo_sta_ignore_link_connect_fail(struct wlan_objmgr_vdev *vdev)
+{
+	if (wlan_cm_is_vdev_disconnected(vdev)) {
+		if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+			return false;
+		else
+			return true;
+	}
+
+	return false;
+}
+#else
+static inline bool
+mlo_sta_ignore_link_connect_fail(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+#endif
+
 void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev,
 				 struct wlan_cm_connect_resp *rsp)
 {
@@ -1191,12 +1212,13 @@ void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev,
 		return;
 	}
 
-	if (wlan_cm_is_vdev_disconnected(vdev))
-		mlo_free_copied_conn_req(sta_ctx);
+	if (mlo_sta_ignore_link_connect_fail(vdev))
+		return;
 
 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
 		mlo_debug("Vdev: %d", wlan_vdev_get_id(vdev));
 		if (wlan_cm_is_vdev_disconnected(vdev)) {
+			mlo_free_copied_conn_req(sta_ctx);
 			mlo_handle_sta_link_connect_failure(vdev, rsp);
 			return;
 		} else if (!wlan_cm_is_vdev_connected(vdev)) {