qcacmn: Fix race condition of mlo disconnect/connect

Steps:
1. wpa_supplicant started connect, scheduler thread was connecting vdev0.
2. Wifico disconnect cmd came, found vdev1 not connected, drop cmd for
vdev1.
3. scheduler thread connected vdev0, started to connect vdev1.
4. Wifico started to disconnect vdev0.
5. scheduler thread created bss peer of vdev1, connected vdev1.
6. scheduler thread deleted bss peer of vdev0 as part of disconnect vdev0.
7. F/W assert for deleting assoc peer before link peer.

To fix it, when partner link connect complete, if found assoc link not
connected, trigger mlo disconnect.

Change-Id: I8bb06992c7a0976cdab7a6470180b5faa1f386ab
CRs-Fixed: 3330583
This commit is contained in:
Jianmin Zhu
2022-11-08 17:15:05 +08:00
committed by Madan Koyyalamudi
parent 062186ff39
commit 604581a51d

View File

@@ -784,13 +784,19 @@ static QDF_STATUS ml_activate_pend_disconn_req_cb(struct scheduler_msg *msg)
mlo_dev_ctx = vdev->mlo_dev_ctx;
sta_ctx = mlo_dev_ctx->sta_ctx;
mlo_disconnect(vdev, sta_ctx->disconn_req->source,
sta_ctx->disconn_req->reason_code,
&sta_ctx->disconn_req->bssid);
qdf_mem_free(sta_ctx->disconn_req);
sta_ctx->disconn_req = NULL;
if (sta_ctx->disconn_req) {
mlo_disconnect(vdev, sta_ctx->disconn_req->source,
sta_ctx->disconn_req->reason_code,
&sta_ctx->disconn_req->bssid);
qdf_mem_free(sta_ctx->disconn_req);
sta_ctx->disconn_req = NULL;
} else {
mlo_disconnect(vdev, CM_MLME_DISCONNECT,
REASON_DEAUTH_NETWORK_LEAVING,
NULL);
}
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLO_MGR_ID);
return QDF_STATUS_SUCCESS;
}
@@ -917,6 +923,7 @@ void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev,
{
struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
struct wlan_mlo_sta *sta_ctx = NULL;
struct wlan_objmgr_vdev *assoc_vdev;
if (mlo_dev_ctx) {
sta_ctx = mlo_dev_ctx->sta_ctx;
@@ -932,6 +939,16 @@ void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev,
return;
}
assoc_vdev = mlo_get_assoc_link_vdev(vdev->mlo_dev_ctx);
if (assoc_vdev && QDF_IS_STATUS_SUCCESS(rsp->connect_status) &&
!wlan_cm_is_vdev_connected(assoc_vdev)) {
mlo_debug("Handle pending disconnect for vdev %d",
wlan_vdev_get_id(vdev));
if (assoc_vdev != vdev)
mlo_handle_pending_disconnect(vdev);
return;
}
if (wlan_cm_is_vdev_disconnected(vdev))
mlo_free_copied_conn_req(sta_ctx);