Linux wireless drivers development
 help / color / mirror / Atom feed
From: Alastair D'Silva <alastair@d-silva.org>
To: Ping-Ke Shih <pkshih@realtek.com>, linux-wireless@vger.kernel.org
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
	Ulf Hansson <ulfh@kernel.org>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	Kalle Valo <kvalo@kernel.org>, Luka Gejak <luka.gejak@linux.dev>,
	linux-kernel@vger.kernel.org,
	Alastair D'Silva <alastair@d-silva.org>
Subject: [PATCH v3 2/2] wifi: rtw88: sdio: Split rtw_sdio_rx_isr into 8051 and 3081 variants
Date: Thu,  1 Oct 2026 10:03:03 +1000	[thread overview]
Message-ID: <20261001000303.3505264-3-alastair@d-silva.org> (raw)
In-Reply-To: <20261001000303.3505264-1-alastair@d-silva.org>

Following the split of rtw_sdio_handle_interrupt(), the receive FIFO drain
loop in rtw_sdio_rx_isr() still contained a growing number of special
cases between 8051 and 3081 chips, evaluated twice per packet in the RX
hot path:

1. Register width: 8051 uses a 16-bit read of REG_SDIO_RX0_REQ_LEN,
   while 3081 uses a 32-bit read.
2. Loop termination: 8051 must re-read REG_SDIO_HISR on each iteration
   because the RX buffer may contain data while HW or FW is still filling
   it. Conversely, 3081 has improved HW/FW that can use rx_len
   unconditionally, previously requiring a synthetic assignment of
   hisr = REG_SDIO_HISR_RX_REQUEST to trick the loop condition into
   continuing.

To avoid accumulating further special cases and eliminate per-packet
branching in the RX hot path, split rtw_sdio_rx_isr() into separate
rtw_sdio_rx_isr_8051() and rtw_sdio_rx_isr_3081() functions.

This removes the artificial hisr assignment on 3081 and keeps the RX
processing logic cleanly separated by architecture.

Assisted-by: LLM
Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
---
v3:
- New patch in v3.
- Split rtw_sdio_rx_isr into 8051 and 3081 variants following the dispatcher split.
- Eliminates per-packet wcpu branching in the RX hot path and removes artificial
  hisr assignments on 3081.
- Added Assisted-by tag per Documentation/process/coding-assistants.rst.

 drivers/net/wireless/realtek/rtw88/sdio.c | 54 ++++++++++++-----------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index 63d62242ac1e..fbf67427b450 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -1418,16 +1418,12 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len)
 	}
 }
 
-static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev)
+static void rtw_sdio_rx_isr_8051(struct rtw_dev *rtwdev)
 {
 	u32 rx_len, hisr, total_rx_bytes = 0;
 
 	do {
-		if (rtw_chip_wcpu_8051(rtwdev))
-			rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN);
-		else
-			rx_len = rtw_read32(rtwdev, REG_SDIO_RX0_REQ_LEN);
-
+		rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN);
 		if (!rx_len)
 			break;
 
@@ -1435,33 +1431,41 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev)
 
 		total_rx_bytes += rx_len;
 
-		if (rtw_chip_wcpu_8051(rtwdev)) {
-			/* Stop if no more RX requests are pending, even if
-			 * rx_len could be greater than zero in the next
-			 * iteration. This is needed because the RX buffer may
-			 * already contain data while either HW or FW are not
-			 * done filling that buffer yet. Still reading the
-			 * buffer can result in packets where
-			 * rtw_rx_pkt_stat.pkt_len is zero or points beyond the
-			 * end of the buffer.
-			 */
-			hisr = rtw_read32(rtwdev, REG_SDIO_HISR);
-		} else {
-			/* RTW_WCPU_3081 chips have improved hardware or
-			 * firmware and can use rx_len unconditionally.
-			 */
-			hisr = REG_SDIO_HISR_RX_REQUEST;
-		}
+		/* Stop if no more RX requests are pending, even if
+		 * rx_len could be greater than zero in the next
+		 * iteration. This is needed because the RX buffer may
+		 * already contain data while either HW or FW are not
+		 * done filling that buffer yet. Still reading the
+		 * buffer can result in packets where
+		 * rtw_rx_pkt_stat.pkt_len is zero or points beyond the
+		 * end of the buffer.
+		 */
+		hisr = rtw_read32(rtwdev, REG_SDIO_HISR);
 	} while (total_rx_bytes < SZ_64K && hisr & REG_SDIO_HISR_RX_REQUEST);
 }
 
+static void rtw_sdio_rx_isr_3081(struct rtw_dev *rtwdev)
+{
+	u32 rx_len, total_rx_bytes = 0;
+
+	do {
+		rx_len = rtw_read32(rtwdev, REG_SDIO_RX0_REQ_LEN);
+		if (!rx_len)
+			break;
+
+		rtw_sdio_rxfifo_recv(rtwdev, rx_len);
+
+		total_rx_bytes += rx_len;
+	} while (total_rx_bytes < SZ_64K);
+}
+
 static void rtw_sdio_handle_interrupt_8051(struct rtw_dev *rtwdev, u32 hisr)
 {
 	if (hisr & REG_SDIO_HISR_TXERR)
 		rtw_sdio_tx_err_isr(rtwdev);
 	if (hisr & REG_SDIO_HISR_RX_REQUEST) {
 		hisr &= ~REG_SDIO_HISR_RX_REQUEST;
-		rtw_sdio_rx_isr(rtwdev);
+		rtw_sdio_rx_isr_8051(rtwdev);
 	}
 
 	/*
@@ -1483,7 +1487,7 @@ static void rtw_sdio_handle_interrupt_3081(struct rtw_dev *rtwdev, u32 hisr)
 	if (hisr & REG_SDIO_HISR_TXERR)
 		rtw_sdio_tx_err_isr(rtwdev);
 	if (hisr & REG_SDIO_HISR_RX_REQUEST)
-		rtw_sdio_rx_isr(rtwdev);
+		rtw_sdio_rx_isr_3081(rtwdev);
 
 	/* Unmasking HIMR re-asserts the IRQ line if new packets arrived */
 	rtw_sdio_enable_interrupt(rtwdev);
-- 
2.53.0


  parent reply	other threads:[~2026-10-01  0:03 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01  0:03 [PATCH v3 0/2] wifi: rtw88: sdio: Fix interrupt storm on 3081 chips and split RX handling Alastair D'Silva
2026-10-01  0:03 ` [PATCH v3 1/2] wifi: rtw88: sdio: Fix unhandled RX request interrupt storm Alastair D'Silva
2026-10-01  6:02   ` Luka Gejak
2026-10-05  3:35   ` Ping-Ke Shih
2026-10-05  4:39     ` Luka Gejak
2026-10-05  5:30       ` Ping-Ke Shih
2026-10-05  6:44         ` Alastair D'Silva
2026-10-05  6:57           ` Ping-Ke Shih
2026-10-05  8:20     ` Alastair D'Silva
2026-10-05  8:43       ` Ping-Ke Shih
2026-10-01  0:03 ` Alastair D'Silva [this message]
2026-10-05  3:41   ` [PATCH v3 2/2] wifi: rtw88: sdio: Split rtw_sdio_rx_isr into 8051 and 3081 variants Ping-Ke Shih
2026-10-02  2:15 ` [PATCH v3 0/2] wifi: rtw88: sdio: Fix interrupt storm on 3081 chips and split RX handling 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=20261001000303.3505264-3-alastair@d-silva.org \
    --to=alastair@d-silva.org \
    --cc=jernej.skrabec@gmail.com \
    --cc=kvalo@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=luka.gejak@linux.dev \
    --cc=martin.blumenstingl@googlemail.com \
    --cc=pkshih@realtek.com \
    --cc=ulfh@kernel.org \
    /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