diff options
-rw-r--r-- | drivers/net/r6040.c | 99 |
1 files changed, 58 insertions, 41 deletions
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index d277deb872e0..0972152e5d28 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -295,7 +295,6 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, | |||
295 | static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) | 295 | static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) |
296 | { | 296 | { |
297 | struct r6040_descriptor *descptr; | 297 | struct r6040_descriptor *descptr; |
298 | void __iomem *ioaddr = lp->base; | ||
299 | 298 | ||
300 | descptr = lp->rx_insert_ptr; | 299 | descptr = lp->rx_insert_ptr; |
301 | while (lp->rx_free_desc < RX_DCNT) { | 300 | while (lp->rx_free_desc < RX_DCNT) { |
@@ -309,8 +308,6 @@ static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) | |||
309 | descptr->status = 0x8000; | 308 | descptr->status = 0x8000; |
310 | descptr = descptr->vndescp; | 309 | descptr = descptr->vndescp; |
311 | lp->rx_free_desc++; | 310 | lp->rx_free_desc++; |
312 | /* Trigger RX DMA */ | ||
313 | iowrite16(lp->mcr0 | 0x0002, ioaddr); | ||
314 | } | 311 | } |
315 | lp->rx_insert_ptr = descptr; | 312 | lp->rx_insert_ptr = descptr; |
316 | } | 313 | } |
@@ -318,21 +315,16 @@ static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) | |||
318 | static void r6040_alloc_txbufs(struct net_device *dev) | 315 | static void r6040_alloc_txbufs(struct net_device *dev) |
319 | { | 316 | { |
320 | struct r6040_private *lp = netdev_priv(dev); | 317 | struct r6040_private *lp = netdev_priv(dev); |
321 | void __iomem *ioaddr = lp->base; | ||
322 | 318 | ||
323 | lp->tx_free_desc = TX_DCNT; | 319 | lp->tx_free_desc = TX_DCNT; |
324 | 320 | ||
325 | lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; | 321 | lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; |
326 | r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); | 322 | r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); |
327 | |||
328 | iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); | ||
329 | iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); | ||
330 | } | 323 | } |
331 | 324 | ||
332 | static void r6040_alloc_rxbufs(struct net_device *dev) | 325 | static void r6040_alloc_rxbufs(struct net_device *dev) |
333 | { | 326 | { |
334 | struct r6040_private *lp = netdev_priv(dev); | 327 | struct r6040_private *lp = netdev_priv(dev); |
335 | void __iomem *ioaddr = lp->base; | ||
336 | 328 | ||
337 | lp->rx_free_desc = 0; | 329 | lp->rx_free_desc = 0; |
338 | 330 | ||
@@ -340,9 +332,58 @@ static void r6040_alloc_rxbufs(struct net_device *dev) | |||
340 | r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); | 332 | r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); |
341 | 333 | ||
342 | r6040_rx_buf_alloc(lp, dev); | 334 | r6040_rx_buf_alloc(lp, dev); |
335 | } | ||
336 | |||
337 | static void r6040_init_mac_regs(struct net_device *dev) | ||
338 | { | ||
339 | struct r6040_private *lp = netdev_priv(dev); | ||
340 | void __iomem *ioaddr = lp->base; | ||
341 | int limit = 2048; | ||
342 | u16 cmd; | ||
343 | |||
344 | /* Mask Off Interrupt */ | ||
345 | iowrite16(MSK_INT, ioaddr + MIER); | ||
343 | 346 | ||
347 | /* Reset RDC MAC */ | ||
348 | iowrite16(MAC_RST, ioaddr + MCR1); | ||
349 | while (limit--) { | ||
350 | cmd = ioread16(ioaddr + MCR1); | ||
351 | if (cmd & 0x1) | ||
352 | break; | ||
353 | } | ||
354 | /* Reset internal state machine */ | ||
355 | iowrite16(2, ioaddr + MAC_SM); | ||
356 | iowrite16(0, ioaddr + MAC_SM); | ||
357 | udelay(5000); | ||
358 | |||
359 | /* MAC Bus Control Register */ | ||
360 | iowrite16(MBCR_DEFAULT, ioaddr + MBCR); | ||
361 | |||
362 | /* Buffer Size Register */ | ||
363 | iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR); | ||
364 | |||
365 | /* Write TX ring start address */ | ||
366 | iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); | ||
367 | iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); | ||
368 | |||
369 | /* Write RX ring start address */ | ||
344 | iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); | 370 | iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); |
345 | iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); | 371 | iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); |
372 | |||
373 | /* Set interrupt waiting time and packet numbers */ | ||
374 | iowrite16(0x0F06, ioaddr + MT_ICR); | ||
375 | iowrite16(0x0F06, ioaddr + MR_ICR); | ||
376 | |||
377 | /* Enable interrupts */ | ||
378 | iowrite16(INT_MASK, ioaddr + MIER); | ||
379 | |||
380 | /* Enable TX and RX */ | ||
381 | iowrite16(lp->mcr0 | 0x0002, ioaddr); | ||
382 | |||
383 | /* Let TX poll the descriptors | ||
384 | * we may got called by r6040_tx_timeout which has left | ||
385 | * some unsent tx buffers */ | ||
386 | iowrite16(0x01, ioaddr + MTPR); | ||
346 | } | 387 | } |
347 | 388 | ||
348 | static void r6040_tx_timeout(struct net_device *dev) | 389 | static void r6040_tx_timeout(struct net_device *dev) |
@@ -350,27 +391,16 @@ static void r6040_tx_timeout(struct net_device *dev) | |||
350 | struct r6040_private *priv = netdev_priv(dev); | 391 | struct r6040_private *priv = netdev_priv(dev); |
351 | void __iomem *ioaddr = priv->base; | 392 | void __iomem *ioaddr = priv->base; |
352 | 393 | ||
353 | printk(KERN_WARNING "%s: transmit timed out, status %4.4x, PHY status " | 394 | printk(KERN_WARNING "%s: transmit timed out, int enable %4.4x " |
354 | "%4.4x\n", | 395 | "status %4.4x, PHY status %4.4x\n", |
355 | dev->name, ioread16(ioaddr + MIER), | 396 | dev->name, ioread16(ioaddr + MIER), |
397 | ioread16(ioaddr + MISR), | ||
356 | r6040_mdio_read(dev, priv->mii_if.phy_id, MII_BMSR)); | 398 | r6040_mdio_read(dev, priv->mii_if.phy_id, MII_BMSR)); |
357 | 399 | ||
358 | disable_irq(dev->irq); | ||
359 | napi_disable(&priv->napi); | ||
360 | spin_lock(&priv->lock); | ||
361 | /* Clear all descriptors */ | ||
362 | r6040_free_txbufs(dev); | ||
363 | r6040_free_rxbufs(dev); | ||
364 | r6040_alloc_txbufs(dev); | ||
365 | r6040_alloc_rxbufs(dev); | ||
366 | |||
367 | /* Reset MAC */ | ||
368 | iowrite16(MAC_RST, ioaddr + MCR1); | ||
369 | spin_unlock(&priv->lock); | ||
370 | enable_irq(dev->irq); | ||
371 | |||
372 | dev->stats.tx_errors++; | 400 | dev->stats.tx_errors++; |
373 | netif_wake_queue(dev); | 401 | |
402 | /* Reset MAC and re-init all registers */ | ||
403 | r6040_init_mac_regs(dev); | ||
374 | } | 404 | } |
375 | 405 | ||
376 | static struct net_device_stats *r6040_get_stats(struct net_device *dev) | 406 | static struct net_device_stats *r6040_get_stats(struct net_device *dev) |
@@ -676,8 +706,6 @@ static void r6040_up(struct net_device *dev) | |||
676 | r6040_alloc_txbufs(dev); | 706 | r6040_alloc_txbufs(dev); |
677 | r6040_alloc_rxbufs(dev); | 707 | r6040_alloc_rxbufs(dev); |
678 | 708 | ||
679 | /* Buffer Size Register */ | ||
680 | iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR); | ||
681 | /* Read the PHY ID */ | 709 | /* Read the PHY ID */ |
682 | lp->switch_sig = r6040_phy_read(ioaddr, 0, 2); | 710 | lp->switch_sig = r6040_phy_read(ioaddr, 0, 2); |
683 | 711 | ||
@@ -694,20 +722,9 @@ static void r6040_up(struct net_device *dev) | |||
694 | else | 722 | else |
695 | lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0; | 723 | lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0; |
696 | } | 724 | } |
697 | /* MAC Bus Control Register : | ||
698 | * - wait 1 host clock SDRAM bus request | ||
699 | * - RX FIFO : 32 bytes | ||
700 | * - TX FIFO : 64 bytes | ||
701 | * - FIFO transfer lenght : 16 bytes */ | ||
702 | iowrite16(MBCR_DEFAULT, ioaddr + MBCR); | ||
703 | 725 | ||
704 | /* MAC TX/RX Enable */ | 726 | /* Set duplex mode */ |
705 | lp->mcr0 |= lp->phy_mode; | 727 | lp->mcr0 |= lp->phy_mode; |
706 | iowrite16(lp->mcr0, ioaddr); | ||
707 | |||
708 | /* set interrupt waiting time and packet numbers */ | ||
709 | iowrite16(0x0F06, ioaddr + MT_ICR); | ||
710 | iowrite16(0x0F06, ioaddr + MR_ICR); | ||
711 | 728 | ||
712 | /* improve performance (by RDC guys) */ | 729 | /* improve performance (by RDC guys) */ |
713 | r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000)); | 730 | r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000)); |
@@ -715,8 +732,8 @@ static void r6040_up(struct net_device *dev) | |||
715 | r6040_phy_write(ioaddr, 0, 19, 0x0000); | 732 | r6040_phy_write(ioaddr, 0, 19, 0x0000); |
716 | r6040_phy_write(ioaddr, 0, 30, 0x01F0); | 733 | r6040_phy_write(ioaddr, 0, 30, 0x01F0); |
717 | 734 | ||
718 | /* Interrupt Mask Register */ | 735 | /* Initialize all MAC registers */ |
719 | iowrite16(INT_MASK, ioaddr + MIER); | 736 | r6040_init_mac_regs(dev); |
720 | } | 737 | } |
721 | 738 | ||
722 | /* | 739 | /* |