summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2017-04-30 21:57:08 +0200
committerJoe Hershberger <joe.hershberger@ni.com>2017-06-02 14:44:20 -0500
commit2303bff7d55df47105740e5d635d50ef9f6856b6 (patch)
treeff94f77aa0bb50d3fd07ced4b4e0ea279c49a9d0
parent52e727c8eb449db8b8dcb38201cbe034c8fa3c04 (diff)
net: pch_gbe: Add cache maintenance
On MIPS systems DMA isn't coherent with the CPU caches unless an IOCU is present. When there is no IOCU we need to writeback or invalidate the data caches at appropriate points. Perform this cache maintenance in the pch_gbe driver which is used on the MIPS Boston development board. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Tested-by: Bin Meng <bmeng.cn@gmail.com> Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
-rw-r--r--drivers/net/pch_gbe.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index 14323512b0..8866f6632f 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -120,6 +120,8 @@ static void pch_gbe_rx_descs_init(struct udevice *dev)
rx_desc[i].buffer_addr = dm_pci_virt_to_mem(priv->dev,
priv->rx_buff[i]);
+ flush_dcache_range((ulong)rx_desc, (ulong)&rx_desc[PCH_GBE_DESC_NUM]);
+
writel(dm_pci_virt_to_mem(priv->dev, rx_desc),
&mac_regs->rx_dsc_base);
writel(sizeof(struct pch_gbe_rx_desc) * (PCH_GBE_DESC_NUM - 1),
@@ -137,6 +139,8 @@ static void pch_gbe_tx_descs_init(struct udevice *dev)
memset(tx_desc, 0, sizeof(struct pch_gbe_tx_desc) * PCH_GBE_DESC_NUM);
+ flush_dcache_range((ulong)tx_desc, (ulong)&tx_desc[PCH_GBE_DESC_NUM]);
+
writel(dm_pci_virt_to_mem(priv->dev, tx_desc),
&mac_regs->tx_dsc_base);
writel(sizeof(struct pch_gbe_tx_desc) * (PCH_GBE_DESC_NUM - 1),
@@ -245,6 +249,8 @@ static int pch_gbe_send(struct udevice *dev, void *packet, int length)
u32 int_st;
ulong start;
+ flush_dcache_range((ulong)packet, (ulong)packet + length);
+
tx_head = &priv->tx_desc[0];
tx_desc = &priv->tx_desc[priv->tx_idx];
@@ -258,6 +264,8 @@ static int pch_gbe_send(struct udevice *dev, void *packet, int length)
tx_desc->dma_status = 0;
tx_desc->gbec_status = 0;
+ flush_dcache_range((ulong)tx_desc, (ulong)&tx_desc[1]);
+
/* Test the wrap-around condition */
if (++priv->tx_idx >= PCH_GBE_DESC_NUM)
priv->tx_idx = 0;
@@ -295,8 +303,12 @@ static int pch_gbe_recv(struct udevice *dev, int flags, uchar **packetp)
if (virt_to_phys(rx_desc) == hw_desc)
return -EAGAIN;
+ /* Invalidate the descriptor */
+ invalidate_dcache_range((ulong)rx_desc, (ulong)&rx_desc[1]);
+
length = rx_desc->rx_words_eob - 3 - ETH_FCS_LEN;
buffer = dm_pci_mem_to_virt(priv->dev, rx_desc->buffer_addr, length, 0);
+ invalidate_dcache_range((ulong)buffer, (ulong)buffer + length);
*packetp = (uchar *)buffer;
return length;