summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Huang <echuang@realtek.com>2023-04-18 09:28:20 +0800
committerKalle Valo <kvalo@kernel.org>2023-05-05 14:58:29 +0300
commit5feecb40e735b7cb4173328fabfc49ddc2b3b1bc (patch)
tree4d0bdef70b7a4208e38cbe2b97a5e2017cebe1a0
parente3715859c75322fae560c46384f944006f367515 (diff)
downloadlinux-stable-5feecb40e735b7cb4173328fabfc49ddc2b3b1bc.tar.gz
linux-stable-5feecb40e735b7cb4173328fabfc49ddc2b3b1bc.tar.bz2
linux-stable-5feecb40e735b7cb4173328fabfc49ddc2b3b1bc.zip
wifi: rtw89: add EVM for antenna diversity
Take EVM into consideration when doing antenna diversity, and the priority is higher than RSSI. Since EVM is more relevant to performance than RSSI, especially in OTA environment. Signed-off-by: Eric Huang <echuang@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/20230418012820.5139-8-pkshih@realtek.com
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h1
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c17
2 files changed, 17 insertions, 1 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index ca9d6e9258ff..40406ecce5bd 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3134,6 +3134,7 @@ struct rtw89_antdiv_stats {
u16 pkt_cnt_cck;
u16 pkt_cnt_ofdm;
u16 pkt_cnt_non_legacy;
+ u32 evm;
};
struct rtw89_antdiv_info {
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index b9a3ebc2e790..5eac00cd5188 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -2956,6 +2956,7 @@ void rtw89_phy_antdiv_sts_instance_reset(struct rtw89_antdiv_stats *antdiv_sts)
antdiv_sts->pkt_cnt_cck = 0;
antdiv_sts->pkt_cnt_ofdm = 0;
antdiv_sts->pkt_cnt_non_legacy = 0;
+ antdiv_sts->evm = 0;
}
static void rtw89_phy_antdiv_sts_instance_add(struct rtw89_dev *rtwdev,
@@ -2969,10 +2970,12 @@ static void rtw89_phy_antdiv_sts_instance_add(struct rtw89_dev *rtwdev,
} else {
ewma_rssi_add(&stats->ofdm_rssi_avg, phy_ppdu->rssi_avg);
stats->pkt_cnt_ofdm++;
+ stats->evm += phy_ppdu->ofdm.evm_min;
}
} else {
ewma_rssi_add(&stats->non_legacy_rssi_avg, phy_ppdu->rssi_avg);
stats->pkt_cnt_non_legacy++;
+ stats->evm += phy_ppdu->ofdm.evm_min;
}
}
@@ -2988,6 +2991,11 @@ static u8 rtw89_phy_antdiv_sts_instance_get_rssi(struct rtw89_antdiv_stats *stat
return ewma_rssi_read(&stats->cck_rssi_avg);
}
+static u8 rtw89_phy_antdiv_sts_instance_get_evm(struct rtw89_antdiv_stats *stats)
+{
+ return phy_div(stats->evm, stats->pkt_cnt_non_legacy + stats->pkt_cnt_ofdm);
+}
+
void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
@@ -4270,15 +4278,22 @@ static void rtw89_phy_antdiv_decision_state(struct rtw89_dev *rtwdev)
struct rtw89_hal *hal = &rtwdev->hal;
bool no_change = false;
u8 main_rssi, aux_rssi;
+ u8 main_evm, aux_evm;
u32 candidate;
antdiv->get_stats = false;
antdiv->training_count = 0;
main_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->main_stats);
+ main_evm = rtw89_phy_antdiv_sts_instance_get_evm(&antdiv->main_stats);
aux_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->aux_stats);
+ aux_evm = rtw89_phy_antdiv_sts_instance_get_evm(&antdiv->aux_stats);
- if (main_rssi > aux_rssi + RTW89_TX_DIV_RSSI_RAW_TH)
+ if (main_evm > aux_evm + ANTDIV_EVM_DIFF_TH)
+ candidate = RF_A;
+ else if (aux_evm > main_evm + ANTDIV_EVM_DIFF_TH)
+ candidate = RF_B;
+ else if (main_rssi > aux_rssi + RTW89_TX_DIV_RSSI_RAW_TH)
candidate = RF_A;
else if (aux_rssi > main_rssi + RTW89_TX_DIV_RSSI_RAW_TH)
candidate = RF_B;