From 438c9178cd8ab629025374ea598b060024a410e7 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Tue, 21 Oct 2025 21:33:58 +0800 Subject: [PATCH] wifi: rtw89: support EHT rate pattern via bitrate mask When setting bitrate mask, e.g. using iw set bitrates, there are some designated patterns to be recognized, called rate pattern. When a rate pattern is matched, treat the setting as asking a fixed rate. Now, add support to recognize EHT rates. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20251021133402.15467-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/phy.c | 39 +++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index ba7feadd75828..23892c1359a56 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -231,7 +231,12 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, return -1; } - if (link_sta->he_cap.has_he) { + if (link_sta->eht_cap.has_eht) { + cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[0], + RA_MASK_EHT_1SS_RATES); + cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[1], + RA_MASK_EHT_2SS_RATES); + } else if (link_sta->he_cap.has_he) { cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0], RA_MASK_HE_1SS_RATES); cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1], @@ -557,6 +562,14 @@ static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next, return true; } +enum __rtw89_hw_rate_invalid_bases { + /* no EHT rate for ax chip */ + RTW89_HW_RATE_EHT_NSS1_MCS0 = RTW89_HW_RATE_INVAL, + RTW89_HW_RATE_EHT_NSS2_MCS0 = RTW89_HW_RATE_INVAL, + RTW89_HW_RATE_EHT_NSS3_MCS0 = RTW89_HW_RATE_INVAL, + RTW89_HW_RATE_EHT_NSS4_MCS0 = RTW89_HW_RATE_INVAL, +}; + #define RTW89_HW_RATE_BY_CHIP_GEN(rate) \ { \ [RTW89_CHIP_AX] = RTW89_HW_RATE_ ## rate, \ @@ -572,6 +585,12 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, struct rtw89_phy_rate_pattern next_pattern = {0}; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + static const u16 hw_rate_eht[][RTW89_CHIP_GEN_NUM] = { + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS1_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS2_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS3_MCS0), + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS4_MCS0), + }; static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = { RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0), RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0), @@ -596,6 +615,17 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, u8 tx_nss = rtwdev->hal.tx_nss; u8 i; + if (chip_gen == RTW89_CHIP_AX) + goto rs_11ax; + + for (i = 0; i < tx_nss; i++) + if (!__check_rate_pattern(&next_pattern, hw_rate_eht[i][chip_gen], + RA_MASK_EHT_RATES, RTW89_RA_MODE_EHT, + mask->control[nl_band].eht_mcs[i], + 0, true)) + goto out; + +rs_11ax: for (i = 0; i < tx_nss; i++) if (!__check_rate_pattern(&next_pattern, hw_rate_he[i][chip_gen], RA_MASK_HE_RATES, RTW89_RA_MODE_HE, @@ -640,6 +670,13 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, if (!next_pattern.enable) goto out; + if (unlikely(next_pattern.rate >= RTW89_HW_RATE_INVAL)) { + rtw89_debug(rtwdev, RTW89_DBG_RA, + "pattern invalid target: chip_gen %d, mode 0x%x\n", + chip_gen, next_pattern.ra_mode); + goto out; + } + rtwvif_link->rate_pattern = next_pattern; rtw89_debug(rtwdev, RTW89_DBG_RA, "configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n", -- 2.47.3