aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r6040.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/r6040.c')
-rw-r--r--drivers/net/r6040.c99
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,
295static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) 295static 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)
318static void r6040_alloc_txbufs(struct net_device *dev) 315static 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
332static void r6040_alloc_rxbufs(struct net_device *dev) 325static 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
337static 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
348static void r6040_tx_timeout(struct net_device *dev) 389static 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
376static struct net_device_stats *r6040_get_stats(struct net_device *dev) 406static 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/*