diff options
author | Michal Simek | 2013-01-24 06:04:12 -0600 |
---|---|---|
committer | Michal Simek | 2013-04-30 04:39:17 -0500 |
commit | 058687597d3ff26c415db33614b881de258a365b (patch) | |
tree | e90ec46378a8d4ad788fbefe606c84d892de3378 /drivers | |
parent | 3b90d0afe55d99d35801cfbac2c2a39a65f89ca8 (diff) | |
download | u-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.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 { | |||
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, ®s->idr); | 244 | /* Disable all interrupts */ |
244 | 245 | writel(0xFFFFFFFF, ®s->idr); | |
245 | /* Disable the receiver & transmitter */ | 246 | |
246 | writel(0, ®s->nwctrl); | 247 | /* Disable the receiver & transmitter */ |
247 | writel(0, ®s->txsr); | 248 | writel(0, ®s->nwctrl); |
248 | writel(0, ®s->rxsr); | 249 | writel(0, ®s->txsr); |
249 | writel(0, ®s->phymntnc); | 250 | writel(0, ®s->rxsr); |
250 | 251 | writel(0, ®s->phymntnc); | |
251 | /* Clear the Hash registers for the mac address pointed by AddressPtr */ | 252 | |
252 | writel(0x0, ®s->hashl); | 253 | /* Clear the Hash registers for the mac address |
253 | /* Write bits [63:32] in TOP */ | 254 | * pointed by AddressPtr |
254 | writel(0x0, ®s->hashh); | 255 | */ |
255 | 256 | writel(0x0, ®s->hashl); | |
256 | /* Clear all counters */ | 257 | /* Write bits [63:32] in TOP */ |
257 | for (i = 0; i <= stat_size; i++) | 258 | writel(0x0, ®s->hashh); |
258 | readl(®s->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(®s->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), ®s->rxqbase); | 278 | writel((u32)&(priv->rx_bd), ®s->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, ®s->nwcfg); | 282 | writel(ZYNQ_GEM_NWCFG_INIT, ®s->nwcfg); |
278 | 283 | ||
279 | /* Setup for DMA Configuration register */ | 284 | /* Setup for DMA Configuration register */ |
280 | writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); | 285 | writel(ZYNQ_GEM_DMACR_INIT, ®s->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(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK | | 288 | setbits_le32(®s->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), ®s->txqbase); | 315 | writel((u32)&(priv->tx_bd), ®s->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; |