Skip to content

Commit

Permalink
rtw88: sdio: honor the host max_req_size in the rx path
Browse files Browse the repository at this point in the history
Use multiple consecutive reads in rtw_sdio_read_port() to limit the number of bytes which are copied by the host from the card in one MMC/SDIO transfer. This allows receiving a buffer that's larger than the hosts max_req_size (number of bytes which can be transferred in one MMC/SDIO transfer). As a result of this the skb_over_panic error is gone as the rtw88 driver is now able to receive more than 1536 bytes from the card (either because the incoming packet is larger than that or because multiple packets have been aggregated).

Signed-off-by: Patrick Yavitz <pyavitz@xxxxx.com>
  • Loading branch information
Patrick Yavitz authored and igorpecovnik committed Jul 11, 2023
1 parent 02ba64b commit 2b5e341
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 30 deletions.
2 changes: 1 addition & 1 deletion lib/functions/compilation/patch/drivers_network.sh
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ driver_rtw88() {
display_alert "Adding" "Upstream wireless RTW88 drivers" "info"
process_patch_file "${SRC}/patch/misc/rtw88/${version}/001-rtw88-linux-next.patch" "applying"
process_patch_file "${SRC}/patch/misc/rtw88/${version}/002-rtw88-linux-next.patch" "applying"
process_patch_file "${SRC}/patch/misc/rtw88/hack/001-revert-rtw88-sdio-size-and-timout-to-rfc-v1.patch" "applying"
#process_patch_file "${SRC}/patch/misc/rtw88/hack/001-revert-rtw88-sdio-size-and-timout-to-rfc-v1.patch" "applying"
process_patch_file "${SRC}/patch/misc/rtw88/hack/002-rtw88-usb-make-work-queues-high-priority.patch" "applying"
process_patch_file "${SRC}/patch/misc/rtw88/hack/003-rtw88-decrease-the-log-level-of-tx-report.patch" "applying"
fi
Expand Down
30 changes: 21 additions & 9 deletions patch/misc/rtw88/6.1/002-rtw88-linux-next.patch
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,9 @@
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cu driver");
+MODULE_LICENSE("Dual BSD/GPL");
--- /dev/null 2023-06-17 08:32:20.061755428 -0400
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-22 13:52:09.000000000 -0400
@@ -0,0 +1,1404 @@
--- /dev/null 2023-07-07 19:42:40.585806232 -0400
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-07-10 05:58:23.384448785 -0400
@@ -0,0 +1,1416 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright (C) 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2021 Jernej Skrabec <jernej.skrabec@gmail.com>
Expand Down Expand Up @@ -896,19 +896,31 @@
+static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count)
+{
+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+ struct mmc_host *host = rtwsdio->sdio_func->card->host;
+ bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio);
+ u32 rxaddr = rtwsdio->rx_addr++;
+ size_t bytes;
+ int ret;
+
+ if (bus_claim)
+ sdio_claim_host(rtwsdio->sdio_func);
+
+ ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count);
+ if (ret)
+ rtw_warn(rtwdev,
+ "Failed to read %zu byte(s) from SDIO port 0x%08x",
+ count, rxaddr);
+ while (count > 0) {
+ bytes = min_t(size_t, host->max_req_size, count);
+
+ ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr),
+ bytes);
+ if (ret) {
+ rtw_warn(rtwdev,
+ "Failed to read %zu byte(s) from SDIO port 0x%08x",
+ bytes, rxaddr);
+ break;
+ }
+
+ count -= bytes;
+ buf += bytes;
+ }
+
+ if (bus_claim)
+ sdio_release_host(rtwsdio->sdio_func);
Expand Down
30 changes: 21 additions & 9 deletions patch/misc/rtw88/6.2/002-rtw88-linux-next.patch
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@
+MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cs driver");
+MODULE_LICENSE("Dual BSD/GPL");
--- /dev/null 2023-06-17 08:32:20.061755428 -0400
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-22 13:52:09.000000000 -0400
@@ -0,0 +1,1404 @@
--- /dev/null 2023-07-07 19:42:40.585806232 -0400
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-07-10 05:58:23.384448785 -0400
@@ -0,0 +1,1416 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright (C) 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2021 Jernej Skrabec <jernej.skrabec@gmail.com>
Expand Down Expand Up @@ -664,19 +664,31 @@
+static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count)
+{
+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+ struct mmc_host *host = rtwsdio->sdio_func->card->host;
+ bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio);
+ u32 rxaddr = rtwsdio->rx_addr++;
+ size_t bytes;
+ int ret;
+
+ if (bus_claim)
+ sdio_claim_host(rtwsdio->sdio_func);
+
+ ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count);
+ if (ret)
+ rtw_warn(rtwdev,
+ "Failed to read %zu byte(s) from SDIO port 0x%08x",
+ count, rxaddr);
+ while (count > 0) {
+ bytes = min_t(size_t, host->max_req_size, count);
+
+ ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr),
+ bytes);
+ if (ret) {
+ rtw_warn(rtwdev,
+ "Failed to read %zu byte(s) from SDIO port 0x%08x",
+ bytes, rxaddr);
+ break;
+ }
+
+ count -= bytes;
+ buf += bytes;
+ }
+
+ if (bus_claim)
+ sdio_release_host(rtwsdio->sdio_func);
Expand Down
30 changes: 21 additions & 9 deletions patch/misc/rtw88/6.3/002-rtw88-linux-next.patch
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@
+MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cs driver");
+MODULE_LICENSE("Dual BSD/GPL");
--- /dev/null 2023-06-17 08:32:20.061755428 -0400
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-22 13:52:09.000000000 -0400
@@ -0,0 +1,1404 @@
--- /dev/null 2023-07-07 19:42:40.585806232 -0400
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-07-10 05:58:23.384448785 -0400
@@ -0,0 +1,1416 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright (C) 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2021 Jernej Skrabec <jernej.skrabec@gmail.com>
Expand Down Expand Up @@ -664,19 +664,31 @@
+static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count)
+{
+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+ struct mmc_host *host = rtwsdio->sdio_func->card->host;
+ bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio);
+ u32 rxaddr = rtwsdio->rx_addr++;
+ size_t bytes;
+ int ret;
+
+ if (bus_claim)
+ sdio_claim_host(rtwsdio->sdio_func);
+
+ ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count);
+ if (ret)
+ rtw_warn(rtwdev,
+ "Failed to read %zu byte(s) from SDIO port 0x%08x",
+ count, rxaddr);
+ while (count > 0) {
+ bytes = min_t(size_t, host->max_req_size, count);
+
+ ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr),
+ bytes);
+ if (ret) {
+ rtw_warn(rtwdev,
+ "Failed to read %zu byte(s) from SDIO port 0x%08x",
+ bytes, rxaddr);
+ break;
+ }
+
+ count -= bytes;
+ buf += bytes;
+ }
+
+ if (bus_claim)
+ sdio_release_host(rtwsdio->sdio_func);
Expand Down
88 changes: 88 additions & 0 deletions patch/misc/rtw88/6.4/002-rtw88-linux-next.patch
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,91 @@
+MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
+MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver");
+MODULE_LICENSE("Dual BSD/GPL");
From: Martin Blumenstingl @ 2023-07-09 19:57 UTC (permalink / raw)
To: linux-wireless
Cc: linux-kernel, jernej.skrabec, pkshih, ulf.hansson, kvalo,
tony0620emma, Martin Blumenstingl, Lukas F . Hartmann

