Commit 5feecb40 authored by Eric Huang's avatar Eric Huang Committed by Kalle Valo
Browse files

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: default avatarEric Huang <echuang@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230418012820.5139-8-pkshih@realtek.com
parent e3715859
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 {
+16 −1
Original line number Diff line number Diff line
@@ -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;