aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Simek2013-01-24 06:04:12 -0600
committerMichal Simek2013-04-30 04:39:17 -0500
commit058687597d3ff26c415db33614b881de258a365b (patch)
treee90ec46378a8d4ad788fbefe606c84d892de3378 /drivers
parent3b90d0afe55d99d35801cfbac2c2a39a65f89ca8 (diff)
downloadu-boot-058687597d3ff26c415db33614b881de258a365b.tar.gz
u-boot-058687597d3ff26c415db33614b881de258a365b.tar.xz
u-boot-058687597d3ff26c415db33614b881de258a365b.zip
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.c86
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 {
134 u32 rxbd_current; 134 u32 rxbd_current;
135 u32 rx_first_buf; 135 u32 rx_first_buf;
136 int phyaddr; 136 int phyaddr;
137 int init;
137 struct phy_device *phydev; 138 struct phy_device *phydev;
138 struct mii_dev *bus; 139 struct mii_dev *bus;
139}; 140};
@@ -239,50 +240,57 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
239 SUPPORTED_1000baseT_Half | 240 SUPPORTED_1000baseT_Half |
240 SUPPORTED_1000baseT_Full; 241 SUPPORTED_1000baseT_Full;
241 242
242 /* Disable all interrupts */ 243 if (!priv->init) {
243 writel(0xFFFFFFFF, &regs->idr); 244 /* Disable all interrupts */
244 245 writel(0xFFFFFFFF, &regs->idr);
245 /* Disable the receiver & transmitter */ 246
246 writel(0, &regs->nwctrl); 247 /* Disable the receiver & transmitter */
247 writel(0, &regs->txsr); 248 writel(0, &regs->nwctrl);
248 writel(0, &regs->rxsr); 249 writel(0, &regs->txsr);
249 writel(0, &regs->phymntnc); 250 writel(0, &regs->rxsr);
250 251 writel(0, &regs->phymntnc);
251 /* Clear the Hash registers for the mac address pointed by AddressPtr */ 252
252 writel(0x0, &regs->hashl); 253 /* Clear the Hash registers for the mac address
253 /* Write bits [63:32] in TOP */ 254 * pointed by AddressPtr
254 writel(0x0, &regs->hashh); 255 */
255 256 writel(0x0, &regs->hashl);
256 /* Clear all counters */ 257 /* Write bits [63:32] in TOP */
257 for (i = 0; i <= stat_size; i++) 258 writel(0x0, &regs->hashh);
258 readl(&regs->stat[i]); 259
259 260 /* Clear all counters */
260 /* Setup RxBD space */ 261 for (i = 0; i <= stat_size; i++)
261 memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd)); 262 readl(&regs->stat[i]);
262 /* Create the RxBD ring */ 263
263 memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers)); 264 /* Setup RxBD space */
264 265 memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd));
265 for (i = 0; i < RX_BUF; i++) { 266 /* Create the RxBD ring */
266 priv->rx_bd[i].status = 0xF0000000; 267 memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers));
267 priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) + 268
269 for (i = 0; i < RX_BUF; i++) {
270 priv->rx_bd[i].status = 0xF0000000;
271 priv->rx_bd[i].addr =
272 (u32)((char *)&(priv->rxbuffers) +
268 (i * PKTSIZE_ALIGN)); 273 (i * PKTSIZE_ALIGN));
269 } 274 }
270 /* WRAP bit to last BD */ 275 /* WRAP bit to last BD */
271 priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; 276 priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
272 /* Write RxBDs to IP */ 277 /* Write RxBDs to IP */
273 writel((u32) &(priv->rx_bd), &regs->rxqbase); 278 writel((u32)&(priv->rx_bd), &regs->rxqbase);
274 279
275 /* MAC Setup */ 280 /* MAC Setup */
276 /* Setup Network Configuration register */ 281 /* Setup Network Configuration register */
277 writel(ZYNQ_GEM_NWCFG_INIT, &regs->nwcfg); 282 writel(ZYNQ_GEM_NWCFG_INIT, &regs->nwcfg);
278 283
279 /* Setup for DMA Configuration register */ 284 /* Setup for DMA Configuration register */
280 writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr); 285 writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
281 286
282 /* Setup for Network Control register, MDIO, Rx and Tx enable */ 287 /* Setup for Network Control register, MDIO, Rx and Tx enable */
283 setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK | 288 setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK |
284 ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK); 289 ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK);
285 290
291 priv->init++;
292 }
293
286 /* interface - look at tsec */ 294 /* interface - look at tsec */
287 phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); 295 phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
288 296
@@ -307,7 +315,7 @@ static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
307 writel((u32)&(priv->tx_bd), &regs->txqbase); 315 writel((u32)&(priv->tx_bd), &regs->txqbase);
308 316
309 /* Setup Tx BD */ 317 /* Setup Tx BD */
310 memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd)); 318 memset((void *)&(priv->tx_bd), 0, sizeof(struct emac_bd));
311 319
312 priv->tx_bd.addr = (u32)ptr; 320 priv->tx_bd.addr = (u32)ptr;
313 priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK; 321 priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK;