aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r6040.c
diff options
context:
space:
mode:
authorFlorian Fainelli <florian.fainelli@telecomint.eu>2008-07-13 08:29:20 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-07-22 19:56:30 -0400
commitfec3a23be0daceeb0695f8296aea07ea1ad073d8 (patch)
treeaa4a7af7f89c423c0f0d1ca3de3c29c237207a38 /drivers/net/r6040.c
parent3d25434816356e8d1e3167c5f7a56d3d81aeb239 (diff)
r6040: fix scheduling while atomic in r6040_tx_timeout
Add a helper function which only modifies R6040 MAC registers use it when we timeout, and on adapter initialization. Fix the scheduling while atomic but in the timeout routine due to the reallocation of rx/tx buffers. Signed-Off-By: Joerg Albert <jal2@gmx.de> Signed-off-by: Florian Fainelli <florian.fainelli@telecomint.eu> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
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/*