[PATCH] wifi: ath11k: apply the 160 MHz NSS ratio to the radio
Rameshkumar Sundaram
rameshkumar.sundaram at oss.qualcomm.com
Wed Oct 21 03:51:48 PDT 2026
On 10/11/2026 6:06 PM, Julius Bairaktaris wrote:
> The firmware reports the NSS a radio supports at 160 MHz as a ratio of
> its 80 MHz NSS. Peer assoc applies that ratio to the peer's NSS instead,
> so on a radio with a 1:2 ratio a two-stream peer is sent one stream at
> 160 MHz. The HE 160 and 80+80 MCS maps copy the 80 MHz map, so a
> 4-chain radio with that ratio offers 4 streams at 160 MHz where it
> supports 2.
>
> Take the 160 MHz NSS from the radio's TX chains, as ath12k does since
> commit a82ce08775bc ("wifi: ath12k: add extended NSS bandwidth support
> for 160 MHz"), and limit the 160 and 80+80 MCS maps to the ratio when
> the firmware reports one.
>
> Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.9.0.1-02146-QCAHKSWPL_SILICONZ-1
>
Fixes: ??
> Assisted-by: Claude:claude-opus-5-5
The model-specific "Claude:claude-opus-5-5" attribution may no longer be
required according to the newer guidance -
https://www.kernel.org/doc/html/latest/process/coding-assistants.html#attribution
> Signed-off-by: Julius Bairaktaris <julius at bairaktaris.de>
> ---
> On a Xiaomi AX3600 (IPQ8071A, 4-chain 5 GHz radio, firmware reports
> WMI_NSS_RATIO_1BY2_NSS), `iw phy` lists 4 streams in the HE 160 MHz
> MCS sets without this patch and 2 with it.
>
> drivers/net/wireless/ath/ath11k/mac.c | 24 +++++++++++++++++-------
> 1 file changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> index c1fa42edd3630..6cd163cab9bd7 100644
> --- a/drivers/net/wireless/ath/ath11k/mac.c
> +++ b/drivers/net/wireless/ath/ath11k/mac.c
> @@ -2278,7 +2278,7 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar,
>
> if (arg->peer_phymode == MODE_11AC_VHT160 ||
> arg->peer_phymode == MODE_11AC_VHT80_80) {
> - tx_nss = ath11k_get_nss_160mhz(ar, max_nss);
> + tx_nss = ath11k_get_nss_160mhz(ar, ar->num_tx_chains);
seems ath12k has same issue for VHT care to fix it ?
> rx_nss = min(arg->peer_nss, tx_nss);
> arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE;
>
> @@ -2588,7 +2588,7 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
>
> if (arg->peer_phymode == MODE_11AX_HE160 ||
> arg->peer_phymode == MODE_11AX_HE80_80) {
> - tx_nss = ath11k_get_nss_160mhz(ar, max_nss);
> + tx_nss = ath11k_get_nss_160mhz(ar, ar->num_tx_chains);
> rx_nss = min(arg->peer_nss, tx_nss);
> arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE;
>
> @@ -5940,7 +5940,7 @@ static void ath11k_mac_set_hemcsmap(struct ath11k *ar,
> struct ieee80211_sta_he_cap *he_cap,
> int band)
> {
> - u16 txmcs_map, rxmcs_map;
> + u16 txmcs_map, rxmcs_map, txmcs_map_160, rxmcs_map_160;
> u32 i;
>
> rxmcs_map = 0;
> @@ -5958,18 +5958,28 @@ static void ath11k_mac_set_hemcsmap(struct ath11k *ar,
> else
> rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
> }
> +
> + txmcs_map_160 = txmcs_map;
> + rxmcs_map_160 = rxmcs_map;
> + if (cap->nss_ratio_enabled) {
> + for (i = ath11k_get_nss_160mhz(ar, ar->num_tx_chains); i < 8; i++)
> + txmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
> + for (i = ath11k_get_nss_160mhz(ar, ar->num_rx_chains); i < 8; i++)
> + rxmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
> + }
> +
> he_cap->he_mcs_nss_supp.rx_mcs_80 =
> cpu_to_le16(rxmcs_map & 0xffff);
> he_cap->he_mcs_nss_supp.tx_mcs_80 =
> cpu_to_le16(txmcs_map & 0xffff);
> he_cap->he_mcs_nss_supp.rx_mcs_160 =
> - cpu_to_le16(rxmcs_map & 0xffff);
> + cpu_to_le16(rxmcs_map_160);
> he_cap->he_mcs_nss_supp.tx_mcs_160 =
> - cpu_to_le16(txmcs_map & 0xffff);
> + cpu_to_le16(txmcs_map_160);
> he_cap->he_mcs_nss_supp.rx_mcs_80p80 =
> - cpu_to_le16(rxmcs_map & 0xffff);
> + cpu_to_le16(rxmcs_map_160);
> he_cap->he_mcs_nss_supp.tx_mcs_80p80 =
> - cpu_to_le16(txmcs_map & 0xffff);
> + cpu_to_le16(txmcs_map_160);
> }
>
> static int ath11k_mac_copy_he_cap(struct ath11k *ar,
Actual changes looks fine to me
--
Ramesh
More information about the ath11k
mailing list