]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: fix VHT MCS assignment
authorBaochen Qiang <baochen.qiang@oss.qualcomm.com>
Thu, 9 Oct 2025 21:16:55 +0000 (14:16 -0700)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Wed, 15 Oct 2025 23:37:54 +0000 (16:37 -0700)
While associating, firmware needs the peer's receive capability
to calculate its own VHT transmit MCS. Currently, the host
sends this information via mcs->rx_mcs_set field, but firmware
actually reads it from mcs->tx_mcs_set field. This mismatch is
incorrect.

This issue has not caused failures so far because most peers
advertise identical TX and RX capabilities. Fix this by
assigning the value to tx_mcs_set as expected.

Additionally, the rate control mask is intended to limit our
transmit MCS, so it should also apply to the peer's receive
capability. Update the logic accordingly.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20251009211656.2386085-2-quic_pradeepc@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/mac.c
drivers/net/wireless/ath/ath12k/wmi.c
drivers/net/wireless/ath/ath12k/wmi.h

index 84473dbf22e13d1dc4a9596edc2890e459b484d7..3037076060760d0f4313da887d4d41e238e0b5fc 100644 (file)
@@ -2249,7 +2249,6 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar,
        struct cfg80211_chan_def def;
        enum nl80211_band band;
        u16 *vht_mcs_mask;
-       u16 tx_mcs_map;
        u8 ampdu_factor;
        u8 max_nss, vht_mcs;
        int i, vht_nss, nss_idx;
@@ -2340,10 +2339,10 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar,
        arg->peer_nss = min(link_sta->rx_nss, max_nss);
        arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
        arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
-       arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
+       arg->rx_mcs_set = ath12k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask);
 
-       tx_mcs_map = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
-       arg->tx_mcs_set = ath12k_peer_assoc_h_vht_limit(tx_mcs_map, vht_mcs_mask);
+       arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
+       arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
 
        /* In QCN9274 platform, VHT MCS rate 10 and 11 is enabled by default.
         * VHT MCS rate 10 and 11 is not supported in 11ac standard.
index ff6b3d4ea8208459f4e7bcf4475d386adce2d120..e76275bd6916f7601678cd4af6455d7f5f25c2c2 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 #include <linux/skbuff.h>
 #include <linux/ctype.h>
@@ -2367,10 +2367,13 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
        cmd->peer_bw_rxnss_override |= cpu_to_le32(arg->peer_bw_rxnss_override);
 
        if (arg->vht_capable) {
-               mcs->rx_max_rate = cpu_to_le32(arg->rx_max_rate);
-               mcs->rx_mcs_set = cpu_to_le32(arg->rx_mcs_set);
-               mcs->tx_max_rate = cpu_to_le32(arg->tx_max_rate);
-               mcs->tx_mcs_set = cpu_to_le32(arg->tx_mcs_set);
+               /* Firmware interprets mcs->tx_mcs_set field as peer's
+                * RX capability
+                */
+               mcs->rx_max_rate = cpu_to_le32(arg->tx_max_rate);
+               mcs->rx_mcs_set = cpu_to_le32(arg->tx_mcs_set);
+               mcs->tx_max_rate = cpu_to_le32(arg->rx_max_rate);
+               mcs->tx_mcs_set = cpu_to_le32(arg->rx_mcs_set);
        }
 
        /* HE Rates */
index d9fd6a6b708ddb14b704e65f6d014db3abe60446..64bd968989c841f3a023f0fe1a1f66ec9fde01f5 100644 (file)
@@ -4204,8 +4204,10 @@ struct wmi_unit_test_cmd {
 struct ath12k_wmi_vht_rate_set_params {
        __le32 tlv_header;
        __le32 rx_max_rate;
+       /* MCS at which the peer can transmit */
        __le32 rx_mcs_set;
        __le32 tx_max_rate;
+       /* MCS at which the peer can receive */
        __le32 tx_mcs_set;
        __le32 tx_max_mcs_nss;
 } __packed;