mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead
@ 2026-11-15 14:23 Leonard Lausen
  2026-11-15 14:23 ` [PATCH 1/2] wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO Leonard Lausen
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Leonard Lausen @ 2026-11-15 14:23 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: leonard, Shawn Lin, Heiko Stuebner, linux-wireless,
	linux-rockchip, linux-kernel

Reduce SDIO request overhead by filtering hardware-handled control
frames and combining adjacent TX-capacity reads.

RTL8822CS on NanoPi M5, median TCP Mbit/s:

                              Upload   Download
  Neither patch                170.4      241.2
  Filtering only               258.2      263.3
  Combined register reads only 186.5      261.6
  Both patches                 286.9      273.5

Together the patches improved median upload by 68% and download by 13.4%.
Upload and download were measured in separate sessions, with four
20-second upload samples and four 30-second download samples per
configuration. Testing used a shared Wi-Fi network, so throughput can vary.

Runtime baseline: v7.4-rc2 plus the RX-bounds fix accepted in rtw-next
(83ca360e85280) and the MMC voltage-switch fixes in linux-next
(67a97316a31a3, a3838c21e28e5). All variants use stock MMC host limits,
198 MHz SDR104, performance governors and identical CPU placement:
SDIO IRQ on CPU4, iperf client on CPU6, server on CPU7. Traffic crosses
Wi-Fi/AP/Ethernet between two endpoints on the board.

All 20 configured rtw88 modules built with W=1. Sanitized function models
cover credit-read errors, fallback and buffer ownership. Module IDs,
filter registers, traffic paths and kernel logs were checked. AP/monitor,
suspend/resume and other-chip hardware remain untested.

AI assistance: Codex inspected sources, developed the changes and messages,
and automated validation. Prompts requested small optimizations measured
individually and together, with explicit prerequisite and impact checks.

Leonard Lausen (2):
  wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO
  wifi: rtw88: sdio: combine free TX page register reads

 drivers/net/wireless/realtek/rtw88/reg.h      |  4 ++
 drivers/net/wireless/realtek/rtw88/rtw8822c.c |  9 +++
 drivers/net/wireless/realtek/rtw88/sdio.c     | 58 +++++++++++++++++--
 drivers/net/wireless/realtek/rtw88/sdio.h     |  1 +
 4 files changed, 68 insertions(+), 4 deletions(-)

base-commit: 7475ea8b58616b33c04afb976cf0fbaad9dd63fb

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO
  2026-11-15 14:23 [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead Leonard Lausen
@ 2026-11-15 14:23 ` Leonard Lausen
  2026-11-15 14:29   ` Leonard Lausen
  2026-11-15 14:23 ` [PATCH 2/2] wifi: rtw88: sdio: combine free TX page register reads Leonard Lausen
  2026-11-15 18:26 ` [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead Luka Gejak
  2 siblings, 1 reply; 5+ messages in thread
From: Leonard Lausen @ 2026-11-15 14:23 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: leonard, Shawn Lin, Heiko Stuebner, linux-wireless,
	linux-rockchip, linux-kernel

RTL8822C forwards every control-frame subtype to the host by default.
ACK, Block Ack, RTS and CTS frames are handled by hardware, but forwarding
them also adds small SDIO transfers to the data path.

Clear these four subtypes from the SDIO default RX filter. Retain BAR,
PS-Poll and the remaining subtypes, and store the default in rxfltmap1
so FIF_CONTROL can still request all control frames.

Limit the new default to SDIO, where profiling identified the overhead
and throughput tests measured a benefit. PCIe and USB use different
receive paths and have not been validated with this filter setting.

FriendlyElec's RTL8822CS driver also filters control frames at startup;
this change retains additional subtypes for mac80211.

On RTL8822CS/NanoPi M5 at 198 MHz SDR104, this patch alone increased
median TCP upload from 170 to 258 Mbit/s (+52%). 

A separate download test (four 30-second samples per configuration)
measured 241 to 263 Mbit/s (+9%).

Link: https://github.com/friendlyarm/rtl8822cs/blob/c8b944a34bba2116fcdb060362bde40242bb87e5/hal/rtl8822c/rtl8822c_halinit.c
---
 drivers/net/wireless/realtek/rtw88/reg.h      | 4 ++++
 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 9 +++++++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index afcdb66fdb9a1..8e220580be4f8 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -587,6 +587,10 @@
 
 #define REG_RXFLTMAP0		0x06A0
 #define REG_RXFLTMAP1		0x06A2
+#define BIT_RXFLTMAP1_BACK	BIT(9)
+#define BIT_RXFLTMAP1_RTS	BIT(11)
+#define BIT_RXFLTMAP1_CTS	BIT(12)
+#define BIT_RXFLTMAP1_ACK	BIT(13)
 #define REG_RXFLTMAP2		0x06A4
 #define REG_RXFLTMAP4		0x068A
 #define REG_BT_COEX_TABLE0	0x06C0
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 32d9709f2c243..9c9e4f2397282 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -2096,6 +2096,15 @@ static int rtw8822c_mac_init(struct rtw_dev *rtwdev)
 	rtw_write8(rtwdev, REG_WMAC_TRXPTCL_CTL_H  + 2, WLAN_BAR_ACK_TYPE);
 	rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
 	rtwdev->hal.rxfltmap1 = WLAN_RX_FILTER1;
+	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) {
+		/* Hardware handles these frames; retain BAR and PS-Poll for
+		 * mac80211. FIF_CONTROL restores all subtypes for monitors.
+		 */
+		rtwdev->hal.rxfltmap1 &= ~(BIT_RXFLTMAP1_BACK |
+						BIT_RXFLTMAP1_RTS |
+						BIT_RXFLTMAP1_CTS |
+						BIT_RXFLTMAP1_ACK);
+	}
 	rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1);
 	rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
 	rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/2] wifi: rtw88: sdio: combine free TX page register reads
  2026-11-15 14:23 [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead Leonard Lausen
  2026-11-15 14:23 ` [PATCH 1/2] wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO Leonard Lausen
