From: Vincent Schurink <spam@acio.nl>
To: Ping-Ke Shih <pkshih@realtek.com>
Cc: linux-wireless@vger.kernel.org, Vincent Schurink <spam@acio.nl>
Subject: [PATCH rtw-next v2] wifi: rtw89: set RA init rate level from RSSI in RA update
Date: Thu, 12 Nov 2026 08:56:22 +0100 [thread overview]
Message-ID: <20261112075622.32785-1-spam@acio.nl> (raw)
When a station associates to an AP, the AP does not know the RSSI of
the station yet. Thus, rtw89_phy_ra_assoc() sends init_rate_lv 0 to the
firmware. With this value, the firmware RA of RTL8922A uses 20 MHz and
VHT-MCS 2 for the station. The firmware RA does not try a higher rate,
also when the PER is 0. On an 80 MHz AP, the TCP throughput to the
station stays at approximately 35 Mbit/s.
Move the mapping from RSSI to init_rate_lv to a function, and use it in
the RA association and in the RA update. The firmware uses
init_rate_lv only together with upd_all. Thus, the RA update also sets
upd_all one time, when the level changes from 0 to a known level.
Tested on RTL8912AU (RTL8922A, USB) in AP mode with hostapd 2.10 and
VHT 80 MHz. The client is an Intel Meteor Lake CNVi (iwlwifi) at
-48 dBm. Each test reconnects the client, then sends TCP from the AP
for 3 x 20 s.
Before: TX rate VHT-MCS 2 at 20 MHz, TCP 34 Mbit/s.
With init_rate_lv in the RA update but without upd_all: no change,
TCP 34 Mbit/s.
After: TX rate VHT-MCS 5 to 9 at 80 MHz, TCP 323 to 380 Mbit/s.
Signed-off-by: Vincent Schurink <spam@acio.nl>
---
v2:
- Add rtw89_phy_ra_get_init_rate_lv() and use it in the RA association
and in the RA update, as suggested by Ping-Ke. Remove the
ra_rssi_unknown flag and the second rtw89_phy_ra_assoc() call.
- Set upd_all when the level changes from 0 to a known level. The test
shows that init_rate_lv in the RA update without upd_all has no
effect: the rate stays at VHT-MCS 2, 20 MHz.
- For AX chips, an RA update with upd_all has no CSI fields, because
the RA update calls rtw89_fw_h2c_ra() with csi false. I could not
test AX chips.
v1: https://lore.kernel.org/linux-wireless/20261108131723.206533-1-spam@acio.nl/
drivers/net/wireless/realtek/rtw89/phy.c | 28 ++++++++++++++++--------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 795920b899d..b6057465c87 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -502,6 +502,20 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra->csi_mode = csi_mode;
}
+static u8 rtw89_phy_ra_get_init_rate_lv(struct rtw89_sta_link *rtwsta_link)
+{
+ u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
+
+ if (rssi > 40)
+ return 1;
+ if (rssi > 20)
+ return 2;
+ if (rssi > 1)
+ return 3;
+
+ return 0;
+}
+
void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link,
u32 changed)
@@ -509,6 +523,7 @@ void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_ra_info *ra = &rtwsta_link->ra;
+ u8 prev_lv = ra->init_rate_lv;
struct ieee80211_link_sta *link_sta;
rcu_read_lock();
@@ -519,6 +534,9 @@ void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev,
rcu_read_unlock();
+ ra->init_rate_lv = rtw89_phy_ra_get_init_rate_lv(rtwsta_link);
+ if (!prev_lv && ra->init_rate_lv)
+ ra->upd_all = 1;
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED)
ra->upd_mask = 1;
if (changed & (IEEE80211_RC_BW_CHANGED | IEEE80211_RC_NSS_CHANGED))
@@ -733,7 +751,6 @@ void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_
struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_ra_info *ra = &rtwsta_link->ra;
- u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
struct ieee80211_link_sta *link_sta;
bool csi;
@@ -747,14 +764,7 @@ void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_
rcu_read_unlock();
- if (rssi > 40)
- ra->init_rate_lv = 1;
- else if (rssi > 20)
- ra->init_rate_lv = 2;
- else if (rssi > 1)
- ra->init_rate_lv = 3;
- else
- ra->init_rate_lv = 0;
+ ra->init_rate_lv = rtw89_phy_ra_get_init_rate_lv(rtwsta_link);
ra->upd_all = 1;
rtw89_debug(rtwdev, RTW89_DBG_RA,
"ra assoc: macid = %d, mode = %d, bw = %d, nss = %d, lv = %d",
--
2.53.0
next reply other threads:[~2026-11-12 7:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 7:56 Vincent Schurink [this message]
2026-11-13 1:20 ` [PATCH rtw-next v2] wifi: rtw89: set RA init rate level from RSSI in RA update Ping-Ke Shih
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261112075622.32785-1-spam@acio.nl \
--to=spam@acio.nl \
--cc=linux-wireless@vger.kernel.org \
--cc=pkshih@realtek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox