]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath12k: fix inconsistent arvif state in vdev_create error paths
authorWei Zhang <wei.zhang@oss.qualcomm.com>
Tue, 12 May 2026 04:49:04 +0000 (21:49 -0700)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 1 Jun 2026 16:58:04 +0000 (09:58 -0700)
ath12k_mac_vdev_create() has three error path issues that leave arvif
in an inconsistent state:

1. When ath12k_wmi_vdev_create() fails, the function returns directly
   without clearing arvif->ar, which was already set before the WMI
   call. Subsequent code checking arvif->ar to determine vdev readiness
   will see a non-NULL value despite no vdev existing in firmware.

2. When ath12k_wmi_send_peer_delete_cmd() fails in err_peer_del, the
   code jumped to err: skipping the DP peer cleanup and vdev rollback,
   leaving num_created_vdevs, vdev maps and arvif list membership live.

3. When ath12k_wait_for_peer_delete_done() fails, the code jumped to
   err_vdev_del: skipping the DP peer cleanup.

Fix by changing the ath12k_wmi_vdev_create() failure to goto err instead
of returning directly, routing both err_peer_del failure paths through
err_dp_peer_del: for proper DP peer and vdev rollback, and consolidating
the arvif state cleanup at err:.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3

Fixes: 477cabfdb776 ("wifi: ath12k: modify link arvif creation and removal for MLO")
Signed-off-by: Wei Zhang <wei.zhang@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260512044906.1735821-2-wei.zhang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/mac.c

index 87b27f7cff5d6d9205618c49fb3cbad7162d253e..b9b95f7f1f60b073d5d056fea3d2e6f1d2c5111d 100644 (file)
@@ -10302,7 +10302,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
        if (ret) {
                ath12k_warn(ab, "failed to create WMI vdev %d: %d\n",
                            arvif->vdev_id, ret);
-               return ret;
+               goto err;
        }
 
        ar->num_created_vdevs++;
@@ -10449,13 +10449,13 @@ err_peer_del:
                if (ret) {
                        ath12k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n",
                                    arvif->vdev_id, arvif->bssid);
-                       goto err;
+                       goto err_dp_peer_del;
                }
 
                ret = ath12k_wait_for_peer_delete_done(ar, arvif->vdev_id,
                                                       arvif->bssid);
                if (ret)
-                       goto err_vdev_del;
+                       goto err_dp_peer_del;
 
                ar->num_peers--;
        }
@@ -10472,8 +10472,6 @@ err_vdev_del:
 
        ath12k_wmi_vdev_delete(ar, arvif->vdev_id);
        ar->num_created_vdevs--;
-       arvif->is_created = false;
-       arvif->ar = NULL;
        ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id);
        ab->free_vdev_map |= 1LL << arvif->vdev_id;
        ab->free_vdev_stats_id_map &= ~(1LL << arvif->vdev_stats_id);
@@ -10482,6 +10480,7 @@ err_vdev_del:
        spin_unlock_bh(&ar->data_lock);
 
 err:
+       arvif->is_created = false;
        arvif->ar = NULL;
        return ret;
 }