rtw88: add dynamic rrsr configuration
authorPo-Hao Huang <phhuang@realtek.com>
Tue, 9 Feb 2021 07:07:48 +0000 (15:07 +0800)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 12 Feb 2021 07:50:53 +0000 (09:50 +0200)
Register rrsr determines the response rate we send.
In field tests, using rate higher than current tx rate could lead
to difficulty for the receiving end to receive management/control
frames. Calculate current modulation level by tx rate then cross out
rate higher than those.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210209070755.23019-2-pkshih@realtek.com
drivers/net/wireless/realtek/rtw88/main.c
drivers/net/wireless/realtek/rtw88/main.h
drivers/net/wireless/realtek/rtw88/phy.c
drivers/net/wireless/realtek/rtw88/phy.h
drivers/net/wireless/realtek/rtw88/reg.h
drivers/net/wireless/realtek/rtw88/rtw8822c.h

index 757aaf4..8714967 100644 (file)
@@ -894,6 +894,7 @@ static u64 rtw_update_rate_mask(struct rtw_dev *rtwdev,
 
 void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
 {
+       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
        struct ieee80211_sta *sta = si->sta;
        struct rtw_efuse *efuse = &rtwdev->efuse;
        struct rtw_hal *hal = &rtwdev->hal;
@@ -938,6 +939,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
                } else {
                        wireless_set = WIRELESS_OFDM;
                }
+               dm_info->rrsr_val_init = RRSR_INIT_5G;
        } else if (hal->current_band_type == RTW_BAND_2G) {
                ra_mask |= sta->supp_rates[NL80211_BAND_2GHZ];
                if (sta->vht_cap.vht_supported) {
@@ -955,6 +957,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
                } else {
                        wireless_set = WIRELESS_CCK | WIRELESS_OFDM;
                }
+               dm_info->rrsr_val_init = RRSR_INIT_2G;
        } else {
                rtw_err(rtwdev, "Unknown band type\n");
                wireless_set = 0;
index 8752419..296a9b4 100644 (file)
@@ -1495,6 +1495,9 @@ struct rtw_iqk_info {
        } result;
 };
 
+#define RRSR_INIT_2G 0x15f
+#define RRSR_INIT_5G 0x150
+
 struct rtw_dm_info {
        u32 cck_fa_cnt;
        u32 ofdm_fa_cnt;
@@ -1525,6 +1528,8 @@ struct rtw_dm_info {
        u8 cck_gi_l_bnd;
 
        u8 tx_rate;
+       u32 rrsr_val_init;
+       u32 rrsr_mask_min;
        u8 thermal_avg[RTW_RF_PATH_MAX];
        u8 thermal_meter_k;
        s8 delta_power_index[RTW_RF_PATH_MAX];
index d44960c..e114dde 100644 (file)
@@ -465,6 +465,60 @@ static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev)
        rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
 }
 
+static u32 rtw_phy_get_rrsr_mask(struct rtw_dev *rtwdev, u8 rate_idx)
+{
+       u8 rate_order;
+
+       rate_order = rate_idx;
+
+       if (rate_idx >= DESC_RATEVHT4SS_MCS0)
+               rate_order -= DESC_RATEVHT4SS_MCS0;
+       else if (rate_idx >= DESC_RATEVHT3SS_MCS0)
+               rate_order -= DESC_RATEVHT3SS_MCS0;
+       else if (rate_idx >= DESC_RATEVHT2SS_MCS0)
+               rate_order -= DESC_RATEVHT2SS_MCS0;
+       else if (rate_idx >= DESC_RATEVHT1SS_MCS0)
+               rate_order -= DESC_RATEVHT1SS_MCS0;
+       else if (rate_idx >= DESC_RATEMCS24)
+               rate_order -= DESC_RATEMCS24;
+       else if (rate_idx >= DESC_RATEMCS16)
+               rate_order -= DESC_RATEMCS16;
+       else if (rate_idx >= DESC_RATEMCS8)
+               rate_order -= DESC_RATEMCS8;
+       else if (rate_idx >= DESC_RATEMCS0)
+               rate_order -= DESC_RATEMCS0;
+       else if (rate_idx >= DESC_RATE6M)
+               rate_order -= DESC_RATE6M;
+       else
+               rate_order -= DESC_RATE1M;
+
+       if (rate_idx >= DESC_RATEMCS0 || rate_order == 0)
+               rate_order++;
+
+       return GENMASK(rate_order + RRSR_RATE_ORDER_CCK_LEN - 1, 0);
+}
+
+static void rtw_phy_rrsr_mask_min_iter(void *data, struct ieee80211_sta *sta)
+{
+       struct rtw_dev *rtwdev = (struct rtw_dev *)data;
+       struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
+       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+       u32 mask = 0;
+
+       mask = rtw_phy_get_rrsr_mask(rtwdev, si->ra_report.desc_rate);
+       if (mask < dm_info->rrsr_mask_min)
+               dm_info->rrsr_mask_min = mask;
+}
+
+static void rtw_phy_rrsr_update(struct rtw_dev *rtwdev)
+{
+       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+       dm_info->rrsr_mask_min = RRSR_RATE_ORDER_MAX;
+       rtw_iterate_stas_atomic(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev);
+       rtw_write32(rtwdev, REG_RRSR, dm_info->rrsr_val_init & dm_info->rrsr_mask_min);
+}
+
 static void rtw_phy_dpk_track(struct rtw_dev *rtwdev)
 {
        struct rtw_chip_info *chip = rtwdev->chip;
@@ -561,13 +615,19 @@ static void rtw_phy_pwr_track(struct rtw_dev *rtwdev)
        rtwdev->chip->ops->pwr_track(rtwdev);
 }
 
+static void rtw_phy_ra_track(struct rtw_dev *rtwdev)
+{
+       rtw_phy_ra_info_update(rtwdev);
+       rtw_phy_rrsr_update(rtwdev);
+}
+
 void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
 {
        /* for further calculation */
        rtw_phy_statistics(rtwdev);
        rtw_phy_dig(rtwdev);
        rtw_phy_cck_pd(rtwdev);
-       rtw_phy_ra_info_update(rtwdev);
+       rtw_phy_ra_track(rtwdev);
        rtw_phy_dpk_track(rtwdev);
        rtw_phy_pwr_track(rtwdev);
 }
index b924ed0..a4fcfb8 100644 (file)
@@ -185,4 +185,7 @@ enum rtw_phy_cck_pd_lv {
 #define LSSI_READ_EDGE_MASK    0x80000000
 #define LSSI_READ_DATA_MASK    0xfffff
 
+#define RRSR_RATE_ORDER_MAX    0xfffff
+#define RRSR_RATE_ORDER_CCK_LEN        4
+
 #endif
index cf9a3b6..ea518aa 100644 (file)
 #define REG_DARFRC             0x0430
 #define REG_DARFRCH            0x0434
 #define REG_RARFRCH            0x043C
+#define REG_RRSR               0x0440
+#define BITS_RRSR_RSC          GENMASK(22, 21)
 #define REG_ARFR0              0x0444
 #define REG_ARFRH0             0x0448
 #define REG_ARFR1_V1           0x044C
index 32b4771..bb2495b 100644 (file)
@@ -164,8 +164,6 @@ const struct rtw_table name ## _tbl = {                     \
 
 #define REG_ANAPARLDO_POW_MAC  0x0029
 #define BIT_LDOE25_PON         BIT(0)
-#define REG_RRSR               0x0440
-#define BITS_RRSR_RSC          (BIT(21) | BIT(22))
 
 #define REG_TXDFIR0    0x808
 #define REG_DFIRBW     0x810