History log of /linux-master/drivers/net/wireless/realtek/rtw88/sdio.c
Revision Date Author Comments
# 00384f56 19-Nov-2023 Martin Blumenstingl <martin.blumenstingl@googlemail.com>

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 works around the
problem for some time (but does not fully fix it). 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() and 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).

In case of an receive errors (-EILSEQ has been observed by Lukas) we
need to drain the remaining data from the card's buffer, otherwise the
card will return corrupt data for the next rtw_sdio_read_port() call.

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>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Tested-by: Lukas F. Hartmann <lukas@mntre.com>
Reported-by: Lukas F. Hartmann <lukas@mntre.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Tested-by: Lukas F. Hartmann <lukas@mntre.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231120115726.1569323-1-martin.blumenstingl@googlemail.com


# e967229e 22-May-2023 Martin Blumenstingl <martin.blumenstingl@googlemail.com>

wifi: rtw88: sdio: Check the HISR RX_REQUEST bit in rtw_sdio_rx_isr()

rtw_sdio_rx_isr() is responsible for receiving data from the wifi chip
and is called from the SDIO interrupt handler when the interrupt status
register (HISR) has the RX_REQUEST bit set. After the first batch of
data has been processed by the driver the wifi chip may have more data
ready to be read, which is managed by a loop in rtw_sdio_rx_isr().

It turns out that there are cases where the RX buffer length (from the
REG_SDIO_RX0_REQ_LEN register) does not match the data we receive. The
following two cases were observed with a RTL8723DS card:
- RX length is smaller than the total packet length including overhead
and actual data bytes (whose length is part of the buffer we read from
the wifi chip and is stored in rtw_rx_pkt_stat.pkt_len). This can
result in errors like:
skbuff: skb_over_panic: text:ffff8000011924ac len:3341 put:3341
(one case observed was: RX buffer length = 1536 bytes but
rtw_rx_pkt_stat.pkt_len = 1546 bytes, this is not valid as it means
we need to read beyond the end of the buffer)
- RX length looks valid but rtw_rx_pkt_stat.pkt_len is zero

Check if the RX_REQUEST is set in the HISR register for each iteration
inside rtw_sdio_rx_isr(). This mimics what the RTL8723DS vendor driver
does and makes the driver only read more data if the RX_REQUEST bit is
set (which seems to be a way for the card's hardware or firmware to
tell the host that data is ready to be processed).

For RTW_WCPU_11AC chips this check is not needed. The RTL8822BS vendor
driver for example states that this check is unnecessary (but still uses
it) and the RTL8822CS drops this check entirely.

Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230522202425.1827005-2-martin.blumenstingl@googlemail.com


# cb0ddaaa 15-May-2023 Martin Blumenstingl <martin.blumenstingl@googlemail.com>

wifi: rtw88: sdio: Always use two consecutive bytes for word operations

The Allwinner sunxi-mmc controller cannot handle word (16 bit)
transfers. So and sdio_{read,write}w fails with messages like the
following example using an RTL8822BS (but the same problems were also
observed with RTL8822CS and RTL8723DS chips):
rtw_8822bs mmc1:0001:1: Firmware version 27.2.0, H2C version 13
sunxi-mmc 4021000.mmc: unaligned scatterlist: os f80 length 2
sunxi-mmc 4021000.mmc: map DMA failed
rtw_8822bs mmc1:0001:1: sdio read16 failed (0x10230): -22

Use two consecutive single byte accesses for word operations instead. It
turns out that upon closer inspection this is also what the vendor
driver does, even though it does have support for sdio_{read,write}w. So
we can conclude that the rtw88 chips do support word access but only on
SDIO controllers that also support it. Since there's no way to detect if
the controller supports word access or not the rtw88 sdio driver
switches to the easiest approach: avoiding word access.

Reported-by: Larry Finger <Larry.Finger@lwfinger.net>
Closes: https://lore.kernel.org/linux-wireless/527585e5-9cdd-66ed-c3af-6da162f4b720@lwfinger.net/
Reported-by: Rudi Heitbaum <rudi@heitbaum.com>
Link: https://github.com/LibreELEC/LibreELEC.tv/pull/7837#issue-1708469467
Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets")
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230515195043.572375-1-martin.blumenstingl@googlemail.com


# 65371a3f 05-Apr-2023 Martin Blumenstingl <martin.blumenstingl@googlemail.com>

wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets

Add a sub-driver for SDIO based chipsets which implements the following
functionality:
- register accessors for 8, 16 and 32 bits for all states of the card
(including usage of 4x 8 bit access for one 32 bit buffer if the card
is not fully powered on yet - or if it's fully powered on then 1x 32
bit access is used)
- checking whether there's space in the TX FIFO queue to transmit data
- transfers from the host to the device for actual network traffic,
reserved pages (for firmware download) and H2C (host-to-card)
transfers
- receiving data from the device
- deep power saving state

The transmit path is optimized so DMA-capable SDIO host controllers can
directly use the buffers provided because the buffer's physical
addresses are 8 byte aligned.

The receive path is prepared to support RX aggregation where the
chipset combines multiple MAC frames into one bigger buffer to reduce
SDIO transfer overhead.

Co-developed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230405200729.632435-3-martin.blumenstingl@googlemail.com