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
This commit is contained in:
Eric Huang
2023-04-18 09:28:20 +08:00
committed by Kalle Valo
parent e3715859c7
commit 5feecb40e7
2 changed files with 17 additions and 1 deletions

View File

@@ -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 {

View File

@@ -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;