diff options
author | Michal Simek <michal.simek@xilinx.com> | 2013-01-24 13:04:12 +0100 |
---|---|---|
committer | Michal Simek <michal.simek@xilinx.com> | 2013-04-30 11:39:17 +0200 |
commit | 058687597d3ff26c415db33614b881de258a365b (patch) | |
tree | e90ec46378a8d4ad788fbefe606c84d892de3378 /drivers | |
parent | 3b90d0afe55d99d35801cfbac2c2a39a65f89ca8 (diff) |
net: gem: Do not initialize BDs again
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>
Reviewed-by: Tom Rini <trini@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/zynq_gem.c | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index c0da628378..7758cf89c2 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, ®s->idr); - - /* Disable the receiver & transmitter */ - writel(0, ®s->nwctrl); - writel(0, ®s->txsr); - writel(0, ®s->rxsr); - writel(0, ®s->phymntnc); - - /* Clear the Hash registers for the mac address pointed by AddressPtr */ - writel(0x0, ®s->hashl); - /* Write bits [63:32] in TOP */ - writel(0x0, ®s->hashh); - - /* Clear all counters */ - for (i = 0; i <= stat_size; i++) - readl(®s->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, ®s->idr); + + /* Disable the receiver & transmitter */ + writel(0, ®s->nwctrl); + writel(0, ®s->txsr); + writel(0, ®s->rxsr); + writel(0, ®s->phymntnc); + + /* Clear the Hash registers for the mac address + * pointed by AddressPtr + */ + writel(0x0, ®s->hashl); + /* Write bits [63:32] in TOP */ + writel(0x0, ®s->hashh); + + /* Clear all counters */ + for (i = 0; i <= stat_size; i++) + readl(®s->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), ®s->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), ®s->rxqbase); - /* MAC Setup */ - /* Setup Network Configuration register */ - writel(ZYNQ_GEM_NWCFG_INIT, ®s->nwcfg); + /* MAC Setup */ + /* Setup Network Configuration register */ + writel(ZYNQ_GEM_NWCFG_INIT, ®s->nwcfg); - /* Setup for DMA Configuration register */ - writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); + /* Setup for DMA Configuration register */ + writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); - /* Setup for Network Control register, MDIO, Rx and Tx enable */ - setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK | + /* Setup for Network Control register, MDIO, Rx and Tx enable */ + setbits_le32(®s->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), ®s->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; |