Lukas reports skb_over_panic errors on his Banana Pi BPI-CM4 which comes
with an Amlogic A311D (G12B) SoC and a RTL8822CS SDIO wifi/Bluetooth
combo card. The error he observed is identical to what has been fixed
in commit e967229ead0e ("wifi: rtw88: sdio: Check the HISR RX_REQUEST
bit in rtw_sdio_rx_isr()") but that commit didn't fix Lukas' problem.

Lukas found that disabling or limiting RX aggregation fix the problem
for him. In the following discussion a few key topics have been
discussed which have an impact on this problem:
- The Amlogic A311D (G12B) SoC has a hardware bug in the SDIO controller
which prevents DMA transfers. Instead all transfers need to go through
the controller SRAM which limits transfers to 1536 bytes
- rtw88 chips don't split incoming (RX) packets, so if a big packet is
received this is forwarded to the host in it's original form
- rtw88 chips can do RX aggregation, meaning more multiple incoming
packets can be pulled by the host from the card with one MMC/SDIO
transfer. This Depends on settings in the REG_RXDMA_AGG_PG_TH
register (BIT_RXDMA_AGG_PG_TH limits the number of packets that will
be aggregated, BIT_DMA_AGG_TO_V1 configures a timeout for aggregation
and BIT_EN_PRE_CALC makes the chip honor the limits more effectively)

Use multiple consecutive reads in rtw_sdio_read_port() to limit the
number of bytes which are copied by the host from the card in one
MMC/SDIO transfer. This allows receiving a buffer that's larger than
the hosts max_req_size (number of bytes which can be transferred in
one MMC/SDIO transfer). As a result of this the skb_over_panic error
is gone as the rtw88 driver is now able to receive more than 1536 bytes
from the card (either because the incoming packet is larger than that
or because multiple packets have been aggregated).

Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets")
Reported-by: Lukas F. Hartmann <lukas@mntre.com>
Closes: https://lore.kernel.org/linux-wireless/CAFBinCBaXtebixKbjkWKW_WXc5k=NdGNaGUjVE8NCPNxOhsb2g@mail.gmail.com/
Suggested-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/wireless/realtek/rtw88/sdio.c | 24 +++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index 2c1fb2dabd40..b19262ec5d8c 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -500,19 +500,31 @@ static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size,
static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count)
{
struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+ struct mmc_host *host = rtwsdio->sdio_func->card->host;
bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio);
u32 rxaddr = rtwsdio->rx_addr++;
+ size_t bytes;
int ret;

