
Hello Matthias,
On Fri, 2024-04-26 at 10:02 +0200, Matthias Schiffer wrote:
Buffers must not have an unclean cache before being used for DMA - a pending write-back may corrupt the next dev-to-mem transfer otherwise.
This was consistently noticeable during long TFTP transfers, when an ARP request is answered by U-Boot in the middle of the transfer:
As U-Boot's arp_receive() reuses the receive buffer to prepare its reply packet, the beginning of one of the next incoming TFTP packets is overwritten by the ARP reply. The corrupted packet is ignored, but the TFTP transfer stalls for a few seconds until a timeout is detected and a retransmit is triggered.
Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com
thanks for the series! I've tested it on a custom AM625-based board issuing a a couple of pings:
am65_cpsw_nuss ethernet@8000000: K3 CPSW: nuss_ver: 0x6BA01103 cpsw_ver: 0x6BA81103 ale_ver: 0x00290105 Ports:2 Net: eth0: ethernet@8000000port@1 Autobooting in 3 seconds, press "<Esc><Esc>" to stop U-Boot# ping 192.168.251.10 ti-udma dma-controller@485c0000: k3_dmaring Ring probed rings:150, sci-dev-id:30 ti-udma dma-controller@485c0000: dma-ring-reset-quirk: disabled am65_cpsw_nuss_port ethernet@8000000port@1: K3 CPSW: rflow_id_base: 19 link up on port 1, speed 100, full duplex Using ethernet@8000000port@1 device host 192.168.251.10 is alive U-Boot# ping 192.168.251.10 am65_cpsw_nuss_port ethernet@8000000port@1: K3 CPSW: rflow_id_base: 19 link up on port 1, speed 100, full duplex Using ethernet@8000000port@1 device host 192.168.251.10 is alive
This sequence looks exactly the same with your patches and without. Therefore for the whole series:
Tested-by: Alexander Sverdlin alexander.sverdlin@siemens.com
drivers/dma/ti/k3-udma.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index 4e6f7f570c5..8f6d396653e 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -2678,6 +2678,9 @@ int udma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size) cppi5_hdesc_set_pktlen(desc_rx, size); cppi5_hdesc_attach_buf(desc_rx, dma_dst, size, dma_dst, size); + invalidate_dcache_range((unsigned long)dma_dst, + (unsigned long)(dma_dst + size));
flush_dcache_range((unsigned long)desc_rx, ALIGN((unsigned long)desc_rx + uc->config.hdesc_size, ARCH_DMA_MINALIGN));