]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: ath12k: introduce host_alloc_ml_id hardware parameter
authorBaochen Qiang <baochen.qiang@oss.qualcomm.com>
Mon, 20 Jul 2026 06:43:26 +0000 (14:43 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 27 Jul 2026 15:00:42 +0000 (08:00 -0700)
Different ath12k devices diverge on who allocates MLD peer id:
WCN7850/QCC2072 have the firmware allocate it and notify the host via
HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP event; While others let the host allocate
it and pass it down through WMI_PEER_ASSOC_CMDID with
ATH12K_WMI_FLAG_MLO_PEER_ID_VALID set.

Currently ath12k host allocates this ID and sends it to firmware by
default for all devices. This breaks WCN7850/QCC2072, because the host
maintained ID may be different from the firmware-allocated one.
Consequently data path may fail to find the dp peer and drop some received
packets. From user point of view, this results in bugs reported in [1] or
the 4-way handshake timeout issue.

Add host_alloc_ml_id flag to struct ath12k_hw_params (and a copy on struct
ath12k_hw for hot-path access) so subsequent patches can branch on it. Set
true for QCN9274/IPQ5332/IPQ5424, false for WCN7850/QCC2072. The flag will
be consumed by subsequent patches.

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

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221039
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260720-ath12k-fw-allocated-ml-peer-id-v2-5-630632758a80@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/hw.h
drivers/net/wireless/ath/ath12k/mac.c
drivers/net/wireless/ath/ath12k/wifi7/hw.c

index fc5127b5c1a37f7d3e1e9319b13638472147441a..1f56474efbea4511d5f8f0e1be4fa747380fea75 100644 (file)
@@ -793,6 +793,7 @@ struct ath12k_hw {
        enum ath12k_hw_state state;
        bool regd_updated;
        bool use_6ghz_regd;
+       bool host_alloc_ml_id;
 
        u8 num_radio;
 
index 86fb8b71961350dd26e33fa6e7f2b66d89d723ca..8d2fa0bfb96c1dfdd7f195b519d9b3efbbddb675 100644 (file)
@@ -236,6 +236,8 @@ struct ath12k_hw_params {
                u32 max_client_dbs;
                u32 max_client_dbs_sbs;
        } client;
+
+       bool host_alloc_ml_id;
 };
 
 struct ath12k_hw_ops {
index 06f1a1ba994ad0ca82be6dc234917eb9c5a3f082..51641c5ff265a344c97d6e58386a0e3fce24d0c9 100644 (file)
@@ -15385,8 +15385,9 @@ int ath12k_mac_allocate(struct ath12k_hw_group *ag)
        int mac_id, device_id, total_radio, num_hw;
        struct ath12k_base *ab;
        struct ath12k_hw *ah;
-       int ret, i, j;
+       bool conf = false;
        u8 radio_per_hw;
+       int ret, i, j;
 
        total_radio = 0;
        for (i = 0; i < ag->num_devices; i++) {
@@ -15426,6 +15427,20 @@ int ath12k_mac_allocate(struct ath12k_hw_group *ag)
                        }
 
                        ab = ag->ab[device_id];
+
+                       /*
+                        * the assumption is all devices within an ah
+                        * share the same host_alloc_ml_id configuration
+                        */
+                       if (j == 0) {
+                               conf = ab->hw_params->host_alloc_ml_id;
+                       } else if (conf != ab->hw_params->host_alloc_ml_id) {
+                               ath12k_warn(ab, "inconsistent ML ID config within ah, device 0 uses %s allocated ID, while device %u doesn't\n",
+                                           conf ? "host" : "firmware", device_id);
+                               ret = -EINVAL;
+                               goto err;
+                       }
+
                        pdev_map[j].ab = ab;
                        pdev_map[j].pdev_idx = mac_id;
                        mac_id++;
@@ -15450,6 +15465,7 @@ int ath12k_mac_allocate(struct ath12k_hw_group *ag)
                }
 
                ah->dev = ab->dev;
+               ah->host_alloc_ml_id = conf;
 
                ag->ah[i] = ah;
                ag->num_hw++;
index d9fdd2fc82986abef849a0f068b66db33afe02bc..03dedfd907fc7f4bf835653efee867dfe101344f 100644 (file)
@@ -442,6 +442,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
                        .max_client_dbs = 128,
                        .max_client_dbs_sbs = 128,
                },
+
+               .host_alloc_ml_id = true,
        },
        {
                .name = "wcn7850 hw2.0",
@@ -533,6 +535,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
                        .max_client_dbs = 128,
                        .max_client_dbs_sbs = 128,
                },
+
+               .host_alloc_ml_id = false,
        },
        {
                .name = "qcn9274 hw2.0",
@@ -620,6 +624,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
                        .max_client_dbs = 128,
                        .max_client_dbs_sbs = 128,
                },
+
+               .host_alloc_ml_id = true,
        },
        {
                .name = "ipq5332 hw1.0",
@@ -700,6 +706,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
                        .max_client_dbs = 128,
                        .max_client_dbs_sbs = 128,
                },
+
+               .host_alloc_ml_id = true,
        },
        {
                .name = "qcc2072 hw1.0",
@@ -792,6 +800,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
                        .max_client_dbs = 128,
                        .max_client_dbs_sbs = 128,
                },
+
+               .host_alloc_ml_id = false,
        },
        {
                .name = "ipq5424 hw1.0",
@@ -876,6 +886,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
                        .max_client_dbs = 128,
                        .max_client_dbs_sbs = 128,
                },
+
+               .host_alloc_ml_id = true,
        },
 };