diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2006-02-07 02:05:17 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-07 02:05:17 -0500 |
commit | 3cfc15103aa56c2c7ee6dd312c24a8d1697bade1 (patch) | |
tree | 73e0e3b3fe0e381ec9f7e511dcd99326fe4d89f6 /drivers/net | |
parent | cc8c6e379ca30a18cb18553abeb15fe19120bf7b (diff) | |
parent | 371e8bc2af11b0571982390932bc07b5ffed9aba (diff) |
Merge branch 'for-jeff' of git://electric-eye.fr.zoreil.com/home/romieu/linux-2.6
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/8139too.c | 38 | ||||
-rw-r--r-- | drivers/net/r8169.c | 13 |
2 files changed, 33 insertions, 18 deletions
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index adfba44dac5a..2beac55b57d6 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -586,6 +586,7 @@ struct rtl8139_private { | |||
586 | dma_addr_t tx_bufs_dma; | 586 | dma_addr_t tx_bufs_dma; |
587 | signed char phys[4]; /* MII device addresses. */ | 587 | signed char phys[4]; /* MII device addresses. */ |
588 | char twistie, twist_row, twist_col; /* Twister tune state. */ | 588 | char twistie, twist_row, twist_col; /* Twister tune state. */ |
589 | unsigned int watchdog_fired : 1; | ||
589 | unsigned int default_port : 4; /* Last dev->if_port value. */ | 590 | unsigned int default_port : 4; /* Last dev->if_port value. */ |
590 | unsigned int have_thread : 1; | 591 | unsigned int have_thread : 1; |
591 | spinlock_t lock; | 592 | spinlock_t lock; |
@@ -638,6 +639,7 @@ static void rtl8139_set_rx_mode (struct net_device *dev); | |||
638 | static void __set_rx_mode (struct net_device *dev); | 639 | static void __set_rx_mode (struct net_device *dev); |
639 | static void rtl8139_hw_start (struct net_device *dev); | 640 | static void rtl8139_hw_start (struct net_device *dev); |
640 | static void rtl8139_thread (void *_data); | 641 | static void rtl8139_thread (void *_data); |
642 | static void rtl8139_tx_timeout_task(void *_data); | ||
641 | static struct ethtool_ops rtl8139_ethtool_ops; | 643 | static struct ethtool_ops rtl8139_ethtool_ops; |
642 | 644 | ||
643 | /* write MMIO register, with flush */ | 645 | /* write MMIO register, with flush */ |
@@ -1598,13 +1600,14 @@ static void rtl8139_thread (void *_data) | |||
1598 | { | 1600 | { |
1599 | struct net_device *dev = _data; | 1601 | struct net_device *dev = _data; |
1600 | struct rtl8139_private *tp = netdev_priv(dev); | 1602 | struct rtl8139_private *tp = netdev_priv(dev); |
1601 | unsigned long thr_delay; | 1603 | unsigned long thr_delay = next_tick; |
1602 | 1604 | ||
1603 | if (rtnl_shlock_nowait() == 0) { | 1605 | if (tp->watchdog_fired) { |
1606 | tp->watchdog_fired = 0; | ||
1607 | rtl8139_tx_timeout_task(_data); | ||
1608 | } else if (rtnl_shlock_nowait() == 0) { | ||
1604 | rtl8139_thread_iter (dev, tp, tp->mmio_addr); | 1609 | rtl8139_thread_iter (dev, tp, tp->mmio_addr); |
1605 | rtnl_unlock (); | 1610 | rtnl_unlock (); |
1606 | |||
1607 | thr_delay = next_tick; | ||
1608 | } else { | 1611 | } else { |
1609 | /* unlikely race. mitigate with fast poll. */ | 1612 | /* unlikely race. mitigate with fast poll. */ |
1610 | thr_delay = HZ / 2; | 1613 | thr_delay = HZ / 2; |
@@ -1631,7 +1634,8 @@ static void rtl8139_stop_thread(struct rtl8139_private *tp) | |||
1631 | if (tp->have_thread) { | 1634 | if (tp->have_thread) { |
1632 | cancel_rearming_delayed_work(&tp->thread); | 1635 | cancel_rearming_delayed_work(&tp->thread); |
1633 | tp->have_thread = 0; | 1636 | tp->have_thread = 0; |
1634 | } | 1637 | } else |
1638 | flush_scheduled_work(); | ||
1635 | } | 1639 | } |
1636 | 1640 | ||
1637 | static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | 1641 | static inline void rtl8139_tx_clear (struct rtl8139_private *tp) |
@@ -1642,14 +1646,13 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | |||
1642 | /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ | 1646 | /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ |
1643 | } | 1647 | } |
1644 | 1648 | ||
1645 | 1649 | static void rtl8139_tx_timeout_task (void *_data) | |
1646 | static void rtl8139_tx_timeout (struct net_device *dev) | ||
1647 | { | 1650 | { |
1651 | struct net_device *dev = _data; | ||
1648 | struct rtl8139_private *tp = netdev_priv(dev); | 1652 | struct rtl8139_private *tp = netdev_priv(dev); |
1649 | void __iomem *ioaddr = tp->mmio_addr; | 1653 | void __iomem *ioaddr = tp->mmio_addr; |
1650 | int i; | 1654 | int i; |
1651 | u8 tmp8; | 1655 | u8 tmp8; |
1652 | unsigned long flags; | ||
1653 | 1656 | ||
1654 | printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x " | 1657 | printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x " |
1655 | "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd), | 1658 | "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd), |
@@ -1670,23 +1673,34 @@ static void rtl8139_tx_timeout (struct net_device *dev) | |||
1670 | if (tmp8 & CmdTxEnb) | 1673 | if (tmp8 & CmdTxEnb) |
1671 | RTL_W8 (ChipCmd, CmdRxEnb); | 1674 | RTL_W8 (ChipCmd, CmdRxEnb); |
1672 | 1675 | ||
1673 | spin_lock(&tp->rx_lock); | 1676 | spin_lock_bh(&tp->rx_lock); |
1674 | /* Disable interrupts by clearing the interrupt mask. */ | 1677 | /* Disable interrupts by clearing the interrupt mask. */ |
1675 | RTL_W16 (IntrMask, 0x0000); | 1678 | RTL_W16 (IntrMask, 0x0000); |
1676 | 1679 | ||
1677 | /* Stop a shared interrupt from scavenging while we are. */ | 1680 | /* Stop a shared interrupt from scavenging while we are. */ |
1678 | spin_lock_irqsave (&tp->lock, flags); | 1681 | spin_lock_irq(&tp->lock); |
1679 | rtl8139_tx_clear (tp); | 1682 | rtl8139_tx_clear (tp); |
1680 | spin_unlock_irqrestore (&tp->lock, flags); | 1683 | spin_unlock_irq(&tp->lock); |
1681 | 1684 | ||
1682 | /* ...and finally, reset everything */ | 1685 | /* ...and finally, reset everything */ |
1683 | if (netif_running(dev)) { | 1686 | if (netif_running(dev)) { |
1684 | rtl8139_hw_start (dev); | 1687 | rtl8139_hw_start (dev); |
1685 | netif_wake_queue (dev); | 1688 | netif_wake_queue (dev); |
1686 | } | 1689 | } |
1687 | spin_unlock(&tp->rx_lock); | 1690 | spin_unlock_bh(&tp->rx_lock); |
1688 | } | 1691 | } |
1689 | 1692 | ||
1693 | static void rtl8139_tx_timeout (struct net_device *dev) | ||
1694 | { | ||
1695 | struct rtl8139_private *tp = netdev_priv(dev); | ||
1696 | |||
1697 | if (!tp->have_thread) { | ||
1698 | INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev); | ||
1699 | schedule_delayed_work(&tp->thread, next_tick); | ||
1700 | } else | ||
1701 | tp->watchdog_fired = 1; | ||
1702 | |||
1703 | } | ||
1690 | 1704 | ||
1691 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) | 1705 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) |
1692 | { | 1706 | { |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 2e1bed153c39..6e1018448eea 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -484,13 +484,12 @@ static void mdio_write(void __iomem *ioaddr, int RegAddr, int value) | |||
484 | int i; | 484 | int i; |
485 | 485 | ||
486 | RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); | 486 | RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); |
487 | udelay(1000); | ||
488 | 487 | ||
489 | for (i = 2000; i > 0; i--) { | 488 | for (i = 20; i > 0; i--) { |
490 | /* Check if the RTL8169 has completed writing to the specified MII register */ | 489 | /* Check if the RTL8169 has completed writing to the specified MII register */ |
491 | if (!(RTL_R32(PHYAR) & 0x80000000)) | 490 | if (!(RTL_R32(PHYAR) & 0x80000000)) |
492 | break; | 491 | break; |
493 | udelay(100); | 492 | udelay(25); |
494 | } | 493 | } |
495 | } | 494 | } |
496 | 495 | ||
@@ -499,15 +498,14 @@ static int mdio_read(void __iomem *ioaddr, int RegAddr) | |||
499 | int i, value = -1; | 498 | int i, value = -1; |
500 | 499 | ||
501 | RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); | 500 | RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); |
502 | udelay(1000); | ||
503 | 501 | ||
504 | for (i = 2000; i > 0; i--) { | 502 | for (i = 20; i > 0; i--) { |
505 | /* Check if the RTL8169 has completed retrieving data from the specified MII register */ | 503 | /* Check if the RTL8169 has completed retrieving data from the specified MII register */ |
506 | if (RTL_R32(PHYAR) & 0x80000000) { | 504 | if (RTL_R32(PHYAR) & 0x80000000) { |
507 | value = (int) (RTL_R32(PHYAR) & 0xFFFF); | 505 | value = (int) (RTL_R32(PHYAR) & 0xFFFF); |
508 | break; | 506 | break; |
509 | } | 507 | } |
510 | udelay(100); | 508 | udelay(25); |
511 | } | 509 | } |
512 | return value; | 510 | return value; |
513 | } | 511 | } |
@@ -677,6 +675,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
677 | 675 | ||
678 | if (duplex == DUPLEX_HALF) | 676 | if (duplex == DUPLEX_HALF) |
679 | auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); | 677 | auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); |
678 | |||
679 | if (duplex == DUPLEX_FULL) | ||
680 | auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half); | ||
680 | } | 681 | } |
681 | 682 | ||
682 | tp->phy_auto_nego_reg = auto_nego; | 683 | tp->phy_auto_nego_reg = auto_nego; |