Explorar o código

qcacmn: Add mlo peer check in disconnect handling

In case of handling disconnect while sta is connected, if previous
connection is non-ml and a new connect is received with ml
connection on partner link then disconnect request on connected link
is getting ignored.
Fix to add mlo peer check in disconnect handling.

Change-Id: I456b45a080375b93ce209300bf7719e9e53733dc
CRs-Fixed: 3394233
Himanshu Batra %!s(int64=2) %!d(string=hai) anos
pai
achega
97524335e8
Modificáronse 1 ficheiros con 36 adicións e 33 borrados
  1. 36 33
      umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

+ 36 - 33
umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

@@ -217,9 +217,10 @@ mlo_send_link_disconnect(struct wlan_objmgr_vdev *vdev,
 
 	mlo_sta_get_vdev_list(vdev, &vdev_count, wlan_vdev_list);
 	for (i =  0; i < vdev_count; i++) {
-		if (qdf_test_bit(i, sta_ctx->wlan_connected_links) &&
-		    wlan_vdev_list[i] !=
-		    mlo_get_assoc_link_vdev(vdev->mlo_dev_ctx))
+		if ((wlan_vdev_list[i] != mlo_get_assoc_link_vdev(vdev->mlo_dev_ctx)) &&
+		    (qdf_test_bit(i, sta_ctx->wlan_connected_links) ||
+		    (wlan_cm_is_vdev_connected(wlan_vdev_list[i]) &&
+		    !wlan_peer_is_mlo(wlan_vdev_get_bsspeer(wlan_vdev_list[i])))))
 			wlan_cm_disconnect(wlan_vdev_list[i],
 					   link_source, reason_code,
 					   NULL);
@@ -461,7 +462,7 @@ static QDF_STATUS mlo_disconnect_no_lock(struct wlan_objmgr_vdev *vdev,
 		status = mlo_validate_disconn_req(vdev, source,
 						  reason_code, bssid);
 		if (QDF_IS_STATUS_ERROR(status)) {
-			mlo_debug("Connect in progress, deferring disconnect");
+			mlo_err("Connect in progress, deferring disconnect");
 			return status;
 		}
 
@@ -469,8 +470,10 @@ static QDF_STATUS mlo_disconnect_no_lock(struct wlan_objmgr_vdev *vdev,
 			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] != assoc_vdev)
+			if ((mlo_dev_ctx->wlan_vdev_list[i] != assoc_vdev) &&
+			    (qdf_test_bit(i, mlo_dev_ctx->sta_ctx->wlan_connected_links) ||
+			    (wlan_cm_is_vdev_connected(mlo_dev_ctx->wlan_vdev_list[i]) &&
+			     !wlan_peer_is_mlo(wlan_vdev_get_bsspeer(mlo_dev_ctx->wlan_vdev_list[i])))))
 				wlan_cm_disconnect(mlo_dev_ctx->wlan_vdev_list[i],
 						   source, reason_code,
 						   NULL);
@@ -1240,7 +1243,7 @@ static QDF_STATUS mlo_disconnect_req(struct wlan_objmgr_vdev *vdev,
 			status = mlo_validate_disconn_req(vdev, source,
 							  reason_code, bssid);
 			if (QDF_IS_STATUS_ERROR(status)) {
-				mlo_debug("Connect in progress, deferring disconnect");
+				mlo_err("Connect in progress, deferring disconnect");
 				mlo_dev_lock_release(mlo_dev_ctx);
 				return status;
 			}
@@ -1354,6 +1357,10 @@ static QDF_STATUS ml_activate_connect_req_sched_cb(struct scheduler_msg *msg)
 	struct wlan_objmgr_vdev *vdev = msg->bodyptr;
 	struct wlan_mlo_dev_context *mlo_dev_ctx = NULL;
 	struct wlan_mlo_sta *sta_ctx = NULL;
+	uint8_t i = 0;
+	struct mlo_partner_info partner_info;
+	struct mlo_link_info partner_link_info;
+	struct wlan_objmgr_vdev *tmp_vdev;
 
 	if (!vdev) {
 		mlme_err("Null input vdev");
@@ -1372,6 +1379,28 @@ static QDF_STATUS ml_activate_connect_req_sched_cb(struct scheduler_msg *msg)
 		return QDF_STATUS_E_INVAL;
 	}
 
+	if (sta_ctx->connect_req->ml_parnter_info.num_partner_links) {
+		partner_info = sta_ctx->connect_req->ml_parnter_info;
+		wlan_vdev_mlme_set_mlo_vdev(vdev);
+		wlan_vdev_mlme_clear_mlo_link_vdev(vdev);
+		mlo_clear_connect_req_links_bmap(vdev);
+		mlo_update_connect_req_links(vdev, 1);
+		for (i = 0; i < partner_info.num_partner_links; i++) {
+			partner_link_info = partner_info.partner_link_info[i];
+			tmp_vdev = mlo_get_ml_vdev_by_mac(
+					vdev,
+					&partner_link_info.link_addr);
+			if (tmp_vdev) {
+				mlo_update_connect_req_links(tmp_vdev, 1);
+				wlan_vdev_mlme_set_mlo_vdev(tmp_vdev);
+				wlan_vdev_mlme_set_mlo_link_vdev(tmp_vdev);
+				wlan_vdev_set_link_id(
+					tmp_vdev,
+					partner_link_info.link_id);
+			}
+		}
+	}
+
 	mlo_connect(vdev, sta_ctx->connect_req);
 	mlo_free_connect_ies(sta_ctx->connect_req);
 	qdf_mem_free(sta_ctx->connect_req);
@@ -1404,13 +1433,9 @@ static inline
 void mlo_sta_link_handle_pending_connect(struct wlan_objmgr_vdev *vdev)
 {
 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
-	struct wlan_objmgr_vdev *tmp_vdev;
 	struct scheduler_msg msg = {0};
 	QDF_STATUS ret;
 	struct wlan_mlo_sta *sta_ctx = NULL;
-	uint8_t i = 0;
-	struct mlo_partner_info partner_info;
-	struct mlo_link_info partner_link_info;
 
 	if (!mlo_dev_ctx) {
 		mlo_err("ML dev ctx is null");
@@ -1441,28 +1466,6 @@ void mlo_sta_link_handle_pending_connect(struct wlan_objmgr_vdev *vdev)
 					     WLAN_MLO_MGR_ID);
 		return;
 	}
-
-	if (sta_ctx->connect_req->ml_parnter_info.num_partner_links) {
-		partner_info = sta_ctx->connect_req->ml_parnter_info;
-		wlan_vdev_mlme_set_mlo_vdev(vdev);
-		wlan_vdev_mlme_clear_mlo_link_vdev(vdev);
-		mlo_clear_connect_req_links_bmap(vdev);
-		mlo_update_connect_req_links(vdev, 1);
-		for (i = 0; i < partner_info.num_partner_links; i++) {
-			partner_link_info = partner_info.partner_link_info[i];
-			tmp_vdev = mlo_get_ml_vdev_by_mac(
-					vdev,
-					&partner_link_info.link_addr);
-			if (tmp_vdev) {
-				mlo_update_connect_req_links(tmp_vdev, 1);
-				wlan_vdev_mlme_set_mlo_vdev(tmp_vdev);
-				wlan_vdev_mlme_set_mlo_link_vdev(tmp_vdev);
-				wlan_vdev_set_link_id(
-					tmp_vdev,
-					partner_link_info.link_id);
-			}
-		}
-	}
 }
 #endif