@ 2026-11-15 14:23 ` Leonard Lausen
  2026-11-15 18:26 ` [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead Luka Gejak
  2 siblings, 0 replies; 5+ messages in thread
From: Leonard Lausen @ 2026-11-15 14:23 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: leonard, Shawn Lin, Heiko Stuebner, linux-wireless,
	linux-rockchip, linux-kernel

TX capacity checks on non-8051 chips read three adjacent 32-bit registers
in separate SDIO requests. Combine them into one 12-byte CMD53 read when
the existing power/alignment check permits it, with the per-register
fallback otherwise. Propagate read errors before checking queue capacity.

Allocate a DMA-safe buffer at probe and copy its little-endian values
into the caller's array before releasing the host. Holding the host
through the read and copy serializes access to the shared buffer.

On RTL8822CS/NanoPi M5 at 198 MHz SDR104, median TCP upload increased
from 170 to 186 Mbit/s (+9%) with this patch alone, and from 258 to
287 Mbit/s (+11%) when added after control-frame filtering.

A separate download test  measured 241 to 262 Mbit/s (+8%) with this
patch alone, and 263 to 274 Mbit/s (+4%) when added after filtering.

Assisted-by: LLM
Signed-off-by: Leonard Lausen <leonard@lausen.nl>
---
 drivers/net/wireless/realtek/rtw88/sdio.c | 58 +++++++++++++++++++++--
 drivers/net/wireless/realtek/rtw88/sdio.h |  1 +
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index dc2fd0f8f9fff..4aeff250a6d6a 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -26,6 +26,7 @@
 #define RTW_SDIO_TX_FIFO_HIWATER			16
 #define RTW_SDIO_TX_FIFO_LOWATER			8
 #define RTW_SDIO_TX_RETRY_DELAY			msecs_to_jiffies(1)
+#define RTW_SDIO_FREE_TXPG_COUNT			3
 
 static bool rtw_sdio_is_bus_addr(u32 addr)
 {
@@ -675,6 +676,40 @@ static atomic_t *rtw_sdio_8723bs_free_txpg(struct rtw_dev *rtwdev, u8 queue)
 	}
 }
 
