Patchwork [U-Boot,06/14] net: gem: Do not initialize BDs again

login
register
mail settings
Submitter Michal Simek
Date April 22, 2013, 2:52 p.m.
Message ID <f82402bbdb297fc812851395638c53940d1cdbbb.1366641836.git.michal.simek@xilinx.com>
Download mbox | patch
Permalink /patch/238554/
State Changes Requested
Delegated to: Tom Rini
Headers show

Comments

Michal Simek - April 22, 2013, 2:52 p.m.
BDs can be correctly setup just once and init function
performs only phy autodetection and enabling RX/TX.
RX/TX are disabled in halt function.

This patch solves the problem with repeatable tftp transfers.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
 drivers/net/zynq_gem.c | 86 +++++++++++++++++++++++++++-----------------------
 1 file changed, 47 insertions(+), 39 deletions(-)

--
1.8.2.1

Patch

diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index c0da628..7758cf8 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -134,6 +134,7 @@  struct zynq_gem_priv {
 	u32 rxbd_current;
 	u32 rx_first_buf;
 	int phyaddr;
+	int init;
 	struct phy_device *phydev;
 	struct mii_dev *bus;
 };
@@ -239,50 +240,57 @@  static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
 			SUPPORTED_1000baseT_Half |
 			SUPPORTED_1000baseT_Full;

-	/* Disable all interrupts */
-	writel(0xFFFFFFFF, &regs->idr);
-
-	/* Disable the receiver & transmitter */
-	writel(0, &regs->nwctrl);
-	writel(0, &regs->txsr);
-	writel(0, &regs->rxsr);
-	writel(0, &regs->phymntnc);
-
-	/* Clear the Hash registers for the mac address pointed by AddressPtr */
-	writel(0x0, &regs->hashl);
-	/* Write bits [63:32] in TOP */
-	writel(0x0, &regs->hashh);
-
-	/* Clear all counters */
-	for (i = 0; i <= stat_size; i++)
-		readl(&regs->stat[i]);
-
-	/* Setup RxBD space */
-	memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd));
-	/* Create the RxBD ring */
-	memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers));
-
-	for (i = 0; i < RX_BUF; i++) {
-		priv->rx_bd[i].status = 0xF0000000;
-		priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) +
+	if (!priv->init) {
+		/* Disable all interrupts */
+		writel(0xFFFFFFFF, &regs->idr);
+
+		/* Disable the receiver & transmitter */
+		writel(0, &regs->nwctrl);
+		writel(0, &regs->txsr);
+		writel(0, &regs->rxsr);
+		writel(0, &regs->phymntnc);
+
+		/* Clear the Hash registers for the mac address
+		 * pointed by AddressPtr
+		 */
+		writel(0x0, &regs->hashl);
+		/* Write bits [63:32] in TOP */
+		writel(0x0, &regs->hashh);
+
+		/* Clear all counters */
+		for (i = 0; i <= stat_size; i++)
+			readl(&regs->stat[i]);
+
+		/* Setup RxBD space */
+		memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd));
+		/* Create the RxBD ring */
+		memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers));
+
+		for (i = 0; i < RX_BUF; i++) {
+			priv->rx_bd[i].status = 0xF0000000;
+			priv->rx_bd[i].addr =
+					(u32)((char *)&(priv->rxbuffers) +
 							(i * PKTSIZE_ALIGN));
-	}
-	/* WRAP bit to last BD */
-	priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
-	/* Write RxBDs to IP */
-	writel((u32) &(priv->rx_bd), &regs->rxqbase);
+		}
+		/* WRAP bit to last BD */
+		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
+		/* Write RxBDs to IP */
+		writel((u32)&(priv->rx_bd), &regs->rxqbase);

-	/* MAC Setup */
-	/* Setup Network Configuration register */
-	writel(ZYNQ_GEM_NWCFG_INIT, &regs->nwcfg);
+		/* MAC Setup */
+		/* Setup Network Configuration register */
+		writel(ZYNQ_GEM_NWCFG_INIT, &regs->nwcfg);

-	/* Setup for DMA Configuration register */
-	writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
+		/* Setup for DMA Configuration register */
+		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);

-	/* Setup for Network Control register, MDIO, Rx and Tx enable */
-	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK |
+		/* Setup for Network Control register, MDIO, Rx and Tx enable */
+		setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK |
 			ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK);

+		priv->init++;
+	}
+
 	/* interface - look at tsec */
 	phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);

@@ -307,7 +315,7 @@  static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
 	writel((u32)&(priv->tx_bd), &regs->txqbase);

 	/* Setup Tx BD */
-	memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd));
+	memset((void *)&(priv->tx_bd), 0, sizeof(struct emac_bd));

 	priv->tx_bd.addr = (u32)ptr;
 	priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK;