Control: reassign -1 src:linux 6.1.27-1
Control: retitle -1 rtw88_pci: RX DMA errors despite rx_no_aspm workaround
Control: tag -1 upstream patch moreinfo

On Mon, 2023-06-19 at 03:20 -0300, Leandro Cunha wrote:
> Package: firmware-realtek
> Version: 20230404-1
> Severity: important
> 
> This firmware contains the rtw88 module

It doesn't - firmware and drivers are two different things.

> and needs some settings to
> have a stable connection, like disabling the ASPM (Active State Power
> Management)
[...]

OK, but if this is a general problem it should be fixed in the driver
and not by adding a configuration file.

This *was* supposed to have been fixed by
<https://git.kernel.org/linus/24f5e38a13b5ae2b6105cda8bb47c19108e62a9a>
but apparently not.

Could you please test whether the attached patch fixes this (without
also using disable_aspm=1)?  Instructions for rebuilding the kernel are
at
<https://kernel-team.pages.debian.net/kernel-handbook/ch-common-tasks.html#s-common-official>.

Ben.

-- 
Ben Hutchings
compatible: Gracefully accepts erroneous data from any source

From 44b626514f8064f721c694ce977cf3a14da75047 Mon Sep 17 00:00:00 2001
From: Ben Hutchings <b...@debian.org>
Date: Tue, 20 Jun 2023 19:46:47 +0200
Subject: [PATCH] rtw88_pci: Apply rx_no_aspm workaround for longer

In certain configurations we need to keep the PCIe link in L0 to avoid
RX DMA errors.  Currently we do this while the poll function is
running, but this only roughly corresponds to when RX DMA is
happening.

Instead, keep the link in L0 for the whole time that NAPI polling is
enabled.  Use napi_schedule_prep()+__napi_schedule() rather than
napi_schedule(), so that we know for sure when we start and stop
polling.

Signed-off-by: Ben Hutchings <b...@debian.org>
---
 drivers/net/wireless/realtek/rtw88/pci.c | 27 +++++++++++++++++-------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index 672ddde80816..406bb12374d1 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -1014,7 +1014,15 @@ static void rtw_pci_rx_isr(struct rtw_dev *rtwdev)
 	struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv;
 	struct napi_struct *napi = &rtwpci->napi;
 
-	napi_schedule(napi);
+	if (napi_schedule_prep(napi)) {
+		__napi_schedule(napi);
+
+		/* If necessary, keep link in L0 so long as we are in
+		 * NAPI polling
+		 */
+		if (rtwpci->rx_no_aspm)
+			rtw_pci_link_ps(rtwdev, false);
+	}
 }
 
 static int rtw_pci_get_hw_rx_ring_nr(struct rtw_dev *rtwdev,
@@ -1644,9 +1652,6 @@ static int rtw_pci_napi_poll(struct napi_struct *napi, int budget)
 					      priv);
 	int work_done = 0;
 
-	if (rtwpci->rx_no_aspm)
-		rtw_pci_link_ps(rtwdev, false);
-
 	while (work_done < budget) {
 		u32 work_done_once;
 
@@ -1667,11 +1672,17 @@ static int rtw_pci_napi_poll(struct napi_struct *napi, int budget)
 		 * not be processed immediately. Check whether dma ring is
 		 * empty and perform napi_schedule accordingly.
 		 */
-		if (rtw_pci_get_hw_rx_ring_nr(rtwdev, rtwpci))
-			napi_schedule(napi);
+		if (rtw_pci_get_hw_rx_ring_nr(rtwdev, rtwpci) &&
+		    napi_schedule_prep(napi)) {
+			__napi_schedule(napi);
+		} else {
+			/* If we kept link into L0, allow it to
+			 * re-enter L1 until next IRQ
+			 */
+			if (rtwpci->rx_no_aspm)
+				rtw_pci_link_ps(rtwdev, true);
+		}
 	}
-	if (rtwpci->rx_no_aspm)
-		rtw_pci_link_ps(rtwdev, true);
 
 	return work_done;
 }

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to