Commit 48308726 authored by Po-Hao Huang's avatar Po-Hao Huang Committed by Kalle Valo
Browse files

rtw88: add dynamic rrsr configuration



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: default avatarPo-Hao Huang <phhuang@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Reviewed-by: default avatarBrian Norris <briannorris@chromium.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210209070755.23019-2-pkshih@realtek.com
parent 3304b6f9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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;
+5 −0
Original line number Diff line number Diff line
@@ -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];
+61 −1
Original line number Diff line number Diff line
@@ -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);
}
+3 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -306,6 +306,8 @@
#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
Loading