[PATCH v2 1/2] wifi: ath11k: apply the 160 MHz NSS ratio to the radio
Julius Bairaktaris
julius at bairaktaris.de
Wed Oct 21 09:51:37 PDT 2026
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: f552d6fd2f27 ("ath11k: add support for 80P80 and 160 MHz bandwidth")
Assisted-by: LLM
Signed-off-by: Julius Bairaktaris <julius at bairaktaris.de>
---
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 1a237adaa37d1..a842306d65d9c 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);
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,
--
2.53.0
More information about the ath12k
mailing list