public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Alexey Brodkin <Alexey.Brodkin@synopsys.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3] net/designware: make driver compatible with data cache
Date: Wed, 22 Jan 2014 20:49:09 +0400	[thread overview]
Message-ID: <1390409349-9406-1-git-send-email-abrodkin@synopsys.com> (raw)

From: Alexey Brodkin <Alexey.Brodkin@synopsys.com>

Up until now this driver only worked with data cache disabled.
To make it work with enabled data cache following changes were required:

 * Flush Tx/Rx buffer descriptors their modification
 * Invalidate Tx/Rx buffer descriptors before reading its values
 * Flush cache for data passed from CPU to GMAC
 * Invalidate cache for data passed from GMAC to CPU

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>

Cc: Joe Hershberger <joe.hershberger@ni.com>
Cc: Vipin Kumar <vipin.kumar@st.com>
Cc: Stefan Roese <sr@denx.de>
Cc: Mischa Jonker <mjonker@synopsys.com>
Cc: Shiraz Hashim <shiraz.hashim@st.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Cc: Amit Virdi <amit.virdi@st.com>
Cc: Sonic Zhang <sonic.zhang@analog.com>

Compared to v2:
 1. Removed trailing white space
---
 drivers/net/designware.c | 53 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 22155b4..c0c8659 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -51,6 +51,11 @@ static void tx_descs_init(struct eth_device *dev)
 	/* Correcting the last pointer of the chain */
 	desc_p->dmamac_next = &desc_table_p[0];
 
+	/* Flush all Tx buffer descriptors at once */
+	flush_dcache_range((unsigned int)priv->tx_mac_descrtable,
+			   (unsigned int)priv->tx_mac_descrtable +
+			   sizeof(priv->tx_mac_descrtable));
+
 	writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
 }
 
@@ -63,6 +68,15 @@ static void rx_descs_init(struct eth_device *dev)
 	struct dmamacdescr *desc_p;
 	u32 idx;
 
+	/* Before passing buffers to GMAC we need to make sure zeros
+	 * written there right after "priv" structure allocation were
+	 * flushed into RAM.
+	 * Otherwise there's a chance to get some of them flushed in RAM when
+	 * GMAC is already pushing data to RAM via DMA. This way incoming from
+	 * GMAC data will be corrupted. */
+	flush_dcache_range((unsigned int)rxbuffs, (unsigned int)rxbuffs +
+			   RX_TOTAL_BUFSIZE);
+
 	for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
 		desc_p = &desc_table_p[idx];
 		desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
@@ -78,6 +92,11 @@ static void rx_descs_init(struct eth_device *dev)
 	/* Correcting the last pointer of the chain */
 	desc_p->dmamac_next = &desc_table_p[0];
 
+	/* Flush all Rx buffer descriptors at once */
+	flush_dcache_range((unsigned int)priv->rx_mac_descrtable,
+			   (unsigned int)priv->rx_mac_descrtable +
+			   sizeof(priv->rx_mac_descrtable));
+
 	writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
 }
 
@@ -197,6 +216,11 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
 	u32 desc_num = priv->tx_currdescnum;
 	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
 
+	/* Invalidate only "status" field for the following check */
+	invalidate_dcache_range((unsigned long)&desc_p->txrx_status,
+				(unsigned long)&desc_p->txrx_status +
+				sizeof(desc_p->txrx_status));
+
 	/* Check if the descriptor is owned by CPU */
 	if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
 		printf("CPU not owner of tx frame\n");
@@ -205,6 +229,10 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
 
 	memcpy((void *)desc_p->dmamac_addr, packet, length);
 
+	/* Flush data to be sent */
+	flush_dcache_range((unsigned long)desc_p->dmamac_addr,
+			   (unsigned long)desc_p->dmamac_addr + length);
+
 #if defined(CONFIG_DW_ALTDESCRIPTOR)
 	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
 	desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \
@@ -220,6 +248,10 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
 	desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
 #endif
 
+	/* Flush modified buffer descriptor */
+	flush_dcache_range((unsigned long)desc_p,
+			   (unsigned long)desc_p + sizeof(struct dmamacdescr));
+
 	/* Test the wrap-around condition. */
 	if (++desc_num >= CONFIG_TX_DESCR_NUM)
 		desc_num = 0;
@@ -235,18 +267,28 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
 static int dw_eth_recv(struct eth_device *dev)
 {
 	struct dw_eth_dev *priv = dev->priv;
-	u32 desc_num = priv->rx_currdescnum;
+	u32 status, desc_num = priv->rx_currdescnum;
 	struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
-
-	u32 status = desc_p->txrx_status;
 	int length = 0;
 
+	/* Invalidate entire buffer descriptor */
+	invalidate_dcache_range((unsigned long)desc_p,
+				(unsigned long)desc_p +
+				sizeof(struct dmamacdescr));
+
+	status = desc_p->txrx_status;
+
 	/* Check  if the owner is the CPU */
 	if (!(status & DESC_RXSTS_OWNBYDMA)) {
 
 		length = (status & DESC_RXSTS_FRMLENMSK) >> \
 			 DESC_RXSTS_FRMLENSHFT;
 
+		/* Invalidate received data */
+		invalidate_dcache_range((unsigned long)desc_p->dmamac_addr,
+					(unsigned long)desc_p->dmamac_addr +
+					length);
+
 		NetReceive(desc_p->dmamac_addr, length);
 
 		/*
@@ -255,6 +297,11 @@ static int dw_eth_recv(struct eth_device *dev)
 		 */
 		desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
 
+		/* Flush only status field - others weren't changed */
+		flush_dcache_range((unsigned long)&desc_p->txrx_status,
+				   (unsigned long)&desc_p->txrx_status +
+				   sizeof(desc_p->txrx_status));
+
 		/* Test the wrap-around condition. */
 		if (++desc_num >= CONFIG_RX_DESCR_NUM)
 			desc_num = 0;
-- 
1.8.4.2

             reply	other threads:[~2014-01-22 16:49 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-22 16:49 Alexey Brodkin [this message]
2014-01-22 16:55 ` [U-Boot] [PATCH v3] net/designware: make driver compatible with data cache Stefan Roese
2014-01-22 17:10 ` Mischa Jonker
2014-01-22 17:30   ` Alexey Brodkin
2014-02-07 14:21 ` [U-Boot] [U-Boot, " Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1390409349-9406-1-git-send-email-abrodkin@synopsys.com \
    --to=alexey.brodkin@synopsys.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox