diff mbox series

[v2,1/2] wifi: rtl8xxxu: Report the RSSI to the firmware

Message ID 2aab4f3f-e914-4fe1-f29a-deac91774d05@gmail.com
State New
Headers show
Series [v2,1/2] wifi: rtl8xxxu: Report the RSSI to the firmware | expand

Commit Message

Bitterblue Smith Jan. 8, 2023, 3:06 p.m. UTC
Or in the case of RTL8188EU, report the RSSI to the rate control code.

The rate control code for RTL8188EU is less likely to switch to a lower
rate when the RSSI is high. The firmware-based rate control in the other
chips probably works the same way.

This affects all the chips, but it was only tested with RTL8188EU,
RTL8188FU, and RTL8192EU.

Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
v2:
 - Suggestion from Ping-Ke Shih:
   - Make h2c_size 4 instead of 3 in rtl8xxxu_gen1_report_rssi().
     Just to make it less confusing. It doesn't change the behaviour.
---
 .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h  | 23 +++++++++++++
 .../realtek/rtl8xxxu/rtl8xxxu_8188e.c         |  6 ++++
 .../realtek/rtl8xxxu/rtl8xxxu_8188f.c         |  1 +
 .../realtek/rtl8xxxu/rtl8xxxu_8192c.c         |  1 +
 .../realtek/rtl8xxxu/rtl8xxxu_8192e.c         |  1 +
 .../realtek/rtl8xxxu/rtl8xxxu_8723a.c         |  1 +
 .../realtek/rtl8xxxu/rtl8xxxu_8723b.c         |  1 +
 .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 34 +++++++++++++++++++
 8 files changed, 68 insertions(+)

Comments

Ping-Ke Shih Jan. 9, 2023, 1:36 a.m. UTC | #1
> -----Original Message-----
> From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> Sent: Sunday, January 8, 2023 11:07 PM
> To: linux-wireless@vger.kernel.org
> Cc: Jes Sorensen <Jes.Sorensen@gmail.com>; Ping-Ke Shih <pkshih@realtek.com>
> Subject: [PATCH v2 1/2] wifi: rtl8xxxu: Report the RSSI to the firmware
> 
> Or in the case of RTL8188EU, report the RSSI to the rate control code.
> 
> The rate control code for RTL8188EU is less likely to switch to a lower
> rate when the RSSI is high. The firmware-based rate control in the other
> chips probably works the same way.
> 
> This affects all the chips, but it was only tested with RTL8188EU,
> RTL8188FU, and RTL8192EU.
> 
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>

Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>

> ---
> v2:
>  - Suggestion from Ping-Ke Shih:
>    - Make h2c_size 4 instead of 3 in rtl8xxxu_gen1_report_rssi().
>      Just to make it less confusing. It doesn't change the behaviour.
> ---
>  .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h  | 23 +++++++++++++
>  .../realtek/rtl8xxxu/rtl8xxxu_8188e.c         |  6 ++++
>  .../realtek/rtl8xxxu/rtl8xxxu_8188f.c         |  1 +
>  .../realtek/rtl8xxxu/rtl8xxxu_8192c.c         |  1 +
>  .../realtek/rtl8xxxu/rtl8xxxu_8192e.c         |  1 +
>  .../realtek/rtl8xxxu/rtl8xxxu_8723a.c         |  1 +
>  .../realtek/rtl8xxxu/rtl8xxxu_8723b.c         |  1 +
>  .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 34 +++++++++++++++++++
>  8 files changed, 68 insertions(+)
> 

[...]
Ping-Ke Shih Jan. 9, 2023, 1:36 a.m. UTC | #2
> -----Original Message-----
> From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> Sent: Sunday, January 8, 2023 11:08 PM
> To: linux-wireless@vger.kernel.org
> Cc: Jes Sorensen <Jes.Sorensen@gmail.com>; Ping-Ke Shih <pkshih@realtek.com>
> Subject: [PATCH v2 2/2] wifi: rtl8xxxu: Use a longer retry limit of 48
> 
> The Realtek rate control algorithm goes back and forth a lot between
> the highest and the lowest rate it's allowed to use. This is due to
> a lot of frames being dropped because the retry limits set by
> IEEE80211_CONF_CHANGE_RETRY_LIMITS are too low. (Experimentally, they
> are 4 for long frames and 7 for short frames.)
> 
> The vendor drivers hardcode the value 48 for both retry limits (for
> station mode), which makes dropped frames very rare and thus the rate
> control is more stable.
> 
> Because most Realtek chips handle the rate control in the firmware,
> which can't be modified, ignore the limits set by
> IEEE80211_CONF_CHANGE_RETRY_LIMITS and use the value 48 (set during
> chip initialisation), same as the vendor drivers.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>

Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>

> ---
> v2:
>  - Use Cc tag instead of Fixes.
> ---
>  drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 9 ---------
>  1 file changed, 9 deletions(-)
> 
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> index 4c76fad67150..ab4074caf191 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> @@ -6184,7 +6184,6 @@ static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
>  {
>  	struct rtl8xxxu_priv *priv = hw->priv;
>  	struct device *dev = &priv->udev->dev;
> -	u16 val16;
>  	int ret = 0, channel;
>  	bool ht40;
> 
> @@ -6194,14 +6193,6 @@ static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
>  			 __func__, hw->conf.chandef.chan->hw_value,
>  			 changed, hw->conf.chandef.width);
> 
> -	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
> -		val16 = ((hw->conf.long_frame_max_tx_count <<
> -			  RETRY_LIMIT_LONG_SHIFT) & RETRY_LIMIT_LONG_MASK) |
> -			((hw->conf.short_frame_max_tx_count <<
> -			  RETRY_LIMIT_SHORT_SHIFT) & RETRY_LIMIT_SHORT_MASK);
> -		rtl8xxxu_write16(priv, REG_RETRY_LIMIT, val16);
> -	}
> -
>  	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
>  		switch (hw->conf.chandef.width) {
>  		case NL80211_CHAN_WIDTH_20_NOHT:
> --
> 2.38.0
> 
> ------Please consider the environment before printing this e-mail.
Kalle Valo Jan. 16, 2023, 4:27 p.m. UTC | #3
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:

> Or in the case of RTL8188EU, report the RSSI to the rate control code.
> 
> The rate control code for RTL8188EU is less likely to switch to a lower
> rate when the RSSI is high. The firmware-based rate control in the other
> chips probably works the same way.
> 
> This affects all the chips, but it was only tested with RTL8188EU,
> RTL8188FU, and RTL8192EU.
> 
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>

2 patches applied to wireless-next.git, thanks.

3922dc9fbdb8 wifi: rtl8xxxu: Report the RSSI to the firmware
2a86aa9a1892 wifi: rtl8xxxu: Use a longer retry limit of 48
diff mbox series

Patch

diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
index be9479f969b7..90268479d3ad 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -1168,6 +1168,26 @@  struct h2c_cmd {
 			u8 cmd;
 			u8 data;
 		} __packed bt_grant;
+		struct {
+			u8 cmd;
+			u8 macid;
+			u8 unknown0;
+			u8 rssi;
+			/*
+			 * [0]   - is_rx
+			 * [1]   - stbc_en
+			 * [2]   - noisy_decision
+			 * [6]   - bf_en
+			 */
+			u8 data;
+			/*
+			 * [0:6] - ra_th_offset
+			 * [7]   - ra_offset_direction
+			 */
+			u8 ra_th_offset;
+			u8 unknown1;
+			u8 unknown2;
+		} __packed rssi_report;
 	};
 };
 
@@ -1585,6 +1605,7 @@  struct rtl8xxxu_fileops {
 				  u32 ramask, u8 rateid, int sgi, int txbw_40mhz);
 	void (*report_connect) (struct rtl8xxxu_priv *priv,
 				u8 macid, bool connect);
+	void (*report_rssi) (struct rtl8xxxu_priv *priv, u8 macid, u8 rssi);
 	void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
 			     struct ieee80211_tx_info *tx_info,
 			     struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
@@ -1686,6 +1707,8 @@  void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
 				  u8 macid, bool connect);
 void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
 				  u8 macid, bool connect);
+void rtl8xxxu_gen1_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi);
+void rtl8xxxu_gen2_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi);
 void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv);
 void rtl8xxxu_gen1_enable_rf(struct rtl8xxxu_priv *priv);
 void rtl8xxxu_gen1_disable_rf(struct rtl8xxxu_priv *priv);
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
index 37658a090aee..08f3b93ad8d0 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
@@ -1784,6 +1784,11 @@  rtl8188e_update_rate_mask(struct rtl8xxxu_priv *priv,
 	rtl8188e_arfb_refresh(ra);
 }
 