+static int rtw_sdio_read_free_txpg(struct rtw_dev *rtwdev, u32 *free_txpg)
+{
+	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+	bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio);
+	u32 addr = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_FREE_TXPG);
+	int i, ret;
+
+	if (bus_claim)
+		sdio_claim_host(rtwsdio->sdio_func);
+
+	if (!rtw_sdio_use_memcpy_io(rtwdev, addr, sizeof(u32))) {
+		for (i = 0; i < RTW_SDIO_FREE_TXPG_COUNT; i++) {
+			free_txpg[i] = rtw_sdio_readl(rtwdev, addr + i * sizeof(u32), &ret);
+			if (ret)
+				break;
+		}
+		goto out;
+	}
+
+	ret = sdio_memcpy_fromio(rtwsdio->sdio_func, rtwsdio->free_txpg, addr,
+				 RTW_SDIO_FREE_TXPG_COUNT * sizeof(__le32));
+	if (!ret) {
+		/* Copy the shared DMA buffer before releasing the host. */
+		for (i = 0; i < RTW_SDIO_FREE_TXPG_COUNT; i++)
+			free_txpg[i] = le32_to_cpu(rtwsdio->free_txpg[i]);
+	}
+
+out:
+	if (bus_claim)
+		sdio_release_host(rtwsdio->sdio_func);
+
+	return ret;
+}
+
 static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue,
 				    size_t count)
 {
@@ -727,11 +762,14 @@ static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue,
 		/* add the pages from the public queue */
 		pages_free += (free_txpg >> 24) & 0xff;
 	} else {
-		u32 free_txpg[3];
+		u32 free_txpg[RTW_SDIO_FREE_TXPG_COUNT];
+		int ret;
 
-		free_txpg[0] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG);
-		free_txpg[1] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG + 4);
-		free_txpg[2] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG + 8);
+		ret = rtw_sdio_read_free_txpg(rtwdev, free_txpg);
+		if (ret) {
+			rtw_warn(rtwdev, "Failed to read free TX pages: %d\n", ret);
+			return ret;
+		}
 
 		switch (queue) {
 		case RTW_TX_QUEUE_BCN:
@@ -1777,6 +1815,7 @@ int rtw_sdio_probe(struct sdio_func *sdio_func,
 {
 	struct ieee80211_hw *hw;
 	struct rtw_dev *rtwdev;
+	struct rtw_sdio *rtwsdio;
 	int drv_data_size;
 	int ret;
 
@@ -1798,6 +1837,17 @@ int rtw_sdio_probe(struct sdio_func *sdio_func,
 	if (ret)
 		goto err_release_hw;
 
+	rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+	if (!rtw_chip_wcpu_8051(rtwdev)) {
+		rtwsdio->free_txpg = devm_kmalloc_array(rtwdev->dev,
+							RTW_SDIO_FREE_TXPG_COUNT,
+							sizeof(*rtwsdio->free_txpg), GFP_KERNEL);
+		if (!rtwsdio->free_txpg) {
+			ret = -ENOMEM;
+			goto err_deinit_core;
+		}
+	}
+
 	rtw_dbg(rtwdev, RTW_DBG_SDIO,
 		"rtw88 SDIO probe: vendor=0x%04x device=%04x class=%02x",
 		id->vendor, id->device, id->class);
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.h b/drivers/net/wireless/realtek/rtw88/sdio.h
index 6e7e6009744b0..8310bf6d54b59 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.h
+++ b/drivers/net/wireless/realtek/rtw88/sdio.h
@@ -181,6 +181,7 @@ struct rtw_sdio {
 	atomic_t tx_oqt_free;
 	/* one writer at a time between the credit check and the accounting */
 	struct mutex tx_credit_lock;
+	__le32 *free_txpg;
 };
 
 extern const struct dev_pm_ops rtw_sdio_pm_ops;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO
  2026-11-15 14:23 ` [PATCH 1/2] wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO Leonard Lausen
@ 2026-11-15 14:29   ` Leonard Lausen
  0 siblings, 0 replies; 5+ messages in thread
From: Leonard Lausen @ 2026-11-15 14:29 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: Shawn Lin, Heiko Stuebner, linux-wireless, linux-rockchip, linux-kernel

RTL8822C forwards every control-frame subtype to the host by default.
ACK, Block Ack, RTS and CTS frames are handled by hardware, but forwarding
them also adds small SDIO transfers to the data path.

Clear these four subtypes from the SDIO default RX filter. Retain BAR,
PS-Poll and the remaining subtypes, and store the default in rxfltmap1
so FIF_CONTROL can still request all control frames.

Limit the new default to SDIO, where profiling identified the overhead
and throughput tests measured a benefit. PCIe and USB use different
receive paths and have not been validated with this filter setting.

FriendlyElec's RTL8822CS driver also filters control frames at startup;
this change retains additional subtypes for mac80211.

On RTL8822CS/NanoPi M5 at 198 MHz SDR104, this patch alone increased
median TCP upload from 170 to 258 Mbit/s (+52%).
A separate download test (four 30-second samples per configuration)
measured 241 to 263 Mbit/s (+9%).

Link: 
https://github.com/friendlyarm/rtl8822cs/blob/c8b944a34bba2116fcdb060362bde40242bb87e5/hal/rtl8822c/rtl8822c_halinit.c
Assisted-by: LLM
Signed-off-by: Leonard Lausen <leonard@lausen.nl>
---
Resending with the Signed-off-by and Assisted-by tags.

  drivers/net/wireless/realtek/rtw88/reg.h      | 4 ++++
  drivers/net/wireless/realtek/rtw88/rtw8822c.c | 9 +++++++++
  2 files changed, 13 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/reg.h 
b/drivers/net/wireless/realtek/rtw88/reg.h
index afcdb66fdb9a1..8e220580be4f8 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -587,6 +587,10 @@
   #define REG_RXFLTMAP0		0x06A0
  #define REG_RXFLTMAP1		0x06A2
+#define BIT_RXFLTMAP1_BACK	BIT(9)
+#define BIT_RXFLTMAP1_RTS	BIT(11)
+#define BIT_RXFLTMAP1_CTS	BIT(12)
+#define BIT_RXFLTMAP1_ACK	BIT(13)
  #define REG_RXFLTMAP2		0x06A4
  #define REG_RXFLTMAP4		0x068A
  #define REG_BT_COEX_TABLE0	0x06C0
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c 
b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 32d9709f2c243..9c9e4f2397282 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -2096,6 +2096,15 @@ static int rtw8822c_mac_init(struct rtw_dev *rtwdev)
  	rtw_write8(rtwdev, REG_WMAC_TRXPTCL_CTL_H  + 2, WLAN_BAR_ACK_TYPE);
  	rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
  	rtwdev->hal.rxfltmap1 = WLAN_RX_FILTER1;
+	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) {
+		/* Hardware handles these frames; retain BAR and PS-Poll for
+		 * mac80211. FIF_CONTROL restores all subtypes for monitors.
+		 */
+		rtwdev->hal.rxfltmap1 &= ~(BIT_RXFLTMAP1_BACK |
+						BIT_RXFLTMAP1_RTS |
+						BIT_RXFLTMAP1_CTS |
+						BIT_RXFLTMAP1_ACK);
+	}
  	rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1);
  	rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
  	rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead
  2026-11-15 14:23 [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead Leonard Lausen
  2026-11-15 14:23 ` [PATCH 1/2] wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO Leonard Lausen
  2026-11-15 14:23 ` [PATCH 2/2] wifi: rtw88: sdio: combine free TX page register reads Leonard Lausen
@ 2026-11-15 18:26 ` Luka Gejak
  2 siblings, 0 replies; 5+ messages in thread
From: Luka Gejak @ 2026-11-15 18:26 UTC (permalink / raw)
  To: linux-wireless, Leonard Lausen, Ping-Ke Shih
  Cc: leonard, Shawn Lin, Heiko Stuebner, linux-rockchip, linux-kernel

Hi Leonard,

On November 15, 2026 3:23:28 PM GMT+01:00, Leonard Lausen
<leonard@lausen.nl> wrote:
>Reduce SDIO request overhead by filtering hardware-handled control
>frames and combining adjacent TX-capacity reads.
>
>RTL8822CS on NanoPi M5, median TCP Mbit/s:
>
>                              Upload   Download
>  Neither patch                170.4      241.2
>  Filtering only               258.2      263.3
>  Combined register reads only 186.5      261.6
>  Both patches                 286.9      273.5
>
>Together the patches improved median upload by 68% and download by 13.4%.
>Upload and download were measured in separate sessions, with four
>20-second upload samples and four 30-second download samples per
>configuration. Testing used a shared Wi-Fi network, so throughput can
>vary.
>
>Runtime baseline: v7.4-rc2 plus the RX-bounds fix accepted in rtw-next
>(83ca360e85280) and the MMC voltage-switch fixes in linux-next

Series targeted for rtw-next should be based on rtw-next, unless there is
a good reason for doing otherwise.

>(67a97316a31a3, a3838c21e28e5). All variants use stock MMC host limits,
>198 MHz SDR104, performance governors and identical CPU placement:
>SDIO IRQ on CPU4, iperf client on CPU6, server on CPU7. Traffic crosses
>Wi-Fi/AP/Ethernet between two endpoints on the board.
>
>All 20 configured rtw88 modules built with W=1. Sanitized function models
>cover credit-read errors, fallback and buffer ownership. Module IDs,
>filter registers, traffic paths and kernel logs were checked. AP/monitor,
>suspend/resume and other-chip hardware remain untested.
>
>AI assistance: Codex inspected sources, developed the changes and
>messages,
>and automated validation. Prompts requested small optimizations measured
>individually and together, with explicit prerequisite and impact checks.
>
>Leonard Lausen (2):
>  wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO
>  wifi: rtw88: sdio: combine free TX page register reads
>
> drivers/net/wireless/realtek/rtw88/reg.h      |  4 ++
> drivers/net/wireless/realtek/rtw88/rtw8822c.c |  9 +++
> drivers/net/wireless/realtek/rtw88/sdio.c     | 58 +++++++++++++++++--
> drivers/net/wireless/realtek/rtw88/sdio.h     |  1 +
> 4 files changed, 68 insertions(+), 4 deletions(-)
>
>base-commit: 7475ea8b58616b33c04afb976cf0fbaad9dd63fb

Can you resend this properly, as v2, as resending singular patches is not
encouraged?

For the actual patches:

Read Documentation/process/coding-style.rst and
apply what you learn in there to all patches. Furthermore Assisted-by tag
is deprecated and should be removed, which you would have seen if you had
ran checkpatch on your patches. Address these and other style issues and I
will review v2, as I don't have time right now.

Best regards,
Luka Gejak

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-11-15 18:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-15 14:23 [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead Leonard Lausen
2026-11-15 14:23 ` [PATCH 1/2] wifi: rtw88: 8822c: filter hardware-handled control frames on SDIO Leonard Lausen
2026-11-15 14:29   ` Leonard Lausen
2026-11-15 14:23 ` [PATCH 2/2] wifi: rtw88: sdio: combine free TX page register reads Leonard Lausen
2026-11-15 18:26 ` [PATCH 0/2] wifi: rtw88: reduce RTL8822CS SDIO request overhead Luka Gejak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®