From 2fa22776720fa8d9bb230c5468d68c418fae3924 Mon Sep 17 00:00:00 2001 From: Patrick Yavitz Date: Fri, 17 Nov 2023 06:25:42 -0500 Subject: [PATCH] patch: misc: rtw88: `6.7` linux 6.7.y support Signed-off-by: Patrick Yavitz --- ...less-realtek-rtw88-upstream-wireless.patch | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 patch/misc/rtw88/6.7/001-drivers-net-wireless-realtek-rtw88-upstream-wireless.patch diff --git a/patch/misc/rtw88/6.7/001-drivers-net-wireless-realtek-rtw88-upstream-wireless.patch b/patch/misc/rtw88/6.7/001-drivers-net-wireless-realtek-rtw88-upstream-wireless.patch new file mode 100644 index 0000000000..c7b7fce383 --- /dev/null +++ b/patch/misc/rtw88/6.7/001-drivers-net-wireless-realtek-rtw88-upstream-wireless.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +To: linux-wireless@vger.kernel.org +Date: Wed, 2 Aug 2023 00:27:32 +0000 +Subject: [PATCH] wifi: rtw88: sdio: Honor the host max_req_size in the RX path + +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 +Closes: https://lore.kernel.org/linux-wireless/CAFBinCBaXtebixKbjkWKW_WXc5k=NdGNaGUjVE8NCPNxOhsb2g@mail.gmail.com/ +Suggested-by: Ping-Ke Shih +Signed-off-by: Martin Blumenstingl +--- + 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 +