[PATCH master 22/23] net: bcmgenet: map DMA buffers with dma_map_single

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We need to map DMA buffers first before handing them off to HW,
otherwise dirty cache lines may get evicted in the time window
between HW conducting DMA to rx_buffer and dma_sync_single_for_cpu
invalidating the CPU cache leading to corrupted packets.

This was detected by CONFIG_DMA_API_DEBUG, but needed adding a manual
!dev check into debug_dma_sync_single_for_cpu/device to silence the
not-yet fixed reports about the Rpi mailbox driver.

Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx>
---
Cc: Enrico Scholz <enrico.scholz@xxxxxxxxxxxxxxxxx>
---
 drivers/net/bcmgenet.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/bcmgenet.c b/drivers/net/bcmgenet.c
index 9e0bacb31adf..acbb973a92f2 100644
--- a/drivers/net/bcmgenet.c
+++ b/drivers/net/bcmgenet.c
@@ -356,12 +356,13 @@ static void rx_descs_init(struct bcmgenet_eth_priv *priv)
 	len_stat = (RX_BUF_LENGTH << DMA_BUFLENGTH_SHIFT) | DMA_OWN;
 
 	for (i = 0; i < RX_DESCS; i++) {
-		writel(lower_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]),
-		       desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_LO);
-		writel(upper_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]),
-		       desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_HI);
-		writel(len_stat,
-		       desc_base + i * DMA_DESC_SIZE + DMA_DESC_LENGTH_STATUS);
+		dma_addr_t dma_addr = dma_map_single(priv->dev, &rxbuffs[i * RX_BUF_LENGTH],
+			   RX_BUF_LENGTH, DMA_FROM_DEVICE);
+		void *desc = desc_base + i * DMA_DESC_SIZE;
+
+		writel(lower_32_bits(dma_addr), desc + DMA_DESC_ADDRESS_LO);
+		writel(upper_32_bits(dma_addr), desc + DMA_DESC_ADDRESS_HI);
+		writel(len_stat, desc + DMA_DESC_LENGTH_STATUS);
 	}
 }
 
-- 
2.39.2





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux