Commit 2ad2a813 authored by Bitterblue Smith's avatar Bitterblue Smith Committed by Kalle Valo
Browse files

wifi: rtl8xxxu: Fix the CCK RSSI calculation



The CCK RSSI calculation is incorrect for the RTL8723BU, RTL8192EU,
and RTL8188FU. Add new functions for these chips with code copied from
their vendor drivers. Use the old code only for the RTL8723AU and
RTL8192CU.

I didn't notice any difference in the reported signal strength with my
RTL8188FU, but I didn't look very hard either.

Signed-off-by: default avatarBitterblue Smith <rtl8821cerfe2@gmail.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/926c838f-4997-698b-4da9-44582e2af99a@gmail.com
parent 57b328bc
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1395,6 +1395,7 @@ struct rtl8xxxu_priv {
	u32 ep_tx_normal_queue:1;
	u32 ep_tx_low_queue:1;
	u32 rx_buf_aggregation:1;
	u32 cck_agc_report_type:1;
	u8 default_crystal_cap;
	unsigned int pipe_interrupt;
	unsigned int pipe_in;
@@ -1499,6 +1500,7 @@ struct rtl8xxxu_fileops {
			     bool short_preamble, bool ampdu_enable,
			     u32 rts_rate);
	void (*set_crystal_cap) (struct rtl8xxxu_priv *priv, u8 crystal_cap);
	s8 (*cck_rssi) (struct rtl8xxxu_priv *priv, u8 cck_agc_rpt);
	int writeN_block_size;
	int rx_agg_buf_size;
	char tx_desc_size;
@@ -1609,6 +1611,7 @@ void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
			   u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5);
void rtl8723bu_phy_init_antenna_selection(struct rtl8xxxu_priv *priv);
void rtl8723a_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap);
s8 rtl8723a_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt);

extern struct rtl8xxxu_fileops rtl8188fu_fops;
extern struct rtl8xxxu_fileops rtl8192cu_fops;
+32 −0
Original line number Diff line number Diff line
@@ -1658,6 +1658,37 @@ static void rtl8188f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap)
	cfo->crystal_cap = crystal_cap;
}

static s8 rtl8188f_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt)
{
	s8 rx_pwr_all = 0x00;
	u8 vga_idx, lna_idx;

	lna_idx = (cck_agc_rpt & 0xE0) >> 5;
	vga_idx = cck_agc_rpt & 0x1F;

	switch (lna_idx) {
	case 7:
		if (vga_idx <= 27)
			rx_pwr_all = -100 + 2 * (27 - vga_idx);
		else
			rx_pwr_all = -100;
		break;
	case 5:
		rx_pwr_all = -74 + 2 * (21 - vga_idx);
		break;
	case 3:
		rx_pwr_all = -60 + 2 * (20 - vga_idx);
		break;
	case 1:
		rx_pwr_all = -44 + 2 * (19 - vga_idx);
		break;
	default:
		break;
	}

	return rx_pwr_all;
}

struct rtl8xxxu_fileops rtl8188fu_fops = {
	.parse_efuse = rtl8188fu_parse_efuse,
	.load_firmware = rtl8188fu_load_firmware,
@@ -1682,6 +1713,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops = {
	.report_connect = rtl8xxxu_gen2_report_connect,
	.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
	.set_crystal_cap = rtl8188f_set_crystal_cap,
	.cck_rssi = rtl8188f_cck_rssi,
	.writeN_block_size = 128,
	.rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24),
	.tx_desc_size = sizeof(struct rtl8xxxu_txdesc40),
+1 −0
Original line number Diff line number Diff line
@@ -561,6 +561,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = {
	.update_rate_mask = rtl8xxxu_update_rate_mask,
	.report_connect = rtl8xxxu_gen1_report_connect,
	.fill_txdesc = rtl8xxxu_fill_txdesc_v1,
	.cck_rssi = rtl8723a_cck_rssi,
	.writeN_block_size = 128,
	.rx_agg_buf_size = 16000,
	.tx_desc_size = sizeof(struct rtl8xxxu_txdesc32),
+23 −0
Original line number Diff line number Diff line
@@ -1670,6 +1670,28 @@ static void rtl8192e_enable_rf(struct rtl8xxxu_priv *priv)
	rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8);
}

static s8 rtl8192e_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt)
{
	static const s8 lna_gain_table_0[8] = {15, 9, -10, -21, -23, -27, -43, -44};
	static const s8 lna_gain_table_1[8] = {24, 18, 13, -4, -11, -18, -31, -36};

	s8 rx_pwr_all = 0x00;
	u8 vga_idx, lna_idx;
	s8 lna_gain = 0;

	lna_idx = (cck_agc_rpt & 0xE0) >> 5;
	vga_idx = cck_agc_rpt & 0x1F;

	if (priv->cck_agc_report_type == 0)
		lna_gain = lna_gain_table_0[lna_idx];
	else
		lna_gain = lna_gain_table_1[lna_idx];

	rx_pwr_all = lna_gain - (2 * vga_idx);

	return rx_pwr_all;
}

struct rtl8xxxu_fileops rtl8192eu_fops = {
	.parse_efuse = rtl8192eu_parse_efuse,
	.load_firmware = rtl8192eu_load_firmware,
@@ -1691,6 +1713,7 @@ struct rtl8xxxu_fileops rtl8192eu_fops = {
	.report_connect = rtl8xxxu_gen2_report_connect,
	.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
	.set_crystal_cap = rtl8723a_set_crystal_cap,
	.cck_rssi = rtl8192e_cck_rssi,
	.writeN_block_size = 128,
	.tx_desc_size = sizeof(struct rtl8xxxu_txdesc40),
	.rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24),
+23 −0
Original line number Diff line number Diff line
@@ -386,6 +386,28 @@ void rtl8723a_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap)
	cfo->crystal_cap = crystal_cap;
}

s8 rtl8723a_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt)
{
	s8 rx_pwr_all = 0x00;

	switch (cck_agc_rpt & 0xc0) {
	case 0xc0:
		rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
		break;
	case 0x80:
		rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
		break;
	case 0x40:
		rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
		break;
	case 0x00:
		rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
		break;
	}

	return rx_pwr_all;
}

struct rtl8xxxu_fileops rtl8723au_fops = {
	.parse_efuse = rtl8723au_parse_efuse,
	.load_firmware = rtl8723au_load_firmware,
@@ -408,6 +430,7 @@ struct rtl8xxxu_fileops rtl8723au_fops = {
	.report_connect = rtl8xxxu_gen1_report_connect,
	.fill_txdesc = rtl8xxxu_fill_txdesc_v1,
	.set_crystal_cap = rtl8723a_set_crystal_cap,
	.cck_rssi = rtl8723a_cck_rssi,
	.writeN_block_size = 1024,
	.rx_agg_buf_size = 16000,
	.tx_desc_size = sizeof(struct rtl8xxxu_txdesc32),
Loading