summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw89/phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/phy.c')
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index ba7feadd7582..9f418b1fb7ed 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],
@@ -471,6 +476,10 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra->ra_mask = ra_mask;
ra->fix_giltf_en = fix_giltf_en;
ra->fix_giltf = fix_giltf;
+ ra->partial_bw_er = link_sta->he_cap.has_he ?
+ !!(link_sta->he_cap.he_cap_elem.phy_cap_info[6] &
+ IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE) : 0;
+ ra->band = chan->band_type;
if (!csi)
return;
@@ -557,6 +566,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 +589,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 +619,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 +674,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",
@@ -2339,6 +2380,21 @@ static u8 rtw89_channel_to_idx(struct rtw89_dev *rtwdev, u8 band, u8 channel)
}
}
+static bool rtw89_phy_validate_txpwr_limit_bw(struct rtw89_dev *rtwdev,
+ u8 band, u8 bw)
+{
+ switch (band) {
+ case RTW89_BAND_2G:
+ return bw < RTW89_2G_BW_NUM;
+ case RTW89_BAND_5G:
+ return bw < RTW89_5G_BW_NUM;
+ case RTW89_BAND_6G:
+ return bw < RTW89_6G_BW_NUM;
+ default:
+ return false;
+ }
+}
+
s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch)
{
@@ -2363,6 +2419,11 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
};
s8 cstr;
+ if (!rtw89_phy_validate_txpwr_limit_bw(rtwdev, band, bw)) {
+ rtw89_warn(rtwdev, "invalid band %u bandwidth %u\n", band, bw);
+ return 0;
+ }
+
switch (band) {
case RTW89_BAND_2G:
if (has_ant_gain)
@@ -4551,7 +4612,7 @@ static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo)
s32 dcfo_comp_val;
int sign;
- if (rtwdev->chip->chip_id == RTL8922A)
+ if (!dcfo_comp)
return;
if (!is_linked) {