aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuan-Chung Chen <damon.chen@realtek.com>2022-09-12 15:00:13 +0800
committerKalle Valo <kvalo@kernel.org>2022-09-19 13:02:36 +0300
commit0891b366cef4d3d229d5737928e8312838d8a792 (patch)
treeacdcbc4f8ae75216cdd08f3fd28667ff65a3ff21
parentwifi: rtw89: coex: show connecting state in debug message (diff)
downloadlinux-dev-0891b366cef4d3d229d5737928e8312838d8a792.tar.xz
linux-dev-0891b366cef4d3d229d5737928e8312838d8a792.zip
wifi: rtw89: support for setting HE GI and LTF
Support setting HE GI and LTF values to the kernel via nl80211. We currently only support some GI and LTF values settings. The command example is: iw wlan0 set bitrates he-gi-2.4 0.8 he-ltf-2.4 2 Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220912070014.10018-2-pkshih@realtek.com
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h4
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.h10
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c39
4 files changed, 54 insertions, 1 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 28a33039e29e..e64ecb3768c0 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2069,7 +2069,9 @@ struct rtw89_ra_info {
u8 ra_csi_rate_en:1;
u8 fixed_csi_rate_en:1;
u8 cr_tbl_sel:1;
- u8 rsvd2:5;
+ u8 fix_giltf_en:1;
+ u8 fix_giltf:3;
+ u8 rsvd2:1;
u8 csi_mcs_ss_idx;
u8 csi_mode:2;
u8 csi_gi_ltf:3;
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 2444f5938bf6..28b746ab4884 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -1468,6 +1468,8 @@ int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi
RTW89_SET_FWCMD_RA_MASK_2(cmd, FIELD_GET(MASKBYTE2, ra->ra_mask));
RTW89_SET_FWCMD_RA_MASK_3(cmd, FIELD_GET(MASKBYTE3, ra->ra_mask));
RTW89_SET_FWCMD_RA_MASK_4(cmd, FIELD_GET(MASKBYTE4, ra->ra_mask));
+ RTW89_SET_FWCMD_RA_FIX_GILTF_EN(cmd, ra->fix_giltf_en);
+ RTW89_SET_FWCMD_RA_FIX_GILTF(cmd, ra->fix_giltf);
if (csi) {
RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, 1);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index a055ea55b2ad..6e3aca44906a 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -361,6 +361,16 @@ static inline void RTW89_SET_FWCMD_RA_CR_TBL_SEL(void *cmd, u32 val)
le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(10));
}
+static inline void RTW89_SET_FWCMD_RA_FIX_GILTF_EN(void *cmd, u32 val)
+{
+ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(11));
+}
+
+static inline void RTW89_SET_FWCMD_RA_FIX_GILTF(void *cmd, u32 val)
+{
+ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(14, 12));
+}
+
static inline void RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(void *cmd, u32 val)
{
le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(23, 16));
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 094f41cd0928..be2c3715bbf4 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -193,6 +193,40 @@ static const u64
rtw89_ra_mask_he_rates[4] = {RA_MASK_HE_1SS_RATES, RA_MASK_HE_2SS_RATES,
RA_MASK_HE_3SS_RATES, RA_MASK_HE_4SS_RATES};
+static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev,
+ struct rtw89_sta *rtwsta,
+ bool *fix_giltf_en, u8 *fix_giltf)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ struct cfg80211_bitrate_mask *mask = &rtwsta->mask;
+ u8 band = chan->band_type;
+ enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
+ u8 he_gi = mask->control[nl_band].he_gi;
+ u8 he_ltf = mask->control[nl_band].he_ltf;
+
+ if (!rtwsta->use_cfg_mask)
+ return;
+
+ if (he_ltf == 2 && he_gi == 2) {
+ *fix_giltf = RTW89_GILTF_LGI_4XHE32;
+ } else if (he_ltf == 2 && he_gi == 0) {
+ *fix_giltf = RTW89_GILTF_SGI_4XHE08;
+ } else if (he_ltf == 1 && he_gi == 1) {
+ *fix_giltf = RTW89_GILTF_2XHE16;
+ } else if (he_ltf == 1 && he_gi == 0) {
+ *fix_giltf = RTW89_GILTF_2XHE08;
+ } else if (he_ltf == 0 && he_gi == 1) {
+ *fix_giltf = RTW89_GILTF_1XHE16;
+ } else if (he_ltf == 0 && he_gi == 0) {
+ *fix_giltf = RTW89_GILTF_1XHE08;
+ } else {
+ *fix_giltf_en = false;
+ return;
+ }
+
+ *fix_giltf_en = true;
+}
+
static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta, bool csi)
{
@@ -210,8 +244,10 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
u8 bw_mode = 0;
u8 stbc_en = 0;
u8 ldpc_en = 0;
+ u8 fix_giltf = 0;
u8 i;
bool sgi = false;
+ bool fix_giltf_en = false;
memset(ra, 0, sizeof(*ra));
/* Set the ra mask from sta's capability */
@@ -226,6 +262,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[1] &
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
ldpc_en = 1;
+ rtw89_phy_ra_gi_ltf(rtwdev, rtwsta, &fix_giltf_en, &fix_giltf);
} else if (sta->deflink.vht_cap.vht_supported) {
u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map);
@@ -335,6 +372,8 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra->ss_num = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
ra->en_sgi = sgi;
ra->ra_mask = ra_mask;
+ ra->fix_giltf_en = fix_giltf_en;
+ ra->fix_giltf = fix_giltf;
if (!csi)
return;