+static void rtl8188e_ra_set_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi)
+{
+	priv->ra_info.rssi_sta_ra = rssi;
+}
+
 void rtl8188e_ra_info_init_all(struct rtl8xxxu_ra_info *ra)
 {
 	ra->decision_rate = DESC_RATE_MCS7;
@@ -1842,6 +1847,7 @@  struct rtl8xxxu_fileops rtl8188eu_fops = {
 	.set_tx_power = rtl8188f_set_tx_power,
 	.update_rate_mask = rtl8188e_update_rate_mask,
 	.report_connect = rtl8xxxu_gen2_report_connect,
+	.report_rssi = rtl8188e_ra_set_rssi,
 	.fill_txdesc = rtl8xxxu_fill_txdesc_v3,
 	.set_crystal_cap = rtl8188f_set_crystal_cap,
 	.cck_rssi = rtl8188e_cck_rssi,
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
index f5a0c7a8a581..af6e2c8a5025 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
@@ -1732,6 +1732,7 @@  struct rtl8xxxu_fileops rtl8188fu_fops = {
 	.set_tx_power = rtl8188f_set_tx_power,
 	.update_rate_mask = rtl8xxxu_gen2_update_rate_mask,
 	.report_connect = rtl8xxxu_gen2_report_connect,
+	.report_rssi = rtl8xxxu_gen2_report_rssi,
 	.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
 	.set_crystal_cap = rtl8188f_set_crystal_cap,
 	.cck_rssi = rtl8188f_cck_rssi,
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
index 8981a86c833f..e61d65c3579b 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
@@ -609,6 +609,7 @@  struct rtl8xxxu_fileops rtl8192cu_fops = {
 	.set_tx_power = rtl8xxxu_gen1_set_tx_power,
 	.update_rate_mask = rtl8xxxu_update_rate_mask,
 	.report_connect = rtl8xxxu_gen1_report_connect,
+	.report_rssi = rtl8xxxu_gen1_report_rssi,
 	.fill_txdesc = rtl8xxxu_fill_txdesc_v1,
 	.cck_rssi = rtl8723a_cck_rssi,
 	.writeN_block_size = 128,
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
index ca1688600947..4a1c9bcafe31 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
@@ -1784,6 +1784,7 @@  struct rtl8xxxu_fileops rtl8192eu_fops = {
 	.set_tx_power = rtl8192e_set_tx_power,
 	.update_rate_mask = rtl8xxxu_gen2_update_rate_mask,
 	.report_connect = rtl8xxxu_gen2_report_connect,
+	.report_rssi = rtl8xxxu_gen2_report_rssi,
 	.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
 	.set_crystal_cap = rtl8723a_set_crystal_cap,
 	.cck_rssi = rtl8192e_cck_rssi,
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
index e881ee33c6e8..5ed523db2d87 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
@@ -478,6 +478,7 @@  struct rtl8xxxu_fileops rtl8723au_fops = {
 	.set_tx_power = rtl8xxxu_gen1_set_tx_power,
 	.update_rate_mask = rtl8xxxu_update_rate_mask,
 	.report_connect = rtl8xxxu_gen1_report_connect,
+	.report_rssi = rtl8xxxu_gen1_report_rssi,
 	.fill_txdesc = rtl8xxxu_fill_txdesc_v1,
 	.set_crystal_cap = rtl8723a_set_crystal_cap,
 	.cck_rssi = rtl8723a_cck_rssi,
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
index 0ed667d5ed25..21613d60dc22 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
@@ -1727,6 +1727,7 @@  struct rtl8xxxu_fileops rtl8723bu_fops = {
 	.set_tx_power = rtl8723b_set_tx_power,
 	.update_rate_mask = rtl8xxxu_gen2_update_rate_mask,
 	.report_connect = rtl8xxxu_gen2_report_connect,
+	.report_rssi = rtl8xxxu_gen2_report_rssi,
 	.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
 	.set_crystal_cap = rtl8723a_set_crystal_cap,
 	.cck_rssi = rtl8723b_cck_rssi,
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index fd97c040948a..4c76fad67150 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -4461,6 +4461,37 @@  void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
 	rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt));
 }
 
+void rtl8xxxu_gen1_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi)
+{
+	struct h2c_cmd h2c;
+	const int h2c_size = 4;
+
+	memset(&h2c, 0, sizeof(struct h2c_cmd));
+
+	h2c.rssi_report.cmd = H2C_SET_RSSI;
+	h2c.rssi_report.macid = macid;
+	h2c.rssi_report.rssi = rssi;
+
+	rtl8xxxu_gen1_h2c_cmd(priv, &h2c, h2c_size);
+}
+
+void rtl8xxxu_gen2_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi)
+{
+	struct h2c_cmd h2c;
+	int h2c_size = sizeof(h2c.rssi_report);
+
+	if (priv->rtl_chip == RTL8723B)
+		h2c_size = 4;
+
+	memset(&h2c, 0, sizeof(struct h2c_cmd));
+
+	h2c.rssi_report.cmd = H2C_8723B_RSSI_SETTING;
+	h2c.rssi_report.macid = macid;
+	h2c.rssi_report.rssi = rssi;
+
+	rtl8xxxu_gen2_h2c_cmd(priv, &h2c, h2c_size);
+}
+
 void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
 {
 	u8 agg_ctrl, usb_spec, page_thresh, timeout;
@@ -6701,6 +6732,9 @@  static void rtl8xxxu_watchdog_callback(struct work_struct *work)
 
 		signal = ieee80211_ave_rssi(vif);
 
+		priv->fops->report_rssi(priv, 0,
+					rtl8xxxu_signal_to_snr(signal));
+
 		if (priv->fops->set_crystal_cap)
 			rtl8xxxu_track_cfo(priv);