if (bus_claim)
sdio_claim_host(rtwsdio->sdio_func);

- ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
- RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count);
- if (ret)
- rtw_warn(rtwdev,
- "Failed to read %zu byte(s) from SDIO port 0x%08x",
- count, rxaddr);
+ while (count > 0) {
+ bytes = min_t(size_t, host->max_req_size, count);
+
+ ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr),
+ bytes);
+ if (ret) {
+ rtw_warn(rtwdev,
+ "Failed to read %zu byte(s) from SDIO port 0x%08x",
+ bytes, rxaddr);
+ break;
+ }
+
+ count -= bytes;
+ buf += bytes;
+ }

if (bus_claim)
sdio_release_host(rtwsdio->sdio_func);
--
2.41.0
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
From: Patrick Yavitz <pyavitz@gmail.com>
From: Patrick Yavitz @ 2023-06-30
Subject: v2: rtw88: decrease the log level of tx report

Reduce 'failed to get tx report from firmware' dmesg spam.

https://lore.kernel.org/linux-wireless/20210713104524.47101-1-pkshih@realtek.com/
https://cgit.freebsd.org/src/commit/?id=e140d551b78670fbf99c83a59438cb13de50420f

Signed-off-by: Patrick Yavitz <pyavitz@gxxx.com>
Signed-off-by: Patrick Yavitz <pyavitz@xxxxx.com>
diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
--- a/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-30 13:28:40.396914119 -0400
+++ b/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-30 16:57:33.868259352 -0400
Expand Down

0 comments on commit 2b5e341

Please sign in to comment.